source: mainline/uspace/lib/ui/src/scrollbar.c@ f2b9ecf

ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since f2b9ecf was bd16113, checked in by Jiri Svoboda <jiri@…>, 3 years ago

Scrollbar (WIP)

  • Property mode set to 100644
File size: 18.9 KB
Line 
1/*
2 * Copyright (c) 2022 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libui
30 * @{
31 */
32/**
33 * @file Scrollbar
34 */
35
36#include <errno.h>
37#include <gfx/color.h>
38#include <gfx/context.h>
39#include <gfx/render.h>
40#include <gfx/text.h>
41#include <io/pos_event.h>
42#include <stdlib.h>
43#include <str.h>
44#include <ui/control.h>
45#include <ui/paint.h>
46#include <ui/pbutton.h>
47#include <ui/scrollbar.h>
48#include "../private/resource.h"
49#include "../private/scrollbar.h"
50
51/*
52 * The kind reader will appreciate that scrollbar thumb dimensions 23:15
53 * are chosen such that, after subtracting the frame width (2 times 1),
54 * we get 21:13, which is a good approximation of the golden ratio.
55 */
56enum {
57 /** Scrollbar button width */
58 ui_scrollbar_btn_len = 20,
59 /** Scrollbar button width in text mode */
60 ui_scrollbar_btn_len_text = 1,
61 /** Scrollbar thumb frame thickness */
62 ui_scrollbar_thumb_frame_thickness = 1,
63 /** Scrollbar thumb bevel width */
64 ui_scrollbar_thumb_bevel_width = 2,
65 /** Scrollbar default thumb length */
66 ui_scrollbar_def_thumb_len = 20,
67 /** Scrollbar default thumb length in text mode */
68 ui_scrollbar_def_thumb_len_text = 1,
69 /** Scrollbar minimum thumb length */
70 ui_scrollbar_min_thumb_len = 10,
71 /** Scrollbar minimum thumb length in text mode */
72 ui_scrollbar_min_thumb_len_text = 1,
73};
74
75static void ui_scrollbar_btn_up_clicked(ui_pbutton_t *, void *);
76static void ui_scrollbar_btn_down_clicked(ui_pbutton_t *, void *);
77static void ui_scrollbar_ctl_destroy(void *);
78static errno_t ui_scrollbar_ctl_paint(void *);
79static ui_evclaim_t ui_scrollbar_ctl_pos_event(void *, pos_event_t *);
80
81ui_pbutton_cb_t ui_scrollbar_btn_up_cb = {
82 .clicked = ui_scrollbar_btn_up_clicked
83};
84
85ui_pbutton_cb_t ui_scrollbar_btn_down_cb = {
86 .clicked = ui_scrollbar_btn_down_clicked
87};
88
89/** Scrollbar control ops */
90ui_control_ops_t ui_scrollbar_ops = {
91 .destroy = ui_scrollbar_ctl_destroy,
92 .paint = ui_scrollbar_ctl_paint,
93 .pos_event = ui_scrollbar_ctl_pos_event
94};
95
96/** Create new scrollbar.
97 *
98 * @param resource UI resource
99 * @param rscrollbar Place to store pointer to new scrollbar
100 * @return EOK on success, ENOMEM if out of memory
101 */
102errno_t ui_scrollbar_create(ui_resource_t *resource,
103 ui_scrollbar_t **rscrollbar)
104{
105 ui_scrollbar_t *scrollbar;
106 errno_t rc;
107
108 scrollbar = calloc(1, sizeof(ui_scrollbar_t));
109 if (scrollbar == NULL)
110 return ENOMEM;
111
112 rc = ui_control_new(&ui_scrollbar_ops, (void *) scrollbar,
113 &scrollbar->control);
114 if (rc != EOK) {
115 free(scrollbar);
116 return rc;
117 }
118
119 rc = ui_pbutton_create(resource, resource->textmode ? "\u25c4" : "<",
120 &scrollbar->btn_up);
121 if (rc != EOK)
122 goto error;
123
124 ui_pbutton_set_cb(scrollbar->btn_up, &ui_scrollbar_btn_up_cb,
125 (void *) scrollbar);
126
127 rc = ui_pbutton_create(resource, resource->textmode ? "\u25ba" : ">",
128 &scrollbar->btn_down);
129 if (rc != EOK)
130 goto error;
131
132 ui_pbutton_set_cb(scrollbar->btn_down, &ui_scrollbar_btn_down_cb,
133 (void *) scrollbar);
134
135 scrollbar->thumb_len = resource->textmode ?
136 ui_scrollbar_def_thumb_len_text :
137 ui_scrollbar_def_thumb_len;
138
139 scrollbar->res = resource;
140 *rscrollbar = scrollbar;
141 return EOK;
142error:
143 ui_scrollbar_destroy(scrollbar);
144 return rc;
145}
146
147/** Destroy scrollbar.
148 *
149 * @param scrollbar Scrollbar or @c NULL
150 */
151void ui_scrollbar_destroy(ui_scrollbar_t *scrollbar)
152{
153 if (scrollbar == NULL)
154 return;
155
156 ui_pbutton_destroy(scrollbar->btn_up);
157 ui_pbutton_destroy(scrollbar->btn_down);
158 ui_control_delete(scrollbar->control);
159 free(scrollbar);
160}
161
162/** Get base control from scrollbar.
163 *
164 * @param scrollbar Scrollbar
165 * @return Control
166 */
167ui_control_t *ui_scrollbar_ctl(ui_scrollbar_t *scrollbar)
168{
169 return scrollbar->control;
170}
171
172/** Set scrollbar callbacks.
173 *
174 * @param scrollbar Scrollbar
175 * @param cb Scrollbar callbacks
176 * @param arg Callback argument
177 */
178void ui_scrollbar_set_cb(ui_scrollbar_t *scrollbar, ui_scrollbar_cb_t *cb, void *arg)
179{
180 scrollbar->cb = cb;
181 scrollbar->arg = arg;
182}
183
184/** Set scrollbar rectangle.
185 *
186 * @param scrollbar Scrollbar
187 * @param rect New scrollbar rectangle
188 */
189void ui_scrollbar_set_rect(ui_scrollbar_t *scrollbar, gfx_rect_t *rect)
190{
191 ui_scrollbar_geom_t geom;
192
193 scrollbar->rect = *rect;
194
195 ui_scrollbar_get_geom(scrollbar, &geom);
196 ui_pbutton_set_rect(scrollbar->btn_up, &geom.up_btn_rect);
197 ui_pbutton_set_rect(scrollbar->btn_down, &geom.down_btn_rect);
198}
199
200/** Paint outer thumb frame.
201 *
202 * @param scrollbar Scrollbar
203 * @return EOK on success or an error code
204 */
205static errno_t ui_scrollbar_paint_thumb_frame(ui_resource_t *res, gfx_rect_t *rect,
206 gfx_coord_t thickness, gfx_rect_t *inside)
207{
208 gfx_rect_t drect;
209 errno_t rc;
210
211 rc = gfx_set_color(res->gc, res->btn_frame_color);
212 if (rc != EOK)
213 goto error;
214
215 drect.p0.x = rect->p0.x + 1;
216 drect.p0.y = rect->p0.y;
217 drect.p1.x = rect->p1.x - 1;
218 drect.p1.y = rect->p0.y + thickness;
219 rc = gfx_fill_rect(res->gc, &drect);
220 if (rc != EOK)
221 goto error;
222
223 drect.p0.x = rect->p0.x + 1;
224 drect.p0.y = rect->p1.y - thickness;
225 drect.p1.x = rect->p1.x - 1;
226 drect.p1.y = rect->p1.y;
227 rc = gfx_fill_rect(res->gc, &drect);
228 if (rc != EOK)
229 goto error;
230
231 drect.p0.x = rect->p0.x;
232 drect.p0.y = rect->p0.y + 1;
233 drect.p1.x = rect->p0.x + thickness;
234 drect.p1.y = rect->p1.y - 1;
235 rc = gfx_fill_rect(res->gc, &drect);
236 if (rc != EOK)
237 goto error;
238
239 drect.p0.x = rect->p1.x - thickness;
240 drect.p0.y = rect->p0.y + 1;
241 drect.p1.x = rect->p1.x;
242 drect.p1.y = rect->p1.y - 1;
243 rc = gfx_fill_rect(res->gc, &drect);
244 if (rc != EOK)
245 goto error;
246
247 if (inside != NULL) {
248 inside->p0.x = rect->p0.x + thickness;
249 inside->p0.y = rect->p0.y + thickness;
250 inside->p1.x = rect->p1.x - thickness;
251 inside->p1.y = rect->p1.y - thickness;
252 }
253
254 return EOK;
255error:
256 return rc;
257}
258
259/** Paint outset scrollbar bevel.
260 *
261 * @param scrollbar Scrollbar
262 * @return EOK on success or an error code
263 */
264static errno_t ui_scrollbar_paint_outset(ui_scrollbar_t *scrollbar,
265 gfx_rect_t *rect, gfx_rect_t *inside)
266{
267 return ui_paint_bevel(scrollbar->res->gc, rect,
268 scrollbar->res->btn_highlight_color,
269 scrollbar->res->btn_shadow_color, ui_scrollbar_thumb_bevel_width, inside);
270}
271
272/** Determine scrollbar thumb rectagle.
273 *
274 * @param scrollbar Scrollbar
275 */
276static void ui_scrollbar_thumb_rect(ui_scrollbar_t *scrollbar, gfx_rect_t *rect)
277{
278 ui_scrollbar_geom_t geom;
279
280 ui_scrollbar_get_geom(scrollbar, &geom);
281 *rect = geom.thumb_rect;
282}
283
284/** Determine scrollbar through length.
285 *
286 * Return the size of the space within which the thumb can move
287 * (without subtracting the length of the thumb).
288 *
289 * @param scrollbar Scrollbar
290 * @return Scrollbar through length in pixels
291 */
292gfx_coord_t ui_scrollbar_through_length(ui_scrollbar_t *scrollbar)
293{
294 gfx_coord2_t dims;
295 gfx_coord_t w;
296
297 gfx_rect_dims(&scrollbar->rect, &dims);
298 w = scrollbar->res->textmode ? ui_scrollbar_btn_len_text :
299 ui_scrollbar_btn_len;
300 return dims.x - 2 * w;
301}
302
303/** Determine scrollbar move length.
304 *
305 * Return the maximum distance the thumb can move.
306 *
307 * @param scrollbar Scrollbar
308 * @return Scrollbar move length in pixels
309 */
310gfx_coord_t ui_scrollbar_move_length(ui_scrollbar_t *scrollbar)
311{
312 return ui_scrollbar_through_length(scrollbar) -
313 scrollbar->thumb_len;
314}
315
316/** Set scrollbar thumb length.
317 *
318 * @param scrollbar Scrollbar
319 * @param len Thumb length in pixels
320 */
321void ui_scrollbar_set_thumb_length(ui_scrollbar_t *scrollbar, gfx_coord_t len)
322{
323 gfx_coord_t min_len;
324 gfx_coord_t max_len;
325
326 min_len = scrollbar->res->textmode ?
327 ui_scrollbar_min_thumb_len_text :
328 ui_scrollbar_min_thumb_len;
329
330 max_len = ui_scrollbar_through_length(scrollbar);
331 if (len < min_len)
332 len = min_len;
333 if (len > max_len)
334 len = max_len;
335
336 if (len != scrollbar->thumb_len) {
337 (void) ui_scrollbar_thumb_clear(scrollbar);
338 scrollbar->thumb_len = len;
339 (void) ui_scrollbar_paint(scrollbar);
340 }
341}
342
343/** Get scrollbar thumb position.
344 *
345 * @param scrollbar Scrollbar
346 * @return Scrollbar thumb position in pixels
347 */
348gfx_coord_t ui_scrollbar_get_pos(ui_scrollbar_t *scrollbar)
349{
350 return scrollbar->pos;
351}
352
353/** Set scrollbar thumb position.
354 *
355 * The position is clipped to the allowed range.
356 *
357 * @param scrollbar Scrollbar
358 * @parap pos Scrollbar thumb position in pixels
359 */
360void ui_scrollbar_set_pos(ui_scrollbar_t *scrollbar, gfx_coord_t pos)
361{
362 gfx_coord_t length;
363
364 length = ui_scrollbar_move_length(scrollbar);
365 if (pos < 0)
366 pos = 0;
367 if (pos > length)
368 pos = length;
369
370 if (pos != scrollbar->pos) {
371 (void) ui_scrollbar_thumb_clear(scrollbar);
372 scrollbar->pos = pos;
373 (void) ui_scrollbar_paint(scrollbar);
374 ui_scrollbar_moved(scrollbar, pos);
375 }
376}
377
378/** Paint scrollbar in graphics mode.
379 *
380 * @param scrollbar Scrollbar
381 * @return EOK on success or an error code
382 */
383errno_t ui_scrollbar_paint_gfx(ui_scrollbar_t *scrollbar)
384{
385 ui_scrollbar_geom_t geom;
386 gfx_rect_t brect;
387 gfx_rect_t irect;
388 errno_t rc;
389
390 ui_scrollbar_get_geom(scrollbar, &geom);
391
392 /* Paint scrollbar frame */
393
394 rc = ui_paint_inset_frame(scrollbar->res, &scrollbar->rect, NULL);
395 if (rc != EOK)
396 goto error;
397
398 /* Paint scrollbar through */
399
400 rc = gfx_set_color(scrollbar->res->gc,
401 scrollbar->res->sbar_through_color);
402 if (rc != EOK)
403 goto error;
404
405 rc = gfx_fill_rect(scrollbar->res->gc, &geom.through_rect);
406 if (rc != EOK)
407 goto error;
408
409 /* Paint scrollbar thumb */
410
411 rc = ui_scrollbar_paint_thumb_frame(scrollbar->res, &geom.thumb_rect,
412 ui_scrollbar_thumb_frame_thickness, &brect);
413 if (rc != EOK)
414 goto error;
415
416 rc = ui_scrollbar_paint_outset(scrollbar, &brect, &irect);
417 if (rc != EOK)
418 goto error;
419
420 rc = gfx_set_color(scrollbar->res->gc, scrollbar->res->btn_face_color);
421 if (rc != EOK)
422 goto error;
423
424 rc = gfx_fill_rect(scrollbar->res->gc, &irect);
425 if (rc != EOK)
426 goto error;
427
428 rc = ui_pbutton_paint(scrollbar->btn_up);
429 if (rc != EOK)
430 goto error;
431
432 rc = ui_pbutton_paint(scrollbar->btn_down);
433 if (rc != EOK)
434 goto error;
435
436 rc = gfx_update(scrollbar->res->gc);
437 if (rc != EOK)
438 goto error;
439
440 return EOK;
441error:
442 return rc;
443}
444
445/** Paint scrollbar in text mode.
446 *
447 * @param scrollbar Scrollbar
448 * @return EOK on success or an error code
449 */
450errno_t ui_scrollbar_paint_text(ui_scrollbar_t *scrollbar)
451{
452 gfx_coord2_t pos;
453 gfx_text_fmt_t fmt;
454 gfx_coord_t w, i;
455 char *buf;
456 const char *gchar;
457 size_t gcharsz;
458 errno_t rc;
459
460 /* Paint scrollbar through */
461
462 pos = scrollbar->rect.p0;
463 pos.x += ui_scrollbar_btn_len_text;
464
465 gfx_text_fmt_init(&fmt);
466 fmt.font = scrollbar->res->font;
467 fmt.color = scrollbar->res->sbar_through_color;
468 fmt.halign = gfx_halign_left;
469 fmt.valign = gfx_valign_top;
470
471 w = scrollbar->rect.p1.x - scrollbar->rect.p0.x -
472 2 * ui_scrollbar_btn_len_text;
473 gchar = "\u2592";
474 gcharsz = str_size(gchar);
475
476 buf = malloc(w * gcharsz + 1);
477 if (buf == NULL)
478 return ENOMEM;
479
480 for (i = 0; i < w; i++)
481 str_cpy(buf + i * gcharsz, (w - i) * gcharsz + 1, gchar);
482 buf[w * gcharsz] = '\0';
483
484 rc = gfx_puttext(&pos, &fmt, buf);
485 free(buf);
486 if (rc != EOK)
487 goto error;
488
489 /* Paint scrollbar thumb */
490
491 pos.x += scrollbar->pos;
492
493 gchar = "\u25a0";
494 gcharsz = str_size(gchar);
495 w = scrollbar->thumb_len;
496
497 buf = malloc(w * gcharsz + 1);
498 if (buf == NULL)
499 return ENOMEM;
500
501 for (i = 0; i < w; i++)
502 str_cpy(buf + i * gcharsz, (w - i) * gcharsz + 1, gchar);
503 buf[w * gcharsz] = '\0';
504
505 rc = gfx_puttext(&pos, &fmt, buf);
506 free(buf);
507 if (rc != EOK)
508 goto error;
509
510 rc = ui_pbutton_paint(scrollbar->btn_up);
511 if (rc != EOK)
512 goto error;
513
514 rc = ui_pbutton_paint(scrollbar->btn_down);
515 if (rc != EOK)
516 goto error;
517
518 rc = gfx_update(scrollbar->res->gc);
519 if (rc != EOK)
520 goto error;
521
522 return EOK;
523error:
524 return rc;
525}
526
527/** Paint scrollbar.
528 *
529 * @param scrollbar Scrollbar
530 * @return EOK on success or an error code
531 */
532errno_t ui_scrollbar_paint(ui_scrollbar_t *scrollbar)
533{
534 if (scrollbar->res->textmode)
535 return ui_scrollbar_paint_text(scrollbar);
536 else
537 return ui_scrollbar_paint_gfx(scrollbar);
538}
539
540/** Get scrollbar geometry.
541 *
542 * @param scrollbar Scrollbar
543 * @param geom Structure to fill in with computed geometry
544 */
545void ui_scrollbar_get_geom(ui_scrollbar_t *scrollbar, ui_scrollbar_geom_t *geom)
546{
547 gfx_coord_t btn_len;
548 gfx_rect_t orect;
549 gfx_rect_t irect;
550
551 if (scrollbar->res->textmode) {
552 btn_len = ui_scrollbar_btn_len_text;
553 } else {
554 btn_len = ui_scrollbar_btn_len;
555 }
556
557 if (scrollbar->res->textmode) {
558 irect = scrollbar->rect;
559 orect = scrollbar->rect;
560 } else {
561 ui_paint_get_inset_frame_inside(scrollbar->res,
562 &scrollbar->rect, &irect);
563 ui_paint_get_bevel_inside(scrollbar->res->gc,
564 &scrollbar->rect, 1, &orect);
565 }
566
567 /* Up button */
568 geom->up_btn_rect.p0.x = orect.p0.x;
569 geom->up_btn_rect.p0.y = orect.p0.y;
570 geom->up_btn_rect.p1.x = orect.p0.x + btn_len;
571 geom->up_btn_rect.p1.y = orect.p1.y;
572
573 /* Through */
574 geom->through_rect.p0.x = geom->up_btn_rect.p1.x;
575 geom->through_rect.p0.y = irect.p0.y;
576 geom->through_rect.p1.x = orect.p1.x - btn_len;
577 geom->through_rect.p1.y = irect.p1.y;
578
579 /* Thumb */
580 geom->thumb_rect.p0.x = geom->up_btn_rect.p1.x + scrollbar->pos;
581 geom->thumb_rect.p0.y = orect.p0.y;
582 geom->thumb_rect.p1.x = geom->thumb_rect.p0.x + scrollbar->thumb_len;
583 geom->thumb_rect.p1.y = orect.p1.y;
584
585 /* Down button */
586 geom->down_btn_rect.p0.x = geom->through_rect.p1.x;
587 geom->down_btn_rect.p0.y = orect.p0.y;
588 geom->down_btn_rect.p1.x = orect.p1.x;
589 geom->down_btn_rect.p1.y = orect.p1.y;
590}
591
592/** Clear scrollbar thumb.
593 *
594 * @param scrollbar Scrollbar
595 * @return EOK on success or an error code
596 */
597errno_t ui_scrollbar_thumb_clear(ui_scrollbar_t *scrollbar)
598{
599 gfx_rect_t rect;
600 errno_t rc;
601
602 /* No need to clear thumb in text mode */
603 if (scrollbar->res->textmode)
604 return EOK;
605
606 ui_scrollbar_thumb_rect(scrollbar, &rect);
607
608 rc = gfx_set_color(scrollbar->res->gc, scrollbar->res->wnd_face_color);
609 if (rc != EOK)
610 goto error;
611
612 rc = gfx_fill_rect(scrollbar->res->gc, &rect);
613 if (rc != EOK)
614 goto error;
615
616 return EOK;
617error:
618 return rc;
619}
620
621/** Press down scrollbar.
622 *
623 * @param scrollbar Scrollbar
624 * @param pos Pointer position
625 */
626void ui_scrollbar_press(ui_scrollbar_t *scrollbar, gfx_coord2_t *pos)
627{
628 if (scrollbar->held)
629 return;
630
631 scrollbar->held = true;
632 scrollbar->press_pos = *pos;
633 scrollbar->last_pos = scrollbar->pos;
634
635 (void) ui_scrollbar_paint(scrollbar);
636}
637
638/** Release scrollbar.
639 *
640 * @param scrollbar Scrollbar
641 * @param pos Pointer position
642 */
643void ui_scrollbar_release(ui_scrollbar_t *scrollbar, gfx_coord2_t *pos)
644{
645 if (!scrollbar->held)
646 return;
647
648 ui_scrollbar_update(scrollbar, pos);
649 scrollbar->held = false;
650}
651
652/** Pointer moved.
653 *
654 * @param scrollbar Scrollbar
655 * @param pos New pointer position
656 */
657void ui_scrollbar_update(ui_scrollbar_t *scrollbar, gfx_coord2_t *pos)
658{
659 gfx_coord_t spos;
660
661 if (scrollbar->held) {
662 spos = scrollbar->last_pos + pos->x - scrollbar->press_pos.x;
663 ui_scrollbar_set_pos(scrollbar, spos);
664 }
665}
666
667/** Scrollbar up button was pressed.
668 *
669 * @param scrollbar Scrollbar
670 */
671void ui_scrollbar_up(ui_scrollbar_t *scrollbar)
672{
673 if (scrollbar->cb != NULL && scrollbar->cb->up != NULL)
674 scrollbar->cb->up(scrollbar, scrollbar->arg);
675}
676
677/** Scrollbar down button was pressed.
678 *
679 * @param scrollbar Scrollbar
680 */
681void ui_scrollbar_down(ui_scrollbar_t *scrollbar)
682{
683 if (scrollbar->cb != NULL && scrollbar->cb->up != NULL)
684 scrollbar->cb->down(scrollbar, scrollbar->arg);
685}
686
687/** Scrollbar was moved.
688 *
689 * @param scrollbar Scrollbar
690 */
691void ui_scrollbar_moved(ui_scrollbar_t *scrollbar, gfx_coord_t pos)
692{
693 if (scrollbar->cb != NULL && scrollbar->cb->moved != NULL)
694 scrollbar->cb->moved(scrollbar, scrollbar->arg, pos);
695}
696
697/** Handle scrollbar position event.
698 *
699 * @param scrollbar Scrollbar
700 * @param pos_event Position event
701 * @return @c ui_claimed iff the event is claimed
702 */
703ui_evclaim_t ui_scrollbar_pos_event(ui_scrollbar_t *scrollbar, pos_event_t *event)
704{
705 gfx_coord2_t pos;
706 gfx_rect_t rect;
707 ui_evclaim_t claimed;
708
709 pos.x = event->hpos;
710 pos.y = event->vpos;
711
712 claimed = ui_pbutton_pos_event(scrollbar->btn_up, event);
713 if (claimed == ui_claimed)
714 return ui_claimed;
715
716 claimed = ui_pbutton_pos_event(scrollbar->btn_down, event);
717 if (claimed == ui_claimed)
718 return ui_claimed;
719
720 switch (event->type) {
721 case POS_PRESS:
722 ui_scrollbar_thumb_rect(scrollbar, &rect);
723 if (gfx_pix_inside_rect(&pos, &rect)) {
724 ui_scrollbar_press(scrollbar, &pos);
725 scrollbar->press_pos = pos;
726 return ui_claimed;
727 }
728 break;
729 case POS_RELEASE:
730 if (scrollbar->held) {
731 ui_scrollbar_release(scrollbar, &pos);
732 return ui_claimed;
733 }
734 break;
735 case POS_UPDATE:
736 ui_scrollbar_update(scrollbar, &pos);
737 break;
738 case POS_DCLICK:
739 break;
740 }
741
742 return ui_unclaimed;
743}
744
745/** Scrollbar up button clicked.
746 *
747 * @param pbutton Up button
748 * @param arg Argument (ui_scrollbar_t *)
749 */
750static void ui_scrollbar_btn_up_clicked(ui_pbutton_t *pbutton, void *arg)
751{
752 ui_scrollbar_t *scrollbar = (ui_scrollbar_t *)arg;
753
754 ui_scrollbar_up(scrollbar);
755}
756
757/** Scrollbar down button clicked.
758 *
759 * @param pbutton Down button
760 * @param arg Argument (ui_scrollbar_t *)
761 */
762static void ui_scrollbar_btn_down_clicked(ui_pbutton_t *pbutton, void *arg)
763{
764 ui_scrollbar_t *scrollbar = (ui_scrollbar_t *)arg;
765
766 ui_scrollbar_down(scrollbar);
767}
768
769/** Destroy scrollbar control.
770 *
771 * @param arg Argument (ui_scrollbar_t *)
772 */
773void ui_scrollbar_ctl_destroy(void *arg)
774{
775 ui_scrollbar_t *scrollbar = (ui_scrollbar_t *) arg;
776
777 ui_scrollbar_destroy(scrollbar);
778}
779
780/** Paint scrollbar control.
781 *
782 * @param arg Argument (ui_scrollbar_t *)
783 * @return EOK on success or an error code
784 */
785errno_t ui_scrollbar_ctl_paint(void *arg)
786{
787 ui_scrollbar_t *scrollbar = (ui_scrollbar_t *) arg;
788
789 return ui_scrollbar_paint(scrollbar);
790}
791
792/** Handle scrollbar control position event.
793 *
794 * @param arg Argument (ui_scrollbar_t *)
795 * @param pos_event Position event
796 * @return @c ui_claimed iff the event is claimed
797 */
798ui_evclaim_t ui_scrollbar_ctl_pos_event(void *arg, pos_event_t *event)
799{
800 ui_scrollbar_t *scrollbar = (ui_scrollbar_t *) arg;
801
802 return ui_scrollbar_pos_event(scrollbar, event);
803}
804
805/** @}
806 */
Note: See TracBrowser for help on using the repository browser.