quiet the masses...
[Rockbox.git] / apps / gui / quickscreen.c
blobf98c926e918166e8697d8cb0c9e5f5ff7e2b37f0
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2008 by Jonathan Gordon
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 "quickscreen.h"
22 #ifdef HAVE_QUICKSCREEN
24 #include <stdio.h>
25 #include "system.h"
26 #include "icons.h"
27 #include "textarea.h"
28 #include "font.h"
29 #include "kernel.h"
30 #include "misc.h"
31 #include "statusbar.h"
32 #include "action.h"
33 #include "settings_list.h"
34 #include "lang.h"
35 #include "option_select.h"
37 static struct viewport vps[NB_SCREENS][QUICKSCREEN_ITEM_COUNT];
39 static void quickscreen_fix_viewports(struct gui_quickscreen *qs,
40 struct screen *display,
41 struct viewport *parent)
43 int height, i, count=0, top;
44 int nb_lines = parent->height/display->char_height;
45 bool single_line_bottom = false;
47 for(i=0; i<QUICKSCREEN_ITEM_COUNT; i++)
49 if (qs->items[i])
50 count++;
51 vps[display->screen_type][i] = *parent;
54 /* special handling when there is only enough room for 2 items.
55 discard the top and bottom items, so only show the 2 side ones */
56 if (nb_lines < 4)
58 qs->items[QUICKSCREEN_TOP] = NULL;
59 qs->items[QUICKSCREEN_BOTTOM] = NULL;
60 vps[display->screen_type][QUICKSCREEN_RIGHT].y = parent->y;
61 vps[display->screen_type][QUICKSCREEN_LEFT].height = parent->height/2;
62 vps[display->screen_type][QUICKSCREEN_RIGHT].y = parent->y+parent->height/2;
63 vps[display->screen_type][QUICKSCREEN_RIGHT].height = parent->height/2;
64 return;
66 else if (nb_lines < 5 && count == 4) /* drop the top item */
68 qs->items[QUICKSCREEN_TOP] = NULL;
69 single_line_bottom = true;
72 height = display->char_height*2;
73 if (nb_lines > 8 ||
74 (nb_lines > 5 && qs->items[QUICKSCREEN_TOP] == NULL))
75 height += display->char_height;
76 /* Top item */
77 if (qs->items[QUICKSCREEN_TOP])
79 vps[display->screen_type][QUICKSCREEN_TOP].y = parent->y;
80 vps[display->screen_type][QUICKSCREEN_TOP].height = height;
82 else
84 vps[display->screen_type][QUICKSCREEN_TOP].height = 0;
86 /* bottom item */
87 if (qs->items[QUICKSCREEN_BOTTOM])
89 if (single_line_bottom)
90 height = display->char_height;
91 vps[display->screen_type][QUICKSCREEN_BOTTOM].y = parent->y+parent->height - height;
92 vps[display->screen_type][QUICKSCREEN_BOTTOM].height = height;
94 else
96 vps[display->screen_type][QUICKSCREEN_BOTTOM].height = 0;
99 /* side items */
100 height = parent->height -
101 vps[display->screen_type][QUICKSCREEN_BOTTOM].height -
102 vps[display->screen_type][QUICKSCREEN_TOP].height ;
103 top = parent->y+vps[display->screen_type][QUICKSCREEN_TOP].height;
104 vps[display->screen_type][QUICKSCREEN_LEFT].y = top;
105 vps[display->screen_type][QUICKSCREEN_RIGHT].y = top;
106 vps[display->screen_type][QUICKSCREEN_LEFT].height = height;
107 vps[display->screen_type][QUICKSCREEN_RIGHT].height = height;
109 vps[display->screen_type][QUICKSCREEN_RIGHT].x = parent->x+parent->width/2;
111 vps[display->screen_type][QUICKSCREEN_LEFT].width = parent->width/2;
112 vps[display->screen_type][QUICKSCREEN_RIGHT].width = parent->width/2;
115 static void quickscreen_draw_text(char *s, int item, bool title,
116 struct screen *display, struct viewport *vp)
118 int nb_lines = vp->height/display->char_height;
119 int w, line = 0, x=0;
120 display->getstringsize(s, &w, NULL);
121 switch (item)
123 case QUICKSCREEN_TOP:
124 if (nb_lines > 2)
126 if (title)
128 display->mono_bitmap(bitmap_icons_7x8[Icon_UpArrow],
129 (vp->width/2)-4, 0, 7, 8);
130 line = 1;
132 else
133 line = 2;
135 else
136 line = title?0:1;
137 x = (vp->width - w)/2;
138 break;
139 case QUICKSCREEN_BOTTOM:
140 if (title && nb_lines > 2 && item == QUICKSCREEN_BOTTOM)
142 display->mono_bitmap(bitmap_icons_7x8[Icon_DownArrow],
143 (vp->width/2)-4, vp->height-8, 7, 8);
145 line = title?0:1;
146 x = (vp->width - w)/2;
147 break;
148 case QUICKSCREEN_LEFT:
149 if (nb_lines > 1)
151 line = nb_lines/2;
152 if (title)
153 line--;
155 else
156 line = 0;
157 if (title)
158 display->mono_bitmap(bitmap_icons_7x8[Icon_FastBackward], 1,
159 line*display->char_height+display->char_height/2, 7, 8);
160 x = 12;
161 break;
162 case QUICKSCREEN_RIGHT:
163 line = nb_lines/2;
164 if (title == false)
165 line++;
166 if (title)
167 display->mono_bitmap(bitmap_icons_7x8[Icon_FastForward],
168 vp->width - 8,
169 line*display->char_height+display->char_height/2, 7, 8);
170 x = vp->width - w - 12;
171 break;
173 if (w>vp->width)
174 display->puts_scroll(0,line,s);
175 else
176 display->putsxy(x, line*display->char_height, s);
179 static void gui_quickscreen_draw(struct gui_quickscreen *qs,
180 struct screen *display,
181 struct viewport *parent)
183 int i;
184 char buf[MAX_PATH];
185 unsigned char *title, *value;
186 void *setting;
187 int temp;
188 display->set_viewport(parent);
189 display->clear_viewport();
190 for (i=0; i<QUICKSCREEN_ITEM_COUNT; i++)
193 if (!qs->items[i])
194 continue;
195 display->set_viewport(&vps[display->screen_type][i]);
196 display->scroll_stop(&vps[display->screen_type][i]);
198 title = P2STR(ID2P(qs->items[i]->lang_id));
199 setting = qs->items[i]->setting;
200 if (qs->items[i]->flags&F_T_BOOL)
201 temp = *(bool*)setting?1:0;
202 else
203 temp = *(int*)setting;
204 value = option_get_valuestring((struct settings_list*)qs->items[i], buf, MAX_PATH, temp);
206 if (vps[display->screen_type][i].height < display->char_height*2)
208 char text[MAX_PATH];
209 snprintf(text, MAX_PATH, "%s: %s", title, value);
210 quickscreen_draw_text(text, i, true, display, &vps[display->screen_type][i]);
212 else
214 quickscreen_draw_text(title, i, true, display, &vps[display->screen_type][i]);
215 quickscreen_draw_text(value, i, false, display, &vps[display->screen_type][i]);
217 display->update_viewport();
219 display->set_viewport(parent);
220 display->update_viewport();
221 display->set_viewport(NULL);
226 * Does the actions associated to the given button if any
227 * - qs : the quickscreen
228 * - button : the key we are going to analyse
229 * returns : true if the button corresponded to an action, false otherwise
231 static bool gui_quickscreen_do_button(struct gui_quickscreen * qs, int button)
233 switch(button)
235 case ACTION_QS_LEFT:
236 if (qs->items[QUICKSCREEN_LEFT])
237 option_select_next_val((struct settings_list *)qs->items[QUICKSCREEN_LEFT]);
238 return(true);
240 case ACTION_QS_DOWN:
241 if (qs->items[QUICKSCREEN_BOTTOM])
242 option_select_next_val((struct settings_list *)qs->items[QUICKSCREEN_BOTTOM]);
243 return(true);
245 case ACTION_QS_RIGHT:
246 if (qs->items[QUICKSCREEN_RIGHT])
247 option_select_next_val((struct settings_list *)qs->items[QUICKSCREEN_RIGHT]);
248 return(true);
250 case ACTION_QS_DOWNINV:
251 if (qs->items[QUICKSCREEN_TOP])
252 option_select_next_val((struct settings_list *)qs->items[QUICKSCREEN_TOP]);
253 return(true);
255 return(false);
258 bool gui_syncquickscreen_run(struct gui_quickscreen * qs, int button_enter)
260 int button, i;
261 bool changed = false;
262 struct viewport vp[NB_SCREENS];
263 /* To quit we need either :
264 * - a second press on the button that made us enter
265 * - an action taken while pressing the enter button,
266 * then release the enter button*/
267 bool can_quit=false;
268 gui_syncstatusbar_draw(&statusbars, true);
269 FOR_NB_SCREENS(i)
271 screens[i].set_viewport(NULL);
272 screens[i].scroll_stop(NULL);
273 vp[i].x = 0;
274 vp[i].width = screens[i].width;
275 vp[i].y = STATUSBAR_HEIGHT;
276 vp[i].height = screens[i].height - STATUSBAR_HEIGHT;
277 #ifdef HAVE_LCD_COLOR
278 if (screens[i].is_color)
280 vp[i].fg_pattern = global_settings.fg_color;
281 vp[i].bg_pattern = global_settings.bg_color;
283 #endif
284 vp[i].xmargin = 0;
285 vp[i].ymargin = 0;
286 vp[i].font = FONT_UI;
287 vp[i].drawmode = STYLE_DEFAULT;
288 quickscreen_fix_viewports(qs, &screens[i], &vp[i]);
289 gui_quickscreen_draw(qs, &screens[i], &vp[i]);
291 while (true) {
292 button = get_action(CONTEXT_QUICKSCREEN,TIMEOUT_BLOCK);
293 if(default_event_handler(button) == SYS_USB_CONNECTED)
294 return(true);
295 if(gui_quickscreen_do_button(qs, button))
297 changed = true;
298 can_quit=true;
299 if (button == ACTION_QS_DOWNINV &&
300 !qs->items[QUICKSCREEN_TOP])
301 break;
302 FOR_NB_SCREENS(i)
303 gui_quickscreen_draw(qs, &screens[i], &vp[i]);
305 else if(button==button_enter)
306 can_quit=true;
308 if((button == button_enter) && can_quit)
309 break;
311 if(button==ACTION_STD_CANCEL)
312 break;
314 gui_syncstatusbar_draw(&statusbars, false);
316 if (changed)
317 settings_apply();
318 return false;
321 bool quick_screen_quick(int button_enter)
323 struct gui_quickscreen qs;
324 qs.items[QUICKSCREEN_LEFT] = find_setting_from_string(global_settings.quickscreen_left, NULL);
325 qs.items[QUICKSCREEN_RIGHT] = find_setting_from_string(global_settings.quickscreen_right,NULL);
326 qs.items[QUICKSCREEN_BOTTOM] = find_setting_from_string(global_settings.quickscreen_bottom, NULL);
327 qs.items[QUICKSCREEN_TOP] = find_setting_from_string(global_settings.quickscreen_top,NULL);
328 qs.callback = NULL;
329 gui_syncquickscreen_run(&qs, button_enter);
330 return(0);
333 #ifdef BUTTON_F3
334 bool quick_screen_f3(int button_enter)
336 struct gui_quickscreen qs;
337 qs.items[QUICKSCREEN_LEFT] = find_setting(&global_settings.scrollbar, NULL);
338 qs.items[QUICKSCREEN_RIGHT] = find_setting(&global_settings.statusbar, NULL);
339 qs.items[QUICKSCREEN_BOTTOM] = find_setting(&global_settings.flip_display, NULL);
340 qs.items[QUICKSCREEN_TOP] = NULL;
341 qs.callback = NULL;
342 gui_syncquickscreen_run(&qs, button_enter);
343 return(0);
345 #endif /* BUTTON_F3 */
347 #endif /* HAVE_QUICKSCREEN */