get it working with images
[kugel-rb.git] / apps / gui / statusbar-skinned.c
blob0f9ee1cdec0f062877533987a407baaa11333d50
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2009 Thomas Martitz
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 ****************************************************************************/
22 #include "config.h"
24 #include "system.h"
25 #include "settings.h"
26 #include "appevents.h"
27 #include "screens.h"
28 #include "screen_access.h"
29 #include "skin_engine/skin_engine.h"
30 #include "skin_engine/wps_internals.h"
31 #include "viewport.h"
32 #include "statusbar.h"
33 #include "statusbar-skinned.h"
34 #include "debug.h"
35 #include "font.h"
36 #include "icon.h"
39 /* currently only one wps_state is needed */
40 extern struct wps_state wps_state; /* from wps.c */
41 static struct gui_wps sb_skin[NB_SCREENS] = {{ .data = NULL }};
42 static struct wps_data sb_skin_data[NB_SCREENS] = {{ .wps_loaded = 0 }};
43 static struct wps_sync_data sb_skin_sync_data = { .do_full_update = false };
45 /* initial setup of wps_data */
46 static int update_delay = DEFAULT_UPDATE_DELAY;
48 bool sb_set_title_text(char* title, enum themable_icons icon, enum screen_type screen)
50 int i;
51 bool retval = false;
52 for(i=0; i<sb_skin_data[screen].num_tokens; i++)
54 if (sb_skin_data[screen].tokens[i].type == WPS_TOKEN_LIST_TITLE_TEXT)
56 sb_skin_data[screen].tokens[i].value.data = title;
57 retval = true;
59 else if (sb_skin_data[screen].tokens[i].type == WPS_TOKEN_LIST_TITLE_ICON)
61 /* Icon_NOICON == -1 which the skin engine wants at position 1, so + 2 */
62 sb_skin_data[screen].tokens[i].value.i = icon+2;
65 return retval;
69 /* This creates and loads a ".sbs" based on the user settings for:
70 * - regular statusbar
71 * - colours
72 * - ui viewport
73 * - backdrop
75 int sb_create_from_settings(enum screen_type screen, bool at_boot)
77 char buf[128], *ptr, *ptr2;
78 int len, remaining = sizeof(buf);
79 int bar_position = statusbar_position(screen);
80 ptr = buf;
81 ptr[0] = '\0';
83 /* setup the inbuilt statusbar */
84 if (bar_position != STATUSBAR_OFF)
86 int y = 0, height = STATUSBAR_HEIGHT;
87 if (bar_position == STATUSBAR_BOTTOM)
89 y = screens[screen].lcdheight - STATUSBAR_HEIGHT;
91 len = snprintf(ptr, remaining, "%%V|0|%d|-|%d|0|-|-|\n%%wi\n",
92 y, height);
93 remaining -= len;
94 ptr += len;
96 /* %Vi viewport, colours handled by the parser */
97 #if NB_SCREENS > 1
98 if (screen == SCREEN_REMOTE)
99 ptr2 = global_settings.remote_ui_vp_config;
100 else
101 #endif
102 ptr2 = global_settings.ui_vp_config;
104 if (ptr2[0] && ptr2[0] != '-') /* from ui viewport setting */
106 len = snprintf(ptr, remaining, "%%ax%%Vi|%s|\n", ptr2);
107 while ((ptr2 = strchr(ptr, ',')))
108 *ptr2 = '|';
110 else
112 int y = 0, height;
113 switch (bar_position)
115 case STATUSBAR_TOP:
116 y = STATUSBAR_HEIGHT;
117 case STATUSBAR_BOTTOM:
118 height = screens[screen].lcdheight - STATUSBAR_HEIGHT;
119 break;
120 default:
121 height = screens[screen].lcdheight;
123 len = snprintf(ptr, remaining, "%%ax%%Vi|0|%d|-|%d|1|-|-|\n",
124 y, height);
126 return sb_skin_data_load(screen, buf, false, true, at_boot);
130 int sb_skin_data_load(enum screen_type screen, const char *buf,
131 bool isfile, bool load_at_boot)
133 struct wps_data *data = sb_skin[screen].data;
135 int success;
136 int ret = skin_data_load(screen, data, buf, isfile, load_at_boot);
137 success = buf && ret;
139 if (success)
140 { /* hide the sb's default viewport because it has nasty effect with stuff
141 * not part of the statusbar,
142 * hence .sbs's without any other vps are unsupported*/
143 struct skin_viewport *vp = find_viewport(VP_DEFAULT_LABEL, data);
144 struct skin_token_list *next_vp = data->viewports->next;
146 if (!next_vp)
147 { /* no second viewport, let parsing fail */
148 success = false;
150 /* hide this viewport, forever */
151 vp->hidden_flags = VP_NEVER_VISIBLE;
154 if (!success && isfile)
155 ret = sb_create_from_settings(screen, load_at_boot);
156 return ret;
159 void sbs_data_load_finalize(enum screen_type screen, const char* buf)
161 skin_data_load_finalize(&sb_skin_data[screen], buf);
164 struct viewport *sb_skin_get_info_vp(enum screen_type screen)
166 return &find_viewport(VP_INFO_LABEL, sb_skin[screen].data)->vp;
169 #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
170 char* sb_get_backdrop(enum screen_type screen)
172 return sb_skin[screen].data->backdrop;
175 bool sb_set_backdrop(enum screen_type screen, char* filename)
177 if (!filename)
179 sb_skin[screen].data->backdrop = NULL;
180 return true;
182 else if (!sb_skin[screen].data->backdrop)
184 /* need to make room on the buffer */
185 size_t buf_size;
186 #if defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)
187 if (screen == SCREEN_REMOTE)
188 buf_size = REMOTE_LCD_BACKDROP_BYTES;
189 else
190 #endif
191 buf_size = LCD_BACKDROP_BYTES;
192 sb_skin[screen].data->backdrop = skin_buffer_alloc(buf_size);
193 if (!sb_skin[screen].data->backdrop)
194 return false;
197 if (!screens[screen].backdrop_load(filename, sb_skin[screen].data->backdrop))
198 sb_skin[screen].data->backdrop = NULL;
199 return sb_skin[screen].data->backdrop != NULL;
202 #endif
203 void sb_skin_update(enum screen_type screen, bool force)
205 static long next_update = 0;
206 int i = screen;
207 if (TIME_AFTER(current_tick, next_update) || force)
209 #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
210 /* currently, all remotes are readable without backlight
211 * so still update those */
212 if (lcd_active() || (i != SCREEN_MAIN))
213 #endif
214 skin_update(&sb_skin[i], force?
215 WPS_REFRESH_ALL : WPS_REFRESH_NON_STATIC);
216 next_update = current_tick + update_delay; /* don't update too often */
217 sb_skin[SCREEN_MAIN].sync_data->do_full_update = false;
221 void do_sbs_update_callback(void *param)
223 (void)param;
224 /* the WPS handles changing the actual id3 data in the id3 pointers
225 * we imported, we just want a full update */
226 sb_skin_sync_data.do_full_update = true;
227 /* force timeout in wps main loop, so that the update is instantly */
228 queue_post(&button_queue, BUTTON_NONE, 0);
231 void sb_skin_set_update_delay(int delay)
233 update_delay = delay;
236 void sb_skin_init(void)
238 int i;
239 FOR_NB_SCREENS(i)
241 #ifdef HAVE_ALBUMART
242 sb_skin_data[i].albumart = NULL;
243 sb_skin_data[i].playback_aa_slot = -1;
244 #endif
245 sb_skin[i].data = &sb_skin_data[i];
246 sb_skin[i].display = &screens[i];
247 /* Currently no seperate wps_state needed/possible
248 so use the only available ( "global" ) one */
249 sb_skin[i].state = &wps_state;
250 sb_skin[i].sync_data = &sb_skin_sync_data;