verify: implement P_Array_Append_One
[ajla.git] / stdlib / ui / widget / button.ajla
blob978c4dce0737dc0214a1a6f651cc57bff95adaf6
1 {*
2  * Copyright (C) 2024 Mikulas Patocka
3  *
4  * This file is part of Ajla.
5  *
6  * Ajla is free software: you can redistribute it and/or modify it under the
7  * terms of the GNU General Public License as published by the Free Software
8  * Foundation, either version 3 of the License, or (at your option) any later
9  * version.
10  *
11  * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13  * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * Ajla. If not, see <https://www.gnu.org/licenses/>.
17  *}
19 private unit ui.widget.button;
21 uses ui.widget.common;
23 type button_state;
25 fn button_no_action(w : world, app : appstate, id : wid) : (world, appstate);
26 fn button_init(label : string, braces : bool, color_scheme : bytes, change_focus : fn(world, appstate, wid) : (world, appstate), click : fn(world, appstate, wid) : (world, appstate), w : world, app : appstate, id : wid) : (world, appstate, button_state);
27 fn button_get_width(app : appstate, com : widget_common, st : button_state, x : int) : int;
28 fn button_redraw(app : appstate, curs : curses, com : widget_common, st : button_state) : curses;
29 fn button_get_cursor(app : appstate, com : widget_common, st : button_state) : (int, int);
30 fn button_accepts_key(app : appstate, com : widget_common, st : button_state, k : event_keyboard) : bool;
31 fn button_process_event(w : world, app : appstate, com : widget_common, st : button_state, wev : wevent) : (world, appstate, widget_common, button_state);
33 const button_class~flat := widget_class.[
34         t : button_state,
35         name : "button",
36         is_selectable : true,
37         get_width : button_get_width,
38         redraw : button_redraw,
39         get_cursor : button_get_cursor,
40         accepts_key : button_accepts_key,
41         process_event : button_process_event,
44 implementation
46 record button_state [
47         label : string;
48         braces : bool;
49         color_scheme : bytes;
50         change_focus : fn(world, appstate, wid) : (world, appstate);
51         click : fn(world, appstate, wid) : (world, appstate);
54 fn button_no_action(implicit w : world, implicit app : appstate, id : wid) : (world, appstate)
58 fn button_init(label : string, braces : bool, color_scheme : bytes, change_focus : fn(world, appstate, wid) : (world, appstate), click : fn(world, appstate, wid) : (world, appstate), implicit w : world, implicit app : appstate, id : wid) : (world, appstate, button_state)
60         return button_state.[
61                 label : label,
62                 braces : braces,
63                 color_scheme : color_scheme,
64                 change_focus : change_focus,
65                 click : click,
66         ];
69 fn button_get_width(app : appstate, com : widget_common, st : button_state, x : int) : int
71         if st.braces then
72                 return string_length(`[ ` + st.label + ` ]`);
73         else
74                 return string_length(st.label);
77 fn button_redraw(implicit app : appstate, implicit curs : curses, com : widget_common, st : button_state) : curses
79         curses_set_pos(0, 0);
80         if widget_is_top(com.self) then [
81                 property_set_attrib(property_get_attrib(st.color_scheme + "button-selected", #ffff, #ffff, #ffff, #0000, #0000, #0000, curses_bold, curses_bold));
82         ] else [
83                 property_set_attrib(property_get_attrib(st.color_scheme + "button", #0000, #0000, #0000, #aaaa, #aaaa, #aaaa, 0, curses_invert));
84         ]
85         if st.braces then
86                 curses_print(`[ ` + st.label + ` ]`);
87         else
88                 curses_print(st.label);
91 fn button_get_cursor(implicit app : appstate, com : widget_common, st : button_state) : (int, int)
93         return select(st.braces, 0, 2), 0;
96 fn button_accepts_key(app : appstate, com : widget_common, st : button_state, k : event_keyboard) : bool
98         return k.key = key_enter or k.key = ' ';
101 fn button_process_event(implicit w : world, implicit app : appstate, implicit com : widget_common, implicit st : button_state, wev : wevent) : (world, appstate, widget_common, button_state)
103         if wev is keyboard then [
104                 st.click(com.self);
105                 return;
106         ]
107         if wev is mouse, wev.mouse.prev_buttons = 1, wev.mouse.buttons = 0 then [
108                 st.click(com.self);
109                 return;
110         ]
111         if wev is change_focus then [
112                 st.change_focus(com.self);
113                 widget_enqueue_event(com.self, wevent.redraw.(event_redraw.[
114                         x1 : 0,
115                         x2 : com.size_x,
116                         y1 : 0,
117                         y2 : com.size_y,
118                 ]));
119                 return;
120         ]