diff options
Diffstat (limited to 'apps/gui')
-rw-r--r-- | apps/gui/buttonbar.c | 126 | ||||
-rw-r--r-- | apps/gui/buttonbar.h | 81 | ||||
-rw-r--r-- | apps/gui/icon.c | 49 | ||||
-rw-r--r-- | apps/gui/icon.h | 51 | ||||
-rw-r--r-- | apps/gui/list.c | 499 | ||||
-rw-r--r-- | apps/gui/list.h | 232 | ||||
-rw-r--r-- | apps/gui/scrollbar.c | 106 | ||||
-rw-r--r-- | apps/gui/scrollbar.h | 49 | ||||
-rw-r--r-- | apps/gui/splash.c | 216 | ||||
-rw-r--r-- | apps/gui/splash.h | 39 | ||||
-rw-r--r-- | apps/gui/statusbar.c | 508 | ||||
-rw-r--r-- | apps/gui/statusbar.h | 107 |
12 files changed, 2063 insertions, 0 deletions
diff --git a/apps/gui/buttonbar.c b/apps/gui/buttonbar.c new file mode 100644 index 0000000000..be87b1b81f --- /dev/null +++ b/apps/gui/buttonbar.c | |||
@@ -0,0 +1,126 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) Linus Nielsen Feltzing (2002), Kévin FERRARE (2005) | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "config.h" | ||
21 | #include "buttonbar.h" | ||
22 | |||
23 | #ifdef HAS_BUTTONBAR | ||
24 | |||
25 | #include "lcd.h" | ||
26 | #include "font.h" | ||
27 | #include "string.h" | ||
28 | #include "settings.h" | ||
29 | |||
30 | void gui_buttonbar_init(struct gui_buttonbar * buttonbar) | ||
31 | { | ||
32 | gui_buttonbar_unset(buttonbar); | ||
33 | } | ||
34 | |||
35 | void gui_buttonbar_set_display(struct gui_buttonbar * buttonbar, | ||
36 | struct screen * display) | ||
37 | { | ||
38 | buttonbar->display = display; | ||
39 | } | ||
40 | |||
41 | void gui_buttonbar_draw_button(struct gui_buttonbar * buttonbar, int num) | ||
42 | { | ||
43 | int xpos, ypos, button_width, text_width; | ||
44 | int fw, fh; | ||
45 | struct screen * display = buttonbar->display; | ||
46 | |||
47 | display->setfont(FONT_SYSFIXED); | ||
48 | display->getstringsize("M", &fw, &fh); | ||
49 | |||
50 | button_width = display->width/BUTTONBAR_MAX_BUTTONS; | ||
51 | xpos = num * button_width; | ||
52 | ypos = display->height - fh; | ||
53 | |||
54 | if(buttonbar->caption[num][0] != 0) | ||
55 | { | ||
56 | /* center the text */ | ||
57 | text_width = fw * strlen(buttonbar->caption[num]); | ||
58 | display->putsxy(xpos + (button_width - text_width)/2, | ||
59 | ypos, buttonbar->caption[num]); | ||
60 | } | ||
61 | |||
62 | display->set_drawmode(DRMODE_COMPLEMENT); | ||
63 | display->fillrect(xpos, ypos, button_width - 1, fh); | ||
64 | display->set_drawmode(DRMODE_SOLID); | ||
65 | display->setfont(FONT_UI); | ||
66 | } | ||
67 | |||
68 | void gui_buttonbar_set(struct gui_buttonbar * buttonbar, | ||
69 | const char *caption1, | ||
70 | const char *caption2, | ||
71 | const char *caption3) | ||
72 | { | ||
73 | gui_buttonbar_unset(buttonbar); | ||
74 | if(caption1) | ||
75 | { | ||
76 | strncpy(buttonbar->caption[0], caption1, 7); | ||
77 | buttonbar->caption[0][7] = 0; | ||
78 | } | ||
79 | if(caption2) | ||
80 | { | ||
81 | strncpy(buttonbar->caption[1], caption2, 7); | ||
82 | buttonbar->caption[1][7] = 0; | ||
83 | } | ||
84 | if(caption3) | ||
85 | { | ||
86 | strncpy(buttonbar->caption[2], caption3, 7); | ||
87 | buttonbar->caption[2][7] = 0; | ||
88 | } | ||
89 | } | ||
90 | |||
91 | void gui_buttonbar_unset(struct gui_buttonbar * buttonbar) | ||
92 | { | ||
93 | int i; | ||
94 | for(i = 0;i < BUTTONBAR_MAX_BUTTONS;++i) | ||
95 | buttonbar->caption[i][0] = 0; | ||
96 | } | ||
97 | |||
98 | void gui_buttonbar_draw(struct gui_buttonbar * buttonbar) | ||
99 | { | ||
100 | struct screen * display = buttonbar->display; | ||
101 | int i; | ||
102 | |||
103 | display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); | ||
104 | display->fillrect(0, display->height - BUTTONBAR_HEIGHT, | ||
105 | display->width, BUTTONBAR_HEIGHT); | ||
106 | display->set_drawmode(DRMODE_SOLID); | ||
107 | |||
108 | for(i = 0;i < BUTTONBAR_MAX_BUTTONS;++i) | ||
109 | gui_buttonbar_draw_button(buttonbar, i); | ||
110 | display->update_rect(0, display->height - BUTTONBAR_HEIGHT, | ||
111 | display->width, BUTTONBAR_HEIGHT); | ||
112 | } | ||
113 | |||
114 | bool gui_buttonbar_isset(struct gui_buttonbar * buttonbar) | ||
115 | { | ||
116 | /* If all buttons are unset, the button bar is considered disabled */ | ||
117 | if(!global_settings.buttonbar) | ||
118 | return(false); | ||
119 | int i; | ||
120 | for(i = 0;i < BUTTONBAR_MAX_BUTTONS;++i) | ||
121 | if(buttonbar->caption[i] != 0) | ||
122 | return true; | ||
123 | return false; | ||
124 | } | ||
125 | |||
126 | #endif /* HAS_BUTTONBAR */ | ||
diff --git a/apps/gui/buttonbar.h b/apps/gui/buttonbar.h new file mode 100644 index 0000000000..ee7b8d02c4 --- /dev/null +++ b/apps/gui/buttonbar.h | |||
@@ -0,0 +1,81 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 by Kévin FERRARE | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #ifndef _GUI_BUTTONBAR_H_ | ||
21 | #define _GUI_BUTTONBAR_H_ | ||
22 | #include "config.h" | ||
23 | #include "button.h" | ||
24 | #if CONFIG_KEYPAD == RECORDER_PAD | ||
25 | |||
26 | #define HAS_BUTTONBAR | ||
27 | #define BUTTONBAR_HEIGHT 8 | ||
28 | #define BUTTONBAR_MAX_BUTTONS 3 | ||
29 | #define BUTTONBAR_CAPTION_LENGTH 8 | ||
30 | #include "screen_access.h" | ||
31 | |||
32 | struct gui_buttonbar | ||
33 | { | ||
34 | char caption[BUTTONBAR_MAX_BUTTONS][BUTTONBAR_CAPTION_LENGTH]; | ||
35 | struct screen * display; | ||
36 | }; | ||
37 | |||
38 | /* | ||
39 | * Initializes the buttonbar | ||
40 | * - buttonbar : the buttonbar | ||
41 | */ | ||
42 | extern void gui_buttonbar_init(struct gui_buttonbar * buttonbar); | ||
43 | |||
44 | /* | ||
45 | * Attach the buttonbar to a screen | ||
46 | * - buttonbar : the buttonbar | ||
47 | * - display : the display to attach the buttonbar | ||
48 | */ | ||
49 | extern void gui_buttonbar_set_display(struct gui_buttonbar * buttonbar, | ||
50 | struct screen * display); | ||
51 | |||
52 | /* | ||
53 | * Set the caption of the items of the buttonbar | ||
54 | * - buttonbar : the buttonbar | ||
55 | * - caption1,2,3 : the first, second and thirds items of the bar | ||
56 | */ | ||
57 | extern void gui_buttonbar_set(struct gui_buttonbar * buttonbar, | ||
58 | const char *caption1, | ||
59 | const char *caption2, | ||
60 | const char *caption3); | ||
61 | |||
62 | /* | ||
63 | * Disable the buttonbar | ||
64 | * - buttonbar : the buttonbar | ||
65 | */ | ||
66 | extern void gui_buttonbar_unset(struct gui_buttonbar * buttonbar); | ||
67 | |||
68 | /* | ||
69 | * Draw the buttonbar on it's attached screen | ||
70 | * - buttonbar : the buttonbar | ||
71 | */ | ||
72 | extern void gui_buttonbar_draw(struct gui_buttonbar * buttonbar); | ||
73 | |||
74 | /* | ||
75 | * Returns true if the buttonbar has something to display, false otherwise | ||
76 | * - buttonbar : the buttonbar | ||
77 | */ | ||
78 | extern bool gui_buttonbar_isset(struct gui_buttonbar * buttonbar); | ||
79 | |||
80 | #endif /* CONFIG_KEYPAD == RECORDER_PAD */ | ||
81 | #endif /* _GUI_BUTTONBAR_H_ */ | ||
diff --git a/apps/gui/icon.c b/apps/gui/icon.c new file mode 100644 index 0000000000..4d174d3427 --- /dev/null +++ b/apps/gui/icon.c | |||
@@ -0,0 +1,49 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) Robert E. Hak(2002), Kévin FERRARE (2005) | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "config.h" | ||
21 | #include "icon.h" | ||
22 | #include "screen_access.h" | ||
23 | #include "icons.h" | ||
24 | |||
25 | /* Count in letter positions, NOT pixels */ | ||
26 | void screen_put_iconxy(struct screen * display, int x, int y, ICON icon) | ||
27 | { | ||
28 | #ifdef HAVE_LCD_BITMAP | ||
29 | if(icon==0)/* Don't display invalid icons */ | ||
30 | return; | ||
31 | int xpos, ypos; | ||
32 | xpos = x*CURSOR_WIDTH; | ||
33 | ypos = y*display->char_height + display->getymargin(); | ||
34 | if ( display->char_height > CURSOR_HEIGHT )/* center the cursor */ | ||
35 | ypos += (display->char_height - CURSOR_HEIGHT) / 2; | ||
36 | display->mono_bitmap(icon, xpos, ypos, CURSOR_WIDTH, CURSOR_HEIGHT); | ||
37 | #else | ||
38 | display->putc(x, y, icon); | ||
39 | #endif | ||
40 | } | ||
41 | |||
42 | void screen_put_cursorxy(struct screen * display, int x, int y) | ||
43 | { | ||
44 | #ifdef HAVE_LCD_BITMAP | ||
45 | screen_put_iconxy(display, x, y, bitmap_icons_6x8[Icon_Cursor]); | ||
46 | #else | ||
47 | screen_put_iconxy(display, x, y, CURSOR_CHAR); | ||
48 | #endif | ||
49 | } | ||
diff --git a/apps/gui/icon.h b/apps/gui/icon.h new file mode 100644 index 0000000000..46faf0972f --- /dev/null +++ b/apps/gui/icon.h | |||
@@ -0,0 +1,51 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 by Kévin FERRARE | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #ifndef _GUI_ICON_H_ | ||
21 | #define _GUI_ICON_H_ | ||
22 | #include "lcd.h" | ||
23 | #include "screen_access.h" | ||
24 | /* Defines a type for the icons since it's not the same thing on | ||
25 | * char-based displays and bitmap displays */ | ||
26 | #ifdef HAVE_LCD_BITMAP | ||
27 | #define ICON const unsigned char * | ||
28 | #else | ||
29 | #define ICON unsigned short | ||
30 | #endif | ||
31 | |||
32 | #define CURSOR_CHAR 0x92 | ||
33 | #define CURSOR_WIDTH 6 | ||
34 | #define CURSOR_HEIGHT 8 | ||
35 | /* | ||
36 | * Draws a cursor at a given position | ||
37 | * - screen : the screen where we put the cursor | ||
38 | * - x, y : the position, in character, not in pixel !! | ||
39 | */ | ||
40 | extern void screen_put_cursorxy(struct screen * screen, int x, int y); | ||
41 | |||
42 | /* | ||
43 | * Put an icon on a screen at a given position | ||
44 | * (the position is given in characters) | ||
45 | * - screen : the screen where we put our icon | ||
46 | * - x, y : the position, in character, not in pixel !! | ||
47 | * - icon : the icon to put | ||
48 | */ | ||
49 | extern void screen_put_iconxy(struct screen * screen, int x, int y, ICON icon); | ||
50 | |||
51 | #endif /*_GUI_ICON_H_*/ | ||
diff --git a/apps/gui/list.c b/apps/gui/list.c new file mode 100644 index 0000000000..bb3eb7caaa --- /dev/null +++ b/apps/gui/list.c | |||
@@ -0,0 +1,499 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 by Kévin FERRARE | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "config.h" | ||
21 | #include "lcd.h" | ||
22 | #include "font.h" | ||
23 | #include "button.h" | ||
24 | #include "sprintf.h" | ||
25 | #include "settings.h" | ||
26 | #include "kernel.h" | ||
27 | |||
28 | #include "screen_access.h" | ||
29 | #include "list.h" | ||
30 | #include "scrollbar.h" | ||
31 | #include "statusbar.h" | ||
32 | |||
33 | #ifdef HAVE_LCD_CHARCELLS | ||
34 | #define SCROLL_LIMIT 1 | ||
35 | #else | ||
36 | #define SCROLL_LIMIT 2 | ||
37 | #endif | ||
38 | |||
39 | |||
40 | |||
41 | void gui_list_init(struct gui_list * gui_list, | ||
42 | void (*callback_get_item_icon)(int selected_item, ICON * icon), | ||
43 | char * (*callback_get_item_name)(int selected_item, char *buffer)) | ||
44 | { | ||
45 | gui_list->callback_get_item_icon = callback_get_item_icon; | ||
46 | gui_list->callback_get_item_name = callback_get_item_name; | ||
47 | gui_list->display = NULL; | ||
48 | gui_list_set_nb_items(gui_list, 0); | ||
49 | gui_list->selected_item = 0; | ||
50 | gui_list->start_item = 0; | ||
51 | } | ||
52 | |||
53 | void gui_list_set_nb_items(struct gui_list * gui_list, int nb_items) | ||
54 | { | ||
55 | gui_list->nb_items = nb_items; | ||
56 | } | ||
57 | |||
58 | void gui_list_set_display(struct gui_list * gui_list, struct screen * display) | ||
59 | { | ||
60 | if(gui_list->display != 0) /* we switched from a previous display */ | ||
61 | gui_list->display->stop_scroll(); | ||
62 | gui_list->display = display; | ||
63 | #ifdef HAVE_LCD_CHARCELLS | ||
64 | display->double_height(false); | ||
65 | #endif | ||
66 | gui_list_put_selection_in_screen(gui_list, false); | ||
67 | } | ||
68 | |||
69 | void gui_list_put_selection_in_screen(struct gui_list * gui_list, | ||
70 | bool put_from_end) | ||
71 | { | ||
72 | struct screen * display = gui_list->display; | ||
73 | if(put_from_end) | ||
74 | { | ||
75 | int list_end = gui_list->selected_item + SCROLL_LIMIT - 1; | ||
76 | if(list_end > gui_list->nb_items) | ||
77 | list_end = gui_list->nb_items; | ||
78 | gui_list->start_item = list_end - display->nb_lines; | ||
79 | } | ||
80 | else | ||
81 | { | ||
82 | int list_start = gui_list->selected_item - SCROLL_LIMIT + 1; | ||
83 | if(list_start + display->nb_lines > gui_list->nb_items) | ||
84 | list_start = gui_list->nb_items - display->nb_lines; | ||
85 | gui_list->start_item = list_start; | ||
86 | } | ||
87 | if(gui_list->start_item < 0) | ||
88 | gui_list->start_item = 0; | ||
89 | } | ||
90 | |||
91 | void gui_list_get_selected_item_name(struct gui_list * gui_list, char *buffer) | ||
92 | { | ||
93 | gui_list->callback_get_item_name(gui_list->selected_item, buffer); | ||
94 | } | ||
95 | |||
96 | int gui_list_get_selected_item_position(struct gui_list * gui_list) | ||
97 | { | ||
98 | return gui_list->selected_item; | ||
99 | } | ||
100 | |||
101 | void gui_list_draw(struct gui_list * gui_list) | ||
102 | { | ||
103 | struct screen * display=gui_list->display; | ||
104 | int cursor_pos = 0; | ||
105 | int icon_pos = 1; | ||
106 | int text_pos; | ||
107 | bool draw_icons = (gui_list->callback_get_item_icon != NULL && | ||
108 | global_settings.show_icons) ; | ||
109 | bool draw_cursor; | ||
110 | int i; | ||
111 | |||
112 | /* Adjust the position of icon, cursor, text */ | ||
113 | #ifdef HAVE_LCD_BITMAP | ||
114 | bool draw_scrollbar = (global_settings.scrollbar && | ||
115 | display->nb_lines < gui_list->nb_items); | ||
116 | |||
117 | int list_y_start = screen_get_text_y_start(gui_list->display); | ||
118 | int list_y_end = screen_get_text_y_end(gui_list->display); | ||
119 | |||
120 | draw_cursor = !global_settings.invert_cursor; | ||
121 | text_pos = 0; /* here it's in pixels */ | ||
122 | if(draw_scrollbar) | ||
123 | { | ||
124 | ++cursor_pos; | ||
125 | ++icon_pos; | ||
126 | text_pos += SCROLLBAR_WIDTH; | ||
127 | } | ||
128 | if(!draw_cursor) | ||
129 | { | ||
130 | --icon_pos; | ||
131 | } | ||
132 | else | ||
133 | text_pos += CURSOR_WIDTH; | ||
134 | |||
135 | if(draw_icons) | ||
136 | text_pos += 8; | ||
137 | #else | ||
138 | draw_cursor = true; | ||
139 | if(draw_icons) | ||
140 | text_pos = 2; /* here it's in chars */ | ||
141 | else | ||
142 | text_pos = 1; | ||
143 | #endif | ||
144 | /* The drawing part */ | ||
145 | #ifdef HAVE_LCD_BITMAP | ||
146 | /* clear the drawing area */ | ||
147 | display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); | ||
148 | display->fillrect(0, list_y_start, | ||
149 | display->width, list_y_end - list_y_start); | ||
150 | display->set_drawmode(DRMODE_SOLID); | ||
151 | |||
152 | /* FIXME: should not be handled here, but rather in the | ||
153 | * code that changes fonts */ | ||
154 | screen_update_nblines(display); | ||
155 | |||
156 | display->stop_scroll(); | ||
157 | display->setmargins(text_pos, list_y_start); | ||
158 | #else | ||
159 | display->clear_display(); | ||
160 | #endif | ||
161 | |||
162 | for(i = 0;i < display->nb_lines;++i) | ||
163 | { | ||
164 | char entry_buffer[MAX_PATH]; | ||
165 | char * entry_name; | ||
166 | int current_item = gui_list->start_item + i; | ||
167 | |||
168 | /* When there are less items to display than the | ||
169 | * current available space on the screen, we stop*/ | ||
170 | if(current_item >= gui_list->nb_items) | ||
171 | break; | ||
172 | entry_name = gui_list->callback_get_item_name(current_item, | ||
173 | entry_buffer); | ||
174 | if(current_item == gui_list->selected_item) | ||
175 | { | ||
176 | /* The selected item must be displayed scrolling */ | ||
177 | #ifdef HAVE_LCD_BITMAP | ||
178 | if (global_settings.invert_cursor)/* Display inverted-line-style*/ | ||
179 | display->puts_scroll_style(0, i, entry_name, STYLE_INVERT); | ||
180 | else | ||
181 | display->puts_scroll(0, i, entry_name); | ||
182 | #else | ||
183 | display->puts_scroll(text_pos, i, entry_name); | ||
184 | #endif | ||
185 | |||
186 | if(draw_cursor) | ||
187 | screen_put_cursorxy(display, cursor_pos, i); | ||
188 | } | ||
189 | else | ||
190 | {/* normal item */ | ||
191 | #ifdef HAVE_LCD_BITMAP | ||
192 | display->puts(0, i, entry_name); | ||
193 | #else | ||
194 | display->puts(text_pos, i, entry_name); | ||
195 | #endif | ||
196 | } | ||
197 | /* Icons display */ | ||
198 | if(draw_icons) | ||
199 | { | ||
200 | ICON icon; | ||
201 | gui_list->callback_get_item_icon(current_item, &icon); | ||
202 | screen_put_iconxy(display, icon_pos, i, icon); | ||
203 | } | ||
204 | } | ||
205 | #ifdef HAVE_LCD_BITMAP | ||
206 | /* Draw the scrollbar if needed*/ | ||
207 | if(draw_scrollbar) | ||
208 | { | ||
209 | int scrollbar_y_end = display->char_height * | ||
210 | display->nb_lines + list_y_start; | ||
211 | gui_scrollbar_draw(display, 0, list_y_start, SCROLLBAR_WIDTH-1, | ||
212 | scrollbar_y_end - list_y_start, gui_list->nb_items, | ||
213 | gui_list->start_item, | ||
214 | gui_list->start_item + display->nb_lines, VERTICAL); | ||
215 | } | ||
216 | display->update_rect(0, list_y_start, display->width, | ||
217 | list_y_end - list_y_start); | ||
218 | #else | ||
219 | #ifdef SIMULATOR | ||
220 | display->update(); | ||
221 | #endif | ||
222 | #endif | ||
223 | } | ||
224 | |||
225 | void gui_list_select_item(struct gui_list * gui_list, int item_number) | ||
226 | { | ||
227 | if( item_number > gui_list->nb_items-1 || item_number < 0 ) | ||
228 | return; | ||
229 | gui_list->selected_item = item_number; | ||
230 | gui_list_put_selection_in_screen(gui_list, false); | ||
231 | } | ||
232 | |||
233 | void gui_list_select_next(struct gui_list * gui_list) | ||
234 | { | ||
235 | int item_pos; | ||
236 | int end_item; | ||
237 | int nb_lines = gui_list->display->nb_lines; | ||
238 | |||
239 | ++gui_list->selected_item; | ||
240 | |||
241 | if( gui_list->selected_item >= gui_list->nb_items ) | ||
242 | { | ||
243 | /* we have already reached the bottom of the list */ | ||
244 | gui_list->selected_item = 0; | ||
245 | gui_list->start_item = 0; | ||
246 | } | ||
247 | else | ||
248 | { | ||
249 | item_pos = gui_list->selected_item - gui_list->start_item; | ||
250 | end_item = gui_list->start_item + nb_lines; | ||
251 | /* we start scrolling vertically when reaching the line | ||
252 | * (nb_lines-SCROLL_LIMIT) | ||
253 | * and when we are not in the last part of the list*/ | ||
254 | if( item_pos > nb_lines-SCROLL_LIMIT && end_item < gui_list->nb_items ) | ||
255 | ++gui_list->start_item; | ||
256 | } | ||
257 | } | ||
258 | |||
259 | void gui_list_select_previous(struct gui_list * gui_list) | ||
260 | { | ||
261 | int item_pos; | ||
262 | int nb_lines = gui_list->display->nb_lines; | ||
263 | |||
264 | --gui_list->selected_item; | ||
265 | if( gui_list->selected_item < 0 ) | ||
266 | { | ||
267 | /* we have aleady reached the top of the list */ | ||
268 | int start; | ||
269 | gui_list->selected_item = gui_list->nb_items-1; | ||
270 | start = gui_list->nb_items-nb_lines; | ||
271 | if( start < 0 ) | ||
272 | gui_list->start_item = 0; | ||
273 | else | ||
274 | gui_list->start_item = start; | ||
275 | } | ||
276 | else | ||
277 | { | ||
278 | item_pos = gui_list->selected_item - gui_list->start_item; | ||
279 | if( item_pos < SCROLL_LIMIT-1 && gui_list->start_item > 0 ) | ||
280 | --gui_list->start_item; | ||
281 | } | ||
282 | } | ||
283 | |||
284 | void gui_list_select_next_page(struct gui_list * gui_list, int nb_lines) | ||
285 | { | ||
286 | if(gui_list->selected_item == gui_list->nb_items-1) | ||
287 | gui_list->selected_item = 0; | ||
288 | else | ||
289 | { | ||
290 | gui_list->selected_item += nb_lines; | ||
291 | if(gui_list->selected_item > gui_list->nb_items-1) | ||
292 | gui_list->selected_item = gui_list->nb_items-1; | ||
293 | } | ||
294 | gui_list_put_selection_in_screen(gui_list, true); | ||
295 | } | ||
296 | |||
297 | void gui_list_select_previous_page(struct gui_list * gui_list, int nb_lines) | ||
298 | { | ||
299 | if(gui_list->selected_item == 0) | ||
300 | gui_list->selected_item = gui_list->nb_items - 1; | ||
301 | else | ||
302 | { | ||
303 | gui_list->selected_item -= nb_lines; | ||
304 | if(gui_list->selected_item < 0) | ||
305 | gui_list->selected_item = 0; | ||
306 | } | ||
307 | gui_list_put_selection_in_screen(gui_list, false); | ||
308 | } | ||
309 | |||
310 | void gui_list_add_item(struct gui_list * gui_list) | ||
311 | { | ||
312 | ++gui_list->nb_items; | ||
313 | /* if only one item in the list, select it */ | ||
314 | if(gui_list->nb_items == 1) | ||
315 | gui_list->selected_item = 0; | ||
316 | } | ||
317 | |||
318 | void gui_list_del_item(struct gui_list * gui_list) | ||
319 | { | ||
320 | int nb_lines = gui_list->display->nb_lines; | ||
321 | |||
322 | if(gui_list->nb_items > 0) | ||
323 | { | ||
324 | int dist_selected_from_end = gui_list->nb_items | ||
325 | - gui_list->selected_item - 1; | ||
326 | int dist_start_from_end = gui_list->nb_items | ||
327 | - gui_list->start_item - 1; | ||
328 | if(dist_selected_from_end == 0) | ||
329 | { | ||
330 | /* Oops we are removing the selected item, | ||
331 | select the previous one */ | ||
332 | --gui_list->selected_item; | ||
333 | } | ||
334 | --gui_list->nb_items; | ||
335 | |||
336 | /* scroll the list if needed */ | ||
337 | if( (dist_start_from_end < nb_lines) && (gui_list->start_item != 0) ) | ||
338 | --gui_list->start_item; | ||
339 | } | ||
340 | } | ||
341 | |||
342 | /* | ||
343 | * Synchronized lists stuffs | ||
344 | */ | ||
345 | void gui_synclist_init( | ||
346 | struct gui_synclist * lists, | ||
347 | void (*callback_get_item_icon)(int selected_item, ICON * icon), | ||
348 | char * (*callback_get_item_name)(int selected_item, char *buffer) | ||
349 | ) | ||
350 | { | ||
351 | int i; | ||
352 | for(i = 0;i < NB_SCREENS;i++) | ||
353 | { | ||
354 | gui_list_init(&(lists->gui_list[i]), callback_get_item_icon, | ||
355 | callback_get_item_name); | ||
356 | gui_list_set_display(&(lists->gui_list[i]), &(screens[i])); | ||
357 | } | ||
358 | } | ||
359 | |||
360 | void gui_synclist_set_nb_items(struct gui_synclist * lists, int nb_items) | ||
361 | { | ||
362 | int i; | ||
363 | for(i = 0;i < NB_SCREENS;i++) | ||
364 | { | ||
365 | gui_list_set_nb_items(&(lists->gui_list[i]), nb_items); | ||
366 | } | ||
367 | } | ||
368 | |||
369 | void gui_synclist_get_selected_item_name(struct gui_synclist * lists, | ||
370 | char *buffer) | ||
371 | { | ||
372 | gui_list_get_selected_item_name(&(lists->gui_list[0]), buffer); | ||
373 | } | ||
374 | |||
375 | int gui_synclist_get_selected_item_position(struct gui_synclist * lists) | ||
376 | { | ||
377 | return gui_list_get_selected_item_position(&(lists->gui_list[0])); | ||
378 | } | ||
379 | |||
380 | void gui_synclist_draw(struct gui_synclist * lists) | ||
381 | { | ||
382 | int i; | ||
383 | for(i = 0;i < NB_SCREENS;i++) | ||
384 | gui_list_draw(&(lists->gui_list[i])); | ||
385 | } | ||
386 | |||
387 | void gui_synclist_select_item(struct gui_synclist * lists, int item_number) | ||
388 | { | ||
389 | int i; | ||
390 | for(i = 0;i < NB_SCREENS;i++) | ||
391 | gui_list_select_item(&(lists->gui_list[i]), item_number); | ||
392 | } | ||
393 | |||
394 | void gui_synclist_select_next(struct gui_synclist * lists) | ||
395 | { | ||
396 | int i; | ||
397 | for(i = 0;i < NB_SCREENS;i++) | ||
398 | gui_list_select_next(&(lists->gui_list[i])); | ||
399 | } | ||
400 | |||
401 | void gui_synclist_select_previous(struct gui_synclist * lists) | ||
402 | { | ||
403 | int i; | ||
404 | for(i = 0;i < NB_SCREENS;i++) | ||
405 | gui_list_select_previous(&(lists->gui_list[i])); | ||
406 | } | ||
407 | |||
408 | void gui_synclist_select_next_page(struct gui_synclist * lists, | ||
409 | enum screen_type screen) | ||
410 | { | ||
411 | int i; | ||
412 | for(i = 0;i < NB_SCREENS;i++) | ||
413 | gui_list_select_next_page(&(lists->gui_list[i]), | ||
414 | screens[screen].nb_lines); | ||
415 | } | ||
416 | |||
417 | void gui_synclist_select_previous_page(struct gui_synclist * lists, | ||
418 | enum screen_type screen) | ||
419 | { | ||
420 | int i; | ||
421 | for(i = 0;i < NB_SCREENS;i++) | ||
422 | gui_list_select_previous_page(&(lists->gui_list[i]), | ||
423 | screens[screen].nb_lines); | ||
424 | } | ||
425 | |||
426 | void gui_synclist_add_item(struct gui_synclist * lists) | ||
427 | { | ||
428 | int i; | ||
429 | for(i = 0;i < NB_SCREENS;i++) | ||
430 | gui_list_add_item(&(lists->gui_list[i])); | ||
431 | } | ||
432 | |||
433 | void gui_synclist_del_item(struct gui_synclist * lists) | ||
434 | { | ||
435 | int i; | ||
436 | for(i = 0;i < NB_SCREENS;i++) | ||
437 | gui_list_del_item(&(lists->gui_list[i])); | ||
438 | } | ||
439 | |||
440 | bool gui_synclist_do_button(struct gui_synclist * lists, unsigned button) | ||
441 | { | ||
442 | switch(button) | ||
443 | { | ||
444 | case LIST_PREV: | ||
445 | case LIST_PREV | BUTTON_REPEAT: | ||
446 | #ifdef LIST_RC_PREV | ||
447 | case LIST_RC_PREV: | ||
448 | case LIST_RC_PREV | BUTTON_REPEAT: | ||
449 | #endif | ||
450 | gui_synclist_select_previous(lists); | ||
451 | gui_synclist_draw(lists); | ||
452 | return true; | ||
453 | |||
454 | case LIST_NEXT: | ||
455 | case LIST_NEXT | BUTTON_REPEAT: | ||
456 | #ifdef LIST_RC_NEXT | ||
457 | case LIST_RC_NEXT: | ||
458 | case LIST_RC_NEXT | BUTTON_REPEAT: | ||
459 | #endif | ||
460 | gui_synclist_select_next(lists); | ||
461 | gui_synclist_draw(lists); | ||
462 | return true; | ||
463 | /* for pgup / pgdown, we are obliged to have a different behaviour depending on the screen | ||
464 | * for which the user pressed the key since for example, remote and main screen doesn't | ||
465 | * have the same number of lines*/ | ||
466 | #ifdef LIST_PGUP | ||
467 | case LIST_PGUP: | ||
468 | case LIST_PGUP | BUTTON_REPEAT: | ||
469 | gui_synclist_select_previous_page(lists, SCREEN_MAIN); | ||
470 | gui_synclist_draw(lists); | ||
471 | return true; | ||
472 | #endif | ||
473 | |||
474 | #ifdef LIST_RC_PGUP | ||
475 | case LIST_RC_PGUP: | ||
476 | case LIST_RC_PGUP | BUTTON_REPEAT: | ||
477 | gui_synclist_select_previous_page(lists, SCREEN_REMOTE); | ||
478 | gui_synclist_draw(lists); | ||
479 | return true; | ||
480 | #endif | ||
481 | |||
482 | #ifdef LIST_PGDN | ||
483 | case LIST_PGDN: | ||
484 | case LIST_PGDN | BUTTON_REPEAT: | ||
485 | gui_synclist_select_next_page(lists, SCREEN_MAIN); | ||
486 | gui_synclist_draw(lists); | ||
487 | return true; | ||
488 | #endif | ||
489 | |||
490 | #ifdef LIST_RC_PGDN | ||
491 | case LIST_RC_PGDN: | ||
492 | case LIST_RC_PGDN | BUTTON_REPEAT: | ||
493 | gui_synclist_select_next_page(lists, SCREEN_REMOTE); | ||
494 | gui_synclist_draw(lists); | ||
495 | return true; | ||
496 | #endif | ||
497 | } | ||
498 | return false; | ||
499 | } | ||
diff --git a/apps/gui/list.h b/apps/gui/list.h new file mode 100644 index 0000000000..fd553f381c --- /dev/null +++ b/apps/gui/list.h | |||
@@ -0,0 +1,232 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 by Kévin FERRARE | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #ifndef _GUI_LIST_H_ | ||
21 | #define _GUI_LIST_H_ | ||
22 | |||
23 | #include "config.h" | ||
24 | #include "icon.h" | ||
25 | #include "screen_access.h" | ||
26 | |||
27 | #define SCROLLBAR_WIDTH 6 | ||
28 | |||
29 | /* Key assignement */ | ||
30 | #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ | ||
31 | (CONFIG_KEYPAD == IRIVER_H300_PAD) | ||
32 | #define LIST_NEXT BUTTON_DOWN | ||
33 | #define LIST_PREV BUTTON_UP | ||
34 | #define LIST_PGUP (BUTTON_ON | BUTTON_UP) | ||
35 | #define LIST_PGDN (BUTTON_ON | BUTTON_DOWN) | ||
36 | #define LIST_RC_NEXT BUTTON_RC_FF | ||
37 | #define LIST_RC_PREV BUTTON_RC_REW | ||
38 | #define LIST_RC_PGUP BUTTON_RC_SOURCE | ||
39 | #define LIST_RC_PGDN BUTTON_RC_BITRATE | ||
40 | |||
41 | #elif CONFIG_KEYPAD == RECORDER_PAD | ||
42 | #define LIST_NEXT BUTTON_DOWN | ||
43 | #define LIST_PREV BUTTON_UP | ||
44 | #define LIST_PGUP (BUTTON_ON | BUTTON_UP) | ||
45 | #define LIST_PGDN (BUTTON_ON | BUTTON_DOWN) | ||
46 | #define LIST_RC_NEXT BUTTON_RC_RIGHT | ||
47 | #define LIST_RC_PREV BUTTON_RC_LEFT | ||
48 | |||
49 | #elif CONFIG_KEYPAD == PLAYER_PAD | ||
50 | #define LIST_NEXT BUTTON_RIGHT | ||
51 | #define LIST_PREV BUTTON_LEFT | ||
52 | #define LIST_RC_NEXT BUTTON_RC_RIGHT | ||
53 | #define LIST_RC_PREV BUTTON_RC_LEFT | ||
54 | |||
55 | #elif CONFIG_KEYPAD == ONDIO_PAD | ||
56 | #define LIST_NEXT BUTTON_DOWN | ||
57 | #define LIST_PREV BUTTON_UP | ||
58 | |||
59 | #elif CONFIG_KEYPAD == GMINI100_PAD | ||
60 | #define LIST_NEXT BUTTON_DOWN | ||
61 | #define LIST_PREV BUTTON_UP | ||
62 | #define LIST_PGUP (BUTTON_ON | BUTTON_UP) | ||
63 | #define LIST_PGDN (BUTTON_ON | BUTTON_DOWN) | ||
64 | #endif | ||
65 | |||
66 | |||
67 | struct gui_list | ||
68 | { | ||
69 | int nb_items; | ||
70 | int selected_item; | ||
71 | int start_item; /* the item that is displayed at the top of the screen */ | ||
72 | |||
73 | void (*callback_get_item_icon)(int selected_item, ICON * icon); | ||
74 | char * (*callback_get_item_name)(int selected_item, char *buffer); | ||
75 | |||
76 | struct screen * display; | ||
77 | int line_scroll_limit; | ||
78 | }; | ||
79 | |||
80 | /* | ||
81 | * Initializes a scrolling list | ||
82 | * - gui_list : the list structure to initialize | ||
83 | * - callback_get_item_icon : pointer to a function that associates an icon | ||
84 | * to a given item number | ||
85 | * - callback_get_item_name : pointer to a function that associates a label | ||
86 | * to a given item number | ||
87 | */ | ||
88 | extern void gui_list_init(struct gui_list * gui_list, | ||
89 | void (*callback_get_item_icon)(int selected_item, ICON * icon), | ||
90 | char * (*callback_get_item_name)(int selected_item, char *buffer) | ||
91 | ); | ||
92 | |||
93 | /* | ||
94 | * Sets the numburs of items the list can currently display | ||
95 | * note that the list's context like the currently pointed item is resetted | ||
96 | * - gui_list : the list structure to initialize | ||
97 | * - nb_items : the numbers of items you want | ||
98 | */ | ||
99 | extern void gui_list_set_nb_items(struct gui_list * gui_list, int nb_items); | ||
100 | |||
101 | /* | ||
102 | * Puts the selection in the screen | ||
103 | * - gui_list : the list structure | ||
104 | * - put_from_end : if true, selection will be put as close from | ||
105 | * the end of the list as possible, else, it's | ||
106 | * from the beginning | ||
107 | */ | ||
108 | extern void gui_list_put_selection_in_screen(struct gui_list * gui_list, | ||
109 | bool put_from_end); | ||
110 | |||
111 | /* | ||
112 | * Attach the scrolling list to a screen | ||
113 | * (The previous screen attachement is lost) | ||
114 | * - gui_list : the list structure | ||
115 | * - display : the screen to attach | ||
116 | */ | ||
117 | extern void gui_list_set_display(struct gui_list * gui_list, | ||
118 | struct screen * display); | ||
119 | |||
120 | /* | ||
121 | * Gives the name of the selected object | ||
122 | * - gui_list : the list structure | ||
123 | * - buffer : a buffer which is filled with the name | ||
124 | */ | ||
125 | extern void gui_list_get_selected_item_name(struct gui_list * gui_list, | ||
126 | char *buffer); | ||
127 | |||
128 | /* | ||
129 | * Gives the position of the selected item | ||
130 | * - gui_list : the list structure | ||
131 | * Returns the position | ||
132 | */ | ||
133 | extern int gui_list_get_selected_item_position(struct gui_list * gui_list); | ||
134 | |||
135 | /* | ||
136 | * Selects an item in the list | ||
137 | * - gui_list : the list structure | ||
138 | * - item_number : the number of the item which will be selected | ||
139 | */ | ||
140 | extern void gui_list_select_item(struct gui_list * gui_list, int item_number); | ||
141 | |||
142 | /* | ||
143 | * Draws the list on the attached screen | ||
144 | * - gui_list : the list structure | ||
145 | */ | ||
146 | extern void gui_list_draw(struct gui_list * gui_list); | ||
147 | |||
148 | /* | ||
149 | * Selects the next item in the list | ||
150 | * (Item 0 gets selected if the end of the list is reached) | ||
151 | * - gui_list : the list structure | ||
152 | */ | ||
153 | extern void gui_list_select_next(struct gui_list * gui_list); | ||
154 | |||
155 | /* | ||
156 | * Selects the previous item in the list | ||
157 | * (Last item in the list gets selected if the list beginning is reached) | ||
158 | * - gui_list : the list structure | ||
159 | */ | ||
160 | extern void gui_list_select_previous(struct gui_list * gui_list); | ||
161 | |||
162 | /* | ||
163 | * Go to next page if any, else selects the last item in the list | ||
164 | * - gui_list : the list structure | ||
165 | * - nb_lines : the number of lines to try to move the cursor | ||
166 | */ | ||
167 | extern void gui_list_select_next_page(struct gui_list * gui_list, | ||
168 | int nb_lines); | ||
169 | |||
170 | /* | ||
171 | * Go to previous page if any, else selects the first item in the list | ||
172 | * - gui_list : the list structure | ||
173 | * - nb_lines : the number of lines to try to move the cursor | ||
174 | */ | ||
175 | extern void gui_list_select_previous_page(struct gui_list * gui_list, | ||
176 | int nb_lines); | ||
177 | |||
178 | /* | ||
179 | * Adds an item to the list (the callback will be asked for one more item) | ||
180 | * - gui_list : the list structure | ||
181 | */ | ||
182 | extern void gui_list_add_item(struct gui_list * gui_list); | ||
183 | |||
184 | /* | ||
185 | * Removes an item to the list (the callback will be asked for one less item) | ||
186 | * - gui_list : the list structure | ||
187 | */ | ||
188 | extern void gui_list_del_item(struct gui_list * gui_list); | ||
189 | |||
190 | |||
191 | /* | ||
192 | * This part handles as many lists as there are connected screens | ||
193 | * (the api is similar to the ones above) | ||
194 | * The lists on the screens are synchronized ; | ||
195 | * theirs items and selected items are the same, but of course, | ||
196 | * they can be displayed on screens with different sizes | ||
197 | * The final aim is to let the programmer handle many lists in one | ||
198 | * function call and make its code independant from the number of screens | ||
199 | */ | ||
200 | struct gui_synclist | ||
201 | { | ||
202 | struct gui_list gui_list[NB_SCREENS]; | ||
203 | }; | ||
204 | |||
205 | extern void gui_synclist_init(struct gui_synclist * lists, | ||
206 | void (*callback_get_item_icon)(int selected_item, ICON * icon), | ||
207 | char * (*callback_get_item_name)(int selected_item, char *buffer) | ||
208 | ); | ||
209 | extern void gui_synclist_set_nb_items(struct gui_synclist * lists, int nb_items); | ||
210 | extern void gui_synclist_get_selected_item_name(struct gui_synclist * lists, | ||
211 | char *buffer); | ||
212 | extern int gui_synclist_get_selected_item_position(struct gui_synclist * lists); | ||
213 | extern void gui_synclist_draw(struct gui_synclist * lists); | ||
214 | extern void gui_synclist_select_item(struct gui_synclist * lists, | ||
215 | int item_number); | ||
216 | extern void gui_synclist_select_next(struct gui_synclist * lists); | ||
217 | extern void gui_synclist_select_previous(struct gui_synclist * lists); | ||
218 | extern void gui_synclist_select_next_page(struct gui_synclist * lists, | ||
219 | enum screen_type screen); | ||
220 | extern void gui_synclist_select_previous_page(struct gui_synclist * lists, | ||
221 | enum screen_type screen); | ||
222 | extern void gui_synclist_add_item(struct gui_synclist * lists); | ||
223 | extern void gui_synclist_del_item(struct gui_synclist * lists); | ||
224 | /* | ||
225 | * Do the action implied by the given button, | ||
226 | * returns true if something has been done, false otherwise | ||
227 | * - lists : the synchronized lists | ||
228 | * - button : the keycode of a pressed button | ||
229 | */ | ||
230 | extern bool gui_synclist_do_button(struct gui_synclist * lists, unsigned button); | ||
231 | |||
232 | #endif /* _GUI_LIST_H_ */ | ||
diff --git a/apps/gui/scrollbar.c b/apps/gui/scrollbar.c new file mode 100644 index 0000000000..9d5717f1a7 --- /dev/null +++ b/apps/gui/scrollbar.c | |||
@@ -0,0 +1,106 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) Markus Braun (2002), Kévin FERRARE (2005) | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "config.h" | ||
21 | #include "lcd.h" | ||
22 | #ifdef HAVE_LCD_BITMAP | ||
23 | #include "limits.h" | ||
24 | #include "scrollbar.h" | ||
25 | #include "screen_access.h" | ||
26 | |||
27 | void gui_scrollbar_draw(struct screen * screen, int x, int y, | ||
28 | int width, int height, int items, | ||
29 | int min_shown, int max_shown, | ||
30 | enum orientation orientation) | ||
31 | { | ||
32 | int min; | ||
33 | int max; | ||
34 | int inner_len; | ||
35 | int start; | ||
36 | int size; | ||
37 | |||
38 | /* draw box */ | ||
39 | screen->drawrect(x, y, width, height); | ||
40 | |||
41 | screen->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); | ||
42 | |||
43 | /* clear edge pixels */ | ||
44 | screen->drawpixel(x, y); | ||
45 | screen->drawpixel((x + width - 1), y); | ||
46 | screen->drawpixel(x, (y + height - 1)); | ||
47 | screen->drawpixel((x + width - 1), (y + height - 1)); | ||
48 | |||
49 | /* clear pixels in progress bar */ | ||
50 | screen->fillrect(x + 1, y + 1, width - 2, height - 2); | ||
51 | |||
52 | /* min should be min */ | ||
53 | if(min_shown < max_shown) { | ||
54 | min = min_shown; | ||
55 | max = max_shown; | ||
56 | } | ||
57 | else { | ||
58 | min = max_shown; | ||
59 | max = min_shown; | ||
60 | } | ||
61 | |||
62 | /* limit min and max */ | ||
63 | if(min < 0) | ||
64 | min = 0; | ||
65 | if(min > items) | ||
66 | min = items; | ||
67 | |||
68 | if(max < 0) | ||
69 | max = 0; | ||
70 | if(max > items) | ||
71 | max = items; | ||
72 | |||
73 | if (orientation == VERTICAL) | ||
74 | inner_len = height - 2; | ||
75 | else | ||
76 | inner_len = width - 2; | ||
77 | |||
78 | /* avoid overflows */ | ||
79 | while (items > (INT_MAX / inner_len)) { | ||
80 | items >>= 1; | ||
81 | min >>= 1; | ||
82 | max >>= 1; | ||
83 | } | ||
84 | |||
85 | /* calc start and end of the knob */ | ||
86 | if (items > 0 && items > (max - min)) { | ||
87 | size = inner_len * (max - min) / items; | ||
88 | if (size == 0) { /* width of knob is null */ | ||
89 | size = 1; | ||
90 | start = (inner_len - 1) * min / items; | ||
91 | } else { | ||
92 | start = (inner_len - size) * min / (items - (max - min)); | ||
93 | } | ||
94 | } else { /* if null draw full bar */ | ||
95 | size = inner_len; | ||
96 | start = 0; | ||
97 | } | ||
98 | |||
99 | screen->set_drawmode(DRMODE_SOLID); | ||
100 | |||
101 | if(orientation == VERTICAL) | ||
102 | screen->fillrect(x + 1, y + start + 1, width - 2, size); | ||
103 | else | ||
104 | screen->fillrect(x + start + 1, y + 1, size, height - 2); | ||
105 | } | ||
106 | #endif /* HAVE_LCD_BITMAP */ | ||
diff --git a/apps/gui/scrollbar.h b/apps/gui/scrollbar.h new file mode 100644 index 0000000000..51c08352ba --- /dev/null +++ b/apps/gui/scrollbar.h | |||
@@ -0,0 +1,49 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 Kévin FERRARE | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #ifndef _GUI_SCROLLBAR_H_ | ||
21 | #define _GUI_SCROLLBAR_H_ | ||
22 | #include <lcd.h> | ||
23 | #ifdef HAVE_LCD_BITMAP | ||
24 | |||
25 | struct screen; | ||
26 | |||
27 | enum orientation { | ||
28 | VERTICAL, | ||
29 | HORIZONTAL | ||
30 | }; | ||
31 | |||
32 | /* | ||
33 | * Draws a scrollbar on the given screen | ||
34 | * - screen : the screen to put the scrollbar on | ||
35 | * - x : x start position of the scrollbar | ||
36 | * - y : y start position of the scrollbar | ||
37 | * - width : you won't guess =(^o^)= | ||
38 | * - height : I won't tell you either ! | ||
39 | * - items : total number of items on the screen | ||
40 | * - min_shown : index of the starting item on the screen | ||
41 | * - max_shown : index of the last item on the screen | ||
42 | * - orientation : either VERTICAL or HORIZONTAL | ||
43 | */ | ||
44 | extern void gui_scrollbar_draw(struct screen * screen, int x, int y, | ||
45 | int width, int height, int items, | ||
46 | int min_shown, int max_shown, | ||
47 | enum orientation orientation); | ||
48 | #endif /* HAVE_LCD_BITMAP */ | ||
49 | #endif /* _GUI_SCROLLBAR_H_ */ | ||
diff --git a/apps/gui/splash.c b/apps/gui/splash.c new file mode 100644 index 0000000000..a3cbb198df --- /dev/null +++ b/apps/gui/splash.c | |||
@@ -0,0 +1,216 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) Daniel Stenberg (2002), Kévin FERRARE (2005) | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "stdarg.h" | ||
20 | #include "string.h" | ||
21 | #include "stdio.h" | ||
22 | #include "kernel.h" | ||
23 | #include "screen_access.h" | ||
24 | |||
25 | |||
26 | #ifdef HAVE_LCD_BITMAP | ||
27 | |||
28 | #define SPACE 3 /* pixels between words */ | ||
29 | #define MAXLETTERS 128 /* 16*8 */ | ||
30 | #define MAXLINES 10 | ||
31 | |||
32 | #else | ||
33 | |||
34 | #define SPACE 1 /* one letter space */ | ||
35 | #define MAXLETTERS 22 /* 11 * 2 */ | ||
36 | #define MAXLINES 2 | ||
37 | |||
38 | #endif | ||
39 | |||
40 | |||
41 | void internal_splash(struct screen * screen, | ||
42 | bool center, const char *fmt, va_list ap) | ||
43 | { | ||
44 | char *next; | ||
45 | char *store=NULL; | ||
46 | int x=0; | ||
47 | int y=0; | ||
48 | int w, h; | ||
49 | unsigned char splash_buf[MAXLETTERS]; | ||
50 | unsigned char widths[MAXLINES]; | ||
51 | int line=0; | ||
52 | bool first=true; | ||
53 | #ifdef HAVE_LCD_BITMAP | ||
54 | int maxw=0; | ||
55 | #endif | ||
56 | |||
57 | #ifdef HAVE_LCD_CHARCELLS | ||
58 | screen->double_height (false); | ||
59 | #endif | ||
60 | vsnprintf( splash_buf, sizeof(splash_buf), fmt, ap ); | ||
61 | |||
62 | if(center) { | ||
63 | /* first a pass to measure sizes */ | ||
64 | next = strtok_r(splash_buf, " ", &store); | ||
65 | while (next) { | ||
66 | #ifdef HAVE_LCD_BITMAP | ||
67 | screen->getstringsize(next, &w, &h); | ||
68 | #else | ||
69 | w = strlen(next); | ||
70 | h = 1; /* store height in characters */ | ||
71 | #endif | ||
72 | if(!first) { | ||
73 | if(x+w> screen->width) { | ||
74 | /* Too wide, wrap */ | ||
75 | y+=h; | ||
76 | line++; | ||
77 | if((y > (screen->height-h)) || (line > screen->nb_lines)) | ||
78 | /* STOP */ | ||
79 | break; | ||
80 | x=0; | ||
81 | first=true; | ||
82 | } | ||
83 | } | ||
84 | else | ||
85 | first = false; | ||
86 | |||
87 | /* think of it as if the text was written here at position x,y | ||
88 | being w pixels/chars wide and h high */ | ||
89 | |||
90 | x += w+SPACE; | ||
91 | widths[line]=x-SPACE; /* don't count the trailing space */ | ||
92 | #ifdef HAVE_LCD_BITMAP | ||
93 | /* store the widest line */ | ||
94 | if(widths[line]>maxw) | ||
95 | maxw = widths[line]; | ||
96 | #endif | ||
97 | next = strtok_r(NULL, " ", &store); | ||
98 | } | ||
99 | |||
100 | #ifdef HAVE_LCD_BITMAP | ||
101 | /* Start displaying the message at position y. The reason for the | ||
102 | added h here is that it isn't added until the end of lines in the | ||
103 | loop above and we always break the loop in the middle of a line. */ | ||
104 | y = (screen->height - (y+h) )/2; | ||
105 | #else | ||
106 | y = 0; /* vertical center on 2 lines would be silly */ | ||
107 | #endif | ||
108 | first=true; | ||
109 | |||
110 | /* Now recreate the string again since the strtok_r() above has ruined | ||
111 | the one we already have! Here's room for improvements! */ | ||
112 | vsnprintf( splash_buf, sizeof(splash_buf), fmt, ap ); | ||
113 | } | ||
114 | va_end( ap ); | ||
115 | |||
116 | if(center) | ||
117 | { | ||
118 | x = (screen->width-widths[0])/2; | ||
119 | if(x < 0) | ||
120 | x = 0; | ||
121 | } | ||
122 | |||
123 | #ifdef HAVE_LCD_BITMAP | ||
124 | /* If we center the display, then just clear the box we need and put | ||
125 | a nice little frame and put the text in there! */ | ||
126 | if(center && (y > 2)) { | ||
127 | int xx = (screen->width-maxw)/2 - 2; | ||
128 | /* The new graphics routines handle clipping, so no need to check */ | ||
129 | #if LCD_DEPTH > 1 | ||
130 | #ifdef HAVE_LCD_COLOR | ||
131 | screen->set_background((struct rgb){LCD_MAX_RED-1, LCD_MAX_GREEN-1, | ||
132 | LCD_MAX_BLUE-1}); | ||
133 | #else | ||
134 | if(screen->depth>1) | ||
135 | screen->set_background(LCD_MAX_LEVEL-1); | ||
136 | #endif | ||
137 | #endif | ||
138 | screen->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); | ||
139 | screen->fillrect(xx, y-2, maxw+4, screen->height-y*2+4); | ||
140 | screen->set_drawmode(DRMODE_SOLID); | ||
141 | screen->drawrect(xx, y-2, maxw+4, screen->height-y*2+4); | ||
142 | } | ||
143 | else | ||
144 | #endif | ||
145 | screen->clear_display(); | ||
146 | line=0; | ||
147 | next = strtok_r(splash_buf, " ", &store); | ||
148 | while (next) { | ||
149 | #ifdef HAVE_LCD_BITMAP | ||
150 | screen->getstringsize(next, &w, &h); | ||
151 | #else | ||
152 | w = strlen(next); | ||
153 | h = 1; | ||
154 | #endif | ||
155 | if(!first) { | ||
156 | if(x+w> screen->width) { | ||
157 | /* too wide */ | ||
158 | y+=h; | ||
159 | line++; /* goto next line */ | ||
160 | first=true; | ||
161 | if(y > (screen->height-h)) | ||
162 | /* STOP */ | ||
163 | break; | ||
164 | if(center) { | ||
165 | x = (screen->width-widths[line])/2; | ||
166 | if(x < 0) | ||
167 | x = 0; | ||
168 | } | ||
169 | else | ||
170 | x=0; | ||
171 | } | ||
172 | } | ||
173 | else | ||
174 | first=false; | ||
175 | #ifdef HAVE_LCD_BITMAP | ||
176 | screen->putsxy(x, y, next); | ||
177 | #else | ||
178 | screen->puts(x, y, next); | ||
179 | #endif | ||
180 | x += w+SPACE; /* pixels space! */ | ||
181 | next = strtok_r(NULL, " ", &store); | ||
182 | } | ||
183 | |||
184 | #if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH > 1) | ||
185 | if(screen->depth > 1) | ||
186 | screen->set_background(LCD_WHITE); | ||
187 | #endif | ||
188 | #if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR) | ||
189 | screen->update(); | ||
190 | #endif | ||
191 | } | ||
192 | |||
193 | void gui_splash(struct screen * screen, int ticks, | ||
194 | bool center, const char *fmt, ...) | ||
195 | { | ||
196 | va_list ap; | ||
197 | va_start( ap, fmt ); | ||
198 | internal_splash(screen, center, fmt, ap); | ||
199 | va_end( ap ); | ||
200 | |||
201 | if(ticks) | ||
202 | sleep(ticks); | ||
203 | } | ||
204 | |||
205 | void gui_syncsplash(int ticks, bool center, const char *fmt, ...) | ||
206 | { | ||
207 | va_list ap; | ||
208 | int i; | ||
209 | va_start( ap, fmt ); | ||
210 | for(i=0;i<NB_SCREENS;++i) | ||
211 | internal_splash(&(screens[i]), center, fmt, ap); | ||
212 | va_end( ap ); | ||
213 | |||
214 | if(ticks) | ||
215 | sleep(ticks); | ||
216 | } | ||
diff --git a/apps/gui/splash.h b/apps/gui/splash.h new file mode 100644 index 0000000000..b0d55db890 --- /dev/null +++ b/apps/gui/splash.h | |||
@@ -0,0 +1,39 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 by Kévin FERRARE | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | /* | ||
21 | * Puts a splash message on the given screen for a given period | ||
22 | * - screen : the screen to put the splash on | ||
23 | * - ticks : how long the splash is displayed (in rb ticks) | ||
24 | * - center : FALSE means left-justified, TRUE means | ||
25 | * horizontal and vertical center | ||
26 | * - fmt : what to say *printf style | ||
27 | */ | ||
28 | extern void gui_splash(struct screen * screen, int ticks, | ||
29 | bool center, const char *fmt, ...); | ||
30 | |||
31 | /* | ||
32 | * Puts a splash message on all the screens for a given period | ||
33 | * - ticks : how long the splash is displayed (in rb ticks) | ||
34 | * - center : FALSE means left-justified, TRUE means | ||
35 | * horizontal and vertical center | ||
36 | * - fmt : what to say *printf style | ||
37 | */ | ||
38 | extern void gui_syncsplash(int ticks, bool center, | ||
39 | const char *fmt, ...); | ||
diff --git a/apps/gui/statusbar.c b/apps/gui/statusbar.c new file mode 100644 index 0000000000..5ddc194610 --- /dev/null +++ b/apps/gui/statusbar.c | |||
@@ -0,0 +1,508 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) Robert E. Hak (2002), Linus Nielsen Feltzing (2002), Kévin FERRARE (2005) | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "config.h" | ||
21 | #include "screen_access.h" | ||
22 | #include "lcd.h" | ||
23 | #include "font.h" | ||
24 | #include "kernel.h" | ||
25 | #include "string.h" /* for memcmp oO*/ | ||
26 | #include "sprintf.h" | ||
27 | #include "sound.h" | ||
28 | #include "power.h" | ||
29 | #include "settings.h" | ||
30 | #include "icons.h" | ||
31 | #include "powermgmt.h" | ||
32 | #include "button.h" | ||
33 | |||
34 | #include "status.h" /* needed for battery_state global var */ | ||
35 | #include "wps.h" /* for keys_locked */ | ||
36 | #include "statusbar.h" | ||
37 | |||
38 | |||
39 | /* FIXME: should be removed from icon.h to avoid redefinition, | ||
40 | but still needed for compatibility with old system */ | ||
41 | #define STATUSBAR_X_POS 0 | ||
42 | #define STATUSBAR_Y_POS 0 /* MUST be a multiple of 8 */ | ||
43 | #define STATUSBAR_HEIGHT 8 | ||
44 | #define STATUSBAR_BATTERY_X_POS 0 | ||
45 | #define STATUSBAR_BATTERY_WIDTH 18 | ||
46 | #define STATUSBAR_PLUG_X_POS STATUSBAR_X_POS + \ | ||
47 | STATUSBAR_BATTERY_WIDTH +2 | ||
48 | #define STATUSBAR_PLUG_WIDTH 7 | ||
49 | #define STATUSBAR_VOLUME_X_POS STATUSBAR_X_POS + \ | ||
50 | STATUSBAR_BATTERY_WIDTH + \ | ||
51 | STATUSBAR_PLUG_WIDTH +2+2 | ||
52 | #define STATUSBAR_VOLUME_WIDTH 16 | ||
53 | #define STATUSBAR_PLAY_STATE_X_POS STATUSBAR_X_POS + \ | ||
54 | STATUSBAR_BATTERY_WIDTH + \ | ||
55 | STATUSBAR_PLUG_WIDTH + \ | ||
56 | STATUSBAR_VOLUME_WIDTH+2+2+2 | ||
57 | #define STATUSBAR_PLAY_STATE_WIDTH 7 | ||
58 | #define STATUSBAR_PLAY_MODE_X_POS STATUSBAR_X_POS + \ | ||
59 | STATUSBAR_BATTERY_WIDTH + \ | ||
60 | STATUSBAR_PLUG_WIDTH + \ | ||
61 | STATUSBAR_VOLUME_WIDTH + \ | ||
62 | STATUSBAR_PLAY_STATE_WIDTH + \ | ||
63 | 2+2+2+2 | ||
64 | #define STATUSBAR_PLAY_MODE_WIDTH 7 | ||
65 | #define STATUSBAR_SHUFFLE_X_POS STATUSBAR_X_POS + \ | ||
66 | STATUSBAR_BATTERY_WIDTH + \ | ||
67 | STATUSBAR_PLUG_WIDTH + \ | ||
68 | STATUSBAR_VOLUME_WIDTH + \ | ||
69 | STATUSBAR_PLAY_STATE_WIDTH + \ | ||
70 | STATUSBAR_PLAY_MODE_WIDTH + \ | ||
71 | 2+2+2+2+2 | ||
72 | #define STATUSBAR_SHUFFLE_WIDTH 7 | ||
73 | #define STATUSBAR_LOCK_X_POS STATUSBAR_X_POS + \ | ||
74 | STATUSBAR_BATTERY_WIDTH + \ | ||
75 | STATUSBAR_PLUG_WIDTH + \ | ||
76 | STATUSBAR_VOLUME_WIDTH + \ | ||
77 | STATUSBAR_PLAY_STATE_WIDTH + \ | ||
78 | STATUSBAR_PLAY_MODE_WIDTH + \ | ||
79 | STATUSBAR_SHUFFLE_WIDTH + \ | ||
80 | 2+2+2+2+2+2 | ||
81 | #define STATUSBAR_LOCK_WIDTH 5 | ||
82 | #define STATUSBAR_DISK_WIDTH 12 | ||
83 | #define STATUSBAR_DISK_X_POS(statusbar_width) statusbar_width - \ | ||
84 | STATUSBAR_DISK_WIDTH | ||
85 | #define STATUSBAR_TIME_X_END(statusbar_width) statusbar_width-1 | ||
86 | |||
87 | void gui_statusbar_init(struct gui_statusbar * bar) | ||
88 | { | ||
89 | bar->last_volume = -1; /* -1 means "first update ever" */ | ||
90 | bar->battery_icon_switch_tick = 0; | ||
91 | #ifdef HAVE_USB_POWER | ||
92 | bar->battery_charge_step = 0; | ||
93 | #endif | ||
94 | } | ||
95 | |||
96 | void gui_statusbar_set_screen(struct gui_statusbar * bar, | ||
97 | struct screen * display) | ||
98 | { | ||
99 | bar->display = display; | ||
100 | gui_statusbar_draw(bar, false); | ||
101 | } | ||
102 | |||
103 | void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw) | ||
104 | { | ||
105 | #ifdef HAVE_LCD_BITMAP | ||
106 | if(!global_settings.statusbar) | ||
107 | return; | ||
108 | #endif | ||
109 | |||
110 | struct screen * display = bar->display; | ||
111 | |||
112 | #ifdef HAVE_LCD_BITMAP | ||
113 | struct tm* tm; /* For Time */ | ||
114 | #else | ||
115 | (void)force_redraw; /* players always "redraw" */ | ||
116 | #endif | ||
117 | |||
118 | bar->info.volume = sound_val2phys(SOUND_VOLUME, global_settings.volume); | ||
119 | bar->info.inserted = charger_inserted(); | ||
120 | bar->info.battlevel = battery_level(); | ||
121 | bar->info.battery_safe = battery_level_safe(); | ||
122 | |||
123 | #ifdef HAVE_LCD_BITMAP | ||
124 | tm = get_time(); | ||
125 | bar->info.hour = tm->tm_hour; | ||
126 | bar->info.minute = tm->tm_min; | ||
127 | bar->info.shuffle = global_settings.playlist_shuffle; | ||
128 | #if CONFIG_KEYPAD == IRIVER_H100_PAD | ||
129 | bar->info.keylock = button_hold(); | ||
130 | #else | ||
131 | bar->info.keylock = keys_locked; | ||
132 | #endif | ||
133 | bar->info.repeat = global_settings.repeat_mode; | ||
134 | bar->info.playmode = current_playmode(); | ||
135 | #if CONFIG_LED == LED_VIRTUAL | ||
136 | bar->info.led = led_read(HZ/2); /* delay should match polling interval */ | ||
137 | #endif | ||
138 | #ifdef HAVE_USB_POWER | ||
139 | bar->info.usb_power = usb_powered(); | ||
140 | #endif | ||
141 | |||
142 | /* only redraw if forced to, or info has changed */ | ||
143 | if (force_redraw || | ||
144 | bar->info.inserted || | ||
145 | !bar->info.battery_safe || | ||
146 | bar->info.redraw_volume || | ||
147 | memcmp(&(bar->info), &(bar->lastinfo), sizeof(struct status_info))) | ||
148 | { | ||
149 | display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); | ||
150 | display->fillrect(0,0,display->width,8); | ||
151 | display->set_drawmode(DRMODE_SOLID); | ||
152 | |||
153 | #else | ||
154 | |||
155 | /* players always "redraw" */ | ||
156 | { | ||
157 | #endif | ||
158 | |||
159 | #ifdef HAVE_CHARGING | ||
160 | if (bar->info.inserted) { | ||
161 | battery_state = true; | ||
162 | #if defined(HAVE_CHARGE_CTRL) || CONFIG_BATTERY == BATT_LIION2200 | ||
163 | /* zero battery run time if charging */ | ||
164 | if (charge_state > 0) { | ||
165 | global_settings.runtime = 0; | ||
166 | lasttime = current_tick; | ||
167 | } | ||
168 | |||
169 | /* animate battery if charging */ | ||
170 | if ((charge_state == 1) || | ||
171 | (charge_state == 2)) { | ||
172 | #else | ||
173 | global_settings.runtime = 0; | ||
174 | lasttime = current_tick; | ||
175 | { | ||
176 | #endif | ||
177 | /* animate in three steps (34% per step for a better look) */ | ||
178 | bar->info.battlevel = bar->battery_charge_step * 34; | ||
179 | if (bar->info.battlevel > 100) | ||
180 | bar->info.battlevel = 100; | ||
181 | if(TIME_AFTER(current_tick, bar->battery_icon_switch_tick)) { | ||
182 | bar->battery_charge_step=(bar->battery_charge_step+1)%4; | ||
183 | bar->battery_icon_switch_tick = current_tick + HZ; | ||
184 | } | ||
185 | } | ||
186 | } | ||
187 | else | ||
188 | #endif /* HAVE_CHARGING */ | ||
189 | { | ||
190 | if (bar->info.battery_safe) | ||
191 | battery_state = true; | ||
192 | else { | ||
193 | /* blink battery if level is low */ | ||
194 | if(TIME_AFTER(current_tick, bar->battery_icon_switch_tick) && | ||
195 | (bar->info.battlevel > -1)) { | ||
196 | bar->battery_icon_switch_tick = current_tick+HZ; | ||
197 | battery_state = !battery_state; | ||
198 | } | ||
199 | } | ||
200 | } | ||
201 | #ifdef HAVE_LCD_BITMAP | ||
202 | if (battery_state) | ||
203 | gui_statusbar_icon_battery(display, bar->info.battlevel); | ||
204 | /* draw power plug if charging */ | ||
205 | if (bar->info.inserted) | ||
206 | display->mono_bitmap(bitmap_icons_7x8[Icon_Plug], | ||
207 | STATUSBAR_PLUG_X_POS, | ||
208 | STATUSBAR_Y_POS, STATUSBAR_PLUG_WIDTH, | ||
209 | STATUSBAR_HEIGHT); | ||
210 | #ifdef HAVE_USB_POWER | ||
211 | else if (bar->info.usb_power) | ||
212 | display->mono_bitmap(bitmap_icons_7x8[Icon_USBPlug], | ||
213 | STATUSBAR_PLUG_X_POS, | ||
214 | STATUSBAR_Y_POS, STATUSBAR_PLUG_WIDTH, | ||
215 | STATUSBAR_HEIGHT); | ||
216 | #endif | ||
217 | |||
218 | bar->info.redraw_volume = gui_statusbar_icon_volume(bar, | ||
219 | bar->info.volume); | ||
220 | gui_statusbar_icon_play_state(display, current_playmode() + | ||
221 | Icon_Play); | ||
222 | switch (bar->info.repeat) { | ||
223 | #ifdef AB_REPEAT_ENABLE | ||
224 | case REPEAT_AB: | ||
225 | gui_statusbar_icon_play_mode(display, Icon_RepeatAB); | ||
226 | break; | ||
227 | #endif | ||
228 | |||
229 | case REPEAT_ONE: | ||
230 | gui_statusbar_icon_play_mode(display, Icon_RepeatOne); | ||
231 | break; | ||
232 | |||
233 | case REPEAT_ALL: | ||
234 | case REPEAT_SHUFFLE: | ||
235 | gui_statusbar_icon_play_mode(display, Icon_Repeat); | ||
236 | break; | ||
237 | } | ||
238 | if (bar->info.shuffle) | ||
239 | gui_statusbar_icon_shuffle(display); | ||
240 | if (bar->info.keylock) | ||
241 | gui_statusbar_icon_lock(display); | ||
242 | #ifdef HAVE_RTC | ||
243 | gui_statusbar_time(display, bar->info.hour, bar->info.minute); | ||
244 | #endif | ||
245 | #if CONFIG_LED == LED_VIRTUAL | ||
246 | if (bar->info.led) | ||
247 | statusbar_led(); | ||
248 | #endif | ||
249 | display->update_rect(0, 0, display->width, STATUSBAR_HEIGHT); | ||
250 | bar->lastinfo = bar->info; | ||
251 | #endif | ||
252 | } | ||
253 | |||
254 | |||
255 | #ifndef HAVE_LCD_BITMAP | ||
256 | if (bar->info.battlevel > -1) | ||
257 | display->icon(ICON_BATTERY, battery_state); | ||
258 | display->icon(ICON_BATTERY_1, bar->info.battlevel > 25); | ||
259 | display->icon(ICON_BATTERY_2, bar->info.battlevel > 50); | ||
260 | display->icon(ICON_BATTERY_3, bar->info.battlevel > 75); | ||
261 | |||
262 | display->icon(ICON_VOLUME, true); | ||
263 | display->icon(ICON_VOLUME_1, bar->info.volume > 10); | ||
264 | display->icon(ICON_VOLUME_2, bar->info.volume > 30); | ||
265 | display->icon(ICON_VOLUME_3, bar->info.volume > 50); | ||
266 | display->icon(ICON_VOLUME_4, bar->info.volume > 70); | ||
267 | display->icon(ICON_VOLUME_5, bar->info.volume > 90); | ||
268 | |||
269 | display->icon(ICON_PLAY, current_playmode() == STATUS_PLAY); | ||
270 | display->icon(ICON_PAUSE, current_playmode() == STATUS_PAUSE); | ||
271 | |||
272 | display->icon(ICON_REPEAT, global_settings.repeat_mode != REPEAT_OFF); | ||
273 | display->icon(ICON_1, global_settings.repeat_mode == REPEAT_ONE); | ||
274 | |||
275 | display->icon(ICON_RECORD, record); | ||
276 | display->icon(ICON_AUDIO, audio); | ||
277 | display->icon(ICON_PARAM, param); | ||
278 | display->icon(ICON_USB, usb); | ||
279 | #endif | ||
280 | } | ||
281 | |||
282 | #ifdef HAVE_LCD_BITMAP | ||
283 | /* from icon.c */ | ||
284 | /* | ||
285 | * Print battery icon to status bar | ||
286 | */ | ||
287 | void gui_statusbar_icon_battery(struct screen * display, int percent) | ||
288 | { | ||
289 | int fill; | ||
290 | char buffer[5]; | ||
291 | unsigned int width, height; | ||
292 | |||
293 | /* fill battery */ | ||
294 | fill = percent; | ||
295 | if (fill < 0) | ||
296 | fill = 0; | ||
297 | if (fill > 100) | ||
298 | fill = 100; | ||
299 | |||
300 | #if defined(HAVE_CHARGE_CTRL) && !defined(SIMULATOR) /* Rec v1 target only */ | ||
301 | /* show graphical animation when charging instead of numbers */ | ||
302 | if ((global_settings.battery_display) && | ||
303 | (charge_state != 1) && | ||
304 | (percent > -1)) { | ||
305 | #else /* all others */ | ||
306 | if (global_settings.battery_display && (percent > -1)) { | ||
307 | #endif | ||
308 | /* Numeric display */ | ||
309 | display->setfont(FONT_SYSFIXED); | ||
310 | snprintf(buffer, sizeof(buffer), "%3d", fill); | ||
311 | display->getstringsize(buffer, &width, &height); | ||
312 | if (height <= STATUSBAR_HEIGHT) | ||
313 | display->putsxy(STATUSBAR_BATTERY_X_POS | ||
314 | + STATUSBAR_BATTERY_WIDTH / 2 | ||
315 | - width/2, STATUSBAR_Y_POS, buffer); | ||
316 | display->setfont(FONT_UI); | ||
317 | |||
318 | } | ||
319 | else { | ||
320 | /* draw battery */ | ||
321 | display->drawrect(STATUSBAR_BATTERY_X_POS, STATUSBAR_Y_POS, 17, 7); | ||
322 | display->vline(STATUSBAR_BATTERY_X_POS + 17, STATUSBAR_Y_POS + 2, | ||
323 | STATUSBAR_Y_POS + 4); | ||
324 | |||
325 | fill = fill * 15 / 100; | ||
326 | display->fillrect(STATUSBAR_BATTERY_X_POS + 1, STATUSBAR_Y_POS + 1, | ||
327 | fill, 5); | ||
328 | } | ||
329 | |||
330 | if (percent == -1) { | ||
331 | display->setfont(FONT_SYSFIXED); | ||
332 | display->putsxy(STATUSBAR_BATTERY_X_POS + STATUSBAR_BATTERY_WIDTH / 2 | ||
333 | - 4, STATUSBAR_Y_POS, "?"); | ||
334 | display->setfont(FONT_UI); | ||
335 | } | ||
336 | } | ||
337 | |||
338 | /* | ||
339 | * Print volume gauge to status bar | ||
340 | */ | ||
341 | bool gui_statusbar_icon_volume(struct gui_statusbar * bar, int percent) | ||
342 | { | ||
343 | int i; | ||
344 | int volume; | ||
345 | int vol; | ||
346 | char buffer[4]; | ||
347 | unsigned int width, height; | ||
348 | bool needs_redraw = false; | ||
349 | int type = global_settings.volume_type; | ||
350 | struct screen * display=bar->display; | ||
351 | |||
352 | volume = percent; | ||
353 | if (volume < 0) | ||
354 | volume = 0; | ||
355 | if (volume > 100) | ||
356 | volume = 100; | ||
357 | |||
358 | if (volume == 0) { | ||
359 | display->mono_bitmap(bitmap_icons_7x8[Icon_Mute], | ||
360 | STATUSBAR_VOLUME_X_POS + STATUSBAR_VOLUME_WIDTH / 2 - 4, | ||
361 | STATUSBAR_Y_POS, 7, STATUSBAR_HEIGHT); | ||
362 | } | ||
363 | else { | ||
364 | /* We want to redraw the icon later on */ | ||
365 | if (bar->last_volume != volume && bar->last_volume >= 0) { | ||
366 | bar->volume_icon_switch_tick = current_tick + HZ; | ||
367 | } | ||
368 | |||
369 | /* If the timeout hasn't yet been reached, we show it numerically | ||
370 | and tell the caller that we want to be called again */ | ||
371 | if (TIME_BEFORE(current_tick,bar->volume_icon_switch_tick)) { | ||
372 | type = 1; | ||
373 | needs_redraw = true; | ||
374 | } | ||
375 | |||
376 | /* display volume level numerical? */ | ||
377 | if (type) | ||
378 | { | ||
379 | display->setfont(FONT_SYSFIXED); | ||
380 | snprintf(buffer, sizeof(buffer), "%2d", percent); | ||
381 | display->getstringsize(buffer, &width, &height); | ||
382 | if (height <= STATUSBAR_HEIGHT) | ||
383 | { | ||
384 | display->putsxy(STATUSBAR_VOLUME_X_POS | ||
385 | + STATUSBAR_VOLUME_WIDTH / 2 | ||
386 | - width/2, STATUSBAR_Y_POS, buffer); | ||
387 | } | ||
388 | display->setfont(FONT_UI); | ||
389 | } else { | ||
390 | /* display volume bar */ | ||
391 | vol = volume * 14 / 100; | ||
392 | for(i=0; i < vol; i++) { | ||
393 | display->vline(STATUSBAR_VOLUME_X_POS + i, | ||
394 | STATUSBAR_Y_POS + 6 - i / 2, | ||
395 | STATUSBAR_Y_POS + 6); | ||
396 | } | ||
397 | } | ||
398 | } | ||
399 | bar->last_volume = volume; | ||
400 | |||
401 | return needs_redraw; | ||
402 | } | ||
403 | |||
404 | /* | ||
405 | * Print play state to status bar | ||
406 | */ | ||
407 | void gui_statusbar_icon_play_state(struct screen * display, int state) | ||
408 | { | ||
409 | display->mono_bitmap(bitmap_icons_7x8[state], STATUSBAR_PLAY_STATE_X_POS, | ||
410 | STATUSBAR_Y_POS, STATUSBAR_PLAY_STATE_WIDTH, | ||
411 | STATUSBAR_HEIGHT); | ||
412 | } | ||
413 | |||
414 | /* | ||
415 | * Print play mode to status bar | ||
416 | */ | ||
417 | void gui_statusbar_icon_play_mode(struct screen * display, int mode) | ||
418 | { | ||
419 | display->mono_bitmap(bitmap_icons_7x8[mode], STATUSBAR_PLAY_MODE_X_POS, | ||
420 | STATUSBAR_Y_POS, STATUSBAR_PLAY_MODE_WIDTH, | ||
421 | STATUSBAR_HEIGHT); | ||
422 | } | ||
423 | |||
424 | /* | ||
425 | * Print shuffle mode to status bar | ||
426 | */ | ||
427 | void gui_statusbar_icon_shuffle(struct screen * display) | ||
428 | { | ||
429 | display->mono_bitmap(bitmap_icons_7x8[Icon_Shuffle], | ||
430 | STATUSBAR_SHUFFLE_X_POS, STATUSBAR_Y_POS, | ||
431 | STATUSBAR_SHUFFLE_WIDTH, STATUSBAR_HEIGHT); | ||
432 | } | ||
433 | |||
434 | /* | ||
435 | * Print lock when keys are locked | ||
436 | */ | ||
437 | void gui_statusbar_icon_lock(struct screen * display) | ||
438 | { | ||
439 | display->mono_bitmap(bitmap_icons_5x8[Icon_Lock], STATUSBAR_LOCK_X_POS, | ||
440 | STATUSBAR_Y_POS, 5, 8); | ||
441 | } | ||
442 | |||
443 | #if CONFIG_LED == LED_VIRTUAL | ||
444 | /* | ||
445 | * no real LED: disk activity in status bar | ||
446 | */ | ||
447 | void gui_statusbar_led(struct screen * display) | ||
448 | { | ||
449 | display->mono_bitmap(bitmap_icon_disk, STATUSBAR_DISK_X_POS, | ||
450 | STATUSBAR_Y_POS, STATUSBAR_DISK_WIDTH(screen->width), | ||
451 | STATUSBAR_HEIGHT); | ||
452 | } | ||
453 | #endif | ||
454 | |||
455 | |||
456 | #ifdef HAVE_RTC | ||
457 | /* | ||
458 | * Print time to status bar | ||
459 | */ | ||
460 | void gui_statusbar_time(struct screen * display, int hour, int minute) | ||
461 | { | ||
462 | unsigned char buffer[6]; | ||
463 | unsigned int width, height; | ||
464 | if ( hour >= 0 && | ||
465 | hour <= 23 && | ||
466 | minute >= 0 && | ||
467 | minute <= 59 ) { | ||
468 | if ( global_settings.timeformat ) { /* 12 hour clock */ | ||
469 | hour %= 12; | ||
470 | if ( hour == 0 ) { | ||
471 | hour += 12; | ||
472 | } | ||
473 | } | ||
474 | snprintf(buffer, sizeof(buffer), "%02d:%02d", hour, minute); | ||
475 | } | ||
476 | else { | ||
477 | strncpy(buffer, "--:--", sizeof buffer); | ||
478 | } | ||
479 | display->setfont(FONT_SYSFIXED); | ||
480 | display->getstringsize(buffer, &width, &height); | ||
481 | if (height <= STATUSBAR_HEIGHT) { | ||
482 | display->putsxy(STATUSBAR_TIME_X_END(display->width) - width, | ||
483 | STATUSBAR_Y_POS, buffer); | ||
484 | } | ||
485 | display->setfont(FONT_UI); | ||
486 | |||
487 | } | ||
488 | #endif | ||
489 | |||
490 | #endif /* HAVE_LCD_BITMAP */ | ||
491 | |||
492 | void gui_syncstatusbar_init(struct gui_syncstatusbar * bars) | ||
493 | { | ||
494 | int i; | ||
495 | for(i = 0;i < NB_SCREENS;++i) { | ||
496 | gui_statusbar_init( &(bars->statusbars[i]) ); | ||
497 | gui_statusbar_set_screen( &(bars->statusbars[i]), &(screens[i]) ); | ||
498 | } | ||
499 | } | ||
500 | |||
501 | void gui_syncstatusbar_draw(struct gui_syncstatusbar * bars, | ||
502 | bool force_redraw) | ||
503 | { | ||
504 | int i; | ||
505 | for(i = 0;i < NB_SCREENS;++i) { | ||
506 | gui_statusbar_draw( &(bars->statusbars[i]), force_redraw ); | ||
507 | } | ||
508 | } | ||
diff --git a/apps/gui/statusbar.h b/apps/gui/statusbar.h new file mode 100644 index 0000000000..434d679e29 --- /dev/null +++ b/apps/gui/statusbar.h | |||
@@ -0,0 +1,107 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 by Kévin FERRARE | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #ifndef _GUI_STATUSBAR_H_ | ||
21 | #define _GUI_STATUSBAR_H_ | ||
22 | |||
23 | #include "config.h" | ||
24 | #include "status.h" | ||
25 | |||
26 | struct status_info { | ||
27 | int battlevel; | ||
28 | int volume; | ||
29 | int hour; | ||
30 | int minute; | ||
31 | int playmode; | ||
32 | int repeat; | ||
33 | bool inserted; | ||
34 | bool shuffle; | ||
35 | bool keylock; | ||
36 | bool battery_safe; | ||
37 | bool redraw_volume; /* true if the volume gauge needs updating */ | ||
38 | #if CONFIG_LED == LED_VIRTUAL | ||
39 | bool led; /* disk LED simulation in the status bar */ | ||
40 | #endif | ||
41 | #ifdef HAVE_USB_POWER | ||
42 | bool usb_power; | ||
43 | #endif | ||
44 | }; | ||
45 | |||
46 | struct gui_statusbar | ||
47 | { | ||
48 | /* Volume icon stuffs */ | ||
49 | long volume_icon_switch_tick; | ||
50 | int last_volume; | ||
51 | |||
52 | long battery_icon_switch_tick; | ||
53 | |||
54 | #ifdef HAVE_CHARGING | ||
55 | int battery_charge_step; | ||
56 | #endif | ||
57 | |||
58 | struct status_info info; | ||
59 | struct status_info lastinfo; | ||
60 | |||
61 | struct screen * display; | ||
62 | }; | ||
63 | |||
64 | /* | ||
65 | * Initializes a status bar | ||
66 | * - bar : the bar to initialize | ||
67 | */ | ||
68 | extern void gui_statusbar_init(struct gui_statusbar * bar); | ||
69 | |||
70 | /* | ||
71 | * Attach the status bar to a screen | ||
72 | * (The previous screen attachement is lost) | ||
73 | * - bar : the statusbar structure | ||
74 | * - display : the screen to attach | ||
75 | */ | ||
76 | extern void gui_statusbar_set_screen(struct gui_statusbar * bar, struct screen * display); | ||
77 | |||
78 | /* | ||
79 | * Draws the status bar on the attached screen | ||
80 | * - bar : the statusbar structure | ||
81 | */ | ||
82 | extern void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw); | ||
83 | |||
84 | void gui_statusbar_icon_battery(struct screen * display, int percent); | ||
85 | bool gui_statusbar_icon_volume(struct gui_statusbar * bar, int percent); | ||
86 | void gui_statusbar_icon_play_state(struct screen * display, int state); | ||
87 | void gui_statusbar_icon_play_mode(struct screen * display, int mode); | ||
88 | void gui_statusbar_icon_shuffle(struct screen * display); | ||
89 | void gui_statusbar_icon_lock(struct screen * display); | ||
90 | #if CONFIG_LED == LED_VIRTUAL | ||
91 | void gui_statusbar_led(struct screen * display); | ||
92 | #endif | ||
93 | |||
94 | #ifdef HAVE_RTC | ||
95 | void gui_statusbar_time(struct screen * display, int hour, int minute); | ||
96 | #endif | ||
97 | |||
98 | |||
99 | struct gui_syncstatusbar | ||
100 | { | ||
101 | struct gui_statusbar statusbars[NB_SCREENS]; | ||
102 | }; | ||
103 | |||
104 | extern void gui_syncstatusbar_init(struct gui_syncstatusbar * bars); | ||
105 | extern void gui_syncstatusbar_draw(struct gui_syncstatusbar * bars, bool force_redraw); | ||
106 | |||
107 | #endif /*_GUI_STATUSBAR_H_*/ | ||