mxToolbar.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. /**
  2. * Copyright (c) 2006-2015, JGraph Ltd
  3. * Copyright (c) 2006-2015, Gaudenz Alder
  4. */
  5. /**
  6. * Class: mxToolbar
  7. *
  8. * Creates a toolbar inside a given DOM node. The toolbar may contain icons,
  9. * buttons and combo boxes.
  10. *
  11. * Event: mxEvent.SELECT
  12. *
  13. * Fires when an item was selected in the toolbar. The <code>function</code>
  14. * property contains the function that was selected in <selectMode>.
  15. *
  16. * Constructor: mxToolbar
  17. *
  18. * Constructs a toolbar in the specified container.
  19. *
  20. * Parameters:
  21. *
  22. * container - DOM node that contains the toolbar.
  23. */
  24. function mxToolbar(container)
  25. {
  26. this.container = container;
  27. };
  28. /**
  29. * Extends mxEventSource.
  30. */
  31. mxToolbar.prototype = new mxEventSource();
  32. mxToolbar.prototype.constructor = mxToolbar;
  33. /**
  34. * Variable: container
  35. *
  36. * Reference to the DOM nodes that contains the toolbar.
  37. */
  38. mxToolbar.prototype.container = null;
  39. /**
  40. * Variable: enabled
  41. *
  42. * Specifies if events are handled. Default is true.
  43. */
  44. mxToolbar.prototype.enabled = true;
  45. /**
  46. * Variable: noReset
  47. *
  48. * Specifies if <resetMode> requires a forced flag of true for resetting
  49. * the current mode in the toolbar. Default is false. This is set to true
  50. * if the toolbar item is double clicked to avoid a reset after a single
  51. * use of the item.
  52. */
  53. mxToolbar.prototype.noReset = false;
  54. /**
  55. * Variable: updateDefaultMode
  56. *
  57. * Boolean indicating if the default mode should be the last selected
  58. * switch mode or the first inserted switch mode. Default is true, that
  59. * is the last selected switch mode is the default mode. The default mode
  60. * is the mode to be selected after a reset of the toolbar. If this is
  61. * false, then the default mode is the first inserted mode item regardless
  62. * of what was last selected. Otherwise, the selected item after a reset is
  63. * the previously selected item.
  64. */
  65. mxToolbar.prototype.updateDefaultMode = true;
  66. /**
  67. * Function: addItem
  68. *
  69. * Adds the given function as an image with the specified title and icon
  70. * and returns the new image node.
  71. *
  72. * Parameters:
  73. *
  74. * title - Optional string that is used as the tooltip.
  75. * icon - Optional URL of the image to be used. If no URL is given, then a
  76. * button is created.
  77. * funct - Function to execute on a mouse click.
  78. * pressedIcon - Optional URL of the pressed image. Default is a gray
  79. * background.
  80. * style - Optional style classname. Default is mxToolbarItem.
  81. * factoryMethod - Optional factory method for popup menu, eg.
  82. * function(menu, evt, cell) { menu.addItem('Hello, World!'); }
  83. */
  84. mxToolbar.prototype.addItem = function(title, icon, funct, pressedIcon, style, factoryMethod)
  85. {
  86. var img = document.createElement((icon != null) ? 'img' : 'button');
  87. var initialClassName = style || ((factoryMethod != null) ?
  88. 'mxToolbarMode' : 'mxToolbarItem');
  89. img.className = initialClassName;
  90. img.setAttribute('src', icon);
  91. if (title != null)
  92. {
  93. if (icon != null)
  94. {
  95. img.setAttribute('title', title);
  96. }
  97. else
  98. {
  99. mxUtils.write(img, title);
  100. }
  101. }
  102. this.container.appendChild(img);
  103. // Invokes the function on a click on the toolbar item
  104. if (funct != null)
  105. {
  106. mxEvent.addListener(img, 'click', funct);
  107. if (mxClient.IS_TOUCH)
  108. {
  109. mxEvent.addListener(img, 'touchend', funct);
  110. }
  111. }
  112. var mouseHandler = mxUtils.bind(this, function(evt)
  113. {
  114. if (pressedIcon != null)
  115. {
  116. img.setAttribute('src', icon);
  117. }
  118. else
  119. {
  120. img.style.backgroundColor = '';
  121. }
  122. });
  123. // Highlights the toolbar item with a gray background
  124. // while it is being clicked with the mouse
  125. mxEvent.addGestureListeners(img, mxUtils.bind(this, function(evt)
  126. {
  127. if (pressedIcon != null)
  128. {
  129. img.setAttribute('src', pressedIcon);
  130. }
  131. else
  132. {
  133. img.style.backgroundColor = 'gray';
  134. }
  135. // Popup Menu
  136. if (factoryMethod != null)
  137. {
  138. if (this.menu == null)
  139. {
  140. this.menu = new mxPopupMenu();
  141. this.menu.init();
  142. }
  143. var last = this.currentImg;
  144. if (this.menu.isMenuShowing())
  145. {
  146. this.menu.hideMenu();
  147. }
  148. if (last != img)
  149. {
  150. // Redirects factory method to local factory method
  151. this.currentImg = img;
  152. this.menu.factoryMethod = factoryMethod;
  153. var point = new mxPoint(
  154. img.offsetLeft,
  155. img.offsetTop + img.offsetHeight);
  156. this.menu.popup(point.x, point.y, null, evt);
  157. // Sets and overrides to restore classname
  158. if (this.menu.isMenuShowing())
  159. {
  160. img.className = initialClassName + 'Selected';
  161. this.menu.hideMenu = function()
  162. {
  163. mxPopupMenu.prototype.hideMenu.apply(this);
  164. img.className = initialClassName;
  165. this.currentImg = null;
  166. };
  167. }
  168. }
  169. }
  170. }), null, mouseHandler);
  171. mxEvent.addListener(img, 'mouseout', mouseHandler);
  172. return img;
  173. };
  174. /**
  175. * Function: addCombo
  176. *
  177. * Adds and returns a new SELECT element using the given style. The element
  178. * is placed inside a DIV with the mxToolbarComboContainer style classname.
  179. *
  180. * Parameters:
  181. *
  182. * style - Optional style classname. Default is mxToolbarCombo.
  183. */
  184. mxToolbar.prototype.addCombo = function(style)
  185. {
  186. var div = document.createElement('div');
  187. div.style.display = 'inline';
  188. div.className = 'mxToolbarComboContainer';
  189. var select = document.createElement('select');
  190. select.className = style || 'mxToolbarCombo';
  191. div.appendChild(select);
  192. this.container.appendChild(div);
  193. return select;
  194. };
  195. /**
  196. * Function: addActionCombo
  197. *
  198. * Adds and returns a new SELECT element using the given title as the
  199. * default element. The selection is reset to this element after each
  200. * change.
  201. *
  202. * Parameters:
  203. *
  204. * title - String that specifies the title of the default element.
  205. * style - Optional style classname. Default is mxToolbarCombo.
  206. */
  207. mxToolbar.prototype.addActionCombo = function(title, style)
  208. {
  209. var select = document.createElement('select');
  210. select.className = style || 'mxToolbarCombo';
  211. this.addOption(select, title, null);
  212. mxEvent.addListener(select, 'change', function(evt)
  213. {
  214. var value = select.options[select.selectedIndex];
  215. select.selectedIndex = 0;
  216. if (value.funct != null)
  217. {
  218. value.funct(evt);
  219. }
  220. });
  221. this.container.appendChild(select);
  222. return select;
  223. };
  224. /**
  225. * Function: addOption
  226. *
  227. * Adds and returns a new OPTION element inside the given SELECT element.
  228. * If the given value is a function then it is stored in the option's funct
  229. * field.
  230. *
  231. * Parameters:
  232. *
  233. * combo - SELECT element that will contain the new entry.
  234. * title - String that specifies the title of the option.
  235. * value - Specifies the value associated with this option.
  236. */
  237. mxToolbar.prototype.addOption = function(combo, title, value)
  238. {
  239. var option = document.createElement('option');
  240. mxUtils.writeln(option, title);
  241. if (typeof(value) == 'function')
  242. {
  243. option.funct = value;
  244. }
  245. else
  246. {
  247. option.setAttribute('value', value);
  248. }
  249. combo.appendChild(option);
  250. return option;
  251. };
  252. /**
  253. * Function: addSwitchMode
  254. *
  255. * Adds a new selectable item to the toolbar. Only one switch mode item may
  256. * be selected at a time. The currently selected item is the default item
  257. * after a reset of the toolbar.
  258. */
  259. mxToolbar.prototype.addSwitchMode = function(title, icon, funct, pressedIcon, style)
  260. {
  261. var img = document.createElement('img');
  262. img.initialClassName = style || 'mxToolbarMode';
  263. img.className = img.initialClassName;
  264. img.setAttribute('src', icon);
  265. img.altIcon = pressedIcon;
  266. if (title != null)
  267. {
  268. img.setAttribute('title', title);
  269. }
  270. mxEvent.addListener(img, 'click', mxUtils.bind(this, function(evt)
  271. {
  272. var tmp = this.selectedMode.altIcon;
  273. if (tmp != null)
  274. {
  275. this.selectedMode.altIcon = this.selectedMode.getAttribute('src');
  276. this.selectedMode.setAttribute('src', tmp);
  277. }
  278. else
  279. {
  280. this.selectedMode.className = this.selectedMode.initialClassName;
  281. }
  282. if (this.updateDefaultMode)
  283. {
  284. this.defaultMode = img;
  285. }
  286. this.selectedMode = img;
  287. var tmp = img.altIcon;
  288. if (tmp != null)
  289. {
  290. img.altIcon = img.getAttribute('src');
  291. img.setAttribute('src', tmp);
  292. }
  293. else
  294. {
  295. img.className = img.initialClassName+'Selected';
  296. }
  297. this.fireEvent(new mxEventObject(mxEvent.SELECT));
  298. funct();
  299. }));
  300. this.container.appendChild(img);
  301. if (this.defaultMode == null)
  302. {
  303. this.defaultMode = img;
  304. // Function should fire only once so
  305. // do not pass it with the select event
  306. this.selectMode(img);
  307. funct();
  308. }
  309. return img;
  310. };
  311. /**
  312. * Function: addMode
  313. *
  314. * Adds a new item to the toolbar. The selection is typically reset after
  315. * the item has been consumed, for example by adding a new vertex to the
  316. * graph. The reset is not carried out if the item is double clicked.
  317. *
  318. * The function argument uses the following signature: funct(evt, cell) where
  319. * evt is the native mouse event and cell is the cell under the mouse.
  320. */
  321. mxToolbar.prototype.addMode = function(title, icon, funct, pressedIcon, style, toggle)
  322. {
  323. toggle = (toggle != null) ? toggle : true;
  324. var img = document.createElement((icon != null) ? 'img' : 'button');
  325. img.initialClassName = style || 'mxToolbarMode';
  326. img.className = img.initialClassName;
  327. img.setAttribute('src', icon);
  328. img.altIcon = pressedIcon;
  329. if (title != null)
  330. {
  331. img.setAttribute('title', title);
  332. }
  333. if (this.enabled && toggle)
  334. {
  335. mxEvent.addListener(img, 'click', mxUtils.bind(this, function(evt)
  336. {
  337. this.selectMode(img, funct);
  338. this.noReset = false;
  339. }));
  340. mxEvent.addListener(img, 'dblclick', mxUtils.bind(this, function(evt)
  341. {
  342. this.selectMode(img, funct);
  343. this.noReset = true;
  344. }));
  345. if (this.defaultMode == null)
  346. {
  347. this.defaultMode = img;
  348. this.defaultFunction = funct;
  349. this.selectMode(img, funct);
  350. }
  351. }
  352. this.container.appendChild(img);
  353. return img;
  354. };
  355. /**
  356. * Function: selectMode
  357. *
  358. * Resets the state of the previously selected mode and displays the given
  359. * DOM node as selected. This function fires a select event with the given
  360. * function as a parameter.
  361. */
  362. mxToolbar.prototype.selectMode = function(domNode, funct)
  363. {
  364. if (this.selectedMode != domNode)
  365. {
  366. if (this.selectedMode != null)
  367. {
  368. var tmp = this.selectedMode.altIcon;
  369. if (tmp != null)
  370. {
  371. this.selectedMode.altIcon = this.selectedMode.getAttribute('src');
  372. this.selectedMode.setAttribute('src', tmp);
  373. }
  374. else
  375. {
  376. this.selectedMode.className = this.selectedMode.initialClassName;
  377. }
  378. }
  379. this.selectedMode = domNode;
  380. var tmp = this.selectedMode.altIcon;
  381. if (tmp != null)
  382. {
  383. this.selectedMode.altIcon = this.selectedMode.getAttribute('src');
  384. this.selectedMode.setAttribute('src', tmp);
  385. }
  386. else
  387. {
  388. this.selectedMode.className = this.selectedMode.initialClassName+'Selected';
  389. }
  390. this.fireEvent(new mxEventObject(mxEvent.SELECT, "function", funct));
  391. }
  392. };
  393. /**
  394. * Function: resetMode
  395. *
  396. * Selects the default mode and resets the state of the previously selected
  397. * mode.
  398. */
  399. mxToolbar.prototype.resetMode = function(forced)
  400. {
  401. if ((forced || !this.noReset) && this.selectedMode != this.defaultMode)
  402. {
  403. // The last selected switch mode will be activated
  404. // so the function was already executed and is
  405. // no longer required here
  406. this.selectMode(this.defaultMode, this.defaultFunction);
  407. }
  408. };
  409. /**
  410. * Function: addSeparator
  411. *
  412. * Adds the specifies image as a separator.
  413. *
  414. * Parameters:
  415. *
  416. * icon - URL of the separator icon.
  417. */
  418. mxToolbar.prototype.addSeparator = function(icon)
  419. {
  420. return this.addItem(null, icon, null);
  421. };
  422. /**
  423. * Function: addBreak
  424. *
  425. * Adds a break to the container.
  426. */
  427. mxToolbar.prototype.addBreak = function()
  428. {
  429. mxUtils.br(this.container);
  430. };
  431. /**
  432. * Function: addLine
  433. *
  434. * Adds a horizontal line to the container.
  435. */
  436. mxToolbar.prototype.addLine = function()
  437. {
  438. var hr = document.createElement('hr');
  439. hr.style.marginRight = '6px';
  440. hr.setAttribute('size', '1');
  441. this.container.appendChild(hr);
  442. };
  443. /**
  444. * Function: destroy
  445. *
  446. * Removes the toolbar and all its associated resources.
  447. */
  448. mxToolbar.prototype.destroy = function ()
  449. {
  450. mxEvent.release(this.container);
  451. this.container = null;
  452. this.defaultMode = null;
  453. this.defaultFunction = null;
  454. this.selectedMode = null;
  455. if (this.menu != null)
  456. {
  457. this.menu.destroy();
  458. }
  459. };
  460. __mxOutput.mxToolbar = typeof mxToolbar !== 'undefined' ? mxToolbar : undefined;