iup_flat_button.e 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. class IUP_FLAT_BUTTON
  2. -- Creates an interface element that is a button, but it does not have native
  3. -- decorations. When selected, this element activates a function in the
  4. -- application. Its visual presentation can contain a text and/or an image.
  5. --
  6. -- It behaves just like an IUP_BUTTON, but since it is not a native control it
  7. -- has more flexibility for additional options. It can also behave like an
  8. -- IUP_TOGGLE (without the checkmark).
  9. --
  10. -- It inherits from IUP_CANVAS. Inherits all callbacks of the IUP_CANVAS, but
  11. -- redefines a few of them. Including ACTION, BUTTON_CB, FOCUS_CB,
  12. -- LEAVEWINDOW_CB, and ENTERWINDOW_CB. To allow the application to use those
  13. -- callbacks the same callbacks are exported with the "FLAT_" prefix using the
  14. -- same parameters, except the FLAT_ACTION callback that now mimics the
  15. -- IUP_BUTTON ACTION. They are all called before the internal callbacks and if
  16. -- they return IUP_IGNORE the internal callbacks are not processed.
  17. inherit
  18. IUP_CANVAS
  19. redefine
  20. set_border,
  21. execute_flat_action,
  22. execute_flat_button,
  23. execute_flat_focus,
  24. execute_flat_enterwindow,
  25. execute_flat_leavewindow,
  26. execute_valuechanged
  27. end
  28. IUP_WIDGET_FGCOLOR
  29. IUP_WIDGET_SPACING
  30. IUP_WIDGET_TITLE
  31. IUP_WIDGET_IGNORERADIO
  32. create {ANY}
  33. flat_button
  34. feature {ANY}
  35. flat_button (title: STRING)
  36. --
  37. local
  38. a_flat_button, p: POINTER
  39. do
  40. if title /= Void then
  41. a_flat_button := int_flat_button(title.to_external)
  42. else
  43. a_flat_button := int_flat_button(p)
  44. end
  45. set_widget(a_flat_button)
  46. end
  47. -- Attributes
  48. set_alignment (horizontal, vertical: STRING)
  49. -- (non inheritable): horizontal and vertical alignment. Possible values:
  50. -- "ALEFT", "ACENTER" and "ARIGHT", combined to "ATOP", "ACENTER" and
  51. -- "ABOTTOM". Default: "ACENTER:ACENTER".
  52. require
  53. is_valid_vertical_alignment(vertical)
  54. is_valid_horizontal_alignment(horizontal)
  55. local
  56. str: STRING
  57. do
  58. create str.copy(horizontal)
  59. str.append_string(":")
  60. str.append_string(vertical)
  61. iup_open.set_attribute(Current, "ALIGNMENT", str)
  62. end
  63. set_back_image (name: STRING)
  64. -- (non inheritable): image name to be used as background. It will be
  65. -- zoomed to fill the background (it does not includes the border).
  66. do
  67. iup_open.set_attribute(Current, "BACKIMAGE", name)
  68. end
  69. set_back_image_highlight (name: STRING)
  70. -- (non inheritable): background image name of the element in highlight
  71. -- state. If it is not defined then the BACKIMAGE is used.
  72. do
  73. iup_open.set_attribute(Current, "BACKIMAGEHIGHLIGHT", name)
  74. end
  75. set_back_image_inactive (name: STRING)
  76. -- (non inheritable): background image name of the element when inactive.
  77. -- If it is not defined then the BACKIMAGE is used and its colors will be
  78. -- replaced by a modified version creating the disabled effect.
  79. do
  80. iup_open.set_attribute(Current, "BACKIMAGEINACTIVE", name)
  81. end
  82. set_back_image_press (name: STRING)
  83. -- (non inheritable): background image name of the element in pressed
  84. -- state. If it is not defined then the BACKIMAGE is used.
  85. do
  86. iup_open.set_attribute(Current, "BACKIMAGEPRESS", name)
  87. end
  88. set_border (state: BOOLEAN)
  89. -- (creation only): Shows a border around the canvas. Default: "False".
  90. do
  91. Precursor (state)
  92. end
  93. set_rgb_border_color (red: INTEGER; green: INTEGER; blue: INTEGER)
  94. -- color used for borders. Default: "50 150 255". This is for the
  95. -- flat button drawn border.
  96. do
  97. iup_open.set_attribute(Current, "BORDERCOLOR",
  98. rgb_to_string(red, green, blue))
  99. end
  100. get_rgb_border_color: TUPLE[INTEGER, INTEGER, INTEGER]
  101. -- Return the RGB values of the border color.
  102. do
  103. Result := iup_open.get_rgb(Current, "BORDERCOLOR")
  104. end
  105. set_rgb_border_pressed_color (red: INTEGER; green: INTEGER; blue: INTEGER)
  106. -- color used for borders when pressed or selected. Default use border
  107. -- color.
  108. do
  109. iup_open.set_attribute(Current, "BORDERPSCOLOR",
  110. rgb_to_string(red, green, blue))
  111. end
  112. get_rgb_border_pressed_color: TUPLE[INTEGER, INTEGER, INTEGER]
  113. -- Return the RGB values of the border pressed color.
  114. do
  115. Result := iup_open.get_rgb(Current, "BORDERPSCOLOR")
  116. end
  117. set_rgb_border_highlighted_color (red: INTEGER; green: INTEGER; blue: INTEGER)
  118. -- color used for borders when highlighted. Default use border color.
  119. do
  120. iup_open.set_attribute(Current, "BORDERHLCOLOR",
  121. rgb_to_string(red, green, blue))
  122. end
  123. get_rgb_border_highlighted_color: TUPLE[INTEGER, INTEGER, INTEGER]
  124. -- Return the RGB values of the border highlighted color.
  125. do
  126. Result := iup_open.get_rgb(Current, "BORDERHLCOLOR")
  127. end
  128. set_border_width (value: INTEGER)
  129. -- line width used for borders. Default: "1". Any borders can be hidden
  130. -- by simply setting this value to 0. This is for the flat button drawn
  131. -- border.
  132. require
  133. non_negative: value >= 0
  134. do
  135. iup_open.set_attribute(Current, "BORDERWIDTH", value.to_string)
  136. end
  137. get_border_width: INTEGER
  138. local
  139. str: STRING
  140. do
  141. str := iup_open.get_attribute(Current, "BORDERWIDTH")
  142. if str.is_integer then
  143. Result := str.to_integer
  144. end
  145. end
  146. set_fit_to_back_image (state: BOOLEAN)
  147. -- (non inheritable): enable the natural size to be computed from the
  148. -- back image. If back image is not defined will be ignored. When set to
  149. -- True it will set border width to 0. Default: False.
  150. do
  151. iup_open.set_attribute(Current, "FITTOBACKIMAGE", boolean_to_yesno(state))
  152. end
  153. set_front_image (name: STRING)
  154. -- (non inheritable): image name to be used as foreground. It will be
  155. -- zoomed to fill the foreground (it does not includes the border). The
  156. -- foreground has the same are as the background, but it is drawn at last.
  157. do
  158. iup_open.set_attribute(Current, "FRONTIMAGE", name)
  159. end
  160. set_front_image_highlight (name: STRING)
  161. -- (non inheritable): foreground image name of the element in highlight
  162. -- state. If it is not defined then the FRONTIMAGE is used.
  163. do
  164. iup_open.set_attribute(Current, "FRONTIMAGEHIGHLIGHT", name)
  165. end
  166. set_front_image_inactive (name: STRING)
  167. -- (non inheritable): foreground image name of the element when inactive.
  168. -- If it is not defined then the FRONTIMAGE is used and its colors will
  169. -- be replaced by a modified version creating the disabled effect.
  170. do
  171. iup_open.set_attribute(Current, "FRONTIMAGEINACTIVE", name)
  172. end
  173. set_front_image_press (name: STRING)
  174. -- (non inheritable): foreground image name of the element in pressed
  175. -- state. If it is not defined then the FRONTIMAGE is used.
  176. do
  177. iup_open.set_attribute(Current, "FRONTIMAGEPRESS", name)
  178. end
  179. has_focus: BOOLEAN
  180. -- Returns the button state if has focus.
  181. local
  182. str: STRING
  183. do
  184. str := iup_open.get_attribute(Current, "HASFOCUS")
  185. Result := yesno_to_boolean(str)
  186. end
  187. set_rgb_highlight_color (red: INTEGER; green: INTEGER; blue: INTEGER)
  188. -- color used to indicate a highlight state. Default: "200 225 245".
  189. do
  190. iup_open.set_attribute(Current, "HLCOLOR", rgb_to_string(red, green, blue))
  191. end
  192. get_rgb_highlight_color: TUPLE[INTEGER, INTEGER, INTEGER]
  193. do
  194. Result := iup_open.get_rgb(Current, "HLCOLOR")
  195. end
  196. is_highlighted: BOOLEAN
  197. -- Returns the button state if highlighted.
  198. local
  199. str: STRING
  200. do
  201. str := iup_open.get_attribute(Current, "HIGHLIGHTED")
  202. Result := yesno_to_boolean(str)
  203. end
  204. set_image (name: STRING)
  205. -- (non inheritable): Image name.
  206. do
  207. iup_open.set_attribute(Current, "IMAGE", name)
  208. end
  209. set_image_highlight (name: STRING)
  210. -- (non inheritable): Image name of the element in highlight state. If it
  211. -- is not defined then the IMAGE is used.
  212. do
  213. iup_open.set_attribute(Current, "IMAGEHIGHLIGHT", name)
  214. end
  215. set_image_inactive (name: STRING)
  216. -- (non inheritable): Image name of the element when inactive. If it is
  217. -- not defined then the IMAGE is used and its colors will be replaced by
  218. -- a modified version creating the disabled effect.
  219. do
  220. iup_open.set_attribute(Current, "IMAGEINACTIVE", name)
  221. end
  222. set_image_press (name: STRING)
  223. -- (non inheritable): Image name of the element in pressed state. If it
  224. -- is not defined then the IMAGE is used.
  225. do
  226. iup_open.set_attribute(Current, "IMAGEPRESS", name)
  227. end
  228. set_image_position (pos: STRING)
  229. -- (non inheritable): Position of the image relative to the text when
  230. -- both are displayed. Can be: LEFT, RIGHT, TOP, BOTTOM. Default: LEFT.
  231. require
  232. is_valid_position(pos)
  233. do
  234. iup_open.set_attribute(Current, "IMAGEPOSITION", pos)
  235. end
  236. set_padding (horizontal, vertical: INTEGER)
  237. -- internal margin. Works just like the margin attribute of the IUP_HBOX
  238. -- and IUP_VBOX containers, but uses a different name to avoid
  239. -- inheritance problems. Default value: "0x0".
  240. require
  241. horizontal >= 0
  242. vertical >= 0
  243. local
  244. margin: STRING
  245. do
  246. margin := horizontal.to_string
  247. margin.append_string("x")
  248. margin.append_string(vertical.to_string)
  249. iup_open.set_attribute(Current, "PADDING", margin)
  250. end
  251. get_padding: TUPLE[INTEGER, INTEGER]
  252. -- Return the value of the padding.
  253. local
  254. margin: STRING
  255. do
  256. margin := iup_open.get_attribute(Current, "PADDING")
  257. Result := components_of_size(margin)
  258. end
  259. is_pressed: BOOLEAN
  260. -- Returns the button state if pressed.
  261. local
  262. str: STRING
  263. do
  264. str := iup_open.get_attribute(Current, "PRESSED")
  265. Result := yesno_to_boolean(str)
  266. end
  267. set_rgb_press_color (red: INTEGER; green: INTEGER; blue: INTEGER)
  268. -- color used to indicate a press state. Default: "150 200 235".
  269. do
  270. iup_open.set_attribute(Current, "PSCOLOR", rgb_to_string(red, green, blue))
  271. end
  272. get_rgb_press_color: TUPLE[INTEGER, INTEGER, INTEGER]
  273. do
  274. Result := iup_open.get_rgb(Current, "PSCOLOR")
  275. end
  276. is_radio: BOOLEAN
  277. -- returns if the toggle is inside a radio. Valid only after the element
  278. -- is mapped and TOGGLE=True.
  279. local
  280. str: STRING
  281. do
  282. str := iup_open.get_attribute(Current, "RADIO")
  283. if is_yes_no(str) then
  284. Result := yesno_to_boolean(str)
  285. end
  286. end
  287. set_toggle (state: BOOLEAN)
  288. -- enabled the toggle behavior. Default: False.
  289. do
  290. iup_open.set_attribute(Current, "TOGGLE", boolean_to_yesno(state))
  291. end
  292. set_text_alignment (value: STRING)
  293. require
  294. is_valid_text_alignment(value)
  295. do
  296. iup_open.set_attribute(Current, "TEXTALIGNMENT", value)
  297. end
  298. get_value: STRING
  299. -- Toggle's state. Values can be "ON", "OFF" or "TOGGLE".
  300. do
  301. Result := iup_open.get_attribute(Current, "VALUE")
  302. end
  303. -- Operations
  304. set_on
  305. do
  306. iup_open.set_attribute(Current, "VALUE", "ON")
  307. end
  308. set_off
  309. do
  310. iup_open.set_attribute(Current, "VALUE", "OFF")
  311. end
  312. invert
  313. -- Invert the current state.
  314. do
  315. iup_open.set_attribute(Current, "VALUE", "TOGGLE")
  316. end
  317. -- Extra callbacks
  318. set_cb_flat_action (act: FUNCTION[TUPLE[IUP_FLAT_BUTTON], STRING])
  319. -- Action generated when the button 1 (usually left) is selected. This
  320. -- callback is called only after the mouse is released and when it is
  321. -- released inside the button area.
  322. --
  323. -- ih: identifier of the element that activated the event.
  324. --
  325. -- Returns: IUP_CLOSE will be processed.
  326. local
  327. operation: INTEGER
  328. do
  329. cb_flat_action := act
  330. if cb_flat_action /= Void then
  331. operation := 1
  332. else
  333. operation := 0
  334. end
  335. iup_open.set_callback (Current, "FLAT_ACTION", "Fnff", operation)
  336. end
  337. set_cb_flat_button (act: FUNCTION[TUPLE[IUP_FLAT_BUTTON, INTEGER, INTEGER, INTEGER, INTEGER, STRING], STRING])
  338. -- Action generated when any mouse button is pressed and when it is
  339. -- released. Both calls occur before the ACTION callback when button 1 is
  340. -- being used.
  341. -- IUP_CANVAS: identifies the element that activated the event.
  342. -- button: identifies the activated mouse button:
  343. --
  344. -- 1 - left mouse button (button 1);
  345. -- 2 - middle mouse button (button 2);
  346. -- 3 - right mouse button (button 3).
  347. --
  348. -- pressed: indicates the state of the button:
  349. --
  350. -- 0 - mouse button was released;
  351. -- 1 - mouse button was pressed.
  352. --
  353. -- x, y: position in the canvas where the event has occurred, in pixels.
  354. --
  355. -- status: status of the mouse buttons and some keyboard keys at the
  356. -- moment the event is generated. The following macros must be used for
  357. -- verification:
  358. --
  359. -- Returns: IUP_CLOSE will be processed. On some controls if IUP_IGNORE
  360. -- is returned the action is ignored (this is system dependent).
  361. local
  362. operation: INTEGER
  363. do
  364. cb_flat_button := act
  365. if cb_flat_button /= Void then
  366. operation := 1
  367. else
  368. operation := 0
  369. end
  370. iup_open.set_callback (Current, "FLAT_BUTTON_CB", "NONEEDED", operation)
  371. end
  372. set_cb_flat_focus (act: FUNCTION[TUPLE[IUP_FLAT_BUTTON, INTEGER], STRING])
  373. -- Called when the canvas gets or looses the focus. It is called after
  374. -- the common callbacks GETFOCUS_CB and KILL_FOCUS_CB.
  375. -- ih: identifier of the element that activated the event.
  376. -- focus: is non zero if the canvas is getting the focus, is zero if it
  377. -- is loosing the focus.
  378. local
  379. operation: INTEGER
  380. do
  381. cb_flat_focus := act
  382. if cb_focus /= Void then
  383. operation := 1
  384. else
  385. operation := 0
  386. end
  387. iup_open.set_callback (Current, "FLAT_FOCUS_CB", "NONEEDED", operation)
  388. end
  389. set_cb_flat_enter_window (act: FUNCTION[TUPLE[IUP_FLAT_BUTTON], STRING])
  390. -- Action generated when the mouse enters the native element.
  391. local
  392. operation: INTEGER
  393. do
  394. cb_flat_enterwindow := act
  395. if cb_enterwindow /= Void then
  396. operation := 1
  397. else
  398. operation := 0
  399. end
  400. iup_open.set_callback (Current, "FLAT_ENTERWINDOW_CB", "NONEEDED", operation)
  401. end
  402. set_cb_flat_leave_window (act: FUNCTION[TUPLE[IUP_FLAT_BUTTON], STRING])
  403. -- Action generated when the mouse leaves the native element.
  404. local
  405. operation: INTEGER
  406. do
  407. cb_flat_leavewindow := act
  408. if cb_leavewindow /= Void then
  409. operation := 1
  410. else
  411. operation := 0
  412. end
  413. iup_open.set_callback (Current, "FLAT_LEAVEWINDOW_CB", "NONEEDED", operation)
  414. end
  415. set_cb_value_changed (act: FUNCTION[TUPLE[IUP_FLAT_BUTTON], STRING])
  416. -- Called after the value was interactively changed by the
  417. -- user. Called after the ACTION callback, but under the same context.
  418. local
  419. operation: INTEGER
  420. do
  421. cb_valuechanged := act
  422. if cb_valuechanged /= Void then
  423. operation := 1
  424. else
  425. operation := 0
  426. end
  427. iup_open.set_callback (Current, "VALUECHANGED_CB", "NONEEDED", operation)
  428. end
  429. feature {IUP}
  430. -- Callbacks
  431. execute_flat_action: STRING
  432. do
  433. Result := cb_flat_action.item([Current])
  434. end
  435. execute_flat_button (btn, pressed, x, y: INTEGER; status: STRING): STRING
  436. do
  437. Result := cb_flat_button.item([Current, btn, pressed, x, y, status])
  438. end
  439. execute_flat_focus (focus: INTEGER): STRING
  440. do
  441. Result := cb_flat_focus.item([Current, focus])
  442. end
  443. execute_flat_enterwindow: STRING
  444. do
  445. Result := cb_flat_enterwindow.item([Current])
  446. end
  447. execute_flat_leavewindow: STRING
  448. do
  449. Result := cb_flat_leavewindow.item([Current])
  450. end
  451. execute_valuechanged: STRING
  452. do
  453. Result := cb_valuechanged.item([Current])
  454. end
  455. feature {}
  456. cb_flat_action: FUNCTION[TUPLE[IUP_FLAT_BUTTON], STRING]
  457. cb_flat_button: FUNCTION[TUPLE[IUP_FLAT_BUTTON, INTEGER, INTEGER, INTEGER, INTEGER, STRING], STRING]
  458. cb_flat_focus: FUNCTION[TUPLE[IUP_FLAT_BUTTON, INTEGER], STRING]
  459. cb_flat_enterwindow: FUNCTION[TUPLE[IUP_FLAT_BUTTON], STRING]
  460. cb_flat_leavewindow: FUNCTION[TUPLE[IUP_FLAT_BUTTON], STRING]
  461. cb_valuechanged: FUNCTION[TUPLE[IUP_FLAT_BUTTON], STRING]
  462. -- Internals
  463. int_flat_button (title: POINTER): POINTER
  464. external "plug_in"
  465. alias "{
  466. location: "${sys}/plugins"
  467. module_name: "iup"
  468. feature_name: "IupFlatButton"
  469. }"
  470. end
  471. -- Validations
  472. is_valid_vertical_alignment (value: STRING): BOOLEAN
  473. do
  474. if value.is_equal("ATOP") or
  475. value.is_equal("ACENTER") or
  476. value.is_equal("ABOTTOM") then
  477. Result := True
  478. else
  479. Result := False
  480. end
  481. end
  482. is_valid_horizontal_alignment (value: STRING): BOOLEAN
  483. do
  484. if value.is_equal("ALEFT") or
  485. value.is_equal("ACENTER") or
  486. value.is_equal("ARIGHT") then
  487. Result := True
  488. else
  489. Result := False
  490. end
  491. end
  492. is_valid_position (value: STRING): BOOLEAN
  493. do
  494. if value.is_equal("LEFT") or
  495. value.is_equal("RIGHT") or
  496. value.is_equal("TOP") or
  497. value.is_equal("BOTTOM") then
  498. Result := True
  499. else
  500. Result := False
  501. end
  502. end
  503. is_valid_text_alignment (value: STRING): BOOLEAN
  504. do
  505. if value.is_equal("ALEFT") or
  506. value.is_equal("ACENTER") or
  507. value.is_equal("ARIGHT") then
  508. Result := True
  509. else
  510. Result := False
  511. end
  512. end
  513. end -- class IUP_FLAT_BUTTON
  514. -- The MIT License (MIT)
  515. -- Copyright (c) 2016, 2017 by German A. Arias
  516. -- Permission is hereby granted, free of charge, to any person obtaining a copy
  517. -- of this software and associated documentation files (the "Software"), to deal
  518. -- in the Software without restriction, including without limitation the rights
  519. -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  520. -- copies of the Software, and to permit persons to whom the Software is
  521. -- furnished to do so, subject to the following conditions:
  522. --
  523. -- The above copyright notice and this permission notice shall be included in
  524. -- all copies or substantial portions of the Software.
  525. --
  526. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  527. -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  528. -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  529. -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  530. -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  531. -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  532. -- SOFTWARE.