summaryrefslogtreecommitdiff
path: root/src/ui/scrollwidget.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/scrollwidget.c')
-rw-r--r--src/ui/scrollwidget.c57
1 files changed, 52 insertions, 5 deletions
diff --git a/src/ui/scrollwidget.c b/src/ui/scrollwidget.c
index cbfd2e70..1be62bb8 100644
--- a/src/ui/scrollwidget.c
+++ b/src/ui/scrollwidget.c
@@ -1,5 +1,6 @@
1#include "scrollwidget.h" 1#include "scrollwidget.h"
2#include "paint.h" 2#include "paint.h"
3#include "util.h"
3 4
4iDefineObjectConstruction(ScrollWidget) 5iDefineObjectConstruction(ScrollWidget)
5 6
@@ -8,6 +9,8 @@ struct Impl_ScrollWidget {
8 iRangei range; 9 iRangei range;
9 int thumb; 10 int thumb;
10 int thumbSize; 11 int thumbSize;
12 iClick click;
13 int startThumb;
11}; 14};
12 15
13void init_ScrollWidget(iScrollWidget *d) { 16void init_ScrollWidget(iScrollWidget *d) {
@@ -19,19 +22,23 @@ void init_ScrollWidget(iScrollWidget *d) {
19 moveToParentRightEdge_WidgetFlag, 22 moveToParentRightEdge_WidgetFlag,
20 iTrue); 23 iTrue);
21 w->rect.size.x = gap_UI * 3; 24 w->rect.size.x = gap_UI * 3;
25 init_Click(&d->click, d, SDL_BUTTON_LEFT);
22} 26}
23 27
24void deinit_ScrollWidget(iScrollWidget *d) { 28void deinit_ScrollWidget(iScrollWidget *d) {
25 iUnused(d); 29 iUnused(d);
26} 30}
27 31
32static int thumbSize_ScrollWidget_(const iScrollWidget *d) {
33 return iMax(gap_UI * 6, d->thumbSize);
34}
35
28static iRect thumbRect_ScrollWidget_(const iScrollWidget *d) { 36static iRect thumbRect_ScrollWidget_(const iScrollWidget *d) {
29 const iRect bounds = bounds_Widget(constAs_Widget(d)); 37 const iRect bounds = bounds_Widget(constAs_Widget(d));
30 iRect rect = init_Rect(bounds.pos.x, bounds.pos.y, bounds.size.x, 0); 38 iRect rect = init_Rect(bounds.pos.x, bounds.pos.y, bounds.size.x, 0);
31 const int total = size_Range(&d->range); 39 const int total = size_Range(&d->range);
32// printf("total: %d thumb: %d thsize: %d\n", total, d->thumb, d->thumbSize); fflush(stdout);
33 if (total > 0) { 40 if (total > 0) {
34 const int tsize = iMax(gap_UI * 6, d->thumbSize); 41 const int tsize = thumbSize_ScrollWidget_(d);
35 const int tpos = 42 const int tpos =
36 iClamp((float) d->thumb / (float) total, 0, 1) * (height_Rect(bounds) - tsize); 43 iClamp((float) d->thumb / (float) total, 0, 1) * (height_Rect(bounds) - tsize);
37 rect.pos.y = tpos; 44 rect.pos.y = tpos;
@@ -46,7 +53,7 @@ static void checkVisible_ScrollWidget_(iScrollWidget *d) {
46 53
47void setRange_ScrollWidget(iScrollWidget *d, iRangei range) { 54void setRange_ScrollWidget(iScrollWidget *d, iRangei range) {
48 range.end = iMax(range.start, range.end); 55 range.end = iMax(range.start, range.end);
49 d->range = range; 56 d->range = range;
50 checkVisible_ScrollWidget_(d); 57 checkVisible_ScrollWidget_(d);
51} 58}
52 59
@@ -58,18 +65,58 @@ void setThumb_ScrollWidget(iScrollWidget *d, int thumb, int thumbSize) {
58 65
59static iBool processEvent_ScrollWidget_(iScrollWidget *d, const SDL_Event *ev) { 66static iBool processEvent_ScrollWidget_(iScrollWidget *d, const SDL_Event *ev) {
60 iWidget *w = as_Widget(d); 67 iWidget *w = as_Widget(d);
68 switch (processEvent_Click(&d->click, ev)) {
69 case started_ClickResult:
70 setFlags_Widget(w, pressed_WidgetFlag, iTrue);
71 d->startThumb = d->thumb;
72 refresh_Widget(w);
73 return iTrue;
74 case drag_ClickResult: {
75 const iRect bounds = bounds_Widget(w);
76 const int offset = delta_Click(&d->click).y;
77 const int total = size_Range(&d->range);
78 int dpos = (float) offset / (float) (height_Rect(bounds) - thumbSize_ScrollWidget_(d)) * total;
79 d->thumb = iClamp(d->startThumb + dpos, d->range.start, d->range.end);
80 postCommand_Widget(w, "scroll.moved arg:%d", d->thumb);
81 refresh_Widget(w);
82 return iTrue;
83 }
84 case finished_ClickResult:
85 case aborted_ClickResult:
86 if (!isMoved_Click(&d->click)) {
87 /* Page up/down. */
88 const iRect tr = thumbRect_ScrollWidget_(d);
89 const int y = pos_Click(&d->click).y;
90 int pgDir = 0;
91 if (y < top_Rect(tr)) {
92 pgDir = -1;
93 }
94 else if (y > bottom_Rect(tr)) {
95 pgDir = +1;
96 }
97 if (pgDir) {
98 postCommand_Widget(w, "scroll.page arg:%d", pgDir);
99 }
100 }
101 setFlags_Widget(w, pressed_WidgetFlag, iFalse);
102 refresh_Widget(w);
103 return iTrue;
104 default:
105 break;
106 }
61 return processEvent_Widget(w, ev); 107 return processEvent_Widget(w, ev);
62} 108}
63 109
64static void draw_ScrollWidget_(const iScrollWidget *d) { 110static void draw_ScrollWidget_(const iScrollWidget *d) {
65 const iWidget *w = constAs_Widget(d); 111 const iWidget *w = constAs_Widget(d);
66 const iRect bounds = bounds_Widget(w); 112 const iRect bounds = bounds_Widget(w);
113 const iBool isPressed = (flags_Widget(w) & pressed_WidgetFlag) != 0;
67 if (bounds.size.x > 0) { 114 if (bounds.size.x > 0) {
68 iPaint p; 115 iPaint p;
69 init_Paint(&p); 116 init_Paint(&p);
70 drawRect_Paint(&p, bounds, black_ColorId); 117 drawRect_Paint(&p, bounds, black_ColorId);
71 iRect tr = thumbRect_ScrollWidget_(d); 118 fillRect_Paint(&p, shrunk_Rect(thumbRect_ScrollWidget_(d), one_I2()),
72 fillRect_Paint(&p, thumbRect_ScrollWidget_(d), gray50_ColorId); 119 isPressed ? orange_ColorId : gray50_ColorId);
73 } 120 }
74} 121}
75 122