Merge tag 'v3.13-final' into maemo-port
[maemo-rb.git] / apps / gui / statusbar-skinned.c
blobfc9735da21d0fe69e4e2f9144e4d551a8e6afd00
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 "action.h"
25 #include "system.h"
26 #include "settings.h"
27 #include "appevents.h"
28 #include "screens.h"
29 #include "screen_access.h"
30 #include "strlcpy.h"
31 #include "skin_parser.h"
32 #include "skin_buffer.h"
33 #include "skin_engine/skin_engine.h"
34 #include "skin_engine/wps_internals.h"
35 #include "viewport.h"
36 #include "statusbar.h"
37 #include "statusbar-skinned.h"
38 #include "debug.h"
39 #include "font.h"
40 #include "icon.h"
41 #include "option_select.h"
42 #ifdef HAVE_TOUCHSCREEN
43 #include "sound.h"
44 #include "misc.h"
45 #endif
47 /* initial setup of wps_data */
48 static int update_delay = DEFAULT_UPDATE_DELAY;
50 static bool sbs_has_title[NB_SCREENS];
51 static char* sbs_title[NB_SCREENS];
52 static enum themable_icons sbs_icon[NB_SCREENS];
53 static bool sbs_loaded[NB_SCREENS] = { false };
55 bool sb_set_title_text(char* title, enum themable_icons icon, enum screen_type screen)
57 sbs_title[screen] = title;
58 /* Icon_NOICON == -1 which the skin engine wants at position 1, so + 2 */
59 sbs_icon[screen] = icon + 2;
60 return sbs_has_title[screen];
63 void sb_skin_has_title(enum screen_type screen)
65 sbs_has_title[screen] = true;
68 const char* sb_get_title(enum screen_type screen)
70 return sbs_has_title[screen] ? sbs_title[screen] : NULL;
72 enum themable_icons sb_get_icon(enum screen_type screen)
74 return sbs_has_title[screen] ? sbs_icon[screen] : Icon_NOICON + 2;
77 int sb_preproccess(enum screen_type screen, struct wps_data *data)
79 (void)data;
80 sbs_loaded[screen] = false;
81 sbs_has_title[screen] = false;
82 viewportmanager_theme_enable(screen, false, NULL);
83 return 1;
85 int sb_postproccess(enum screen_type screen, struct wps_data *data)
87 if (data->wps_loaded)
89 /* hide the sb's default viewport because it has nasty effect with stuff
90 * not part of the statusbar,
91 * hence .sbs's without any other vps are unsupported*/
92 struct skin_viewport *vp = skin_find_item(VP_DEFAULT_LABEL_STRING, SKIN_FIND_VP, data);
93 struct skin_element *tree = SKINOFFSETTOPTR(get_skin_buffer(data), data->tree);
94 struct skin_element *next_vp = SKINOFFSETTOPTR(get_skin_buffer(data), tree->next);
96 if (vp)
98 if (!next_vp)
99 { /* no second viewport, let parsing fail */
100 return 0;
102 /* hide this viewport, forever */
103 vp->hidden_flags = VP_NEVER_VISIBLE;
105 sb_set_info_vp(screen, VP_DEFAULT_LABEL);
106 sbs_loaded[screen] = true;
108 viewportmanager_theme_undo(screen, false);
109 return 1;
112 static OFFSETTYPE(char*) infovp_label[NB_SCREENS];
113 static OFFSETTYPE(char*) oldinfovp_label[NB_SCREENS];
114 void sb_set_info_vp(enum screen_type screen, OFFSETTYPE(char*) label)
116 infovp_label[screen] = label;
119 struct viewport *sb_skin_get_info_vp(enum screen_type screen)
121 if (sbs_loaded[screen] == false)
122 return NULL;
123 struct wps_data *data = skin_get_gwps(CUSTOM_STATUSBAR, screen)->data;
124 struct skin_viewport *vp = NULL;
125 char *label;
126 if (oldinfovp_label[screen] &&
127 (oldinfovp_label[screen] != infovp_label[screen]))
129 /* UI viewport changed, so force a redraw */
130 oldinfovp_label[screen] = infovp_label[screen];
131 viewportmanager_theme_enable(screen, false, NULL);
132 viewportmanager_theme_undo(screen, true);
134 label = SKINOFFSETTOPTR(get_skin_buffer(data), infovp_label[screen]);
135 if (infovp_label[screen] == VP_DEFAULT_LABEL)
136 label = VP_DEFAULT_LABEL_STRING;
137 vp = skin_find_item(label, SKIN_FIND_UIVP, data);
138 if (!vp)
139 return NULL;
140 if (vp->parsed_fontid == 1)
141 vp->vp.font = screens[screen].getuifont();
142 return &vp->vp;
145 #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
146 int sb_get_backdrop(enum screen_type screen)
148 struct wps_data *data = skin_get_gwps(CUSTOM_STATUSBAR, screen)->data;
149 if (data->wps_loaded)
150 return data->backdrop_id;
151 else
152 return -1;
155 #endif
156 static bool force_waiting = false;
157 void sb_skin_update(enum screen_type screen, bool force)
159 struct wps_data *data = skin_get_gwps(CUSTOM_STATUSBAR, screen)->data;
160 static long next_update[NB_SCREENS] = {0};
161 int i = screen;
162 if (!data->wps_loaded)
163 return;
164 if (TIME_AFTER(current_tick, next_update[i]) || force || force_waiting)
166 force_waiting = false;
167 #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
168 /* currently, all remotes are readable without backlight
169 * so still update those */
170 if (lcd_active() || (i != SCREEN_MAIN))
171 #endif
173 bool full_update = skin_do_full_update(CUSTOM_STATUSBAR, screen);
174 skin_update(CUSTOM_STATUSBAR, screen, force ||
175 full_update ? SKIN_REFRESH_ALL : SKIN_REFRESH_NON_STATIC);
177 next_update[i] = current_tick + update_delay; /* don't update too often */
181 void do_sbs_update_callback(void *param)
183 (void)param;
184 /* the WPS handles changing the actual id3 data in the id3 pointers
185 * we imported, we just want a full update */
186 skin_request_full_update(CUSTOM_STATUSBAR);
187 force_waiting = true;
188 /* force timeout in wps main loop, so that the update is instantly */
189 queue_post(&button_queue, BUTTON_NONE, 0);
192 void sb_skin_set_update_delay(int delay)
194 update_delay = delay;
197 /* This creates and loads a ".sbs" based on the user settings for:
198 * - regular statusbar
199 * - colours
200 * - ui viewport
201 * - backdrop
203 char* sb_create_from_settings(enum screen_type screen)
205 static char buf[128];
206 char *ptr, *ptr2;
207 int len, remaining = sizeof(buf);
208 int bar_position = statusbar_position(screen);
209 ptr = buf;
210 ptr[0] = '\0';
212 /* setup the inbuilt statusbar */
213 if (bar_position != STATUSBAR_OFF)
215 int y = 0, height = STATUSBAR_HEIGHT;
216 if (bar_position == STATUSBAR_BOTTOM)
218 y = screens[screen].lcdheight - STATUSBAR_HEIGHT;
220 len = snprintf(ptr, remaining, "%%V(0,%d,-,%d,0)\n%%wi\n",
221 y, height);
222 remaining -= len;
223 ptr += len;
225 /* %Vi viewport, colours handled by the parser */
226 #if NB_SCREENS > 1
227 if (screen == SCREEN_REMOTE)
228 ptr2 = global_settings.remote_ui_vp_config;
229 else
230 #endif
231 ptr2 = global_settings.ui_vp_config;
233 if (ptr2[0] && ptr2[0] != '-') /* from ui viewport setting */
235 char *comma = ptr;
236 int param_count = 0;
237 len = snprintf(ptr, remaining, "%%ax%%Vi(-,%s)\n", ptr2);
238 /* The config put the colours at the end of the viewport,
239 * they need to be stripped for the skin code though */
240 do {
241 param_count++;
242 comma = strchr(comma+1, ',');
244 } while (comma && param_count < 6);
245 if (comma)
247 char *end = comma;
248 char fg[8], bg[8];
249 int i = 0;
250 comma++;
251 while (*comma != ',')
252 fg[i++] = *comma++;
253 fg[i] = '\0'; comma++; i=0;
254 while (*comma != ')')
255 bg[i++] = *comma++;
256 bg[i] = '\0';
257 len += snprintf(end, remaining-len, ") %%Vf(%s) %%Vb(%s)\n", fg, bg);
260 else
262 int y = 0, height;
263 switch (bar_position)
265 case STATUSBAR_TOP:
266 y = STATUSBAR_HEIGHT;
267 case STATUSBAR_BOTTOM:
268 height = screens[screen].lcdheight - STATUSBAR_HEIGHT;
269 break;
270 default:
271 height = screens[screen].lcdheight;
273 len = snprintf(ptr, remaining, "%%ax%%Vi(-,0,%d,-,%d,1)\n",
274 y, height);
276 return buf;
279 void sb_skin_init(void)
281 FOR_NB_SCREENS(i)
283 oldinfovp_label[i] = VP_DEFAULT_LABEL;
287 #ifdef HAVE_TOUCHSCREEN
288 static bool bypass_sb_touchregions = true;
289 void sb_bypass_touchregions(bool enable)
291 bypass_sb_touchregions = enable;
294 int sb_touch_to_button(int context)
296 struct touchregion *region;
297 static int last_context = -1;
298 int button, offset;
299 if (bypass_sb_touchregions)
300 return ACTION_TOUCHSCREEN;
302 if (last_context != context)
303 skin_disarm_touchregions(skin_get_gwps(CUSTOM_STATUSBAR, SCREEN_MAIN)->data);
304 last_context = context;
305 button = skin_get_touchaction(skin_get_gwps(CUSTOM_STATUSBAR, SCREEN_MAIN)->data,
306 &offset, &region);
308 switch (button)
310 #ifdef HAVE_VOLUME_IN_LIST
311 case ACTION_WPS_VOLUP:
312 return ACTION_LIST_VOLUP;
313 case ACTION_WPS_VOLDOWN:
314 return ACTION_LIST_VOLDOWN;
315 #endif
316 /* TODO */
318 return button;
320 #endif