summaryrefslogtreecommitdiff
path: root/src/ui/widget.h
blob: bf6489a09adf015046862e3e91e9021de04a342c (plain)
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
#pragma once

/* Base class for UI widgets. */

#include "metrics.h"

#include <the_Foundation/object.h>
#include <the_Foundation/objectlist.h>
#include <the_Foundation/rect.h>
#include <the_Foundation/string.h>
#include <SDL_events.h>

#define iDeclareWidgetClass(className) \
    iDeclareType(className); \
    typedef iWidgetClass i##className##Class; \
    extern i##className##Class Class_##className;

iDeclareType(Widget)
iBeginDeclareClass(Widget)
    iBool (*processEvent)   (iWidget *, const SDL_Event *);
    void  (*draw)           (const iWidget *);
iEndDeclareClass(Widget)

enum iWidgetFlag {
    hidden_WidgetFlag         = iBit(1),
    disabled_WidgetFlag       = iBit(2),
    hover_WidgetFlag          = iBit(3), /* eligible for mouse hover */
    selected_WidgetFlag       = iBit(4),
    pressed_WidgetFlag        = iBit(5),
    alignLeft_WidgetFlag      = iBit(6),
    alignRight_WidgetFlag     = iBit(7),
    frameless_WidgetFlag      = iBit(8),
    commandOnClick_WidgetFlag = iBit(9),
    drawKey_WidgetFlag        = iBit(10),
    focusable_WidgetFlag      = iBit(11),
    tight_WidgetFlag          = iBit(12), /* smaller padding */
    keepOnTop_WidgetFlag      = iBit(13), /* gets events first; drawn last */
    /* arrange behavior */
    arrangeHorizontal_WidgetFlag           = iBit(17), /* arrange children horizontally */
    arrangeVertical_WidgetFlag             = iBit(18), /* arrange children vertically */
    arrangeWidth_WidgetFlag                = iBit(19), /* area of children becomes parent size */
    arrangeHeight_WidgetFlag               = iBit(20), /* area of children becomes parent size */
    resizeWidthOfChildren_WidgetFlag       = iBit(21),
    resizeHeightOfChildren_WidgetFlag      = iBit(22),
    expand_WidgetFlag                      = iBit(23),
    fixedWidth_WidgetFlag                  = iBit(24),
    fixedHeight_WidgetFlag                 = iBit(25),
    resizeChildrenToWidestChild_WidgetFlag = iBit(26),
    resizeToParentWidth_WidgetFlag         = iBit(27),
    resizeToParentHeight_WidgetFlag        = iBit(28),
    moveToParentRightEdge_WidgetFlag       = iBit(29),
    collapse_WidgetFlag                    = iBit(30), /* when hidden, arrange size to zero */
    wasCollapsed_WidgetFlag                = iBit(31),
    /* combinations */
    arrangeSize_WidgetFlag    = arrangeWidth_WidgetFlag | arrangeHeight_WidgetFlag,
    resizeChildren_WidgetFlag = resizeWidthOfChildren_WidgetFlag | resizeHeightOfChildren_WidgetFlag,
    fixedSize_WidgetFlag      = fixedWidth_WidgetFlag | fixedHeight_WidgetFlag,
};

enum iWidgetAddPos {
    back_WidgetAddPos,
    front_WidgetAddPos,
};

enum iWidgetFocusDir {
    forward_WidgetFocusDir,
    backward_WidgetFocusDir,
};

struct Impl_Widget {
    iObject      object;
    iString      id;
    int          flags;
    iRect        rect;
    int          bgColor;
    int          frameColor;
    iObjectList *children;
    iWidget *    parent;
    iBool (*commandHandler)(iWidget *, const char *);
};

iDeclareObjectConstruction(Widget)

iLocalDef iWidget *as_Widget(iAnyObject *d) {
#if !defined (NDEBUG)
    if (d) {
        iAssertIsObject(d);
        iAssert(isInstance_Object(d, &Class_Widget));
    }
#endif
    return (iWidget *) d;
}

iLocalDef const iWidget *constAs_Widget(const iAnyObject *d) {
#if !defined (NDEBUG)
    if (d) {
        iAssertIsObject(d);
        iAssert(isInstance_Object(d, &Class_Widget));
    }
#endif
    return (const iWidget *) d;
}

void    destroy_Widget      (iWidget *); /* widget removed and deleted later */
void    destroyPending_Widget(void);

const iString *id_Widget    (const iWidget *);
int     flags_Widget        (const iWidget *);
iRect   bounds_Widget       (const iWidget *);
iInt2   localCoord_Widget   (const iWidget *, iInt2 coord);
iBool   contains_Widget     (const iWidget *, iInt2 coord);
iAny *  findChild_Widget    (const iWidget *, const char *id);
iAny *  findFocusable_Widget(const iWidget *startFrom, enum iWidgetFocusDir focusDir);
size_t  childCount_Widget   (const iWidget *);
void    draw_Widget         (const iWidget *);

iBool   isVisible_Widget    (const iWidget *);
iBool   isDisabled_Widget   (const iWidget *);
iBool   isFocused_Widget    (const iWidget *);
iBool   isHover_Widget      (const iWidget *);
iBool   isSelected_Widget   (const iWidget *);
iBool   isCommand_Widget    (const iWidget *d, const SDL_Event *ev, const char *cmd);
iBool   hasParent_Widget    (const iWidget *d, const iWidget *someParent);
void    setId_Widget        (iWidget *, const char *id);
void    setFlags_Widget     (iWidget *, int flags, iBool set);
void    setPos_Widget       (iWidget *, iInt2 pos);
void    setSize_Widget      (iWidget *, iInt2 size);
void    setBackgroundColor_Widget   (iWidget *, int bgColor);
void    setFrameColor_Widget        (iWidget *, int frameColor);
void    setCommandHandler_Widget    (iWidget *, iBool (*handler)(iWidget *, const char *));
iAny *  addChild_Widget     (iWidget *, iAnyObject *child); /* holds a ref */
iAny *  addChildPos_Widget  (iWidget *, iAnyObject *child, enum iWidgetAddPos addPos);
iAny *  addChildFlags_Widget(iWidget *, iAnyObject *child, int childFlags); /* holds a ref */
iAny *  removeChild_Widget  (iWidget *, iAnyObject *child); /* returns a ref */
iAny *  child_Widget        (iWidget *, size_t index); /* O(n) */
size_t  childIndex_Widget   (const iWidget *, const iAnyObject *child); /* O(n) */
void    arrange_Widget      (iWidget *);
iBool   dispatchEvent_Widget(iWidget *, const SDL_Event *);
iBool   processEvent_Widget (iWidget *, const SDL_Event *);
void    postCommand_Widget  (const iWidget *, const char *cmd, ...);
void    refresh_Widget      (const iWidget *);

void    setFocus_Widget     (iWidget *);
iWidget *focus_Widget       (void);
iWidget *hover_Widget       (void);
void    unhover_Widget      (void);
void    setMouseGrab_Widget (iWidget *);
iWidget *mouseGrab_Widget   (void);

iBool   equalWidget_Command (const char *cmd, const iWidget *widget, const char *checkCommand);