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 ****************************************************************************/
29 #include "statusbar.h"
31 #include "settings_list.h"
37 #include "quickscreen.h"
40 static struct viewport vps
[NB_SCREENS
][QUICKSCREEN_ITEM_COUNT
];
41 static struct viewport vp_icons
[NB_SCREENS
];
42 /* vp_icons will be used like this:
43 the side icons will be aligned to the top of this vp and to their sides
44 the bottom icon wil be aligned center and at the bottom of this vp */
47 #define MAX_NEEDED_LINES 8
48 #define CENTER_MARGIN 10 /* pixels between the 2 center items minimum */
49 #define CENTER_ICONAREA_WIDTH (CENTER_MARGIN+8*2)
51 static void quickscreen_fix_viewports(struct gui_quickscreen
*qs
,
52 struct screen
*display
,
53 struct viewport
*parent
)
55 int char_height
, i
, screen
= display
->screen_type
;
56 int left_width
, right_width
, bottom_lines
= 3;
58 int nb_lines
= viewport_get_nb_lines(parent
);
59 char_height
= parent
->height
/nb_lines
;
61 vp_icons
[screen
] = *parent
;
63 vps
[screen
][QUICKSCREEN_BOTTOM
] = *parent
;
64 if (nb_lines
<= MIN_LINES
) /* make the bottom item use 1 line */
68 vps
[screen
][QUICKSCREEN_BOTTOM
].height
= bottom_lines
*char_height
;
69 vps
[screen
][QUICKSCREEN_BOTTOM
].y
= parent
->y
+ parent
->height
- bottom_lines
*char_height
;
70 if (nb_lines
>= MAX_NEEDED_LINES
)
72 vps
[screen
][QUICKSCREEN_BOTTOM
].y
-= char_height
;
75 /* adjust the left/right items widths to fit the screen nicely */
76 s
= P2STR(ID2P(qs
->items
[QUICKSCREEN_LEFT
]->lang_id
));
77 left_width
= display
->getstringsize(s
, NULL
, NULL
);
78 s
= P2STR(ID2P(qs
->items
[QUICKSCREEN_RIGHT
]->lang_id
));
79 right_width
= display
->getstringsize(s
, NULL
, NULL
);
80 nb_lines
-= bottom_lines
;
82 vps
[screen
][QUICKSCREEN_LEFT
] = *parent
;
83 vps
[screen
][QUICKSCREEN_RIGHT
] = *parent
;
84 vps
[screen
][QUICKSCREEN_LEFT
].x
= parent
->x
;
85 if (nb_lines
<= MIN_LINES
)
89 vps
[screen
][QUICKSCREEN_LEFT
].y
= parent
->y
+ (i
*char_height
);
90 vps
[screen
][QUICKSCREEN_RIGHT
].y
= parent
->y
+ (i
*char_height
);
94 i
= nb_lines
*char_height
;
96 vps
[screen
][QUICKSCREEN_LEFT
].height
= i
;
97 vps
[screen
][QUICKSCREEN_RIGHT
].height
= i
;
98 vp_icons
[screen
].y
= vps
[screen
][QUICKSCREEN_LEFT
].y
+ (char_height
/2);
99 vp_icons
[screen
].height
= vps
[screen
][QUICKSCREEN_BOTTOM
].y
- vp_icons
[screen
].y
;
101 if (left_width
+ right_width
> display
->width
- CENTER_MARGIN
) /* scrolling needed */
103 int width
= (parent
->width
- CENTER_ICONAREA_WIDTH
)/2;
104 vps
[screen
][QUICKSCREEN_LEFT
].width
= width
;
105 vps
[screen
][QUICKSCREEN_RIGHT
].width
= width
;
106 vps
[screen
][QUICKSCREEN_RIGHT
].x
= parent
->x
+parent
->width
- width
;
107 vp_icons
[screen
].x
= parent
->x
+ width
;
108 vp_icons
[screen
].width
= CENTER_ICONAREA_WIDTH
;
113 if (left_width
> right_width
)
117 width
+= CENTER_MARGIN
;
118 if (width
*2 < parent
->width
/2)
120 width
+= parent
->width
/6;
121 /* add some padding on the edges */
124 vps
[screen
][QUICKSCREEN_LEFT
].width
= width
;
125 vps
[screen
][QUICKSCREEN_RIGHT
].width
= width
;
126 vps
[screen
][QUICKSCREEN_RIGHT
].x
= parent
->x
+ parent
->width
- width
;
127 vp_icons
[screen
].x
= parent
->x
+ width
;
130 vp_icons
[screen
].x
+= pad
;
131 vps
[screen
][QUICKSCREEN_LEFT
].x
+= pad
;
132 vps
[screen
][QUICKSCREEN_RIGHT
].x
-= pad
;
133 /* need to add the pad to the bottom to make it all centered nicely */
134 vps
[screen
][QUICKSCREEN_BOTTOM
].x
+= pad
;
135 vps
[screen
][QUICKSCREEN_BOTTOM
].width
-= pad
;
137 vp_icons
[screen
].width
= vps
[screen
][QUICKSCREEN_RIGHT
].x
- width
;
142 static void quickscreen_draw_text(char *s
, int item
, bool title
,
143 struct screen
*display
, struct viewport
*vp
)
145 int nb_lines
= viewport_get_nb_lines(vp
);
146 int w
, h
, line
= 0, x
=0;
147 display
->getstringsize(s
, &w
, &h
);
149 if (nb_lines
> 1 && !title
)
153 case QUICKSCREEN_BOTTOM
:
154 x
= (vp
->width
- w
)/2;
156 case QUICKSCREEN_LEFT
:
159 case QUICKSCREEN_RIGHT
:
164 display
->puts_scroll(0,line
,s
);
166 display
->putsxy(x
, line
*h
, s
);
169 static void gui_quickscreen_draw(struct gui_quickscreen
*qs
,
170 struct screen
*display
,
171 struct viewport
*parent
)
175 unsigned char *title
, *value
;
178 display
->set_viewport(parent
);
179 display
->clear_viewport();
180 for (i
=0; i
<QUICKSCREEN_ITEM_COUNT
; i
++)
185 display
->set_viewport(&vps
[display
->screen_type
][i
]);
186 display
->scroll_stop(&vps
[display
->screen_type
][i
]);
188 title
= P2STR(ID2P(qs
->items
[i
]->lang_id
));
189 setting
= qs
->items
[i
]->setting
;
190 if ((qs
->items
[i
]->flags
& F_BOOL_SETTING
) == F_BOOL_SETTING
)
191 temp
= *(bool*)setting
?1:0;
193 temp
= *(int*)setting
;
194 value
= option_get_valuestring((struct settings_list
*)qs
->items
[i
], buf
, MAX_PATH
, temp
);
196 if (vps
[display
->screen_type
][i
].height
< display
->char_height
*2)
199 snprintf(text
, MAX_PATH
, "%s: %s", title
, value
);
200 quickscreen_draw_text(text
, i
, true, display
, &vps
[display
->screen_type
][i
]);
204 quickscreen_draw_text(title
, i
, true, display
, &vps
[display
->screen_type
][i
]);
205 quickscreen_draw_text(value
, i
, false, display
, &vps
[display
->screen_type
][i
]);
207 display
->update_viewport();
210 display
->set_viewport(&vp_icons
[display
->screen_type
]);
211 display
->mono_bitmap(bitmap_icons_7x8
[Icon_FastForward
],
212 vp_icons
[display
->screen_type
].width
- 8, 0, 7, 8);
213 display
->mono_bitmap(bitmap_icons_7x8
[Icon_FastBackward
], 0, 0, 7, 8);
214 display
->mono_bitmap(bitmap_icons_7x8
[Icon_DownArrow
],
215 (vp_icons
[display
->screen_type
].width
/2) - 4,
216 vp_icons
[display
->screen_type
].height
- 7, 7, 8);
217 display
->update_viewport();
219 display
->set_viewport(parent
);
220 display
->update_viewport();
221 display
->set_viewport(NULL
);
224 static int option_value(const struct settings_list
*setting
)
226 if ((setting
->flags
& F_BOOL_SETTING
) == F_BOOL_SETTING
)
228 return *(bool*)setting
->setting
==true?1:0;
231 return *(int*)setting
->setting
;
234 static void talk_qs_option(struct settings_list
*opt
, bool enqueue
)
236 if (global_settings
.talk_menu
) {
239 talk_id(opt
->lang_id
, true);
240 option_talk_value(opt
, option_value(opt
), true);
245 * Does the actions associated to the given button if any
246 * - qs : the quickscreen
247 * - button : the key we are going to analyse
248 * returns : true if the button corresponded to an action, false otherwise
250 static bool gui_quickscreen_do_button(struct gui_quickscreen
* qs
, int button
)
256 item
= QUICKSCREEN_LEFT
;
260 case ACTION_QS_DOWNINV
:
261 item
= QUICKSCREEN_BOTTOM
;
264 case ACTION_QS_RIGHT
:
265 item
= QUICKSCREEN_RIGHT
;
271 option_select_next_val((struct settings_list
*)qs
->items
[item
], false, true);
272 talk_qs_option((struct settings_list
*)qs
->items
[item
], false);
276 bool gui_syncquickscreen_run(struct gui_quickscreen
* qs
, int button_enter
)
279 struct viewport vp
[NB_SCREENS
];
280 bool changed
= false;
281 /* To quit we need either :
282 * - a second press on the button that made us enter
283 * - an action taken while pressing the enter button,
284 * then release the enter button*/
286 gui_syncstatusbar_draw(&statusbars
, true);
289 screens
[i
].set_viewport(NULL
);
290 screens
[i
].stop_scroll();
291 viewport_set_defaults(&vp
[i
], i
);
292 quickscreen_fix_viewports(qs
, &screens
[i
], &vp
[i
]);
293 gui_quickscreen_draw(qs
, &screens
[i
], &vp
[i
]);
295 /* Announce current selection on entering this screen. This is all
296 queued up, but can be interrupted as soon as a setting is
298 cond_talk_ids(VOICE_QUICKSCREEN
);
299 talk_qs_option((struct settings_list
*)qs
->items
[QUICKSCREEN_LEFT
], true);
300 talk_qs_option((struct settings_list
*)qs
->items
[QUICKSCREEN_BOTTOM
], true);
301 talk_qs_option((struct settings_list
*)qs
->items
[QUICKSCREEN_RIGHT
], true);
303 button
= get_action(CONTEXT_QUICKSCREEN
,HZ
/5);
304 if(default_event_handler(button
) == SYS_USB_CONNECTED
)
306 if(gui_quickscreen_do_button(qs
, button
))
311 gui_quickscreen_draw(qs
, &screens
[i
], &vp
[i
]);
315 else if(button
==button_enter
)
318 if((button
== button_enter
) && can_quit
)
321 if(button
==ACTION_STD_CANCEL
)
324 gui_syncstatusbar_draw(&statusbars
, false);
326 /* Notify that we're exiting this screen */
327 cond_talk_ids_fq(VOICE_OK
);
331 bool quick_screen_quick(int button_enter
)
333 struct gui_quickscreen qs
;
334 bool oldshuffle
= global_settings
.playlist_shuffle
;
335 int oldrepeat
= global_settings
.repeat_mode
;
336 qs
.items
[QUICKSCREEN_LEFT
] = find_setting(&global_settings
.playlist_shuffle
, NULL
);
337 qs
.items
[QUICKSCREEN_RIGHT
] = find_setting(&global_settings
.repeat_mode
, NULL
);
338 qs
.items
[QUICKSCREEN_BOTTOM
] = find_setting(&global_settings
.dirfilter
, NULL
);
340 if (gui_syncquickscreen_run(&qs
, button_enter
))
343 settings_apply(false);
344 /* make sure repeat/shuffle/any other nasty ones get updated */
345 if ( oldrepeat
!= global_settings
.repeat_mode
&&
346 (audio_status() & AUDIO_STATUS_PLAY
) )
348 audio_flush_and_reload_tracks();
350 if (oldshuffle
!= global_settings
.playlist_shuffle
351 && audio_status() & AUDIO_STATUS_PLAY
)
353 #if CONFIG_CODEC == SWCODEC
354 dsp_set_replaygain();
356 if (global_settings
.playlist_shuffle
)
357 playlist_randomise(NULL
, current_tick
, true);
359 playlist_sort(NULL
, true);
366 bool quick_screen_f3(int button_enter
)
368 struct gui_quickscreen qs
;
369 qs
.items
[QUICKSCREEN_LEFT
] = find_setting(&global_settings
.scrollbar
, NULL
);
370 qs
.items
[QUICKSCREEN_RIGHT
] = find_setting(&global_settings
.statusbar
, NULL
);
371 qs
.items
[QUICKSCREEN_BOTTOM
] = find_setting(&global_settings
.flip_display
, NULL
);
373 if (gui_syncquickscreen_run(&qs
, button_enter
))
376 settings_apply(false);
380 #endif /* BUTTON_F3 */