summaryrefslogtreecommitdiff
path: root/apps/gui/list.c
diff options
context:
space:
mode:
authorTeruaki Kawashima <teru@rockbox.org>2010-01-07 12:51:57 +0000
committerTeruaki Kawashima <teru@rockbox.org>2010-01-07 12:51:57 +0000
commit67470c890aa33f721d29025a4d69c83103eb0b05 (patch)
treec7a92b417b6f5eedbb458fb9a61c59e3884bd780 /apps/gui/list.c
parent669afd093d3c9e9ae282dcea17b43d9a6ad3cc1a (diff)
downloadrockbox-67470c890aa33f721d29025a4d69c83103eb0b05.tar.gz
rockbox-67470c890aa33f721d29025a4d69c83103eb0b05.zip
list: improvement to move and show selection in multi-line lists.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24195 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/gui/list.c')
-rw-r--r--apps/gui/list.c94
1 files changed, 43 insertions, 51 deletions
diff --git a/apps/gui/list.c b/apps/gui/list.c
index 8e350b514c..0c05e01785 100644
--- a/apps/gui/list.c
+++ b/apps/gui/list.c
@@ -40,12 +40,6 @@
40#include "viewport.h" 40#include "viewport.h"
41#include "appevents.h" 41#include "appevents.h"
42 42
43#ifdef HAVE_LCD_CHARCELLS
44#define SCROLL_LIMIT 1
45#else
46#define SCROLL_LIMIT (nb_lines<3?1:2)
47#endif
48
49/* The minimum number of pending button events in queue before starting 43/* The minimum number of pending button events in queue before starting
50 * to limit list drawing interval. 44 * to limit list drawing interval.
51 */ 45 */
@@ -100,6 +94,17 @@ static void list_init_viewports(struct gui_synclist *list)
100 list_need_reinit = false; 94 list_need_reinit = false;
101} 95}
102#else 96#else
97static struct viewport parent[NB_SCREENS] =
98{
99 [SCREEN_MAIN] =
100 {
101 .x = 0,
102 .y = 0,
103 .width = LCD_WIDTH,
104 .height = LCD_HEIGHT
105 },
106};
107
103#define list_init_viewports(a) 108#define list_init_viewports(a)
104#endif 109#endif
105 110
@@ -118,16 +123,6 @@ static int list_get_nb_lines(struct gui_synclist *list, enum screen_type screen)
118 return viewport_get_nb_lines(&vp); 123 return viewport_get_nb_lines(&vp);
119} 124}
120#else 125#else
121static struct viewport parent[NB_SCREENS] =
122{
123 [SCREEN_MAIN] =
124 {
125 .x = 0,
126 .y = 0,
127 .width = LCD_WIDTH,
128 .height = LCD_HEIGHT
129 },
130};
131#define list_display_title(l, i) false 126#define list_display_title(l, i) false
132#define list_get_nb_lines(list, screen) \ 127#define list_get_nb_lines(list, screen) \
133 viewport_get_nb_lines((list)->parent[(screen)]); 128 viewport_get_nb_lines((list)->parent[(screen)]);
@@ -256,45 +251,38 @@ static void gui_list_put_selection_on_screen(struct gui_synclist * gui_list,
256 int bottom = MAX(0, gui_list->nb_items - nb_lines); 251 int bottom = MAX(0, gui_list->nb_items - nb_lines);
257 int new_start_item = gui_list->start_item[screen]; 252 int new_start_item = gui_list->start_item[screen];
258 int difference = gui_list->selected_item - gui_list->start_item[screen]; 253 int difference = gui_list->selected_item - gui_list->start_item[screen];
254#ifdef HAVE_LCD_CHARCELLS
255 const int scroll_limit_up = 0;
256 const int scroll_limit_down = 1;
257#else
258 const int scroll_limit_up = (nb_lines < gui_list->selected_size+2 ? 0:1);
259 const int scroll_limit_down = (scroll_limit_up+gui_list->selected_size);
260#endif
259 261
260 /* edge case, selected last item */ 262 if (gui_list->show_selection_marker == false)
261 if (gui_list->selected_item == gui_list->nb_items -1)
262 { 263 {
263 new_start_item = bottom; 264 new_start_item = gui_list->selected_item;
264 } 265 }
265 /* selected first item */ 266 else if (gui_list->selected_size >= nb_lines)
266 else if (gui_list->selected_item == 0)
267 { 267 {
268 new_start_item = 0; 268 new_start_item = gui_list->selected_item;
269 } 269 }
270 else if (difference < SCROLL_LIMIT) /* list moved up */ 270 else if (global_settings.scroll_paginated)
271 { 271 {
272 if (global_settings.scroll_paginated) 272 nb_lines -= nb_lines%gui_list->selected_size;
273 if (difference < 0 || difference >= nb_lines)
273 { 274 {
274 if (new_start_item > gui_list->selected_item) 275 new_start_item = gui_list->selected_item -
275 new_start_item = (gui_list->selected_item/nb_lines)*nb_lines; 276 (gui_list->selected_item%nb_lines);
276 }
277 else
278 {
279 new_start_item = gui_list->selected_item - SCROLL_LIMIT + 1;
280 } 277 }
281 } 278 }
282 else if (difference > nb_lines - SCROLL_LIMIT) /* list moved down */ 279 else if (difference <= scroll_limit_up) /* list moved up */
283 { 280 {
284 /* always move the screen if selection isnt "visible" */ 281 new_start_item = gui_list->selected_item - scroll_limit_up;
285 if (gui_list->show_selection_marker == false) 282 }
286 { 283 else if (difference > nb_lines - scroll_limit_down) /* list moved down */
287 new_start_item += 2*gui_list->selected_size; 284 {
288 } 285 new_start_item = gui_list->selected_item + scroll_limit_down - nb_lines;
289 else if (global_settings.scroll_paginated)
290 {
291 if (new_start_item + nb_lines <= gui_list->selected_item)
292 new_start_item = (gui_list->selected_item/nb_lines)*nb_lines;
293 }
294 else
295 {
296 new_start_item = gui_list->selected_item + SCROLL_LIMIT - nb_lines;
297 }
298 } 286 }
299 if (new_start_item < 0) 287 if (new_start_item < 0)
300 gui_list->start_item[screen] = 0; 288 gui_list->start_item[screen] = 0;
@@ -326,10 +314,10 @@ static void gui_list_select_at_offset(struct gui_synclist * gui_list,
326 if (gui_list->selected_size > 1) 314 if (gui_list->selected_size > 1)
327 { 315 {
328 offset *= gui_list->selected_size; 316 offset *= gui_list->selected_size;
329 /* always select the first item of multi-line lists */
330 offset -= offset%gui_list->selected_size;
331 } 317 }
318
332 new_selection = gui_list->selected_item + offset; 319 new_selection = gui_list->selected_item + offset;
320
333 if (new_selection >= gui_list->nb_items) 321 if (new_selection >= gui_list->nb_items)
334 { 322 {
335 gui_list->selected_item = gui_list->limit_scroll ? 323 gui_list->selected_item = gui_list->limit_scroll ?
@@ -475,6 +463,8 @@ static void gui_synclist_select_next_page(struct gui_synclist * lists,
475 enum screen_type screen) 463 enum screen_type screen)
476{ 464{
477 int nb_lines = list_get_nb_lines(lists, screen); 465 int nb_lines = list_get_nb_lines(lists, screen);
466 if (lists->selected_size > 1)
467 nb_lines = MAX(1, nb_lines/lists->selected_size);
478 gui_list_select_at_offset(lists, nb_lines); 468 gui_list_select_at_offset(lists, nb_lines);
479} 469}
480 470
@@ -482,6 +472,8 @@ static void gui_synclist_select_previous_page(struct gui_synclist * lists,
482 enum screen_type screen) 472 enum screen_type screen)
483{ 473{
484 int nb_lines = list_get_nb_lines(lists, screen); 474 int nb_lines = list_get_nb_lines(lists, screen);
475 if (lists->selected_size > 1)
476 nb_lines = MAX(1, nb_lines/lists->selected_size);
485 gui_list_select_at_offset(lists, -nb_lines); 477 gui_list_select_at_offset(lists, -nb_lines);
486} 478}
487 479
@@ -829,10 +821,10 @@ bool simplelist_show_list(struct simplelist_info *info)
829 getname = info->get_name; 821 getname = info->get_name;
830 else 822 else
831 getname = simplelist_static_getname; 823 getname = simplelist_static_getname;
832 824
833 FOR_NB_SCREENS(i) 825 FOR_NB_SCREENS(i)
834 viewportmanager_theme_enable(i, true, NULL); 826 viewportmanager_theme_enable(i, true, NULL);
835 827
836 gui_synclist_init(&lists, getname, info->callback_data, 828 gui_synclist_init(&lists, getname, info->callback_data,
837 info->scroll_all, info->selection_size, NULL); 829 info->scroll_all, info->selection_size, NULL);
838 830
@@ -908,7 +900,7 @@ bool simplelist_show_list(struct simplelist_info *info)
908 } 900 }
909 talk_shutup(); 901 talk_shutup();
910 FOR_NB_SCREENS(i) 902 FOR_NB_SCREENS(i)
911 viewportmanager_theme_undo(i, false); 903 viewportmanager_theme_undo(i, false);
912 return false; 904 return false;
913} 905}
914 906