2 * Copyright (C) 2024 Mikulas Patocka
4 * This file is part of Ajla.
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
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.
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/>.
19 private unit ui.widget.fkeys;
21 uses ui.widget.common;
25 fn fkeys_init(n_keys : int, color_scheme : bytes, w : world, app : appstate, id : wid) : (world, appstate, fkeys_state);
26 fn fkeys_redraw(app : appstate, curs : curses, com : widget_common, st : fkeys_state) : curses;
27 fn fkeys_process_event(w : world, app : appstate, com : widget_common, st : fkeys_state, wev : wevent) : (world, appstate, widget_common, fkeys_state);
29 const fkeys_class~flat := widget_class.[
32 is_selectable : false,
33 redraw : fkeys_redraw,
34 process_event : fkeys_process_event,
40 labels : list(string);
45 fn fkeys_load(implicit app : appstate, implicit st : fkeys_state) : fkeys_state
47 var p := property_get("fkeys");
49 for i := 0 to len(st.labels) do [
51 st.labels[i] := p.l[i].s;
58 fn fkeys_init(n_keys : int, color_scheme : bytes, implicit w : world, implicit app : appstate, id : wid) : (world, appstate, fkeys_state)
60 property_observe(id, "fkeys");
61 implicit st := fkeys_state.[
62 labels : fill(``, n_keys),
63 lengths : fill(0, n_keys),
64 color_scheme : color_scheme,
69 fn fkeys_reflow(implicit app : appstate, implicit com : widget_common, implicit st : fkeys_state) : (appstate, widget_common, fkeys_state)
72 for i := 0 to len(st.labels) do [
75 num_size += len(ntos(i + 1));
77 var label_size := max(com.size_x - num_size, 0);
78 for i := 0 to len(st.labels) do [
79 st.lengths[i] := label_size div len(st.labels) + select(i < label_size mod len(st.labels), 0, 1);
84 fn fkeys_redraw(implicit app : appstate, implicit curs : curses, com : widget_common, st : fkeys_state) : curses
86 var pn := property_get_attrib(st.color_scheme + "fkeys-number", #aaaa, #aaaa, #aaaa, #0000, #0000, #0000, 0, 0);
87 var pt := property_get_attrib(st.color_scheme + "fkeys-text", #0000, #0000, #0000, #aaaa, #aaaa, #aaaa, 0, curses_invert);
89 for i := 0 to len(st.labels) do [
90 property_set_attrib(pn);
93 curses_print(utf8_to_string(ntos(i + 1)));
94 property_set_attrib(pt);
95 var s := st.labels[i];
96 var l := st.lengths[i];
97 s := list_right_pad(s, l, ' ')[ .. l];
102 fn fkeys_process_event(implicit w : world, implicit app : appstate, implicit com : widget_common, implicit st : fkeys_state, wev : wevent) : (world, appstate, widget_common, fkeys_state)
104 if wev is resize then [
106 com.size_x := wev.resize.x;
107 com.y := wev.resize.y - 1;
112 if wev is property_changed then [
116 if wev is keyboard then [
117 widget_enqueue_event_to_underlying(com.self, wev);
120 if wev is mouse then [
122 var mx, my := widget_relative_mouse_coords(com.self, wev.mouse);
123 if (wev.mouse.prev_buttons and not wev.mouse.buttons) <> 0, my = 0 then [
124 for i := 0 to len(st.labels) do [
131 this_len += len(ntos(i + 1));
132 this_len += st.lengths[i];
133 if mx < this_len then [
140 widget_enqueue_event_to_underlying(com.self, wev);
143 var wev_f := wevent.keyboard.(event_keyboard.[
144 key : key_f1 - clicked,
148 widget_enqueue_event_to_underlying(com.self, wev_f);
154 widget_enqueue_event(com.self, wevent.redraw.(event_redraw.[