Introduce Rockbox Utility to the manual as automated installation option. Only rather...
[Rockbox.git] / apps / gui / scrollbar.c
blobe2e70fd9fb6ec1438cb2b21ca59640b53990cb58
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) Markus Braun (2002)
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include "scrollbar.h"
21 #ifdef HAVE_LCD_BITMAP
22 #include "config.h"
23 #include "limits.h"
24 #include "bmp.h"
26 void gui_scrollbar_draw(struct screen * screen, int x, int y,
27 int width, int height, int items,
28 int min_shown, int max_shown,
29 unsigned flags)
31 int inner_x, inner_y, inner_wd, inner_ht, inner_len;
32 int min, max, range;
33 int start, size;
34 #ifdef HAVE_LCD_COLOR
35 int infill;
36 #endif
38 /* min should be min */
39 if(min_shown < max_shown) {
40 min = min_shown;
41 max = max_shown;
43 else {
44 min = max_shown;
45 max = min_shown;
48 /* limit min and max */
49 if(min < 0)
50 min = 0;
51 if(min > items)
52 min = items;
54 if(max < 0)
55 max = 0;
56 if(max > items)
57 max = items;
59 range = max - min;
61 inner_x = x + 1;
62 inner_y = y + 1;
63 inner_wd = width - 2;
64 inner_ht = height - 2;
66 if (flags & HORIZONTAL)
67 inner_len = inner_wd;
68 else
69 inner_len = inner_ht;
71 /* avoid overflows */
72 while (items > (INT_MAX / inner_len)) {
73 items >>= 1;
74 range >>= 1;
77 /* calc start and end of the knob */
78 if (items > 0 && items > range) {
79 size = inner_len * range / items;
80 if (size == 0) { /* width of knob is null */
81 size = 1;
82 start = (inner_len - 1) * min / items;
83 } else {
84 start = (inner_len - size) * min / (items - range);
86 } else { /* if null draw full bar */
87 size = inner_len;
88 start = 0;
91 /* draw box */
92 #ifdef HAVE_LCD_COLOR
93 /* must avoid corners if case of (flags & FOREGROUND) */
94 screen->hline(inner_x, x + inner_wd, y);
95 screen->hline(inner_x, x + inner_wd, y + height - 1);
96 screen->vline(x, inner_y, y + inner_ht);
97 screen->vline(x + width - 1, inner_y, y + inner_ht);
98 #else
99 screen->drawrect(x, y, width, height);
100 #endif
102 screen->set_drawmode(DRMODE_SOLID | DRMODE_INVERSEVID);
104 #ifdef HAVE_LCD_COLOR
105 infill = flags & (screen->depth > 1 ? INNER_FILL_MASK : INNER_FILL);
107 if (!(flags & FOREGROUND))
109 #endif
110 /* clear corner pixels */
111 screen->drawpixel(x, y);
112 screen->drawpixel(x + width - 1, y);
113 screen->drawpixel(x, y + height - 1);
114 screen->drawpixel(x + width - 1, y + height - 1);
116 #ifdef HAVE_LCD_COLOR
117 if (infill != INNER_BGFILL)
118 infill = INNER_FILL;
121 if (infill == INNER_FILL)
122 #endif
124 /* clear pixels in progress bar */
125 screen->fillrect(inner_x, inner_y, inner_wd, inner_ht);
128 screen->set_drawmode(DRMODE_SOLID);
130 #ifdef HAVE_LCD_COLOR
131 if (infill == INNER_BGFILL)
133 /* fill inner area with current background color */
134 unsigned fg = screen->get_foreground();
135 screen->set_foreground(screen->get_background());
136 screen->fillrect(inner_x, inner_y, inner_wd, inner_ht);
137 screen->set_foreground(fg);
139 #endif
141 if (flags & HORIZONTAL)
143 inner_x += start;
144 inner_wd = size;
146 else
148 inner_y += start;
149 inner_ht = size;
152 screen->fillrect(inner_x, inner_y, inner_wd, inner_ht);
155 void gui_bitmap_scrollbar_draw(struct screen * screen, struct bitmap bm, int x, int y,
156 int width, int height, int items,
157 int min_shown, int max_shown,
158 unsigned flags)
160 int min;
161 int max;
162 int inner_len;
163 int start;
164 int size;
166 screen->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
168 /* clear pixels in progress bar */
169 screen->fillrect(x, y, width, height);
171 /* min should be min */
172 if(min_shown < max_shown) {
173 min = min_shown;
174 max = max_shown;
176 else {
177 min = max_shown;
178 max = min_shown;
181 /* limit min and max */
182 if(min < 0)
183 min = 0;
184 if(min > items)
185 min = items;
187 if(max < 0)
188 max = 0;
189 if(max > items)
190 max = items;
192 if (flags & HORIZONTAL)
193 inner_len = width;
194 else
195 inner_len = height;
197 /* avoid overflows */
198 while (items > (INT_MAX / inner_len)) {
199 items >>= 1;
200 min >>= 1;
201 max >>= 1;
204 /* calc start and end of the knob */
205 if (items > 0 && items > (max - min)) {
206 size = inner_len * (max - min) / items;
207 if (size == 0) { /* width of knob is null */
208 size = 1;
209 start = (inner_len - 1) * min / items;
210 } else {
211 start = (inner_len - size) * min / (items - (max - min));
213 } else { /* if null draw full bar */
214 size = inner_len;
215 start = 0;
218 screen->set_drawmode(DRMODE_SOLID);
220 if (flags & HORIZONTAL) {
221 #if LCD_DEPTH > 1
222 if (bm.format == FORMAT_MONO)
223 #endif
224 screen->mono_bitmap_part(bm.data, 0, 0,
225 bm.width, x + start, y, size, height);
226 #if LCD_DEPTH > 1
227 else
228 screen->transparent_bitmap_part((fb_data *)bm.data, 0, 0,
229 bm.width, x + start, y, size, height);
230 #endif
231 } else {
232 #if LCD_DEPTH > 1
233 if (bm.format == FORMAT_MONO)
234 #endif
235 screen->mono_bitmap_part(bm.data, 0, 0,
236 bm.width, x, y + start, width, size);
237 #if LCD_DEPTH > 1
238 else
239 screen->transparent_bitmap_part((fb_data *)bm.data, 0, 0,
240 bm.width, x, y + start, width, size);
241 #endif
245 void show_busy_slider(struct screen *s, int x, int y, int width, int height)
247 static int start = 0, dir = 1;
248 gui_scrollbar_draw(s, x, y, width, height, 100,
249 start, start+20, HORIZONTAL);
250 #if NB_SCREENS > 1
251 if (s->screen_type == SCREEN_MAIN)
253 #endif
254 start += (dir*2);
255 if (start > 79)
256 dir = -1;
257 else if (start < 1)
258 dir = 1;
259 #if NB_SCREENS > 1
261 #endif
264 #endif /* HAVE_LCD_BITMAP */