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
28 #include <stdlib.h> /* malloc() */
29 #include <string.h> /* strdup() */
31 static void s3dw_scrollbar_draw(s3dw_widget
*widget
)
33 s3dw_scrollbar
*scrollbar
= (s3dw_scrollbar
*)widget
;
34 float back_vertices
[3*32];
36 unsigned int back_polygons
[44*4] = {
38 0, 4, 5, 0, 0, 5, 1, 0,
39 1, 5, 6, 0, 1, 6, 2, 0,
40 3, 2, 7, 0, 7, 2, 6, 0,
41 3, 7, 4, 0, 3, 4, 0, 0,
43 /* sides of big box */
44 12, 13, 9, 0, 12, 9, 8, 0,
45 14, 15, 11, 0, 14, 11, 10, 0,
48 9, 16, 17, 0, 9, 17, 10, 0,
49 17, 18, 14, 0, 17, 14, 10, 0,
50 13, 14, 18, 0, 13, 18, 19, 0,
51 13, 19, 16, 0, 13, 16, 9, 0,
54 19, 18, 17, 0, 19, 17, 16, 0,
56 /* up arrow background surface */
63 20, 23, 24, 0, 20, 24, 21, 0,
64 21, 24, 25, 0, 21, 25, 22, 0,
65 20, 22, 25, 0, 20, 25, 23, 0,
68 /* down arrow background surface */
75 26, 27, 31, 0, 26, 31, 30, 0,
76 31, 27, 28, 0, 31, 28, 29, 0,
77 26, 30, 29, 0, 26, 29, 28, 0,
81 unsigned int bar_polygons
[14*4] = {
83 0, 4, 5, 0, 0, 5, 1, 0,
84 1, 5, 6, 0, 1, 6, 2, 0,
85 3, 2, 6, 0, 3, 6, 7, 0,
86 3, 7, 4, 0, 3, 4, 0, 0,
88 7, 6, 4, 0, 4, 6, 5, 0,
90 /* back, only visible sides */
91 2, 3, 11, 0, 2, 11, 10, 0,
92 1, 9, 8, 0, 1, 8, 0, 0
94 float bar_vertices
[12*3];
99 w
= (scrollbar
->type
== S3DW_SBAR_VERT
) ? widget
->width
: widget
->height
;
100 h
= (scrollbar
->type
== S3DW_SBAR_VERT
) ? widget
->height
: widget
->width
;
101 /* outside/big box */
102 back_vertices
[0*3+0] = w
* 0.0;
103 back_vertices
[0*3+1] = 0.0 - h
;
104 back_vertices
[0*3+2] = 0.0;
105 back_vertices
[1*3+0] = w
* 1.0;
106 back_vertices
[1*3+1] = 0.0 - h
;
107 back_vertices
[1*3+2] = 0.0;
108 back_vertices
[2*3+0] = w
* 1.0;
109 back_vertices
[2*3+1] = 0.0;
110 back_vertices
[2*3+2] = 0.0;
111 back_vertices
[3*3+0] = w
* 0.0;
112 back_vertices
[3*3+1] = 0.0;
113 back_vertices
[3*3+2] = 0.0;
114 back_vertices
[4*3+0] = w
* 0.125;
115 back_vertices
[4*3+1] = w
* 0.125 - h
;
116 back_vertices
[4*3+2] = 0.25;
117 back_vertices
[5*3+0] = w
* 0.875;
118 back_vertices
[5*3+1] = w
* 0.125 - h
;
119 back_vertices
[5*3+2] = 0.25;
120 back_vertices
[6*3+0] = w
* 0.875;
121 back_vertices
[6*3+1] = w
* -0.125;
122 back_vertices
[6*3+2] = 0.25;
123 back_vertices
[7*3+0] = w
* 0.125;
124 back_vertices
[7*3+1] = w
* -0.125;
125 back_vertices
[7*3+2] = 0.25;
128 back_vertices
[8*3+0] = w
* 0.125;
129 back_vertices
[8*3+1] = w
- h
;
130 back_vertices
[8*3+2] = 0.25;
131 back_vertices
[9*3+0] = w
* 0.25;
132 back_vertices
[9*3+1] = w
- h
;
133 back_vertices
[9*3+2] = 0.25;
134 back_vertices
[10*3+0] = w
* 0.75;
135 back_vertices
[10*3+1] = w
- h
;
136 back_vertices
[10*3+2] = 0.25;
137 back_vertices
[11*3+0] = w
* 0.875;
138 back_vertices
[11*3+1] = w
- h
;
139 back_vertices
[11*3+2] = 0.25;
142 back_vertices
[12*3+0] = w
* 0.125;
143 back_vertices
[12*3+1] = -w
;
144 back_vertices
[12*3+2] = 0.25;
145 back_vertices
[13*3+0] = w
* 0.25;
146 back_vertices
[13*3+1] = -w
;
147 back_vertices
[13*3+2] = 0.25;
148 back_vertices
[14*3+0] = w
* 0.75;
149 back_vertices
[14*3+1] = -w
;
150 back_vertices
[14*3+2] = 0.25;
151 back_vertices
[15*3+0] = w
* 0.875;
152 back_vertices
[15*3+1] = -w
;
153 back_vertices
[15*3+2] = 0.25;
156 back_vertices
[16*3+0] = w
* 0.25;
157 back_vertices
[16*3+1] = w
* 0.125 - h
+ w
;
158 back_vertices
[16*3+2] = 0.125;
159 back_vertices
[17*3+0] = w
* 0.75;
160 back_vertices
[17*3+1] = w
* 0.125 - h
+ w
;
161 back_vertices
[17*3+2] = 0.125;
162 back_vertices
[18*3+0] = w
* 0.75;
163 back_vertices
[18*3+1] = w
* -0.125 - w
;
164 back_vertices
[18*3+2] = 0.125;
165 back_vertices
[19*3+0] = w
* 0.25;
166 back_vertices
[19*3+1] = w
* -0.125 - w
;
167 back_vertices
[19*3+2] = 0.125;
170 back_vertices
[20*3+0] = w
* 0.25;
171 back_vertices
[20*3+1] = w
* -0.875;
172 back_vertices
[20*3+2] = 0.25;
173 back_vertices
[21*3+0] = w
* 0.75;
174 back_vertices
[21*3+1] = w
* -0.875;
175 back_vertices
[21*3+2] = 0.25;
176 back_vertices
[22*3+0] = w
* 0.5;
177 back_vertices
[22*3+1] = w
* -0.25;
178 back_vertices
[22*3+2] = 0.25;
179 back_vertices
[23*3+0] = w
* 0.375;
180 back_vertices
[23*3+1] = w
* -0.75;
181 back_vertices
[23*3+2] = 0.375;
182 back_vertices
[24*3+0] = w
* 0.625;
183 back_vertices
[24*3+1] = w
* -0.75;
184 back_vertices
[24*3+2] = 0.375;
185 back_vertices
[25*3+0] = w
* 0.5;
186 back_vertices
[25*3+1] = w
* -0.375;
187 back_vertices
[25*3+2] = 0.375;
190 back_vertices
[26*3+0] = w
* 0.25;
191 back_vertices
[26*3+1] = -h
+ w
* 0.875;
192 back_vertices
[26*3+2] = 0.25;
193 back_vertices
[27*3+0] = w
* 0.75;
194 back_vertices
[27*3+1] = -h
+ w
* 0.875;
195 back_vertices
[27*3+2] = 0.25;
196 back_vertices
[28*3+0] = w
* 0.5;
197 back_vertices
[28*3+1] = -h
+ w
* 0.25;
198 back_vertices
[28*3+2] = 0.25;
199 back_vertices
[29*3+0] = w
* 0.375;
200 back_vertices
[29*3+1] = -h
+ w
* 0.75;
201 back_vertices
[29*3+2] = 0.375;
202 back_vertices
[30*3+0] = w
* 0.625;
203 back_vertices
[30*3+1] = -h
+ w
* 0.75;
204 back_vertices
[30*3+2] = 0.375;
205 back_vertices
[31*3+0] = w
* 0.5;
206 back_vertices
[31*3+1] = -h
+ w
* 0.375;
207 back_vertices
[31*3+2] = 0.375;
209 /* scrollbar bar poinst */
210 bar_vertices
[0*3+0] = w
* 0.25;
211 bar_vertices
[0*3+1] = -(h
- 3) + w
* 0.125;
212 bar_vertices
[0*3+2] = 0.25;
213 bar_vertices
[1*3+0] = w
* 0.75;
214 bar_vertices
[1*3+1] = -(h
- 3) + w
* 0.125;
215 bar_vertices
[1*3+2] = 0.25;
216 bar_vertices
[2*3+0] = w
* 0.75;
217 bar_vertices
[2*3+1] = -w
* 0.125;
218 bar_vertices
[2*3+2] = 0.25;
219 bar_vertices
[3*3+0] = w
* 0.25;
220 bar_vertices
[3*3+1] = -w
* 0.125;
221 bar_vertices
[3*3+2] = 0.25;
223 bar_vertices
[4*3+0] = w
* 0.125;
224 bar_vertices
[4*3+1] = -(h
- 3) + w
* 0.25;
225 bar_vertices
[4*3+2] = 0.375;
226 bar_vertices
[5*3+0] = w
* 0.875;
227 bar_vertices
[5*3+1] = -(h
- 3) + w
* 0.25;
228 bar_vertices
[5*3+2] = 0.375;
229 bar_vertices
[6*3+0] = w
* 0.875;
230 bar_vertices
[6*3+1] = -w
* 0.25;
231 bar_vertices
[6*3+2] = 0.375;
232 bar_vertices
[7*3+0] = w
* 0.125;
233 bar_vertices
[7*3+1] = -w
* 0.25;
234 bar_vertices
[7*3+2] = 0.375;
236 bar_vertices
[8*3+0] = w
* 0.125;
237 bar_vertices
[8*3+1] = -(h
- 3) + w
* 0.25;
238 bar_vertices
[8*3+2] = 0.175;
239 bar_vertices
[9*3+0] = w
* 0.875;
240 bar_vertices
[9*3+1] = -(h
- 3) + w
* 0.25;
241 bar_vertices
[9*3+2] = 0.175;
242 bar_vertices
[10*3+0] = w
* 0.875;
243 bar_vertices
[10*3+1] = -w
* 0.25;
244 bar_vertices
[10*3+2] = 0.175;
245 bar_vertices
[11*3+0] = w
* 0.125;
246 bar_vertices
[11*3+1] = -w
* 0.25;
247 bar_vertices
[11*3+2] = 0.175;
252 if (scrollbar
->type
== S3DW_SBAR_HORI
) { /* rotate x and y for horizontal scrollbar */
253 for (i
= 0; i
< 32; i
++) {
254 temp
= back_vertices
[i
*3];
255 back_vertices
[i
*3] = -back_vertices
[i
*3+1];
256 back_vertices
[i
*3+1] = -temp
;
258 for (i
= 0; i
< 44; i
++) { /* change clockwiseness */
259 j
= back_polygons
[i
*4];
260 back_polygons
[i
*4] = back_polygons
[i
*4+1];
261 back_polygons
[i
*4+1] = j
;
263 for (i
= 0; i
< 12; i
++) {
264 temp
= bar_vertices
[i
*3];
265 bar_vertices
[i
*3] = -bar_vertices
[i
*3+1];
266 bar_vertices
[i
*3+1] = -temp
;
268 for (i
= 0; i
< 14; i
++) { /* change clockwiseness */
269 j
= bar_polygons
[i
*4];
270 bar_polygons
[i
*4] = bar_polygons
[i
*4+1];
271 bar_polygons
[i
*4+1] = j
;
275 widget
->oid
= s3d_new_object();
276 scrollbar
->loid
= s3d_new_object();
277 scrollbar
->roid
= s3d_new_object();
278 scrollbar
->baroid
= s3d_new_object();
279 s3d_push_materials_a(widget
->oid
, widget
->style
->input_mat
, 1);
280 s3d_push_materials_a(scrollbar
->loid
, widget
->style
->input_mat
, 1);
281 s3d_push_materials_a(scrollbar
->roid
, widget
->style
->input_mat
, 1);
282 s3d_push_materials_a(scrollbar
->baroid
, widget
->style
->input_mat
, 1);
283 s3d_push_vertices(widget
->oid
, back_vertices
, 20);
284 s3d_push_vertices(scrollbar
->loid
, back_vertices
, 32);
285 s3d_push_vertices(scrollbar
->roid
, back_vertices
, 32);
286 s3d_push_vertices(scrollbar
->baroid
, bar_vertices
, 12);
288 s3d_push_polygons(widget
->oid
, back_polygons
, 22);
289 s3d_push_polygons(scrollbar
->loid
, back_polygons
+ 4*22, 11);
290 s3d_push_polygons(scrollbar
->roid
, back_polygons
+ 4*33, 11);
291 s3d_push_polygons(scrollbar
->baroid
, bar_polygons
, 14);
292 s3d_link(widget
->oid
, widget
->parent
->oid
);
293 s3d_link(scrollbar
->loid
, widget
->oid
);
294 s3d_link(scrollbar
->roid
, widget
->oid
);
295 s3d_link(scrollbar
->baroid
, widget
->oid
);
296 s3d_translate(widget
->oid
, widget
->x
, -widget
->y
, 0);
297 if (scrollbar
->type
== S3DW_SBAR_VERT
)
298 s3d_translate(scrollbar
->baroid
, 0, -1.5, 0);
300 s3d_translate(scrollbar
->baroid
, 1.5, 0, 0);
303 /* show the scrollbar */
304 void s3dw_scrollbar_show(s3dw_widget
*widget
)
306 s3dw_scrollbar
*scrollbar
= (s3dw_scrollbar
*)widget
;
307 s3d_flags_on(widget
->oid
, S3D_OF_VISIBLE
| S3D_OF_SELECTABLE
);
308 s3d_flags_on(scrollbar
->loid
, S3D_OF_VISIBLE
| S3D_OF_SELECTABLE
);
309 s3d_flags_on(scrollbar
->roid
, S3D_OF_VISIBLE
| S3D_OF_SELECTABLE
);
310 s3d_flags_on(scrollbar
->baroid
, S3D_OF_VISIBLE
| S3D_OF_SELECTABLE
);
313 /* hides the scrollbar */
314 void s3dw_scrollbar_hide(s3dw_widget
*widget
)
316 s3dw_scrollbar
*scrollbar
= (s3dw_scrollbar
*)widget
;
317 s3d_flags_off(widget
->oid
, S3D_OF_VISIBLE
| S3D_OF_SELECTABLE
);
318 s3d_flags_off(scrollbar
->loid
, S3D_OF_VISIBLE
| S3D_OF_SELECTABLE
);
319 s3d_flags_off(scrollbar
->roid
, S3D_OF_VISIBLE
| S3D_OF_SELECTABLE
);
320 s3d_flags_off(scrollbar
->baroid
, S3D_OF_VISIBLE
| S3D_OF_SELECTABLE
);
323 /* create a new scrollbar in the surface */
324 s3dw_scrollbar
*s3dw_scrollbar_new(s3dw_widget
*parent
, int type
, float posx
, float posy
, float length
)
326 s3dw_scrollbar
*scrollbar
;
328 scrollbar
= (s3dw_scrollbar
*)malloc(sizeof(s3dw_scrollbar
));
329 widget
= s3dw_widget_new((s3dw_widget
*)scrollbar
);
330 widget
->type
= S3DW_TSCROLLBAR
;
331 if ((scrollbar
->type
= type
) == S3DW_SBAR_HORI
) {
333 widget
->width
= length
;
336 widget
->height
= length
;
341 scrollbar
->loid
= -1;
342 scrollbar
->roid
= -1;
343 scrollbar
->baroid
= -1;
344 scrollbar
->lonclick
= s3dw_nothing
;
345 scrollbar
->ronclick
= s3dw_nothing
;
346 s3dw_widget_append(parent
, widget
);
347 s3dw_scrollbar_draw(widget
);
351 void s3dw_scrollbar_erase(s3dw_widget
*widget
)
353 s3dw_scrollbar
*scrollbar
= (s3dw_scrollbar
*)widget
;
354 s3d_del_object(widget
->oid
);
355 s3d_del_object(scrollbar
->loid
);
356 s3d_del_object(scrollbar
->roid
);
357 s3d_del_object(scrollbar
->baroid
);
359 /* destroy the scrollbar */
360 void s3dw_scrollbar_destroy(s3dw_widget
*widget
)
362 s3dw_scrollbar
*scrollbar
= (s3dw_scrollbar
*)widget
;
363 s3dw_scrollbar_erase(widget
);
366 /* handle key events */
367 int s3dw_scrollbar_event_key(s3dw_widget
*S3DUNUSED(widget
), struct s3d_key_event
*S3DUNUSED(keys
))
371 /* handle click events */
372 int s3dw_scrollbar_event_click(s3dw_widget
*widget
, uint32_t oid
)
374 s3dw_scrollbar
*scrollbar
= (s3dw_scrollbar
*)widget
;
375 if (scrollbar
->loid
== (int)oid
) {
376 scrollbar
->lonclick(widget
);
379 if (scrollbar
->roid
== (int)oid
) {
380 scrollbar
->ronclick(widget
);