Release s3d 0.2.2
[s3d.git] / libs3dw / widget.c
blobbea9347667ff692a0d8d3f6ef88a7b03976b3c4c
1 /*
2 * widget.c
4 * Copyright (C) 2006-2011 Simon Wunderlich <dotslash@packetmixer.de>
6 * This file is part of the s3d Widgets, a Widget Library for s3d.
7 * See http://s3d.berlios.de/ for more updates.
9 * s3d Widgets is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * s3d Widgets is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with the s3d Widgets; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #include <s3d.h>
25 #include <s3dw.h>
26 #include <s3dw_int.h>
27 #include <stdlib.h> /* malloc() */
28 #include <string.h> /* strdup() */
29 s3dw_widget *s3dw_widget_new(s3dw_widget *widget)
31 widget->type = -1;
32 widget->x = widget->ax = 0;
33 widget->y = widget->ay = 0;
34 widget->z = widget->az = 0;
35 widget->rx = widget->arx = 0;
36 widget->ry = widget->ary = 0;
37 widget->rz = widget->arz = 0;
38 widget->s = widget->as = 1;
39 widget->width = 0;
40 widget->height = 0;
41 widget->nobj = 0;
42 widget->pobj = NULL;
43 widget->parent = NULL;
44 widget->ptr = NULL;
45 widget->focus = -1;
46 widget->flags = S3DW_ACTIVE;
47 widget->oid = -1;
48 return widget;
50 /* widget clicked, call specific function and check kids */
51 int s3dw_widget_event_click(s3dw_widget *widget, uint32_t oid)
53 int i;
54 s3dprintf(VLOW, "processing click event for widget %10p of type %d, oid %d (%d), subobjects: %d", (void*)widget, widget->type, widget->oid, oid, widget->nobj);
55 if (s3dwcb_click[widget->type](widget, oid)) return 1;
56 for (i = 0; i < widget->nobj; i++)
57 if (s3dw_widget_event_click(widget->pobj[i], oid)) return 1;
58 return 0;
60 /* widget received key,,call specific function and check (focused) kids */
61 int s3dw_widget_event_key(s3dw_widget *widget, struct s3d_key_event *keys)
63 if (s3dwcb_key[widget->type](widget, keys)) return 1;
64 if (widget->focus != -1)
65 if (s3dw_widget_event_key(widget->pobj[widget->focus], keys)) return 1;
66 return 0;
70 /* append an widget */
71 void s3dw_widget_append(s3dw_widget *parent, s3dw_widget *widget)
73 parent->nobj++;
74 parent->pobj = (s3dw_widget**)realloc(parent->pobj, sizeof(s3dw_widget **) * (parent->nobj));
75 parent->pobj[parent->nobj-1] = widget;
76 widget->parent = parent;
77 widget->style = parent->style;
78 if (!(parent->flags&S3DW_VISIBLE))
79 widget->flags |= S3DW_VISIBLE;
81 /* removes an widget from it's parent, should have been appended before */
82 static void s3dw_widget_remove(s3dw_widget *widget)
84 s3dw_widget *parent = widget->parent;
85 int i, stackpos;
87 stackpos = s3dw_ani_stackpos(widget);
88 if (stackpos != -1)
89 s3dw_ani_del(stackpos);
90 if (parent == NULL) return;
92 for (i = 0; i < parent->nobj; i++) /* search ... */
93 if (parent->pobj[i] == widget) { /* ... and destroy */
94 if (parent->focus == i) parent->focus = -1;
95 if (parent->focus == (parent->nobj - 1)) parent->focus = i;
96 parent->pobj[i] = parent->pobj[parent->nobj-1]; /* swap last element to the to be deleted one */
97 parent->nobj--;
101 /** \brief delete widget
103 * Deletes any widget. Should be casted with S3DWIDGET().
105 void s3dw_delete(s3dw_widget *widget)
107 s3dw_widget_remove(widget);
108 /* remove kids */
109 while (widget->nobj > 0) /* will decrease as child-delete will call s3dw_widget_remove() */
110 s3dw_delete(widget->pobj[0]);
111 free(widget->pobj);
112 s3dwcb_destroy[widget->type](widget); /* type-specific destroy */
115 /** \brief make widget visible
117 * Switches a widget visible. Should be casted with S3DWIDGET().
119 void s3dw_show(s3dw_widget *widget)
121 widget->flags |= S3DW_VISIBLE;
122 s3dw_widget_visible(widget);
125 /** \brief give widget focus
127 * Gives focus to the widget, relative to its parent. That means you can focus a
128 * surface, and each surface can focus one of its element, e.g. an input field.
129 * Should be casted with S3DWIDGET().
131 void s3dw_focus(s3dw_widget *focus)
133 int i;
134 for (i = 0; i < focus->parent->nobj; i++)
135 if (focus->parent->pobj[i] == focus) {
136 focus->parent->focus = i;
137 return;
141 /* show visible kids */
142 void s3dw_widget_visible(s3dw_widget *widget)
144 int i;
145 s3dw_widget *kid;
146 for (i = 0; i < widget->nobj; i++) {
147 kid = widget->pobj[i];
148 if (widget->flags&S3DW_VISIBLE)
149 s3dw_widget_visible(kid);
151 widget->flags |= S3DW_ONSCREEN;
152 s3dwcb_show[widget->type](widget);
155 /** \brief apply widgets moving function
157 * Moves/translates the widget as you specified in it's private s3dw_widget
158 * structure. Should be casted with S3DWIDGET().
160 void s3dw_moveit(s3dw_widget *widget)
162 s3dw_ani_add(widget);