ToolPanel.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. /* Copyright (c) Business Objects 2006. All rights reserved. */
  2. if (typeof(bobj.crv.ToolPanel) == 'undefined') {
  3. bobj.crv.ToolPanel = {};
  4. }
  5. if (typeof(bobj.crv.GroupTree) == 'undefined') {
  6. bobj.crv.GroupTree = {};
  7. }
  8. if (typeof(bobj.crv.GroupTreeNode) == 'undefined') {
  9. bobj.crv.GroupTreeNode = {};
  10. }
  11. bobj.crv.ToolPanelType = { //values must match server's expectations
  12. None: 'None',
  13. GroupTree : 'GroupTree',
  14. ParameterPanel: 'ParameterPanel'
  15. };
  16. /**
  17. * ToolPanel constructor
  18. *
  19. * @param kwArgs.id [String] DOM node id
  20. * @param kwArgs.width [String] Width
  21. * @param kwArgs.height [String] Height
  22. */
  23. bobj.crv.newToolPanel = function(kwArgs) {
  24. kwArgs = MochiKit.Base.update({
  25. id: bobj.uniqueId() + "_toolPanel",
  26. width: '300px',
  27. height: '100%',
  28. initialViewType: bobj.crv.ToolPanelType.None
  29. }, kwArgs);
  30. var o = newWidget(kwArgs.id);
  31. // Update instance with constructor arguments
  32. bobj.fillIn(o, kwArgs);
  33. o.widgetType = 'ToolPanel';
  34. o._children = [];
  35. o._selectedChild = null;
  36. // Update instance with member functions
  37. o.initOld = o.init;
  38. o.resizeOld = o.resize;
  39. MochiKit.Base.update(o, bobj.crv.ToolPanel);
  40. return o;
  41. };
  42. /**
  43. * Adds a child widget as a view. If the child has an isSelected attribute
  44. * that evaluates as true, it will be the selected (active) view.
  45. *
  46. * This function must be called before getHTML() is called.
  47. *
  48. * @param widget [Widget] Child view widget
  49. */
  50. bobj.crv.ToolPanel.addChild = function(widget) {
  51. if (!widget) {return;}
  52. var connect = MochiKit.Signal.connect;
  53. var partial = MochiKit.Base.partial;
  54. var signal = MochiKit.Signal.signal;
  55. var Type = bobj.crv.ToolPanelType;
  56. if (widget.widgetType == 'GroupTree') {
  57. this._groupTree = widget;
  58. connect(this._groupTree, 'grpDrilldown', partial(signal, this, 'grpDrilldown'));
  59. connect(this._groupTree, 'grpNodeRetrieveChildren', partial(signal, this, 'grpNodeRetrieveChildren'));
  60. connect(this._groupTree, 'grpNodeCollapse', partial(signal, this, 'grpNodeCollapse'));
  61. connect(this._groupTree, 'grpNodeExpand', partial(signal, this, 'grpNodeExpand'));
  62. if (this.initialViewType == Type.GroupTree) {
  63. this._selectedChild = widget;
  64. }
  65. }
  66. else if (widget.widgetType == 'ParameterPanel') {
  67. this._paramPanel = widget;
  68. if (this.initialViewType == Type.ParameterPanel) {
  69. this._selectedChild = widget;
  70. }
  71. }
  72. this._children.push(widget);
  73. };
  74. bobj.crv.ToolPanel.setView = function(panelType) {
  75. if (this._selectedChild) {
  76. bobj.getContainer(this._selectedChild).style.display = 'none';
  77. }
  78. var Type = bobj.crv.ToolPanelType;
  79. if (Type.GroupTree == panelType) {
  80. this._selectedChild = this._groupTree;
  81. }
  82. else if (Type.ParameterPanel == panelType) {
  83. this._selectedChild = this._paramPanel;
  84. }
  85. else {
  86. this._selectedChild = null;
  87. }
  88. var container = bobj.getContainer(this._selectedChild);
  89. if (container) {
  90. container.style.display = '';
  91. }
  92. this._doLayout();
  93. };
  94. bobj.crv.ToolPanel.getHTML = function() {
  95. var h = bobj.html;
  96. var content = '';
  97. var children = this._children;
  98. for (var i = 0, len = children.length; i < len; ++i) {
  99. var child = children[i];
  100. var display = child === this._selectedChild ? '' : 'none';
  101. content += h.DIV({style:{display:display}}, child.getHTML());
  102. }
  103. var isDisplayed = (bobj.crv.ToolPanelType.None !== this.initialViewType);
  104. var layerAtt = {
  105. id: this.id,
  106. 'class': 'palette',
  107. style: {
  108. position : 'absolute',
  109. margin: '0',
  110. width: this.width,
  111. height: this.height,
  112. overflow: 'hidden',
  113. display: isDisplayed ? '' : 'none'
  114. }
  115. };
  116. var html = h.DIV(layerAtt, content);
  117. return html + bobj.crv.getInitHTML(this.widx);
  118. };
  119. bobj.crv.ToolPanel.init = function() {
  120. this.initOld();
  121. var children = this._children;
  122. for (var i = 0, len = children.length; i < len; ++i) {
  123. children[i].init();
  124. }
  125. };
  126. bobj.crv.ToolPanel.update = function(update, updatePack) {
  127. if(update && update.cons == "bobj.crv.newToolPanel") {
  128. for(var childVar in update.children) {
  129. var child = update.children[childVar];
  130. if(child) {
  131. switch(child.cons) {
  132. case "bobj.crv.newGroupTree":
  133. if(this._groupTree && updatePack.updateGroupTree()) {
  134. this._groupTree.update(child, updatePack);
  135. }
  136. break;
  137. case "bobj.crv.newParameterPanel":
  138. break; // will update parameter panel
  139. }
  140. }
  141. }
  142. }
  143. };
  144. bobj.crv.ToolPanel._doLayout = function() {
  145. var innerWidth = this.layer.clientWidth;
  146. var contentHeight = this.layer.clientHeight;
  147. if (this._selectedChild) {
  148. this._selectedChild.setDisplay(true);
  149. this._selectedChild.resize(innerWidth, contentHeight);
  150. }
  151. };
  152. bobj.crv.ToolPanel.resize = function(w, h) {
  153. bobj.setOuterSize(this.layer, w, h);
  154. this._doLayout();
  155. MochiKit.Signal.signal(this, 'resize', this.layer.offsetWidth, this.layer.offsetHeight);
  156. };
  157. bobj.crv.ToolPanel.getParameterPanel = function() {
  158. return this._paramPanel;
  159. };
  160. /*
  161. ================================================================================
  162. GroupTree
  163. ================================================================================
  164. */
  165. /**
  166. * GroupTree constructor.
  167. *
  168. * @param kwArgs.id [String] DOM node id
  169. * @param kwArgs.icns [String] URL to magnifying glass icon
  170. * @param kwArgs.minIcon [String] URL to min.gif
  171. * @param kwArgs.plusIcon [String] URL to plus.gif
  172. */
  173. bobj.crv.newGroupTree = function(kwArgs) {
  174. var UPDATE = MochiKit.Base.update;
  175. kwArgs = UPDATE({
  176. id: bobj.uniqueId(),
  177. visualStyle : {
  178. className : null,
  179. backgroundColor : null,
  180. borderWidth : null,
  181. borderStyle : null,
  182. borderColor : null,
  183. fontFamily : null,
  184. fontWeight : null,
  185. textDecoration : null,
  186. color : null,
  187. width : null,
  188. height : null,
  189. fontStyle : null,
  190. fontSize : null
  191. },
  192. icns : bobj.crvUri('images/magnify.gif'),
  193. minIcon : bobj.crvUri('images/min.gif'),
  194. plusIcon : bobj.crvUri('images/plus.gif')
  195. }, kwArgs);
  196. var o = newTreeWidget( kwArgs.id + '_tree',
  197. '100%',
  198. '100%',
  199. kwArgs.icns, null, null, null,
  200. bobj.crv.GroupTree._expand,
  201. bobj.crv.GroupTree._collapse,
  202. null,
  203. kwArgs.minIcon, kwArgs.plusIcon);
  204. o._children = [];
  205. bobj.fillIn(o, kwArgs);
  206. o.widgetType = 'GroupTree';
  207. o.initOld = o.init;
  208. UPDATE(o, bobj.crv.GroupTree);
  209. return o;
  210. };
  211. /**
  212. * Adds a child widget as a group tree node.
  213. *
  214. * @param widget [Widget] Child tree node widget
  215. */
  216. bobj.crv.GroupTree.addChild = function(widget) {
  217. var CONNECT = MochiKit.Signal.connect;
  218. widget.expandPath = this._children.length + '';
  219. this._children.push(widget);
  220. widget._updateProperty(this.enableDrilldown, this.enableNavigation);
  221. this.add(widget);
  222. widget.delayedAddChild(this.enableDrilldown, this.enableNavigation);
  223. CONNECT(widget, 'grpDrilldown', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'grpDrilldown'));
  224. CONNECT(widget, 'grpNodeRetrieveChildren', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'grpNodeRetrieveChildren'));
  225. };
  226. bobj.crv.GroupTree.init = function() {
  227. this.initOld();
  228. bobj.setVisualStyle(this.layer,this.visualStyle);
  229. var children = this._children;
  230. for (var i = 0, len = children.length; i < len; i++) {
  231. children[i].init();
  232. }
  233. };
  234. bobj.crv.GroupTree.update = function(update, updatePack) {
  235. if(update && updatePack) {
  236. var updatePath = updatePack.groupTreePath();
  237. if(updatePath.length > 0) {
  238. var pathArray = updatePath.split('-');
  239. var updateNode = update;
  240. var treeNode = this;
  241. for(var i = 0,end = pathArray.length; i < end; i++) {
  242. if(updateNode && treeNode) {
  243. updateNode = updateNode.children[0];
  244. treeNode = treeNode._children[parseInt(pathArray[i])];
  245. }
  246. }
  247. if(updateNode && treeNode && updateNode.args.groupPath == treeNode.groupPath) {
  248. if(treeNode._children && treeNode._children.length == 0) { // Only add children if they were not previously added
  249. this.updateNode(updateNode,treeNode);
  250. treeNode.delayedAddChild(update.args.enableDrilldown, update.args.enableNavigation);
  251. }
  252. treeNode.expand();
  253. }
  254. }
  255. }
  256. };
  257. bobj.crv.GroupTree.updateNode = function(updateNode, treeNode) {
  258. if(updateNode && treeNode) {
  259. for(var nodeNum in updateNode.children) {
  260. var node = bobj.crv.createWidget(updateNode.children[nodeNum]);
  261. treeNode.addChild(node);
  262. }
  263. }
  264. };
  265. /**
  266. * Private. Callback function when a (complete) group tree node is collapsed.
  267. */
  268. bobj.crv.GroupTree._collapse = function(expandPath) {
  269. MochiKit.Signal.signal(this, 'grpNodeCollapse', expandPath);
  270. };
  271. /**
  272. * Private. Callback function when a (complete) group tree node is expanded.
  273. */
  274. bobj.crv.GroupTree._expand = function(expandPath) {
  275. MochiKit.Signal.signal(this, 'grpNodeExpand', expandPath);
  276. };
  277. bobj.crv.GroupTree.resize = function(width, height) {
  278. bobj.setOuterSize(this.layer,width,height);
  279. };
  280. /**
  281. * GroupTreeNode constructor.
  282. *
  283. * @param kwArgs.id [String] DOM node id
  284. * @param kwArgs.groupName [String] Name of the group
  285. * @param kwArgs.groupPath [String] Path of the group
  286. */
  287. bobj.crv.newGroupTreeNode = function(kwArgs) {
  288. var UPDATE = MochiKit.Base.update;
  289. kwArgs = UPDATE({id: bobj.uniqueId()}, kwArgs);
  290. var iconAlt = null;
  291. var iconId = -1; // by default, no icon
  292. if (!kwArgs.isVisible) {
  293. iconId = 0;
  294. iconAlt = L_bobj_crv_Tree_Drilldown_Node.replace('%1', kwArgs.groupName);
  295. }
  296. var o = newTreeWidgetElem(iconId, kwArgs.groupName, kwArgs.groupPath, null, null, null, iconAlt);
  297. o._children = [];
  298. bobj.fillIn(o, kwArgs);
  299. o.widgetType = 'GroupTreeNode';
  300. o.initOld = o.init;
  301. o.selectOld = o.select;
  302. o.select = bobj.crv.GroupTreeNode._drilldown;
  303. UPDATE(o, bobj.crv.GroupTreeNode);
  304. return o;
  305. };
  306. bobj.crv.GroupTreeNode.init = function() {
  307. this.initOld();
  308. this._setVisualStyle();
  309. if (this.isStatic) {
  310. //"treeNormal" is the default css class for tree node text
  311. var spans = MochiKit.DOM.getElementsByTagAndClassName("span", "treeNormal", this.layer);
  312. if (spans && spans.length > 0) {
  313. spans[0].style.cursor = 'text';
  314. }
  315. }
  316. };
  317. bobj.crv.GroupTreeNode.expand = function() {
  318. var elemId = TreeIdToIdx(this.layer);
  319. _TreeWidgetElemInstances[elemId].expanded = false
  320. TreeWidget_toggleCB(elemId);
  321. };
  322. bobj.crv.GroupTreeNode.collapse = function() {
  323. var elemId = TreeIdToIdx(this.layer);
  324. _TreeWidgetElemInstances[elemId].expanded = true
  325. TreeWidget_toggleCB(elemId);
  326. };
  327. bobj.crv.GroupTreeNode._setVisualStyle = function () {
  328. try{
  329. var textNode = this.layer.lastChild;
  330. var parentNode = this.treeView;
  331. }
  332. catch(err){
  333. return;
  334. }
  335. var pvStyle = parentNode.visualStyle;
  336. var tStyle = textNode.style;
  337. if(pvStyle.fontFamily) {
  338. tStyle.fontFamily = pvStyle.fontFamily;
  339. }
  340. if(pvStyle.fontWeight) {
  341. tStyle.fontWeight = pvStyle.fontWeight;
  342. }
  343. if(pvStyle.textDecoration) {
  344. tStyle.textDecoration = pvStyle.textDecoration;
  345. }
  346. if(pvStyle.color) {
  347. tStyle.color = pvStyle.color;
  348. }
  349. if(pvStyle.fontStyle) {
  350. tStyle.fontStyle = pvStyle.fontStyle;
  351. }
  352. if(pvStyle.fontSize) {
  353. tStyle.fontSize = pvStyle.fontSize;
  354. }
  355. };
  356. /**
  357. * Delay add the child nodes to a node recursively.
  358. * The addition of nodes has to happen in a top-down fashion because each node has a reference to the tree
  359. * and this reference is retrieved from the parent node.
  360. */
  361. bobj.crv.GroupTreeNode.delayedAddChild = function(enableDrilldown, enableNavigation) {
  362. var CONNECT = MochiKit.Signal.connect;
  363. var SIGNAL = MochiKit.Signal.signal;
  364. var PARTIAL = MochiKit.Base.partial;
  365. var childCount = this._children.length;
  366. if (childCount > 0) {
  367. this.expanded = true;
  368. }
  369. else {
  370. this.expanded = false;
  371. if (!this.leaf) {
  372. this.setIncomplete(bobj.crv.GroupTreeNode._getChildren);
  373. }
  374. }
  375. var children = this._children;
  376. for (var i = 0; i < childCount; i++) {
  377. var childNode = children[i];
  378. childNode.expandPath = this.expandPath + '-' + i;
  379. childNode._updateProperty(enableDrilldown, enableNavigation);
  380. this.add(childNode);
  381. CONNECT(childNode, 'grpDrilldown', PARTIAL(SIGNAL, this, 'grpDrilldown'));
  382. CONNECT(childNode, 'grpNodeRetrieveChildren', PARTIAL(SIGNAL, this, 'grpNodeRetrieveChildren'));
  383. childNode.delayedAddChild(enableDrilldown, enableNavigation);
  384. }
  385. };
  386. bobj.crv.GroupTreeNode.addChild = function(widget) {
  387. this._children.push(widget);
  388. };
  389. /**
  390. * Private. Callback function when a group tree node is clicked, which is a group drilldown.
  391. */
  392. bobj.crv.GroupTreeNode._drilldown = function() {
  393. this.selectOld();
  394. MochiKit.Signal.signal(this, 'grpDrilldown', this.groupName, this.groupPath, this.isVisible);
  395. };
  396. /**
  397. * Private. Callback function when an incomplete group tree node is expanded.
  398. */
  399. bobj.crv.GroupTreeNode._getChildren = function() {
  400. this.plusLyr.src = _skin + '../loading.gif';
  401. MochiKit.Signal.signal(this, 'grpNodeRetrieveChildren', this.expandPath);
  402. };
  403. /**
  404. * Private. Change the select event handler and text style class based on the two given flags.
  405. */
  406. bobj.crv.GroupTreeNode._updateProperty = function (enableDrilldown, enableNavigation) {
  407. var isStatic = false;
  408. if (this.isVisible && !enableNavigation) {
  409. isStatic = true;
  410. }
  411. else if (!this.isVisible && !enableDrilldown) {
  412. isStatic = true;
  413. }
  414. if (isStatic) {
  415. this.select = function() {};
  416. }
  417. this.isStatic = isStatic;
  418. };