First commit:
[kugel-rb.git] / apps / gui / scrollbar.c
blob5a12ea6a1cc0a99bce37c8cc5e5c765d14e6d45d
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 /* calculates the start and size of the knob */
27 static void scrollbar_helper(int min_shown, int max_shown, int items,
28 int inner_len, int *size, int *start)
30 int min, max, range;
32 /* min should be min */
33 if(min_shown < max_shown) {
34 min = min_shown;
35 max = max_shown;
37 else {
38 min = max_shown;
39 max = min_shown;
42 /* limit min and max */
43 if(min < 0)
44 min = 0;
45 if(min > items)
46 min = items;
48 if(max < 0)
49 max = 0;
50 if(max > items)
51 max = items;
53 range = max - min;
55 /* avoid overflows */
56 while (items > (INT_MAX / inner_len)) {
57 items >>= 1;
58 range >>= 1;
61 /* calc start and end of the knob */
62 if (items > 0 && items > range) {
63 *size = inner_len * range / items;
64 if (*size == 0) { /* width of knob is null */
65 *size = 1;
66 *start = (inner_len - 1) * min / items;
67 } else {
68 *start = (inner_len - *size) * min / (items - range);
70 } else { /* if null draw full bar */
71 *size = inner_len;
72 *start = 0;
75 return;
78 void gui_scrollbar_draw(struct screen * screen, int x, int y,
79 int width, int height, int items,
80 int min_shown, int max_shown,
81 unsigned flags)
83 int inner_x, inner_y, inner_wd, inner_ht, inner_len;
84 int start, size;
85 #ifdef HAVE_LCD_COLOR
86 int infill;
87 #endif
89 inner_x = x + 1;
90 inner_y = y + 1;
91 inner_wd = width - 2;
92 inner_ht = height - 2;
94 if (flags & HORIZONTAL)
95 inner_len = inner_wd;
96 else
97 inner_len = inner_ht;
99 scrollbar_helper(min_shown, max_shown, items, inner_len, &size, &start);
101 /* draw box */
102 #ifdef HAVE_LCD_COLOR
103 /* must avoid corners if case of (flags & FOREGROUND) */
104 screen->hline(inner_x, x + inner_wd, y);
105 screen->hline(inner_x, x + inner_wd, y + height - 1);
106 screen->vline(x, inner_y, y + inner_ht);
107 screen->vline(x + width - 1, inner_y, y + inner_ht);
108 #else
109 screen->drawrect(x, y, width, height);
110 #endif
112 screen->set_drawmode(DRMODE_SOLID | DRMODE_INVERSEVID);
114 #ifdef HAVE_LCD_COLOR
115 infill = flags & (screen->depth > 1 ? INNER_FILL_MASK : INNER_FILL);
117 if (!(flags & FOREGROUND))
119 #endif
120 /* clear corner pixels */
121 screen->drawpixel(x, y);
122 screen->drawpixel(x + width - 1, y);
123 screen->drawpixel(x, y + height - 1);
124 screen->drawpixel(x + width - 1, y + height - 1);
126 #ifdef HAVE_LCD_COLOR
127 if (infill != INNER_BGFILL)
128 infill = INNER_FILL;
131 if (infill == INNER_FILL)
132 #endif
134 /* clear pixels in progress bar */
135 screen->fillrect(inner_x, inner_y, inner_wd, inner_ht);
138 screen->set_drawmode(DRMODE_SOLID);
140 #ifdef HAVE_LCD_COLOR
141 if (infill == INNER_BGFILL)
143 /* fill inner area with current background color */
144 unsigned fg = screen->get_foreground();
145 screen->set_foreground(screen->get_background());
146 screen->fillrect(inner_x, inner_y, inner_wd, inner_ht);
147 screen->set_foreground(fg);
149 #endif
151 if (flags & HORIZONTAL)
153 inner_x += start;
154 inner_wd = size;
156 else
158 inner_y += start;
159 inner_ht = size;
162 screen->fillrect(inner_x, inner_y, inner_wd, inner_ht);
165 void gui_bitmap_scrollbar_draw(struct screen * screen, struct bitmap bm, int x, int y,
166 int width, int height, int items,
167 int min_shown, int max_shown,
168 unsigned flags)
170 int start;
171 int size;
172 int inner_len;
174 screen->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
176 /* clear pixels in progress bar */
177 screen->fillrect(x, y, width, height);
179 if (flags & HORIZONTAL)
180 inner_len = width;
181 else
182 inner_len = height;
184 scrollbar_helper(min_shown, max_shown, items, inner_len, &size, &start);
186 screen->set_drawmode(DRMODE_SOLID);
188 if (flags & HORIZONTAL) {
189 #if LCD_DEPTH > 1
190 if (bm.format == FORMAT_MONO)
191 #endif
192 screen->mono_bitmap_part(bm.data, 0, 0,
193 bm.width, x + start, y, size, height);
194 #if LCD_DEPTH > 1
195 else
196 screen->transparent_bitmap_part((fb_data *)bm.data, 0, 0,
197 bm.width, x + start, y, size, height);
198 #endif
199 } else {
200 #if LCD_DEPTH > 1
201 if (bm.format == FORMAT_MONO)
202 #endif
203 screen->mono_bitmap_part(bm.data, 0, 0,
204 bm.width, x, y + start, width, size);
205 #if LCD_DEPTH > 1
206 else
207 screen->transparent_bitmap_part((fb_data *)bm.data, 0, 0,
208 bm.width, x, y + start, width, size);
209 #endif
213 void show_busy_slider(struct screen *s, int x, int y, int width, int height)
215 static int start = 0, dir = 1;
216 gui_scrollbar_draw(s, x, y, width, height, 100,
217 start, start+20, HORIZONTAL);
218 #if NB_SCREENS > 1
219 if (s->screen_type == SCREEN_MAIN)
221 #endif
222 start += (dir*2);
223 if (start > 79)
224 dir = -1;
225 else if (start < 1)
226 dir = 1;
227 #if NB_SCREENS > 1
229 #endif
232 #endif /* HAVE_LCD_BITMAP */