1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
26 #include "appevents.h"
28 #include "screen_access.h"
29 #include "skin_engine/skin_engine.h"
30 #include "skin_engine/wps_internals.h"
32 #include "statusbar.h"
33 #include "statusbar-skinned.h"
37 /* currently only one wps_state is needed */
38 extern struct wps_state wps_state
; /* from wps.c */
39 static struct gui_wps sb_skin
[NB_SCREENS
] = {{ .data
= NULL
}};
40 static struct wps_data sb_skin_data
[NB_SCREENS
] = {{ .wps_loaded
= 0 }};
41 static struct wps_sync_data sb_skin_sync_data
= { .do_full_update
= false };
43 /* initial setup of wps_data */
44 static void sb_skin_update(void*);
45 static bool loaded_ok
[NB_SCREENS
] = { false };
46 static int update_delay
= DEFAULT_UPDATE_DELAY
;
49 void sb_skin_data_load(enum screen_type screen
, const char *buf
, bool isfile
)
51 struct wps_data
*data
= sb_skin
[screen
].data
;
54 success
= buf
&& skin_data_load(screen
, data
, buf
, isfile
);
57 { /* hide the sb's default viewport because it has nasty effect with stuff
58 * not part of the statusbar,
59 * hence .sbs's without any other vps are unsupported*/
60 struct skin_viewport
*vp
= find_viewport(VP_DEFAULT_LABEL
, data
);
61 struct skin_token_list
*next_vp
= data
->viewports
->next
;
64 { /* no second viewport, let parsing fail */
67 /* hide this viewport, forever */
68 vp
->hidden_flags
= VP_NEVER_VISIBLE
;
72 remove_event(GUI_EVENT_ACTIONUPDATE
, sb_skin_update
);
74 loaded_ok
[screen
] = success
;
77 /* temporary viewport structs while the non-skinned bar is in the build */
78 static struct viewport inbuilt
[NB_SCREENS
];
79 struct viewport
*sb_skin_get_info_vp(enum screen_type screen
)
81 int bar_setting
= global_settings
.statusbar
;
83 if (screen
== SCREEN_REMOTE
)
84 bar_setting
= global_settings
.remote_statusbar
;
86 if (bar_setting
== STATUSBAR_CUSTOM
)
87 return &find_viewport(VP_INFO_LABEL
, sb_skin
[screen
].data
)->vp
;
88 else if (bar_setting
== STATUSBAR_OFF
)
92 viewport_set_fullscreen(&inbuilt
[screen
], screen
);
93 /* WE need to return the UI area.. NOT the statusbar area! */
94 if (bar_setting
== STATUSBAR_TOP
)
95 inbuilt
[screen
].y
= STATUSBAR_HEIGHT
;
96 inbuilt
[screen
].height
-= STATUSBAR_HEIGHT
;
97 return &inbuilt
[screen
];
101 inline bool sb_skin_get_state(enum screen_type screen
)
103 int skinbars
= sb_skin
[screen
].sync_data
->statusbars
;
104 /* Temp fix untill the hardcoded bar is removed */
105 int bar_setting
= global_settings
.statusbar
;
107 if (screen
== SCREEN_REMOTE
)
108 bar_setting
= global_settings
.remote_statusbar
;
112 case STATUSBAR_CUSTOM
:
113 return loaded_ok
[screen
] && (skinbars
& VP_SB_ONSCREEN(screen
));
115 case STATUSBAR_BOTTOM
:
117 return (viewportmanager_get_statusbar()&VP_SB_ONSCREEN(screen
));
119 return false; /* Should never actually get here */
123 static void do_update_callback(void *param
)
126 /* the WPS handles changing the actual id3 data in the id3 pointers
127 * we imported, we just want a full update */
128 sb_skin_sync_data
.do_full_update
= true;
129 /* force timeout in wps main loop, so that the update is instantly */
130 queue_post(&button_queue
, BUTTON_NONE
, 0);
134 void sb_skin_set_state(int state
, enum screen_type screen
)
136 sb_skin
[screen
].sync_data
->do_full_update
= true;
137 int skinbars
= sb_skin
[screen
].sync_data
->statusbars
;
140 skinbars
|= VP_SB_ONSCREEN(screen
);
144 skinbars
&= ~VP_SB_ONSCREEN(screen
);
149 #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
150 add_event(LCD_EVENT_ACTIVATION
, false, do_update_callback
);
152 add_event(PLAYBACK_EVENT_TRACK_CHANGE
, false,
154 add_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE
, false,
156 add_event(GUI_EVENT_ACTIONUPDATE
, false, sb_skin_update
);
160 #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
161 remove_event(LCD_EVENT_ACTIVATION
, do_update_callback
);
163 remove_event(PLAYBACK_EVENT_TRACK_CHANGE
, do_update_callback
);
164 remove_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE
, do_update_callback
);
165 remove_event(GUI_EVENT_ACTIONUPDATE
, sb_skin_update
);
168 sb_skin
[screen
].sync_data
->statusbars
= skinbars
;
171 static void sb_skin_update(void* param
)
173 static long next_update
= 0;
175 int forced_draw
= param
|| sb_skin
[SCREEN_MAIN
].sync_data
->do_full_update
;
176 if (TIME_AFTER(current_tick
, next_update
) || forced_draw
)
180 if (sb_skin_get_state(i
))
182 #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
183 /* currently, all remotes are readable without backlight
184 * so still update those */
185 if (lcd_active() || (i
!= SCREEN_MAIN
))
187 skin_update(&sb_skin
[i
], forced_draw
?
188 WPS_REFRESH_ALL
: WPS_REFRESH_NON_STATIC
);
191 next_update
= current_tick
+ update_delay
; /* don't update too often */
192 sb_skin
[SCREEN_MAIN
].sync_data
->do_full_update
= false;
196 void sb_skin_set_update_delay(int delay
)
198 update_delay
= delay
;
202 void sb_skin_init(void)
208 sb_skin_data
[i
].albumart
= NULL
;
209 sb_skin_data
[i
].playback_aa_slot
= -1;
211 sb_skin
[i
].data
= &sb_skin_data
[i
];
212 sb_skin
[i
].display
= &screens
[i
];
213 /* Currently no seperate wps_state needed/possible
214 so use the only available ( "global" ) one */
215 sb_skin
[i
].state
= &wps_state
;
216 sb_skin_sync_data
.statusbars
= VP_SB_HIDE_ALL
;
217 sb_skin
[i
].sync_data
= &sb_skin_sync_data
;