summaryrefslogtreecommitdiff
path: root/apps/gui/bitmap/list.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/gui/bitmap/list.c')
-rw-r--r--apps/gui/bitmap/list.c211
1 files changed, 111 insertions, 100 deletions
diff --git a/apps/gui/bitmap/list.c b/apps/gui/bitmap/list.c
index a3f5da92ea..3b2f16db8c 100644
--- a/apps/gui/bitmap/list.c
+++ b/apps/gui/bitmap/list.c
@@ -45,19 +45,13 @@
45#define SCROLLBAR_WIDTH 6 45#define SCROLLBAR_WIDTH 6
46#define ICON_PADDING 1 46#define ICON_PADDING 1
47 47
48static struct viewport title_text[NB_SCREENS], title_icons[NB_SCREENS], 48/* these are static to make scrolling work */
49 list_text[NB_SCREENS], list_icons[NB_SCREENS]; 49static struct viewport list_text[NB_SCREENS], title_text[NB_SCREENS];
50 50
51/* should probably be moved somewhere else */
52int list_title_height(struct gui_synclist *list, struct viewport *vp)
53{
54 (void)list;
55 return font_get(vp->font)->height;
56}
57int gui_list_get_item_offset(struct gui_synclist * gui_list, int item_width, 51int gui_list_get_item_offset(struct gui_synclist * gui_list, int item_width,
58 int text_pos, struct screen * display, 52 int text_pos, struct screen * display,
59 struct viewport *vp); 53 struct viewport *vp);
60bool list_display_title(struct gui_synclist *list, struct viewport *vp); 54bool list_display_title(struct gui_synclist *list, enum screen_type screen);
61 55
62/* Draw the list... 56/* Draw the list...
63 internal screen layout: 57 internal screen layout:
@@ -70,47 +64,51 @@ bool list_display_title(struct gui_synclist *list, struct viewport *vp);
70 | | | | 64 | | | |
71 ------------------ 65 ------------------
72*/ 66*/
73static bool draw_title(struct screen *display, struct viewport *parent, 67static bool draw_title(struct screen *display, struct gui_synclist *list)
74 struct gui_synclist *list)
75{ 68{
76 struct viewport *vp_icons = &title_icons[display->screen_type]; 69 const int screen = display->screen_type;
77 struct viewport *vp_text = &title_text[display->screen_type]; 70 if (!list_display_title(list, screen))
78 if (!list_display_title(list, parent))
79 return false; 71 return false;
80 *vp_text = *parent; 72 title_text[screen] = *(list->parent[screen]);
81 vp_text->height = list_title_height(list, parent); 73 title_text[screen].height
74 = font_get(title_text[screen].font)->height;
82 if (list->title_icon != Icon_NOICON && global_settings.show_icons) 75 if (list->title_icon != Icon_NOICON && global_settings.show_icons)
83 { 76 {
84 *vp_icons = *vp_text; 77 struct viewport title_icon = *(list->parent[screen]);
85 vp_icons->width = get_icon_width(display->screen_type) 78 title_icon = title_text[screen];
79 title_icon.width = get_icon_width(screen)
86 + ICON_PADDING*2; 80 + ICON_PADDING*2;
87 vp_icons->x += ICON_PADDING; 81 title_icon.x += ICON_PADDING;
88 82
89 vp_text->width -= vp_icons->width + vp_icons->x; 83 title_text[screen].width -= title_icon.width + title_icon.x;
90 vp_text->x += vp_icons->width + vp_icons->x; 84 title_text[screen].x += title_icon.width + title_icon.x;
91 85
92 display->set_viewport(vp_icons); 86 display->set_viewport(&title_icon);
93 screen_put_icon(display, 0, 0, list->title_icon); 87 screen_put_icon(display, 0, 0, list->title_icon);
94 } 88 }
95 display->set_viewport(vp_text); 89 title_text[screen].drawmode = STYLE_DEFAULT;
96 vp_text->drawmode = STYLE_DEFAULT;
97#ifdef HAVE_LCD_COLOR 90#ifdef HAVE_LCD_COLOR
98 if (list->title_color >= 0) 91 if (list->title_color >= 0)
99 { 92 {
100 vp_text->drawmode |= (STYLE_COLORED|list->title_color);} 93 title_text[screen].drawmode
94 |= (STYLE_COLORED|list->title_color);
95 }
101#endif 96#endif
102 display->puts_scroll_style_offset(0, 0, list->title, 97 display->set_viewport(&title_text[screen]);
103 vp_text->drawmode, 0); 98 display->puts_scroll_style(0, 0, list->title,
99 title_text[screen].drawmode);
104 return true; 100 return true;
105} 101}
106 102
107void list_draw(struct screen *display, struct viewport *parent, 103void list_draw(struct screen *display, struct gui_synclist *list)
108 struct gui_synclist *list)
109{ 104{
105 struct viewport list_icons;
110 int start, end, line_height, i; 106 int start, end, line_height, i;
111 int icon_width = get_icon_width(display->screen_type) + ICON_PADDING; 107 const int screen = display->screen_type;
112 bool show_cursor = !global_settings.cursor_style && 108 const int icon_width = get_icon_width(screen) + ICON_PADDING;
109 const bool show_cursor = !global_settings.cursor_style &&
113 list->show_selection_marker; 110 list->show_selection_marker;
111 struct viewport *parent = (list->parent[screen]);
114#ifdef HAVE_LCD_COLOR 112#ifdef HAVE_LCD_COLOR
115 unsigned char cur_line = 0; 113 unsigned char cur_line = 0;
116#endif 114#endif
@@ -120,55 +118,55 @@ void list_draw(struct screen *display, struct viewport *parent,
120 display->set_viewport(parent); 118 display->set_viewport(parent);
121 display->clear_viewport(); 119 display->clear_viewport();
122 display->stop_scroll(); 120 display->stop_scroll();
123 list_text[display->screen_type] = *parent; 121 list_text[screen] = *parent;
124 if ((show_title = draw_title(display, parent, list))) 122 if ((show_title = draw_title(display, list)))
125 { 123 {
126 list_text[display->screen_type].y += list_title_height(list, parent); 124 list_text[screen].y += line_height;
127 list_text[display->screen_type].height -= list_title_height(list, parent); 125 list_text[screen].height -= line_height;
128 } 126 }
129 127
130 start = list->start_item[display->screen_type]; 128 start = list->start_item[screen];
131 end = start + viewport_get_nb_lines(&list_text[display->screen_type]); 129 end = start + viewport_get_nb_lines(&list_text[screen]);
132 130
133 /* draw the scrollbar if its needed */ 131 /* draw the scrollbar if its needed */
134 if (global_settings.scrollbar && 132 if (global_settings.scrollbar &&
135 viewport_get_nb_lines(&list_text[display->screen_type]) < list->nb_items) 133 viewport_get_nb_lines(&list_text[screen]) < list->nb_items)
136 { 134 {
137 struct viewport vp; 135 struct viewport vp;
138 vp = list_text[display->screen_type]; 136 vp = list_text[screen];
139 vp.width = SCROLLBAR_WIDTH; 137 vp.width = SCROLLBAR_WIDTH;
140 list_text[display->screen_type].width -= SCROLLBAR_WIDTH; 138 list_text[screen].width -= SCROLLBAR_WIDTH;
141 list_text[display->screen_type].x += SCROLLBAR_WIDTH; 139 list_text[screen].x += SCROLLBAR_WIDTH;
142 vp.height = line_height * 140 vp.height = line_height *
143 viewport_get_nb_lines(&list_text[display->screen_type]); 141 viewport_get_nb_lines(&list_text[screen]);
144 vp.x = parent->x; 142 vp.x = parent->x;
145 display->set_viewport(&vp); 143 display->set_viewport(&vp);
146 gui_scrollbar_draw(display, 0, 0, SCROLLBAR_WIDTH-1, 144 gui_scrollbar_draw(display, 0, 0, SCROLLBAR_WIDTH-1,
147 vp.height, list->nb_items, 145 vp.height, list->nb_items,
148 list->start_item[display->screen_type], 146 list->start_item[screen],
149 list->start_item[display->screen_type] + end-start, 147 list->start_item[screen] + end-start,
150 VERTICAL); 148 VERTICAL);
151 } 149 }
152 else if (show_title) 150 else if (show_title)
153 { 151 {
154 /* shift everything right a bit... */ 152 /* shift everything right a bit... */
155 list_text[display->screen_type].width -= SCROLLBAR_WIDTH; 153 list_text[screen].width -= SCROLLBAR_WIDTH;
156 list_text[display->screen_type].x += SCROLLBAR_WIDTH; 154 list_text[screen].x += SCROLLBAR_WIDTH;
157 } 155 }
158 156
159 /* setup icon placement */ 157 /* setup icon placement */
160 list_icons[display->screen_type] = list_text[display->screen_type]; 158 list_icons = list_text[screen];
161 int icon_count = global_settings.show_icons && 159 int icon_count = global_settings.show_icons &&
162 (list->callback_get_item_icon != NULL) ? 1 : 0; 160 (list->callback_get_item_icon != NULL) ? 1 : 0;
163 if (show_cursor) 161 if (show_cursor)
164 icon_count++; 162 icon_count++;
165 if (icon_count) 163 if (icon_count)
166 { 164 {
167 list_icons[display->screen_type].width = icon_width * icon_count; 165 list_icons.width = icon_width * icon_count;
168 list_text[display->screen_type].width -= 166 list_text[screen].width -=
169 list_icons[display->screen_type].width + ICON_PADDING; 167 list_icons.width + ICON_PADDING;
170 list_text[display->screen_type].x += 168 list_text[screen].x +=
171 list_icons[display->screen_type].width + ICON_PADDING; 169 list_icons.width + ICON_PADDING;
172 } 170 }
173 171
174 for (i=start; i<end && i<list->nb_items; i++) 172 for (i=start; i<end && i<list->nb_items; i++)
@@ -181,14 +179,14 @@ void list_draw(struct screen *display, struct viewport *parent,
181 s = list->callback_get_item_name(i, list->data, entry_buffer, 179 s = list->callback_get_item_name(i, list->data, entry_buffer,
182 sizeof(entry_buffer)); 180 sizeof(entry_buffer));
183 entry_name = P2STR(s); 181 entry_name = P2STR(s);
184 display->set_viewport(&list_text[display->screen_type]); 182 display->set_viewport(&list_text[screen]);
185 list_text[display->screen_type].drawmode = STYLE_DEFAULT; 183 list_text[screen].drawmode = STYLE_DEFAULT;
186 /* position the string at the correct offset place */ 184 /* position the string at the correct offset place */
187 int item_width,h; 185 int item_width,h;
188 display->getstringsize(entry_name, &item_width, &h); 186 display->getstringsize(entry_name, &item_width, &h);
189 item_offset = gui_list_get_item_offset(list, item_width, 187 item_offset = gui_list_get_item_offset(list, item_width,
190 text_pos, display, 188 text_pos, display,
191 &list_text[display->screen_type]); 189 &list_text[screen]);
192 190
193#ifdef HAVE_LCD_COLOR 191#ifdef HAVE_LCD_COLOR
194 /* if the list has a color callback */ 192 /* if the list has a color callback */
@@ -198,73 +196,75 @@ void list_draw(struct screen *display, struct viewport *parent,
198 /* if color selected */ 196 /* if color selected */
199 if (color >= 0) 197 if (color >= 0)
200 { 198 {
201 list_text[display->screen_type].drawmode |= STYLE_COLORED|color; 199 list_text[screen].drawmode |= STYLE_COLORED|color;
202 } 200 }
203 } 201 }
204#endif 202#endif
205 if(i >= list->selected_item && 203 if(i >= list->selected_item && i < list->selected_item
206 i < list->selected_item + list->selected_size && list->show_selection_marker) 204 + list->selected_size && list->show_selection_marker)
207 {/* The selected item must be displayed scrolling */ 205 {/* The selected item must be displayed scrolling */
208 if (global_settings.cursor_style == 1 206 if (global_settings.cursor_style == 1
209#ifdef HAVE_REMOTE_LCD 207#ifdef HAVE_REMOTE_LCD
210 /* the global_settings.cursor_style check is here to make sure 208 /* the global_settings.cursor_style check is here to make
211 if they want the cursor instead of bar it will work */ 209 * sure if they want the cursor instead of bar it will work
210 */
212 || (display->depth < 16 && global_settings.cursor_style) 211 || (display->depth < 16 && global_settings.cursor_style)
213#endif 212#endif
214 ) 213 )
215 { 214 {
216 /* Display inverted-line-style */ 215 /* Display inverted-line-style */
217 list_text[display->screen_type].drawmode = STYLE_INVERT; 216 list_text[screen].drawmode = STYLE_INVERT;
218 } 217 }
219#ifdef HAVE_LCD_COLOR 218#ifdef HAVE_LCD_COLOR
220 else if (global_settings.cursor_style == 2) 219 else if (global_settings.cursor_style == 2)
221 { 220 {
222 /* Display colour line selector */ 221 /* Display colour line selector */
223 list_text[display->screen_type].drawmode = STYLE_COLORBAR; 222 list_text[screen].drawmode = STYLE_COLORBAR;
224 } 223 }
225 else if (global_settings.cursor_style == 3) 224 else if (global_settings.cursor_style == 3)
226 { 225 {
227 /* Display gradient line selector */ 226 /* Display gradient line selector */
228 list_text[display->screen_type].drawmode = STYLE_GRADIENT; 227 list_text[screen].drawmode = STYLE_GRADIENT;
229 228
230 /* Make the lcd driver know how many lines the gradient should 229 /* Make the lcd driver know how many lines the gradient should
231 cover and current line number */ 230 cover and current line number */
232 /* number of selected lines */ 231 /* number of selected lines */
233 list_text[display->screen_type].drawmode |= NUMLN_PACK(list->selected_size); 232 list_text[screen].drawmode |= NUMLN_PACK(list->selected_size);
234 /* current line number, zero based */ 233 /* current line number, zero based */
235 list_text[display->screen_type].drawmode |= CURLN_PACK(cur_line); 234 list_text[screen].drawmode |= CURLN_PACK(cur_line);
236 cur_line++; 235 cur_line++;
237 } 236 }
238#endif 237#endif
239 /* if the text is smaller than the viewport size */ 238 /* if the text is smaller than the viewport size */
240 if (item_offset > item_width - (list_text[display->screen_type].width - text_pos)) 239 if (item_offset> item_width
240 - (list_text[screen].width - text_pos))
241 { 241 {
242 /* don't scroll */ 242 /* don't scroll */
243 display->puts_style_offset(0, i-start, entry_name, 243 display->puts_style_offset(0, i-start, entry_name,
244 list_text[display->screen_type].drawmode, item_offset); 244 list_text[screen].drawmode, item_offset);
245 } 245 }
246 else 246 else
247 { 247 {
248 display->puts_scroll_style_offset(0, i-start, entry_name, 248 display->puts_scroll_style_offset(0, i-start, entry_name,
249 list_text[display->screen_type].drawmode, item_offset); 249 list_text[screen].drawmode, item_offset);
250 } 250 }
251 } 251 }
252 else 252 else
253 { 253 {
254 if (list->scroll_all) 254 if (list->scroll_all)
255 display->puts_scroll_style_offset(0, i-start, entry_name, 255 display->puts_scroll_style_offset(0, i-start, entry_name,
256 list_text[display->screen_type].drawmode, item_offset); 256 list_text[screen].drawmode, item_offset);
257 else 257 else
258 display->puts_style_offset(0, i-start, entry_name, 258 display->puts_style_offset(0, i-start, entry_name,
259 list_text[display->screen_type].drawmode, item_offset); 259 list_text[screen].drawmode, item_offset);
260 } 260 }
261 /* do the icon */ 261 /* do the icon */
262 if (list->callback_get_item_icon && global_settings.show_icons) 262 if (list->callback_get_item_icon && global_settings.show_icons)
263 { 263 {
264 display->set_viewport(&list_icons[display->screen_type]); 264 display->set_viewport(&list_icons);
265 screen_put_icon_with_offset(display, show_cursor?1:0, 265 screen_put_icon_with_offset(display, show_cursor?1:0,
266 (i-start),show_cursor?ICON_PADDING:0,0, 266 (i-start),show_cursor?ICON_PADDING:0,0,
267 list->callback_get_item_icon(i, list->data)); 267 list->callback_get_item_icon(i, list->data));
268 if (show_cursor && i >= list->selected_item && 268 if (show_cursor && i >= list->selected_item &&
269 i < list->selected_item + list->selected_size) 269 i < list->selected_item + list->selected_size)
270 { 270 {
@@ -274,14 +274,12 @@ void list_draw(struct screen *display, struct viewport *parent,
274 else if (show_cursor && i >= list->selected_item && 274 else if (show_cursor && i >= list->selected_item &&
275 i < list->selected_item + list->selected_size) 275 i < list->selected_item + list->selected_size)
276 { 276 {
277 display->set_viewport(&list_icons[display->screen_type]); 277 display->set_viewport(&list_icons);
278 screen_put_icon(display, 0, (i-start), Icon_Cursor); 278 screen_put_icon(display, 0, (i-start), Icon_Cursor);
279 } 279 }
280 } 280 }
281
282 display->set_viewport(parent); 281 display->set_viewport(parent);
283 display->update_viewport(); 282 display->update_viewport();
284 display->set_viewport(NULL);
285} 283}
286 284
287 285
@@ -292,10 +290,10 @@ void list_draw(struct screen *display, struct viewport *parent,
292 */ 290 */
293static bool scrolling=false; 291static bool scrolling=false;
294 292
295unsigned gui_synclist_do_touchscreen(struct gui_synclist * gui_list, struct viewport *parent) 293unsigned gui_synclist_do_touchscreen(struct gui_synclist * gui_list)
296{ 294{
297 short x, y; 295 short x, y;
298 unsigned button = action_get_touchscreen_press(&x, &y); 296 int button = action_get_touchscreen_press(&x, &y);
299 int line; 297 int line;
300 struct screen *display = &screens[SCREEN_MAIN]; 298 struct screen *display = &screens[SCREEN_MAIN];
301 if (button == BUTTON_NONE) 299 if (button == BUTTON_NONE)
@@ -315,13 +313,15 @@ unsigned gui_synclist_do_touchscreen(struct gui_synclist * gui_list, struct view
315 /* Scroll bar */ 313 /* Scroll bar */
316 else 314 else
317 { 315 {
318 int nb_lines = viewport_get_nb_lines(&list_text[SCREEN_MAIN]); 316 int nb_lines = viewport_get_nb_lines(&list_text[screen]);
319 if (nb_lines < gui_list->nb_items) 317 if (nb_lines < gui_list->nb_items)
320 { 318 {
321 int scrollbar_size = nb_lines * font_get(parent->font)->height; 319 int scrollbar_size = nb_lines*
322 int actual_y = y - list_text[SCREEN_MAIN].y; 320 font_get(gui_list->parent[screen]->font)->height;
321 int actual_y = y - list_text[screen].y;
323 322
324 int new_selection = (actual_y * gui_list->nb_items) / scrollbar_size; 323 int new_selection = (actual_y * gui_list->nb_items)
324 / scrollbar_size;
325 325
326 int start_item = new_selection - nb_lines/2; 326 int start_item = new_selection - nb_lines/2;
327 if(start_item < 0) 327 if(start_item < 0)
@@ -329,7 +329,7 @@ unsigned gui_synclist_do_touchscreen(struct gui_synclist * gui_list, struct view
329 else if(start_item > gui_list->nb_items - nb_lines) 329 else if(start_item > gui_list->nb_items - nb_lines)
330 start_item = gui_list->nb_items - nb_lines; 330 start_item = gui_list->nb_items - nb_lines;
331 331
332 gui_list->start_item[SCREEN_MAIN] = start_item; 332 gui_list->start_item[screen] = start_item;
333 gui_synclist_select_item(gui_list, new_selection); 333 gui_synclist_select_item(gui_list, new_selection);
334 334
335 return ACTION_REDRAW; 335 return ACTION_REDRAW;
@@ -350,27 +350,31 @@ unsigned gui_synclist_do_touchscreen(struct gui_synclist * gui_list, struct view
350 * | will bring up the context menu of it. | 350 * | will bring up the context menu of it. |
351 * |--------------------------------------------------------| 351 * |--------------------------------------------------------|
352 */ 352 */
353 if (y > list_text[SCREEN_MAIN].y) 353 if (y > list_text[screen].y)
354 { 354 {
355 int line_height, actual_y; 355 int line_height, actual_y;
356 static int last_y = 0; 356 static int last_y = 0;
357 357
358 actual_y = y - list_text[SCREEN_MAIN].y; 358 actual_y = y - list_text[screen].y;
359 line_height = font_get(parent->font)->height; 359 line_height = font_get(gui_list->parent[screen]->font)->height;
360 line = actual_y / line_height; 360 line = actual_y / line_height;
361 361
362 if(actual_y%line_height == 0) /* Pressed a border */ 362 if(actual_y%line_height == 0) /* Pressed a border */
363 return ACTION_NONE; 363 return ACTION_NONE;
364 364
365 if (gui_list->start_item[SCREEN_MAIN]+line > gui_list->nb_items) /* Pressed below the list*/ 365 if (gui_list->start_item[screen]+line > gui_list->nb_items)
366 {
367 /* Pressed below the list*/
366 return ACTION_NONE; 368 return ACTION_NONE;
367 369 }
368 last_y = actual_y; 370 last_y = actual_y;
369 if (line != gui_list->selected_item - gui_list->start_item[SCREEN_MAIN] && button ^ BUTTON_REL) 371 if (line != gui_list->selected_item
372 - gui_list->start_item[screen] && button ^ BUTTON_REL)
370 { 373 {
371 if(button & BUTTON_REPEAT) 374 if(button & BUTTON_REPEAT)
372 scrolling = true; 375 scrolling = true;
373 gui_synclist_select_item(gui_list, gui_list->start_item[SCREEN_MAIN]+line); 376 gui_synclist_select_item(gui_list, gui_list->start_item[screen]
377 + line);
374 return ACTION_REDRAW; 378 return ACTION_REDRAW;
375 } 379 }
376 380
@@ -378,15 +382,17 @@ unsigned gui_synclist_do_touchscreen(struct gui_synclist * gui_list, struct view
378 { 382 {
379 if(!scrolling) 383 if(!scrolling)
380 { 384 {
381 /* Pen was hold on the same line as the previously selected one 385 /* Pen was hold on the same line as the
382 * => simulate long button press 386 * previously selected one
387 * => simulate long button press
383 */ 388 */
384 return ACTION_STD_CONTEXT; 389 return ACTION_STD_CONTEXT;
385 } 390 }
386 else 391 else
387 { 392 {
388 /* Pen was moved across several lines and then released on this one 393 /* Pen was moved across several lines and then released on
389 * => do nothing 394 * this one
395 * => do nothing
390 */ 396 */
391 scrolling = false; 397 scrolling = false;
392 return ACTION_NONE; 398 return ACTION_NONE;
@@ -394,8 +400,8 @@ unsigned gui_synclist_do_touchscreen(struct gui_synclist * gui_list, struct view
394 } 400 }
395 else if(button == BUTTON_REL) 401 else if(button == BUTTON_REL)
396 { 402 {
397 /* Pen was released on either the same line as the previously selected one 403 /* Pen was released on either the same line as the previously
398 * or an other one 404 * selected one or an other one
399 * => simulate short press 405 * => simulate short press
400 */ 406 */
401 return ACTION_STD_OK; 407 return ACTION_STD_OK;
@@ -404,11 +410,16 @@ unsigned gui_synclist_do_touchscreen(struct gui_synclist * gui_list, struct view
404 return ACTION_NONE; 410 return ACTION_NONE;
405 } 411 }
406 /* Title goes up one level (only on BUTTON_REL&~BUTTON_REPEAT) */ 412 /* Title goes up one level (only on BUTTON_REL&~BUTTON_REPEAT) */
407 else if (y > title_text[SCREEN_MAIN].y && draw_title(display, parent, gui_list) && button == BUTTON_REL) 413 else if (y > title_text[screen].y && draw_title(display, gui_list)
414 && button == BUTTON_REL)
415 {
408 return ACTION_STD_CANCEL; 416 return ACTION_STD_CANCEL;
417 }
409 /* Title or statusbar is cancel (only on BUTTON_REL&~BUTTON_REPEAT) */ 418 /* Title or statusbar is cancel (only on BUTTON_REL&~BUTTON_REPEAT) */
410 else if (global_settings.statusbar && button == BUTTON_REL) 419 else if (global_settings.statusbar && button == BUTTON_REL)
420 {
411 return ACTION_STD_CANCEL; 421 return ACTION_STD_CANCEL;
422 }
412 } 423 }
413 return ACTION_NONE; 424 return ACTION_NONE;
414} 425}