1 #include "scrollable.h"
2
3 #include "draw.h"
4 #include "svg.h"
5
6 #include "../macros.h"
7 #include "../ui.h"
8
scroll_draw(SCROLLABLE * s,int x,int y,int width,int height)9 void scroll_draw(SCROLLABLE *s, int x, int y, int width, int height) {
10 uint32_t c = s->content_height;
11 uint32_t h = height, m, dy;
12 uint32_t scroll_width = 0;
13 if (s->small) {
14 scroll_width = SCROLL_WIDTH / 2;
15 } else {
16 scroll_width = SCROLL_WIDTH;
17 }
18
19 if (h >= c) {
20 // If h(eight) > c(ontent height), don't draw anything.
21 return;
22 } else {
23 m = (h * h) / c;
24 double d = (h - m);
25 dy = (s->d * d) + 0.5;
26 }
27
28 y += dy;
29 x += s->x;
30
31 if (!s->left) {
32 x += width - scroll_width;
33 }
34
35 drawalpha(s->small ? BM_SCROLLHALFTOP_SMALL : BM_SCROLLHALFTOP, x, y, scroll_width, scroll_width / 2, s->color);
36
37 y += scroll_width / 2;
38 int y2 = y + m - scroll_width;
39 if (scroll_width > m) {
40 y2 = y;
41 }
42 drawrect(x, y, x + scroll_width, y2, s->color);
43
44 drawalpha(s->small ? BM_SCROLLHALFBOT_SMALL : BM_SCROLLHALFBOT, x, y2, scroll_width, scroll_width / 2, s->color);
45 }
46
scroll_gety(SCROLLABLE * s,int height)47 int scroll_gety(SCROLLABLE *s, int height) {
48 int c = s->content_height;
49
50 if (c > height) {
51 return (s->d * (double)(c - height)) + 0.5;
52 }
53
54 return 0;
55 }
56
scroll_mmove(SCROLLABLE * s,int UNUSED (px),int UNUSED (py),int width,int height,int x,int y,int UNUSED (dx),int dy)57 bool scroll_mmove(SCROLLABLE *s, int UNUSED(px), int UNUSED(py), int width, int height, int x, int y, int UNUSED(dx),
58 int dy) {
59 bool draw = false;
60
61 bool hit = inrect(x, y, s->left ? 0 : (width - SCROLL_WIDTH), 0, SCROLL_WIDTH, height);
62 if (s->mouseover != hit) {
63 s->mouseover = hit;
64 draw = true;
65 }
66
67 s->mouseover2 = inrect(x, y, 0, 0, width, height);
68
69 if (s->mousedown) {
70 uint32_t c = s->content_height;
71 uint32_t h = height;
72
73 if (c > h) {
74 uint32_t m = (h * h) / c;
75 double d = (h - m);
76
77 s->d = ((s->d * d) + (double)dy) / d;
78
79 if (s->d < 0.0) {
80 s->d = 0.0;
81 } else if (s->d >= 1.0) {
82 s->d = 1.0;
83 }
84
85 draw = true;
86 }
87 }
88
89 return draw;
90 }
91
scroll_mdown(SCROLLABLE * s)92 bool scroll_mdown(SCROLLABLE *s) {
93 if (s->mouseover) {
94 s->mousedown = 1;
95 return true;
96 }
97
98 return false;
99 }
100
scroll_mright(SCROLLABLE * UNUSED (s))101 bool scroll_mright(SCROLLABLE *UNUSED(s)) { return false; }
102
scroll_mwheel(SCROLLABLE * s,int height,double delta,bool smooth)103 bool scroll_mwheel(SCROLLABLE *s, int height, double delta, bool smooth) {
104
105 /* Variable which controls scroll speed. How much one scroll step
106 * moves viewport */
107 double scroll_speed_multip = 5.0;
108
109 if (s->mouseover2) {
110 uint32_t content_height = s->content_height;
111 uint32_t port_height = height;
112
113 if (content_height > port_height) {
114 /* Scrolling is relative to amount of total content in component */
115 if (smooth) {
116 // this seems to be the magic equation that makes it scroll at the same speed
117 // regardless of how big the port is compared to the content.
118 s->d -= (delta * (32.0 * port_height / content_height) / content_height) * scroll_speed_multip;
119 } else {
120 uint32_t magic = (port_height * port_height) / content_height;
121 double fred = (port_height - magic);
122 s->d -= 16.0 * delta / fred;
123 }
124
125 if (s->d < 0.0) {
126 s->d = 0.0;
127 } else if (s->d >= 1.0) {
128 s->d = 1.0;
129 }
130
131 return true;
132 }
133 }
134
135 return false;
136 }
137
scroll_mup(SCROLLABLE * s)138 bool scroll_mup(SCROLLABLE *s) {
139 if (s->mousedown) {
140 s->mousedown = 0;
141 return true;
142 }
143
144 return false;
145 }
146
scroll_mleave(SCROLLABLE * s)147 bool scroll_mleave(SCROLLABLE *s) {
148 if (s->mouseover) {
149 s->mouseover = 0;
150 return true;
151 }
152
153 s->mouseover2 = 0;
154
155 return false;
156 }
157