diff options
-rw-r--r-- | apps/gui/list.c | 197 |
1 files changed, 91 insertions, 106 deletions
diff --git a/apps/gui/list.c b/apps/gui/list.c index 23939469c5..43bbbe27cb 100644 --- a/apps/gui/list.c +++ b/apps/gui/list.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include "string.h" | 25 | #include "string.h" |
26 | #include "settings.h" | 26 | #include "settings.h" |
27 | #include "kernel.h" | 27 | #include "kernel.h" |
28 | #include "system.h" | ||
28 | 29 | ||
29 | #include "action.h" | 30 | #include "action.h" |
30 | #include "screen_access.h" | 31 | #include "screen_access.h" |
@@ -39,7 +40,7 @@ | |||
39 | #ifdef HAVE_LCD_CHARCELLS | 40 | #ifdef HAVE_LCD_CHARCELLS |
40 | #define SCROLL_LIMIT 1 | 41 | #define SCROLL_LIMIT 1 |
41 | #else | 42 | #else |
42 | #define SCROLL_LIMIT ((nb_lines/4)<2?2:nb_lines/4) | 43 | #define SCROLL_LIMIT (nb_lines<3?1:2) |
43 | #endif | 44 | #endif |
44 | 45 | ||
45 | /* The minimum number of pending button events in queue before starting | 46 | /* The minimum number of pending button events in queue before starting |
@@ -57,9 +58,7 @@ static struct gui_list* last_list_displayed[NB_SCREENS]; | |||
57 | #define SHOW_LIST_TITLE ((gui_list->title != NULL) && \ | 58 | #define SHOW_LIST_TITLE ((gui_list->title != NULL) && \ |
58 | (gui_list->display->nb_lines > 2)) | 59 | (gui_list->display->nb_lines > 2)) |
59 | 60 | ||
60 | static void gui_list_put_selection_in_screen(struct gui_list * gui_list, | 61 | static void gui_list_select_at_offset(struct gui_list * gui_list, int offset); |
61 | bool put_from_end); | ||
62 | |||
63 | 62 | ||
64 | /* | 63 | /* |
65 | * Initializes a scrolling list | 64 | * Initializes a scrolling list |
@@ -113,7 +112,7 @@ static void gui_list_set_display(struct gui_list * gui_list, struct screen * dis | |||
113 | #ifdef HAVE_LCD_CHARCELLS | 112 | #ifdef HAVE_LCD_CHARCELLS |
114 | display->double_height(false); | 113 | display->double_height(false); |
115 | #endif | 114 | #endif |
116 | gui_list_put_selection_in_screen(gui_list, false); | 115 | gui_list_select_at_offset(gui_list, 0); |
117 | } | 116 | } |
118 | 117 | ||
119 | /* | 118 | /* |
@@ -153,51 +152,6 @@ static void gui_list_flash(struct gui_list * gui_list) | |||
153 | #endif | 152 | #endif |
154 | } | 153 | } |
155 | 154 | ||
156 | /* | ||
157 | * Puts the selection in the screen | ||
158 | * - gui_list : the list structure | ||
159 | * - put_from_end : if true, selection will be put as close from | ||
160 | * the end of the list as possible, else, it's | ||
161 | * from the beginning | ||
162 | */ | ||
163 | static void gui_list_put_selection_in_screen(struct gui_list * gui_list, | ||
164 | bool put_from_end) | ||
165 | { | ||
166 | #ifdef HAVE_LCD_BITMAP | ||
167 | gui_list->display->setfont(FONT_UI); | ||
168 | #endif | ||
169 | gui_textarea_update_nblines(gui_list->display); | ||
170 | int nb_lines=gui_list->display->nb_lines; | ||
171 | if (SHOW_LIST_TITLE) | ||
172 | nb_lines--; | ||
173 | if (gui_list->nb_items < nb_lines) | ||
174 | { | ||
175 | gui_list->start_item = 0; | ||
176 | } | ||
177 | else if (global_settings.scroll_paginated && | ||
178 | gui_list->nb_items - gui_list->selected_item < nb_lines) | ||
179 | { | ||
180 | gui_list->start_item = gui_list->nb_items - nb_lines; | ||
181 | } | ||
182 | else if(put_from_end) | ||
183 | { | ||
184 | int list_end = gui_list->selected_item + SCROLL_LIMIT; | ||
185 | if(list_end >= gui_list->nb_items) | ||
186 | list_end = gui_list->nb_items; | ||
187 | gui_list->start_item = list_end - nb_lines; | ||
188 | } | ||
189 | else if (gui_list->nb_items-gui_list->selected_item < nb_lines) | ||
190 | { | ||
191 | gui_list->start_item = gui_list->nb_items - nb_lines; | ||
192 | } | ||
193 | else | ||
194 | { | ||
195 | int list_start = gui_list->selected_item - SCROLL_LIMIT - 1; | ||
196 | gui_list->start_item = list_start; | ||
197 | if(gui_list->start_item < 0) | ||
198 | gui_list->start_item = 0; | ||
199 | } | ||
200 | } | ||
201 | 155 | ||
202 | #ifdef HAVE_LCD_BITMAP | 156 | #ifdef HAVE_LCD_BITMAP |
203 | static int gui_list_get_item_offset(struct gui_list * gui_list, int item_width, | 157 | static int gui_list_get_item_offset(struct gui_list * gui_list, int item_width, |
@@ -505,85 +459,116 @@ static void gui_list_select_item(struct gui_list * gui_list, int item_number) | |||
505 | if( item_number > gui_list->nb_items-1 || item_number < 0 ) | 459 | if( item_number > gui_list->nb_items-1 || item_number < 0 ) |
506 | return; | 460 | return; |
507 | gui_list->selected_item = item_number; | 461 | gui_list->selected_item = item_number; |
508 | gui_list_put_selection_in_screen(gui_list, false); | 462 | gui_list_select_at_offset(gui_list, 0); |
509 | } | 463 | } |
510 | 464 | ||
511 | static void gui_list_select_at_offset(struct gui_list * gui_list, int offset) | 465 | /* select an item above the current one */ |
466 | static void gui_list_select_above(struct gui_list * gui_list, int items) | ||
512 | { | 467 | { |
513 | int nb_lines = gui_list->display->nb_lines; | 468 | int nb_lines = gui_list->display->nb_lines; |
514 | if (SHOW_LIST_TITLE) | 469 | if (SHOW_LIST_TITLE) |
515 | nb_lines--; | 470 | nb_lines--; |
516 | 471 | ||
517 | 472 | gui_list->selected_item -= items; | |
518 | if (gui_list->selected_size > 1) | 473 | /* in bottom "3rd" of the screen, so dont move the start item. |
519 | { | 474 | by 3rd I mean above SCROLL_LIMIT lines above the end of the screen */ |
520 | offset *= gui_list->selected_size; | 475 | if (items && gui_list->start_item + SCROLL_LIMIT < gui_list->selected_item) |
521 | /* always select the first item of multi-line lists */ | 476 | return; |
522 | offset -= offset%gui_list->selected_size; | 477 | if (gui_list->selected_item < 0) |
523 | } | ||
524 | gui_list->selected_item += offset; | ||
525 | |||
526 | if (offset < 0) /* moving up the list */ | ||
527 | { | 478 | { |
528 | if (gui_list->selected_item < 0) | 479 | if(gui_list->limit_scroll) |
529 | { | 480 | { |
530 | if(gui_list->limit_scroll) | 481 | gui_list->selected_item = 0; |
531 | { | 482 | gui_list->start_item = 0; |
532 | gui_list->selected_item = 0; | 483 | } |
533 | gui_list->start_item = 0; | 484 | else |
534 | } | 485 | { |
535 | else | 486 | gui_list->selected_item += gui_list->nb_items; |
487 | if (global_settings.scroll_paginated) | ||
536 | { | 488 | { |
537 | gui_list->selected_item = gui_list->nb_items - | 489 | gui_list->start_item = gui_list->nb_items - nb_lines; |
538 | gui_list->selected_size; | ||
539 | if (gui_list->nb_items >= nb_lines ) | ||
540 | gui_list->start_item = gui_list->selected_item - | ||
541 | nb_lines + gui_list->selected_size; | ||
542 | } | 490 | } |
543 | return; | ||
544 | } | 491 | } |
492 | } | ||
493 | if (gui_list->nb_items > nb_lines) | ||
494 | { | ||
545 | if (global_settings.scroll_paginated) | 495 | if (global_settings.scroll_paginated) |
546 | { | 496 | { |
547 | if (gui_list->selected_item < gui_list->start_item) | 497 | if (gui_list->start_item > gui_list->selected_item) |
548 | { | 498 | gui_list->start_item = MAX(0, gui_list->start_item - nb_lines); |
549 | gui_list->start_item -= nb_lines; | 499 | } |
550 | if (gui_list->start_item < 0) | 500 | else |
551 | gui_list->start_item = 0; | 501 | { |
552 | } | 502 | int top_of_screen = gui_list->selected_item - SCROLL_LIMIT; |
503 | int temp = MIN(top_of_screen, gui_list->nb_items - nb_lines); | ||
504 | gui_list->start_item = MAX(0, temp); | ||
553 | } | 505 | } |
554 | else if (gui_list->selected_item - gui_list->start_item <= SCROLL_LIMIT) | ||
555 | gui_list_put_selection_in_screen(gui_list, false); | ||
556 | } | 506 | } |
557 | else /* moving down */ | 507 | else gui_list->start_item = 0; |
508 | if (gui_list->selected_size > 1) | ||
558 | { | 509 | { |
559 | if (gui_list->selected_item >= gui_list->nb_items) | 510 | if (gui_list->start_item + nb_lines == gui_list->selected_item) |
511 | gui_list->start_item++; | ||
512 | } | ||
513 | } | ||
514 | /* select an item below the current one */ | ||
515 | static void gui_list_select_below(struct gui_list * gui_list, int items) | ||
516 | { | ||
517 | int nb_lines = gui_list->display->nb_lines; | ||
518 | if (SHOW_LIST_TITLE) | ||
519 | nb_lines--; | ||
520 | |||
521 | gui_list->selected_item += items; | ||
522 | /* in top "3rd" of the screen, so dont move the start item */ | ||
523 | if (items && | ||
524 | (gui_list->start_item + nb_lines - SCROLL_LIMIT > gui_list->selected_item) | ||
525 | && (gui_list->selected_item < gui_list->nb_items)) | ||
526 | return; | ||
527 | |||
528 | if (gui_list->selected_item >= gui_list->nb_items) | ||
529 | { | ||
530 | if(gui_list->limit_scroll) | ||
560 | { | 531 | { |
561 | if(gui_list->limit_scroll) | 532 | gui_list->selected_item = gui_list->nb_items-gui_list->selected_size; |
562 | { | 533 | gui_list->start_item = MAX(0,gui_list->nb_items - nb_lines); |
563 | if (gui_list->nb_items >= nb_lines) | 534 | } |
564 | gui_list->start_item = gui_list->nb_items - nb_lines; | 535 | else |
565 | gui_list->selected_item = gui_list->nb_items - | 536 | { |
566 | gui_list->selected_size; | 537 | gui_list->selected_item = 0; |
567 | } | 538 | gui_list->start_item = 0; |
568 | else | ||
569 | { | ||
570 | gui_list->selected_item = 0; | ||
571 | gui_list->start_item = 0; | ||
572 | } | ||
573 | return; | ||
574 | } | 539 | } |
540 | return; | ||
541 | } | ||
542 | int bottom = gui_list->nb_items - nb_lines; | ||
543 | if (gui_list->nb_items > nb_lines) | ||
544 | { | ||
575 | if (global_settings.scroll_paginated) | 545 | if (global_settings.scroll_paginated) |
576 | { | 546 | { |
577 | if (gui_list->selected_item - gui_list->start_item >= nb_lines) | 547 | if (gui_list->start_item + nb_lines <= gui_list->selected_item) |
578 | { | 548 | gui_list->start_item = MIN(bottom, gui_list->selected_item); |
579 | gui_list->start_item = gui_list->selected_item; | 549 | } |
580 | if (gui_list->nb_items - gui_list->start_item < nb_lines) | 550 | else |
581 | gui_list->start_item = gui_list->nb_items - nb_lines; | 551 | { |
582 | } | 552 | int top_of_screen = gui_list->selected_item + SCROLL_LIMIT - nb_lines; |
553 | int temp = MAX(0, top_of_screen); | ||
554 | gui_list->start_item = MIN(bottom, temp); | ||
583 | } | 555 | } |
584 | else if (nb_lines - (gui_list->selected_item - gui_list->start_item) <= SCROLL_LIMIT) | ||
585 | gui_list_put_selection_in_screen(gui_list, true); | ||
586 | } | 556 | } |
557 | else gui_list->start_item = 0; | ||
558 | } | ||
559 | |||
560 | static void gui_list_select_at_offset(struct gui_list * gui_list, int offset) | ||
561 | { | ||
562 | if (gui_list->selected_size > 1) | ||
563 | { | ||
564 | offset *= gui_list->selected_size; | ||
565 | /* always select the first item of multi-line lists */ | ||
566 | offset -= offset%gui_list->selected_size; | ||
567 | } | ||
568 | if (offset < 0) | ||
569 | gui_list_select_above(gui_list, -offset); | ||
570 | else | ||
571 | gui_list_select_below(gui_list, offset); | ||
587 | } | 572 | } |
588 | 573 | ||
589 | /* | 574 | /* |