7 #include "../graphics.h"
15 #include "scrollbar.h"
18 static void free_listbox(struct xuni_t
*xuni
, struct widget_t
*widget
);
19 static void reposition_listbox(struct xuni_t
*xuni
, struct widget_t
*widget
);
20 static void rescale_listbox(struct xuni_t
*xuni
, struct widget_t
*widget
);
21 static void paint_listbox(struct xuni_t
*xuni
, struct widget_t
*widget
);
23 void listbox_widget_event(struct xuni_t
*xuni
, struct widget_t
*widget
,
24 enum widget_event_t event
) {
26 static void (*function
[])(struct xuni_t
*xuni
, struct widget_t
*widget
)
36 call_widget_event_func(xuni
, widget
, event
, function
,
37 sizeof(function
) / sizeof(*function
));
40 double real_scale_width(struct widget_t
*widget
) {
43 w
*= widget
->pos
->scale
.w
/ 100.0;
44 if(widget
->base
) w
*= real_scale_width(widget
->base
);
49 double real_scale_height(struct widget_t
*widget
) {
52 h
*= widget
->pos
->scale
.h
/ 100.0;
53 if(widget
->base
) h
*= real_scale_height(widget
->base
);
58 double calculate_scrollbar_width(struct widget_t
*widget
,
59 struct xuni_t
*xuni
) {
63 ratio
= (widget
->pos
->scale
.w
/ 100.0 * xuni
->smode
->screen
->w
)
64 / (widget
->pos
->scale
.h
/ 100.0 * xuni
->smode
->screen
->h
);
66 return (100.0 / 15.0) / (real_scale_width(widget
));
69 double calculate_scrollbar_height(struct widget_t
*widget
,
70 struct xuni_t
*xuni
) {
72 return (100.0 / 15.0) / (real_scale_height(widget
));
75 void init_listbox(struct widget_t
*widget
, struct xuni_t
*xuni
,
76 enum scrollbar_use_t allow
, enum scrollbar_use_t force
) {
78 double width
= calculate_scrollbar_width(widget
, xuni
);
79 double height
= calculate_scrollbar_height(widget
, xuni
);
80 /*double boxsize = 100.0 / 20.0;*/
81 double boxsize
= get_box_width(xuni
, xuni
->theme
->current
) * 4;
82 double boxsizeh
= get_box_height(xuni
, xuni
->theme
->current
) * 4;
85 /*printf("%f %f\n", boxsize, boxsizeh);*/
87 if(force
& SCROLLBAR_USE_VERTICAL
) w
= width
;
88 if(force
& SCROLLBAR_USE_HORIZONTAL
) h
= height
;
90 widget
->type
= WIDGET_LISTBOX
;
91 widget
->p
.listbox
= xuni_memory_allocate(sizeof(*widget
->p
.listbox
));
93 widget
->p
.listbox
->scroll
.allow
= allow
;
94 widget
->p
.listbox
->scroll
.force
= force
;
95 widget
->p
.listbox
->scroll
.current
= force
;
97 widget
->p
.listbox
->maxwidth
= 100;
98 /*widget->p.listbox->yclip = 0;*/
100 add_allocate_widget_compose(widget
, "listbox area");
102 init_widget_pos(last_compose_widget(widget
),
103 0, 0, 100.0 - w
, 100.0 - h
, POS_PACK_NONE
);
104 init_box(last_compose_widget(widget
), BOX_STYLE_ALWAYSIN
, 0);
105 last_compose_widget(widget
)->visibility
&= ~WIDGET_VISIBILITY_INDEPENDENT
;
107 add_allocate_widget_compose(widget
, "listbox vertical scrollbar");
109 init_widget_pos(last_compose_widget(widget
),
110 100.0 - width
, 0, width
, 100.0 - h
, POS_PACK_NONE
);
111 init_scrollbar(last_compose_widget(widget
), xuni
, widget
->pos
->scale
.h
,
112 SCROLLBAR_ORIENTATION_VERTICAL
);
113 if((force
& SCROLLBAR_USE_VERTICAL
) == 0) {
114 last_compose_widget(widget
)->visibility
115 &= ~WIDGET_VISIBILITY_VISIBLE
;
118 add_allocate_widget_compose(widget
, "listbox horizontal scrollbar");
120 init_widget_pos(last_compose_widget(widget
),
121 0, 100.0 - height
, 100.0 - w
, height
, POS_PACK_NONE
);
122 init_scrollbar(last_compose_widget(widget
), xuni
, widget
->pos
->scale
.h
,
123 SCROLLBAR_ORIENTATION_HORIZONTAL
);
124 if((force
& SCROLLBAR_USE_HORIZONTAL
) == 0) {
125 last_compose_widget(widget
)->visibility
126 &= ~WIDGET_VISIBILITY_VISIBLE
;
129 add_allocate_widget_compose(widget
, "listbox data");
131 init_widget_pos(last_compose_widget(widget
), boxsize
, boxsizeh
,
132 100.0 - boxsize
* 2 - w
, 100.0 - boxsizeh
* 2 - h
, POS_PACK_NONE
);
133 init_panel(last_compose_widget(widget
));
134 last_compose_widget(widget
)->visibility
&= ~WIDGET_VISIBILITY_INDEPENDENT
;
136 last_compose_widget(widget
)->visibility
&= ~WIDGET_VISIBILITY_NOT_COMPOSE
;
138 widget
->visibility
&= ~WIDGET_VISIBILITY_NOT_COMPOSE
;
141 void add_listbox_item(struct xuni_t
*xuni
, struct widget_t
*widget
,
142 size_t font
, const char *data
) {
144 struct widget_t
*prev
= last_compose_widget(widget
);
148 if(prev
&& prev
->pos
) {
149 x
= prev
->pos
->scale
.x
;
150 y
= prev
->pos
->scale
.y
; /* !!! */
155 x
= 0 /*widget->pos->scale.x*/;
156 y
= 0 /*widget->pos->scale.y*/;
159 add_allocate_widget_compose(widget
, "listbox item");
161 init_widget_pos(last_compose_widget(widget
),
162 x
, y
, 0, 0, POS_PACK_TOP
);
164 p
= xuni_memory_duplicate_string(data
);
165 init_label(last_compose_widget(widget
),
166 font
, p
, LABEL_ALIGN_LEFT
, 255, 255, 255);
167 xuni_memory_decrement((void *)p
);
169 last_compose_widget(widget
)->visibility
&= ~WIDGET_VISIBILITY_INDEPENDENT
;
171 widget_event(xuni
, last_compose_widget(widget
), WIDGET_EVENT_RESCALE
);
174 struct widget_t
*listbox_sel_item(struct widget_t
*widget
) {
175 struct widget_t
*data
= widget
->compose
->widget
[WID_LISTBOX_DATA
];
178 if(!data
->compose
) return 0;
180 for(x
= 0; x
< data
->compose
->widgets
; x
++) {
181 if(data
->compose
->widget
[x
]->sel
) {
182 return data
->compose
->widget
[x
];
186 /*log_message(ERROR_TYPE_WARNING, 0, __FILE__, __LINE__,
187 "No listbox item selected");
188 print_widget_backtrace(widget);*/
193 void listbox_calculate_scrollbar_max(struct xuni_t
*xuni
,
194 struct widget_t
*widget
) {
196 struct widget_t
*area
= widget
->compose
->widget
[WID_LISTBOX_DATA
];
197 struct widget_t
*first
;
198 struct widget_t
*last
= last_compose_widget(area
);
201 /*printf("rescale_listbox()\n");*/
204 first
= area
->compose
->widget
[0];
205 /* !!! area->pos->real.h isn't quite right */
206 /*widget->pos->real.y = prev->pos->real.y + prev->p.label->label->h;*/
207 /*max = last->pos->real.y + last->pos->real.h
208 - area->pos->real.y - area->pos->real.h;*/
210 height
= get_box_height(xuni
, xuni
->theme
->current
) / 100.0
211 * xuni
->smode
->height
;
213 max
= ((last
->pos
->real
.y
- area
->pos
->real
.y
)
214 - (first
->pos
->real
.y
- area
->pos
->real
.y
)
216 - (area
->pos
->real
.h
- last
->pos
->real
.h
) - height
* 2;
219 printf("get_real_pos(y): %i\n",
220 get_real_pos(last
->pos
->scale
.y
, area
->pos
->real
.w
));
221 printf("last->pos->real.y: %i\n", last
->pos
->real
.y
);
222 printf("first total: %i\n",
223 /*(last->pos->real.y - area->pos->real.y + last->pos->real.h));*/
224 (get_real_pos(last
->pos
->scale
.y
, area
->pos
->real
.w
)
225 - area
->pos
->real
.y
+ last
->pos
->real
.h
));
226 printf("last->pos->real.y: %i\n", last
->pos
->real
.y
);
227 printf("last->pos->real.h: %i\n", last
->pos
->real
.h
);
228 printf("area->pos->real.y: %i\n", area
->pos
->real
.y
);
229 printf("area->pos->real.h: %i\n", area
->pos
->real
.h
);
230 printf("max: %i\n", max
);
235 set_scrollbar_max(xuni
, widget
->compose
->widget
[WID_LISTBOX_VSCROLL
],
239 static void free_listbox(struct xuni_t
*xuni
, struct widget_t
*widget
) {
240 xuni_memory_free(widget
->p
.listbox
);
243 static void paint_listbox(struct xuni_t
*xuni
, struct widget_t
*widget
) {
244 /*size_t x, start = 3;*/
245 /*int height, width;*/
248 widget_event(xuni
, widget
->compose
->widget
[WID_LISTBOX_BOX
],
251 /*height = get_box_height(xuni, xuni->theme->current) / 100.0
252 * xuni->smode->height;
253 width = get_box_width(xuni, xuni->theme->current) / 100.0
254 * xuni->smode->width;*/
256 yclip
= get_scrollbar_pos_int(
257 widget
->compose
->widget
[WID_LISTBOX_VSCROLL
]);
258 /*wclip = widget->compose->widget[WID_LISTBOX_BOX]->pos->real.w - width * 2;
259 hclip = widget->compose->widget[WID_LISTBOX_BOX]->pos->real.h;*/
262 /*clear_widget_clip(xuni, widget->compose->widget[WID_LISTBOX_DATA]);*/
264 /* !!! why does +width work but +height not? */
265 add_widget_clip(xuni
, widget
->compose
->widget
[WID_LISTBOX_DATA
],
266 0, -yclip
+ width
, 0, yclip
/*+ width*/, /*-width * 2*/0, 0);
269 widget_event(xuni
, widget
->compose
->widget
[WID_LISTBOX_DATA
],
273 /* !!! why does +width work but +height not? */
274 add_widget_clip(xuni
, widget
->compose
->widget
[WID_LISTBOX_DATA
],
275 0, -(-yclip
+ width
), 0, -yclip
/*+ width*/, /*-width * 2*/0, 0);
278 widget_event(xuni
, widget
->compose
->widget
[WID_LISTBOX_VSCROLL
],
280 widget_event(xuni
, widget
->compose
->widget
[WID_LISTBOX_HSCROLL
],
284 static void reposition_listbox(struct xuni_t
*xuni
, struct widget_t
*widget
) {
285 int yclip
= get_scrollbar_pos_int(
286 widget
->compose
->widget
[WID_LISTBOX_VSCROLL
]);
287 int xclip
= get_scrollbar_pos_int(
288 widget
->compose
->widget
[WID_LISTBOX_HSCROLL
]);
290 listbox_calculate_scrollbar_max(xuni
, widget
);
291 set_scrollbar_max(xuni
, widget
->compose
->widget
[WID_LISTBOX_HSCROLL
],
292 widget
->p
.listbox
->maxwidth
);
294 clear_widget_clip(xuni
, widget
->compose
->widget
[WID_LISTBOX_DATA
]);
296 add_panel_clip(xuni
, widget
->compose
->widget
[WID_LISTBOX_DATA
],
297 -xclip
, -yclip
, xclip
, yclip
, 0, 0);
298 /*add_widget_clip(xuni, widget->compose->widget[WID_LISTBOX_DATA],
299 width, 0, 0, 0, -width * 2, 0);*/
302 static void rescale_listbox(struct xuni_t
*xuni
, struct widget_t
*widget
) {
304 double width
= calculate_scrollbar_width(widget
, xuni
);
305 double boxsize
= (get_box_width(xuni
->theme
->current
) / 100.0) * 2.0
306 * widget
->pos
->real
.w
;
307 double boxsizeh
= (get_box_height(xuni
->theme
->current
) / 100.0) * 2.0
308 * widget
->pos
->real
.h
;
309 /*double boxsizeh = get_box_height(xuni->theme->current)
310 * (get_box_height(xuni->theme->current) / 100.0);*/
311 struct widget_t
*data
= widget
->compose
->widget
[WID_LISTBOX_DATA
];
313 data
->pos
->scale
.x
= boxsize
;
314 data
->pos
->scale
.y
= boxsizeh
;
315 data
->pos
->scale
.w
= 100.0 - width
- boxsize
* 2;
316 data
->pos
->scale
.h
= 100.0 - boxsizeh
* 2;
318 widget_compose_event(xuni
, widget
, WIDGET_EVENT_RESCALE
);