ltk

Socket-based GUI for X11 (WIP)
git clone git://lumidify.org/ltk.git (fast, but not encrypted)
git clone https://lumidify.org/git/ltk.git (encrypted, but very slow)
Log | Files | Refs | README | LICENSE

widget.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 */