diff --git a/apps/SOURCES b/apps/SOURCES index 0408c32..945c22a 100644 --- a/apps/SOURCES +++ b/apps/SOURCES @@ -78,6 +78,7 @@ gui/quickscreen.c #endif gui/wps.c +gui/statusbar-skinned.c gui/scrollbar.c gui/splash.c gui/statusbar.c diff --git a/apps/filetree.c b/apps/filetree.c index ec79324..c7f563d 100644 --- a/apps/filetree.c +++ b/apps/filetree.c @@ -482,7 +482,26 @@ int ft_enter(struct tree_context* c) break; #endif - +#ifdef HAVE_LCD_BITMAP + case FILE_ATTR_SBS: + splash(0, ID2P(LANG_WAIT)); + set_file(buf, (char *)global_settings.sbs_file, + MAX_FILENAME); + global_settings.statusbar = STATUSBAR_CUSTOM; + settings_apply_skins(); + viewportmanager_theme_changed(THEME_STATUSBAR); + break; +#endif +#ifdef HAVE_REMOTE_LCD + case FILE_ATTR_RSBS: + splash(0, ID2P(LANG_WAIT)); + set_file(buf, (char *)global_settings.rsbs_file, + MAX_FILENAME); + global_settings.remote_statusbar = STATUSBAR_CUSTOM; + settings_apply_skins(); + viewportmanager_theme_changed(THEME_STATUSBAR); + break; +#endif /* wps config file */ case FILE_ATTR_WPS: splash(0, ID2P(LANG_WAIT)); diff --git a/apps/filetypes.c b/apps/filetypes.c index ffa7161..bd24fab 100644 --- a/apps/filetypes.c +++ b/apps/filetypes.c @@ -108,6 +108,12 @@ static const struct filetype inbuilt_filetypes[] = { #endif { "bmark",FILE_ATTR_BMARK, Icon_Bookmark, VOICE_EXT_BMARK }, { "cue", FILE_ATTR_CUE, Icon_Bookmark, VOICE_EXT_CUESHEET }, +#ifdef HAVE_LCD_BITMAP + { "sbs", FILE_ATTR_SBS, Icon_Wps, VOICE_EXT_SBS }, +#endif +#ifdef HAVE_REMOTE_LCD + { "rsbs", FILE_ATTR_RSBS, Icon_Wps, VOICE_EXT_RSBS }, +#endif #ifdef BOOTFILE_EXT { BOOTFILE_EXT, FILE_ATTR_MOD, Icon_Firmware, VOICE_EXT_AJZ }, #endif diff --git a/apps/filetypes.h b/apps/filetypes.h index f872cf8..d3846b0 100644 --- a/apps/filetypes.h +++ b/apps/filetypes.h @@ -41,6 +41,8 @@ #define FILE_ATTR_KBD 0x0C00 /* keyboard file */ #define FILE_ATTR_FMR 0x0D00 /* preset file */ #define FILE_ATTR_CUE 0x0E00 /* cuesheet file */ +#define FILE_ATTR_SBS 0x0F00 /* statusbar file */ +#define FILE_ATTR_RSBS 0x1000 /* remote statusbar file */ #define FILE_ATTR_MASK 0xFF00 /* which bits tree.c uses for file types */ struct filetype { diff --git a/apps/gui/list.c b/apps/gui/list.c index 9b139dd..85b220d 100644 --- a/apps/gui/list.c +++ b/apps/gui/list.c @@ -29,6 +29,7 @@ #include "kernel.h" #include "system.h" +#include "appevents.h" #include "action.h" #include "screen_access.h" #include "list.h" diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c index 0a43a19..90265bc 100644 --- a/apps/gui/skin_engine/skin_display.c +++ b/apps/gui/skin_engine/skin_display.c @@ -64,6 +64,7 @@ #include "wps_internals.h" #include "skin_engine.h" +#include "statusbar-skinned.h" static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode); @@ -105,7 +106,6 @@ bool gui_wps_display(struct gui_wps *gwps) vp->bg_pattern = display->get_background(); } #endif - display->clear_display(); display->backdrop_show(BACKDROP_SKIN_WPS); return skin_redraw(gwps, WPS_REFRESH_ALL); } @@ -137,28 +137,30 @@ void skin_statusbar_changed(struct gui_wps *skin) return; struct wps_data *data = skin->data; const struct screen *display = skin->display; + const int screen = display->screen_type; struct viewport *vp = &find_viewport(VP_DEFAULT_LABEL, data)->vp; - viewport_set_fullscreen(vp, display->screen_type); + viewport_set_fullscreen(vp, screen); if (data->wps_sb_tag) { /* fix up the default viewport */ if (data->show_sb_on_wps) { - bool bar_at_top = - statusbar_position(display->screen_type) != STATUSBAR_BOTTOM; + if (statusbar_position(screen) != STATUSBAR_OFF) + return; /* vp is fixed already */ - vp->y = bar_at_top?STATUSBAR_HEIGHT:0; + vp->y = STATUSBAR_HEIGHT; vp->height = display->lcdheight - STATUSBAR_HEIGHT; } else { - vp->y = 0; + if (statusbar_position(screen) == STATUSBAR_OFF) + return; /* vp is fixed already */ + vp->y = vp->x = 0; vp->height = display->lcdheight; + vp->width = display->lcdwidth; } } - - } static void draw_progressbar(struct gui_wps *gwps, @@ -167,6 +169,7 @@ static void draw_progressbar(struct gui_wps *gwps, struct screen *display = gwps->display; struct wps_state *state = gwps->state; struct progressbar *pb = wps_vp->pb; + struct mp3entry *id3 = state->id3; int y = pb->y; if (y < 0) @@ -178,27 +181,37 @@ static void draw_progressbar(struct gui_wps *gwps, y = (-y -1)*line_height + (0 > center ? 0 : center); } + int elapsed, length; + if (id3) + { + elapsed = id3->elapsed; + length = id3->length; + } + else + { + elapsed = 0; + length = 0; + } + if (pb->have_bitmap_pb) gui_bitmap_scrollbar_draw(display, pb->bm, - pb->x, y, pb->width, pb->bm.height, - state->id3->length ? state->id3->length : 1, 0, - state->id3->length ? state->id3->elapsed - + state->ff_rewind_count : 0, - HORIZONTAL); + pb->x, y, pb->width, pb->bm.height, + length ? length : 1, 0, + length ? elapsed + state->ff_rewind_count : 0, + HORIZONTAL); else gui_scrollbar_draw(display, pb->x, y, pb->width, pb->height, - state->id3->length ? state->id3->length : 1, 0, - state->id3->length ? state->id3->elapsed - + state->ff_rewind_count : 0, - HORIZONTAL); + length ? length : 1, 0, + length ? elapsed + state->ff_rewind_count : 0, + HORIZONTAL); #ifdef AB_REPEAT_ENABLE - if ( ab_repeat_mode_enabled() && state->id3->length != 0 ) - ab_draw_markers(display, state->id3->length, + if ( ab_repeat_mode_enabled() && length != 0 ) + ab_draw_markers(display, length, pb->x, pb->x + pb->width, y, pb->height); #endif - if (state->id3->cuesheet) - cue_draw_markers(display, state->id3->cuesheet, state->id3->length, + if (id3 && id3->cuesheet) + cue_draw_markers(display, state->id3->cuesheet, length, pb->x, pb->x + pb->width, y+1, pb->height-2); } @@ -277,12 +290,20 @@ static bool draw_player_progress(struct gui_wps *gwps) int pos = 0; int i; - if (!state->id3) - return false; + int elapsed, length; + if (LIKELY(state->id3)) + { + elapsed = state->id3->elapsed; + length = state->id3->length; + } + else + { + elapsed = 0; + length = 0; + } - if (state->id3->length) - pos = 36 * (state->id3->elapsed + state->ff_rewind_count) - / state->id3->length; + if (length) + pos = 36 * (elapsed + state->ff_rewind_count) / length; for (i = 0; i < 7; i++, pos -= 5) { @@ -325,12 +346,24 @@ static void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size) int digit, i, j; bool softchar; - if (!state->id3 || buf_size < 34) /* worst case: 11x UTF-8 char + \0 */ + int elapsed, length; + if (LIKELY(state->id3)) + { + elapsed = id3->elapsed; + length = id3->length; + } + else + { + elapsed = 0; + length = 0; + } + + if (buf_size < 34) /* worst case: 11x UTF-8 char + \0 */ return; - time = state->id3->elapsed + state->ff_rewind_count; - if (state->id3->length) - pos = 55 * time / state->id3->length; + time = elapsed + state->ff_rewind_count; + if (length) + pos = 55 * time / length; memset(timestr, 0, sizeof(timestr)); format_time(timestr, sizeof(timestr)-2, time); @@ -461,7 +494,12 @@ static bool evaluate_conditional(struct gui_wps *gwps, int *token_index) #ifdef HAVE_LCD_BITMAP /* clear all pictures in the conditional and nested ones */ if (data->tokens[i].type == WPS_TOKEN_IMAGE_PRELOAD_DISPLAY) - clear_image_pos(gwps, find_image(data->tokens[i].value.i&0xFF, gwps->data)); + { + struct gui_img *tmp = find_image(data->tokens[i].value.i&0xFF, + data); + if (tmp) + clear_image_pos(gwps, tmp); + } #endif #ifdef HAVE_ALBUMART if (data->tokens[i].type == WPS_TOKEN_ALBUMART_DISPLAY) @@ -471,6 +509,7 @@ static bool evaluate_conditional(struct gui_wps *gwps, int *token_index) return true; } + #ifdef HAVE_LCD_BITMAP struct gui_img* find_image(char label, struct wps_data *data) { @@ -497,9 +536,8 @@ struct skin_viewport* find_viewport(char label, struct wps_data *data) list = list->next; } return NULL; -} - - +} + /* Read a (sub)line to the given alignment format buffer. linebuf is the buffer where the data is actually stored. align is the alignment format that'll be used to display the text. @@ -881,14 +919,8 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode) { struct wps_data *data = gwps->data; struct screen *display = gwps->display; - struct wps_state *state = gwps->state; - - if (!data || !state || !display) - return false; - - struct mp3entry *id3 = state->id3; - if (!id3) + if (!data || !display || !gwps->state) return false; unsigned flags; @@ -921,15 +953,19 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode) if (refresh_mode == WPS_REFRESH_ALL) { struct skin_line *line; - - display->set_viewport(&find_viewport(VP_DEFAULT_LABEL, data)->vp); - display->clear_viewport(); - + struct skin_viewport *skin_viewport = find_viewport(VP_DEFAULT_LABEL, data); + + if (!(skin_viewport->hidden_flags & VP_NEVER_VISIBLE)) + { + display->set_viewport(&skin_viewport->vp); + display->clear_viewport(); + } + for (viewport_list = data->viewports; viewport_list; viewport_list = viewport_list->next) { - struct skin_viewport *skin_viewport = - (struct skin_viewport *)viewport_list->token->value.data; + skin_viewport = + (struct skin_viewport *)viewport_list->token->value.data; for(line = skin_viewport->lines; line; line = line->next) { line->curr_subline = NULL; @@ -952,6 +988,10 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode) { struct skin_viewport *skin_viewport = (struct skin_viewport *)viewport_list->token->value.data; + if (skin_viewport->hidden_flags&VP_NEVER_VISIBLE) + { + continue; + } if (skin_viewport->hidden_flags&VP_DRAW_HIDEABLE) { if (skin_viewport->hidden_flags&VP_DRAW_HIDDEN) @@ -967,8 +1007,11 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode) struct skin_viewport *skin_viewport = (struct skin_viewport *)viewport_list->token->value.data; unsigned vp_refresh_mode = refresh_mode; + display->set_viewport(&skin_viewport->vp); + int hidden_vp = 0; + #ifdef HAVE_LCD_BITMAP /* Set images to not to be displayed */ struct skin_token_list *imglist = data->images; @@ -980,7 +1023,11 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode) } #endif /* dont redraw the viewport if its disabled */ - if ((skin_viewport->hidden_flags&VP_DRAW_HIDDEN)) + if (skin_viewport->hidden_flags&VP_NEVER_VISIBLE) + { /* don't draw anything into this one */ + vp_refresh_mode = 0; hidden_vp = true; + } + else if ((skin_viewport->hidden_flags&VP_DRAW_HIDDEN)) { if (!(skin_viewport->hidden_flags&VP_DRAW_WASHIDDEN)) display->scroll_stop(&skin_viewport->vp); @@ -994,6 +1041,7 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode) vp_refresh_mode = WPS_REFRESH_ALL; skin_viewport->hidden_flags = VP_DRAW_HIDEABLE; } + if (vp_refresh_mode == WPS_REFRESH_ALL) { display->clear_viewport(); @@ -1015,7 +1063,7 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode) flags = line->curr_subline->line_type; if (vp_refresh_mode == WPS_REFRESH_ALL || (flags & vp_refresh_mode) - || new_subline_refresh) + || new_subline_refresh || hidden_vp) { /* get_line tells us if we need to update the line */ update_line = get_line(gwps, subline, @@ -1061,7 +1109,7 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode) } #endif - if (update_line && + if (update_line && !hidden_vp && /* conditionals clear the line which means if the %Vd is put into the default viewport there will be a blank line. To get around this we dont allow any actual drawing to happen in the @@ -1080,7 +1128,6 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode) write_line(display, &align, line_count, false); } } - #ifdef HAVE_LCD_BITMAP /* progressbar */ if (vp_refresh_mode & WPS_REFRESH_PLAYER_PROGRESS) @@ -1091,7 +1138,8 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode) } } /* Now display any images in this viewport */ - wps_display_images(gwps, &skin_viewport->vp); + if (!hidden_vp) + wps_display_images(gwps, &skin_viewport->vp); #endif } diff --git a/apps/gui/skin_engine/skin_engine.h b/apps/gui/skin_engine/skin_engine.h index c52f720..704a785 100644 --- a/apps/gui/skin_engine/skin_engine.h +++ b/apps/gui/skin_engine/skin_engine.h @@ -27,7 +27,6 @@ #include "wps_internals.h" /* TODO: remove this line.. shoudlnt be needed */ - #ifdef HAVE_TOUCHSCREEN int wps_get_touchaction(struct wps_data *data); #endif @@ -44,7 +43,6 @@ bool skin_update(struct gui_wps *gwps, unsigned int update_type); * or from a skinfile (isfile = true) */ bool skin_data_load(struct wps_data *wps_data, - struct screen *display, const char *buf, bool isfile); diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index 07f38bb..cdc8c31 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c @@ -674,7 +674,13 @@ static int parse_viewport(const char *wps_bufptr, return WPS_ERROR_INVALID_PARAM; - if (*ptr == 'l') + if (*ptr == 'i') + { + skin_vp->label = VP_INFO_LABEL; + skin_vp->hidden_flags = VP_NEVER_VISIBLE; + ++ptr; + } + else if (*ptr == 'l') { if (*(ptr+1) == '|') { @@ -1611,7 +1617,6 @@ static bool load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char else { /* Abort if we can't load an image */ - DEBUGF("ERR: Failed to load image - %s\n",img_path); loaded = false; } return loaded; @@ -1670,7 +1675,6 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir) /* to setup up the wps-data from a format-buffer (isfile = false) from a (wps-)file (isfile = true)*/ bool skin_data_load(struct wps_data *wps_data, - struct screen *display, const char *buf, bool isfile) { @@ -1682,11 +1686,13 @@ bool skin_data_load(struct wps_data *wps_data, int albumart_max_height = wps_data->albumart_max_height; int albumart_max_width = wps_data->albumart_max_width; #endif + if (!wps_data || !buf) return false; wps_reset(wps_data); - + + /* alloc default viewport, will be fixed up later */ curr_vp = skin_buffer_alloc(sizeof(struct skin_viewport)); if (!curr_vp) return false; @@ -1698,9 +1704,6 @@ bool skin_data_load(struct wps_data *wps_data, /* Initialise the first (default) viewport */ curr_vp->label = VP_DEFAULT_LABEL; - curr_vp->vp.x = 0; - curr_vp->vp.width = display->getwidth(); - curr_vp->vp.height = display->getheight(); curr_vp->pb = NULL; curr_vp->hidden_flags = 0; curr_vp->lines = NULL; @@ -1708,32 +1711,7 @@ bool skin_data_load(struct wps_data *wps_data, curr_line = NULL; if (!skin_start_new_line(curr_vp, 0)) return false; - - switch (statusbar_position(display->screen_type)) - { - case STATUSBAR_OFF: - curr_vp->vp.y = 0; - break; - case STATUSBAR_TOP: - curr_vp->vp.y = STATUSBAR_HEIGHT; - curr_vp->vp.height -= STATUSBAR_HEIGHT; - break; - case STATUSBAR_BOTTOM: - curr_vp->vp.y = 0; - curr_vp->vp.height -= STATUSBAR_HEIGHT; - break; - } -#ifdef HAVE_LCD_BITMAP - curr_vp->vp.font = FONT_UI; - curr_vp->vp.drawmode = DRMODE_SOLID; -#endif -#if LCD_DEPTH > 1 - if (display->depth > 1) - { - curr_vp->vp.fg_pattern = display->get_foreground(); - curr_vp->vp.bg_pattern = display->get_background(); - } -#endif + if (!isfile) { return wps_parse(wps_data, buf, false); diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c index 1254900..9db5178 100644 --- a/apps/gui/skin_engine/skin_tokens.c +++ b/apps/gui/skin_engine/skin_tokens.c @@ -59,7 +59,7 @@ static char* get_codectype(const struct mp3entry* id3) { - if (id3->codectype < AFMT_NUM_CODECS) { + if (id3 && id3->codectype < AFMT_NUM_CODECS) { return (char*)audio_formats[id3->codectype].label; } else { return NULL; @@ -115,6 +115,28 @@ static char* get_dir(char* buf, int buf_size, const char* path, int level) and the original value of *intval, inclusive). When not treating a conditional/enum, intval should be NULL. */ + +/* a few macros for the id3 == NULL case */ + +#define HANDLE_NULL_ID3(field) (LIKELY(id3) ? id3->field : na) + +#define HANDLE_NULL_ID3_NUM_ZERO { if (UNLIKELY(!id3)) return zero; } + +#define HANDLE_NULL_ID3_NUM_NULL { if (UNLIKELY(!id3)) return zero; } + +#define HANDLE_NULL_ID3_NUM_INTVAL(field) \ + do { \ + if (intval) { \ + *intval = (LIKELY(id3) ? id3->field + 1 : 0); \ + } \ + if (LIKELY(id3)) \ + { \ + snprintf(buf, buf_size, "%ld", id3->field); \ + return buf; \ + } \ + return zero; \ + } while (0) + const char *get_token_value(struct gui_wps *gwps, struct wps_token *token, char *buf, int buf_size, @@ -125,6 +147,9 @@ const char *get_token_value(struct gui_wps *gwps, struct wps_data *data = gwps->data; struct wps_state *state = gwps->state; + int elapsed, length; + static const char * const na = "n/a"; + static const char * const zero = "0"; if (!data || !state) return NULL; @@ -136,8 +161,16 @@ const char *get_token_value(struct gui_wps *gwps, else id3 = state->id3; - if (!id3) - return NULL; + if (id3) + { + elapsed = id3->elapsed; + length = id3->length; + } + else + { + elapsed = 0; + length = 0; + } #if CONFIG_RTC struct tm* tm = NULL; @@ -173,17 +206,17 @@ const char *get_token_value(struct gui_wps *gwps, case WPS_TOKEN_TRACK_TIME_ELAPSED: format_time(buf, buf_size, - id3->elapsed + state->ff_rewind_count); + elapsed + state->ff_rewind_count); return buf; case WPS_TOKEN_TRACK_TIME_REMAINING: format_time(buf, buf_size, - id3->length - id3->elapsed - + length - elapsed - state->ff_rewind_count); return buf; case WPS_TOKEN_TRACK_LENGTH: - format_time(buf, buf_size, id3->length); + format_time(buf, buf_size, length); return buf; case WPS_TOKEN_PLAYLIST_ENTRIES: @@ -230,37 +263,38 @@ const char *get_token_value(struct gui_wps *gwps, return buf; case WPS_TOKEN_TRACK_ELAPSED_PERCENT: - if (id3->length <= 0) + if (length <= 0) return NULL; if (intval) { - *intval = limit * (id3->elapsed + state->ff_rewind_count) - / id3->length + 1; + *intval = limit * (elapsed + state->ff_rewind_count) + / length + 1; } snprintf(buf, buf_size, "%d", - 100*(id3->elapsed + state->ff_rewind_count) / id3->length); + 100*(elapsed + state->ff_rewind_count) / length); return buf; case WPS_TOKEN_METADATA_ARTIST: - return id3->artist; + return HANDLE_NULL_ID3(artist); case WPS_TOKEN_METADATA_COMPOSER: - return id3->composer; + return HANDLE_NULL_ID3(composer); case WPS_TOKEN_METADATA_ALBUM: - return id3->album; + return HANDLE_NULL_ID3(album); case WPS_TOKEN_METADATA_ALBUM_ARTIST: - return id3->albumartist; + return HANDLE_NULL_ID3(albumartist); case WPS_TOKEN_METADATA_GROUPING: - return id3->grouping; + return HANDLE_NULL_ID3(grouping); case WPS_TOKEN_METADATA_GENRE: - return id3->genre_string; + return HANDLE_NULL_ID3(genre_string); case WPS_TOKEN_METADATA_DISC_NUMBER: + HANDLE_NULL_ID3_NUM_NULL; if (id3->disc_string) return id3->disc_string; if (id3->discnum) { @@ -270,6 +304,7 @@ const char *get_token_value(struct gui_wps *gwps, return NULL; case WPS_TOKEN_METADATA_TRACK_NUMBER: + HANDLE_NULL_ID3_NUM_NULL; if (id3->track_string) return id3->track_string; @@ -280,9 +315,10 @@ const char *get_token_value(struct gui_wps *gwps, return NULL; case WPS_TOKEN_METADATA_TRACK_TITLE: - return id3->title; + return HANDLE_NULL_ID3(title); case WPS_TOKEN_METADATA_VERSION: + HANDLE_NULL_ID3_NUM_NULL; switch (id3->id3version) { case ID3_VER_1_0: @@ -305,6 +341,7 @@ const char *get_token_value(struct gui_wps *gwps, } case WPS_TOKEN_METADATA_YEAR: + HANDLE_NULL_ID3_NUM_NULL; if( id3->year_string ) return id3->year_string; @@ -315,7 +352,7 @@ const char *get_token_value(struct gui_wps *gwps, return NULL; case WPS_TOKEN_METADATA_COMMENT: - return id3->comment; + return HANDLE_NULL_ID3(comment); #ifdef HAVE_ALBUMART case WPS_TOKEN_ALBUMART_DISPLAY: @@ -330,7 +367,7 @@ const char *get_token_value(struct gui_wps *gwps, #endif case WPS_TOKEN_FILE_BITRATE: - if(id3->bitrate) + if(id3 && id3->bitrate) snprintf(buf, buf_size, "%d", id3->bitrate); else return "?"; @@ -339,7 +376,9 @@ const char *get_token_value(struct gui_wps *gwps, case WPS_TOKEN_FILE_CODEC: if (intval) { - if(id3->codectype == AFMT_UNKNOWN) + if (UNLIKELY(!id3)) + *intval = 0; + else if(id3->codectype == AFMT_UNKNOWN) *intval = AFMT_NUM_CODECS; else *intval = id3->codectype; @@ -347,10 +386,12 @@ const char *get_token_value(struct gui_wps *gwps, return get_codectype(id3); case WPS_TOKEN_FILE_FREQUENCY: + HANDLE_NULL_ID3_NUM_ZERO; snprintf(buf, buf_size, "%ld", id3->frequency); return buf; case WPS_TOKEN_FILE_FREQUENCY_KHZ: + HANDLE_NULL_ID3_NUM_ZERO; /* ignore remainders < 100, so 22050 Hz becomes just 22k */ if ((id3->frequency % 1000) < 100) snprintf(buf, buf_size, "%ld", id3->frequency / 1000); @@ -361,6 +402,7 @@ const char *get_token_value(struct gui_wps *gwps, return buf; case WPS_TOKEN_FILE_NAME: + if (!id3) return na; if (get_dir(buf, buf_size, id3->path, 0)) { /* Remove extension */ char* sep = strrchr(buf, '.'); @@ -374,20 +416,24 @@ const char *get_token_value(struct gui_wps *gwps, } case WPS_TOKEN_FILE_NAME_WITH_EXTENSION: + if (!id3) return na; return get_dir(buf, buf_size, id3->path, 0); case WPS_TOKEN_FILE_PATH: - return id3->path; + return HANDLE_NULL_ID3(path); case WPS_TOKEN_FILE_SIZE: + HANDLE_NULL_ID3_NUM_ZERO; snprintf(buf, buf_size, "%ld", id3->filesize / 1024); return buf; case WPS_TOKEN_FILE_VBR: - return id3->vbr ? "(avg)" : NULL; + return (LIKELY(id3) && id3->vbr) ? "(avg)" : NULL; case WPS_TOKEN_FILE_DIRECTORY: - return get_dir(buf, buf_size, id3->path, token->value.i); + if (LIKELY(id3)) + return get_dir(buf, buf_size, id3->path, token->value.i); + return na; case WPS_TOKEN_BATTERY_PERCENT: { @@ -636,27 +682,16 @@ const char *get_token_value(struct gui_wps *gwps, return buf; #endif + #ifdef HAVE_TAGCACHE case WPS_TOKEN_DATABASE_PLAYCOUNT: - if (intval) { - *intval = id3->playcount + 1; - } - snprintf(buf, buf_size, "%ld", id3->playcount); - return buf; + HANDLE_NULL_ID3_NUM_INTVAL(playcount); case WPS_TOKEN_DATABASE_RATING: - if (intval) { - *intval = id3->rating + 1; - } - snprintf(buf, buf_size, "%d", id3->rating); - return buf; + HANDLE_NULL_ID3_NUM_INTVAL(rating); case WPS_TOKEN_DATABASE_AUTOSCORE: - if (intval) - *intval = id3->score + 1; - - snprintf(buf, buf_size, "%d", id3->score); - return buf; + HANDLE_NULL_ID3_NUM_INTVAL(score); #endif #if (CONFIG_CODEC == SWCODEC) @@ -674,9 +709,13 @@ const char *get_token_value(struct gui_wps *gwps, val = 1; /* off */ else { - int type = - get_replaygain_mode(id3->track_gain_string != NULL, + int type; + if (LIKELY(id3)) + type = get_replaygain_mode(id3->track_gain_string != NULL, id3->album_gain_string != NULL); + else + type = -1; + if (type < 0) val = 6; /* no tag */ else @@ -695,6 +734,7 @@ const char *get_token_value(struct gui_wps *gwps, case 6: return "+0.00 dB"; break; + /* due to above, coming here with !id3 shouldn't be possible */ case 2: case 4: strlcpy(buf, id3->track_gain_string, buf_size); diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h index d1674ac..25dc52e 100644 --- a/apps/gui/skin_engine/wps_internals.h +++ b/apps/gui/skin_engine/wps_internals.h @@ -191,11 +191,14 @@ struct skin_line { struct skin_line *next; }; -#define VP_DRAW_HIDEABLE 0x1 -#define VP_DRAW_HIDDEN 0x2 -#define VP_DRAW_WASHIDDEN 0x4 -#define VP_DEFAULT_LABEL '|' -#define VP_NO_LABEL '-' +#define VP_DRAW_HIDEABLE 0x1 +#define VP_DRAW_HIDDEN 0x2 +#define VP_DRAW_WASHIDDEN 0x4 +/* these are never drawn, nor cleared, i.e. just ignored */ +#define VP_NEVER_VISIBLE 0x8 +#define VP_DEFAULT_LABEL '|' +#define VP_NO_LABEL '-' +#define VP_INFO_LABEL '_' struct skin_viewport { struct viewport vp; /* The LCD viewport struct */ struct progressbar *pb; diff --git a/apps/gui/statusbar-skinned.c b/apps/gui/statusbar-skinned.c new file mode 100644 index 0000000..fb85984 --- /dev/null +++ b/apps/gui/statusbar-skinned.c @@ -0,0 +1,150 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 Thomas Martitz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "config.h" + +#include "system.h" +#include "settings.h" +#include "appevents.h" +#include "screens.h" +#include "screen_access.h" +#include "skin_engine/skin_engine.h" +#include "skin_engine/wps_internals.h" +#include "viewport.h" +#include "statusbar.h" +#include "debug.h" + + +/* currently only one wps_state is needed */ +extern struct wps_state wps_state; +static struct gui_wps sb_skin[NB_SCREENS]; +static struct wps_data sb_skin_data[NB_SCREENS]; + +/* initial setup of wps_data */ +static void sb_skin_update(void*); +static bool loaded_ok[NB_SCREENS] = { false }; +static int skinbars = 0; + +void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile) +{ + struct wps_data *data = sb_skin[screen].data; + + int success; + success = buf && skin_data_load(data, buf, isfile); + + if (success) + { /* hide the sb's default viewport because it has nasty effect with stuff + * not part of the statusbar, + * hence .sbs's without any other vps are unsupported*/ + struct skin_viewport *vp = find_viewport(VP_DEFAULT_LABEL, data); + struct skin_token_list *next_vp = data->viewports->next; + + if (!next_vp) + { /* no second viewport, let parsing fail */ + success = false; + } + /* hide this viewport, forever */ + vp->hidden_flags = VP_NEVER_VISIBLE; + } + + if (!success) + remove_event(GUI_EVENT_ACTIONUPDATE, sb_skin_update); + +#ifdef HAVE_REMOVE_LCD + data->remote_wps = !(screen == SCREEN_MAIN); +#endif + loaded_ok[screen] = success; +} + +void sb_skin_data_init(enum screen_type screen) +{ + skin_data_init(sb_skin[screen].data); +} + +struct viewport *sb_skin_get_info_vp(enum screen_type screen) +{ + return &find_viewport(VP_INFO_LABEL, sb_skin[screen].data)->vp; +} + +inline bool sb_skin_get_state(enum screen_type screen) +{ + return loaded_ok[screen] && (statusbar_position(screen) + == STATUSBAR_CUSTOM); +} + +void sb_skin_set_state(int state, enum screen_type screen) +{ + sb_skin[screen].state->do_full_update = true; + if (state) + { + skinbars |= VP_SB_ONSCREEN(screen); + } + else + { + skinbars &= ~VP_SB_ONSCREEN(screen); + } + + if (skinbars) + add_event(GUI_EVENT_ACTIONUPDATE, false, sb_skin_update); + else + remove_event(GUI_EVENT_ACTIONUPDATE, sb_skin_update); +} + +static void sb_skin_update(void* param) +{ + static long next_update = 0; + int i; + int forced_draw = param || sb_skin[SCREEN_MAIN].state->do_full_update; + if (TIME_AFTER(current_tick, next_update) || forced_draw) + { + FOR_NB_SCREENS(i) + { + if (sb_skin_get_state(i)) + { + skin_update(&sb_skin[i], forced_draw? + WPS_REFRESH_ALL : WPS_REFRESH_NON_STATIC); + } + } + next_update = current_tick + HZ/2; + sb_skin[SCREEN_MAIN].state->do_full_update = true; + } +} + +void sb_skin_init(void) +{ + int i; + FOR_NB_SCREENS(i) + { + skin_data_init(&sb_skin_data[i]); +#ifdef HAVE_ALBUMART + sb_skin_data[i].wps_uses_albumart = 0; +#endif +#ifdef HAVE_REMOTE_LCD + sb_skin_data[i].remote_wps = (i == SCREEN_REMOTE); +#endif + sb_skin[i].data = &sb_skin_data[i]; + sb_skin[i].display = &screens[i]; + /* Currently no seperate wps_state needed/possible + so use the only available ( "global" ) one */ + sb_skin[i].state = &wps_state; + sb_skin[i].statusbars = &skinbars; + } +} diff --git a/apps/gui/statusbar-skinned.h b/apps/gui/statusbar-skinned.h new file mode 100644 index 0000000..ca27211 --- /dev/null +++ b/apps/gui/statusbar-skinned.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 Thomas Martitz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include +#include +#include +#include "config.h" + +#ifndef __STATUSBAR_SKINNED_H__ +#define __STATUSBAR_SKINNED_H__ + + +void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile); +void sb_skin_data_init(enum screen_type screen); + +/* probably temporary, to shut the classic statusbar up */ +bool sb_skin_get_state(enum screen_type screen); +void sb_skin_set_state(int state, enum screen_type screen); +void sb_skin_init(void); +struct viewport *sb_skin_get_info_vp(enum screen_type screen); + +#ifdef HAVE_ALBUMART +bool sb_skin_uses_statusbar(int *width, int *height); +#endif + +#endif /* __STATUSBAR_SKINNED_H__ */ diff --git a/apps/gui/statusbar.c b/apps/gui/statusbar.c index 7a361e5..436ca68 100644 --- a/apps/gui/statusbar.c +++ b/apps/gui/statusbar.c @@ -187,6 +187,9 @@ void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw) { struct screen * display = bar->display; + if (!display) + return; + #ifdef HAVE_LCD_CHARCELLS int val; (void)force_redraw; /* The Player always has "redraw" */ diff --git a/apps/gui/statusbar.h b/apps/gui/statusbar.h index 84d3785..b25edbf 100644 --- a/apps/gui/statusbar.h +++ b/apps/gui/statusbar.h @@ -55,7 +55,8 @@ struct status_info { }; /* statusbar visibility/position, used for settings also */ -enum statusbar_values { STATUSBAR_OFF = 0, STATUSBAR_TOP, STATUSBAR_BOTTOM }; +enum statusbar_values { STATUSBAR_OFF = 0, STATUSBAR_TOP, STATUSBAR_BOTTOM, + STATUSBAR_CUSTOM }; struct gui_statusbar { diff --git a/apps/gui/viewport.c b/apps/gui/viewport.c index e05cd78..ad9d6d6 100644 --- a/apps/gui/viewport.c +++ b/apps/gui/viewport.c @@ -33,7 +33,9 @@ #include "viewport.h" #include "statusbar.h" #include "screen_access.h" +#include "statusbar-skinned.h" #include "appevents.h" +#include "debug.h" @@ -87,8 +89,9 @@ static bool showing_bars(enum screen_type screen) if (statusbar_enabled & VP_SB_ONSCREEN(screen)) { #ifdef HAVE_LCD_BITMAP - bool ignore = statusbar_enabled & VP_SB_IGNORE_SETTING(screen); - return ignore || (statusbar_position(screen)); + int ignore; + ignore = statusbar_enabled & VP_SB_IGNORE_SETTING(screen); + return ignore || (statusbar_position(screen) != STATUSBAR_OFF); #else return true; #endif @@ -102,19 +105,29 @@ void viewport_set_fullscreen(struct viewport *vp, enum screen_type screen) vp->width = screens[screen].lcdwidth; #ifdef HAVE_LCD_BITMAP - vp->drawmode = DRMODE_SOLID; - vp->font = FONT_UI; /* default to UI to discourage SYSFONT use */ - - vp->height = screens[screen].lcdheight; - if (statusbar_position(screen) != STATUSBAR_BOTTOM && showing_bars(screen)) - vp->y = STATUSBAR_HEIGHT; - else - vp->y = 0; + struct viewport *sb_skin_vp = sb_skin_get_info_vp(screen); + if (sb_skin_vp && sb_skin_get_state(screen) + && statusbar_enabled & VP_SB_ONSCREEN(screen)) + { + *vp = *sb_skin_vp; + } + else + { + if (statusbar_position(screen) != STATUSBAR_BOTTOM && showing_bars(screen)) + vp->y = STATUSBAR_HEIGHT; + else + vp->y = 0; #else - vp->y = 0; + { + vp->y = 0; #endif - vp->height = screens[screen].lcdheight - (showing_bars(screen)?STATUSBAR_HEIGHT:0); + vp->height = screens[screen].lcdheight + - (showing_bars(screen)?STATUSBAR_HEIGHT:0); + } +#ifdef HAVE_LCD_BITMAP + vp->font = FONT_UI; /* default to UI to discourage SYSFONT use */ + vp->drawmode = DRMODE_SOLID; #if LCD_DEPTH > 1 #ifdef HAVE_REMOTE_LCD /* We only need this test if there is a remote LCD */ @@ -134,6 +147,7 @@ void viewport_set_fullscreen(struct viewport *vp, enum screen_type screen) vp->bg_pattern = LCD_REMOTE_DEFAULT_BG; } #endif +#endif } void viewport_set_defaults(struct viewport *vp, enum screen_type screen) @@ -167,20 +181,26 @@ int viewportmanager_get_statusbar(void) int viewportmanager_set_statusbar(int enabled) { int old = statusbar_enabled; + int i; + statusbar_enabled = enabled; - if (enabled) + + FOR_NB_SCREENS(i) { - int i; - FOR_NB_SCREENS(i) + if (showing_bars(i) + && statusbar_position(i) != STATUSBAR_CUSTOM) { - if (showing_bars(i)) - gui_statusbar_draw(&statusbars.statusbars[i], true); + add_event(GUI_EVENT_ACTIONUPDATE, false, viewportmanager_redraw); + gui_statusbar_draw(&statusbars.statusbars[i], true); } - add_event(GUI_EVENT_ACTIONUPDATE, false, viewportmanager_redraw); + else + remove_event(GUI_EVENT_ACTIONUPDATE, viewportmanager_redraw); } - else + + FOR_NB_SCREENS(i) { - remove_event(GUI_EVENT_ACTIONUPDATE, viewportmanager_redraw); + sb_skin_set_state(showing_bars(i) + && statusbar_position(i) == STATUSBAR_CUSTOM, i); } return old; } @@ -191,7 +211,8 @@ static void viewportmanager_redraw(void* data) FOR_NB_SCREENS(i) { - if (showing_bars(i)) + if (showing_bars(i) + && statusbar_position(i) != STATUSBAR_CUSTOM) gui_statusbar_draw(&statusbars.statusbars[i], NULL != data); } } @@ -214,28 +235,19 @@ void viewportmanager_theme_changed(int which) /* reset the ui viewport */ FOR_NB_SCREENS(i) ui_vp_info.active[i] = retval & BIT_N(i); - - if (retval != 0) - add_event(GUI_EVENT_REFRESH, false, viewportmanager_ui_vp_changed); - else - remove_event(GUI_EVENT_REFRESH, viewportmanager_ui_vp_changed); /* and point to it */ ui_vp_info.vp = custom_vp; } - if (which & THEME_STATUSBAR) + if (which & (THEME_STATUSBAR)) { - statusbar_enabled = VP_SB_HIDE_ALL; - + statusbar_enabled = 0; FOR_NB_SCREENS(i) { if (statusbar_position(i) != STATUSBAR_OFF) statusbar_enabled |= VP_SB_ONSCREEN(i); } - if (statusbar_enabled != VP_SB_HIDE_ALL) - add_event(GUI_EVENT_ACTIONUPDATE, false, viewportmanager_redraw); - else - remove_event(GUI_EVENT_ACTIONUPDATE, viewportmanager_redraw); + viewportmanager_set_statusbar(statusbar_enabled); /* reposition viewport to fit statusbar, only if not using the ui vp */ @@ -245,6 +257,18 @@ void viewportmanager_theme_changed(int which) viewport_set_fullscreen(&custom_vp[i], i); } } + + int event_add = 0; + FOR_NB_SCREENS(i) + { + event_add = ui_vp_info.active[i]; + event_add |= (statusbar_position(i) == STATUSBAR_CUSTOM); + } + + if (event_add) + add_event(GUI_EVENT_REFRESH, false, viewportmanager_ui_vp_changed); + else + remove_event(GUI_EVENT_REFRESH, viewportmanager_ui_vp_changed); } static void viewportmanager_ui_vp_changed(void *param) @@ -257,10 +281,10 @@ static void viewportmanager_ui_vp_changed(void *param) FOR_NB_SCREENS(i) screens[i].clear_display(); /* redraw the statusbar if it was enabled */ - viewportmanager_set_statusbar(statusbar_enabled); + send_event(GUI_EVENT_ACTIONUPDATE, (void*)true); /* call the passed function which will redraw the content of * the current screen */ - if (param != NULL) + if (draw_func != NULL) draw_func(); FOR_NB_SCREENS(i) screens[i].update(); diff --git a/apps/gui/viewport.h b/apps/gui/viewport.h index 2ed138b..768df83 100644 --- a/apps/gui/viewport.h +++ b/apps/gui/viewport.h @@ -56,14 +56,14 @@ void viewport_set_defaults(struct viewport *vp, enum screen_type screen); */ -#define THEME_STATUSBAR (BIT_N(0)) -#define THEME_UI_VIEWPORT (BIT_N(1)) -#define THEME_ALL (~(0u)) - -#define VP_SB_HIDE_ALL 0 -#define VP_SB_ONSCREEN(screen) BIT_N(screen) -#define VP_SB_IGNORE_SETTING(screen) BIT_N(4+screen) -#define VP_SB_ALLSCREENS (VP_SB_ONSCREEN(0)|VP_SB_ONSCREEN(1)) +#define THEME_STATUSBAR (BIT_N(0)) +#define THEME_UI_VIEWPORT (BIT_N(1)) +#define THEME_ALL (~(0u)) + +#define VP_SB_HIDE_ALL 0 +#define VP_SB_ONSCREEN(screen) BIT_N(screen) +#define VP_SB_IGNORE_SETTING(screen) BIT_N(4+screen) +#define VP_SB_ALLSCREENS (VP_SB_ONSCREEN(0)|VP_SB_ONSCREEN(1)) /* * Initialize the viewportmanager, which in turns initializes the UI vp and diff --git a/apps/gui/wps.c b/apps/gui/wps.c index f624365..888ebec 100644 --- a/apps/gui/wps.c +++ b/apps/gui/wps.c @@ -31,7 +31,6 @@ #include "action.h" #include "kernel.h" #include "filetypes.h" -#include "debug.h" #include "sprintf.h" #include "settings.h" #include "skin_engine/skin_engine.h" @@ -81,7 +80,7 @@ /* this is for the viewportmanager */ static int wpsbars; /* currently only one wps_state is needed */ -static struct wps_state wps_state; +struct wps_state wps_state; static struct gui_wps gui_wps[NB_SCREENS]; static struct wps_data wps_datas[NB_SCREENS]; @@ -128,8 +127,8 @@ void wps_data_load(enum screen_type screen, const char *buf, bool isfile) #endif /* __PCTOOL__ */ - loaded_ok = buf && skin_data_load(gui_wps[screen].data, - &screens[screen], buf, isfile); + loaded_ok = buf && skin_data_load(gui_wps[screen].data, buf, isfile); + if (!loaded_ok) /* load the hardcoded default */ { char *skin_buf[NB_SCREENS] = { @@ -152,11 +151,11 @@ void wps_data_load(enum screen_type screen, const char *buf, bool isfile) "%pb\n", #endif }; - skin_data_load(gui_wps[screen].data, &screens[screen], - skin_buf[screen], false); + skin_data_load(gui_wps[screen].data, skin_buf[screen], false); } #ifdef HAVE_REMOVE_LCD gui_wps[screen].data->remote_wps = !(screen == SCREEN_MAIN); + #endif } @@ -721,7 +720,6 @@ long gui_wps_show(void) #endif } } - #ifdef HAVE_LCD_BITMAP /* when the peak meter is enabled we want to have a few extra updates to make it look smooth. On the diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 915c329..c3622a4 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -12735,3 +12735,45 @@ quickscreen: "Set as Top Quickscreen Item" + + id: LANG_STATUSBAR_CUSTOM + desc: in Settings -> General -> Display -> statusbar + user: core + + *: "Custom" + + + *: "Custom" + + + *: "Custom" + + + + id: VOICE_EXT_SBS + desc: spoken only, for file extension + user: core + + *: "" + + + *: "" + + + *: "statusbar skin" + + + + id: VOICE_EXT_RSBS + desc: spoken only, for file extension + user: core + + *: "" + + + *: "" + + + *: "remote statusbar skin" + + diff --git a/apps/main.c b/apps/main.c index 6aa16e5..ff775c2 100644 --- a/apps/main.c +++ b/apps/main.c @@ -73,6 +73,7 @@ #include "scrobbler.h" #include "icon.h" #include "viewport.h" +#include "statusbar-skinned.h" #ifdef IPOD_ACCESSORY_PROTOCOL #include "iap.h" @@ -311,6 +312,7 @@ static void init(void) settings_reset(); settings_load(SETTINGS_ALL); gui_sync_wps_init(); + sb_skin_init(); settings_apply(true); init_dircache(true); init_dircache(false); @@ -536,6 +538,7 @@ static void init(void) } gui_sync_wps_init(); + sb_skin_init(); settings_apply(true); init_dircache(false); #ifdef HAVE_TAGCACHE diff --git a/apps/menus/theme_menu.c b/apps/menus/theme_menu.c index b4505de..8c8276a 100644 --- a/apps/menus/theme_menu.c +++ b/apps/menus/theme_menu.c @@ -159,12 +159,16 @@ static int statusbar_callback_ex(int action,const struct menu_item_ex *this_item old_bar[screen] = statusbar_position(screen); break; case ACTION_EXIT_MENUITEM: - gui_statusbar_changed(screen, old_bar[screen]); send_event(GUI_EVENT_STATUSBAR_TOGGLE, NULL); send_event(GUI_EVENT_ACTIONUPDATE, (void*)true); + if ((old_bar[screen] == STATUSBAR_CUSTOM) + || (statusbar_position(screen) == STATUSBAR_CUSTOM)) + send_event(GUI_EVENT_REFRESH, NULL); + else + gui_statusbar_changed(screen, old_bar[screen]); break; } - return action; + return ACTION_REDRAW; } #ifdef HAVE_REMOTE_LCD diff --git a/apps/plugin.c b/apps/plugin.c index a497ad0..1a70113 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -800,8 +800,6 @@ int plugin_load(const char* plugin, const void* parameter) #ifdef HAVE_TOUCHSCREEN touchscreen_set_mode(global_settings.touch_mode); #endif - - viewportmanager_set_statusbar(oldbars); button_clear_queue(); @@ -830,13 +828,14 @@ int plugin_load(const char* plugin, const void* parameter) #endif #endif + viewportmanager_set_statusbar(oldbars); + viewport_set_current_vp(NULL); + if (rc != PLUGIN_GOTO_WPS) { send_event(GUI_EVENT_REFRESH, NULL); } - viewportmanager_set_statusbar(oldbars); - viewport_set_current_vp(NULL); if (pfn_tsr_exit == NULL) plugin_loaded = false; diff --git a/apps/settings.c b/apps/settings.c index 4c16c6a..8e4c277 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -71,6 +71,7 @@ #include "wps.h" #include "skin_engine/skin_engine.h" #include "viewport.h" +#include "statusbar-skinned.h" #if CONFIG_CODEC == MAS3507D void dac_line_in(bool enable); @@ -740,6 +741,17 @@ void settings_apply_skins(void) char buf[MAX_PATH]; /* re-initialize the skin buffer before we start reloading skins */ skin_buffer_init(); + if ( global_settings.sbs_file[0] && + global_settings.sbs_file[0] != 0xff ) { + snprintf(buf, sizeof buf, WPS_DIR "/%s.sbs", + global_settings.sbs_file); + sb_skin_data_load(SCREEN_MAIN, buf, true); + } + else + { + sb_skin_data_init(SCREEN_MAIN); + sb_skin_data_load(SCREEN_MAIN, NULL, true); + } if ( global_settings.wps_file[0] && global_settings.wps_file[0] != 0xff ) { snprintf(buf, sizeof buf, WPS_DIR "/%s.wps", @@ -752,6 +764,17 @@ void settings_apply_skins(void) wps_data_load(SCREEN_MAIN, NULL, true); } #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1) + if ( global_settings.rsbs_file[0] && + global_settings.rsbs_file[0] != 0xff ) { + snprintf(buf, sizeof buf, WPS_DIR "/%s.rsbs", + global_settings.rsbs_file); + sb_skin_data_load(SCREEN_REMOTE, buf, true); + } + else + { + sb_skin_data_init(SCREEN_REMOTE); + sb_skin_data_load(SCREEN_REMOTE, NULL, true); + } if ( global_settings.rwps_file[0]) { snprintf(buf, sizeof buf, WPS_DIR "/%s.rwps", global_settings.rwps_file); @@ -763,6 +786,7 @@ void settings_apply_skins(void) wps_data_load(SCREEN_REMOTE, NULL, true); } #endif + viewportmanager_theme_changed(THEME_STATUSBAR); } void settings_apply(bool read_disk) @@ -994,7 +1018,8 @@ void settings_apply(bool read_disk) enc_global_settings_apply(); #endif #ifdef HAVE_LCD_BITMAP - viewportmanager_theme_changed(THEME_ALL); + /* already called with THEME_STATUSBAR in settings_apply_skins() */ + viewportmanager_theme_changed(THEME_UI_VIEWPORT); #endif } diff --git a/apps/settings.h b/apps/settings.h index e8ffe91..e71f334 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -60,6 +60,7 @@ struct opt_items { #define FONT_DIR ROCKBOX_DIR "/fonts" #define LANG_DIR ROCKBOX_DIR "/langs" #define WPS_DIR ROCKBOX_DIR "/wps" +#define SB_DIR ROCKBOX_DIR "/statusbar" #define THEME_DIR ROCKBOX_DIR "/themes" #define ICON_DIR ROCKBOX_DIR "/icons" @@ -545,6 +546,7 @@ struct user_settings int peak_meter_max; /* range maximum */ unsigned char wps_file[MAX_FILENAME+1]; /* last wps */ + unsigned char sbs_file[MAX_FILENAME+1]; /* last statusbar skin */ unsigned char lang_file[MAX_FILENAME+1]; /* last language */ unsigned char playlist_catalog_dir[MAX_FILENAME+1]; int skip_length; /* skip length */ @@ -720,6 +722,7 @@ struct user_settings unsigned char remote_icon_file[MAX_FILENAME+1]; unsigned char remote_viewers_icon_file[MAX_FILENAME+1]; unsigned char rwps_file[MAX_FILENAME+1]; /* last remote-wps */ + unsigned char rsbs_file[MAX_FILENAME+1]; /* last remote statusbar skin */ #ifdef HAS_REMOTE_BUTTON_HOLD int remote_backlight_on_button_hold; /* what to do with remote backlight when hold switch is on */ diff --git a/apps/settings_list.c b/apps/settings_list.c index 958c458..051fbd6 100644 --- a/apps/settings_list.c +++ b/apps/settings_list.c @@ -199,6 +199,7 @@ static const char graphic_numeric[] = "graphic,numeric"; /* Default theme settings */ #define DEFAULT_WPSNAME "cabbiev2" +#define DEFAULT_SBS_NAME DEFAULT_WPSNAME #ifdef HAVE_LCD_BITMAP @@ -603,14 +604,14 @@ const struct settings_list settings[] = { ID2P(LANG_INVERT_CURSOR_BAR)), #endif CHOICE_SETTING(F_THEMESETTING|F_TEMPVAR, statusbar, - LANG_STATUS_BAR, STATUSBAR_TOP, "statusbar","off,top,bottom", - NULL, 3, ID2P(LANG_OFF), ID2P(LANG_STATUSBAR_TOP), - ID2P(LANG_STATUSBAR_BOTTOM)), + LANG_STATUS_BAR, STATUSBAR_TOP, "statusbar","off,top,bottom,custom", + NULL, 4, ID2P(LANG_OFF), ID2P(LANG_STATUSBAR_TOP), + ID2P(LANG_STATUSBAR_BOTTOM), ID2P(LANG_STATUSBAR_CUSTOM)), #ifdef HAVE_REMOTE_LCD CHOICE_SETTING(F_THEMESETTING|F_TEMPVAR, remote_statusbar, - LANG_REMOTE_STATUSBAR, STATUSBAR_TOP, "remote statusbar","off,top,bottom", - NULL, 3, ID2P(LANG_OFF), ID2P(LANG_STATUSBAR_TOP), - ID2P(LANG_STATUSBAR_BOTTOM)), + LANG_REMOTE_STATUSBAR, STATUSBAR_TOP, "remote statusbar","off,top,bottom,custom", + NULL, 4, ID2P(LANG_OFF), ID2P(LANG_STATUSBAR_TOP), + ID2P(LANG_STATUSBAR_BOTTOM), ID2P(LANG_STATUSBAR_CUSTOM)), #endif CHOICE_SETTING(F_THEMESETTING|F_TEMPVAR, scrollbar, LANG_SCROLL_BAR, SCROLLBAR_LEFT, "scrollbar","off,left,right", @@ -1392,9 +1393,13 @@ const struct settings_list settings[] = { DEFAULT_FONTNAME, FONT_DIR "/", ".fnt"), #endif TEXT_SETTING(F_THEMESETTING,wps_file, "wps", - DEFAULT_WPSNAME, WPS_DIR "/", ".wps"), + DEFAULT_SBS_NAME, WPS_DIR "/", ".wps"), + TEXT_SETTING(F_THEMESETTING,sbs_file, "sb", + DEFAULT_WPSNAME, WPS_DIR "/", ".sbs"), TEXT_SETTING(0,lang_file,"lang","",LANG_DIR "/",".lng"), #ifdef HAVE_REMOTE_LCD + TEXT_SETTING(F_THEMESETTING,rsbs_file, "rsb", + DEFAULT_SBS_NAME, WPS_DIR "/", ".rsbs"), TEXT_SETTING(F_THEMESETTING,rwps_file,"rwps", DEFAULT_WPSNAME, WPS_DIR "/", ".rwps"), #endif diff --git a/wps/WPSLIST b/wps/WPSLIST index 58fa5f1..4f762f0 100644 --- a/wps/WPSLIST +++ b/wps/WPSLIST @@ -44,6 +44,8 @@ selector type: bar (inverse) Name: rockbox_default.wps RWPS: rockbox_default.rwps +SBS: +RSBS: Author: Rockbox team Font: 08-Schumacher-Clean.fnt Font.11x2x1: @@ -59,6 +61,8 @@ selector type: bar (inverse) Name: boxes.wps rwps: boxes.rwps +SBS: +RSBS: Author: Christi Scarborough (after Magnus Westerlund) Font: 08-Schumacher-Clean.fnt Statusbar: top @@ -76,6 +80,8 @@ remote ui viewport: - Name: engineeer2.wps RWPS: engineeer2.rwps +SBS: +RSBS: Author: Magnus Westerlund Font: 08-Nedore.fnt Statusbar: top @@ -90,6 +96,8 @@ remote ui viewport: - Name: iAmp.wps RWPS: iAmp.rwps +SBS: +RSBS: Author: Raymond Hoh Font: 12-Nimbus.fnt backdrop: @@ -104,6 +112,8 @@ remote ui viewport: - Name: zezayer.wps RWPS: zezayer.rwps +SBS: +RSBS: Author: Jake Owen Font: 08-Nedore.fnt Statusbar: top @@ -153,6 +163,8 @@ Statusbar: top Name: marquee.wps RWPS: marquee.rwps +SBS: +RSBS: Author: Mike Sobel Font: 13-Nimbus.fnt Statusbar: top @@ -176,6 +188,8 @@ remote ui viewport: - Name: DancePuffDuo.wps RWPS: DancePuffDuo.rwps +SBS: +RSBS: Author: Chris Oxtoby Font: 13-Nimbus.fnt Statusbar: top @@ -199,6 +213,8 @@ Statusbar: top Name: iCatcher.wps RWPS: iCatcher.rwps +SBS: +RSBS: Author: Ioannis Koutoulakis Font.112x64x1: 08-Rockfont.fnt Font.128x64x1: 08-Rockfont.fnt @@ -235,6 +251,8 @@ Statusbar: top Name: UniCatcher.wps RWPS: UniCatcher.rwps +SBS: +RSBS: Author: Ioannis Koutoulakis Font: 16-GNU-Unifont.fnt Foreground Color: 000000 @@ -258,6 +276,8 @@ Statusbar: top Name: Rockboxed.wps RWPS: rockbox_default.rwps +SBS: +RSBS: Author: Roan Horning Font.112x64x1: 08-Schumacher-Clean.fnt Font.128x64x1: 08-Schumacher-Clean.fnt @@ -291,6 +311,9 @@ Author: Jens Arnold Name: cabbiev2.wps RWPS: cabbiev2.rwps +SBS: +SBS.176x220x16: cabbiev2.sbs +RSBS: # Real name of the creator of the WPS Author: Johannes Voggenthaler, Apoo Maha, Marc Guay, Alex Vanderpol, Jerry Lange, Keith Perri, Mark Fawcus, and Marianne Arnold with support from Rockbox developers and forums. Based on Cabbie by Yohann Misquitta. @@ -372,6 +395,8 @@ viewers iconset.240x400x16: /.rockbox/icons/tango_small_viewers.bmp # Whether the WPS is designed to have the statusbar on or off Statusbar: top +statusbar.176x220x16: custom +remote statusbar: top # list & remote ui viewports ui viewport: - diff --git a/wps/wpsbuild.pl b/wps/wpsbuild.pl index e9e5c29..7378f30 100755 --- a/wps/wpsbuild.pl +++ b/wps/wpsbuild.pl @@ -32,9 +32,18 @@ my $cppdef = $target; my @depthlist = ( 16, 8, 4, 2, 1 ); # These parameters are filled in as we parse wpslist +my $req_size; +my $req_g_wps; +my $req_t; +my $req_t_wps; my $wps; my $wps_prefix; +my $sbs_prefix; my $rwps; +my $sbs; +my $sbs_w_size; +my $rsbs; +my $rsbs_w_size; my $width; my $height; my $font; @@ -42,9 +51,6 @@ my $fgcolor; my $bgcolor; my $statusbar; my $author; -my $req_g; -my $req_g_wps; -my $req_t_wps; my $backdrop; my $lineselectstart; my $lineselectend; @@ -191,12 +197,26 @@ sub copywps my $dir; my @filelist; my $file; + my $__sb; if($wpslist =~ /(.*)WPSLIST/) { $dir = $1; -# system("cp $dir/$wps .rockbox/wps/"); - #print "$req_t_wps $req_g_wps\n"; + $__sb = $sbs_prefix . "." . $req_size . ".sbs"; + #print "$req_t_wps $req_g_wps $sbs_prefix\n"; + #print "$dir/$__sb\n"; +# system("cp $dir/$wps .rockbox/wps/"); + # check for .WIDTHxHEIGHTxDEPTH.sbs + if (-e "$dir/$__sb") { + system("cp $dir/$__sb $rbdir/wps/$sbs"); + } + # check for .WIDTHxHEIGHTxDEPTH..sbs and overwrite the + # previous sb if needed + $__sb = $sbs_prefix . "." . $req_size . "." . $modelname . ".sbs"; + if (-e "$dir/$__sb") { + system("cp $dir/$__sb $rbdir/wps/$sbs"); + } + if (-e "$dir/$req_t_wps" ) { system("cp $dir/$req_t_wps $rbdir/wps/$wps"); @@ -210,9 +230,9 @@ sub copywps close(WPSFILE); if ($#filelist >= 0) { - if (-e "$dir/$wps_prefix/$req_g") { + if (-e "$dir/$wps_prefix/$req_size") { foreach $file (@filelist) { - system("cp $dir/$wps_prefix/$req_g/$file $rbdir/wps/$wps_prefix/"); + system("cp $dir/$wps_prefix/$req_size/$file $rbdir/wps/$wps_prefix/"); } } elsif (-e "$dir/$wps_prefix") { @@ -235,7 +255,7 @@ sub copywps sub buildcfg { my $cfg = $wps; - my @out; + my @out; $cfg =~ s/\.(r|)wps/.cfg/; @@ -247,6 +267,20 @@ sub buildcfg { wps: /$rbdir/wps/$wps MOO ; + if(defined($sbs)) { + if ($sbs eq '') { + push @out, "sbs: -\n"; + } else { + push @out, "sbs: /$rbdir/wps/$sbs\n"; + } + } + if(defined($sbs) && $has_remote) { + if ($rsbs eq '') { + push @out, "rsbs: -\n"; + } else { + push @out, "rsbs: /$rbdir/wps/$rsbs\n"; + } + } if($font) { push @out, "font: /$rbdir/fonts/$font\n"; } @@ -264,7 +298,7 @@ MOO } if(defined($backdrop)) { if ($backdrop eq '') { - push @out, "backdrop:\n"; + push @out, "backdrop: -\n"; } else { # clip resolution from filename $backdrop =~ s/(\.[0-9]*x[0-9]*x[0-9]*)//; @@ -338,6 +372,8 @@ while() { undef $wps; undef $wps_prefix; undef $rwps; + undef $sbs; + undef $rsbs; undef $width; undef $height; undef $font; @@ -386,23 +422,24 @@ while() { foreach my $d (@depthlist) { next if ($d > $rdepth); - $req_g = $rwidth . "x" . $rheight . "x" . $d; + $req_size = $rwidth . "x" . $rheight . "x" . $d; # check for model specific wps - $req_g_wps = $wps_prefix . "." . $req_g . "." . $modelname . ".wps"; + $req_g_wps = $wps_prefix . "." . $req_size . "." . $modelname . ".wps"; last if (-e "$wpsdir/$req_g_wps"); - $req_g_wps = $wps_prefix . "." . $req_g . ".wps"; + # check for normal wps (with WIDTHxHEIGHTxDEPTH) + $req_g_wps = $wps_prefix . "." . $req_size . ".wps"; last if (-e "$wpsdir/$req_g_wps"); if ($isrwps) { - $req_g = $req_g . "." . $main_width . "x" . $main_height . "x" . "$main_depth"; + $req_size = $req_size . "." . $main_width . "x" . $main_height . "x" . "$main_depth"; - $req_g_wps = $wps_prefix . "." . $req_g . ".wps"; + $req_g_wps = $wps_prefix . "." . $req_size . ".wps"; last if (-e "$wpsdir/$req_g_wps"); } } - $req_t_wps = $wps_prefix . ".txt" . ".wps"; + $req_t_wps = $wps_prefix . $req_t . ".wps"; #print "LCD: $wps wants $width x $height\n"; #print "LCD: is $rwidth x $rheight\n"; @@ -454,6 +491,20 @@ while() { elsif($l =~ /^RWPS\.${main_width}x${main_height}x$main_depth: *(.*)/i) { $rwps = $1; } + elsif($l =~ /^SBS: *(.*)/i) { + $sbs = $sbs_prefix = $1; + $sbs_prefix =~ s/\.(r|)sbs//; + } + elsif($l =~ /^SBS\.${main_width}x${main_height}x$main_depth: *(.*)/i) { + $sbs = $sbs_prefix = $1; + $sbs_prefix =~ s/\.(r|)sbs//; + } + elsif($l =~ /^RSBS: *(.*)/i) { + $rsbs = $1; + } + elsif($l =~ /^RSBS\.${main_width}x${main_height}x$main_depth: *(.*)/i) { + $rsbs = $1; + } elsif($l =~ /^Author: *(.*)/i) { $author = $1; } @@ -526,9 +577,15 @@ while() { elsif($l =~ /^ui viewport: *(.*)/i) { $listviewport = $1; } + elsif($l =~ /^ui viewport\.${main_width}x${main_height}x$main_depth: *(.*)/i) { + $listviewport = $1; + } elsif($l =~ /^remote ui viewport: *(.*)/i) { $remotelistviewport = $1; } + elsif($l =~ /^remote ui viewport\.${main_width}x${main_height}x$main_depth: *(.*)/i) { + $remotelistviewport = $1; + } else{ #print "Unknown line: $l!\n"; }