1 /*
2 GUILIB: An example GUI framework library for use with SDL
3 */
4
5 #include "GUI_widget.h"
6
7
8 /* Widget constructors */
GUI_Widget(void * data)9 GUI_Widget:: GUI_Widget(void *data)
10 {
11 Init(data, 0, 0, 0, 0);
12 }
GUI_Widget(void * data,int x,int y,int w,int h)13 GUI_Widget:: GUI_Widget(void *data, int x, int y, int w, int h)
14 {
15 Init(data, x, y, w, h);
16 }
17 void
Init(void * data,int x,int y,int w,int h)18 GUI_Widget:: Init(void *data, int x, int y, int w, int h)
19 {
20 widget_data = data;
21 screen = NULL;
22 SetRect(x, y, w, h);
23 Show();
24 error = NULL;
25 for (int n=0;n<3; ++n ) {
26 pressed[n]=0;
27 }
28 }
29
30 /* Mark the widget as visible -- this is the default state */
31 void
Show(void)32 GUI_Widget:: Show(void)
33 {
34 status = WIDGET_VISIBLE;
35 }
36
37 /* Mark the widget as hidden; no display, no events */
38 void
Hide(void)39 GUI_Widget:: Hide(void)
40 {
41 status = WIDGET_HIDDEN;
42 }
43
44 /* Mark the widget as free, so it will be deleted by the GUI */
45 void
Delete(void)46 GUI_Widget:: Delete(void)
47 {
48 status = WIDGET_DELETED;
49 }
50
51 /* Report status to GUI */
52 int
Status(void)53 GUI_Widget:: Status(void)
54 {
55 return(status);
56 }
57
58 /* Set the bounds of the widget.
59 If 'w' or 'h' is -1, that parameter will not be changed.
60 */
61 void
SetRect(int x,int y,int w,int h)62 GUI_Widget:: SetRect(int x, int y, int w, int h)
63 {
64 area.x = x;
65 area.y = y;
66 if ( w >= 0 ) {
67 area.w = w;
68 }
69 if ( h >= 0 ) {
70 area.h = h;
71 }
72 }
73 void
SetRect(SDL_Rect ** bounds)74 GUI_Widget:: SetRect(SDL_Rect **bounds)
75 {
76 int minx, maxx;
77 int miny, maxy;
78 int i, v;
79
80 maxx = 0;
81 maxy = 0;
82 for ( i=0; bounds[i]; ++i ) {
83 v = (bounds[i]->x+bounds[i]->w-1);
84 if ( maxx < v ) {
85 maxx = v;
86 }
87 v = (bounds[i]->y+bounds[i]->h-1);
88 if ( maxy < v ) {
89 maxy = v;
90 }
91 }
92 minx = maxx;
93 miny = maxy;
94 for ( i=0; bounds[i]; ++i ) {
95 v = bounds[i]->x;
96 if ( minx > v ) {
97 minx = v;
98 }
99 v = bounds[i]->y;
100 if ( miny > v ) {
101 miny = v;
102 }
103 }
104 SetRect(minx, miny, (maxx-minx+1), (maxy-miny+1));
105 }
106
107 /* Check to see if a point intersects the bounds of the widget.
108 */
109 int
HitRect(int x,int y)110 GUI_Widget:: HitRect(int x, int y)
111 {
112 return(HitRect(x, y, area));
113 }
114 int
HitRect(int x,int y,SDL_Rect & rect)115 GUI_Widget:: HitRect(int x, int y, SDL_Rect &rect)
116 {
117 int hit;
118
119 hit = 1;
120 if ( (x < rect.x) || (x >= (rect.x+rect.w)) ||
121 (y < rect.y) || (y >= (rect.y+rect.h)) ) {
122 hit = 0;
123 }
124 return(hit);
125 }
126
127 /* Set the display surface for this widget */
128 void
SetDisplay(SDL_Surface * display)129 GUI_Widget:: SetDisplay(SDL_Surface *display)
130 {
131 screen = display;
132 }
133
134 /* Show the widget.
135 If the surface needs to be locked, it will be locked
136 before this call, and unlocked after it returns.
137
138 ****************NO, NOT AT ALL IF I'M NOT TOO DUMB TO LOOK******
139 ******OTHERWISE YOU COULDN'T FILLRECT in Display(), ETC!!!! ***********
140 */
141 void
Display(void)142 GUI_Widget:: Display(void)
143 {
144 }
145
146 /* Redraw the widget and only the widget */
Redraw(void)147 void GUI_Widget::Redraw(void)
148 {
149 if (status==WIDGET_VISIBLE)
150 {
151 Display();
152 SDL_UpdateRects(screen,1,&area);
153 }
154 }
155
156 /* GUI idle function -- run when no events pending */
157 GUI_status
Idle(void)158 GUI_Widget:: Idle(void)
159 {
160 return(GUI_PASS);
161 }
162
163 /* Widget event handlers.
164 These functions should return a status telling the GUI whether
165 or not the event should be passed on to other widgets.
166 These are called by the default HandleEvent function.
167 */
168 GUI_status
KeyDown(SDL_keysym key)169 GUI_Widget:: KeyDown(SDL_keysym key)
170 {
171 return(GUI_PASS);
172 }
173 GUI_status
KeyUp(SDL_keysym key)174 GUI_Widget:: KeyUp(SDL_keysym key)
175 {
176 return(GUI_PASS);
177 }
178 GUI_status
MouseDown(int x,int y,int button)179 GUI_Widget:: MouseDown(int x, int y, int button)
180 {
181 return(GUI_PASS);
182 }
183 GUI_status
MouseUp(int x,int y,int button)184 GUI_Widget:: MouseUp(int x, int y, int button)
185 {
186 return(GUI_PASS);
187 }
188 GUI_status
MouseMotion(int x,int y,Uint8 state)189 GUI_Widget:: MouseMotion(int x, int y, Uint8 state)
190 {
191 return(GUI_PASS);
192 }
193
194 /* Main event handler function.
195 This function gets raw SDL events from the GUI.
196 */
197 GUI_status
HandleEvent(const SDL_Event * event)198 GUI_Widget:: HandleEvent(const SDL_Event *event)
199 {
200 switch (event->type) {
201 case SDL_KEYDOWN: {
202 return(KeyDown(event->key.keysym));
203 }
204 break;
205 case SDL_KEYUP: {
206 return(KeyUp(event->key.keysym));
207 }
208 break;
209 case SDL_MOUSEBUTTONDOWN: {
210 int x, y, button;
211 x = event->button.x;
212 y = event->button.y;
213 if ( HitRect(x, y) ) {
214 button = event->button.button;
215 return(MouseDown(x, y, button));
216 }
217 }
218 break;
219 case SDL_MOUSEBUTTONUP: {
220 int x, y, button;
221 x = event->button.x;
222 y = event->button.y;
223 button = event->button.button;
224 if ( HitRect(x, y) )
225 {
226 button = event->button.button;
227 return(MouseUp(x, y, button));
228 }
229 /* if widget was clicked before we must let it deactivate itself*/
230 else if (ClickState(1)) return(MouseUp(-1,-1,button));
231 }
232 break;
233 case SDL_MOUSEMOTION: {
234 int x, y;
235 Uint8 state;
236 x = event->motion.x;
237 y = event->motion.y;
238 state = event->motion.state;
239 if ( HitRect(x, y) )
240 {
241 return(MouseMotion(x, y, state));
242 }
243 /* if widget was clicked before we must let it react*/
244 else if (ClickState(1)) return(MouseMotion(-1,-1,state));
245 }
246 break;
247 default: {
248 /* Pass it along.. */;
249 }
250 break;
251 }
252 return(GUI_PASS);
253 }
254