1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
28 #include "statusbar.h"
30 #include "settings_list.h"
36 #include "quickscreen.h"
39 static struct viewport vps
[NB_SCREENS
][QUICKSCREEN_ITEM_COUNT
];
40 static struct viewport vp_icons
[NB_SCREENS
];
41 /* vp_icons will be used like this:
42 the side icons will be aligned to the top of this vp and to their sides
43 the bottom icon wil be aligned center and at the bottom of this vp */
46 #define MAX_NEEDED_LINES 8
47 #define CENTER_MARGIN 10 /* pixels between the 2 center items minimum */
48 #define CENTER_ICONAREA_WIDTH (CENTER_MARGIN+8*2)
50 static void quickscreen_fix_viewports(struct gui_quickscreen
*qs
,
51 struct screen
*display
,
52 struct viewport
*parent
)
54 #ifdef HAVE_REMOTE_LCD
55 int screen
= display
->screen_type
;
61 int left_width
, right_width
, bottom_lines
= 3;
63 int nb_lines
= viewport_get_nb_lines(parent
);
64 char_height
= parent
->height
/nb_lines
;
66 vp_icons
[screen
] = *parent
;
68 vps
[screen
][QUICKSCREEN_BOTTOM
] = *parent
;
69 if (nb_lines
<= MIN_LINES
) /* make the bottom item use 1 line */
73 vps
[screen
][QUICKSCREEN_BOTTOM
].height
= bottom_lines
*char_height
;
74 vps
[screen
][QUICKSCREEN_BOTTOM
].y
=
75 parent
->y
+ parent
->height
- bottom_lines
*char_height
;
76 if (nb_lines
>= MAX_NEEDED_LINES
)
78 vps
[screen
][QUICKSCREEN_BOTTOM
].y
-= char_height
;
81 /* adjust the left/right items widths to fit the screen nicely */
82 s
= P2STR(ID2P(qs
->items
[QUICKSCREEN_LEFT
]->lang_id
));
83 left_width
= display
->getstringsize(s
, NULL
, NULL
);
84 s
= P2STR(ID2P(qs
->items
[QUICKSCREEN_RIGHT
]->lang_id
));
85 right_width
= display
->getstringsize(s
, NULL
, NULL
);
86 nb_lines
-= bottom_lines
;
88 vps
[screen
][QUICKSCREEN_LEFT
] = *parent
;
89 vps
[screen
][QUICKSCREEN_RIGHT
] = *parent
;
90 vps
[screen
][QUICKSCREEN_LEFT
].x
= parent
->x
;
91 if (nb_lines
<= MIN_LINES
)
95 vps
[screen
][QUICKSCREEN_LEFT
].y
= parent
->y
+ (i
*char_height
);
96 vps
[screen
][QUICKSCREEN_RIGHT
].y
= parent
->y
+ (i
*char_height
);
100 i
= nb_lines
*char_height
;
102 vps
[screen
][QUICKSCREEN_LEFT
].height
= i
;
103 vps
[screen
][QUICKSCREEN_RIGHT
].height
= i
;
104 vp_icons
[screen
].y
= vps
[screen
][QUICKSCREEN_LEFT
].y
+ (char_height
/2);
105 vp_icons
[screen
].height
=
106 vps
[screen
][QUICKSCREEN_BOTTOM
].y
- vp_icons
[screen
].y
;
108 if (left_width
+ right_width
> display
->width
- CENTER_MARGIN
) /* scrolling needed */
110 int width
= (parent
->width
- CENTER_ICONAREA_WIDTH
)/2;
111 vps
[screen
][QUICKSCREEN_LEFT
].width
= width
;
112 vps
[screen
][QUICKSCREEN_RIGHT
].width
= width
;
113 vps
[screen
][QUICKSCREEN_RIGHT
].x
= parent
->x
+parent
->width
- width
;
114 vp_icons
[screen
].x
= parent
->x
+ width
;
115 vp_icons
[screen
].width
= CENTER_ICONAREA_WIDTH
;
120 if (left_width
> right_width
)
124 width
+= CENTER_MARGIN
;
125 if (width
*2 < parent
->width
/2)
127 width
+= parent
->width
/6;
128 /* add some padding on the edges */
131 vps
[screen
][QUICKSCREEN_LEFT
].width
= width
;
132 vps
[screen
][QUICKSCREEN_RIGHT
].width
= width
;
133 vps
[screen
][QUICKSCREEN_RIGHT
].x
= parent
->x
+ parent
->width
- width
;
134 vp_icons
[screen
].x
= parent
->x
+ width
;
137 vp_icons
[screen
].x
+= pad
;
138 vps
[screen
][QUICKSCREEN_LEFT
].x
+= pad
;
139 vps
[screen
][QUICKSCREEN_RIGHT
].x
-= pad
;
140 /* need to add the pad to the bottom to make it all centered nicely */
141 vps
[screen
][QUICKSCREEN_BOTTOM
].x
+= pad
;
142 vps
[screen
][QUICKSCREEN_BOTTOM
].width
-= pad
;
144 vp_icons
[screen
].width
= vps
[screen
][QUICKSCREEN_RIGHT
].x
- width
;
149 static void quickscreen_draw_text(char *s
, int item
, bool title
,
150 struct screen
*display
, struct viewport
*vp
)
152 int nb_lines
= viewport_get_nb_lines(vp
);
153 int w
, h
, line
= 0, x
= 0;
154 display
->getstringsize(s
, &w
, &h
);
156 if (nb_lines
> 1 && !title
)
160 case QUICKSCREEN_BOTTOM
:
161 x
= (vp
->width
- w
)/2;
163 case QUICKSCREEN_LEFT
:
166 case QUICKSCREEN_RIGHT
:
171 display
->puts_scroll(0, line
, s
);
173 display
->putsxy(x
, line
*h
, s
);
176 static void gui_quickscreen_draw(struct gui_quickscreen
*qs
,
177 struct screen
*display
,
178 struct viewport
*parent
)
180 #ifdef HAVE_REMOTE_LCD
181 int screen
= display
->screen_type
;
183 const int screen
= 0;
188 unsigned char *title
, *value
;
191 display
->set_viewport(parent
);
192 display
->clear_viewport();
193 for (i
=0; i
<QUICKSCREEN_ITEM_COUNT
; i
++)
197 display
->set_viewport(&vps
[screen
][i
]);
198 display
->scroll_stop(&vps
[screen
][i
]);
200 title
= P2STR(ID2P(qs
->items
[i
]->lang_id
));
201 setting
= qs
->items
[i
]->setting
;
202 if ((qs
->items
[i
]->flags
& F_BOOL_SETTING
) == F_BOOL_SETTING
)
203 temp
= *(bool*)setting
?1:0;
205 temp
= *(int*)setting
;
206 value
= option_get_valuestring((struct settings_list
*)qs
->items
[i
],
207 buf
, MAX_PATH
, temp
);
209 if (vps
[screen
][i
].height
< display
->char_height
*2)
212 snprintf(text
, MAX_PATH
, "%s: %s", title
, value
);
213 quickscreen_draw_text(text
, i
, true, display
, &vps
[screen
][i
]);
217 quickscreen_draw_text(title
, i
, true, display
, &vps
[screen
][i
]);
218 quickscreen_draw_text(value
, i
, false, display
, &vps
[screen
][i
]);
220 display
->update_viewport();
223 display
->set_viewport(&vp_icons
[screen
]);
224 display
->mono_bitmap(bitmap_icons_7x8
[Icon_FastForward
],
225 vp_icons
[screen
].width
- 8, 0, 7, 8);
226 display
->mono_bitmap(bitmap_icons_7x8
[Icon_FastBackward
], 0, 0, 7, 8);
227 display
->mono_bitmap(bitmap_icons_7x8
[Icon_DownArrow
],
228 (vp_icons
[screen
].width
/2) - 4,
229 vp_icons
[screen
].height
- 7, 7, 8);
230 display
->update_viewport();
232 display
->set_viewport(parent
);
233 display
->update_viewport();
234 display
->set_viewport(NULL
);
237 static int option_value(const struct settings_list
*setting
)
239 if ((setting
->flags
& F_BOOL_SETTING
) == F_BOOL_SETTING
)
241 return *(bool*)setting
->setting
==true?1:0;
244 return *(int*)setting
->setting
;
247 static void talk_qs_option(struct settings_list
*opt
, bool enqueue
)
249 if (global_settings
.talk_menu
) {
252 talk_id(opt
->lang_id
, true);
253 option_talk_value(opt
, option_value(opt
), true);
258 * Does the actions associated to the given button if any
259 * - qs : the quickscreen
260 * - button : the key we are going to analyse
261 * returns : true if the button corresponded to an action, false otherwise
263 static bool gui_quickscreen_do_button(struct gui_quickscreen
* qs
, int button
)
269 item
= QUICKSCREEN_LEFT
;
273 case ACTION_QS_DOWNINV
:
274 item
= QUICKSCREEN_BOTTOM
;
277 case ACTION_QS_RIGHT
:
278 item
= QUICKSCREEN_RIGHT
;
284 option_select_next_val((struct settings_list
*)qs
->items
[item
], false, true);
285 talk_qs_option((struct settings_list
*)qs
->items
[item
], false);
289 bool gui_syncquickscreen_run(struct gui_quickscreen
* qs
, int button_enter
)
292 struct viewport vp
[NB_SCREENS
];
293 bool changed
= false;
294 /* To quit we need either :
295 * - a second press on the button that made us enter
296 * - an action taken while pressing the enter button,
297 * then release the enter button*/
298 bool can_quit
= false;
299 gui_syncstatusbar_draw(&statusbars
, true);
302 screens
[i
].set_viewport(NULL
);
303 screens
[i
].stop_scroll();
304 viewport_set_defaults(&vp
[i
], i
);
305 quickscreen_fix_viewports(qs
, &screens
[i
], &vp
[i
]);
306 gui_quickscreen_draw(qs
, &screens
[i
], &vp
[i
]);
308 /* Announce current selection on entering this screen. This is all
309 queued up, but can be interrupted as soon as a setting is
311 cond_talk_ids(VOICE_QUICKSCREEN
);
312 talk_qs_option((struct settings_list
*)qs
->items
[QUICKSCREEN_LEFT
], true);
313 talk_qs_option((struct settings_list
*)qs
->items
[QUICKSCREEN_BOTTOM
], true);
314 talk_qs_option((struct settings_list
*)qs
->items
[QUICKSCREEN_RIGHT
], true);
316 button
= get_action(CONTEXT_QUICKSCREEN
,HZ
/5);
317 if(default_event_handler(button
) == SYS_USB_CONNECTED
)
319 if(gui_quickscreen_do_button(qs
, button
))
324 gui_quickscreen_draw(qs
, &screens
[i
], &vp
[i
]);
328 else if(button
==button_enter
)
331 if((button
== button_enter
) && can_quit
)
334 if(button
==ACTION_STD_CANCEL
)
337 gui_syncstatusbar_draw(&statusbars
, false);
339 /* Notify that we're exiting this screen */
340 cond_talk_ids_fq(VOICE_OK
);
344 bool quick_screen_quick(int button_enter
)
346 struct gui_quickscreen qs
;
347 bool oldshuffle
= global_settings
.playlist_shuffle
;
348 int oldrepeat
= global_settings
.repeat_mode
;
349 qs
.items
[QUICKSCREEN_LEFT
] =
350 find_setting(&global_settings
.playlist_shuffle
, NULL
);
351 qs
.items
[QUICKSCREEN_RIGHT
] =
352 find_setting(&global_settings
.repeat_mode
, NULL
);
353 qs
.items
[QUICKSCREEN_BOTTOM
] =
354 find_setting(&global_settings
.dirfilter
, NULL
);
356 if (gui_syncquickscreen_run(&qs
, button_enter
))
359 settings_apply(false);
360 /* make sure repeat/shuffle/any other nasty ones get updated */
361 if ( oldrepeat
!= global_settings
.repeat_mode
&&
362 (audio_status() & AUDIO_STATUS_PLAY
) )
364 audio_flush_and_reload_tracks();
366 if (oldshuffle
!= global_settings
.playlist_shuffle
367 && audio_status() & AUDIO_STATUS_PLAY
)
369 #if CONFIG_CODEC == SWCODEC
370 dsp_set_replaygain();
372 if (global_settings
.playlist_shuffle
)
373 playlist_randomise(NULL
, current_tick
, true);
375 playlist_sort(NULL
, true);
382 bool quick_screen_f3(int button_enter
)
384 struct gui_quickscreen qs
;
385 qs
.items
[QUICKSCREEN_LEFT
] =
386 find_setting(&global_settings
.scrollbar
, NULL
);
387 qs
.items
[QUICKSCREEN_RIGHT
] =
388 find_setting(&global_settings
.statusbar
, NULL
);
389 qs
.items
[QUICKSCREEN_BOTTOM
] =
390 find_setting(&global_settings
.flip_display
, NULL
);
392 if (gui_syncquickscreen_run(&qs
, button_enter
))
395 settings_apply(false);
399 #endif /* BUTTON_F3 */