iup_menu.e 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. class IUP_MENU
  2. -- Creates a menu element, which groups 3 types of interface elements: item,
  3. -- submenu and separator. Any other interface element defined inside a menu
  4. -- will be an error.
  5. --
  6. -- A menu can be a menu bar of a dialog, defined by the dialog's MENU
  7. -- attribute, or a popup menu.
  8. --
  9. -- A popup menu is displayed for the user using the popup function (usually on
  10. -- the mouse position) and disappears when an item is selected.
  11. --
  12. -- destroy should be called only for popup menus. Menu bars associated with
  13. -- dialogs are automatically destroyed when the dialog is destroyed. But if you
  14. -- change the menu of a dialog for another menu, the previous one should be
  15. -- destroyed destroy. If you replace a menu bar of a dialog, the previous menu
  16. -- is unmapped.
  17. --
  18. -- Any item inside a menu bar can retrieve attributes from the dialog using
  19. -- get_attribute. It is not necessary to call get_dialog.
  20. --
  21. -- The menu can be created with no elements and be dynamic filled using append
  22. -- or insert.
  23. inherit
  24. IUP_WIDGET
  25. redefine
  26. execute_map,
  27. execute_unmap,
  28. execute_destroy,
  29. execute_open,
  30. execute_menuclose
  31. end
  32. IUP_WIDGET_BGCOLOR
  33. IUP_WIDGET_POPUP
  34. IUP_WIDGET_NAME
  35. create {ANY}
  36. menu_empty,
  37. menu
  38. feature {ANY}
  39. menu_empty
  40. -- Create an empty menu
  41. local
  42. p, a_menu: POINTER
  43. do
  44. a_menu := int_empty_menu (p)
  45. set_widget(a_menu)
  46. end
  47. menu (col: ARRAY[IUP_MENU_ELEMENT])
  48. -- Create a new menu containing the list of item
  49. local
  50. i: INTEGER; arg: ARRAY[POINTER]; s: IUP_WIDGET; a_menu: POINTER
  51. do
  52. i := col.count
  53. create arg.make_filled(default_pointer, 1, i + 1)
  54. i := 0
  55. across
  56. col as ic
  57. loop
  58. i := i + 1
  59. s := ic.item
  60. arg.put(s.widget, i)
  61. end
  62. a_menu := int_menu (get_pointer(arg.to_c))
  63. set_widget(a_menu)
  64. end
  65. -- Attributes
  66. set_radio (state: BOOLEAN)
  67. -- (non inheritable): enables the automatic toggle of one child item.
  68. -- When a child item is selected the other item is automatically
  69. -- deselected. The menu acts like a IUP_RADIO for its children. Submenus
  70. -- and their children are not affected.
  71. do
  72. iup_open.set_attribute(Current, "RADIO", boolean_to_yesno(state))
  73. end
  74. -- Commands to handle heirarchy
  75. append (new_child: IUP_WIDGET): detachable IUP_WIDGET
  76. -- Inserts an interface element at the end of the container, after
  77. -- the last element of the container. Valid for any element that
  78. -- contains other elements like dialog, frame, hbox, vbox, zbox or menu.
  79. -- Returns: the actual parent if the interface element was
  80. -- successfully inserted. Otherwise returns Void.
  81. do
  82. Result := iup_open.iup_append(Current, new_child)
  83. end
  84. insert (ref_child: IUP_WIDGET; new_child: IUP_WIDGET): detachable IUP_WIDGET
  85. -- Inserts an interface element before another child of the
  86. -- container. Valid for any element that contains other elements
  87. -- like dialog, frame, hbox, vbox, zbox, menu, etc.
  88. -- Returns: the actual parent if the interface element was
  89. -- successfully inserted. Otherwise returns NULL
  90. do
  91. Result := iup_open.iup_insert(Current, ref_child, new_child)
  92. end
  93. -- PopUp
  94. popup_mouse_position: STRING
  95. -- Shows the menu at mouse position and restricts user interaction only
  96. -- to the specified element. If there was an error returns IUP_ERROR.
  97. do
  98. Result := iup_open.popup_predefined_xy(Current, "IUP_MOUSEPOS", "IUP_MOUSEPOS")
  99. end
  100. set_popup_alignment (horizontal: STRING; vertical: STRING)
  101. -- alignment of the popup menu relative to the given point. Where horizontal
  102. -- can be: ALEFT, ACENTER or ARIGHT; and vertical can be ATOP, ACENTER or
  103. -- ABOTTOM. Default: ALEFT:ATOP.
  104. require
  105. is_valid_alignment(horizontal, vertical)
  106. local
  107. str: STRING
  108. do
  109. create str.make_from_string(horizontal)
  110. str.append_string(":")
  111. str.append_string(vertical)
  112. iup_open.set_attribute(Current, "POPUPALIGN", str)
  113. end
  114. -- Callbacks
  115. -- Common
  116. set_cb_map (act: detachable FUNCTION[TUPLE[IUP_MENU], STRING])
  117. -- Called right after an element is mapped and its attributes updated.
  118. local
  119. operation: INTEGER
  120. do
  121. cb_map := act
  122. if cb_map /= Void then
  123. operation := 1
  124. else
  125. operation := 0
  126. end
  127. iup_open.set_callback (Current, "MAP_CB", "NONEEDED", operation)
  128. end
  129. set_cb_unmap (act: detachable FUNCTION[TUPLE[IUP_MENU], STRING])
  130. -- Called right before an element is unmapped.
  131. local
  132. operation: INTEGER
  133. do
  134. cb_unmap := act
  135. if cb_unmap /= Void then
  136. operation := 1
  137. else
  138. operation := 0
  139. end
  140. iup_open.set_callback (Current, "UNMAP_CB", "NONEEDED", operation)
  141. end
  142. set_cb_destroy (act: detachable FUNCTION[TUPLE[IUP_MENU], STRING])
  143. -- Called right before an element is destroyed.
  144. local
  145. operation: INTEGER
  146. do
  147. cb_destroy := act
  148. if cb_destroy /= Void then
  149. operation := 1
  150. else
  151. operation := 0
  152. end
  153. iup_open.set_callback (Current, "DESTROY_CB", "NONEEDED", operation)
  154. end
  155. set_cb_open (act: detachable FUNCTION[TUPLE[IUP_MENU], STRING])
  156. -- Called just before the menu is opened.
  157. local
  158. operation: INTEGER
  159. do
  160. cb_open := act
  161. if cb_open /= Void then
  162. operation := 1
  163. else
  164. operation := 0
  165. end
  166. iup_open.set_callback (Current, "OPEN_CB", "NONEEDED", operation)
  167. end
  168. set_cb_menu_close (act: detachable FUNCTION[TUPLE[IUP_MENU], STRING])
  169. -- Called just after the menu is closed.
  170. local
  171. operation: INTEGER
  172. do
  173. cb_menuclose := act
  174. if cb_menuclose /= Void then
  175. operation := 1
  176. else
  177. operation := 0
  178. end
  179. iup_open.set_callback (Current, "MENUCLOSE_CB", "NONEEDED", operation)
  180. end
  181. -- Validations
  182. is_valid_alignment (horizontal, vertical: STRING): BOOLEAN
  183. local
  184. h, v: BOOLEAN
  185. do
  186. if horizontal.is_equal("ALEFT") or
  187. horizontal.is_equal("ACENTER") or
  188. horizontal.is_equal("ARIGHT") then
  189. h := True
  190. else
  191. h := False
  192. end
  193. if vertical.is_equal("ATOP") or
  194. vertical.is_equal("ACENTER") or
  195. vertical.is_equal("ABOTTOM") then
  196. v := True
  197. else
  198. v := False
  199. end
  200. if h and v then
  201. Result := True
  202. else
  203. Result := False
  204. end
  205. end
  206. feature {IUP}
  207. -- Common callbacks
  208. execute_map: STRING
  209. do
  210. if attached cb_map as int_cb then
  211. Result := int_cb.item([Current])
  212. else
  213. Result := "IUP_DEFAULT"
  214. end
  215. end
  216. execute_unmap: STRING
  217. do
  218. if attached cb_unmap as int_cb then
  219. Result := int_cb.item([Current])
  220. else
  221. Result := "IUP_DEFAULT"
  222. end
  223. end
  224. execute_destroy: STRING
  225. do
  226. if attached cb_destroy as int_cb then
  227. Result := int_cb.item([Current])
  228. else
  229. Result := "IUP_DEFAULT"
  230. end
  231. end
  232. -- Extra
  233. execute_open: STRING
  234. do
  235. if attached cb_open as int_cb then
  236. Result := int_cb.item([Current])
  237. else
  238. Result := "IUP_DEFAULT"
  239. end
  240. end
  241. execute_menuclose: STRING
  242. do
  243. if attached cb_menuclose as int_cb then
  244. Result := int_cb.item([Current])
  245. else
  246. Result := "IUP_DEFAULT"
  247. end
  248. end
  249. feature {NONE}
  250. -- For callbacks
  251. cb_map: detachable FUNCTION[TUPLE[IUP_MENU], STRING]
  252. cb_unmap: detachable FUNCTION[TUPLE[IUP_MENU], STRING]
  253. cb_destroy: detachable FUNCTION[TUPLE[IUP_MENU], STRING]
  254. cb_open: detachable FUNCTION[TUPLE[IUP_MENU], STRING]
  255. cb_menuclose: detachable FUNCTION[TUPLE[IUP_MENU], STRING]
  256. -- Internals
  257. int_empty_menu (list: POINTER): POINTER
  258. external
  259. "C inline use %"eiffel-iup.h%""
  260. alias
  261. "return IupMenu ($list);"
  262. end
  263. int_menu (list: POINTER): POINTER
  264. external
  265. "C inline use %"eiffel-iup.h%""
  266. alias
  267. "return IupMenuv ($list)"
  268. end
  269. end
  270. -- The MIT License (MIT)
  271. -- Copyright (c) 2016, 2017, 2019, 2020, 2021 by German A. Arias
  272. -- Permission is hereby granted, free of charge, to any person obtaining a copy
  273. -- of this software and associated documentation files (the "Software"), to deal
  274. -- in the Software without restriction, including without limitation the rights
  275. -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  276. -- copies of the Software, and to permit persons to whom the Software is
  277. -- furnished to do so, subject to the following conditions:
  278. --
  279. -- The above copyright notice and this permission notice shall be included in
  280. -- all copies or substantial portions of the Software.
  281. --
  282. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  283. -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  284. -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  285. -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  286. -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  287. -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  288. -- SOFTWARE.