File: gui_widget.h

package info (click to toggle)
lbreakout2 2.5.2-2.1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k, lenny
  • size: 6,040 kB
  • ctags: 2,374
  • sloc: ansic: 20,911; sh: 2,891; makefile: 374
file content (386 lines) | stat: -rw-r--r-- 14,976 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
/***************************************************************************
                          gui_widget.h  -  description
                             -------------------
    begin                : Fri Oct 11 2002
    copyright            : (C) 2002 by Michael Speck
    email                : kulkanie@gmx.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef __GUI_WIDGET_H
#define __GUI_WIDGET_H

#include "list.h"
#include "stk.h"
#include "gui_theme.h"

//#define GUI_DEBUG

#define GUI_ABORT( msg ) \
 { fprintf( stderr, "Fatal GUI Error!\n%s\n", msg ); exit( 1 ); }
 
/*
====================================================================
GUI events
====================================================================
*/

/* types */
enum {
    GUI_NONE = 0,
    GUI_DESTROY,            /* widget is deleted */
    GUI_ACTIVATED,
    GUI_DEACTIVATED,        /* handle _input_ events or not */
    GUI_DRAW,               /* draw widget to stk_display */
    GUI_TIME_PASSED,        /* msecs since last TIME_PASSED event */
    GUI_FOCUS_IN,           /* widget lost focus */
    GUI_FOCUS_OUT,          /* widget gained focus */
    GUI_MOTION,             /* motion within widget */
    GUI_BUTTON_PRESSED,     
    GUI_BUTTON_RELEASED,    /* mouse button */
    GUI_KEY_PRESSED,
    GUI_KEY_RELEASED,       /* key */
    GUI_CLICKED,            /* mouse button pressed + released */
    GUI_CHANGED,            /* type-dependent data changed */
    GUI_ITEM_SELECTED,      
    GUI_ITEM_UNSELECTED     /* list item (un)selected */
};

/* event */
typedef union {
    int type;
    struct {
        int type;
        int x, y, button;
    } button;
    struct {
        int type;
        int x, y, xrel, yrel;
        int button; /* first button pressed */
        int state; /* full button mask */
    } motion;
    struct {
        int type;
        int keysym;
        int unicode;
    } key;
    struct {
        int type;
        int x, y;
    } item;
    struct {
        int type;
        int ms;
    } time;
} GuiEvent;

/*
====================================================================
Return pointer to simple event (one that doesn't need
additional data)
====================================================================
*/
GuiEvent *gui_event_get_simple( int type );

/*
====================================================================
Initiate a GUI event from an SDL event.
====================================================================
*/
void gui_event_init( GuiEvent *gui_event, SDL_Event *sdl_event );

/*
====================================================================
GUI widget
====================================================================
*/

/* types */
enum {
    GUI_BOX = 0,
    GUI_BUTTON,
    GUI_LABEL,
    GUI_ICON,
    GUI_PROGRESSBAR,
    GUI_RADIOGROUP,
    GUI_SCROLLBAR,
    GUI_EDIT,
    GUI_LIST,
    GUI_SPINBUTTON
};

/* GUI widget - 
   for simplicity only one is used for all types */
