diff options
Diffstat (limited to 'apps/gui/quickscreen.c')
-rw-r--r-- | apps/gui/quickscreen.c | 361 |
1 files changed, 255 insertions, 106 deletions
diff --git a/apps/gui/quickscreen.c b/apps/gui/quickscreen.c index c2da5879fe..8668e9b085 100644 --- a/apps/gui/quickscreen.c +++ b/apps/gui/quickscreen.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * \/ \/ \/ \/ \/ | 7 | * \/ \/ \/ \/ \/ |
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2005 by Kevin Ferrare | 10 | * Copyright (C) 2008 by Jonathan Gordon |
11 | * | 11 | * |
12 | * All files in this archive are subject to the GNU General Public License. | 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. | 13 | * See the file COPYING in the source tree root for full license agreement. |
@@ -17,11 +17,9 @@ | |||
17 | * | 17 | * |
18 | ****************************************************************************/ | 18 | ****************************************************************************/ |
19 | 19 | ||
20 | #include "quickscreen.h" | ||
21 | |||
22 | #ifdef HAVE_QUICKSCREEN | ||
23 | 20 | ||
24 | #include <stdio.h> | 21 | #include <stdio.h> |
22 | #include "config.h" | ||
25 | #include "system.h" | 23 | #include "system.h" |
26 | #include "icons.h" | 24 | #include "icons.h" |
27 | #include "textarea.h" | 25 | #include "textarea.h" |
@@ -30,109 +28,199 @@ | |||
30 | #include "misc.h" | 28 | #include "misc.h" |
31 | #include "statusbar.h" | 29 | #include "statusbar.h" |
32 | #include "action.h" | 30 | #include "action.h" |
31 | #include "settings_list.h" | ||
32 | #include "lang.h" | ||
33 | #include "playlist.h" | ||
34 | #include "dsp.h" | ||
35 | #include "viewport.h" | ||
36 | #include "audio.h" | ||
37 | #include "quickscreen.h" | ||
33 | 38 | ||
34 | void gui_quickscreen_init(struct gui_quickscreen * qs, | 39 | static struct viewport vps[NB_SCREENS][QUICKSCREEN_ITEM_COUNT]; |
35 | struct option_select *left_option, | 40 | static struct viewport vp_icons[NB_SCREENS]; |
36 | struct option_select *bottom_option, | 41 | /* vp_icons will be used like this: |
37 | struct option_select *right_option, | 42 | the side icons will be aligned to the top of this vp and to their sides |
38 | quickscreen_callback callback) | 43 | the bottom icon wil be aligned center and at the bottom of this vp */ |
39 | { | ||
40 | qs->left_option=left_option; | ||
41 | qs->bottom_option=bottom_option; | ||
42 | qs->right_option=right_option; | ||
43 | qs->callback=callback; | ||
44 | } | ||
45 | 44 | ||
46 | /* | 45 | #define MIN_LINES 4 |
47 | * Draws the quickscreen on a given screen | 46 | #define MAX_NEEDED_LINES 8 |
48 | * - qs : the quickscreen | 47 | #define CENTER_MARGIN 10 /* pixels between the 2 center items minimum */ |
49 | * - display : the screen to draw on | 48 | #define CENTER_ICONAREA_WIDTH (CENTER_MARGIN+8*2) |
50 | */ | 49 | |
51 | static void gui_quickscreen_draw(struct gui_quickscreen * qs, struct screen * display) | 50 | static void quickscreen_fix_viewports(struct gui_quickscreen *qs, |
51 | struct screen *display, | ||
52 | struct viewport *parent) | ||
52 | { | 53 | { |
53 | const unsigned char *option; | 54 | int char_height, i, screen = display->screen_type; |
54 | const unsigned char *title; | 55 | int left_width, right_width, bottom_lines = 3; |
55 | int w, font_h; | 56 | unsigned char *s; |
56 | bool statusbar = global_settings.statusbar; | 57 | int nb_lines = viewport_get_nb_lines(parent); |
57 | #ifdef HAS_BUTTONBAR | 58 | char_height = parent->height/nb_lines; |
58 | display->has_buttonbar=false; | 59 | |
59 | #endif | 60 | vp_icons[screen] = *parent; |
60 | gui_textarea_clear(display); | 61 | |
61 | if (display->height / display->char_height < 7) /* we need at leats 7 lines */ | 62 | vps[screen][QUICKSCREEN_BOTTOM] = *parent; |
63 | if (nb_lines <= MIN_LINES) /* make the bottom item use 1 line */ | ||
64 | bottom_lines = 1; | ||
65 | else | ||
66 | bottom_lines = 2; | ||
67 | vps[screen][QUICKSCREEN_BOTTOM].height = bottom_lines*char_height; | ||
68 | vps[screen][QUICKSCREEN_BOTTOM].y = parent->y + parent->height - bottom_lines*char_height; | ||
69 | if (nb_lines >= MAX_NEEDED_LINES) | ||
62 | { | 70 | { |
63 | display->setfont(FONT_SYSFIXED); | 71 | vps[screen][QUICKSCREEN_BOTTOM].y -= char_height; |
64 | } | 72 | } |
65 | display->getstringsize("A", NULL, &font_h); | 73 | |
66 | 74 | /* adjust the left/right items widths to fit the screen nicely */ | |
67 | /* do these calculations once */ | 75 | s = P2STR(ID2P(qs->items[QUICKSCREEN_LEFT]->lang_id)); |
68 | const unsigned int puts_center = display->height/2/font_h; | 76 | left_width = display->getstringsize(s, NULL, NULL); |
69 | const unsigned int puts_bottom = display->height/font_h; | 77 | s = P2STR(ID2P(qs->items[QUICKSCREEN_RIGHT]->lang_id)); |
70 | const unsigned int putsxy_center = display->height/2; | 78 | right_width = display->getstringsize(s, NULL, NULL); |
71 | const unsigned int putsxy_bottom = display->height; | 79 | nb_lines -= bottom_lines; |
72 | 80 | ||
73 | /* Displays the first line of text */ | 81 | vps[screen][QUICKSCREEN_LEFT] = *parent; |
74 | option=(unsigned char *)option_select_get_text(qs->left_option); | 82 | vps[screen][QUICKSCREEN_RIGHT] = *parent; |
75 | title=(unsigned char *)qs->left_option->title; | 83 | vps[screen][QUICKSCREEN_LEFT].x = parent->x; |
76 | display->puts_scroll(2, puts_center-4+!statusbar, title); | 84 | if (nb_lines <= MIN_LINES) |
77 | display->puts_scroll(2, puts_center-3+!statusbar, option); | 85 | i = 0; |
78 | display->mono_bitmap(bitmap_icons_7x8[Icon_FastBackward], 1, | 86 | else |
79 | putsxy_center-(font_h*3), 7, 8); | 87 | i = nb_lines/2; |
80 | 88 | vps[screen][QUICKSCREEN_LEFT].y = parent->y + (i*char_height); | |
81 | /* Displays the second line of text */ | 89 | vps[screen][QUICKSCREEN_RIGHT].y = parent->y + (i*char_height); |
82 | option=(unsigned char *)option_select_get_text(qs->right_option); | 90 | if (nb_lines >= 3) |
83 | title=(unsigned char *)qs->right_option->title; | 91 | i = 3*char_height; |
84 | display->getstringsize(title, &w, NULL); | 92 | else |
85 | if(w > display->width - 8) | 93 | i = nb_lines*char_height; |
94 | |||
95 | vps[screen][QUICKSCREEN_LEFT].height = i; | ||
96 | vps[screen][QUICKSCREEN_RIGHT].height = i; | ||
97 | vp_icons[screen].y = vps[screen][QUICKSCREEN_LEFT].y + (char_height/2); | ||
98 | vp_icons[screen].height = vps[screen][QUICKSCREEN_BOTTOM].y - vp_icons[screen].y; | ||
99 | |||
100 | if (left_width + right_width > display->width - CENTER_MARGIN) /* scrolling needed */ | ||
86 | { | 101 | { |
87 | display->puts_scroll(2, puts_center-2+!statusbar, title); | 102 | int width = (parent->width - CENTER_ICONAREA_WIDTH)/2; |
88 | display->mono_bitmap(bitmap_icons_7x8[Icon_FastForward], 1, | 103 | vps[screen][QUICKSCREEN_LEFT].width = width; |
89 | putsxy_center-font_h, 7, 8); | 104 | vps[screen][QUICKSCREEN_RIGHT].width = width; |
105 | vps[screen][QUICKSCREEN_RIGHT].x = parent->x+parent->width - width; | ||
106 | vp_icons[screen].x = parent->x + width; | ||
107 | vp_icons[screen].width = CENTER_ICONAREA_WIDTH; | ||
90 | } | 108 | } |
91 | else | 109 | else |
92 | { | 110 | { |
93 | display->putsxy(display->width - w - 12, putsxy_center-font_h, title); | 111 | int width, pad = 0; |
94 | display->mono_bitmap(bitmap_icons_7x8[Icon_FastForward], | 112 | if (left_width > right_width) |
95 | display->width - 8, putsxy_center-font_h, 7, 8); | 113 | width = left_width; |
114 | else | ||
115 | width = right_width; | ||
116 | width += CENTER_MARGIN; | ||
117 | if (width*2 < parent->width/2) | ||
118 | { | ||
119 | width += parent->width/6; | ||
120 | /* add some padding on the edges */ | ||
121 | pad = CENTER_MARGIN; | ||
122 | } | ||
123 | vps[screen][QUICKSCREEN_LEFT].width = width; | ||
124 | vps[screen][QUICKSCREEN_RIGHT].width = width; | ||
125 | vps[screen][QUICKSCREEN_RIGHT].x = parent->x + parent->width - width; | ||
126 | vp_icons[screen].x = parent->x + width; | ||
127 | if (pad) | ||
128 | { | ||
129 | vp_icons[screen].x += pad; | ||
130 | vps[screen][QUICKSCREEN_LEFT].x += pad; | ||
131 | vps[screen][QUICKSCREEN_RIGHT].x -= pad; | ||
132 | /* need to add the pad to the bottom to make it all centered nicely */ | ||
133 | vps[screen][QUICKSCREEN_BOTTOM].x += pad; | ||
134 | vps[screen][QUICKSCREEN_BOTTOM].width -= pad; | ||
135 | } | ||
136 | vp_icons[screen].width = vps[screen][QUICKSCREEN_RIGHT].x - width; | ||
137 | |||
96 | } | 138 | } |
97 | display->getstringsize(option, &w, NULL); | 139 | } |
98 | if(w > display->width) | ||
99 | display->puts_scroll(0, puts_center-1+!statusbar, option); | ||
100 | else | ||
101 | display->putsxy(display->width -w-12, putsxy_center, option); | ||
102 | |||
103 | /* Displays the third line of text */ | ||
104 | option=(unsigned char *)option_select_get_text(qs->bottom_option); | ||
105 | title=(unsigned char *)qs->bottom_option->title; | ||
106 | |||
107 | display->getstringsize(title, &w, NULL); | ||
108 | if(w > display->width) | ||
109 | display->puts_scroll(0, puts_bottom-4+!statusbar, title); | ||
110 | else | ||
111 | display->putsxy(display->width/2-w/2, putsxy_bottom-(font_h*3), title); | ||
112 | 140 | ||
113 | display->getstringsize(option, &w, NULL); | 141 | static void quickscreen_draw_text(char *s, int item, bool title, |
114 | if(w > display->width) | 142 | struct screen *display, struct viewport *vp) |
115 | display->puts_scroll(0, puts_bottom-3+!statusbar, option); | 143 | { |
144 | int nb_lines = viewport_get_nb_lines(vp); | ||
145 | int w, h, line = 0, x=0; | ||
146 | display->getstringsize(s, &w, &h); | ||
147 | |||
148 | if (nb_lines > 1 && !title) | ||
149 | line = 1; | ||
150 | switch (item) | ||
151 | { | ||
152 | case QUICKSCREEN_BOTTOM: | ||
153 | x = (vp->width - w)/2; | ||
154 | break; | ||
155 | case QUICKSCREEN_LEFT: | ||
156 | x = 0; | ||
157 | break; | ||
158 | case QUICKSCREEN_RIGHT: | ||
159 | x = vp->width - w; | ||
160 | break; | ||
161 | } | ||
162 | if (w>vp->width) | ||
163 | display->puts_scroll(0,line,s); | ||
116 | else | 164 | else |
117 | display->putsxy(display->width/2-w/2, putsxy_bottom-(font_h*2), option); | 165 | display->putsxy(x, line*h, s); |
118 | display->mono_bitmap(bitmap_icons_7x8[Icon_DownArrow], display->width/2-4, | ||
119 | putsxy_bottom-font_h, 7, 8); | ||
120 | |||
121 | gui_textarea_update(display); | ||
122 | display->setfont(FONT_UI); | ||
123 | } | 166 | } |
124 | 167 | ||
125 | /* | 168 | static void gui_quickscreen_draw(struct gui_quickscreen *qs, |
126 | * Draws the quickscreen on all available screens | 169 | struct screen *display, |
127 | * - qs : the quickscreen | 170 | struct viewport *parent) |
128 | */ | ||
129 | static void gui_syncquickscreen_draw(struct gui_quickscreen * qs) | ||
130 | { | 171 | { |
131 | int i; | 172 | int i; |
132 | FOR_NB_SCREENS(i) | 173 | char buf[MAX_PATH]; |
133 | gui_quickscreen_draw(qs, &screens[i]); | 174 | unsigned char *title, *value; |
175 | void *setting; | ||
176 | int temp; | ||
177 | display->set_viewport(parent); | ||
178 | display->clear_viewport(); | ||
179 | for (i=0; i<QUICKSCREEN_ITEM_COUNT; i++) | ||
180 | { | ||
181 | |||
182 | if (!qs->items[i]) | ||
183 | continue; | ||
184 | display->set_viewport(&vps[display->screen_type][i]); | ||
185 | display->scroll_stop(&vps[display->screen_type][i]); | ||
186 | |||
187 | title = P2STR(ID2P(qs->items[i]->lang_id)); | ||
188 | setting = qs->items[i]->setting; | ||
189 | if ((qs->items[i]->flags & F_BOOL_SETTING) == F_BOOL_SETTING) | ||
190 | temp = *(bool*)setting?1:0; | ||
191 | else | ||
192 | temp = *(int*)setting; | ||
193 | value = option_get_valuestring((struct settings_list*)qs->items[i], buf, MAX_PATH, temp); | ||
194 | |||
195 | if (vps[display->screen_type][i].height < display->char_height*2) | ||
196 | { | ||
197 | char text[MAX_PATH]; | ||
198 | snprintf(text, MAX_PATH, "%s: %s", title, value); | ||
199 | quickscreen_draw_text(text, i, true, display, &vps[display->screen_type][i]); | ||
200 | } | ||
201 | else | ||
202 | { | ||
203 | quickscreen_draw_text(title, i, true, display, &vps[display->screen_type][i]); | ||
204 | quickscreen_draw_text(value, i, false, display, &vps[display->screen_type][i]); | ||
205 | } | ||
206 | display->update_viewport(); | ||
207 | } | ||
208 | /* draw the icons */ | ||
209 | display->set_viewport(&vp_icons[display->screen_type]); | ||
210 | display->mono_bitmap(bitmap_icons_7x8[Icon_FastForward], | ||
211 | vp_icons[display->screen_type].width - 8, 0, 7, 8); | ||
212 | display->mono_bitmap(bitmap_icons_7x8[Icon_FastBackward], 0, 0, 7, 8); | ||
213 | display->mono_bitmap(bitmap_icons_7x8[Icon_DownArrow], | ||
214 | (vp_icons[display->screen_type].width/2) - 4, | ||
215 | vp_icons[display->screen_type].height - 7, 7, 8); | ||
216 | display->update_viewport(); | ||
217 | |||
218 | display->set_viewport(parent); | ||
219 | display->update_viewport(); | ||
220 | display->set_viewport(NULL); | ||
134 | } | 221 | } |
135 | 222 | ||
223 | |||
136 | /* | 224 | /* |
137 | * Does the actions associated to the given button if any | 225 | * Does the actions associated to the given button if any |
138 | * - qs : the quickscreen | 226 | * - qs : the quickscreen |
@@ -141,48 +229,60 @@ static void gui_syncquickscreen_draw(struct gui_quickscreen * qs) | |||
141 | */ | 229 | */ |
142 | static bool gui_quickscreen_do_button(struct gui_quickscreen * qs, int button) | 230 | static bool gui_quickscreen_do_button(struct gui_quickscreen * qs, int button) |
143 | { | 231 | { |
144 | 232 | int item; | |
145 | switch(button) | 233 | switch(button) |
146 | { | 234 | { |
147 | case ACTION_QS_LEFT: | 235 | case ACTION_QS_LEFT: |
148 | option_select_next(qs->left_option); | 236 | item = QUICKSCREEN_LEFT; |
149 | return(true); | 237 | break; |
150 | 238 | ||
151 | case ACTION_QS_DOWN: | 239 | case ACTION_QS_DOWN: |
152 | option_select_next(qs->bottom_option); | 240 | case ACTION_QS_DOWNINV: |
153 | return(true); | 241 | item = QUICKSCREEN_BOTTOM; |
242 | break; | ||
154 | 243 | ||
155 | case ACTION_QS_RIGHT: | 244 | case ACTION_QS_RIGHT: |
156 | option_select_next(qs->right_option); | 245 | item = QUICKSCREEN_RIGHT; |
157 | return(true); | 246 | break; |
158 | 247 | ||
159 | case ACTION_QS_DOWNINV: | 248 | default: |
160 | option_select_prev(qs->bottom_option); | 249 | return false; |
161 | return(true); | ||
162 | } | 250 | } |
163 | return(false); | 251 | option_select_next_val((struct settings_list *)qs->items[item], false, true); |
252 | return true; | ||
164 | } | 253 | } |
165 | 254 | ||
166 | bool gui_syncquickscreen_run(struct gui_quickscreen * qs, int button_enter) | 255 | bool gui_syncquickscreen_run(struct gui_quickscreen * qs, int button_enter) |
167 | { | 256 | { |
168 | int button; | 257 | int button, i; |
258 | struct viewport vp[NB_SCREENS]; | ||
259 | bool changed = false; | ||
169 | /* To quit we need either : | 260 | /* To quit we need either : |
170 | * - a second press on the button that made us enter | 261 | * - a second press on the button that made us enter |
171 | * - an action taken while pressing the enter button, | 262 | * - an action taken while pressing the enter button, |
172 | * then release the enter button*/ | 263 | * then release the enter button*/ |
173 | bool can_quit=false; | 264 | bool can_quit=false; |
174 | gui_syncquickscreen_draw(qs); | ||
175 | gui_syncstatusbar_draw(&statusbars, true); | 265 | gui_syncstatusbar_draw(&statusbars, true); |
266 | FOR_NB_SCREENS(i) | ||
267 | { | ||
268 | screens[i].set_viewport(NULL); | ||
269 | screens[i].stop_scroll(); | ||
270 | viewport_set_defaults(&vp[i], i); | ||
271 | quickscreen_fix_viewports(qs, &screens[i], &vp[i]); | ||
272 | gui_quickscreen_draw(qs, &screens[i], &vp[i]); | ||
273 | } | ||
176 | while (true) { | 274 | while (true) { |
177 | button = get_action(CONTEXT_QUICKSCREEN,TIMEOUT_BLOCK); | 275 | button = get_action(CONTEXT_QUICKSCREEN,TIMEOUT_BLOCK); |
178 | if(default_event_handler(button) == SYS_USB_CONNECTED) | 276 | if(default_event_handler(button) == SYS_USB_CONNECTED) |
179 | return(true); | 277 | return(true); |
180 | if(gui_quickscreen_do_button(qs, button)) | 278 | if(gui_quickscreen_do_button(qs, button)) |
181 | { | 279 | { |
280 | changed = true; | ||
182 | can_quit=true; | 281 | can_quit=true; |
183 | if(qs->callback) | 282 | FOR_NB_SCREENS(i) |
283 | gui_quickscreen_draw(qs, &screens[i], &vp[i]); | ||
284 | if (qs->callback) | ||
184 | qs->callback(qs); | 285 | qs->callback(qs); |
185 | gui_syncquickscreen_draw(qs); | ||
186 | } | 286 | } |
187 | else if(button==button_enter) | 287 | else if(button==button_enter) |
188 | can_quit=true; | 288 | can_quit=true; |
@@ -195,8 +295,57 @@ bool gui_syncquickscreen_run(struct gui_quickscreen * qs, int button_enter) | |||
195 | 295 | ||
196 | gui_syncstatusbar_draw(&statusbars, false); | 296 | gui_syncstatusbar_draw(&statusbars, false); |
197 | } | 297 | } |
198 | return false; | 298 | return changed; |
299 | } | ||
300 | |||
301 | bool quick_screen_quick(int button_enter) | ||
302 | { | ||
303 | struct gui_quickscreen qs; | ||
304 | bool oldshuffle = global_settings.playlist_shuffle; | ||
305 | int oldrepeat = global_settings.repeat_mode; | ||
306 | qs.items[QUICKSCREEN_LEFT] = find_setting(&global_settings.playlist_shuffle, NULL); | ||
307 | qs.items[QUICKSCREEN_RIGHT] = find_setting(&global_settings.repeat_mode, NULL); | ||
308 | qs.items[QUICKSCREEN_BOTTOM] = find_setting(&global_settings.dirfilter, NULL); | ||
309 | qs.callback = NULL; | ||
310 | if (gui_syncquickscreen_run(&qs, button_enter)) | ||
311 | { | ||
312 | settings_save(); | ||
313 | settings_apply(false); | ||
314 | /* make sure repeat/shuffle/any other nasty ones get updated */ | ||
315 | if ( oldrepeat != global_settings.repeat_mode && | ||
316 | (audio_status() & AUDIO_STATUS_PLAY) ) | ||
317 | { | ||
318 | audio_flush_and_reload_tracks(); | ||
319 | } | ||
320 | if (oldshuffle != global_settings.playlist_shuffle | ||
321 | && audio_status() & AUDIO_STATUS_PLAY) | ||
322 | { | ||
323 | #if CONFIG_CODEC == SWCODEC | ||
324 | dsp_set_replaygain(); | ||
325 | #endif | ||
326 | if (global_settings.playlist_shuffle) | ||
327 | playlist_randomise(NULL, current_tick, true); | ||
328 | else | ||
329 | playlist_sort(NULL, true); | ||
330 | } | ||
331 | } | ||
332 | return(0); | ||
199 | } | 333 | } |
200 | 334 | ||
201 | #endif /* HAVE_QUICKSCREEN */ | 335 | #ifdef BUTTON_F3 |
336 | bool quick_screen_f3(int button_enter) | ||
337 | { | ||
338 | struct gui_quickscreen qs; | ||
339 | qs.items[QUICKSCREEN_LEFT] = find_setting(&global_settings.scrollbar, NULL); | ||
340 | qs.items[QUICKSCREEN_RIGHT] = find_setting(&global_settings.statusbar, NULL); | ||
341 | qs.items[QUICKSCREEN_BOTTOM] = find_setting(&global_settings.flip_display, NULL); | ||
342 | qs.callback = NULL; | ||
343 | if (gui_syncquickscreen_run(&qs, button_enter)) | ||
344 | { | ||
345 | settings_save(); | ||
346 | settings_apply(false); | ||
347 | } | ||
348 | return(0); | ||
349 | } | ||
350 | #endif /* BUTTON_F3 */ | ||
202 | 351 | ||