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
27 #include <stdlib.h> /* malloc() */
28 #include <string.h> /* strdup() */
29 s3dw_widget
*s3dw_widget_new(s3dw_widget
*widget
)
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;
43 widget
->parent
= NULL
;
46 widget
->flags
= S3DW_ACTIVE
;
50 /* widget clicked, call specific function and check kids */
51 int s3dw_widget_event_click(s3dw_widget
*widget
, uint32_t oid
)
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;
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;
70 /* append an widget */
71 void s3dw_widget_append(s3dw_widget
*parent
, s3dw_widget
*widget
)
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
;
87 stackpos
= s3dw_ani_stackpos(widget
);
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 */
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
);
109 while (widget
->nobj
> 0) /* will decrease as child-delete will call s3dw_widget_remove() */
110 s3dw_delete(widget
->pobj
[0]);
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
)
134 for (i
= 0; i
< focus
->parent
->nobj
; i
++)
135 if (focus
->parent
->pobj
[i
] == focus
) {
136 focus
->parent
->focus
= i
;
141 /* show visible kids */
142 void s3dw_widget_visible(s3dw_widget
*widget
)
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
);