summaryrefslogtreecommitdiff
path: root/apps/gui
diff options
context:
space:
mode:
Diffstat (limited to 'apps/gui')
-rw-r--r--apps/gui/list.c10
-rw-r--r--apps/gui/skin_engine/skin_display.c5
-rw-r--r--apps/gui/splash.c3
-rw-r--r--apps/gui/statusbar-skinned.c97
-rw-r--r--apps/gui/statusbar-skinned.h3
-rw-r--r--apps/gui/usb_screen.c13
-rw-r--r--apps/gui/viewport.c347
-rw-r--r--apps/gui/viewport.h48
-rw-r--r--apps/gui/wps.c55
9 files changed, 238 insertions, 343 deletions
diff --git a/apps/gui/list.c b/apps/gui/list.c
index 340175c0d0..eacebb5c30 100644
--- a/apps/gui/list.c
+++ b/apps/gui/list.c
@@ -822,14 +822,17 @@ static const char* simplelist_static_getname(int item,
822bool simplelist_show_list(struct simplelist_info *info) 822bool simplelist_show_list(struct simplelist_info *info)
823{ 823{
824 struct gui_synclist lists; 824 struct gui_synclist lists;
825 int action, old_line_count = simplelist_line_count; 825 int action, old_line_count = simplelist_line_count, i;
826 int oldbars = viewportmanager_set_statusbar(VP_SB_ALLSCREENS);
827 const char* (*getname)(int item, void * data, char *buffer, size_t buffer_len); 826 const char* (*getname)(int item, void * data, char *buffer, size_t buffer_len);
828 int wrap = LIST_WRAP_UNLESS_HELD; 827 int wrap = LIST_WRAP_UNLESS_HELD;
829 if (info->get_name) 828 if (info->get_name)
830 getname = info->get_name; 829 getname = info->get_name;
831 else 830 else
832 getname = simplelist_static_getname; 831 getname = simplelist_static_getname;
832
833 FOR_NB_SCREENS(i)
834 viewportmanager_theme_enable(i, true, NULL);
835
833 gui_synclist_init(&lists, getname, info->callback_data, 836 gui_synclist_init(&lists, getname, info->callback_data,
834 info->scroll_all, info->selection_size, NULL); 837 info->scroll_all, info->selection_size, NULL);
835 838
@@ -904,7 +907,8 @@ bool simplelist_show_list(struct simplelist_info *info)
904 return true; 907 return true;
905 } 908 }
906 talk_shutup(); 909 talk_shutup();
907 viewportmanager_set_statusbar(oldbars); 910 FOR_NB_SCREENS(i)
911 viewportmanager_theme_undo(i);
908 return false; 912 return false;
909} 913}
910 914
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c
index 4f33910beb..362e5078f5 100644
--- a/apps/gui/skin_engine/skin_display.c
+++ b/apps/gui/skin_engine/skin_display.c
@@ -1084,11 +1084,6 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode)
1084#ifdef HAVE_LCD_BITMAP 1084#ifdef HAVE_LCD_BITMAP
1085 data->peak_meter_enabled = enable_pm; 1085 data->peak_meter_enabled = enable_pm;
1086#endif 1086#endif
1087
1088 if (refresh_mode & WPS_REFRESH_STATUSBAR)
1089 {
1090 viewportmanager_set_statusbar(gwps->sync_data->statusbars);
1091 }
1092 /* Restore the default viewport */ 1087 /* Restore the default viewport */
1093 display->set_viewport(NULL); 1088 display->set_viewport(NULL);
1094 1089
diff --git a/apps/gui/splash.c b/apps/gui/splash.c
index 4ddd22aba2..39d224a742 100644
--- a/apps/gui/splash.c
+++ b/apps/gui/splash.c
@@ -204,12 +204,15 @@ void splashf(int ticks, const char *fmt, ...)
204 fmt = P2STR((unsigned char *)fmt); 204 fmt = P2STR((unsigned char *)fmt);
205 FOR_NB_SCREENS(i) 205 FOR_NB_SCREENS(i)
206 { 206 {
207 viewportmanager_theme_enable(i, false, NULL);
207 va_start(ap, fmt); 208 va_start(ap, fmt);
208 splash_internal(&(screens[i]), fmt, ap); 209 splash_internal(&(screens[i]), fmt, ap);
209 va_end(ap); 210 va_end(ap);
210 } 211 }
211 if (ticks) 212 if (ticks)
212 sleep(ticks); 213 sleep(ticks);
214 FOR_NB_SCREENS(i)
215 viewportmanager_theme_undo(i);
213} 216}
214 217
215void splash(int ticks, const char *str) 218void splash(int ticks, const char *str)
diff --git a/apps/gui/statusbar-skinned.c b/apps/gui/statusbar-skinned.c
index 4ef739929a..8bdecef692 100644
--- a/apps/gui/statusbar-skinned.c
+++ b/apps/gui/statusbar-skinned.c
@@ -41,7 +41,7 @@ static struct wps_data sb_skin_data[NB_SCREENS] = {{ .wps_loaded = 0 }};
41static struct wps_sync_data sb_skin_sync_data = { .do_full_update = false }; 41static struct wps_sync_data sb_skin_sync_data = { .do_full_update = false };
42 42
43/* initial setup of wps_data */ 43/* initial setup of wps_data */
44static void sb_skin_update(void*); 44
45static bool loaded_ok[NB_SCREENS] = { false }; 45static bool loaded_ok[NB_SCREENS] = { false };
46static int update_delay = DEFAULT_UPDATE_DELAY; 46static int update_delay = DEFAULT_UPDATE_DELAY;
47 47
@@ -68,9 +68,6 @@ void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile)
68 vp->hidden_flags = VP_NEVER_VISIBLE; 68 vp->hidden_flags = VP_NEVER_VISIBLE;
69 } 69 }
70 70
71 if (!success)
72 remove_event(GUI_EVENT_ACTIONUPDATE, sb_skin_update);
73
74 loaded_ok[screen] = success; 71 loaded_ok[screen] = success;
75} 72}
76 73
@@ -96,7 +93,6 @@ struct viewport *sb_skin_get_info_vp(enum screen_type screen)
96 93
97inline bool sb_skin_get_state(enum screen_type screen) 94inline bool sb_skin_get_state(enum screen_type screen)
98{ 95{
99 int skinbars = sb_skin[screen].sync_data->statusbars;
100 /* Temp fix untill the hardcoded bar is removed */ 96 /* Temp fix untill the hardcoded bar is removed */
101 int bar_setting = global_settings.statusbar; 97 int bar_setting = global_settings.statusbar;
102#if NB_SCREENS > 1 98#if NB_SCREENS > 1
@@ -106,87 +102,45 @@ inline bool sb_skin_get_state(enum screen_type screen)
106 switch (bar_setting) 102 switch (bar_setting)
107 { 103 {
108 case STATUSBAR_CUSTOM: 104 case STATUSBAR_CUSTOM:
109 return loaded_ok[screen] && (skinbars & VP_SB_ONSCREEN(screen)); 105 return loaded_ok[screen];
110 case STATUSBAR_TOP: 106 case STATUSBAR_TOP:
111 case STATUSBAR_BOTTOM: 107 case STATUSBAR_BOTTOM:
108 return true;
112 case STATUSBAR_OFF: 109 case STATUSBAR_OFF:
113 return (viewportmanager_get_statusbar()&VP_SB_ONSCREEN(screen)); 110 return false;
114 } 111 }
115 return false; /* Should never actually get here */ 112 return false; /* Should never actually get here */
116} 113}
117 114
118 115void sb_skin_update(enum screen_type screen, bool force)
119static void do_update_callback(void *param)
120{
121 (void)param;
122 /* the WPS handles changing the actual id3 data in the id3 pointers
123 * we imported, we just want a full update */
124 sb_skin_sync_data.do_full_update = true;
125 /* force timeout in wps main loop, so that the update is instantly */
126 queue_post(&button_queue, BUTTON_NONE, 0);
127}
128
129
130void sb_skin_set_state(int state, enum screen_type screen)
131{
132 sb_skin[screen].sync_data->do_full_update = true;
133 int skinbars = sb_skin[screen].sync_data->statusbars;
134 if (state && loaded_ok[screen])
135 {
136 skinbars |= VP_SB_ONSCREEN(screen);
137 }
138 else
139 {
140 skinbars &= ~VP_SB_ONSCREEN(screen);
141 }
142
143 if (skinbars)
144 {
145#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
146 add_event(LCD_EVENT_ACTIVATION, false, do_update_callback);
147#endif
148 add_event(PLAYBACK_EVENT_TRACK_CHANGE, false,
149 do_update_callback);
150 add_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, false,
151 do_update_callback);
152 add_event(GUI_EVENT_ACTIONUPDATE, false, sb_skin_update);
153 }
154 else
155 {
156#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
157 remove_event(LCD_EVENT_ACTIVATION, do_update_callback);
158#endif
159 remove_event(PLAYBACK_EVENT_TRACK_CHANGE, do_update_callback);
160 remove_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, do_update_callback);
161 remove_event(GUI_EVENT_ACTIONUPDATE, sb_skin_update);
162 }
163
164 sb_skin[screen].sync_data->statusbars = skinbars;
165}
166
167static void sb_skin_update(void* param)
168{ 116{
169 static long next_update = 0; 117 static long next_update = 0;
170 int i; 118 int i = screen;
171 int forced_draw = param || sb_skin[SCREEN_MAIN].sync_data->do_full_update; 119 if (TIME_AFTER(current_tick, next_update) || force)
172 if (TIME_AFTER(current_tick, next_update) || forced_draw)
173 { 120 {
174 FOR_NB_SCREENS(i) 121 if (sb_skin_get_state(i))
175 { 122 {
176 if (sb_skin_get_state(i))
177 {
178#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) 123#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
179 /* currently, all remotes are readable without backlight 124 /* currently, all remotes are readable without backlight
180 * so still update those */ 125 * so still update those */
181 if (lcd_active() || (i != SCREEN_MAIN)) 126 if (lcd_active() || (i != SCREEN_MAIN))
182#endif 127#endif
183 skin_update(&sb_skin[i], forced_draw? 128 skin_update(&sb_skin[i], force?
184 WPS_REFRESH_ALL : WPS_REFRESH_NON_STATIC); 129 WPS_REFRESH_ALL : WPS_REFRESH_NON_STATIC);
185 }
186 } 130 }
187 next_update = current_tick + update_delay; /* don't update too often */
188 sb_skin[SCREEN_MAIN].sync_data->do_full_update = false;
189 } 131 }
132 next_update = current_tick + update_delay; /* don't update too often */
133 sb_skin[SCREEN_MAIN].sync_data->do_full_update = false;
134}
135
136void do_sbs_update_callback(void *param)
137{
138 (void)param;
139 /* the WPS handles changing the actual id3 data in the id3 pointers
140 * we imported, we just want a full update */
141 sb_skin_sync_data.do_full_update = true;
142 /* force timeout in wps main loop, so that the update is instantly */
143 queue_post(&button_queue, BUTTON_NONE, 0);
190} 144}
191 145
192void sb_skin_set_update_delay(int delay) 146void sb_skin_set_update_delay(int delay)
@@ -209,7 +163,6 @@ void sb_skin_init(void)
209 /* Currently no seperate wps_state needed/possible 163 /* Currently no seperate wps_state needed/possible
210 so use the only available ( "global" ) one */ 164 so use the only available ( "global" ) one */
211 sb_skin[i].state = &wps_state; 165 sb_skin[i].state = &wps_state;
212 sb_skin_sync_data.statusbars = VP_SB_HIDE_ALL;
213 sb_skin[i].sync_data = &sb_skin_sync_data; 166 sb_skin[i].sync_data = &sb_skin_sync_data;
214 } 167 }
215} 168}
diff --git a/apps/gui/statusbar-skinned.h b/apps/gui/statusbar-skinned.h
index 7c81eb8d01..6016c293b0 100644
--- a/apps/gui/statusbar-skinned.h
+++ b/apps/gui/statusbar-skinned.h
@@ -35,9 +35,9 @@ void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile);
35 35
36/* probably temporary, to shut the classic statusbar up */ 36/* probably temporary, to shut the classic statusbar up */
37bool sb_skin_get_state(enum screen_type screen); 37bool sb_skin_get_state(enum screen_type screen);
38void sb_skin_set_state(int state, enum screen_type screen);
39void sb_skin_init(void); 38void sb_skin_init(void);
40struct viewport *sb_skin_get_info_vp(enum screen_type screen); 39struct viewport *sb_skin_get_info_vp(enum screen_type screen);
40void sb_skin_update(enum screen_type screen, bool force);
41 41
42void sb_skin_set_update_delay(int delay); 42void sb_skin_set_update_delay(int delay);
43 43
@@ -48,4 +48,5 @@ void sb_skin_set_update_delay(int delay);
48#define sb_skin_set_state(a,b) 48#define sb_skin_set_state(a,b)
49#define sb_skin_get_state(a) 49#define sb_skin_get_state(a)
50#endif 50#endif
51void do_sbs_update_callback(void *param);
51#endif /* __STATUSBAR_SKINNED_H__ */ 52#endif /* __STATUSBAR_SKINNED_H__ */
diff --git a/apps/gui/usb_screen.c b/apps/gui/usb_screen.c
index f6285f995e..29d88daf06 100644
--- a/apps/gui/usb_screen.c
+++ b/apps/gui/usb_screen.c
@@ -150,7 +150,7 @@ static void usb_screen_fix_viewports(struct screen *screen,
150 150
151 viewport_set_defaults(parent, screen->screen_type); 151 viewport_set_defaults(parent, screen->screen_type);
152 if (parent->width < logo_width || parent->height < logo_height) 152 if (parent->width < logo_width || parent->height < logo_height)
153 viewport_set_fullscreen(parent, screen->screen_type); 153 viewportmanager_theme_enable(screen->screen_type, false, parent);
154 154
155 *logo = *parent; 155 *logo = *parent;
156 logo->x = parent->x + parent->width - logo_width; 156 logo->x = parent->x + parent->width - logo_width;
@@ -180,8 +180,6 @@ static void usb_screen_fix_viewports(struct screen *screen,
180static void usb_screens_draw(struct usb_screen_vps_t *usb_screen_vps_ar) 180static void usb_screens_draw(struct usb_screen_vps_t *usb_screen_vps_ar)
181{ 181{
182 int i; 182 int i;
183 int usb_bars = VP_SB_ALLSCREENS; /* force statusbars */
184
185 lcd_clear_display(); 183 lcd_clear_display();
186#ifdef HAVE_LCD_REMOTE 184#ifdef HAVE_LCD_REMOTE
187 lcd_remote_clear_display(); 185 lcd_remote_clear_display();
@@ -236,18 +234,12 @@ static void usb_screens_draw(struct usb_screen_vps_t *usb_screen_vps_ar)
236 234
237 screen->update_viewport(); 235 screen->update_viewport();
238 screen->set_viewport(NULL); 236 screen->set_viewport(NULL);
239
240 /* force statusbar by ignoring the setting */
241 usb_bars |= VP_SB_IGNORE_SETTING(i);
242 } 237 }
243
244 viewportmanager_set_statusbar(usb_bars);
245} 238}
246 239
247void gui_usb_screen_run(void) 240void gui_usb_screen_run(void)
248{ 241{
249 int i; 242 int i;
250 int old_bars = viewportmanager_get_statusbar();
251 struct usb_screen_vps_t usb_screen_vps_ar[NB_SCREENS]; 243 struct usb_screen_vps_t usb_screen_vps_ar[NB_SCREENS];
252#if defined HAVE_TOUCHSCREEN 244#if defined HAVE_TOUCHSCREEN
253 enum touchscreen_mode old_mode = touchscreen_get_mode(); 245 enum touchscreen_mode old_mode = touchscreen_get_mode();
@@ -319,9 +311,8 @@ void gui_usb_screen_run(void)
319 FOR_NB_SCREENS(i) 311 FOR_NB_SCREENS(i)
320 { 312 {
321 screens[i].backlight_on(); 313 screens[i].backlight_on();
314 viewportmanager_theme_undo(i);
322 } 315 }
323 viewportmanager_set_statusbar(old_bars);
324 send_event(GUI_EVENT_REFRESH, NULL);
325 316
326} 317}
327#endif /* !defined(USB_NONE) */ 318#endif /* !defined(USB_NONE) */
diff --git a/apps/gui/viewport.c b/apps/gui/viewport.c
index 9a7cfbd3cb..fbf5ea82ad 100644
--- a/apps/gui/viewport.c
+++ b/apps/gui/viewport.c
@@ -28,6 +28,8 @@
28#include "screen_access.h" 28#include "screen_access.h"
29#include "settings.h" 29#include "settings.h"
30#include "misc.h" 30#include "misc.h"
31#include "panic.h"
32#include "viewport.h"
31 33
32/*some short cuts for fg/bg/line selector handling */ 34/*some short cuts for fg/bg/line selector handling */
33#ifdef HAVE_LCD_COLOR 35#ifdef HAVE_LCD_COLOR
@@ -38,10 +40,6 @@
38#define BG_FALLBACK LCD_DEFAULT_BG 40#define BG_FALLBACK LCD_DEFAULT_BG
39#endif 41#endif
40 42
41#ifdef HAVE_LCD_BITMAP
42static void set_default_align_flags(struct viewport *vp);
43#endif
44
45/* all below isn't needed for pc tools (i.e. checkwps/wps editor) 43/* all below isn't needed for pc tools (i.e. checkwps/wps editor)
46 * only viewport_parse_viewport() is */ 44 * only viewport_parse_viewport() is */
47#ifndef __PCTOOL__ 45#ifndef __PCTOOL__
@@ -56,115 +54,187 @@ static void set_default_align_flags(struct viewport *vp);
56#endif 54#endif
57#include "statusbar-skinned.h" 55#include "statusbar-skinned.h"
58#include "debug.h" 56#include "debug.h"
57#include "viewport.h"
59 58
60 59#define VPSTACK_DEPTH 16
61static int statusbar_enabled = 0; 60struct viewport_stack_item
62 61{
63#ifdef HAVE_LCD_BITMAP
64static struct {
65 struct viewport* vp; 62 struct viewport* vp;
66 int active[NB_SCREENS]; 63 bool enabled;
67} ui_vp_info; 64};
68 65
69static struct viewport custom_vp[NB_SCREENS]; 66#ifdef HAVE_LCD_BITMAP
70
71/* callbacks for GUI_EVENT_* events */
72static void viewportmanager_ui_vp_changed(void *param);
73static void viewportmanager_call_draw_func(void *param);
74static void statusbar_toggled(void* param);
75static unsigned viewport_init_ui_vp(void);
76#endif
77static void viewportmanager_redraw(void* data); 67static void viewportmanager_redraw(void* data);
68
69static int theme_stack_top[NB_SCREENS]; /* the last item added */
70static struct viewport_stack_item theme_stack[NB_SCREENS][VPSTACK_DEPTH];
71static bool is_theme_enabled(enum screen_type screen);
78 72
79int viewport_get_nb_lines(const struct viewport *vp) 73static void toggle_theme(void)
80{ 74{
81#ifdef HAVE_LCD_BITMAP 75 bool enable_event = false;
82 return vp->height/font_get(vp->font)->height; 76 static bool was_enabled[NB_SCREENS] = {false};
83#else 77 int i;
84 (void)vp; 78 FOR_NB_SCREENS(i)
85 return 2; 79 {
80 enable_event = enable_event || is_theme_enabled(i);
81 }
82 if (enable_event)
83 {
84 add_event(GUI_EVENT_ACTIONUPDATE, false, viewportmanager_redraw);
85#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
86 add_event(LCD_EVENT_ACTIVATION, false, do_sbs_update_callback);
86#endif 87#endif
87} 88 add_event(PLAYBACK_EVENT_TRACK_CHANGE, false,
88 89 do_sbs_update_callback);
89static bool showing_bars(enum screen_type screen) 90 add_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, false,
90{ 91 do_sbs_update_callback);
91 if (statusbar_enabled & VP_SB_ONSCREEN(screen)) 92
93 /* remove the left overs from the previous screen.
94 * could cause a tiny flicker. Redo your screen code if that happens */
95 FOR_NB_SCREENS(i)
96 {
97 if (!was_enabled[i])
98 {
99 struct viewport deadspace, user;
100 viewport_set_defaults(&user, i);
101 deadspace = user; /* get colours and everything */
102 /* above */
103 deadspace.x = 0;
104 deadspace.y = 0;
105 deadspace.width = screens[i].lcdwidth;
106 deadspace.height = user.y;
107 if (deadspace.width && deadspace.height)
108 {
109 screens[i].set_viewport(&deadspace);
110 screens[i].clear_viewport();
111 screens[i].update_viewport();
112 }
113 /* below */
114 deadspace.y = user.y + user.height;
115 deadspace.height = screens[i].lcdheight - deadspace.y;
116 if (deadspace.width && deadspace.height)
117 {
118 screens[i].set_viewport(&deadspace);
119 screens[i].clear_viewport();
120 screens[i].update_viewport();
121 }
122 /* left */
123 deadspace.x = 0;
124 deadspace.y = 0;
125 deadspace.width = user.x;
126 deadspace.height = screens[i].lcdheight;
127 if (deadspace.width && deadspace.height)
128 {
129 screens[i].set_viewport(&deadspace);
130 screens[i].clear_viewport();
131 screens[i].update_viewport();
132 }
133 /* below */
134 deadspace.x = user.x + user.width;
135 deadspace.width = screens[i].lcdwidth - deadspace.x;
136 if (deadspace.width && deadspace.height)
137 {
138 screens[i].set_viewport(&deadspace);
139 screens[i].clear_viewport();
140 screens[i].update_viewport();
141 }
142 }
143 }
144 send_event(GUI_EVENT_ACTIONUPDATE, (void*)1); /* force a redraw */
145 }
146 else
92 { 147 {
93#ifdef HAVE_LCD_BITMAP 148 FOR_NB_SCREENS(i)
94 int ignore; 149 screens[i].stop_scroll();
95 ignore = statusbar_enabled & VP_SB_IGNORE_SETTING(screen); 150#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
96 return ignore || (statusbar_position(screen) != STATUSBAR_OFF); 151 remove_event(LCD_EVENT_ACTIVATION, do_sbs_update_callback);
97#else
98 return true;
99#endif 152#endif
153 remove_event(PLAYBACK_EVENT_TRACK_CHANGE, do_sbs_update_callback);
154 remove_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, do_sbs_update_callback);
155 remove_event(GUI_EVENT_ACTIONUPDATE, viewportmanager_redraw);
100 } 156 }
101 return false; 157
158 FOR_NB_SCREENS(i)
159 was_enabled[i] = is_theme_enabled(i);
102} 160}
103 161
104 162void viewportmanager_theme_enable(enum screen_type screen, bool enable,
105void viewportmanager_init(void) 163 struct viewport *viewport)
106{ 164{
107#ifdef HAVE_LCD_BITMAP 165 int top = ++theme_stack_top[screen];
108 add_event(GUI_EVENT_STATUSBAR_TOGGLE, false, statusbar_toggled); 166 if (top >= VPSTACK_DEPTH-1)
109#endif 167 panicf("Stack overflow... viewportmanager");
110 viewportmanager_set_statusbar(VP_SB_ALLSCREENS); 168 theme_stack[screen][top].enabled = enable;
169 theme_stack[screen][top].vp = viewport;
170 toggle_theme();
171 /* then be nice and set the viewport up */
172 if (viewport)
173 viewport_set_defaults(viewport, screen);
111} 174}
112 175
113int viewportmanager_get_statusbar(void) 176void viewportmanager_theme_undo(enum screen_type screen)
114{ 177{
115 return statusbar_enabled; 178 int top = --theme_stack_top[screen];
179 if (top < 0)
180 panicf("Stack underflow... viewportmanager");
181
182 toggle_theme();
116} 183}
117 184
118int viewportmanager_set_statusbar(const int enabled) 185
186static bool is_theme_enabled(enum screen_type screen)
119{ 187{
120 int old = statusbar_enabled; 188 int top = theme_stack_top[screen];
121 int i; 189 return theme_stack[screen][top].enabled;
122 190}
123 statusbar_enabled = enabled;
124 191
125 FOR_NB_SCREENS(i) 192static bool custom_vp_loaded_ok[NB_SCREENS];
126 { 193static struct viewport custom_vp[NB_SCREENS];
127 if (showing_bars(i)
128 && statusbar_position(i) != STATUSBAR_CUSTOM)
129 {
130 add_event(GUI_EVENT_ACTIONUPDATE, false, viewportmanager_redraw);
131 gui_statusbar_draw(&statusbars.statusbars[i], true);
132 }
133 else
134 remove_event(GUI_EVENT_ACTIONUPDATE, viewportmanager_redraw);
135 }
136 194
195static unsigned viewport_init_ui_vp(void);
196#endif /* HAVE_LCD_BITMAP */
197
198int viewport_get_nb_lines(const struct viewport *vp)
199{
137#ifdef HAVE_LCD_BITMAP 200#ifdef HAVE_LCD_BITMAP
138 FOR_NB_SCREENS(i) 201 return vp->height/font_get(vp->font)->height;
139 { 202#else
140 sb_skin_set_state(showing_bars(i) 203 (void)vp;
141 && statusbar_position(i) == STATUSBAR_CUSTOM, i); 204 return 2;
142 }
143#endif 205#endif
144 return old;
145} 206}
146 207
147static void viewportmanager_redraw(void* data) 208static void viewportmanager_redraw(void* data)
148{ 209{
149 int i; 210 int i;
150
151 FOR_NB_SCREENS(i) 211 FOR_NB_SCREENS(i)
152 { 212 {
153 if (showing_bars(i) 213#ifdef HAVE_LCD_BITMAP
154 && statusbar_position(i) != STATUSBAR_CUSTOM) 214 if (statusbar_position(i) == STATUSBAR_CUSTOM)
215 sb_skin_update(i, NULL != data);
216 else if (statusbar_position(i) != STATUSBAR_OFF)
217#endif
155 gui_statusbar_draw(&statusbars.statusbars[i], NULL != data); 218 gui_statusbar_draw(&statusbars.statusbars[i], NULL != data);
156 } 219 }
157} 220}
158#ifdef HAVE_LCD_BITMAP
159 221
160static void statusbar_toggled(void* param) 222void viewportmanager_init()
161{ 223{
162 (void)param; 224#ifdef HAVE_LCD_BITMAP
163 /* update vp manager for the new setting and reposition vps 225 int i;
164 * if necessary */ 226 FOR_NB_SCREENS(i)
165 viewportmanager_theme_changed(THEME_STATUSBAR); 227 {
228 theme_stack_top[i] = -1; /* the next call fixes this to 0 */
229 /* We always want the theme enabled by default... */
230 viewportmanager_theme_enable(i, true, NULL);
231 }
232#else
233 add_event(GUI_EVENT_ACTIONUPDATE, false, viewportmanager_redraw);
234#endif
166} 235}
167 236
237#ifdef HAVE_LCD_BITMAP
168void viewportmanager_theme_changed(const int which) 238void viewportmanager_theme_changed(const int which)
169{ 239{
170 int i; 240 int i;
@@ -177,91 +247,25 @@ void viewportmanager_theme_changed(const int which)
177#endif 247#endif
178 if (which & THEME_UI_VIEWPORT) 248 if (which & THEME_UI_VIEWPORT)
179 { 249 {
180 int retval = viewport_init_ui_vp(); 250 viewport_init_ui_vp();
181 /* reset the ui viewport */
182 FOR_NB_SCREENS(i)
183 ui_vp_info.active[i] = retval & BIT_N(i);
184 /* and point to it */
185 ui_vp_info.vp = custom_vp;
186 } 251 }
187 else if (which & THEME_LANGUAGE) 252 if (which & THEME_LANGUAGE)
188 { /* THEME_UI_VIEWPORT handles rtl already */ 253 {
189 FOR_NB_SCREENS(i)
190 set_default_align_flags(&custom_vp[i]);
191 } 254 }
192 if (which & THEME_STATUSBAR) 255 if (which & THEME_STATUSBAR)
193 { 256 {
194 statusbar_enabled = 0;
195 FOR_NB_SCREENS(i) 257 FOR_NB_SCREENS(i)
196 { 258 {
197 if (statusbar_position(i) != STATUSBAR_OFF) 259 /* This can probably be done better...
198 statusbar_enabled |= VP_SB_ONSCREEN(i); 260 * disable the theme so it's forced to do a full redraw */
261 viewportmanager_theme_enable(i, false, NULL);
262 viewportmanager_theme_undo(i);
199 } 263 }
200
201 viewportmanager_set_statusbar(statusbar_enabled);
202
203 /* reposition viewport to fit statusbar, only if not using the ui vp */
204
205 FOR_NB_SCREENS(i)
206 {
207 if (!ui_vp_info.active[i])
208 viewport_set_fullscreen(&custom_vp[i], i);
209 }
210 }
211
212 int event_add = 0;
213 FOR_NB_SCREENS(i)
214 {
215 event_add |= ui_vp_info.active[i];
216 event_add |= (statusbar_position(i) == STATUSBAR_CUSTOM);
217 }
218
219 /* add one of those to ensure the draw function is called always */
220 if (event_add)
221 {
222 add_event(GUI_EVENT_REFRESH, false, viewportmanager_ui_vp_changed);
223 remove_event(GUI_EVENT_REFRESH, viewportmanager_call_draw_func);
224 }
225 else
226 {
227 add_event(GUI_EVENT_REFRESH, false, viewportmanager_call_draw_func);
228 remove_event(GUI_EVENT_REFRESH, viewportmanager_ui_vp_changed);
229 } 264 }
230
231 send_event(GUI_EVENT_THEME_CHANGED, NULL); 265 send_event(GUI_EVENT_THEME_CHANGED, NULL);
232} 266}
233 267
234/* 268/*
235 * simply calls a function that draws stuff, this exists to ensure the
236 * drawing function call in the GUI_EVENT_REFRESH event
237 *
238 * param should be 'void func(void)' */
239static void viewportmanager_call_draw_func(void *param)
240{
241 /* cast param to a function */
242 void (*draw_func)(void) = ((void(*)(void))param);
243 /* call the passed function which will redraw the content of
244 * the current screen */
245 if (draw_func != NULL)
246 draw_func();
247}
248
249static void viewportmanager_ui_vp_changed(void *param)
250{
251 /* if the user changed the theme, we need to initiate a full redraw */
252 int i;
253 /* start with clearing the screen */
254 FOR_NB_SCREENS(i)
255 screens[i].clear_display();
256 /* redraw the statusbar if it was enabled */
257 send_event(GUI_EVENT_ACTIONUPDATE, (void*)true);
258 /* call redraw function */
259 viewportmanager_call_draw_func(param);
260 FOR_NB_SCREENS(i)
261 screens[i].update();
262}
263
264/*
265 * (re)parse the UI vp from the settings 269 * (re)parse the UI vp from the settings
266 * - Returns 270 * - Returns
267 * 0 if no UI vp is used at all 271 * 0 if no UI vp is used at all
@@ -270,7 +274,7 @@ static void viewportmanager_ui_vp_changed(void *param)
270static unsigned viewport_init_ui_vp(void) 274static unsigned viewport_init_ui_vp(void)
271{ 275{
272 int screen; 276 int screen;
273 unsigned ret = 0; 277 const char *ret = NULL;
274 char *setting; 278 char *setting;
275 FOR_NB_SCREENS(screen) 279 FOR_NB_SCREENS(screen)
276 { 280 {
@@ -280,15 +284,13 @@ static unsigned viewport_init_ui_vp(void)
280 else 284 else
281#endif 285#endif
282 setting = global_settings.ui_vp_config; 286 setting = global_settings.ui_vp_config;
283
284 287
285 if (!(viewport_parse_viewport(&custom_vp[screen], screen, 288 ret = viewport_parse_viewport(&custom_vp[screen], screen,
286 setting, ','))) 289 setting, ',');
287 viewport_set_fullscreen(&custom_vp[screen], screen); 290
288 else 291 custom_vp_loaded_ok[screen] = ret?true:false;
289 ret |= BIT_N(screen);
290 } 292 }
291 return ret; 293 return true; /* meh fixme */
292} 294}
293 295
294#ifdef HAVE_TOUCHSCREEN 296#ifdef HAVE_TOUCHSCREEN
@@ -301,6 +303,16 @@ bool viewport_point_within_vp(const struct viewport *vp,
301 return (is_x && is_y); 303 return (is_x && is_y);
302} 304}
303#endif /* HAVE_TOUCHSCREEN */ 305#endif /* HAVE_TOUCHSCREEN */
306
307static void set_default_align_flags(struct viewport *vp)
308{
309 vp->flags &= ~VP_FLAG_ALIGNMENT_MASK;
310#ifndef __PCTOOL__
311 if (UNLIKELY(lang_is_rtl()))
312 vp->flags |= VP_FLAG_ALIGN_RIGHT;
313#endif
314}
315
304#endif /* HAVE_LCD_BITMAP */ 316#endif /* HAVE_LCD_BITMAP */
305#endif /* __PCTOOL__ */ 317#endif /* __PCTOOL__ */
306 318
@@ -363,11 +375,17 @@ void viewport_set_defaults(struct viewport *vp,
363#if defined(HAVE_LCD_BITMAP) && !defined(__PCTOOL__) 375#if defined(HAVE_LCD_BITMAP) && !defined(__PCTOOL__)
364 376
365 struct viewport *sbs_area = NULL, *user_setting = NULL; 377 struct viewport *sbs_area = NULL, *user_setting = NULL;
378 if (!is_theme_enabled(screen))
379 {
380 viewport_set_fullscreen(vp, screen);
381 return;
382 }
366 /* get the two viewports */ 383 /* get the two viewports */
367 if (ui_vp_info.active[screen]) 384 if (custom_vp_loaded_ok[screen])
368 user_setting = &ui_vp_info.vp[screen]; 385 user_setting = &custom_vp[screen];
369 if (sb_skin_get_state(screen)) 386 if (sb_skin_get_state(screen))
370 sbs_area = sb_skin_get_info_vp(screen); 387 sbs_area = sb_skin_get_info_vp(screen);
388
371 /* have both? get their intersection */ 389 /* have both? get their intersection */
372 if (sbs_area && user_setting) 390 if (sbs_area && user_setting)
373 { 391 {
@@ -380,6 +398,7 @@ void viewport_set_defaults(struct viewport *vp,
380 { 398 {
381 /* copy from ui vp first (for other field),fix coordinates after */ 399 /* copy from ui vp first (for other field),fix coordinates after */
382 *vp = *user_setting; 400 *vp = *user_setting;
401 set_default_align_flags(vp);
383 vp->x = MAX(a->x, b->x); 402 vp->x = MAX(a->x, b->x);
384 vp->y = MAX(a->y, b->y); 403 vp->y = MAX(a->y, b->y);
385 vp->width = MIN(a->x + a->width, b->x + b->width) - vp->x; 404 vp->width = MIN(a->x + a->width, b->x + b->width) - vp->x;
@@ -405,16 +424,6 @@ void viewport_set_defaults(struct viewport *vp,
405 424
406 425
407#ifdef HAVE_LCD_BITMAP 426#ifdef HAVE_LCD_BITMAP
408
409static void set_default_align_flags(struct viewport *vp)
410{
411 vp->flags &= ~VP_FLAG_ALIGNMENT_MASK;
412#ifndef __PCTOOL__
413 if (UNLIKELY(lang_is_rtl()))
414 vp->flags |= VP_FLAG_ALIGN_RIGHT;
415#endif
416}
417
418const char* viewport_parse_viewport(struct viewport *vp, 427const char* viewport_parse_viewport(struct viewport *vp,
419 enum screen_type screen, 428 enum screen_type screen,
420 const char *bufptr, 429 const char *bufptr,
diff --git a/apps/gui/viewport.h b/apps/gui/viewport.h
index 54424339ca..6cb8d1f574 100644
--- a/apps/gui/viewport.h
+++ b/apps/gui/viewport.h
@@ -31,60 +31,30 @@
31/* return the number of text lines in the vp viewport */ 31/* return the number of text lines in the vp viewport */
32int viewport_get_nb_lines(const struct viewport *vp); 32int viewport_get_nb_lines(const struct viewport *vp);
33 33
34void viewport_set_defaults(struct viewport *vp,
35 const enum screen_type screen);
36
37/* Used to specify which screens the statusbar (SB) should be displayed on.
38 *
39 * The parameter is a bit OR'ed combination of the following (screen is
40 * SCREEN_MAIN or SCREEN_REMOTE from screen_access.h):
41 *
42 * VP_SB_HIDE_ALL means "hide the SB on all screens"
43 * VP_SB_ONSCREEN(screen) means "display the SB on the given screen
44 * as specified by the SB setting for that screen"
45 * VP_SB_IGNORE_SETTING(screen) means "ignore the SB setting for that screen"
46 * VP_SB_ALLSCREENS means "VP_SB_ONSCREEN for all screens"
47 *
48 * In most cases, VP_SB_ALLSCREENS should be used which means display the SB
49 * as specified by the settings.
50 * For the WPS (and other possible exceptions) use VP_SB_IGNORE_SETTING() to
51 * FORCE the statusbar on for the given screen (i.e it will show regardless
52 * of the setting)
53 *
54 * Returns the status before the call. This value can be used to restore the
55 * SB "displaying rules".
56 */
57
58
59#define THEME_STATUSBAR (BIT_N(0)) 34#define THEME_STATUSBAR (BIT_N(0))
60#define THEME_UI_VIEWPORT (BIT_N(1)) 35#define THEME_UI_VIEWPORT (BIT_N(1))
61#define THEME_BUTTONBAR (BIT_N(2)) 36#define THEME_BUTTONBAR (BIT_N(2))
62#define THEME_LANGUAGE (BIT_N(3)) 37#define THEME_LANGUAGE (BIT_N(3))
63#define THEME_ALL (~(0u)) 38#define THEME_ALL (~(0u))
64 39
65#define VP_SB_HIDE_ALL 0
66#define VP_SB_ONSCREEN(screen) BIT_N(screen)
67#define VP_SB_IGNORE_SETTING(screen) BIT_N(4+screen)
68#define VP_SB_ALLSCREENS (VP_SB_ONSCREEN(0)|VP_SB_ONSCREEN(1))
69
70#ifndef __PCTOOL__ 40#ifndef __PCTOOL__
71/* 41/*
72 * Initialize the viewportmanager, which in turns initializes the UI vp and 42 * Initialize the viewportmanager, which in turns initializes the UI vp and
73 * statusbar stuff 43 * statusbar stuff
74 */ 44 */
75void viewportmanager_init(void); 45void viewportmanager_init(void);
76int viewportmanager_get_statusbar(void);
77int viewportmanager_set_statusbar(const int enabled);
78 46
79 47
80/* 48void viewport_set_defaults(struct viewport *vp,
81 * Initializes the given viewport with maximum dimensions minus status- and 49 const enum screen_type screen);
82 * buttonbar
83 */
84void viewport_set_fullscreen(struct viewport *vp, 50void viewport_set_fullscreen(struct viewport *vp,
85 const enum screen_type screen); 51 const enum screen_type screen);
86 52
87#ifdef HAVE_LCD_BITMAP 53#ifdef HAVE_LCD_BITMAP
54void viewportmanager_theme_enable(enum screen_type screen, bool enable,
55 struct viewport *viewport);
56
57void viewportmanager_theme_undo(enum screen_type screen);
88 58
89/* call this when a theme changed */ 59/* call this when a theme changed */
90void viewportmanager_theme_changed(const int); 60void viewportmanager_theme_changed(const int);
@@ -95,9 +65,9 @@ bool viewport_point_within_vp(const struct viewport *vp,
95#endif 65#endif
96 66
97#else /* HAVE_LCD_CHARCELL */ 67#else /* HAVE_LCD_CHARCELL */
98#define viewport_set_current_vp(a)
99#define viewport_get_current_vp() NULL
100#define viewportmanager_theme_changed(a) 68#define viewportmanager_theme_changed(a)
69#define viewportmanager_theme_enable(...)
70#define viewportmanager_theme_undo(...)
101#endif 71#endif
102 72
103#endif /* __PCTOOL__ */ 73#endif /* __PCTOOL__ */
diff --git a/apps/gui/wps.c b/apps/gui/wps.c
index 757160a586..e500f1c2d9 100644
--- a/apps/gui/wps.c
+++ b/apps/gui/wps.c
@@ -88,9 +88,6 @@ static struct wps_sync_data wps_sync_data = { .do_full_update = false
88static void wps_state_init(void); 88static void wps_state_init(void);
89static void track_changed_callback(void *param); 89static void track_changed_callback(void *param);
90static void nextid3available_callback(void* param); 90static void nextid3available_callback(void* param);
91#ifdef HAVE_LCD_BITMAP
92static void statusbar_toggle_handler(void *data);
93#endif
94 91
95#define WPS_DEFAULTCFG WPS_DIR "/rockbox_default.wps" 92#define WPS_DEFAULTCFG WPS_DIR "/rockbox_default.wps"
96#ifdef HAVE_REMOTE_LCD 93#ifdef HAVE_REMOTE_LCD
@@ -562,24 +559,21 @@ static void wps_lcd_activation_hook(void *param)
562 559
563static void gwps_leave_wps(void) 560static void gwps_leave_wps(void)
564{ 561{
565 int i, oldbars = VP_SB_HIDE_ALL; 562 int i;
566 563
567 FOR_NB_SCREENS(i) 564 FOR_NB_SCREENS(i)
568 { 565 {
569 gui_wps[i].display->stop_scroll(); 566 gui_wps[i].display->stop_scroll();
570 gui_wps[i].display->backdrop_show(BACKDROP_MAIN); 567 gui_wps[i].display->backdrop_show(BACKDROP_MAIN);
571 if (statusbar_position(i) != STATUSBAR_OFF) 568 viewportmanager_theme_undo(i);
572 oldbars |= VP_SB_ONSCREEN(i);
573 } 569 }
574 570
575 viewportmanager_set_statusbar(oldbars);
576#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) 571#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
577 /* Play safe and unregister the hook */ 572 /* Play safe and unregister the hook */
578 remove_event(LCD_EVENT_ACTIVATION, wps_lcd_activation_hook); 573 remove_event(LCD_EVENT_ACTIVATION, wps_lcd_activation_hook);
579#endif 574#endif
580 /* unhandle statusbar update delay */ 575 /* unhandle statusbar update delay */
581 sb_skin_set_update_delay(DEFAULT_UPDATE_DELAY); 576 sb_skin_set_update_delay(DEFAULT_UPDATE_DELAY);
582 send_event(GUI_EVENT_REFRESH, NULL);
583} 577}
584 578
585/* 579/*
@@ -591,6 +585,14 @@ static void gwps_enter_wps(void)
591 { 585 {
592 struct gui_wps *gwps = &gui_wps[i]; 586 struct gui_wps *gwps = &gui_wps[i];
593 struct screen *display = gwps->display; 587 struct screen *display = gwps->display;
588#ifdef HAVE_LCD_BITMAP
589 bool draw = false;
590 if (gui_wps[i].data->wps_sb_tag)
591 draw = gui_wps[i].data->show_sb_on_wps;
592 else if (statusbar_position(i) != STATUSBAR_OFF)
593 draw = true;
594#endif
595 viewportmanager_theme_enable(i, draw, NULL);
594 596
595 display->stop_scroll(); 597 display->stop_scroll();
596 /* Update the values in the first (default) viewport - in case the user 598 /* Update the values in the first (default) viewport - in case the user
@@ -725,8 +727,6 @@ long gui_wps_show(void)
725#ifdef HAVE_LCD_CHARCELLS 727#ifdef HAVE_LCD_CHARCELLS
726 status_set_audio(true); 728 status_set_audio(true);
727 status_set_param(false); 729 status_set_param(false);
728#else
729 statusbar_toggle_handler(NULL);
730#endif 730#endif
731 731
732#ifdef AB_REPEAT_ENABLE 732#ifdef AB_REPEAT_ENABLE
@@ -734,7 +734,7 @@ long gui_wps_show(void)
734 ab_reset_markers(); 734 ab_reset_markers();
735#endif 735#endif
736 wps_state_init(); 736 wps_state_init();
737 737
738 while ( 1 ) 738 while ( 1 )
739 { 739 {
740 bool audio_paused = (audio_status() & AUDIO_STATUS_PAUSE)?true:false; 740 bool audio_paused = (audio_status() & AUDIO_STATUS_PAUSE)?true:false;
@@ -1176,8 +1176,8 @@ long gui_wps_show(void)
1176 sb_skin_set_update_delay(0); 1176 sb_skin_set_update_delay(0);
1177 FOR_NB_SCREENS(i) 1177 FOR_NB_SCREENS(i)
1178 gui_wps[i].display->backdrop_show(BACKDROP_SKIN_WPS); 1178 gui_wps[i].display->backdrop_show(BACKDROP_SKIN_WPS);
1179 send_event(GUI_EVENT_REFRESH, gwps_enter_wps);
1180 wps_sync_data.do_full_update = update = false; 1179 wps_sync_data.do_full_update = update = false;
1180 gwps_enter_wps();
1181 } 1181 }
1182 else if (wps_sync_data.do_full_update || update) 1182 else if (wps_sync_data.do_full_update || update)
1183 { 1183 {
@@ -1271,33 +1271,6 @@ static void wps_state_init(void)
1271} 1271}
1272 1272
1273 1273
1274#ifdef HAVE_LCD_BITMAP
1275static void statusbar_toggle_handler(void *data)
1276{
1277 (void)data;
1278 int i;
1279
1280 int *wpsbars = &wps_sync_data.statusbars;
1281 *wpsbars = VP_SB_HIDE_ALL;
1282 FOR_NB_SCREENS(i)
1283 { /* fix viewports if needed */
1284 skin_statusbar_changed(&gui_wps[i]);
1285
1286 bool draw = false;
1287
1288 /* fix up gui_wps::statusbars, so that the viewportmanager accepts it*/
1289 if (gui_wps[i].data->wps_sb_tag)
1290 draw = gui_wps[i].data->show_sb_on_wps;
1291 else if (statusbar_position(i) != STATUSBAR_OFF)
1292 draw = true;
1293 if (draw)
1294 *wpsbars |=
1295 (VP_SB_ONSCREEN(i) | VP_SB_IGNORE_SETTING(i));
1296 }
1297}
1298#endif
1299
1300
1301void gui_sync_wps_init(void) 1274void gui_sync_wps_init(void)
1302{ 1275{
1303 int i; 1276 int i;
@@ -1315,11 +1288,7 @@ void gui_sync_wps_init(void)
1315 gui_wps[i].display->backdrop_unload(BACKDROP_SKIN_WPS); 1288 gui_wps[i].display->backdrop_unload(BACKDROP_SKIN_WPS);
1316 /* must point to the same struct for both screens */ 1289 /* must point to the same struct for both screens */
1317 gui_wps[i].sync_data = &wps_sync_data; 1290 gui_wps[i].sync_data = &wps_sync_data;
1318 gui_wps[i].sync_data->statusbars = VP_SB_ALLSCREENS;
1319 } 1291 }
1320#ifdef HAVE_LCD_BITMAP
1321 add_event(GUI_EVENT_STATUSBAR_TOGGLE, false, statusbar_toggle_handler);
1322#endif
1323} 1292}
1324 1293
1325 1294