iup_dialog.e 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317
  1. class IUP_DIALOG
  2. -- In IUP you can create your own dialogs or use one of the predefined dialogs.
  3. -- To create your own dialogs you will have to create all the controls of the
  4. -- dialog before the creation of the dialog. All the controls must be composed
  5. -- in a hierarchical structure so the root will be used as a parameter to the
  6. -- dialog creation.
  7. --
  8. -- When a control is created, its parent is not known. After the dialog is
  9. -- created all elements receive a parent. This mechanism is quite different
  10. -- from that of native systems, who first create the dialog and then the
  11. -- element are inserted, using the dialog as a parent. This feature creates
  12. -- some limitations for IUP, usually related to the insertion and removal of
  13. -- controls.
  14. --
  15. -- Since the controls are created in a different order from the native system,
  16. -- native controls can only be created after the dialog. This will happen
  17. -- automatically when the application call the show function to show the dialog.
  18. -- But we often need the native controls to be created so we can use some other
  19. -- functionality of those before they are visible to the user. For that
  20. -- purpose, map function was created. It forces IUP to map the controls to
  21. -- their native system controls. The show function internally uses map before
  22. -- showing the dialog on the screen. show can be called many times, but the map
  23. -- process will occur only once.
  24. --
  25. -- show can be replaced by popup. In this case the result will be a modal
  26. -- dialog and all the other previously shown dialogs will be unavailable to the
  27. -- user. Also the program will interrupt in the function call until the
  28. -- application return IUP_CLOSE or exit_loop is called.
  29. --
  30. -- All dialogs are automatically destroyed in iup_close.
  31. inherit
  32. IUP_CONTAINER
  33. undefine
  34. execute_dragbegin,
  35. execute_dragdatasize,
  36. execute_dragdata,
  37. execute_dragend,
  38. execute_dropdata,
  39. execute_dropmotion
  40. redefine
  41. -- set_maxsize,
  42. -- get_maxsize,
  43. -- set_minsize,
  44. -- get_minsize
  45. execute_map,
  46. execute_unmap,
  47. execute_destroy,
  48. execute_getfocus,
  49. execute_killfocus,
  50. execute_enterwindow,
  51. execute_leavewindow,
  52. execute_k_any,
  53. execute_help,
  54. execute_close,
  55. execute_copydata,
  56. execute_dropfiles,
  57. execute_mdiactivate,
  58. execute_move,
  59. execute_resize,
  60. execute_show,
  61. execute_trayclick,
  62. execute_focus
  63. end
  64. IUP_WIDGET_EXPAND
  65. IUP_WIDGET_TITLE
  66. IUP_WIDGET_VISIBLE
  67. IUP_WIDGET_ACTIVE
  68. IUP_WIDGET_BGCOLOR
  69. IUP_WIDGET_FONT
  70. IUP_WIDGET_SCREENPOSITION
  71. IUP_WIDGET_TIP
  72. IUP_WIDGET_CLIENTOFFSET
  73. IUP_WIDGET_CLIENTSIZE
  74. IUP_WIDGET_RASTERSIZE
  75. IUP_WIDGET_USERSIZE
  76. IUP_WIDGET_ZORDER
  77. IUP_WIDGET_POPUP
  78. IUP_WIDGET_SHOW
  79. IUP_WIDGET_HIDE
  80. IUP_WIDGET_PARENT_DIALOG
  81. IUP_WIDGET_ICON
  82. IUP_WIDGET_DEFAULT_ENTER_ESC
  83. IUP_WIDGET_MAXMIN_SIZE
  84. redefine
  85. set_maxsize,
  86. get_maxsize,
  87. set_minsize,
  88. get_minsize
  89. end
  90. IUP_DRAG_AND_DROP
  91. IUP_WIDGET_CUSTOM_ATTRIBUTES
  92. create {ANY}
  93. dialog
  94. create {IUP}
  95. dialog_widget
  96. feature {ANY}
  97. dialog (content: IUP_WIDGET)
  98. -- Create a new dialog with the specified content
  99. local
  100. a_dialog: POINTER
  101. do
  102. a_dialog := int_dialog(content.widget)
  103. set_widget(a_dialog)
  104. end
  105. -- Attributes
  106. get_dialog_child (name: STRING): detachable IUP_WIDGET
  107. -- Returns the child element that has the NAME attribute equals
  108. -- to the given value on the dialog. Works also for children
  109. -- of a menu that is associated with a dialog.
  110. -- This function will only found the child if the NAME attribute
  111. -- is set at the control.
  112. do
  113. Result := iup_open.iup_get_dialog_child(Current, name)
  114. end
  115. -- Drop button
  116. get_drop_button: detachable IUP_DROP_BUTTON
  117. -- If the dialog is associated to a drop button, then return it.
  118. -- Otherwise return Void.
  119. do
  120. Result := iup_open.get_drop_button_for_dialog(Current)
  121. end
  122. -- Skip BACKGROUND attribute
  123. set_border (state: BOOLEAN)
  124. -- (non inheritable) (creation only): Shows a resize border around the
  125. -- dialog. Default: "YES". BORDER=NO is useful only when RESIZE=NO,
  126. -- MAXBOX=NO, MINBOX=NO, MENUBOX=NO and TITLE=NULL, if any of these are
  127. -- defined there will be always some border.
  128. do
  129. iup_open.set_attribute(Current, "BORDER", boolean_to_yesno(state))
  130. end
  131. has_border: BOOLEAN
  132. -- Border state.
  133. local
  134. str: STRING
  135. do
  136. str := iup_open.get_attribute(Current, "BORDER")
  137. Result := yesno_to_boolean(str)
  138. end
  139. get_border_width: INTEGER
  140. -- (non inheritable): returns the border size.
  141. local
  142. str: STRING
  143. do
  144. str := iup_open.get_attribute(Current, "BORDERSIZE")
  145. Result := str.to_integer
  146. end
  147. set_child_offset (horizontal, vertical: INTEGER)
  148. -- Allow to specify a position offset for the child. Available for native
  149. -- containers only. It will not affect the natural size, and allows to
  150. -- position controls outside the client area. Are integer values
  151. -- corresponding to the horizontal and vertical offsets, respectively,
  152. -- in pixels. Default: 0x0.
  153. require
  154. horizontal >= 0
  155. vertical >= 0
  156. local
  157. offset: STRING
  158. do
  159. offset := horizontal.out
  160. offset.append_string("x")
  161. offset.append_string(vertical.out)
  162. iup_open.set_attribute(Current, "CHILDOFFSET", offset)
  163. end
  164. get_child_offset: TUPLE[INTEGER, INTEGER]
  165. -- Return the offset of the child.
  166. local
  167. offset: STRING
  168. do
  169. offset := iup_open.get_attribute(Current, "CHILDOFFSET")
  170. Result := components_of_size(offset)
  171. end
  172. set_cursor (name: STRING)
  173. -- Defines the element's cursor. See documentation. Default: ARROW
  174. do
  175. iup_open.set_attribute(Current, "CURSOR", name)
  176. end
  177. get_cursor: STRING
  178. -- Return the cursor name.
  179. do
  180. Result := iup_open.get_attribute(Current, "CURSOR")
  181. end
  182. set_nactive (state: BOOLEAN)
  183. -- (non inheritable): same as set_active but does not affects the
  184. -- controls inside the dialog.
  185. do
  186. iup_open.set_attribute(Current, "NACTIVE", boolean_to_yesno(state))
  187. end
  188. is_nactive: BOOLEAN
  189. -- Return the state of nactive.
  190. local
  191. str: STRING
  192. do
  193. str := iup_open.get_attribute(Current, "NACTIVE")
  194. Result := yesno_to_boolean(str)
  195. end
  196. set_size (width, height: INTEGER)
  197. -- (non inheritable): Dialog’s size.
  198. --
  199. -- The dialog Natural size is only considered when the User size is not
  200. -- defined or when it is bigger than the Current size. This behavior is
  201. -- different from a control that goes inside the dialog. Because of that,
  202. -- when SIZE or RASTERSIZE are set (changing the User size), the Current
  203. -- size is internally reset to 0x0, so the the Natural size can be
  204. -- considered when re-computing the Current size of the dialog.
  205. --
  206. -- Values set at SIZE or RASTERSIZE attributes of a dialog are always
  207. -- accepted, regardless of the minimum size required by its children. For
  208. -- a dialog to have the minimum necessary size to fit all elements
  209. -- contained in it, simply define SIZE or RASTERSIZE to NULL. Also if you
  210. -- set SIZE or RASTERSIZE to be used as the initial size of the dialog,
  211. -- its contents will be limited to this size as the minimum size, if you
  212. -- do not want that, then after showing the dialog reset this size to NULL
  213. -- so the dialog can be resized to smaller values. But notice that its
  214. -- contents will still be limited by the Natural size, to also remove
  215. -- that limitation set SHRINK=True. To only change the User size in
  216. -- pixels, without resetting the Current size, set the USERSIZE attribute
  217. -- (since 3.12). Notice that the dialog size includes its decoration (it
  218. -- is the Window size), the area available for controls are returned by
  219. -- the dialog CLIENTSIZE. For more information see Layout Guide.
  220. local
  221. size: STRING
  222. do
  223. size := width.out
  224. size.append_string("x")
  225. size.append_string(height.out)
  226. iup_open.set_attribute(Current, "SIZE", size)
  227. end
  228. set_predefined_size (width, height: STRING)
  229. -- (non inheritable): Dialog’s size using predefined values
  230. -- for width and/or height. However you can combine a predefined
  231. -- value with an integer (as string). The predefined values are:
  232. --
  233. -- "FULL": Defines the dialog’s width (or height) equal to the screen's
  234. -- width (or height)
  235. -- "HALF": Defines the dialog’s width (or height) equal to half the
  236. -- screen's width (or height)
  237. -- "THIRD": Defines the dialog’s width (or height) equal to 1/3 the
  238. -- screen's width (or height)
  239. -- "QUARTER": Defines the dialog’s width (or height) equal to 1/4 of the
  240. -- screen's width (or height)
  241. -- "EIGHTH": Defines the dialog’s width (or height) equal to 1/8 of the
  242. -- screen's width (or height)
  243. require
  244. is_valid_size (width, height)
  245. local
  246. size: STRING
  247. do
  248. size := width
  249. size.append_string("x")
  250. size.append_string(height)
  251. iup_open.set_attribute(Current, "SIZE", size)
  252. end
  253. get_size: TUPLE[INTEGER, INTEGER]
  254. -- The size of the dialog.
  255. local
  256. str: STRING
  257. do
  258. str := iup_open.get_attribute(Current, "SIZE")
  259. Result := components_of_size(str)
  260. end
  261. set_simulate_modal (state: BOOLEAN)
  262. -- Disable all other visible dialogs, just like when the dialog is made
  263. -- modal.
  264. do
  265. iup_open.set_attribute(Current, "SIMULATEMODAL", boolean_to_yesno(state))
  266. end
  267. -- Exclusive
  268. -- Skip CUSTOMFRAMESIMULATE
  269. set_modal_dialog_frame (state: BOOLEAN)
  270. -- Set the common decorations for modal dialogs. This means RESIZE=NO,
  271. -- MINBOX=NO and MAXBOX=NO. In Windows, if the PARENTDIALOG is defined
  272. -- then the MENUBOX is also removed, but the Close button remains.
  273. do
  274. iup_open.set_attribute(Current, "DIALOGFRAME", boolean_to_yesno(state))
  275. end
  276. is_modal_dialog_frame: BOOLEAN
  277. -- Modal dialog.
  278. local
  279. str: STRING
  280. do
  281. str := iup_open.get_attribute(Current, "DIALOGFRAME")
  282. Result := yesno_to_boolean(str)
  283. end
  284. set_fullscreen (state: BOOLEAN)
  285. -- Makes the dialog occupy the whole screen over any system bars in the
  286. -- main monitor. All dialog details, such as title bar, borders, maximize
  287. -- button, etc, are removed. Possible values: True, False. In Motif you
  288. -- may have to click in the dialog to set its focus.
  289. -- In Motif if set to Trur when the dialog is hidden, then it can not be
  290. -- changed after it is visible.
  291. do
  292. iup_open.set_attribute(Current, "FULLSCREEN", boolean_to_yesno(state))
  293. end
  294. get_fullscreen: BOOLEAN
  295. -- Fullscreen status
  296. local
  297. str: STRING
  298. do
  299. str := iup_open.get_attribute(Current, "FULLSCREEN")
  300. Result := yesno_to_boolean(str)
  301. end
  302. set_maxbox (state: BOOLEAN)
  303. -- (creation only): Requires a maximize button from the window manager.
  304. -- If RESIZE=NO then MAXBOX will be set to NO. Default: True. In Motif the
  305. -- decorations are controlled by the Window Manager and may not be
  306. -- possible to be changed from IUP. In Windows MAXBOX is hidden only if
  307. -- MINBOX is hidden as well, or else it will be just disabled.
  308. do
  309. iup_open.set_attribute(Current, "MAXBOX", boolean_to_yesno(state))
  310. end
  311. set_maxsize (width, height: INTEGER)
  312. -- Maximum size for the dialog in raster units (pixels). The windowing
  313. -- system will not be able to change the size beyond this limit. Default:
  314. -- 65535x65535.
  315. do
  316. Precursor (width, height)
  317. end
  318. get_maxsize: TUPLE[INTEGER, INTEGER]
  319. -- Max size of the dialog.
  320. do
  321. Result := Precursor
  322. end
  323. set_menu (name: STRING)
  324. -- Name of a menu. Associates a menu to the dialog as a menu bar. The
  325. -- previous menu, if any, is unmapped. Use set_widget_name to
  326. -- associate a menu to a name.
  327. do
  328. iup_open.set_attribute(Current, "MENU", name)
  329. end
  330. set_menu_widget (menu: IUP_MENU)
  331. -- Set the menu widget to the dialog as a menu bar. The previous menu, if
  332. -- any, is unmapped.
  333. do
  334. iup_open.set_attribute_widget(Current, "MENU", menu)
  335. end
  336. set_menubox (state: BOOLEAN)
  337. -- (creation only): Requires a system menu box from the window manager.
  338. -- If hidden will also remove the Close button. Default: True. In Motif
  339. -- the decorations are controlled by the Window Manager and may not be
  340. -- possible to be changed from IUP. In Windows if hidden will hide also
  341. -- MAXBOX and MINBOX.
  342. do
  343. iup_open.set_attribute(Current, "MENUBOX", boolean_to_yesno(state))
  344. end
  345. set_minbox (state: BOOLEAN)
  346. -- (creation only): Requires a minimize button from the window manager.
  347. -- Default: True. In Motif the decorations are controlled by the Window
  348. -- Manager and may not be possible to be changed from IUP. In Windows
  349. -- MINBOX is hidden only if MAXBOX is hidden as well, or else it will be
  350. -- just disabled.
  351. do
  352. iup_open.set_attribute(Current, "MINBOX", boolean_to_yesno(state))
  353. end
  354. set_minsize (width, height: INTEGER)
  355. -- Minimum size for the dialog in raster units (pixels). The windowing
  356. -- system will not be able to change the size beyond this limit. Default:
  357. -- 1x1. Some systems define a very minimum size greater than this, for
  358. -- instance in Windows the horizontal minimum size includes the window
  359. -- decoration buttons.
  360. do
  361. Precursor (width, height)
  362. end
  363. get_minsize: TUPLE[INTEGER, INTEGER]
  364. -- Min size of the dialog.
  365. do
  366. Result := Precursor
  367. end
  368. is_modal: BOOLEAN
  369. local
  370. str: STRING
  371. do
  372. str := iup_open.get_attribute(Current, "MODAL")
  373. Result := yesno_to_boolean(str)
  374. end
  375. set_native_parent (dlg: IUP_DIALOG)
  376. -- (creation only): Dialog to be used as parent. Used
  377. -- only if PARENTDIALOG is not defined.
  378. do
  379. iup_open.set_attribute_widget(Current, "NATIVEPARENT", dlg)
  380. end
  381. -- Skip placement.
  382. set_resize (state: BOOLEAN)
  383. -- (creation only): Allows interactively changing the dialog’s size.
  384. -- Default: True. If RESIZE=NO then MAXBOX will be set to NO. In Motif
  385. -- the decorations are controlled by the Window Manager and may not be
  386. -- possible to be changed from IUP.
  387. do
  388. iup_open.set_attribute(Current, "RESIZE", boolean_to_yesno(state))
  389. end
  390. set_shrink (state: BOOLEAN)
  391. -- Allows changing the elements’ distribution when the dialog is smaller
  392. -- than the minimum size. Default: False.
  393. do
  394. iup_open.set_attribute(Current, "SHRINK", boolean_to_yesno(state))
  395. end
  396. set_start_focus (name: STRING)
  397. -- Name of the element that must receive the focus right after the dialog
  398. -- is shown using IupShow or IupPopup. If not defined then the first
  399. -- control than can receive the focus is selected. Updated after SHOW_CB
  400. -- is called and only if the focus was not changed during the callback.
  401. do
  402. iup_open.set_attribute(Current, "STARTFOCUS", name)
  403. end
  404. -- Exclusive [System Dependent]
  405. -- Skip HWND
  406. -- Skip SAVEUNDER
  407. -- Skip XWINDOW
  408. -- The next attributes are Windows and GTK only.
  409. is_active_window: BOOLEAN
  410. -- [Windows and GTK Only] (read-only): informs if the dialog is the
  411. --active window (the window with focus). Can be True or False.
  412. local
  413. str: STRING
  414. do
  415. str := iup_open.get_attribute(Current, "ACTIVEWINDOW")
  416. Result := yesno_to_boolean(str)
  417. end
  418. -- Skip CUSTOMFRAME
  419. set_as_drop_files_target (state: BOOLEAN)
  420. -- [Windows and GTK Only] (non inheritable): Enable or disable the drop
  421. -- of files. Default: False, but if DROPFILES_CB is defined when the
  422. -- element is mapped then it will be automatically enabled.
  423. do
  424. iup_open.set_attribute(Current, "DROPFILESTARGET", boolean_to_yesno(state))
  425. end
  426. is_drop_files_target: BOOLEAN
  427. -- Drop files target state.
  428. local
  429. str: STRING
  430. do
  431. str := iup_open.get_attribute(Current, "DROPFILESTARGET")
  432. Result := yesno_to_boolean(str)
  433. end
  434. is_maximized: BOOLEAN
  435. -- [Windows Only] (read-only): indicates if the dialog is maximized. Can
  436. -- be True or False.
  437. local
  438. str: STRING
  439. do
  440. str := iup_open.get_attribute(Current, "MAXIMIZED")
  441. Result := yesno_to_boolean(str)
  442. end
  443. is_minimized: BOOLEAN
  444. -- [Windows Only] (read-only): indicates if the dialog is minimized. Can
  445. -- be True or False.
  446. local
  447. str: STRING
  448. do
  449. str := iup_open.get_attribute(Current, "MINIMIZED")
  450. Result := yesno_to_boolean(str)
  451. end
  452. set_opacity (value: INTEGER)
  453. -- [Windows and GTK Only]: sets the dialog transparency alpha value.
  454. -- Valid values range from 0 (completely transparent) to 255 (opaque). In
  455. -- Windows must be set before map so the native window would be properly
  456. -- initialized when mapped
  457. require
  458. value >= 0
  459. value <= 255
  460. do
  461. iup_open.set_attribute(Current, "OPACITY", value.out)
  462. end
  463. set_opacity_image (name: STRING)
  464. -- [Windows and GTK Only]: sets a transparent image as the dialog shape so
  465. -- it is possible to create a non rectangle window. In Windows must be
  466. -- set before map so the native window would be properly initialized when
  467. -- mapped. In GTK the shape works only as a bitmap mask, to view a color
  468. -- image must also use a label.
  469. do
  470. iup_open.set_attribute(Current, "OPACITYIMAGE", name)
  471. end
  472. set_shape_image (name: STRING)
  473. -- [Windows and GTK Only]: sets a RGBA image as the dialog shape so it is
  474. -- possible to create a non rectangle window with children. (GTK 2.12)
  475. -- Only the fully transparent pixels will be transparent. The pixels
  476. -- colors will be ignored, only the alpha channel is used.
  477. do
  478. iup_open.set_attribute(Current, "SHAPEIMAGE", name)
  479. end
  480. set_top_most (state: BOOLEAN)
  481. -- [Windows and GTK Only]: puts the dialog always in front of all other
  482. -- dialogs in all applications. Default: False.
  483. do
  484. iup_open.set_attribute(Current, "TOPMOST", boolean_to_yesno(state))
  485. end
  486. -- Exclusive Taskbar and Tray/Status Area [Windows and GTK Only]
  487. set_hide_taskbar (state: BOOLEAN)
  488. -- [Windows and GTK Only] (write-only): Action attribute that when set to
  489. -- "YES", hides the dialog, but does not decrement the visible dialog
  490. -- count, does not call SHOW_CB and does not mark the dialog as hidden
  491. -- inside IUP. It is usually used to hide the dialog and keep the tray
  492. -- icon working without closing the main loop. It has the same effect as
  493. -- setting LOCKLOOP=Yes and normally hiding the dialog. IMPORTANT: when
  494. -- you hide using HIDETASKBAR, you must show using HIDETASKBAR also.
  495. -- Possible values: True, False.
  496. do
  497. iup_open.set_attribute(Current, "HIDETASKBAR", boolean_to_yesno(state))
  498. end
  499. -- Skip TASKBARPROGRESS, TASKBARPROGRESSSTATE, TASKBARPROGRESSVALUE
  500. show_task_bar_button
  501. -- [Windows Only]: Force the application button to be shown on
  502. -- the taskbar even if the dialog does not have decorations.
  503. do
  504. iup_open.set_attribute(Current, "TASKBARBUTTON", "SHOW")
  505. end
  506. hide_task_bar_button
  507. -- [Windows Only]: Force the application button to be hidden from the taskbar,
  508. -- but also in this case the system menu, the maximize and minimize buttons
  509. -- will be hidden.
  510. do
  511. iup_open.set_attribute(Current, "TASKBARBUTTON", "HIDE")
  512. end
  513. set_tray (state: BOOLEAN)
  514. -- [Windows and GTK Only]: When set to "True", displays an icon on the
  515. -- system tray.
  516. do
  517. iup_open.set_attribute(Current, "TRAY", boolean_to_yesno(state))
  518. end
  519. set_tray_image (name: STRING)
  520. -- [Windows and GTK Only]: Name of a IUP image to be used as the tray
  521. -- icon. The Windows SDK recommends that cursors and icons should be
  522. -- implemented as resources rather than created at run time.
  523. do
  524. iup_open.set_attribute(Current, "TRAYIMAGE", name)
  525. end
  526. set_tray_tip (text: STRING)
  527. -- [Windows and GTK Only]: Tray icon's tooltip text.
  528. do
  529. iup_open.set_attribute(Current, "TRAYTIP", text)
  530. end
  531. -- Skip TRAYTIPMARKUP, TRAYTIPBALLOON, TRAYTIPBALLOONDELAY,
  532. -- TRAYTIPBALLOONTITLE, TRAYTIPBALLOONTITLEICON
  533. -- Exclusive [GTK Only]
  534. set_dialog_hint (state: BOOLEAN)
  535. -- [GTK Only] (creation-only): if enabled sets the window type hint to a
  536. -- dialog hint.
  537. do
  538. iup_open.set_attribute(Current, "DIALOGHINT", boolean_to_yesno(state))
  539. end
  540. set_hide_title_bar (state: BOOLEAN)
  541. -- [GTK Only] (non inheritable): hides the title bar with all its
  542. -- elements. (since 3.20) (GTK 3.10)
  543. do
  544. iup_open.set_attribute(Current, "HIDETITLEBAR",
  545. boolean_to_yesno(state))
  546. end
  547. -- Exclusive [Windows Only]
  548. set_bring_front (state: BOOLEAN)
  549. -- [Windows Only] (write-only): makes the dialog the foreground window.
  550. -- Use "True" to activate it. Useful for multithreaded applications.
  551. do
  552. iup_open.set_attribute(Current, "BRINGFRONT", boolean_to_yesno(state))
  553. end
  554. set_composited (state: BOOLEAN)
  555. -- [Windows Only] (creation only): controls if the window will have an
  556. -- automatic double buffer for all children. Default is "False". In
  557. -- Windows Vista it is NOT working as expected.
  558. do
  559. iup_open.set_attribute(Current, "COMPOSITED", boolean_to_yesno(state))
  560. end
  561. -- Skip CONTROL
  562. -- Skip CUSTOMFRAMEDRAW, CUSTOMFRAMECAPTIONHEIGHT, CUSTOMFRAMECAPTIONLIMITS
  563. set_help_button (state: BOOLEAN)
  564. -- [Windows Only] (creation only): Inserts a help button in the same
  565. -- place of the maximize button. It can only be used for dialogs without
  566. -- the minimize and maximize buttons, and with the menu box. For the next
  567. -- interaction of the user with a control in the dialog, the callback
  568. -- HELP_CB will be called instead of the control defined ACTION callback.
  569. -- Possible values: True, False. Default: False.
  570. do
  571. iup_open.set_attribute(Current, "HELPBUTTON", boolean_to_yesno(state))
  572. end
  573. set_maximize_at_parent (state: BOOLEAN)
  574. -- [Windows Only]: when using multiple monitors, maximize the dialog
  575. -- in the same monitor that the parent dialog is.
  576. do
  577. iup_open.set_attribute(Current, "MAXIMIZEATPARENT", boolean_to_yesno(state))
  578. end
  579. set_toolbox (state: BOOLEAN)
  580. -- [Windows Only] (creation only): makes the dialog look like a toolbox
  581. -- with a smaller title bar. It is only valid if the PARENTDIALOG or
  582. -- NATIVEPARENT attribute is also defined. Default: False.
  583. do
  584. iup_open.set_attribute(Current, "TOOLBOX", boolean_to_yesno(state))
  585. end
  586. -- Exclusive MDI [Windows Only]
  587. set_mdi_frame (state: BOOLEAN)
  588. --(creation only) [Windows Only] (non inheritable): Configure this dialog
  589. -- as a MDI frame. Can be True or False. Default: False.
  590. do
  591. iup_open.set_attribute(Current, "MDIFRAME", boolean_to_yesno(state))
  592. end
  593. get_mdi_active: STRING
  594. -- [Windows Only] (read-only): Returns the name of the current active MDI
  595. -- child. Use get_attribute_handle to directly retrieve the child
  596. -- widget.
  597. do
  598. Result := iup_open.get_attribute(Current, "MDIACTIVE")
  599. end
  600. set_mdi_activate (name: STRING)
  601. -- [Windows Only] (write-only): Name of a MDI child window to be
  602. -- activated. If value is "NEXT" will activate the next window after the
  603. -- current active window. If value is "PREVIOUS" will activate the
  604. -- previous one.
  605. do
  606. iup_open.set_attribute(Current, "MDIACTIVATE", name)
  607. end
  608. set_mdi_arrange (type: STRING)
  609. -- [Windows Only] (write-only): Action to arrange MDI child windows.
  610. -- Possible values: TILEHORIZONTAL, TILEVERTICAL, CASCADE and ICON
  611. -- (arrange the minimized icons).
  612. require
  613. is_valid_type(type)
  614. do
  615. iup_open.set_attribute(Current, "MDIARRANGE", type)
  616. end
  617. set_mdi_close_all
  618. -- [Windows Only] (write-only): Action to close and destroy all MDI child
  619. -- windows. The CLOSE_CB callback will be called for each child.
  620. -- IMPORTANT: When a MDI child window is closed it is automatically
  621. -- destroyed. The application can override this returning IUP_IGNORE in
  622. -- CLOSE_CB.
  623. do
  624. iup_open.set_attribute(Current, "MDICLOSEALL", "YES")
  625. end
  626. get_mdi_next: STRING
  627. -- [Windows Only] (read-only): Returns the name of the next available
  628. -- MDI child. Use get_attribute_handle to directly retrieve the child
  629. -- widget. Must use MDIACTIVE to retrieve the first child. If the
  630. -- application is going to destroy the child retrieve the next child
  631. -- before destroying the current.
  632. do
  633. Result := iup_open.get_attribute(Current, "MDINEXT")
  634. end
  635. -- For the MDI Client MDICLIENT and MDIMENU see IUP_CANVAS
  636. set_mdi_child (state: BOOLEAN)
  637. -- (creation only) [Windows Only]: Configure this dialog to be a MDI
  638. -- child. The PARENTDIALOG attribute must also be defined. Each MDI child
  639. -- is automatically named if it does not have one. Default: "False".
  640. do
  641. iup_open.set_attribute(Current, "MDICHILD", boolean_to_yesno(state))
  642. end
  643. -- Commands to handle callbacks
  644. -- Common
  645. set_cb_map (act: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING])
  646. -- Called right after an element is mapped and its attributes updated.
  647. local
  648. operation: INTEGER
  649. do
  650. cb_map := act
  651. if cb_map /= Void then
  652. operation := 1
  653. else
  654. operation := 0
  655. end
  656. iup_open.set_callback (Current, "MAP_CB", "NONEEDED", operation)
  657. end
  658. set_cb_unmap (act: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING])
  659. -- Called right before an element is unmapped.
  660. local
  661. operation: INTEGER
  662. do
  663. cb_unmap := act
  664. if cb_unmap /= Void then
  665. operation := 1
  666. else
  667. operation := 0
  668. end
  669. iup_open.set_callback (Current, "UNMAP_CB", "NONEEDED", operation)
  670. end
  671. set_cb_destroy (act: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING])
  672. -- Called right before an element is destroyed.
  673. local
  674. operation: INTEGER
  675. do
  676. cb_destroy := act
  677. if cb_destroy /= Void then
  678. operation := 1
  679. else
  680. operation := 0
  681. end
  682. iup_open.set_callback (Current, "DESTROY_CB", "NONEEDED", operation)
  683. end
  684. set_cb_get_focus (act: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING])
  685. -- Action generated when an element is given keyboard focus.
  686. -- This callback is called after the KILLFOCUS_CB of the element
  687. -- that loosed the focus. The {IUP}.get_focus function during the
  688. -- callback returns the element that loosed the focus.
  689. local
  690. operation: INTEGER
  691. do
  692. cb_getfocus := act
  693. if cb_getfocus /= Void then
  694. operation := 1
  695. else
  696. operation := 0
  697. end
  698. iup_open.set_callback (Current, "GETFOCUS_CB", "NONEEDED", operation)
  699. end
  700. set_cb_kill_focus (act: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING])
  701. -- Action generated when an element loses keyboard focus. This
  702. -- callback is called before the GETFOCUS_CB of the element that
  703. -- gets the focus.
  704. local
  705. operation: INTEGER
  706. do
  707. cb_killfocus := act
  708. if cb_killfocus /= Void then
  709. operation := 1
  710. else
  711. operation := 0
  712. end
  713. iup_open.set_callback (Current, "KILLFOCUS_CB", "NONEEDED", operation)
  714. end
  715. set_cb_enter_window (act: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING])
  716. -- Action generated when the mouse enters the native element.
  717. local
  718. operation: INTEGER
  719. do
  720. cb_enterwindow := act
  721. if cb_enterwindow /= Void then
  722. operation := 1
  723. else
  724. operation := 0
  725. end
  726. iup_open.set_callback (Current, "ENTERWINDOW_CB", "NONEEDED", operation)
  727. end
  728. set_cb_leave_window (act: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING])
  729. -- Action generated when the mouse leaves the native element.
  730. local
  731. operation: INTEGER
  732. do
  733. cb_leavewindow := act
  734. if cb_leavewindow /= Void then
  735. operation := 1
  736. else
  737. operation := 0
  738. end
  739. iup_open.set_callback (Current, "LEAVEWINDOW_CB", "NONEEDED", operation)
  740. end
  741. set_cb_k_any (act: detachable FUNCTION[TUPLE[IUP_DIALOG, INTEGER], STRING])
  742. -- Action generated when a keyboard event occurs.
  743. -- IUP_WIDGET the element that activated the event.
  744. -- INTEGER identifier of typed key. Please refer to the Keyboard
  745. -- Codes table for a list of possible values.
  746. --
  747. -- Returns: If IUP_IGNORE is returned the key is ignored and not
  748. -- processed by the control and not propagated. If returns
  749. -- IUP_CONTINUE, the key will be processed and the event will be
  750. -- propagated to the parent of the element receiving it, this is
  751. -- the default behavior. If returns IUP_DEFAULT the key is processed
  752. -- but it is not propagated. IUP_CLOSE will be processed.
  753. local
  754. operation: INTEGER
  755. do
  756. cb_k_any := act
  757. if cb_k_any /= Void then
  758. operation := 1
  759. else
  760. operation := 0
  761. end
  762. iup_open.set_callback (Current, "K_ANY", "NONEEDED", operation)
  763. end
  764. set_cb_help (act: detachable PROCEDURE[TUPLE[IUP_DIALOG]])
  765. -- Action generated when the user press F1 at a control. In Motif
  766. -- is also activated by the Help button in some workstations
  767. -- keyboard.
  768. -- Returns: IUP_CLOSE will be processed.
  769. local
  770. operation: INTEGER
  771. do
  772. cb_help := act
  773. if cb_help /= Void then
  774. operation := 1
  775. else
  776. operation := 0
  777. end
  778. iup_open.set_callback (Current, "HELP_CB", "NONEEDED", operation)
  779. end
  780. -- Extra
  781. set_cb_close (act: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING])
  782. local
  783. operation: INTEGER
  784. do
  785. cb_close := act
  786. if cb_close /= Void then
  787. operation := 1
  788. else
  789. operation := 0
  790. end
  791. iup_open.set_callback (Current, "CLOSE_CB", "NONEEDED", operation)
  792. end
  793. set_cb_copy_data (act: detachable FUNCTION[TUPLE[IUP_DIALOG, STRING, INTEGER], STRING])
  794. local
  795. operation: INTEGER
  796. do
  797. cb_copydata := act
  798. if cb_copydata /= Void then
  799. operation := 1
  800. else
  801. operation := 0
  802. end
  803. iup_open.set_callback (Current, "COPYDATA_CB", "NONEEDED", operation)
  804. end
  805. set_cb_drop_files (act: detachable FUNCTION[TUPLE[IUP_DIALOG, STRING, INTEGER, INTEGER, INTEGER], STRING])
  806. local
  807. operation: INTEGER
  808. do
  809. cb_dropfiles := act
  810. if cb_dropfiles /= Void then
  811. operation := 1
  812. else
  813. operation := 0
  814. end
  815. iup_open.set_callback (Current, "DROPFILES_CB", "NONEEDED", operation)
  816. end
  817. set_cb_mdi_activate (act: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING])
  818. local
  819. operation: INTEGER
  820. do
  821. cb_mdiactivate := act
  822. if cb_mdiactivate /= Void then
  823. operation := 1
  824. else
  825. operation := 0
  826. end
  827. iup_open.set_callback (Current, "MDIACTIVATE_CB", "NONEEDED", operation)
  828. end
  829. set_cb_move (act: detachable FUNCTION[TUPLE[IUP_DIALOG, INTEGER, INTEGER], STRING])
  830. local
  831. operation: INTEGER
  832. do
  833. cb_move := act
  834. if cb_move /= Void then
  835. operation := 1
  836. else
  837. operation := 0
  838. end
  839. iup_open.set_callback (Current, "MOVE_CB", "NONEEDED", operation)
  840. end
  841. set_cb_resize (act: detachable FUNCTION[TUPLE[IUP_DIALOG, INTEGER, INTEGER], STRING])
  842. local
  843. operation: INTEGER
  844. do
  845. cb_resize := act
  846. if cb_resize /= Void then
  847. operation := 1
  848. else
  849. operation := 0
  850. end
  851. iup_open.set_callback (Current, "RESIZE_CB", "NONEEDED", operation)
  852. end
  853. set_cb_show (act: detachable FUNCTION[TUPLE[IUP_DIALOG, STRING], STRING])
  854. local
  855. operation: INTEGER
  856. do
  857. cb_show := act
  858. if cb_show /= Void then
  859. operation := 1
  860. else
  861. operation := 0
  862. end
  863. iup_open.set_callback (Current, "SHOW_CB", "NONEEDED", operation)
  864. end
  865. set_cb_tray_click (act: detachable FUNCTION[TUPLE[IUP_DIALOG, INTEGER, INTEGER, INTEGER], STRING])
  866. local
  867. operation: INTEGER
  868. do
  869. cb_trayclick := act
  870. if cb_trayclick /= Void then
  871. operation := 1
  872. else
  873. operation := 0
  874. end
  875. iup_open.set_callback (Current, "TRAYCLICK_CB", "NONEEDED", operation)
  876. end
  877. set_cb_focus (act: detachable FUNCTION[TUPLE[IUP_DIALOG, INTEGER], STRING])
  878. -- Called when the dialog or any of its children gets the focus, or when
  879. -- another dialog or any control in another dialog gets the focus. It is
  880. -- called after the common callbacks GETFOCUS_CB and KILLFOCUS_CB.
  881. local
  882. operation: INTEGER
  883. do
  884. cb_focus := act
  885. if cb_focus /= Void then
  886. operation := 1
  887. else
  888. operation := 0
  889. end
  890. iup_open.set_callback (Current, "FOCUS_CB", "NONEEDED", operation)
  891. end
  892. -- Validations
  893. is_valid_size (width, height: STRING): BOOLEAN
  894. local
  895. widths, heights: BOOLEAN
  896. do
  897. if width.is_equal("NULL") or
  898. width.is_equal("FULL") or
  899. width.is_equal("HALF") or
  900. width.is_equal("THIRD") or
  901. width.is_equal("QUARTER") or
  902. width.is_equal("EIGHTH") then
  903. widths := True
  904. elseif width.is_integer and width.to_integer >= 0 then
  905. widths := True
  906. else
  907. widths := False
  908. end
  909. if height.is_equal("NULL") or
  910. height.is_equal("FULL") or
  911. height.is_equal("HALF") or
  912. height.is_equal("THIRD") or
  913. height.is_equal("QUARTER") or
  914. height.is_equal("EIGHTH") then
  915. heights := True
  916. elseif height.is_integer and height.to_integer >= 0 then
  917. heights := True
  918. else
  919. heights := False
  920. end
  921. if widths and heights then
  922. Result := True
  923. else
  924. Result := False
  925. end
  926. end
  927. is_valid_type (type: STRING): BOOLEAN
  928. do
  929. if type.is_equal("TILEHORIZONTAL") or
  930. type.is_equal("TILEVERTICAL") or
  931. type.is_equal("CASCADE") or
  932. type.is_equal("ICON") then
  933. Result := True
  934. else
  935. Result := False
  936. end
  937. end
  938. feature {IUP}
  939. execute_map: STRING
  940. do
  941. if attached cb_map as int_cb then
  942. Result := int_cb.item([Current])
  943. else
  944. Result := "IUP_DEFAULT"
  945. end
  946. end
  947. execute_unmap: STRING
  948. do
  949. if attached cb_unmap as int_cb then
  950. Result := int_cb.item([Current])
  951. else
  952. Result := "IUP_DEFAULT"
  953. end
  954. end
  955. execute_destroy: STRING
  956. do
  957. if attached cb_destroy as int_cb then
  958. Result := int_cb.item([Current])
  959. else
  960. Result := "IUP_DEFAULT"
  961. end
  962. end
  963. execute_getfocus: STRING
  964. do
  965. if attached cb_getfocus as int_cb then
  966. Result := int_cb.item([Current])
  967. else
  968. Result := "IUP_DEFAULT"
  969. end
  970. end
  971. execute_killfocus: STRING
  972. do
  973. if attached cb_killfocus as int_cb then
  974. Result := int_cb.item([Current])
  975. else
  976. Result := "IUP_DEFAULT"
  977. end
  978. end
  979. execute_enterwindow: STRING
  980. do
  981. if attached cb_enterwindow as int_cb then
  982. Result := int_cb.item([Current])
  983. else
  984. Result := "IUP_DEFAULT"
  985. end
  986. end
  987. execute_leavewindow: STRING
  988. do
  989. if attached cb_leavewindow as int_cb then
  990. Result := int_cb.item([Current])
  991. else
  992. Result := "IUP_DEFAULT"
  993. end
  994. end
  995. execute_k_any (c: INTEGER): STRING
  996. do
  997. if attached cb_k_any as int_cb then
  998. Result := int_cb.item([Current, c])
  999. else
  1000. Result := "IUP_DEFAULT"
  1001. end
  1002. end
  1003. execute_help
  1004. do
  1005. if attached cb_help as int_cb then
  1006. int_cb.call([Current])
  1007. end
  1008. end
  1009. execute_close: STRING
  1010. do
  1011. if attached cb_close as int_cb then
  1012. Result := int_cb.item([Current])
  1013. else
  1014. Result := "IUP_DEFAULT"
  1015. end
  1016. end
  1017. execute_copydata (cmdline: STRING; size: INTEGER): STRING
  1018. do
  1019. if attached cb_copydata as int_cb then
  1020. Result := int_cb.item([Current, cmdline, size])
  1021. else
  1022. Result := "IUP_DEFAULT"
  1023. end
  1024. end
  1025. execute_dropfiles (filename: STRING; num: INTEGER; x: INTEGER; y: INTEGER): STRING
  1026. do
  1027. if attached cb_dropfiles as int_cb then
  1028. Result := int_cb.item([Current, filename, num, x, y])
  1029. else
  1030. Result := "IUP_DEFAULT"
  1031. end
  1032. end
  1033. execute_mdiactivate: STRING
  1034. do
  1035. if attached cb_mdiactivate as int_cb then
  1036. Result := int_cb.item([Current])
  1037. else
  1038. Result := "IUP_DEFAULT"
  1039. end
  1040. end
  1041. execute_move (x: INTEGER; y: INTEGER): STRING
  1042. do
  1043. if attached cb_move as int_cb then
  1044. Result := int_cb.item([Current, x, y])
  1045. else
  1046. Result := "IUP_DEFAULT"
  1047. end
  1048. end
  1049. execute_resize (width: INTEGER; height: INTEGER): STRING
  1050. do
  1051. if attached cb_resize as int_cb then
  1052. Result := int_cb.item([Current, width, height])
  1053. else
  1054. Result := "IUP_DEFAULT"
  1055. end
  1056. end
  1057. execute_show (state: STRING): STRING
  1058. do
  1059. if attached cb_show as int_cb then
  1060. Result := int_cb.item([Current, state])
  1061. else
  1062. Result := "IUP_DEFAULT"
  1063. end
  1064. end
  1065. execute_trayclick (but: INTEGER; pressed: INTEGER; dclick: INTEGER): STRING
  1066. do
  1067. if attached cb_trayclick as int_cb then
  1068. Result := int_cb.item([Current, but, pressed, dclick])
  1069. else
  1070. Result := "IUP_DEFAULT"
  1071. end
  1072. end
  1073. execute_focus (focus: INTEGER): STRING
  1074. do
  1075. if attached cb_focus as int_cb then
  1076. Result := int_cb.item([Current, focus])
  1077. else
  1078. Result := "IUP_DEFAULT"
  1079. end
  1080. end
  1081. feature {IUP}
  1082. dialog_widget (a_dialog: POINTER)
  1083. do
  1084. set_widget(a_dialog)
  1085. end
  1086. feature {NONE}
  1087. -- Callbacks
  1088. cb_map: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING]
  1089. cb_unmap: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING]
  1090. cb_destroy: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING]
  1091. cb_getfocus: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING]
  1092. cb_killfocus: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING]
  1093. cb_enterwindow: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING]
  1094. cb_leavewindow: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING]
  1095. cb_k_any: detachable FUNCTION[TUPLE[IUP_DIALOG, INTEGER], STRING]
  1096. cb_help: detachable PROCEDURE[TUPLE[IUP_DIALOG]]
  1097. cb_close: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING]
  1098. cb_copydata: detachable FUNCTION[TUPLE[IUP_DIALOG, STRING, INTEGER], STRING]
  1099. cb_dropfiles: detachable FUNCTION[TUPLE[IUP_DIALOG, STRING, INTEGER, INTEGER, INTEGER], STRING]
  1100. cb_mdiactivate: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING]
  1101. cb_move: detachable FUNCTION[TUPLE[IUP_DIALOG, INTEGER, INTEGER], STRING]
  1102. cb_resize: detachable FUNCTION[TUPLE[IUP_DIALOG, INTEGER, INTEGER], STRING]
  1103. cb_show: detachable FUNCTION[TUPLE[IUP_DIALOG, STRING], STRING]
  1104. cb_trayclick: detachable FUNCTION[TUPLE[IUP_DIALOG, INTEGER, INTEGER, INTEGER], STRING]
  1105. cb_focus: detachable FUNCTION[TUPLE[IUP_DIALOG, INTEGER], STRING]
  1106. -- Internals
  1107. int_dialog (wdt: POINTER): detachable POINTER
  1108. external
  1109. "C inline use %"eiffel-iup.h%""
  1110. alias
  1111. "return IupDialog ($wdt);"
  1112. end
  1113. end -- class IUP_DIALOG
  1114. -- The MIT License (MIT)
  1115. -- Copyright (c) 2016, 2017, 2018, 2019, 2020 by German A. Arias
  1116. -- Permission is hereby granted, free of charge, to any person obtaining a copy
  1117. -- of this software and associated documentation files (the "Software"), to deal
  1118. -- in the Software without restriction, including without limitation the rights
  1119. -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  1120. -- copies of the Software, and to permit persons to whom the Software is
  1121. -- furnished to do so, subject to the following conditions:
  1122. --
  1123. -- The above copyright notice and this permission notice shall be included in
  1124. -- all copies or substantial portions of the Software.
  1125. --
  1126. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  1127. -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  1128. -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  1129. -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  1130. -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  1131. -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  1132. -- SOFTWARE.