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_ICONAREA_WIDTH
)
110 /* scrolling needed */
111 int width
= (parent
->width
- CENTER_ICONAREA_WIDTH
)/2;
112 vps
[screen
][QUICKSCREEN_LEFT
].width
= width
;
113 vps
[screen
][QUICKSCREEN_RIGHT
].width
= width
;
114 vps
[screen
][QUICKSCREEN_RIGHT
].x
= parent
->x
+parent
->width
- width
;
115 vp_icons
[screen
].x
= parent
->x
+ width
;
116 vp_icons
[screen
].width
= CENTER_ICONAREA_WIDTH
;
121 if (left_width
> right_width
)
125 width
+= CENTER_MARGIN
;
126 if (width
*2 < parent
->width
/2)
128 width
+= parent
->width
/6;
129 /* add some padding on the edges */
132 vps
[screen
][QUICKSCREEN_LEFT
].width
= width
;
133 vps
[screen
][QUICKSCREEN_RIGHT
].width
= width
;
134 vps
[screen
][QUICKSCREEN_RIGHT
].x
= parent
->x
+ parent
->width
- width
;
135 vp_icons
[screen
].x
= parent
->x
+ width
;
138 vp_icons
[screen
].x
+= pad
;
139 vps
[screen
][QUICKSCREEN_LEFT
].x
+= pad
;
140 vps
[screen
][QUICKSCREEN_RIGHT
].x
-= pad
;
141 /* need to add the pad to the bottom to make it all centered nicely */
142 vps
[screen
][QUICKSCREEN_BOTTOM
].x
+= pad
;
143 vps
[screen
][QUICKSCREEN_BOTTOM
].width
-= pad
;
145 vp_icons
[screen
].width
= vps
[screen
][QUICKSCREEN_RIGHT
].x
- width
;
150 static void quickscreen_draw_text(char *s
, int item
, bool title
,
151 struct screen
*display
, struct viewport
*vp
)
153 int nb_lines
= viewport_get_nb_lines(vp
);
154 int w
, h
, line
= 0, x
= 0;
155 display
->getstringsize(s
, &w
, &h
);
157 if (nb_lines
> 1 && !title
)
161 case QUICKSCREEN_BOTTOM
:
162 x
= (vp
->width
- w
)/2;
164 case QUICKSCREEN_LEFT
:
167 case QUICKSCREEN_RIGHT
:
172 display
->puts_scroll(0, line
, s
);
174 display
->putsxy(x
, line
*h
, s
);
177 static void gui_quickscreen_draw(struct gui_quickscreen
*qs
,
178 struct screen
*display
,
179 struct viewport
*parent
)
181 #ifdef HAVE_REMOTE_LCD
182 int screen
= display
->screen_type
;
184 const int screen
= 0;
189 unsigned char *title
, *value
;
192 display
->set_viewport(parent
);
193 display
->clear_viewport();
194 for (i
=0; i
<QUICKSCREEN_ITEM_COUNT
; i
++)
198 display
->set_viewport(&vps
[screen
][i
]);
199 display
->scroll_stop(&vps
[screen
][i
]);
201 title
= P2STR(ID2P(qs
->items
[i
]->lang_id
));
202 setting
= qs
->items
[i
]->setting
;
203 temp
= option_value_as_int(qs
->items
[i
]);
204 value
= option_get_valuestring((struct settings_list
*)qs
->items
[i
],
205 buf
, MAX_PATH
, temp
);
207 if (vps
[screen
][i
].height
< display
->char_height
*2)
210 snprintf(text
, MAX_PATH
, "%s: %s", title
, value
);
211 quickscreen_draw_text(text
, i
, true, display
, &vps
[screen
][i
]);
215 quickscreen_draw_text(title
, i
, true, display
, &vps
[screen
][i
]);
216 quickscreen_draw_text(value
, i
, false, display
, &vps
[screen
][i
]);
218 display
->update_viewport();
221 display
->set_viewport(&vp_icons
[screen
]);
222 display
->mono_bitmap(bitmap_icons_7x8
[Icon_FastForward
],
223 vp_icons
[screen
].width
- 8, 0, 7, 8);
224 display
->mono_bitmap(bitmap_icons_7x8
[Icon_FastBackward
], 0, 0, 7, 8);
225 display
->mono_bitmap(bitmap_icons_7x8
[Icon_DownArrow
],
226 (vp_icons
[screen
].width
/2) - 4,
227 vp_icons
[screen
].height
- 7, 7, 8);
228 display
->update_viewport();
230 display
->set_viewport(parent
);
231 display
->update_viewport();
232 display
->set_viewport(NULL
);
235 static void talk_qs_option(struct settings_list
*opt
, bool enqueue
)
237 if (global_settings
.talk_menu
) {
240 talk_id(opt
->lang_id
, true);
241 option_talk_value(opt
, option_value_as_int(opt
), true);
246 * Does the actions associated to the given button if any
247 * - qs : the quickscreen
248 * - button : the key we are going to analyse
249 * returns : true if the button corresponded to an action, false otherwise
251 static bool gui_quickscreen_do_button(struct gui_quickscreen
* qs
, int button
)
257 item
= QUICKSCREEN_LEFT
;
261 case ACTION_QS_DOWNINV
:
262 item
= QUICKSCREEN_BOTTOM
;
265 case ACTION_QS_RIGHT
:
266 item
= QUICKSCREEN_RIGHT
;
272 option_select_next_val((struct settings_list
*)qs
->items
[item
], false, true);
273 talk_qs_option((struct settings_list
*)qs
->items
[item
], false);
277 bool gui_syncquickscreen_run(struct gui_quickscreen
* qs
, int button_enter
)
280 struct viewport vp
[NB_SCREENS
];
281 bool changed
= false;
282 /* To quit we need either :
283 * - a second press on the button that made us enter
284 * - an action taken while pressing the enter button,
285 * then release the enter button*/
286 bool can_quit
= false;
287 gui_syncstatusbar_draw(&statusbars
, true);
290 screens
[i
].set_viewport(NULL
);
291 screens
[i
].stop_scroll();
292 viewport_set_defaults(&vp
[i
], i
);
293 quickscreen_fix_viewports(qs
, &screens
[i
], &vp
[i
]);
294 gui_quickscreen_draw(qs
, &screens
[i
], &vp
[i
]);
296 /* Announce current selection on entering this screen. This is all
297 queued up, but can be interrupted as soon as a setting is
299 cond_talk_ids(VOICE_QUICKSCREEN
);
300 talk_qs_option((struct settings_list
*)qs
->items
[QUICKSCREEN_LEFT
], true);
301 talk_qs_option((struct settings_list
*)qs
->items
[QUICKSCREEN_BOTTOM
], true);
302 talk_qs_option((struct settings_list
*)qs
->items
[QUICKSCREEN_RIGHT
], true);
304 button
= get_action(CONTEXT_QUICKSCREEN
,HZ
/5);
305 if(default_event_handler(button
) == SYS_USB_CONNECTED
)
307 if(gui_quickscreen_do_button(qs
, button
))
312 gui_quickscreen_draw(qs
, &screens
[i
], &vp
[i
]);
316 else if(button
==button_enter
)
319 if((button
== button_enter
) && can_quit
)
322 if(button
==ACTION_STD_CANCEL
)
325 gui_syncstatusbar_draw(&statusbars
, false);
327 /* Notify that we're exiting this screen */
328 cond_talk_ids_fq(VOICE_OK
);
332 bool quick_screen_quick(int button_enter
)
334 struct gui_quickscreen qs
;
335 bool oldshuffle
= global_settings
.playlist_shuffle
;
336 int oldrepeat
= global_settings
.repeat_mode
;
337 qs
.items
[QUICKSCREEN_LEFT
] =
338 find_setting(&global_settings
.playlist_shuffle
, NULL
);
339 qs
.items
[QUICKSCREEN_RIGHT
] =
340 find_setting(&global_settings
.repeat_mode
, NULL
);
341 qs
.items
[QUICKSCREEN_BOTTOM
] =
342 find_setting(&global_settings
.dirfilter
, NULL
);
344 if (gui_syncquickscreen_run(&qs
, button_enter
))
347 settings_apply(false);
348 /* make sure repeat/shuffle/any other nasty ones get updated */
349 if ( oldrepeat
!= global_settings
.repeat_mode
&&
350 (audio_status() & AUDIO_STATUS_PLAY
) )
352 audio_flush_and_reload_tracks();
354 if (oldshuffle
!= global_settings
.playlist_shuffle
355 && audio_status() & AUDIO_STATUS_PLAY
)
357 #if CONFIG_CODEC == SWCODEC
358 dsp_set_replaygain();
360 if (global_settings
.playlist_shuffle
)
361 playlist_randomise(NULL
, current_tick
, true);
363 playlist_sort(NULL
, true);
370 bool quick_screen_f3(int button_enter
)
372 struct gui_quickscreen qs
;
373 qs
.items
[QUICKSCREEN_LEFT
] =
374 find_setting(&global_settings
.scrollbar
, NULL
);
375 qs
.items
[QUICKSCREEN_RIGHT
] =
376 find_setting(&global_settings
.statusbar
, NULL
);
377 qs
.items
[QUICKSCREEN_BOTTOM
] =
378 find_setting(&global_settings
.flip_display
, NULL
);
380 if (gui_syncquickscreen_run(&qs
, button_enter
))
383 settings_apply(false);
387 #endif /* BUTTON_F3 */