typedef struct _GuiWidget {
    struct _GuiWidget *parent; /* widget's parent */
    struct _GuiWidget *root;   /* widget's root (top parent) */
    List *widgets;             /* widget's children */
    struct _GuiWidget *focused_widget; /* recursivly in widgets */
    struct _GuiWidget *default_key_widget; 
        /* child 'default_key_widget' will grab key input if this
           is a root widget that is shown */
    int  type;       /* button, label, icon ... */
    int  visible;    /* gui_widget_draw() updates screen */
    int  active;     /* accept events */
    int  focused;    /* mouse pointer somewhere in widget */
    int  grab_input; /* deny event handling to lower roots */
    int  grab_keys;  /* grab key input if clicked */
    int  grab_focus; /* grab focus IF PRESSED thus motion events
                        are directly passed to widgets handler.
                        the focus is not updated until mouse button
                        is released again. */
    int  pressed;    /* memorize 'button_pressed' event */
    SDL_Rect screen_region; /* absolute region in screen (clipped) */
    SDL_Rect parent_region; /* relative region in parent */
    /* CALLBACKS */
    void (*default_event_handler)(struct _GuiWidget*,GuiEvent*); 
        /* handles event and updates a widget (graphics etc) */
    void (*user_event_handler)(struct _GuiWidget*,GuiEvent*); 
        /* user's possibility to react on event. is NOT called
           from the default_event_handler but from 
           gui_widget_handle_event() itself. */
    /* USED BY ALL WIDGETS BUT TYPE DEPENDANT */
    int  border;        /* size of frame around widget */
    int  width, height; /* widget's size w/o border */
    int  event_mask;    /* events passed to user's event_handler */
    SDL_Surface *surface; /* picture of widget */
    /* SPECS */
    union {
        /* LABEL */
        struct {
            StkFont *font; 
            int     align; /* alignment of text */
            char    *text; /* text */
        } label;
        /* PROGRESSBAR */
        struct {
            int max;    /* maximum value */
            int value;  /* current value */
            int length; /* current length */
            SDL_Surface *wallpaper; /* current beam wallpaper */
        } progressbar;
        /* RADIOGROUP */
        struct {
            int min; /* minimum selections required */
            int max; /* minimum selections allowed */
            int size; /* number of items */
            int *checks;      /* 'checked' flag for each item */
            int check_count;  /* number of selections */
            int single_check; /* id of last item selected */
            int x, y;   /* position of first checkbox in parent */
            int offset; /* offset from one item to next */
        } radiogroup;
        /* SCROLLBAR */
        struct {
            int vertical;    /* vertical scrollbar? */
            int button_size; /* size of (square) buttons */
            int value;       /* current value */
            int min, max;    /* range of value */
            int step;        /* offset for up/down */
            int jump;        /* offset for pgup/pgdown */
            struct _GuiWidget *inc;
            struct _GuiWidget *dec; /* pointers to 'widgets' */
            struct _GuiWidget *track; /* special widget that is NOT
                                         in the 'widgets' list */
        } scrollbar;
        /* EDIT */
        struct {
            int  filter[SDLK_LAST]; /* characters accepted */
            int  multi_line; /* single-line edit or text area? */
            int  size;    /* character limit */
            char *buffer; /* string of edit */
            char *display_buffer; /* contains 'height' lines of 
                length 'width' separated by \0 which will be 
                displayed when drawing. is rendered by 
                gui_edit_adjust_cursor() */
            int  length; /* current string length */
            int  width;  /* characters per line */
            int  height; /* number of lines */
            int  x, y;   /* position in visible characters */
            int  y_offset; /* used to center single-line edits */
            int  pos;    /* position of edit cursor */
            int  start;  /* first character displayed */
            int  line;   /* first line displayed (start/width) */
        } edit;
        /* LIST */
        struct {
            int columns;        /* (fixed) number of columns */
            int item_width;
            int item_height;    /* item size */
            int gap;            /* space between items */
            int rows_per_page;  /* number of rows displayed */
            int item_count;     /* number of items */
            int rows;           /* number of rows */
            int select_type;    /* no, single, multi select */
            int *checks; /* NO_SELECT:     unused
                            SINGLE_SELECT: id of selected item
                            MULTI_SELECT:  flags for all items 
                                           whether they are 
                                           selected or not */
            SDL_Surface 
                *render_buffer; /* 'render_item' renders item 
                                    into this surface*/
            int (*render_item)(int,int,SDL_Surface*); /* user
                defined render callback to render item x,y into
                surface. This item is only displayed
                if 'render_item' returns True. */
            struct _GuiWidget  *scrollbar; /* pointer to 
                                              'widgets' */
        } list;
        /* SPINBUTTON */
        struct {
            int       min, max, step; /* range of value */
            int       value;          /* value */
            struct _GuiWidget *edit;  /* pointer to edit */
            struct _GuiWidget *inc;
            struct _GuiWidget *dec;   /* pointer to buttons */
        } spinbutton;
    } spec;
} GuiWidget;

