summaryrefslogtreecommitdiff
path: root/apps/gui/scrollbar.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/gui/scrollbar.c')
-rw-r--r--apps/gui/scrollbar.c134
1 files changed, 92 insertions, 42 deletions
diff --git a/apps/gui/scrollbar.c b/apps/gui/scrollbar.c
index 4cf92f4b47..f7dead566e 100644
--- a/apps/gui/scrollbar.c
+++ b/apps/gui/scrollbar.c
@@ -26,27 +26,14 @@
26void gui_scrollbar_draw(struct screen * screen, int x, int y, 26void gui_scrollbar_draw(struct screen * screen, int x, int y,
27 int width, int height, int items, 27 int width, int height, int items,
28 int min_shown, int max_shown, 28 int min_shown, int max_shown,
29 enum orientation orientation) 29 unsigned flags)
30{ 30{
31 int min; 31 int inner_x, inner_y, inner_wd, inner_ht, inner_len;
32 int max; 32 int min, max, range;
33 int inner_len; 33 int start, size;
34 int start; 34#ifdef HAVE_LCD_COLOR
35 int size; 35 int infill;
36 36#endif
37 /* draw box */
38 screen->drawrect(x, y, width, height);
39
40 screen->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
41
42 /* clear edge pixels */
43 screen->drawpixel(x, y);
44 screen->drawpixel((x + width - 1), y);
45 screen->drawpixel(x, (y + height - 1));
46 screen->drawpixel((x + width - 1), (y + height - 1));
47
48 /* clear pixels in progress bar */
49 screen->fillrect(x + 1, y + 1, width - 2, height - 2);
50 37
51 /* min should be min */ 38 /* min should be min */
52 if(min_shown < max_shown) { 39 if(min_shown < max_shown) {
@@ -69,10 +56,17 @@ void gui_scrollbar_draw(struct screen * screen, int x, int y,
69 if(max > items) 56 if(max > items)
70 max = items; 57 max = items;
71 58
72 if (orientation == VERTICAL) 59 range = max - min;
73 inner_len = height - 2; 60
61 inner_x = x + 1;
62 inner_y = y + 1;
63 inner_wd = width - 2;
64 inner_ht = height - 2;
65
66 if (flags & HORIZONTAL)
67 inner_len = inner_wd;
74 else 68 else
75 inner_len = width - 2; 69 inner_len = inner_ht;
76 70
77 /* avoid overflows */ 71 /* avoid overflows */
78 while (items > (INT_MAX / inner_len)) { 72 while (items > (INT_MAX / inner_len)) {
@@ -82,31 +76,87 @@ void gui_scrollbar_draw(struct screen * screen, int x, int y,
82 } 76 }
83 77
84 /* calc start and end of the knob */ 78 /* calc start and end of the knob */
85 if (items > 0 && items > (max - min)) { 79 if (items > 0 && items > range) {
86 size = inner_len * (max - min) / items; 80 size = inner_len * range / items;
87 if (size == 0) { /* width of knob is null */ 81 if (size == 0) { /* width of knob is null */
88 size = 1; 82 size = 1;
89 start = (inner_len - 1) * min / items; 83 start = (inner_len - 1) * min / items;
90 } else { 84 } else {
91 start = (inner_len - size) * min / (items - (max - min)); 85 start = (inner_len - size) * min / (items - range);
92 } 86 }
93 } else { /* if null draw full bar */ 87 } else { /* if null draw full bar */
94 size = inner_len; 88 size = inner_len;
95 start = 0; 89 start = 0;
96 } 90 }
97 91
92 /* draw box */
93#ifdef HAVE_LCD_COLOR
94 /* must avoid corners if case of (flags & FOREGROUND) */
95 screen->hline(inner_x, x + inner_wd, y);
96 screen->hline(inner_x, x + inner_wd, y + height - 1);
97 screen->vline(x, inner_y, y + inner_ht);
98 screen->vline(x + width - 1, inner_y, y + inner_ht);
99#else
100 screen->drawrect(x, y, width, height);
101#endif
102
103 screen->set_drawmode(DRMODE_SOLID | DRMODE_INVERSEVID);
104
105#ifdef HAVE_LCD_COLOR
106 infill = flags & (screen->depth > 1 ? INNER_FILL_MASK : INNER_FILL);
107
108 if (!(flags & FOREGROUND))
109 {
110#endif
111 /* clear corner pixels */
112 screen->drawpixel(x, y);
113 screen->drawpixel(x + width - 1, y);
114 screen->drawpixel(x, y + height - 1);
115 screen->drawpixel(x + width - 1, y + height - 1);
116
117#ifdef HAVE_LCD_COLOR
118 if (infill != INNER_BGFILL)
119 infill = INNER_FILL;
120 }
121
122 if (infill == INNER_FILL)
123#endif
124 {
125 /* clear pixels in progress bar */
126 screen->fillrect(inner_x, inner_y, inner_wd, inner_ht);
127 }
128
98 screen->set_drawmode(DRMODE_SOLID); 129 screen->set_drawmode(DRMODE_SOLID);
99 130
100 if(orientation == VERTICAL) 131#ifdef HAVE_LCD_COLOR
101 screen->fillrect(x + 1, y + start + 1, width - 2, size); 132 if (infill == INNER_BGFILL)
133 {
134 /* fill inner area with current background color */
135 unsigned fg = screen->get_foreground();
136 screen->set_foreground(screen->get_background());
137 screen->fillrect(inner_x, inner_y, inner_wd, inner_ht);
138 screen->set_foreground(fg);
139 }
140#endif
141
142 if (flags & HORIZONTAL)
143 {
144 inner_x += start;
145 inner_wd = size;
146 }
102 else 147 else
103 screen->fillrect(x + start + 1, y + 1, size, height - 2); 148 {
149 inner_y += start;
150 inner_ht = size;
151 }
152
153 screen->fillrect(inner_x, inner_y, inner_wd, inner_ht);
104} 154}
105 155
106void gui_bitmap_scrollbar_draw(struct screen * screen, struct bitmap bm, int x, int y, 156void gui_bitmap_scrollbar_draw(struct screen * screen, struct bitmap bm, int x, int y,
107 int width, int height, int items, 157 int width, int height, int items,
108 int min_shown, int max_shown, 158 int min_shown, int max_shown,
109 enum orientation orientation) 159 unsigned flags)
110{ 160{
111 int min; 161 int min;
112 int max; 162 int max;
@@ -140,7 +190,7 @@ void gui_bitmap_scrollbar_draw(struct screen * screen, struct bitmap bm, int x,
140 if(max > items) 190 if(max > items)
141 max = items; 191 max = items;
142 192
143 if (orientation == VERTICAL) 193 if (flags & VERTICAL)
144 inner_len = height; 194 inner_len = height;
145 else 195 else
146 inner_len = width; 196 inner_len = width;
@@ -168,27 +218,27 @@ void gui_bitmap_scrollbar_draw(struct screen * screen, struct bitmap bm, int x,
168 218
169 screen->set_drawmode(DRMODE_SOLID); 219 screen->set_drawmode(DRMODE_SOLID);
170 220
171 if(orientation == VERTICAL) { 221 if (flags & HORIZONTAL) {
172#if LCD_DEPTH > 1 222#if LCD_DEPTH > 1
173 if (bm.format == FORMAT_MONO) 223 if (bm.format == FORMAT_MONO)
174#endif 224#endif
175 screen->mono_bitmap_part(bm.data, 0, 0, 225 screen->mono_bitmap_part(bm.data, 0, 0,
176 bm.width, x, y + start, width, size); 226 bm.width, x + start, y, size, height);
177#if LCD_DEPTH > 1 227#if LCD_DEPTH > 1
178 else 228 else
179 screen->transparent_bitmap_part((fb_data *)bm.data, 0, 0, 229 screen->transparent_bitmap_part((fb_data *)bm.data, 0, 0,
180 bm.width, x, y + start, width, size); 230 bm.width, x + start, y, size, height);
181#endif 231#endif
182 } else { 232 } else {
183#if LCD_DEPTH > 1 233#if LCD_DEPTH > 1
184 if (bm.format == FORMAT_MONO) 234 if (bm.format == FORMAT_MONO)
185#endif 235#endif
186 screen->mono_bitmap_part(bm.data, 0, 0, 236 screen->mono_bitmap_part(bm.data, 0, 0,
187 bm.width, x + start, y, size, height); 237 bm.width, x, y + start, width, size);
188#if LCD_DEPTH > 1 238#if LCD_DEPTH > 1
189 else 239 else
190 screen->transparent_bitmap_part((fb_data *)bm.data, 0, 0, 240 screen->transparent_bitmap_part((fb_data *)bm.data, 0, 0,
191 bm.width, x + start, y, size, height); 241 bm.width, x, y + start, width, size);
192#endif 242#endif
193 } 243 }
194} 244}