Toolbar.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. /**
  2. *$id:Action 。JS,V 2017-12-19
  3. *$author shen.zhi
  4. */
  5. /**
  6. * 构建了一个新的工具栏的编辑。
  7. */
  8. function Toolbar(editorUi, container)
  9. {
  10. this.editorUi = editorUi;
  11. this.container = container;
  12. this.init();
  13. // Global handler to hide the current menu
  14. var md = (mxClient.IS_TOUCH) ? 'touchstart' : 'mousedown';
  15. mxEvent.addListener(document, md, mxUtils.bind(this, function(evt)
  16. {
  17. this.hideMenu();
  18. }));
  19. };
  20. /**
  21. * Adds the toolbar elements.
  22. */
  23. Toolbar.prototype.init = function()
  24. {
  25. this.addItems(['undo', 'redo', 'delete','refreshView', '-', 'actualSize', 'zoomIn', 'zoomOut', '-']);
  26. var fontElt = this.addMenu('Helvetica', mxResources.get('fontFamily'), true, 'fontFamily');
  27. fontElt.style.whiteSpace = 'nowrap';
  28. fontElt.style.overflow = 'hidden';
  29. fontElt.style.width = '70px';
  30. this.addSeparator();
  31. var sizeElt = this.addMenu('12', mxResources.get('fontSize'), true, 'fontSize');
  32. sizeElt.style.whiteSpace = 'nowrap';
  33. sizeElt.style.overflow = 'hidden';
  34. sizeElt.style.width = '30px';
  35. this.addItems(['-', 'bold', 'italic', 'underline']);
  36. var align = this.addMenuFunction('geSprite-left', mxResources.get('align'), false, mxUtils.bind(this, function(menu)
  37. {
  38. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ALIGN], [mxConstants.ALIGN_LEFT], 'geIcon geSprite geSprite-left', null).setAttribute('title', mxResources.get('left'));
  39. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ALIGN], [mxConstants.ALIGN_CENTER], 'geIcon geSprite geSprite-center', null).setAttribute('title', mxResources.get('center'));
  40. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ALIGN], [mxConstants.ALIGN_RIGHT], 'geIcon geSprite geSprite-right', null).setAttribute('title', mxResources.get('right'));
  41. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_VERTICAL_ALIGN], [mxConstants.ALIGN_TOP], 'geIcon geSprite geSprite-top', null).setAttribute('title', mxResources.get('top'));
  42. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_VERTICAL_ALIGN], [mxConstants.ALIGN_MIDDLE], 'geIcon geSprite geSprite-middle', null).setAttribute('title', mxResources.get('middle'));
  43. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_VERTICAL_ALIGN], [mxConstants.ALIGN_BOTTOM], 'geIcon geSprite geSprite-bottom', null).setAttribute('title', mxResources.get('bottom'));
  44. }));
  45. this.addItems(['fontColor', '-']);
  46. var line = this.addMenuFunction('geSprite-straight', mxResources.get('line'), false, mxUtils.bind(this, function(menu)
  47. {
  48. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_EDGE], [null], 'geIcon geSprite geSprite-straight', null).setAttribute('title', mxResources.get('straight'));
  49. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_EDGE], ['entityRelationEdgeStyle'], 'geIcon geSprite geSprite-entity', null).setAttribute('title', mxResources.get('entityRelation'));
  50. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_EDGE, mxConstants.STYLE_ELBOW], ['elbowEdgeStyle', 'horizontal'], 'geIcon geSprite geSprite-helbow', null).setAttribute('title', mxResources.get('horizontal'));
  51. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_EDGE, mxConstants.STYLE_ELBOW], ['elbowEdgeStyle', 'vertical'], 'geIcon geSprite geSprite-velbow', null).setAttribute('title', mxResources.get('vertical'));
  52. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_EDGE], ['segmentEdgeStyle'], 'geIcon geSprite geSprite-segment', null).setAttribute('title', mxResources.get('plain'));
  53. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_EDGE], ['orthogonalEdgeStyle'], 'geIcon geSprite geSprite-orthogonal', null).setAttribute('title', mxResources.get('orthogonal'));
  54. }));
  55. var linestart = this.addMenuFunction('geSprite-startclassic', mxResources.get('lineend'), false, mxUtils.bind(this, function(menu)
  56. {
  57. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.NONE, 0], 'geIcon geSprite geSprite-noarrow', null).setAttribute('title', mxResources.get('none'));
  58. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_CLASSIC, 1], 'geIcon geSprite geSprite-startclassic', null).setAttribute('title', mxResources.get('classic'));
  59. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_OPEN, 1], 'geIcon geSprite geSprite-startopen', null).setAttribute('title', mxResources.get('openArrow'));
  60. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_BLOCK, 1], 'geIcon geSprite geSprite-startblock', null).setAttribute('title', mxResources.get('block'));
  61. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_OVAL, 1], 'geIcon geSprite geSprite-startoval', null).setAttribute('title', mxResources.get('oval'));
  62. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_DIAMOND, 1], 'geIcon geSprite geSprite-startdiamond', null).setAttribute('title', mxResources.get('diamond'));
  63. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_DIAMOND_THIN, 1], 'geIcon geSprite geSprite-startthindiamond', null).setAttribute('title', mxResources.get('diamondThin'));
  64. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_CLASSIC, 0], 'geIcon geSprite geSprite-startclassictrans', null).setAttribute('title', mxResources.get('classic'));
  65. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_BLOCK, 0], 'geIcon geSprite geSprite-startblocktrans', null).setAttribute('title', mxResources.get('block'));
  66. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_OVAL, 0], 'geIcon geSprite geSprite-startovaltrans', null).setAttribute('title', mxResources.get('oval'));
  67. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_DIAMOND, 0], 'geIcon geSprite geSprite-startdiamondtrans', null).setAttribute('title', mxResources.get('diamond'));
  68. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_STARTARROW, 'startFill'], [mxConstants.ARROW_DIAMOND_THIN, 0], 'geIcon geSprite geSprite-startthindiamondtrans', null).setAttribute('title', mxResources.get('diamondThin'));
  69. }));
  70. var lineend = this.addMenuFunction('geSprite-endclassic', mxResources.get('lineend'), false, mxUtils.bind(this, function(menu)
  71. {
  72. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.NONE, 0], 'geIcon geSprite geSprite-noarrow', null).setAttribute('title', mxResources.get('none'));
  73. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_CLASSIC, 1], 'geIcon geSprite geSprite-endclassic', null).setAttribute('title', mxResources.get('classic'));
  74. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_OPEN, 1], 'geIcon geSprite geSprite-endopen', null).setAttribute('title', mxResources.get('openArrow'));
  75. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_BLOCK, 1], 'geIcon geSprite geSprite-endblock', null).setAttribute('title', mxResources.get('block'));
  76. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_OVAL, 1], 'geIcon geSprite geSprite-endoval', null).setAttribute('title', mxResources.get('oval'));
  77. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_DIAMOND, 1], 'geIcon geSprite geSprite-enddiamond', null).setAttribute('title', mxResources.get('diamond'));
  78. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_DIAMOND_THIN, 1], 'geIcon geSprite geSprite-endthindiamond', null).setAttribute('title', mxResources.get('diamondThin'));
  79. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_CLASSIC, 0], 'geIcon geSprite geSprite-endclassictrans', null).setAttribute('title', mxResources.get('classic'));
  80. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_BLOCK, 0], 'geIcon geSprite geSprite-endblocktrans', null).setAttribute('title', mxResources.get('block'));
  81. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_OVAL, 0], 'geIcon geSprite geSprite-endovaltrans', null).setAttribute('title', mxResources.get('oval'));
  82. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_DIAMOND, 0], 'geIcon geSprite geSprite-enddiamondtrans', null).setAttribute('title', mxResources.get('diamond'));
  83. this.editorUi.menus.styleChange(menu, '', [mxConstants.STYLE_ENDARROW, 'endFill'], [mxConstants.ARROW_DIAMOND_THIN, 0], 'geIcon geSprite geSprite-endthindiamondtrans', null).setAttribute('title', mxResources.get('diamondThin'));
  84. }));
  85. this.addItems(['-', 'strokeColor', 'image', 'fillColor']);
  86. this.addItem('geSprite-gradientcolor', 'gradientColor').setAttribute('title', mxResources.get('gradient'));
  87. this.addItems(['shadow']);
  88. var graph = this.editorUi.editor.graph;
  89. // Update font size and font family labels
  90. var update = mxUtils.bind(this, function()
  91. {
  92. var ff = 'Helvetica';
  93. var fs = '12';
  94. var state = graph.getView().getState(graph.getSelectionCell());
  95. if (state != null)
  96. {
  97. ff = state.style[mxConstants.STYLE_FONTFAMILY] || ff;
  98. fs = state.style[mxConstants.STYLE_FONTSIZE] || fs;
  99. if (ff.length > 10)
  100. {
  101. ff = ff.substring(0, 8) + '...';
  102. }
  103. fontElt.innerHTML = ff;
  104. sizeElt.innerHTML = fs;
  105. }
  106. });
  107. graph.getSelectionModel().addListener(mxEvent.CHANGE, update);
  108. graph.getModel().addListener(mxEvent.CHANGE, update);
  109. // Updates button states
  110. this.addEdgeSelectionHandler([line, linestart, lineend]);
  111. this.addSelectionHandler([align]);
  112. };
  113. /**
  114. * Hides the current menu.
  115. */
  116. Toolbar.prototype.hideMenu = function()
  117. {
  118. if (this.currentMenu != null)
  119. {
  120. this.currentMenu.hideMenu();
  121. this.currentMenu.destroy();
  122. this.currentMenu = null;
  123. }
  124. };
  125. /**
  126. * Adds a label to the toolbar.
  127. */
  128. Toolbar.prototype.addMenu = function(label, tooltip, showLabels, name)
  129. {
  130. var menu = this.editorUi.menus.get(name);
  131. var elt = this.addMenuFunction(label, tooltip, showLabels, menu.funct);
  132. menu.addListener('stateChanged', function()
  133. {
  134. elt.setEnabled(menu.enabled);
  135. });
  136. return elt;
  137. };
  138. /**
  139. * Adds a label to the toolbar.
  140. */
  141. Toolbar.prototype.addMenuFunction = function(label, tooltip, showLabels, funct)
  142. {
  143. var elt = (showLabels) ? this.createLabel(label) : this.createButton(label);
  144. this.initElement(elt, tooltip);
  145. this.addMenuHandler(elt, showLabels, funct);
  146. this.container.appendChild(elt);
  147. return elt;
  148. };
  149. /**
  150. * Adds a separator to the separator.
  151. */
  152. Toolbar.prototype.addSeparator = function()
  153. {
  154. var elt = document.createElement('div');
  155. elt.className = 'geSeparator';
  156. this.container.appendChild(elt);
  157. return elt;
  158. };
  159. /**
  160. * Adds given action item
  161. */
  162. Toolbar.prototype.addItems = function(keys)
  163. {
  164. for (var i = 0; i < keys.length; i++)
  165. {
  166. var key = keys[i];
  167. if (key == '-')
  168. {
  169. this.addSeparator();
  170. }
  171. else
  172. {
  173. this.addItem('geSprite-' + key.toLowerCase(), key);
  174. }
  175. }
  176. };
  177. /**
  178. * Adds given action item
  179. */
  180. Toolbar.prototype.addItem = function(sprite, key)
  181. {
  182. var action = this.editorUi.actions.get(key);
  183. var elt = null;
  184. if (action != null)
  185. {
  186. elt = this.addButton(sprite, action.label, action.funct);
  187. elt.setEnabled(action.enabled);
  188. action.addListener('stateChanged', function()
  189. {
  190. elt.setEnabled(action.enabled);
  191. });
  192. }
  193. return elt;
  194. };
  195. /**
  196. * Adds a button to the toolbar.
  197. */
  198. Toolbar.prototype.addButton = function(classname, tooltip, funct)
  199. {
  200. var elt = this.createButton(classname);
  201. this.initElement(elt, tooltip);
  202. this.addClickHandler(elt, funct);
  203. this.container.appendChild(elt);
  204. return elt;
  205. };
  206. /**
  207. * Updates the states of the given toolbar items based on the selection.
  208. */
  209. Toolbar.prototype.addSelectionHandler = function(items)
  210. {
  211. var graph = this.editorUi.editor.graph;
  212. var selectionListener = function()
  213. {
  214. var selected = !graph.isSelectionEmpty();
  215. for (var i = 0; i < items.length; i++)
  216. {
  217. items[i].setEnabled(selected);
  218. }
  219. };
  220. graph.getSelectionModel().addListener(mxEvent.CHANGE, selectionListener);
  221. selectionListener();
  222. };
  223. /**
  224. * Updates the states of the given toolbar items based on the selection.
  225. */
  226. Toolbar.prototype.addEdgeSelectionHandler = function(items)
  227. {
  228. var graph = this.editorUi.editor.graph;
  229. var selectionListener = function()
  230. {
  231. var edgeSelected = false;
  232. if (!graph.isSelectionEmpty())
  233. {
  234. var cells = graph.getSelectionCells();
  235. for (var i = 0; i < cells.length; i++)
  236. {
  237. if (graph.getModel().isEdge(cells[i]))
  238. {
  239. edgeSelected = true;
  240. break;
  241. }
  242. }
  243. }
  244. for (var i = 0; i < items.length; i++)
  245. {
  246. items[i].setEnabled(edgeSelected);
  247. }
  248. };
  249. graph.getSelectionModel().addListener(mxEvent.CHANGE, selectionListener);
  250. selectionListener();
  251. };
  252. /**
  253. * Initializes the given toolbar element.
  254. */
  255. Toolbar.prototype.initElement = function(elt, tooltip)
  256. {
  257. elt.setAttribute('tabindex', '0');
  258. // Adds tooltip
  259. if (tooltip != null)
  260. {
  261. elt.setAttribute('title', tooltip);
  262. }
  263. this.addEnabledState(elt);
  264. };
  265. /**
  266. * Adds enabled state with setter to DOM node (avoids JS wrapper).
  267. */
  268. Toolbar.prototype.addEnabledState = function(elt)
  269. {
  270. var classname = elt.className;
  271. elt.setEnabled = function(value)
  272. {
  273. elt.enabled = value;
  274. if (value)
  275. {
  276. elt.className = classname;
  277. }
  278. else
  279. {
  280. elt.className = classname + ' geDisabled';
  281. }
  282. };
  283. elt.setEnabled(true);
  284. };
  285. /**
  286. * Adds enabled state with setter to DOM node (avoids JS wrapper).
  287. */
  288. Toolbar.prototype.addClickHandler = function(elt, funct)
  289. {
  290. if (funct != null)
  291. {
  292. mxEvent.addListener(elt, 'click', function(evt)
  293. {
  294. if (elt.enabled)
  295. {
  296. funct(evt);
  297. }
  298. mxEvent.consume(evt);
  299. });
  300. }
  301. };
  302. /**
  303. * Creates and returns a new button.
  304. */
  305. Toolbar.prototype.createButton = function(classname)
  306. {
  307. var elt = document.createElement('a');
  308. elt.setAttribute('href', 'javascript:void(0);');
  309. elt.className = 'geButton';
  310. var inner = document.createElement('div');
  311. inner.className = 'geSprite ' + classname;
  312. elt.appendChild(inner);
  313. return elt;
  314. };
  315. /**
  316. * Creates and returns a new button.
  317. */
  318. Toolbar.prototype.createLabel = function(label, tooltip)
  319. {
  320. var elt = document.createElement('a');
  321. elt.setAttribute('href', 'javascript:void(0);');
  322. elt.className = 'geLabel';
  323. mxUtils.write(elt, label);
  324. return elt;
  325. };
  326. /**
  327. * Adds a handler for showing a menu in the given element.
  328. */
  329. Toolbar.prototype.addMenuHandler = function(elt, showLabels, funct, showAll)
  330. {
  331. if (funct != null)
  332. {
  333. var graph = this.editorUi.editor.graph;
  334. var menu = null;
  335. mxEvent.addListener(elt, 'click', mxUtils.bind(this, function(evt)
  336. {
  337. if (elt.enabled == null || elt.enabled)
  338. {
  339. graph.panningHandler.hideMenu();
  340. menu = new mxPopupMenu(funct);
  341. menu.div.className += ' geToolbarMenu';
  342. menu.showDisabled = showAll;
  343. menu.labels = showLabels;
  344. menu.autoExpand = true;
  345. menu.popup(elt.offsetLeft, elt.offsetTop + elt.offsetHeight + 34, null, evt);
  346. this.currentMenu = menu;
  347. }
  348. mxEvent.consume(evt);
  349. }));
  350. }
  351. };