ButtonEditor.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /* ButtonEditor.cpp
  2. *
  3. * Copyright (C) 1996-2011,2013,2014,2015,2017 Paul Boersma
  4. *
  5. * This code is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This code is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. * See the GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this work. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "ButtonEditor.h"
  19. #include "praatP.h"
  20. #include "praat_script.h"
  21. #include "EditorM.h"
  22. #include "machine.h"
  23. Thing_implement (ButtonEditor, HyperPage, 0);
  24. #if defined (_WIN32)
  25. #define BUTTON_WIDTH 72
  26. #elif defined (macintosh)
  27. #define BUTTON_WIDTH 72
  28. #else
  29. #define BUTTON_WIDTH 96
  30. #endif
  31. static void drawMenuCommand (ButtonEditor me, Praat_Command cmd, integer i) {
  32. static MelderString text { };
  33. bool isAdded = cmd -> uniqueID != 0 || !! cmd -> script;
  34. bool isHidden = cmd -> hidden;
  35. bool isToggled = cmd -> toggled;
  36. conststring32 clickText = isHidden ? (isToggled ? (isAdded ? U"REMOVED" : U"HIDDEN") : U"hidden") :
  37. (isToggled ? U"SHOWN" : (isAdded ? (cmd -> uniqueID ? U"ADDED" : U"START-UP") : U"shown"));
  38. MelderString_empty (& text);
  39. if (cmd -> unhidable) {
  40. MelderString_append (& text, U"#unhidable ");
  41. } else {
  42. MelderString_append (& text, U"@@m", i, U"|", clickText, U"@ ");
  43. }
  44. MelderString_append (& text, cmd -> window.get(), U": ");
  45. if (cmd -> menu) {
  46. MelderString_append (& text, cmd -> menu.get(), U": ");
  47. }
  48. if (cmd -> title) {
  49. if (cmd -> executable) {
  50. MelderString_append (& text, U"@@p", i, U"|", cmd -> title.get(), U"@");
  51. } else {
  52. MelderString_append (& text, cmd -> title.get());
  53. }
  54. } else {
  55. MelderString_append (& text, U"---------");
  56. }
  57. if (cmd -> after) {
  58. MelderString_append (& text, U", %%%%after \"", cmd -> after.get(), U"\"%%");
  59. }
  60. if (cmd -> script) {
  61. MelderString_append (& text, U", script \"", Melder_peekExpandBackslashes (cmd -> script.get()), U"\"");
  62. }
  63. HyperPage_any (me, text.string, my p_font, my p_fontSize, cmd -> callback ? 0 : Graphics_ITALIC, 0.0,
  64. cmd -> depth * 0.3, 0.4, 0.0, 0.0, 0);
  65. }
  66. static void drawAction (ButtonEditor me, Praat_Command cmd, integer i) {
  67. static MelderString text { };
  68. bool isAdded = cmd -> uniqueID != 0 || !! cmd -> script;
  69. bool isHidden = cmd -> hidden, isToggled = cmd -> toggled;
  70. conststring32 clickText = isHidden ? (isToggled ? (isAdded ? U"REMOVED" : U"HIDDEN") : U"hidden") :
  71. (isToggled ? U"SHOWN" : (isAdded ? (cmd -> uniqueID ? U"ADDED" : U"START-UP") : U"shown"));
  72. int n1 = cmd -> n1;
  73. MelderString_empty (& text);
  74. if (cmd -> class4) {
  75. MelderString_append (& text, U"#unhidable ");
  76. } else {
  77. MelderString_append (& text, U"@@a", i, U"|", clickText, U"@ ");
  78. }
  79. MelderString_append (& text, cmd -> class1 -> className);
  80. if (n1) {
  81. MelderString_append (& text, U" (", n1, U")");
  82. }
  83. if (cmd -> class2) {
  84. int n2 = cmd -> n2;
  85. MelderString_append (& text, U" & ", cmd -> class2 -> className);
  86. if (n2) {
  87. MelderString_append (& text, U" (", n2, U")");
  88. }
  89. }
  90. if (cmd -> class3) {
  91. int n3 = cmd -> n3;
  92. MelderString_append (& text, U" & ", cmd -> class3 -> className);
  93. if (n3) {
  94. MelderString_append (& text, U" (", n3, U")");
  95. }
  96. }
  97. if (cmd -> class4) {
  98. int n4 = cmd -> n4;
  99. MelderString_append (& text, U" & ", cmd -> class4 -> className);
  100. if (n4) {
  101. MelderString_append (& text, U" (", n4, U")");
  102. }
  103. }
  104. MelderString_append (& text, U": ");
  105. if (cmd -> title) {
  106. if (cmd -> executable) {
  107. MelderString_append (& text, U"@@e", i, U"|", cmd -> title.get(), U"@");
  108. } else {
  109. MelderString_append (& text, cmd -> title.get());
  110. }
  111. } else {
  112. MelderString_append (& text, U"---------");
  113. }
  114. if (cmd -> after) {
  115. MelderString_append (& text, U", %%%%after \"", cmd -> after.get(), U"\"%%");
  116. }
  117. if (cmd -> script) {
  118. MelderString_append (& text, U", script \"", Melder_peekExpandBackslashes (cmd -> script.get()), U"\"");
  119. }
  120. HyperPage_any (me, text.string, my p_font, my p_fontSize, cmd -> callback ? 0 : Graphics_ITALIC, 0.0,
  121. cmd -> depth * 0.3, 0.4, 0.0, 0.0, 0);
  122. }
  123. void structButtonEditor :: v_draw () {
  124. Graphics_clearWs (our graphics.get());
  125. switch (show) {
  126. case 1:
  127. for (integer i = 1, n = praat_getNumberOfMenuCommands (); i <= n; i ++) {
  128. Praat_Command cmd = praat_getMenuCommand (i);
  129. if (str32equ (cmd -> window.get(), U"Objects"))
  130. drawMenuCommand (this, praat_getMenuCommand (i), i);
  131. }
  132. break;
  133. case 2:
  134. for (integer i = 1, n = praat_getNumberOfMenuCommands (); i <= n; i ++) {
  135. Praat_Command cmd = praat_getMenuCommand (i);
  136. if (str32equ (cmd -> window.get(), U"Picture"))
  137. drawMenuCommand (this, praat_getMenuCommand (i), i);
  138. }
  139. break;
  140. case 3:
  141. for (integer i = 1, n = praat_getNumberOfMenuCommands (); i <= n; i ++) {
  142. Praat_Command cmd = praat_getMenuCommand (i);
  143. if (! str32equ (cmd -> window.get(), U"Objects") && ! str32equ (cmd -> window.get(), U"Picture"))
  144. drawMenuCommand (this, praat_getMenuCommand (i), i);
  145. }
  146. break;
  147. case 4:
  148. for (integer i = 1, n = praat_getNumberOfActions (); i <= n; i ++) {
  149. Praat_Command cmd = praat_getAction (i);
  150. conststring32 klas = cmd -> class1 -> className;
  151. if (str32cmp (klas, U"N") < 0)
  152. drawAction (this, praat_getAction (i), i);
  153. }
  154. break;
  155. case 5:
  156. for (integer i = 1, n = praat_getNumberOfActions (); i <= n; i ++) {
  157. Praat_Command cmd = praat_getAction (i);
  158. conststring32 klas = cmd -> class1 -> className;
  159. if (str32cmp (klas, U"N") >= 0)
  160. drawAction (this, praat_getAction (i), i);
  161. }
  162. break;
  163. }
  164. }
  165. int structButtonEditor :: v_goToPage (conststring32 title) {
  166. if (! title || ! title [0]) return 0;
  167. if (str32equ (title, U"Buttons")) return 1;
  168. switch (title [0]) {
  169. case 'a': { // toggle visibility of action
  170. integer i = Melder_atoi (& title [1]);
  171. Praat_Command action = praat_getAction (i);
  172. if (! action) return 0;
  173. if (action -> hidden)
  174. praat_showAction (action -> class1, action -> class2, action -> class3, action -> title.get());
  175. else
  176. praat_hideAction (action -> class1, action -> class2, action -> class3, action -> title.get());
  177. } break;
  178. case 'm': { // toggle visibility of menu command
  179. integer i = Melder_atoi (& title [1]);
  180. Praat_Command menuCommand = praat_getMenuCommand (i);
  181. if (! menuCommand) return 0;
  182. if (menuCommand -> hidden)
  183. praat_showMenuCommand (menuCommand -> window.get(), menuCommand -> menu.get(), menuCommand -> title.get());
  184. else
  185. praat_hideMenuCommand (menuCommand -> window.get(), menuCommand -> menu.get(), menuCommand -> title.get());
  186. } break;
  187. case 'e': { // execute action
  188. integer i = Melder_atoi (& title [1]);
  189. Praat_Command action = praat_getAction (i);
  190. if (! action || ! action -> callback) return 0;
  191. if (action -> title) {
  192. UiHistory_write (U"\n");
  193. UiHistory_write_colonize (action -> title.get());
  194. }
  195. if (action -> script) {
  196. try {
  197. DO_RunTheScriptFromAnyAddedMenuCommand (nullptr, 0, nullptr, action -> script.get(), nullptr, nullptr, false, nullptr);
  198. } catch (MelderError) {
  199. Melder_flushError (U"Command not executed.");
  200. }
  201. } else {
  202. try {
  203. action -> callback (nullptr, 0, nullptr, nullptr, nullptr, nullptr, false, nullptr);
  204. } catch (MelderError) {
  205. Melder_flushError (U"Command not executed.");
  206. }
  207. }
  208. praat_updateSelection ();
  209. } break;
  210. case 'p': { // perform menu command
  211. integer i = Melder_atoi (& title [1]);
  212. Praat_Command menuCommand = praat_getMenuCommand (i);
  213. if (! menuCommand || ! menuCommand -> callback) return 0;
  214. if (menuCommand -> title) {
  215. UiHistory_write (U"\n");
  216. UiHistory_write_colonize (menuCommand -> title.get());
  217. }
  218. if (menuCommand -> script) {
  219. try {
  220. DO_RunTheScriptFromAnyAddedMenuCommand (nullptr, 0, nullptr, menuCommand -> script.get(), nullptr, nullptr, false, nullptr);
  221. } catch (MelderError) {
  222. Melder_flushError (U"Command not executed.");
  223. }
  224. } else {
  225. try {
  226. menuCommand -> callback (nullptr, 0, nullptr, nullptr, nullptr, nullptr, false, nullptr);
  227. } catch (MelderError) {
  228. Melder_flushError (U"Command not executed.");
  229. }
  230. }
  231. praat_updateSelection ();
  232. } break;
  233. default: break;
  234. }
  235. return 0;
  236. }
  237. static void which (ButtonEditor me, int show) {
  238. my show = show;
  239. GuiRadioButton_set (show == 1 ? my button1 : show == 2 ? my button2 : show == 3 ? my button3 : show == 4 ? my button4 : my button5);
  240. HyperPage_goToPage (me, U"Buttons");
  241. }
  242. static void gui_radiobutton_cb_objects (ButtonEditor me, GuiRadioButtonEvent /* event */) { which (me, 1); }
  243. static void gui_radiobutton_cb_picture (ButtonEditor me, GuiRadioButtonEvent /* event */) { which (me, 2); }
  244. static void gui_radiobutton_cb_editors (ButtonEditor me, GuiRadioButtonEvent /* event */) { which (me, 3); }
  245. static void gui_radiobutton_cb_actionsAM (ButtonEditor me, GuiRadioButtonEvent /* event */) { which (me, 4); }
  246. static void gui_radiobutton_cb_actionsNZ (ButtonEditor me, GuiRadioButtonEvent /* event */) { which (me, 5); }
  247. void structButtonEditor :: v_createChildren () {
  248. ButtonEditor_Parent :: v_createChildren ();
  249. int x = 3, y = Machine_getMenuBarHeight () + 4;
  250. GuiRadioGroup_begin ();
  251. button1 = GuiRadioButton_createShown (our windowForm, x, x + BUTTON_WIDTH, y, y + Gui_RADIOBUTTON_HEIGHT,
  252. U"Objects", gui_radiobutton_cb_objects, this, GuiRadioButton_SET);
  253. x += BUTTON_WIDTH + 5;
  254. button2 = GuiRadioButton_createShown (our windowForm, x, x + BUTTON_WIDTH, y, y + Gui_RADIOBUTTON_HEIGHT,
  255. U"Picture", gui_radiobutton_cb_picture, this, 0);
  256. x += BUTTON_WIDTH + 5;
  257. button3 = GuiRadioButton_createShown (our windowForm, x, x + BUTTON_WIDTH, y, y + Gui_RADIOBUTTON_HEIGHT,
  258. U"Editors", gui_radiobutton_cb_editors, this, 0);
  259. x += BUTTON_WIDTH + 5;
  260. button4 = GuiRadioButton_createShown (our windowForm, x, x + BUTTON_WIDTH + 30, y, y + Gui_RADIOBUTTON_HEIGHT,
  261. U"Actions A-M", gui_radiobutton_cb_actionsAM, this, 0);
  262. x += BUTTON_WIDTH + 35;
  263. button5 = GuiRadioButton_createShown (our windowForm, x, x + BUTTON_WIDTH + 30, y, y + Gui_RADIOBUTTON_HEIGHT,
  264. U"Actions N-Z", gui_radiobutton_cb_actionsNZ, this, 0);
  265. GuiRadioGroup_end ();
  266. }
  267. static void menu_cb_ButtonEditorHelp (ButtonEditor /* me */, EDITOR_ARGS_DIRECT) { Melder_help (U"ButtonEditor"); }
  268. void structButtonEditor :: v_createHelpMenuItems (EditorMenu menu) {
  269. ButtonEditor_Parent :: v_createHelpMenuItems (menu);
  270. EditorMenu_addCommand (menu, U"ButtonEditor help", '?', menu_cb_ButtonEditorHelp);
  271. }
  272. autoButtonEditor ButtonEditor_create () {
  273. try {
  274. autoButtonEditor me = Thing_new (ButtonEditor);
  275. HyperPage_init (me.get(), U"Buttons", nullptr);
  276. which (me.get(), 1);
  277. return me;
  278. } catch (MelderError) {
  279. Melder_throw (U"Buttons window not created.");
  280. }
  281. }
  282. /* End of file ButtonEditor.cpp */