Bump version numbers for 3.13
[maemo-rb.git] / apps / gui / bitmap / list-skinned.c
blobd0803b5dc891725aec54da7fe2cdde277ebd59c3
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2011 by Jonathan Gordon
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"
23 #include "system.h"
24 #include "lcd.h"
25 #include "font.h"
26 #include "button.h"
27 #include "string.h"
28 #include "settings.h"
29 #include "kernel.h"
30 #include "file.h"
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"
45 static struct listitem_viewport_cfg *listcfg[NB_SCREENS] = {NULL};
46 static struct gui_synclist *current_list;
48 static int current_row;
49 static int current_column;
51 void skinlist_set_cfg(enum screen_type screen,
52 struct listitem_viewport_cfg *cfg)
54 if (listcfg[screen] != cfg)
56 if (listcfg[screen])
57 screens[screen].scroll_stop(&listcfg[screen]->selected_item_vp.vp);
58 listcfg[screen] = cfg;
59 current_list = NULL;
60 current_column = -1;
61 current_row = -1;
65 static bool skinlist_is_configured(enum screen_type screen,
66 struct gui_synclist *list)
68 return (listcfg[screen] != NULL) &&
69 (!list || (list && list->selected_size == 1));
71 static int current_drawing_line;
72 static int offset_to_item(int offset, bool wrap)
74 int item = current_drawing_line + offset;
75 if (!current_list || current_list->nb_items == 0)
76 return -1;
77 if (item < 0)
79 if (!wrap)
80 return -1;
81 else
82 item = (item + current_list->nb_items) % current_list->nb_items;
84 else if (item >= current_list->nb_items && !wrap)
85 return -1;
86 else
87 item = item % current_list->nb_items;
88 return item;
91 int skinlist_get_item_number()
93 return current_drawing_line;
96 int skinlist_get_item_row()
98 return current_row;
101 int skinlist_get_item_column()
103 return current_column;
107 const char* skinlist_get_item_text(int offset, bool wrap, char* buf, size_t buf_size)
109 int item = offset_to_item(offset, wrap);
110 if (item < 0 || !current_list)
111 return NULL;
112 const char* ret = current_list->callback_get_item_name(
113 item, current_list->data, buf, buf_size);
114 return P2STR((unsigned char*)ret);
117 enum themable_icons skinlist_get_item_icon(int offset, bool wrap)
119 int item = offset_to_item(offset, wrap);
120 if (item < 0 || !current_list || current_list->callback_get_item_icon == NULL)
121 return Icon_NOICON;
122 return current_list->callback_get_item_icon(item, current_list->data);
125 static bool is_selected = false;
126 bool skinlist_is_selected_item(void)
128 return is_selected;
131 int skinlist_get_line_count(enum screen_type screen, struct gui_synclist *list)
133 struct viewport *parent = (list->parent[screen]);
134 if (!skinlist_is_configured(screen, list))
135 return -1;
136 if (listcfg[screen]->tile == true)
138 int rows = (parent->height / listcfg[screen]->height);
139 int cols = (parent->width / listcfg[screen]->width);
140 return rows*cols;
142 else
143 return (parent->height / listcfg[screen]->height);
146 static int current_item;
147 static int current_nbitems;
148 static bool needs_scrollbar[NB_SCREENS];
149 bool skinlist_needs_scrollbar(enum screen_type screen)
151 return needs_scrollbar[screen];
154 void skinlist_get_scrollbar(int* nb_item, int* first_shown, int* last_shown)
156 if (!skinlist_is_configured(0, NULL))
158 *nb_item = 0;
159 *first_shown = 0;
160 *last_shown = 0;
162 else
164 *nb_item = current_item;
165 *first_shown = 0;
166 *last_shown = current_nbitems;
170 bool skinlist_get_item(struct screen *display, struct gui_synclist *list, int x, int y, int *item)
172 const int screen = display->screen_type;
173 if (!skinlist_is_configured(screen, list))
174 return false;
176 int row = y / listcfg[screen]->height;
177 int column = x / listcfg[screen]->width;
178 struct viewport *parent = (list->parent[screen]);
179 int cols = (parent->width / listcfg[screen]->width);
180 *item = row * cols+ column;
181 return true;
184 bool skinlist_draw(struct screen *display, struct gui_synclist *list)
186 int cur_line, display_lines;
187 const int screen = display->screen_type;
188 struct viewport *parent = (list->parent[screen]);
189 char* label = NULL;
190 const int list_start_item = list->start_item[screen];
191 struct gui_wps wps;
192 if (!skinlist_is_configured(screen, list))
193 return false;
195 current_list = list;
196 wps.display = display;
197 wps.data = listcfg[screen]->data;
198 display_lines = skinlist_get_line_count(screen, list);
199 label = (char *)SKINOFFSETTOPTR(get_skin_buffer(wps.data), listcfg[screen]->label);
200 display->set_viewport(parent);
201 display->clear_viewport();
202 current_item = list->selected_item;
203 current_nbitems = list->nb_items;
204 needs_scrollbar[screen] = list->nb_items > display_lines;
206 for (cur_line = 0; cur_line < display_lines; cur_line++)
208 struct skin_element* viewport;
209 struct skin_viewport* skin_viewport = NULL;
210 if (list_start_item+cur_line+1 > list->nb_items)
211 break;
212 current_drawing_line = list_start_item+cur_line;
213 is_selected = list->show_selection_marker &&
214 list_start_item+cur_line == list->selected_item;
216 for (viewport = SKINOFFSETTOPTR(get_skin_buffer(wps.data), listcfg[screen]->data->tree);
217 viewport;
218 viewport = SKINOFFSETTOPTR(get_skin_buffer(wps.data), viewport->next))
220 int original_x, original_y;
221 skin_viewport = SKINOFFSETTOPTR(get_skin_buffer(wps.data), viewport->data);
222 char *viewport_label = SKINOFFSETTOPTR(get_skin_buffer(wps.data), skin_viewport->label);
223 if (viewport->children == 0 || !viewport_label ||
224 (skin_viewport->label && strcmp(label, viewport_label))
226 continue;
227 if (is_selected)
229 memcpy(&listcfg[screen]->selected_item_vp, skin_viewport, sizeof(struct skin_viewport));
230 skin_viewport = &listcfg[screen]->selected_item_vp;
232 original_x = skin_viewport->vp.x;
233 original_y = skin_viewport->vp.y;
234 if (listcfg[screen]->tile)
236 int cols = (parent->width / listcfg[screen]->width);
237 current_column = (cur_line)%cols;
238 current_row = (cur_line)/cols;
240 skin_viewport->vp.x = parent->x + listcfg[screen]->width*current_column + original_x;
241 skin_viewport->vp.y = parent->y + listcfg[screen]->height*current_row + original_y;
243 else
245 current_column = 1;
246 current_row = cur_line;
247 skin_viewport->vp.x = parent->x + original_x;
248 skin_viewport->vp.y = parent->y + original_y +
249 (listcfg[screen]->height*cur_line);
251 display->set_viewport(&skin_viewport->vp);
252 #ifdef HAVE_LCD_BITMAP
253 /* Set images to not to be displayed */
254 struct skin_token_list *imglist = SKINOFFSETTOPTR(get_skin_buffer(wps.data), wps.data->images);
255 while (imglist)
257 struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(wps.data), imglist->token);
258 struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(wps.data), token->value.data);
259 img->display = -1;
260 imglist = SKINOFFSETTOPTR(get_skin_buffer(wps.data), imglist->next);
262 #endif
263 struct skin_element** children = SKINOFFSETTOPTR(get_skin_buffer(wps.data), viewport->children);
264 skin_render_viewport(SKINOFFSETTOPTR(get_skin_buffer(wps.data), (intptr_t)children[0]),
265 &wps, skin_viewport, SKIN_REFRESH_ALL);
266 #ifdef HAVE_LCD_BITMAP
267 wps_display_images(&wps, &skin_viewport->vp);
268 #endif
269 /* force disableing scroll because it breaks later */
270 if (!is_selected)
272 display->scroll_stop(&skin_viewport->vp);
273 skin_viewport->vp.x = original_x;
274 skin_viewport->vp.y = original_y;
278 current_column = -1;
279 current_row = -1;
280 display->set_viewport(parent);
281 display->update_viewport();
282 current_drawing_line = list->selected_item;
283 return true;