5 #include "../graphics.h"
10 #include "scrollbar.h"
14 static void init_vertical_scrollbar(struct widget_t
*widget
,
16 static void init_horizontal_scrollbar(struct widget_t
*widget
,
19 static void free_scrollbar(struct xuni_t
*xuni
, struct widget_t
*widget
);
20 static void reposition_scrollbar(struct xuni_t
*xuni
,
21 struct widget_t
*widget
);
22 static void rescale_scrollbar(struct xuni_t
*xuni
, struct widget_t
*widget
);
23 static void paint_scrollbar(struct xuni_t
*xuni
, struct widget_t
*widget
);
25 static double calculate_seek_height(struct widget_t
*widget
,
28 void scrollbar_widget_event(struct xuni_t
*xuni
, struct widget_t
*widget
,
29 enum widget_event_t event
) {
31 static void (*function
[])(struct xuni_t
*xuni
, struct widget_t
*widget
)
41 call_widget_event_func(xuni
, widget
, event
, function
,
42 sizeof(function
) / sizeof(*function
));
45 void init_scrollbar(struct widget_t
*widget
, struct xuni_t
*xuni
, int max
,
46 enum scrollbar_orientation_t orientation
) {
48 widget
->type
= WIDGET_SCROLLBAR
;
49 widget
->p
.scrollbar
= xuni_memory_allocate(sizeof(*widget
->p
.scrollbar
));
51 widget
->p
.scrollbar
->pos
= 0;
52 widget
->p
.scrollbar
->max
= max
;
53 widget
->p
.scrollbar
->orientation
= orientation
;
55 if(orientation
== SCROLLBAR_ORIENTATION_VERTICAL
) {
56 init_vertical_scrollbar(widget
, xuni
);
58 else if(orientation
== SCROLLBAR_ORIENTATION_HORIZONTAL
) {
59 init_horizontal_scrollbar(widget
, xuni
);
62 printf("Unsupported scrollbar orientation: %i\n", (int)orientation
);
66 static void init_vertical_scrollbar(struct widget_t
*widget
,
67 struct xuni_t
*xuni
) {
69 double height
= widget
->pos
->scale
.w
/* / screen_ratio(xuni->smode) */;
72 add_allocate_widget_compose(widget
, "alwaysinbox");
74 init_widget_pos(last_compose_widget(widget
), 0, height
,
75 100.0, 100.0 - height
* 2, POS_PACK_NONE
);
76 init_box(last_compose_widget(widget
), BOX_STYLE_ALWAYSIN
, 0);
78 /*last_compose_widget(widget)->visibility &= ~WIDGET_VISIBILITY_INDEPENDENT;*/
81 add_allocate_widget_compose(widget
, "less");
83 init_widget_pos(last_compose_widget(widget
), 0, 0, 100.0, height
,
85 init_button(last_compose_widget(widget
), 0);
87 init_button_image(xuni
, last_compose_widget(widget
),
88 widget_nameid_access(xuni
->theme
->current
, THEME_SCROLL_UP
));
90 /*last_compose_widget(widget)->visibility &= ~WIDGET_VISIBILITY_INDEPENDENT;*/
93 add_allocate_widget_compose(widget
, "seek");
95 init_widget_pos(last_compose_widget(widget
), 0, height
, 100.0, height
,
97 init_button(last_compose_widget(widget
), 0);
99 /*last_compose_widget(widget)->visibility &= ~WIDGET_VISIBILITY_INDEPENDENT;*/
102 add_allocate_widget_compose(widget
, "more");
104 init_widget_pos(last_compose_widget(widget
), 0, 100.0 - height
,
105 100.0, height
, POS_PACK_NONE
);
106 init_button(last_compose_widget(widget
), 0);
108 init_button_image(xuni
, last_compose_widget(widget
),
109 widget_nameid_access(xuni
->theme
->current
, THEME_SCROLL_DOWN
));
111 /*last_compose_widget(widget)->visibility &= ~WIDGET_VISIBILITY_INDEPENDENT;
113 widget->visibility &= ~WIDGET_VISIBILITY_NOT_COMPOSE;*/
116 static void init_horizontal_scrollbar(struct widget_t
*widget
,
117 struct xuni_t
*xuni
) {
119 double width
= widget
->pos
->scale
.h
;
122 add_allocate_widget_compose(widget
, "alwaysinbox");
124 init_widget_pos(last_compose_widget(widget
), width
, 0,
125 100.0 - width
* 2, 100.0, POS_PACK_NONE
);
126 init_box(last_compose_widget(widget
), BOX_STYLE_ALWAYSIN
, 0);
129 add_allocate_widget_compose(widget
, "less");
131 init_widget_pos(last_compose_widget(widget
), 0, 0, width
, 100.0,
133 init_button(last_compose_widget(widget
), 0);
135 init_button_image(xuni
, last_compose_widget(widget
),
136 widget_nameid_access(xuni
->theme
->current
, THEME_SCROLL_LEFT
));
139 add_allocate_widget_compose(widget
, "seek");
141 init_widget_pos(last_compose_widget(widget
), width
, 0, width
, 100.0,
143 init_button(last_compose_widget(widget
), 0);
146 add_allocate_widget_compose(widget
, "more");
148 init_widget_pos(last_compose_widget(widget
), 100.0 - width
, 0,
149 width
, 100.0, POS_PACK_NONE
);
150 init_button(last_compose_widget(widget
), 0);
152 init_button_image(xuni
, last_compose_widget(widget
),
153 widget_nameid_access(xuni
->theme
->current
, THEME_SCROLL_RIGHT
));
156 static void free_scrollbar(struct xuni_t
*xuni
, struct widget_t
*widget
) {
157 xuni_memory_free(widget
->p
.scrollbar
);
160 static void paint_scrollbar(struct xuni_t
*xuni
, struct widget_t
*widget
) {
161 widget_event(xuni
, widget
->compose
->widget
[WID_SCROLLBAR_SEEKBAR
],
164 /*set_widget_clip(widget->compose->widget[WID_SCROLLBAR_UP]
165 ->compose->widget[WID_BUTTON_LABEL],
166 widget->compose->widget[WID_SCROLLBAR_UP]->pos->real.x,
167 widget->compose->widget[WID_SCROLLBAR_UP]->pos->real.y,
170 widget->pos->real.h);*/
172 widget_event(xuni
, widget
->compose
->widget
[WID_SCROLLBAR_UP
],
174 widget_event(xuni
, widget
->compose
->widget
[WID_SCROLLBAR_SEEK
],
177 /*set_widget_clip(widget->compose->widget[WID_SCROLLBAR_DOWN]
178 ->compose->widget[WID_BUTTON_LABEL],
179 widget->compose->widget[WID_SCROLLBAR_DOWN]->pos->real.x,
180 widget->compose->widget[WID_SCROLLBAR_DOWN]->pos->real.y,
183 widget->pos->real.h);*/
185 /*printf("Painting WID_SCROLLBAR_DOWN at (%i,%i)\n",
186 widget->compose->widget[WID_SCROLLBAR_DOWN]->pos->real.x,
187 widget->compose->widget[WID_SCROLLBAR_DOWN]->pos->real.y);*/
189 widget_event(xuni
, widget
->compose
->widget
[WID_SCROLLBAR_DOWN
],
193 static void reposition_scrollbar(struct xuni_t
*xuni
,
194 struct widget_t
*widget
) {
196 struct widget_t
*seek
= widget
->compose
->widget
[WID_SCROLLBAR_SEEK
];
197 struct widget_t
*seekbar
= widget
->compose
->widget
[WID_SCROLLBAR_SEEKBAR
];
199 if(widget
->p
.scrollbar
->orientation
== SCROLLBAR_ORIENTATION_VERTICAL
) {
200 add_widget_clip(xuni
, seek
,
201 0, (seekbar
->pos
->scale
.h
- seek
->pos
->scale
.h
)
202 * widget
->p
.scrollbar
->pos
/ 100.0,
206 add_widget_clip(xuni
, seek
,
207 (seekbar
->pos
->scale
.w
- seek
->pos
->scale
.w
)
208 * widget
->p
.scrollbar
->pos
/ 100.0, 0,
213 static void rescale_scrollbar(struct xuni_t
*xuni
, struct widget_t
*widget
) {
216 struct widget_t *seek = widget->compose->widget[WID_SCROLLBAR_SEEK];
218 seek->pos->real.x += get_scrollbar_pos_int(widget);*/
221 static double calculate_seek_height(struct widget_t
*widget
,
222 struct xuni_t
*xuni
) {
226 ratio
= (widget
->pos
->scale
.w
/ 100.0 * xuni
->smode
->screen
->w
)
227 / (widget
->pos
->scale
.h
/ 100.0 * xuni
->smode
->screen
->h
);
229 return (100.0 / 15.0) / (real_scale_height(widget
));
232 /* !!! doesn't really need to be passed xuni */
233 void set_scrollbar_max(struct xuni_t
*xuni
, struct widget_t
*widget
,
236 widget
->p
.scrollbar
->max
= max
;
238 if(widget
->p
.scrollbar
->max
< 0) widget
->p
.scrollbar
->max
= 0;
240 /* in rescale_scrollbar(), this doesn't work the first time */
242 struct widget_t
*seek
, *seekbar
;
243 double boxheight
, minheight
, value
;
245 seek
= widget
->compose
->widget
[WID_SCROLLBAR_SEEK
];
246 seekbar
= widget
->compose
->widget
[WID_SCROLLBAR_SEEKBAR
];
249 seek
->pos
->scale
.h
= seekbar
->pos
->scale
.h
;
252 value
= 1.0 / (1.0 + max
/ (double)widget
->pos
->real
.h
);
254 /* boxheight not used */
255 boxheight
= get_box_height(xuni
, xuni
->theme
->current
);
257 minheight
= calculate_seek_height(widget
, xuni
);
258 /*if(value < boxheight) {
259 seek->pos->scale.h = boxheight;
261 seek
->pos
->scale
.h
= seekbar
->pos
->scale
.h
* value
;
262 if(seek
->pos
->scale
.h
< minheight
) {
263 seek
->pos
->scale
.h
= minheight
;
264 /*printf("set to minimum\n");*/
267 /*printf("value=%f, minheight=%f, seek->pos->scale.h=%f\n",
268 value, minheight, seek->pos->scale.h);*/
271 widget_event(xuni
, widget
, WIDGET_EVENT_RESCALE
);
274 /*printf("set_scrollbar_max(): max=%i pos=%f\n", max,
275 widget->p.scrollbar->pos);*/
277 /*restrict_int(&widget->p.scrollbar->pos, widget->p.scrollbar->max);*/
279 /*widget_event(xuni->smode, widget, WIDGET_EVENT_RESCALE);*/
282 /*! Scrolls the scrollbar \a widget by \a amount, where \a amount is the exact
283 pixel value to move the scrollbar by.
284 \param xuni The xuni_t structure.
285 \param widget The scrollbar widget that should be scrolled. An error will
286 ensue if this widget is not a scrollbar.
287 \param amount The number of pixels to scroll the scrollbar by.
289 void move_scrollbar(struct xuni_t
*xuni
, struct widget_t
*widget
,
292 /*struct widget_t *seek, *seekbar;*/
296 if(assert_widget_type(xuni
, widget
, WIDGET_SCROLLBAR
,
297 __FILE__
, __LINE__
)) {
302 widget
->p
.scrollbar
->pos
303 += (double)amount
/ widget
->p
.scrollbar
->max
* 100.0;
305 restrict_pos(&widget
->p
.scrollbar
->pos
);
307 /*seek = widget->compose->widget[WID_SCROLLBAR_SEEK];
308 seekbar = widget->compose->widget[WID_SCROLLBAR_SEEKBAR];*/
311 printf("seekbar height: %f\n"
314 seekbar->pos->scale.h,
316 (seekbar->pos->scale.h - seek->pos->scale.h));
320 widget->p.scrollbar->max,
321 widget->p.scrollbar->pos,
322 ((double)widget->p.scrollbar->max / widget->p.scrollbar->pos));*/
324 /*add_widget_clip(seek,
325 0, (seekbar->pos->scale.h - seek->pos->scale.h)
326 * ((double)widget->p.scrollbar->pos / widget->p.scrollbar->max),
329 /*widget_event(xuni->smode, widget, WIDGET_EVENT_RESCALE);*/
332 /*! Returns the position of the scrollbar \a widget as a percentage value.
333 Note that this value should stay the same between rescalings.
334 \param widget The scrollbar to return the position of.
335 \return The position that the scrollbar \a widget is scrolled to.
337 double get_scrollbar_pos(struct widget_t
*widget
) {
338 return widget
->p
.scrollbar
->pos
;
341 /*! Converts a scrollbar's position to an absolute pixel value. Note that
342 because scrollbar values are stored as percentages, this function still
343 works if it gets rescaled. The functions that use the value of this
344 function will have to call it again, but it will return the right values.
345 \param widget The scrollbar widget to examine.
346 \return How far the scrollbar is scrolled, as a pixel value.
348 int get_scrollbar_pos_int(struct widget_t
*widget
) {
349 return widget
->p
.scrollbar
->pos
/ 100.0 * widget
->p
.scrollbar
->max
;