diff options
Diffstat (limited to 'apps/gui/bitmap')
-rw-r--r-- | apps/gui/bitmap/list-skinned.c | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/apps/gui/bitmap/list-skinned.c b/apps/gui/bitmap/list-skinned.c new file mode 100644 index 0000000000..2f3ca2bd2d --- /dev/null +++ b/apps/gui/bitmap/list-skinned.c | |||
@@ -0,0 +1,231 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2011 by Jonathan Gordon | ||
11 | * | ||
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. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "config.h" | ||
23 | #include "lcd.h" | ||
24 | #include "font.h" | ||
25 | #include "button.h" | ||
26 | #include "string.h" | ||
27 | #include "settings.h" | ||
28 | #include "kernel.h" | ||
29 | #include "system.h" | ||
30 | #include "file.h" | ||
31 | |||
32 | #include "action.h" | ||
33 | #include "screen_access.h" | ||
34 | #include "list.h" | ||
35 | #include "scrollbar.h" | ||
36 | #include "lang.h" | ||
37 | #include "sound.h" | ||
38 | #include "misc.h" | ||
39 | #include "viewport.h" | ||
40 | #include "statusbar-skinned.h" | ||
41 | #include "skin_engine/skin_engine.h" | ||
42 | #include "skin_engine/skin_display.h" | ||
43 | #include "appevents.h" | ||
44 | |||
45 | static struct listitem_viewport_cfg *listcfg[NB_SCREENS] = {NULL}; | ||
46 | static const char *current_item_text_ptr; | ||
47 | static char current_item_text[MAX_PATH]; | ||
48 | static enum themable_icons current_item_icon; | ||
49 | void skinlist_set_cfg(enum screen_type screen, | ||
50 | struct listitem_viewport_cfg *cfg) | ||
51 | { | ||
52 | if (listcfg[screen] != cfg) | ||
53 | { | ||
54 | if (listcfg[screen]) | ||
55 | screens[screen].scroll_stop(&listcfg[screen]->selected_item_vp.vp); | ||
56 | listcfg[screen] = cfg; | ||
57 | current_item_text_ptr = ""; | ||
58 | } | ||
59 | } | ||
60 | |||
61 | static bool skinlist_is_configured(enum screen_type screen, | ||
62 | struct gui_synclist *list) | ||
63 | { | ||
64 | return (listcfg[screen] != NULL) && | ||
65 | (!list || (list && list->selected_size == 1)); | ||
66 | } | ||
67 | |||
68 | const char* skinlist_get_item_text(void) | ||
69 | { | ||
70 | const char* ret = P2STR((unsigned char*)current_item_text_ptr); | ||
71 | return ret; | ||
72 | } | ||
73 | enum themable_icons skinlist_get_item_icon(void) | ||
74 | { | ||
75 | return current_item_icon; | ||
76 | } | ||
77 | |||
78 | static bool is_selected = false; | ||
79 | bool skinlist_is_selected_item(void) | ||
80 | { | ||
81 | return is_selected; | ||
82 | } | ||
83 | |||
84 | int skinlist_get_line_count(enum screen_type screen, struct gui_synclist *list) | ||
85 | { | ||
86 | struct viewport *parent = (list->parent[screen]); | ||
87 | if (!skinlist_is_configured(screen, list)) | ||
88 | return -1; | ||
89 | if (listcfg[screen]->tile == true) | ||
90 | { | ||
91 | int rows = (parent->height / listcfg[screen]->height); | ||
92 | int cols = (parent->width / listcfg[screen]->width); | ||
93 | return rows*cols; | ||
94 | } | ||
95 | else | ||
96 | return (parent->height / listcfg[screen]->height); | ||
97 | } | ||
98 | |||
99 | static int current_item; | ||
100 | static int current_nbitems; | ||
101 | static bool needs_scrollbar[NB_SCREENS]; | ||
102 | bool skinlist_needs_scrollbar(enum screen_type screen) | ||
103 | { | ||
104 | return needs_scrollbar[screen]; | ||
105 | } | ||
106 | |||
107 | void skinlist_get_scrollbar(int* nb_item, int* first_shown, int* last_shown) | ||
108 | { | ||
109 | if (!skinlist_is_configured(0, NULL)) | ||
110 | { | ||
111 | *nb_item = 0; | ||
112 | *first_shown = 0; | ||
113 | *last_shown = 0; | ||
114 | } | ||
115 | else | ||
116 | { | ||
117 | *nb_item = current_item; | ||
118 | *first_shown = 0; | ||
119 | *last_shown = current_nbitems; | ||
120 | } | ||
121 | } | ||
122 | |||
123 | bool skinlist_draw(struct screen *display, struct gui_synclist *list) | ||
124 | { | ||
125 | int cur_line, display_lines; | ||
126 | const int screen = display->screen_type; | ||
127 | struct viewport *parent = (list->parent[screen]); | ||
128 | char* label = NULL; | ||
129 | const int list_start_item = list->start_item[screen]; | ||
130 | struct gui_wps wps; | ||
131 | if (!skinlist_is_configured(screen, list)) | ||
132 | return false; | ||
133 | wps.display = display; | ||
134 | wps.data = listcfg[screen]->data; | ||
135 | display_lines = skinlist_get_line_count(screen, list); | ||
136 | label = listcfg[screen]->label; | ||
137 | display->set_viewport(parent); | ||
138 | display->clear_viewport(); | ||
139 | current_item = list->selected_item; | ||
140 | current_nbitems = list->nb_items; | ||
141 | needs_scrollbar[screen] = list->nb_items > display_lines; | ||
142 | |||
143 | for (cur_line = 0; cur_line < display_lines; cur_line++) | ||
144 | { | ||
145 | struct skin_element* viewport; | ||
146 | struct skin_viewport* skin_viewport; | ||
147 | if (list_start_item+cur_line+1 > list->nb_items) | ||
148 | break; | ||
149 | is_selected = list->show_selection_marker && | ||
150 | list_start_item+cur_line == list->selected_item; | ||
151 | current_item_text_ptr = list->callback_get_item_name( | ||
152 | list_start_item+cur_line, | ||
153 | list->data, current_item_text, MAX_PATH); | ||
154 | if (list->callback_get_item_icon != NULL) | ||
155 | current_item_icon = list->callback_get_item_icon( | ||
156 | list_start_item+cur_line, list->data); | ||
157 | |||
158 | for (viewport = listcfg[screen]->data->tree; | ||
159 | viewport; | ||
160 | viewport = viewport->next) | ||
161 | { | ||
162 | int origional_x, origional_y; | ||
163 | int origional_w, origional_h; | ||
164 | skin_viewport = (struct skin_viewport*)viewport->data; | ||
165 | if (viewport->children == 0 || !skin_viewport->label || | ||
166 | (skin_viewport->label && strcmp(label, skin_viewport->label)) | ||
167 | ) | ||
168 | continue; | ||
169 | if (is_selected) | ||
170 | { | ||
171 | memcpy(&listcfg[screen]->selected_item_vp, skin_viewport, sizeof(struct skin_viewport)); | ||
172 | skin_viewport = &listcfg[screen]->selected_item_vp; | ||
173 | } | ||
174 | origional_x = skin_viewport->vp.x; | ||
175 | origional_y = skin_viewport->vp.y; | ||
176 | origional_w = skin_viewport->vp.width; | ||
177 | origional_h = skin_viewport->vp.height; | ||
178 | if (listcfg[screen]->tile) | ||
179 | { | ||
180 | int cols = (parent->width / listcfg[screen]->width); | ||
181 | int col = (cur_line)%cols; | ||
182 | int row = (cur_line)/cols; | ||
183 | |||
184 | skin_viewport->vp.x = parent->x + listcfg[screen]->width*col + origional_x; | ||
185 | skin_viewport->vp.y = parent->y + listcfg[screen]->height*row + origional_y; | ||
186 | } | ||
187 | else | ||
188 | { | ||
189 | skin_viewport->vp.x = parent->x + origional_x; | ||
190 | skin_viewport->vp.y = parent->y + origional_y + | ||
191 | (listcfg[screen]->height*cur_line); | ||
192 | } | ||
193 | display->set_viewport(&skin_viewport->vp); | ||
194 | #ifdef HAVE_LCD_BITMAP | ||
195 | /* Set images to not to be displayed */ | ||
196 | struct skin_token_list *imglist = wps.data->images; | ||
197 | while (imglist) | ||
198 | { | ||
199 | struct gui_img *img = (struct gui_img *)imglist->token->value.data; | ||
200 | img->display = -1; | ||
201 | imglist = imglist->next; | ||
202 | } | ||
203 | #endif | ||
204 | skin_render_viewport(viewport->children[0], | ||
205 | &wps, skin_viewport, SKIN_REFRESH_ALL); | ||
206 | #ifdef HAVE_LCD_BITMAP | ||
207 | wps_display_images(&wps, &skin_viewport->vp); | ||
208 | #endif | ||
209 | /* force disableing scroll because it breaks later */ | ||
210 | if (!is_selected) | ||
211 | { | ||
212 | display->scroll_stop(&skin_viewport->vp); | ||
213 | skin_viewport->vp.x = origional_x; | ||
214 | skin_viewport->vp.y = origional_y; | ||
215 | skin_viewport->vp.width = origional_w; | ||
216 | skin_viewport->vp.height = origional_h; | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | display->set_viewport(parent); | ||
221 | display->update_viewport(); | ||
222 | current_item_text_ptr = list->callback_get_item_name( | ||
223 | list->selected_item, | ||
224 | list->data, current_item_text, 2048); | ||
225 | #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) | ||
226 | /* Abuse the callback to force the sbs to update */ | ||
227 | send_event(LCD_EVENT_ACTIVATION, NULL); | ||
228 | #endif | ||
229 | return true; | ||
230 | } | ||
231 | |||