twidget.h - ltk - Socket-based GUI for X11 (WIP)
HTML git clone git://lumidify.org/ltk.git (fast, but not encrypted)
HTML git clone https://lumidify.org/git/ltk.git (encrypted, but very slow)
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
twidget.h (8719B)
---
1 /*
2 * Copyright (c) 2021-2023 lumidify <nobody@lumidify.org>
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #ifndef LTK_WIDGET_H
18 #define LTK_WIDGET_H
19
20 #include "err.h"
21 #include "rect.h"
22 #include "event.h"
23 #include "config.h"
24
25 /* FIXME: SORT OUT INCLUDES PROPERLY! */
26
27 typedef struct ltk_widget ltk_widget;
28 typedef uint32_t ltk_widget_type;
29
30 typedef enum {
31 LTK_ACTIVATABLE_NORMAL = 1,
32 LTK_ACTIVATABLE_SPECIAL = 2,
33 LTK_ACTIVATABLE_ALWAYS = 1|2,
34 /* FIXME: redundant or needs better name - is implied by entries in vtable
35 - if there are widgets that have keyboard functions in the vtable but
36 shouldn't have this set, then it's a bad name */
37 LTK_NEEDS_KEYBOARD = 4,
38 LTK_NEEDS_REDRAW = 8,
39 LTK_HOVER_IS_ACTIVE = 16,
40 } ltk_widget_flags;
41
42 typedef enum {
43 LTK_STICKY_NONE = 0,
44 LTK_STICKY_LEFT = 1 << 0,
45 LTK_STICKY_RIGHT = 1 << 1,
46 LTK_STICKY_TOP = 1 << 2,
47 LTK_STICKY_BOTTOM = 1 << 3,
48 LTK_STICKY_SHRINK_WIDTH = 1 << 4,
49 LTK_STICKY_SHRINK_HEIGHT = 1 << 5,
50 LTK_STICKY_PRESERVE_ASPECT_RATIO = 1 << 6,
51 } ltk_sticky_mask;
52
53 typedef enum {
54 LTK_VERTICAL,
55 LTK_HORIZONTAL
56 } ltk_orientation;
57
58 typedef enum {
59 LTK_NORMAL = 0,
60 LTK_HOVER = 1,
61 LTK_PRESSED = 2,
62 LTK_ACTIVE = 4,
63 LTK_HOVERACTIVE = 1 | 4,
64 LTK_FOCUSED = 8,
65 LTK_DISABLED = 16,
66 } ltk_widget_state;
67
68 #include "surface_cache.h"
69
70 struct ltk_window;
71
72 struct ltk_widget_vtable;
73
74 typedef struct {
75 int client; /* index of client */
76 uint32_t mask; /* generic event mask */
77 uint32_t lmask; /* generic lock mask */
78 uint32_t wmask; /* event mask for specific widget type */
79 uint32_t lwmask; /* lock event mask for specific widget type */
80 } client_event_mask;
81
82 struct ltk_widget {
83 struct ltk_window *window;
84 struct ltk_widget *parent;
85 char *id;
86
87 struct ltk_widget_vtable *vtable;
88
89 /* FIXME: crect and lrect are a bit weird still */
90 /* FIXME: especially the relative positioning is really weird for
91 popups because they're positioned globally but still have a
92 parent-child relationship - weird things can probably happen */
93 /* both rects relative to parent (except for popups) */
94 /* collision rect is only part that is actually shown and used for
95 collision with mouse (but may still not be drawn if hidden by
96 something else) - e.g. in a box with scrolling, a widget that
97 is half cut off by a side of the box will have the logical rect
98 going past the side of the box, but the collision rect will only
99 be the part inside the box */
100 ltk_rect crect; /* collision rect */
101 ltk_rect lrect; /* logical rect */
102 unsigned int ideal_w;
103 unsigned int ideal_h;
104
105 client_event_mask *event_masks;
106 /* FIXME: kind of a waste of space to use size_t here */
107 size_t masks_num;
108 size_t masks_alloc;
109
110 ltk_widget_state state;
111 unsigned int sticky;
112 unsigned short row;
113 unsigned short column;
114 unsigned short row_span;
115 unsigned short column_span;
116 /* needed to properly handle handle local coordinates since
117 popups are positioned globally instead of locally */
118 char popup;
119 char dirty;
120 char hidden;
121 };
122
123 struct ltk_widget_vtable {
124 int (*key_press)(struct ltk_widget *, ltk_key_event *);
125 int (*key_release)(struct ltk_widget *, ltk_key_event *);
126 /* press/release also receive double/triple-click/release */
127 int (*mouse_press)(struct ltk_widget *, ltk_button_event *);
128 int (*mouse_release)(struct ltk_widget *, ltk_button_event *);
129 int (*mouse_scroll)(struct ltk_widget *, ltk_scroll_event *);
130 int (*motion_notify)(struct ltk_widget *, ltk_motion_event *);
131 int (*mouse_leave)(struct ltk_widget *, ltk_motion_event *);
132 int (*mouse_enter)(struct ltk_widget *, ltk_motion_event *);
133 int (*press)(struct ltk_widget *);
134 int (*release)(struct ltk_widget *);
135 void (*cmd_return)(struct ltk_widget *self, char *text, size_t len);
136
137 void (*resize)(struct ltk_widget *);
138 void (*hide)(struct ltk_widget *);
139 /* draw_surface: surface to draw it on
140 x, y: position of logical rectangle on surface
141 clip: clipping rectangle, relative to logical rectangle */
142 void (*draw)(struct ltk_widget *self, ltk_surface *draw_surface, int x, int y, ltk_rect clip);
143 void (*change_state)(struct ltk_widget *, ltk_widget_state);
144 void (*destroy)(struct ltk_widget *, int);
145
146 /* rect is in self's coordinate system */
147 struct ltk_widget *(*nearest_child)(struct ltk_widget *self, ltk_rect rect);
148 struct ltk_widget *(*nearest_child_left)(struct ltk_widget *self, ltk_widget *widget);
149 struct ltk_widget *(*nearest_child_right)(struct ltk_widget *self, ltk_widget *widget);
150 struct ltk_widget *(*nearest_child_above)(struct ltk_widget *self, ltk_widget *widget);
151 struct ltk_widget *(*nearest_child_below)(struct ltk_widget *self, ltk_widget *widget);
152 struct ltk_widget *(*next_child)(struct ltk_widget *self, ltk_widget *child);
153 struct ltk_widget *(*prev_child)(struct ltk_widget *self, ltk_widget *child);
154 struct ltk_widget *(*first_child)(struct ltk_widget *self);
155 struct ltk_widget *(*last_child)(struct ltk_widget *self);
156
157 void (*child_size_change)(struct ltk_widget *, struct ltk_widget *);
158 int (*remove_child)(struct ltk_widget *, struct ltk_widget *, ltk_error *);
159 /* x and y relative to widget's lrect! */
160 struct ltk_widget *(*get_child_at_pos)(struct ltk_widget *, int x, int y);
161 /* r is in self's coordinate system */
162 void (*ensure_rect_shown)(struct ltk_widget *self, ltk_rect r);
163
164 ltk_widget_type type;
165 ltk_widget_flags flags;
166 };
167
168 void ltk_widget_hide(ltk_widget *widget);
169 int ltk_widget_destroy(ltk_widget *widget, int shallow, ltk_error *err);
170 int ltk_widget_destroy_cmd(struct ltk_window *window, ltk_cmd_token *tokens, size_t num_tokens, ltk_error *err);
171 void ltk_fill_widget_defaults(ltk_widget *widget, const char *id, struct ltk_window *window,
172 struct ltk_widget_vtable *vtable, int w, int h);
173 void ltk_widget_change_state(ltk_widget *widget, ltk_widget_state old_state);
174 /* FIXME: move to separate window.h */
175 void ltk_window_key_press_event(ltk_window *window, ltk_key_event *event);
176 void ltk_window_key_release_event(ltk_window *window, ltk_key_event *event);
177 void ltk_window_mouse_press_event(ltk_window *window, ltk_button_event *event);
178 void ltk_window_mouse_scroll_event(ltk_window *window, ltk_scroll_event *event);
179 void ltk_window_mouse_release_event(ltk_window *window, ltk_button_event *event);
180 void ltk_window_motion_notify_event(ltk_window *window, ltk_motion_event *event);
181 void ltk_window_fake_motion_event(ltk_window *window, int x, int y);
182 int ltk_widget_id_free(const char *id);
183 ltk_widget *ltk_get_widget(const char *id, ltk_widget_type type, ltk_error *err);
184 void ltk_set_widget(ltk_widget *widget, const char *id);
185 void ltk_remove_widget(const char *id);
186 void ltk_widgets_init();
187 void ltk_widget_resize(ltk_widget *widget);
188 void ltk_widget_remove_client(int client);
189 void ltk_widget_set_event_mask(ltk_widget *widget, int client, uint32_t mask);
190 void ltk_widget_set_event_lmask(ltk_widget *widget, int client, uint32_t mask);
191 void ltk_widget_set_event_wmask(ltk_widget *widget, int client, uint32_t mask);
192 void ltk_widget_set_event_lwmask(ltk_widget *widget, int client, uint32_t mask);
193 void ltk_widget_add_to_event_mask(ltk_widget *widget, int client, uint32_t mask);
194 void ltk_widget_add_to_event_lmask(ltk_widget *widget, int client, uint32_t mask);
195 void ltk_widget_add_to_event_wmask(ltk_widget *widget, int client, uint32_t mask);
196 void ltk_widget_add_to_event_lwmask(ltk_widget *widget, int client, uint32_t mask);
197 void ltk_widget_remove_from_event_mask(ltk_widget *widget, int client, uint32_t mask);
198 void ltk_widget_remove_from_event_lmask(ltk_widget *widget, int client, uint32_t mask);
199 void ltk_widget_remove_from_event_wmask(ltk_widget *widget, int client, uint32_t mask);
200 void ltk_widget_remove_from_event_lwmask(ltk_widget *widget, int client, uint32_t mask);
201
202
203 /* FIXME: document that pointers inside binding are taken over! */
204 int ltk_widget_register_keypress(const char *func_name, size_t func_len, ltk_keypress_binding b);
205 int ltk_widget_register_keyrelease(const char *func_name, size_t func_len, ltk_keyrelease_binding b);
206 void ltk_widget_cleanup(void);
207
208 #endif /* LTK_WIDGET_H */