1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2008 by Jonathan Gordon
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
30 #include "statusbar.h"
32 #include "settings_list.h"
38 #include "quickscreen.h"
41 static struct viewport vps
[NB_SCREENS
][QUICKSCREEN_ITEM_COUNT
];
42 static struct viewport vp_icons
[NB_SCREENS
];
43 /* vp_icons will be used like this:
44 the side icons will be aligned to the top of this vp and to their sides
45 the bottom icon wil be aligned center and at the bottom of this vp */
48 #define MAX_NEEDED_LINES 8
49 #define CENTER_MARGIN 10 /* pixels between the 2 center items minimum */
50 #define CENTER_ICONAREA_WIDTH (CENTER_MARGIN+8*2)
52 static void quickscreen_fix_viewports(struct gui_quickscreen
*qs
,
53 struct screen
*display
,
54 struct viewport
*parent
)
56 #ifdef HAVE_REMOTE_LCD
57 int screen
= display
->screen_type
;
63 int left_width
, right_width
, bottom_lines
= 3;
65 int nb_lines
= viewport_get_nb_lines(parent
);
66 char_height
= parent
->height
/nb_lines
;
68 vp_icons
[screen
] = *parent
;
70 vps
[screen
][QUICKSCREEN_BOTTOM
] = *parent
;
71 if (nb_lines
<= MIN_LINES
) /* make the bottom item use 1 line */
75 vps
[screen
][QUICKSCREEN_BOTTOM
].height
= bottom_lines
*char_height
;
76 vps
[screen
][QUICKSCREEN_BOTTOM
].y
=
77 parent
->y
+ parent
->height
- bottom_lines
*char_height
;
78 if (nb_lines
>= MAX_NEEDED_LINES
)
80 vps
[screen
][QUICKSCREEN_BOTTOM
].y
-= char_height
;
83 /* adjust the left/right items widths to fit the screen nicely */
84 s
= P2STR(ID2P(qs
->items
[QUICKSCREEN_LEFT
]->lang_id
));
85 left_width
= display
->getstringsize(s
, NULL
, NULL
);
86 s
= P2STR(ID2P(qs
->items
[QUICKSCREEN_RIGHT
]->lang_id
));
87 right_width
= display
->getstringsize(s
, NULL
, NULL
);
88 nb_lines
-= bottom_lines
;
90 vps
[screen
][QUICKSCREEN_LEFT
] = *parent
;
91 vps
[screen
][QUICKSCREEN_RIGHT
] = *parent
;
92 vps
[screen
][QUICKSCREEN_LEFT
].x
= parent
->x
;
93 if (nb_lines
<= MIN_LINES
)
97 vps
[screen
][QUICKSCREEN_LEFT
].y
= parent
->y
+ (i
*char_height
);
98 vps
[screen
][QUICKSCREEN_RIGHT
].y
= parent
->y
+ (i
*char_height
);
102 i
= nb_lines
*char_height
;
104 vps
[screen
][QUICKSCREEN_LEFT
].height
= i
;
105 vps
[screen
][QUICKSCREEN_RIGHT
].height
= i
;
106 vp_icons
[screen
].y
= vps
[screen
][QUICKSCREEN_LEFT
].y
+ (char_height
/2);
107 vp_icons
[screen
].height
=
108 vps
[screen
][QUICKSCREEN_BOTTOM
].y
- vp_icons
[screen
].y
;
110 if (left_width
+ right_width
> display
->lcdwidth
- CENTER_ICONAREA_WIDTH
)
112 /* scrolling needed */
113 int width
= (parent
->width
- CENTER_ICONAREA_WIDTH
)/2;
114 vps
[screen
][QUICKSCREEN_LEFT
].width
= width
;
115 vps
[screen
][QUICKSCREEN_RIGHT
].width
= width
;
116 vps
[screen
][QUICKSCREEN_RIGHT
].x
= parent
->x
+parent
->width
- width
;
117 vp_icons
[screen
].x
= parent
->x
+ width
;
118 vp_icons
[screen
].width
= CENTER_ICONAREA_WIDTH
;
123 if (left_width
> right_width
)
127 width
+= CENTER_MARGIN
;
128 if (width
*2 < parent
->width
/2)
130 width
+= parent
->width
/6;
131 /* add some padding on the edges */
134 vps
[screen
][QUICKSCREEN_LEFT
].width
= width
;
135 vps
[screen
][QUICKSCREEN_RIGHT
].width
= width
;
136 vps
[screen
][QUICKSCREEN_RIGHT
].x
= parent
->x
+ parent
->width
- width
;
137 vp_icons
[screen
].x
= parent
->x
+ width
;
140 vp_icons
[screen
].x
+= pad
;
141 vps
[screen
][QUICKSCREEN_LEFT
].x
+= pad
;
142 vps
[screen
][QUICKSCREEN_RIGHT
].x
-= pad
;
143 /* need to add the pad to the bottom to make it all centered nicely */
144 vps
[screen
][QUICKSCREEN_BOTTOM
].x
+= pad
;
145 vps
[screen
][QUICKSCREEN_BOTTOM
].width
-= pad
;
147 vp_icons
[screen
].width
= vps
[screen
][QUICKSCREEN_RIGHT
].x
- width
;
152 static void quickscreen_draw_text(char *s
, int item
, bool title
,
153 struct screen
*display
, struct viewport
*vp
)
155 int nb_lines
= viewport_get_nb_lines(vp
);
156 int w
, h
, line
= 0, x
= 0;
157 display
->getstringsize(s
, &w
, &h
);
159 if (nb_lines
> 1 && !title
)
163 case QUICKSCREEN_BOTTOM
:
164 x
= (vp
->width
- w
)/2;
166 case QUICKSCREEN_LEFT
:
169 case QUICKSCREEN_RIGHT
:
174 display
->puts_scroll(0, line
, s
);
176 display
->putsxy(x
, line
*h
, s
);
179 static void gui_quickscreen_draw(struct gui_quickscreen
*qs
,
180 struct screen
*display
,
181 struct viewport
*parent
)
183 #ifdef HAVE_REMOTE_LCD
184 int screen
= display
->screen_type
;
186 const int screen
= 0;
191 unsigned char *title
, *value
;
194 display
->set_viewport(parent
);
195 display
->clear_viewport();
196 for (i
=0; i
<QUICKSCREEN_ITEM_COUNT
; i
++)
200 display
->set_viewport(&vps
[screen
][i
]);
201 display
->scroll_stop(&vps
[screen
][i
]);
203 title
= P2STR(ID2P(qs
->items
[i
]->lang_id
));
204 setting
= qs
->items
[i
]->setting
;
205 temp
= option_value_as_int(qs
->items
[i
]);
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 void talk_qs_option(struct settings_list
*opt
, bool enqueue
)
239 if (global_settings
.talk_menu
) {
242 talk_id(opt
->lang_id
, true);
243 option_talk_value(opt
, option_value_as_int(opt
), true);
248 * Does the actions associated to the given button if any
249 * - qs : the quickscreen
250 * - button : the key we are going to analyse
251 * returns : true if the button corresponded to an action, false otherwise
253 static bool gui_quickscreen_do_button(struct gui_quickscreen
* qs
, int button
)
259 item
= QUICKSCREEN_LEFT
;
263 case ACTION_QS_DOWNINV
:
264 item
= QUICKSCREEN_BOTTOM
;
267 case ACTION_QS_RIGHT
:
268 item
= QUICKSCREEN_RIGHT
;
274 option_select_next_val((struct settings_list
*)qs
->items
[item
], false, true);
275 talk_qs_option((struct settings_list
*)qs
->items
[item
], false);
279 bool gui_syncquickscreen_run(struct gui_quickscreen
* qs
, int button_enter
)
282 struct viewport vp
[NB_SCREENS
];
283 bool changed
= false;
284 /* To quit we need either :
285 * - a second press on the button that made us enter
286 * - an action taken while pressing the enter button,
287 * then release the enter button*/
288 bool can_quit
= false;
289 gui_syncstatusbar_draw(&statusbars
, true);
292 screens
[i
].set_viewport(NULL
);
293 screens
[i
].stop_scroll();
294 viewport_set_defaults(&vp
[i
], i
);
295 quickscreen_fix_viewports(qs
, &screens
[i
], &vp
[i
]);
296 gui_quickscreen_draw(qs
, &screens
[i
], &vp
[i
]);
298 /* Announce current selection on entering this screen. This is all
299 queued up, but can be interrupted as soon as a setting is
301 cond_talk_ids(VOICE_QUICKSCREEN
);
302 talk_qs_option((struct settings_list
*)qs
->items
[QUICKSCREEN_LEFT
], true);
303 talk_qs_option((struct settings_list
*)qs
->items
[QUICKSCREEN_BOTTOM
], true);
304 talk_qs_option((struct settings_list
*)qs
->items
[QUICKSCREEN_RIGHT
], true);
306 button
= get_action(CONTEXT_QUICKSCREEN
,HZ
/5);
307 if(default_event_handler(button
) == SYS_USB_CONNECTED
)
309 if(gui_quickscreen_do_button(qs
, button
))
314 gui_quickscreen_draw(qs
, &screens
[i
], &vp
[i
]);
318 else if(button
==button_enter
)
321 if((button
== button_enter
) && can_quit
)
324 if(button
==ACTION_STD_CANCEL
)
327 gui_syncstatusbar_draw(&statusbars
, false);
329 /* Notify that we're exiting this screen */
330 cond_talk_ids_fq(VOICE_OK
);
334 bool quick_screen_quick(int button_enter
)
336 struct gui_quickscreen qs
;
337 bool oldshuffle
= global_settings
.playlist_shuffle
;
338 int oldrepeat
= global_settings
.repeat_mode
;
339 qs
.items
[QUICKSCREEN_LEFT
] =
340 find_setting(&global_settings
.playlist_shuffle
, NULL
);
341 qs
.items
[QUICKSCREEN_RIGHT
] =
342 find_setting(&global_settings
.repeat_mode
, NULL
);
343 qs
.items
[QUICKSCREEN_BOTTOM
] =
344 find_setting(&global_settings
.dirfilter
, NULL
);
346 if (gui_syncquickscreen_run(&qs
, button_enter
))
349 settings_apply(false);
350 /* make sure repeat/shuffle/any other nasty ones get updated */
351 if ( oldrepeat
!= global_settings
.repeat_mode
&&
352 (audio_status() & AUDIO_STATUS_PLAY
) )
354 audio_flush_and_reload_tracks();
356 if (oldshuffle
!= global_settings
.playlist_shuffle
357 && audio_status() & AUDIO_STATUS_PLAY
)
359 #if CONFIG_CODEC == SWCODEC
360 dsp_set_replaygain();
362 if (global_settings
.playlist_shuffle
)
363 playlist_randomise(NULL
, current_tick
, true);
365 playlist_sort(NULL
, true);
372 bool quick_screen_f3(int button_enter
)
374 struct gui_quickscreen qs
;
375 qs
.items
[QUICKSCREEN_LEFT
] =
376 find_setting(&global_settings
.scrollbar
, NULL
);
377 qs
.items
[QUICKSCREEN_RIGHT
] =
378 find_setting(&global_settings
.statusbar
, NULL
);
379 qs
.items
[QUICKSCREEN_BOTTOM
] =
380 find_setting(&global_settings
.flip_display
, NULL
);
382 if (gui_syncquickscreen_run(&qs
, button_enter
))
385 settings_apply(false);
389 #endif /* BUTTON_F3 */