Minor syntactical changes for readability.
[xuni.git] / src / widget / box.c
bloba7292fd218bc5c494085679c41fc7401adeba360
1 /*! \file box.c
3 */
5 #include "../graphics.h"
6 #include "../memory.h"
7 #include "widgets.h"
8 #include "box.h"
9 #include "image.h"
11 /*enum box_image_type_t {
12 BOX_IN_NORMAL,
13 BOX_IN_HOVER,
14 BOX_IN_ACTIVE,
15 BOX_OUT_NORMAL,
16 BOX_OUT_HOVER,
17 BOX_OUT_ACTIVE
18 };*/
20 static void free_box(struct xuni_t *xuni, struct widget_t *widget);
21 static void paint_box(struct xuni_t *xuni, struct widget_t *widget);
22 static void reposition_box(struct xuni_t *xuni, struct widget_t *widget);
23 static void rescale_box(struct xuni_t *xuni, struct widget_t *widget);
25 static void paint_box_image(SDL_Surface *screen, SDL_Surface *image,
26 SDL_Rect *b);
27 static SDL_Surface *get_box_image(struct xuni_t *xuni, struct widget_t *theme,
28 struct box_t *box);
30 /*! Calls the box function appropriate for handling \a event.
32 Uses call_widget_event_func() to call the appropriate function from a
33 lookup table of handler functions.
35 \param xuni The xuni structure. Passed on to call_widget_event_func()
36 and ultimately the handler functions.
37 \param widget The box widget being operated on. Also passed on.
38 \param event The event being sent to the box widget \a widget.
40 void box_widget_event(struct xuni_t *xuni, struct widget_t *widget,
41 enum widget_event_t event) {
43 static void (*function[])(struct xuni_t *xuni, struct widget_t *widget)
44 = {
46 free_box,
48 paint_box,
49 reposition_box,
50 rescale_box
53 call_widget_event_func(xuni, widget, event, function,
54 sizeof(function) / sizeof(*function));
57 void init_box(struct widget_t *widget, enum box_style_t style,
58 struct widget_t *selwidget) {
60 widget->type = WIDGET_BOX;
61 widget->p.box = xuni_memory_allocate(sizeof(*widget->p.box));
63 widget->p.box->style = style;
65 widget->p.box->state = 0;
67 widget->selwidget = selwidget;
70 void set_box_type(struct gui_t *gui, struct widget_t *widget,
71 struct widget_t *box) {
73 int xp, yp;
75 box->p.box->state = 0;
77 /*if(box->visibility & WIDGET_VISIBILITY_CLICKABLE == 0) {
78 printf("Unselable box: \"%s\"\n", widget->name);
79 }*/
81 /* !!! */
82 if((gui->sel.p.widget == widget || gui->active.widget == widget
83 || box->sel) && widget->visibility & WIDGET_VISIBILITY_CLICKABLE) {
85 SDL_GetMouseState(&xp, &yp);
87 if(pos_in_rect(xp, yp, widget->pos)) {
88 box->p.box->state |= BOX_STATE_HOVER;
91 if(gui->active.widget == widget || gui->active.widget == box
92 || gui->sel.clickin) {
94 box->p.box->state |= BOX_STATE_ACTIVE;
99 static void paint_box_image(SDL_Surface *screen, SDL_Surface *image,
100 SDL_Rect *b) {
102 int cw, ch;
103 int boxw, boxh;
105 if(!image) return;
107 boxw = image->w / 2;
108 boxh = image->h / 2;
110 cw = b->w - boxw * 2;
111 ch = b->h - boxh * 2;
113 if(image) {
114 /* !!! there must be a better way to calculate the dimensions of the
115 component images of the box */
116 if(image->w % 2) cw --;
117 if(image->h % 2) ch --;
119 if(cw < 0) cw = 0;
120 if(ch < 0) ch = 0;
122 /* upper left */
123 blit_surface_area(screen, image,
124 b->x, b->y,
125 0, 0, boxw, boxh);
127 /* lower left */
128 blit_surface_area(screen, image,
129 b->x, b->y + boxh + ch,
130 0, boxh, boxw, boxh);
132 /* upper right */
133 blit_surface_area(screen, image,
134 b->x + boxw + cw, b->y,
135 boxw, 0, boxw, boxh);
137 /* lower right */
138 blit_surface_area(screen, image,
139 b->x + boxw + cw, b->y + boxh + ch,
140 boxw, boxh, boxw, boxh);
142 /* top */
143 blit_surface_repeat_area(screen, image,
144 b->x + boxw, b->y, cw, boxh,
145 boxw, 0, 1, boxh);
147 /* bottom */
148 blit_surface_repeat_area(screen, image,
149 b->x + boxw, b->y + boxh + ch,
150 cw, boxh, boxw, boxh,
151 1, boxh);
153 /* left */
154 blit_surface_repeat_area(screen, image,
155 b->x, b->y + boxh, boxw, ch,
156 0, boxh, boxw, 1);
158 /* right */
159 blit_surface_repeat_area(screen, image,
160 b->x + boxw + cw, b->y + boxh,
161 boxw, ch, boxw, boxh,
162 boxw, 1);
164 /*printf("(%5i %5i %5i %5i) with (%5i %5i) and box (%5i %5i)\n",
165 b->x + boxw, b->y + boxh, cw, ch,
166 image->w / 2,
167 image->h / 2,
168 boxw, boxh);*/
170 /* middle -- calls SDL_FillRect(), if possible, which is very fast */
171 fill_area(screen, b->x + boxw, b->y + boxh, cw, ch,
172 image, image->w / 2, image->h / 2);
176 static SDL_Surface *get_box_image(struct xuni_t *xuni, struct widget_t *theme,
177 struct box_t *box) {
179 enum wid_theme_t image = THEME_CORNERS_OUT_NORMAL;
180 struct widget_t *found;
182 if(box->style == BOX_STYLE_NORMAL) {
183 if(box->state == 0) image = THEME_CORNERS_OUT_NORMAL;
184 else if(box->state == BOX_STATE_HOVER) {
185 image = THEME_CORNERS_OUT_HOVER;
187 else if(box->state == BOX_STATE_ACTIVE) {
188 image = THEME_CORNERS_OUT_ACTIVE;
190 else if(box->state == (BOX_STATE_HOVER | BOX_STATE_ACTIVE)) {
191 image = THEME_CORNERS_IN_ACTIVE;
194 else if(box->style == BOX_STYLE_INVERTED) {
195 if(box->state == 0) image = THEME_CORNERS_IN_NORMAL;
196 else if(box->state == BOX_STATE_HOVER) {
197 image = THEME_CORNERS_IN_HOVER;
199 else if(box->state == BOX_STATE_ACTIVE) {
200 image = THEME_CORNERS_IN_ACTIVE;
202 else if(box->state == (BOX_STATE_HOVER | BOX_STATE_ACTIVE)) {
203 image = THEME_CORNERS_OUT_ACTIVE;
206 else if(box->style == BOX_STYLE_ALWAYSIN) {
207 if(box->state == 0) image = THEME_CORNERS_IN_NORMAL;
208 else if(box->state == BOX_STATE_HOVER) image = THEME_CORNERS_IN_HOVER;
209 else image = THEME_CORNERS_IN_ACTIVE;
211 else { /* ALWAYSOUT */
212 image = THEME_CORNERS_OUT_NORMAL;
215 found = get_any_theme_widget(xuni, theme, (size_t)image);
216 return found ? found->p.image->image : 0;
219 void paint_box_previous_state(struct xuni_t *xuni, struct widget_t *widget) {
220 #if 0
221 if(widget->base->id == xuni->gui->tab.sel
222 && widget->base->base->type == WIDGET_PANEL
223 && widget->base->base->id == xuni->gui->tab.panel) {
225 struct widget_t *box = widget_nameid_access(xuni->theme->current,
226 THEME_CORNERS_IN_HOVER);
228 if(box && box->p.image->image) {
229 paint_box_image(xuni->smode->screen,
230 box->p.image->image,
231 xuni->theme->current, &widget->pos->real);
232 return;
235 #endif
237 paint_box_image(xuni->smode->screen,
238 get_box_image(xuni, xuni->theme->current, widget->p.box),
239 &widget->pos->real);
242 static void free_box(struct xuni_t *xuni, struct widget_t *widget) {
243 xuni_memory_free(widget->p.box);
246 static void paint_box(struct xuni_t *xuni, struct widget_t *widget) {
247 /*if(widget->base->base && widget->base->base->type == WIDGET_CHECKBOX) {
248 set_box_type(xuni->gui, widget->base->base, widget);
250 else {
251 set_box_type(xuni->gui, widget, widget);
254 set_box_type(xuni->gui, widget->selwidget ? widget->selwidget : widget,
255 widget);
257 paint_box_previous_state(xuni, widget);
260 static void reposition_box(struct xuni_t *xuni, struct widget_t *widget) {
264 static void rescale_box(struct xuni_t *xuni, struct widget_t *widget) {