diff options
Diffstat (limited to 'apps/gui/bitmap/list.c')
-rw-r--r-- | apps/gui/bitmap/list.c | 132 |
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 | ||
93 | static bool draw_title(struct screen *display, struct gui_synclist *list) | 93 | static 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 | |||
137 | static 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(); |