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.c132
1 files changed, 100 insertions, 32 deletions
diff --git a/apps/gui/bitmap/list.c b/apps/gui/bitmap/list.c
index 194f4c008b..1b051cd800 100644
--- a/apps/gui/bitmap/list.c
+++ b/apps/gui/bitmap/list.c
@@ -90,11 +90,57 @@ static int list_icon_width(enum screen_type screen)
90 return get_icon_width(screen) + ICON_PADDING * 2; 90 return get_icon_width(screen) + ICON_PADDING * 2;
91} 91}
92 92
93static bool draw_title(struct screen *display, struct gui_synclist *list) 93static void _default_listdraw_fn(struct list_putlineinfo_t *list_info)
94{
95 struct screen *display = list_info->display;
96 int x = list_info->x;
97 int y = list_info->y;
98 int item_indent = list_info->item_indent;
99 int item_offset = list_info->item_offset;
100 int icon = list_info->icon;
101 bool is_selected = list_info->is_selected;
102 bool is_title = list_info->is_title;
103 bool show_cursor = list_info->show_cursor;
104 bool have_icons = list_info->have_icons;
105 struct line_desc *linedes = list_info->linedes;
106 char *dsp_text = list_info->dsp_text;
107
108 if (is_title)
109 {
110 if (have_icons)
111 display->put_line(x, y, linedes, "$"ICON_PADDING_S"I$t",
112 icon, dsp_text);
113 else
114 display->put_line(x, y, linedes, "$t", dsp_text);
115 }
116 else if (show_cursor && have_icons)
117 {
118 /* the list can have both, one of or neither of cursor and item icons,
119 * if both don't apply icon padding twice between the icons */
120 display->put_line(x, y,
121 linedes, "$*s$"ICON_PADDING_S"I$i$"ICON_PADDING_S"s$*t",
122 item_indent, is_selected ? Icon_Cursor : Icon_NOICON,
123 icon, item_offset, dsp_text);
124 }
125 else if (show_cursor || have_icons)
126 {
127 display->put_line(x, y, linedes, "$*s$"ICON_PADDING_S"I$*t", item_indent,
128 show_cursor ? (is_selected ? Icon_Cursor:Icon_NOICON):icon,
129 item_offset, dsp_text);
130 }
131 else
132 {
133 display->put_line(x, y, linedes, "$*s$*t", item_indent, item_offset, dsp_text);
134 }
135}
136
137static bool draw_title(struct screen *display,
138 struct gui_synclist *list,
139 list_draw_item *callback_draw_item)
94{ 140{
95 const int screen = display->screen_type; 141 const int screen = display->screen_type;
96 struct viewport *title_text_vp = &title_text[screen]; 142 struct viewport *title_text_vp = &title_text[screen];
97 struct line_desc line = LINE_DESC_DEFINIT; 143 struct line_desc linedes = LINE_DESC_DEFINIT;
98 144
99 if (sb_set_title_text(list->title, list->title_icon, screen)) 145 if (sb_set_title_text(list->title, list->title_icon, screen))
100 return false; /* the sbs is handling the title */ 146 return false; /* the sbs is handling the title */
@@ -102,29 +148,39 @@ static bool draw_title(struct screen *display, struct gui_synclist *list)
102 if (!list_display_title(list, screen)) 148 if (!list_display_title(list, screen))
103 return false; 149 return false;
104 *title_text_vp = *(list->parent[screen]); 150 *title_text_vp = *(list->parent[screen]);
105 line.height = list->line_height[screen]; 151 linedes.height = list->line_height[screen];
106 title_text_vp->height = line.height; 152 title_text_vp->height = linedes.height;
107 153
108#if LCD_DEPTH > 1 154#if LCD_DEPTH > 1
109 /* XXX: Do we want to support the separator on remote displays? */ 155 /* XXX: Do we want to support the separator on remote displays? */
110 if (display->screen_type == SCREEN_MAIN && global_settings.list_separator_height != 0) 156 if (display->screen_type == SCREEN_MAIN && global_settings.list_separator_height != 0)
111 line.separator_height = abs(global_settings.list_separator_height) 157 linedes.separator_height = abs(global_settings.list_separator_height)
112 + (lcd_get_dpi() > 200 ? 2 : 1); 158 + (lcd_get_dpi() > 200 ? 2 : 1);
113#endif 159#endif
114 160
115#ifdef HAVE_LCD_COLOR 161#ifdef HAVE_LCD_COLOR
116 if (list->title_color >= 0) 162 if (list->title_color >= 0)
117 line.style |= (STYLE_COLORED|list->title_color); 163 linedes.style |= (STYLE_COLORED|list->title_color);
118#endif 164#endif
119 line.scroll = true; 165 linedes.scroll = true;
120 166
121 display->set_viewport(title_text_vp); 167 display->set_viewport(title_text_vp);
168 int icon = list->title_icon;
169 int icon_w = list_icon_width(display->screen_type);
170 bool have_icons = false;
171 if (icon != Icon_NOICON && global_settings.show_icons)
172 have_icons = true;
122 173
123 if (list->title_icon != Icon_NOICON && global_settings.show_icons) 174 struct list_putlineinfo_t list_info =
124 put_line(display, 0, 0, &line, "$"ICON_PADDING_S"I$t", 175 {
125 list->title_icon, list->title); 176 .x = 0, .y = 0, .item_indent = 0, .item_offset = 0,
126 else 177 .line = -1, .icon = icon, .icon_width = icon_w,
127 put_line(display, 0, 0, &line, "$t", list->title); 178 .display = display, .vp = title_text_vp, .linedes = &linedes, .list = list,
179 .dsp_text = list->title,
180 .is_selected = false, .is_title = true, .show_cursor = false,
181 .have_icons = have_icons
182 };
183 callback_draw_item(&list_info);
128 184
129 return true; 185 return true;
130} 186}
@@ -133,6 +189,8 @@ void list_draw(struct screen *display, struct gui_synclist *list)
133{ 189{
134 int start, end, item_offset, i; 190 int start, end, item_offset, i;
135 const int screen = display->screen_type; 191 const int screen = display->screen_type;
192 list_draw_item *callback_draw_item;
193
136 const int list_start_item = list->start_item[screen]; 194 const int list_start_item = list->start_item[screen];
137 const bool scrollbar_in_left = (global_settings.scrollbar == SCROLLBAR_LEFT); 195 const bool scrollbar_in_left = (global_settings.scrollbar == SCROLLBAR_LEFT);
138 const bool scrollbar_in_right = (global_settings.scrollbar == SCROLLBAR_RIGHT); 196 const bool scrollbar_in_right = (global_settings.scrollbar == SCROLLBAR_RIGHT);
@@ -145,11 +203,16 @@ void list_draw(struct screen *display, struct gui_synclist *list)
145 struct viewport *list_text_vp = &list_text[screen]; 203 struct viewport *list_text_vp = &list_text[screen];
146 int indent = 0; 204 int indent = 0;
147 205
206 if (list->callback_draw_item != NULL)
207 callback_draw_item = list->callback_draw_item;
208 else
209 callback_draw_item = _default_listdraw_fn;
210
148 struct viewport * last_vp = display->set_viewport(parent); 211 struct viewport * last_vp = display->set_viewport(parent);
149 display->clear_viewport(); 212 display->clear_viewport();
150 display->scroll_stop_viewport(list_text_vp); 213 display->scroll_stop_viewport(list_text_vp);
151 *list_text_vp = *parent; 214 *list_text_vp = *parent;
152 if ((show_title = draw_title(display, list))) 215 if ((show_title = draw_title(display, list, callback_draw_item)))
153 { 216 {
154 int title_height = title_text[screen].height; 217 int title_height = title_text[screen].height;
155 list_text_vp->y += title_height; 218 list_text_vp->y += title_height;
@@ -244,6 +307,16 @@ void list_draw(struct screen *display, struct gui_synclist *list)
244 } 307 }
245 308
246 display->set_viewport(list_text_vp); 309 display->set_viewport(list_text_vp);
310 int icon_w = list_icon_width(screen);
311 int character_width = display->getcharwidth();
312
313 struct list_putlineinfo_t list_info =
314 {
315 .x = 0, .y = 0, .vp = list_text_vp, .list = list,
316 .icon_width = icon_w, .is_title = false, .show_cursor = show_cursor,
317 .have_icons = have_icons, .linedes = &linedes, .display = display
318 };
319
247 for (i=start; i<end && i<list->nb_items; i++) 320 for (i=start; i<end && i<list->nb_items; i++)
248 { 321 {
249 /* do the text */ 322 /* do the text */
@@ -251,7 +324,7 @@ void list_draw(struct screen *display, struct gui_synclist *list)
251 unsigned const char *s; 324 unsigned const char *s;
252 char entry_buffer[MAX_PATH]; 325 char entry_buffer[MAX_PATH];
253 unsigned char *entry_name; 326 unsigned char *entry_name;
254 int text_pos = 0; 327 const int text_pos = 0; /* UNUSED */
255 int line = i - start; 328 int line = i - start;
256 int line_indent = 0; 329 int line_indent = 0;
257 int style = STYLE_DEFAULT; 330 int style = STYLE_DEFAULT;
@@ -268,9 +341,9 @@ void list_draw(struct screen *display, struct gui_synclist *list)
268 if (line_indent) 341 if (line_indent)
269 { 342 {
270 if (global_settings.show_icons) 343 if (global_settings.show_icons)
271 line_indent *= list_icon_width(screen); 344 line_indent *= icon_w;
272 else 345 else
273 line_indent *= display->getcharwidth(); 346 line_indent *= character_width;
274 } 347 }
275 line_indent += indent; 348 line_indent += indent;
276 349
@@ -345,27 +418,22 @@ void list_draw(struct screen *display, struct gui_synclist *list)
345 } 418 }
346 } 419 }
347#endif 420#endif
348
349 linedes.style = style; 421 linedes.style = style;
350 linedes.scroll = is_selected ? true : list->scroll_all; 422 linedes.scroll = is_selected ? true : list->scroll_all;
351 linedes.line = i % list->selected_size; 423 linedes.line = i % list->selected_size;
352 icon = list->callback_get_item_icon ? 424 icon = list->callback_get_item_icon ?
353 list->callback_get_item_icon(i, list->data) : Icon_NOICON; 425 list->callback_get_item_icon(i, list->data) : Icon_NOICON;
354 /* the list can have both, one of or neither of cursor and item icons, 426
355 * if both don't apply icon padding twice between the icons */ 427
356 if (show_cursor && have_icons) 428 list_info.y = line * linedes.height + draw_offset;
357 put_line(display, 0, line * linedes.height + draw_offset, 429 list_info.is_selected = is_selected;
358 &linedes, "$*s$"ICON_PADDING_S"I$i$"ICON_PADDING_S"s$*t", 430 list_info.item_indent = line_indent;
359 line_indent, is_selected ? Icon_Cursor : Icon_NOICON, 431 list_info.line = i;
360 icon, item_offset, entry_name); 432 list_info.icon = icon;
361 else if (show_cursor || have_icons) 433 list_info.dsp_text = entry_name;
362 put_line(display, 0, line * linedes.height + draw_offset, 434 list_info.item_offset = item_offset;
363 &linedes, "$*s$"ICON_PADDING_S"I$*t", line_indent, 435
364 show_cursor ? (is_selected ? Icon_Cursor:Icon_NOICON):icon, 436 callback_draw_item(&list_info);
365 item_offset, entry_name);
366 else
367 put_line(display, 0, line * linedes.height + draw_offset,
368 &linedes, "$*s$*t", line_indent, item_offset, entry_name);
369 } 437 }
370 display->set_viewport(parent); 438 display->set_viewport(parent);
371 display->update_viewport(); 439 display->update_viewport();