/*
====================================================================
Create a basic widget and setup things all different widget types
have in common. If a parent is specified this widget is added to 
it's 'widgets' list. 'x' or 'y' -1 means to center the
widget.
====================================================================
*/
GuiWidget* gui_widget_create( 
    GuiWidget *parent, int type, 
    int x, int y, int width, int height,
    void (*default_event_handler)(GuiWidget*,GuiEvent*),
    void (*user_event_handler)(GuiWidget*,GuiEvent*) );

/*
====================================================================
This function will delete a root widget including all subwidgets.
Subwidgets can't be directly deleted. Resets the widget 
pointer to NULL.
====================================================================
*/
void gui_widget_delete( GuiWidget **widget );

/*
====================================================================
If button is deactivated no input events (key,button,motion)
are handled.
====================================================================
*/
void gui_widget_set_active( GuiWidget *widget, int active );

/*
====================================================================
Draw the widget and its children if visible.
====================================================================
*/
void gui_widget_draw( GuiWidget *widget );

/*
====================================================================
Set 'visible' flag and draw widget (store update rects)
if either parent is visible or it has no parent. 
(thus is a root window). If it is a root window add it to the
root window stack. This new window will handle incoming events
first. 
====================================================================
*/
void gui_widget_show( GuiWidget *widget );

/*
====================================================================
Clear 'visible' flag and restore widget if parent is visible.
If there is no parent (thus is a root window) remove it from
stack and redraw the underlying window (which regains control). If 
a root widget is hidden the background cannot be restored
as it is unknown.
====================================================================
*/
void gui_widget_hide( GuiWidget *widget );

/*
====================================================================
Modify the event mask of a widget to define which events will
be passed to user_event_handler. Update timed_stack if 
GUI_TIME_PASSED is enabled/disabled.
====================================================================
*/
void gui_widget_enable_event( GuiWidget *widget, int event );
void gui_widget_disable_event( GuiWidget *widget, int event );

/*
====================================================================
Pass GuiEvent to user defined callback if it has been installed
and the event mask flag is True for this event.
====================================================================
*/
void gui_widget_call_user_event_handler(
    GuiWidget *widget, GuiEvent *event );
    
/*
====================================================================
Handle the GUI event by calling the default_event_handler()
and the user_event_handler() if one has been installed.
====================================================================
*/
void gui_widget_handle_event( GuiWidget *widget, GuiEvent *event );

/*
====================================================================
Move widget within parent window by a relative value. If the 
widget is visible the changes will be drawn to screen.
====================================================================
*/
void gui_widget_move( GuiWidget *widget, int rel_x, int rel_y );

/*
====================================================================
Move widget within parent window by an absolute value. If the 
widget is visible the changes will be drawn to screen.
====================================================================
*/
void gui_widget_warp( GuiWidget *widget, int abs_x, int abs_y );

/*
====================================================================
Apply parents background or wallpaper within the frame (if
any) of the widget's surface.
====================================================================
*/
void gui_widget_apply_wallpaper( 
    GuiWidget *widget, SDL_Surface *wallpaper, int alpha );
    
/*
====================================================================
Browse the widget tree and set 'focused' true for all widgets
that have the mouse pointer above them. 'focused_widget'
returns the deepest widget that is focused.
====================================================================
*/
void gui_widget_update_focus( 
    GuiWidget *widget, int mx, int my, GuiWidget **focused_widget );
    
/*
====================================================================
Get direct access to widget's surface.
====================================================================
*/
SDL_Surface *gui_widget_get_surface( GuiWidget *widget );

/*
====================================================================
That key grabbing child of a root widget.
====================================================================
*/
void gui_widget_set_default_key_widget( 
    GuiWidget *root, GuiWidget *key_widget );

#endif