1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 by Kevin Ferrare
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
31 #include "screen_access.h"
33 #include "scrollbar.h"
34 #include "statusbar.h"
40 #ifdef HAVE_LCD_CHARCELLS
41 #define SCROLL_LIMIT 1
43 #define SCROLL_LIMIT (nb_lines<3?1:2)
46 /* The minimum number of pending button events in queue before starting
47 * to limit list drawing interval.
49 #define FRAMEDROP_TRIGGER 6
51 #ifdef HAVE_LCD_BITMAP
52 static int offset_step
= 16; /* pixels per screen scroll step */
53 /* should lines scroll out of the screen */
54 static bool offset_out_of_view
= false;
56 static struct gui_list
* last_list_displayed
[NB_SCREENS
];
58 #define SHOW_LIST_TITLE ((gui_list->title != NULL) && \
59 (gui_list->display->nb_lines > 2))
61 static void gui_list_select_at_offset(struct gui_list
* gui_list
, int offset
);
64 * Initializes a scrolling list
65 * - gui_list : the list structure to initialize
66 * - callback_get_item_icon : pointer to a function that associates an icon
67 * to a given item number
68 * - callback_get_item_name : pointer to a function that associates a label
69 * to a given item number
70 * - data : extra data passed to the list callback
72 static void gui_list_init(struct gui_list
* gui_list
,
73 list_get_name callback_get_item_name
,
79 gui_list
->callback_get_item_icon
= NULL
;
80 gui_list
->callback_get_item_name
= callback_get_item_name
;
81 gui_list
->display
= NULL
;
82 gui_list_set_nb_items(gui_list
, 0);
83 gui_list
->selected_item
= 0;
84 gui_list
->start_item
= 0;
85 gui_list
->limit_scroll
= false;
87 gui_list
->cursor_flash_state
=false;
88 #ifdef HAVE_LCD_BITMAP
89 gui_list
->offset_position
= 0;
91 gui_list
->scroll_all
=scroll_all
;
92 gui_list
->selected_size
=selected_size
;
93 gui_list
->title
= NULL
;
94 gui_list
->title_width
= 0;
95 gui_list
->title_icon
= Icon_NOICON
;
97 gui_list
->last_displayed_selected_item
= -1 ;
98 gui_list
->last_displayed_start_item
= -1 ;
99 gui_list
->show_selection_marker
= true;
102 /* this toggles the selection bar or cursor */
103 void gui_synclist_hide_selection_marker(struct gui_synclist
* lists
, bool hide
)
107 lists
->gui_list
[i
].show_selection_marker
= !hide
;
111 * Attach the scrolling list to a screen
112 * (The previous screen attachement is lost)
113 * - gui_list : the list structure
114 * - display : the screen to attach
116 static void gui_list_set_display(struct gui_list
* gui_list
, struct screen
* display
)
118 if(gui_list
->display
!= 0) /* we switched from a previous display */
119 gui_list
->display
->stop_scroll();
120 gui_list
->display
= display
;
121 #ifdef HAVE_LCD_CHARCELLS
122 display
->double_height(false);
124 gui_list_select_at_offset(gui_list
, 0);
128 * One call on 2, the selected lune will either blink the cursor or
129 * invert/display normal the selected line
130 * - gui_list : the list structure
132 static void gui_list_flash(struct gui_list
* gui_list
)
134 struct screen
* display
=gui_list
->display
;
135 gui_list
->cursor_flash_state
=!gui_list
->cursor_flash_state
;
136 int selected_line
=gui_list
->selected_item
-gui_list
->start_item
+SHOW_LIST_TITLE
;
137 #ifdef HAVE_LCD_BITMAP
138 int line_ypos
=display
->getymargin()+display
->char_height
*selected_line
;
139 if (global_settings
.invert_cursor
)
141 int line_xpos
=display
->getxmargin();
142 display
->set_drawmode(DRMODE_COMPLEMENT
);
143 display
->fillrect(line_xpos
, line_ypos
, display
->width
,
144 display
->char_height
);
145 display
->set_drawmode(DRMODE_SOLID
);
146 display
->invertscroll(0, selected_line
);
150 int cursor_xpos
=(global_settings
.scrollbar
&&
151 display
->nb_lines
< gui_list
->nb_items
)?1:0;
152 screen_put_cursorxy(display
, cursor_xpos
, selected_line
,
153 gui_list
->cursor_flash_state
);
155 display
->update_rect(0, line_ypos
,display
->width
,
156 display
->char_height
);
158 screen_put_cursorxy(display
, 0, selected_line
,
159 gui_list
->cursor_flash_state
);
160 gui_textarea_update(display
);
165 #ifdef HAVE_LCD_BITMAP
166 static int gui_list_get_item_offset(struct gui_list
* gui_list
, int item_width
,
169 struct screen
* display
=gui_list
->display
;
172 if (offset_out_of_view
)
174 item_offset
= gui_list
->offset_position
;
178 /* if text is smaller then view */
179 if (item_width
<= display
->width
- text_pos
)
185 /* if text got out of view */
186 if (gui_list
->offset_position
>
187 item_width
- (display
->width
- text_pos
))
188 item_offset
= item_width
- (display
->width
- text_pos
);
190 item_offset
= gui_list
->offset_position
;
199 * Draws the list on the attached screen
200 * - gui_list : the list structure
202 static void gui_list_draw_smart(struct gui_list
*gui_list
)
204 struct screen
* display
=gui_list
->display
;
206 bool draw_icons
= (gui_list
->callback_get_item_icon
!= NULL
&& global_settings
.show_icons
);
210 #ifdef HAVE_LCD_BITMAP
212 int old_margin
= display
->getxmargin();
215 bool partial_draw
= false;
217 #ifdef HAVE_LCD_BITMAP
218 display
->setfont(FONT_UI
);
220 /* Speed up UI by drawing the changed contents only. */
221 if (gui_list
== last_list_displayed
[gui_list
->display
->screen_type
]
222 && gui_list
->last_displayed_start_item
== gui_list
->start_item
223 && gui_list
->selected_size
== 1)
229 lines
= display
->nb_lines
- 1;
231 lines
= display
->nb_lines
;
235 end
= gui_list
->last_displayed_selected_item
- gui_list
->start_item
;
236 i
= gui_list
->selected_item
- gui_list
->start_item
;
250 gui_textarea_clear(display
);
252 end
= display
->nb_lines
;
253 gui_list
->last_displayed_start_item
= gui_list
->start_item
;
254 last_list_displayed
[gui_list
->display
->screen_type
] = gui_list
;
257 gui_list
->last_displayed_selected_item
= gui_list
->selected_item
;
259 /* position and draw the list title & icon */
260 if (SHOW_LIST_TITLE
&& !partial_draw
)
262 if (gui_list
->title_icon
!= NOICON
&& draw_icons
)
264 screen_put_icon(display
, 0, 0, gui_list
->title_icon
);
265 #ifdef HAVE_LCD_BITMAP
266 text_pos
= get_icon_width(display
->screen_type
)+2; /* pixels */
268 text_pos
= 1; /* chars */
276 #ifdef HAVE_LCD_BITMAP
277 screen_set_xmargin(display
, text_pos
); /* margin for title */
278 item_offset
= gui_list_get_item_offset(gui_list
, gui_list
->title_width
,
280 if (item_offset
> gui_list
->title_width
- (display
->width
- text_pos
))
281 display
->puts_offset(0, 0, gui_list
->title
, item_offset
);
283 display
->puts_scroll_offset(0, 0, gui_list
->title
, item_offset
);
285 display
->puts_scroll(text_pos
, 0, gui_list
->title
);
289 /* Adjust the position of icon, cursor, text for the list */
290 #ifdef HAVE_LCD_BITMAP
291 gui_textarea_update_nblines(display
);
294 draw_scrollbar
= (global_settings
.scrollbar
&&
295 lines
< gui_list
->nb_items
);
297 draw_cursor
= !global_settings
.invert_cursor
&&
298 gui_list
->show_selection_marker
;
299 text_pos
= 0; /* here it's in pixels */
300 if(draw_scrollbar
|| SHOW_LIST_TITLE
) /* indent if there's
303 text_pos
+= SCROLLBAR_WIDTH
;
306 text_pos
+= get_icon_width(display
->screen_type
) + 2;
309 text_pos
+= get_icon_width(display
->screen_type
) + 2;
313 text_pos
= 2; /* here it's in chars */
318 #ifdef HAVE_LCD_BITMAP
319 screen_set_xmargin(display
, text_pos
); /* margin for list */
325 if (end
< display
->nb_lines
)
329 for (i
= start
; i
< end
; i
++)
332 char entry_buffer
[MAX_PATH
];
333 unsigned char *entry_name
;
334 int current_item
= gui_list
->start_item
+
335 (SHOW_LIST_TITLE
? i
-1 : i
);
337 /* When there are less items to display than the
338 * current available space on the screen, we stop*/
339 if(current_item
>= gui_list
->nb_items
)
341 s
= gui_list
->callback_get_item_name(current_item
,
344 entry_name
= P2STR(s
);
346 #ifdef HAVE_LCD_BITMAP
347 /* position the string at the correct offset place */
349 display
->getstringsize(entry_name
, &item_width
, &h
);
350 item_offset
= gui_list_get_item_offset(gui_list
, item_width
, text_pos
);
353 if(gui_list
->show_selection_marker
&&
354 current_item
>= gui_list
->selected_item
&&
355 current_item
< gui_list
->selected_item
+ gui_list
->selected_size
)
356 {/* The selected item must be displayed scrolling */
357 #ifdef HAVE_LCD_BITMAP
358 if (global_settings
.invert_cursor
)/* Display inverted-line-style*/
360 /* if text got out of view */
361 if (item_offset
> item_width
- (display
->width
- text_pos
))
364 display
->puts_style_offset(0, i
, entry_name
,
365 STYLE_INVERT
,item_offset
);
369 display
->puts_scroll_style_offset(0, i
, entry_name
,
374 else /* if (!global_settings.invert_cursor) */
376 if (item_offset
> item_width
- (display
->width
- text_pos
))
377 display
->puts_offset(0, i
, entry_name
,item_offset
);
379 display
->puts_scroll_offset(0, i
, entry_name
,item_offset
);
380 if (current_item
% gui_list
->selected_size
!= 0)
384 display
->puts_scroll(text_pos
, i
, entry_name
);
389 screen_put_icon_with_offset(display
, 0, i
,
390 (draw_scrollbar
|| SHOW_LIST_TITLE
)?
397 if(gui_list
->scroll_all
)
399 #ifdef HAVE_LCD_BITMAP
400 display
->puts_scroll_offset(0, i
, entry_name
,item_offset
);
402 display
->puts_scroll(text_pos
, i
, entry_name
);
407 #ifdef HAVE_LCD_BITMAP
408 display
->puts_offset(0, i
, entry_name
,item_offset
);
410 display
->puts(text_pos
, i
, entry_name
);
417 enum themable_icons icon
;
418 icon
= gui_list
->callback_get_item_icon(current_item
, gui_list
->data
);
419 if(icon
> Icon_NOICON
)
421 #ifdef HAVE_LCD_BITMAP
422 int x
= draw_cursor
?1:0;
423 int x_off
= (draw_scrollbar
|| SHOW_LIST_TITLE
) ? SCROLLBAR_WIDTH
: 0;
424 screen_put_icon_with_offset(display
, x
, i
,
427 screen_put_icon(display
, 1, i
, icon
);
433 #ifdef HAVE_LCD_BITMAP
434 /* Draw the scrollbar if needed*/
437 int y_start
= gui_textarea_get_ystart(display
);
439 y_start
+= display
->char_height
;
440 int scrollbar_y_end
= display
->char_height
*
442 gui_scrollbar_draw(display
, 0, y_start
, SCROLLBAR_WIDTH
-1,
443 scrollbar_y_end
- y_start
, gui_list
->nb_items
,
444 gui_list
->start_item
,
445 gui_list
->start_item
+ lines
, VERTICAL
);
448 screen_set_xmargin(display
, old_margin
);
451 gui_textarea_update(display
);
455 * Force a full screen update.
457 static void gui_list_draw(struct gui_list
*gui_list
)
459 last_list_displayed
[gui_list
->display
->screen_type
] = NULL
;
460 return gui_list_draw_smart(gui_list
);
464 * Selects an item in the list
465 * - gui_list : the list structure
466 * - item_number : the number of the item which will be selected
468 static void gui_list_select_item(struct gui_list
* gui_list
, int item_number
)
470 if( item_number
> gui_list
->nb_items
-1 || item_number
< 0 )
472 gui_list
->selected_item
= item_number
;
473 gui_list_select_at_offset(gui_list
, 0);
476 /* select an item above the current one */
477 static void gui_list_select_above(struct gui_list
* gui_list
, int items
)
479 int nb_lines
= gui_list
->display
->nb_lines
;
483 gui_list
->selected_item
-= items
;
485 /* in bottom "3rd" of the screen, so dont move the start item.
486 by 3rd I mean above SCROLL_LIMIT lines above the end of the screen */
487 if (items
&& gui_list
->start_item
+ SCROLL_LIMIT
< gui_list
->selected_item
)
489 if (gui_list
->show_selection_marker
== false)
491 gui_list
->start_item
-= items
;
492 if (gui_list
->start_item
< 0)
493 gui_list
->start_item
= 0;
497 if (gui_list
->selected_item
< 0)
499 if(gui_list
->limit_scroll
)
501 gui_list
->selected_item
= 0;
502 gui_list
->start_item
= 0;
506 gui_list
->selected_item
+= gui_list
->nb_items
;
507 if (global_settings
.scroll_paginated
)
509 gui_list
->start_item
= gui_list
->nb_items
- nb_lines
;
513 if (gui_list
->nb_items
> nb_lines
)
515 if (global_settings
.scroll_paginated
)
517 if (gui_list
->start_item
> gui_list
->selected_item
)
518 gui_list
->start_item
= MAX(0, gui_list
->start_item
- nb_lines
);
522 int top_of_screen
= gui_list
->selected_item
- SCROLL_LIMIT
;
523 int temp
= MIN(top_of_screen
, gui_list
->nb_items
- nb_lines
);
524 gui_list
->start_item
= MAX(0, temp
);
527 else gui_list
->start_item
= 0;
528 if (gui_list
->selected_size
> 1)
530 if (gui_list
->start_item
+ nb_lines
== gui_list
->selected_item
)
531 gui_list
->start_item
++;
534 /* select an item below the current one */
535 static void gui_list_select_below(struct gui_list
* gui_list
, int items
)
537 int nb_lines
= gui_list
->display
->nb_lines
;
542 gui_list
->selected_item
+= items
;
543 bottom
= gui_list
->nb_items
- nb_lines
;
545 /* always move the screen if selection isnt "visible" */
546 if (items
&& gui_list
->show_selection_marker
== false)
550 gui_list
->start_item
= MIN(bottom
, gui_list
->start_item
+
554 /* in top "3rd" of the screen, so dont move the start item */
556 (gui_list
->start_item
+ nb_lines
- SCROLL_LIMIT
> gui_list
->selected_item
)
557 && (gui_list
->selected_item
< gui_list
->nb_items
))
559 if (gui_list
->show_selection_marker
== false)
563 gui_list
->start_item
= MIN(bottom
,
564 gui_list
->start_item
+ items
);
569 if (gui_list
->selected_item
>= gui_list
->nb_items
)
571 if(gui_list
->limit_scroll
)
573 gui_list
->selected_item
= gui_list
->nb_items
-gui_list
->selected_size
;
574 gui_list
->start_item
= MAX(0,gui_list
->nb_items
- nb_lines
);
578 gui_list
->selected_item
= 0;
579 gui_list
->start_item
= 0;
584 if (gui_list
->nb_items
> nb_lines
)
586 if (global_settings
.scroll_paginated
)
588 if (gui_list
->start_item
+ nb_lines
<= gui_list
->selected_item
)
589 gui_list
->start_item
= MIN(bottom
, gui_list
->selected_item
);
593 int top_of_screen
= gui_list
->selected_item
+ SCROLL_LIMIT
- nb_lines
;
594 int temp
= MAX(0, top_of_screen
);
595 gui_list
->start_item
= MIN(bottom
, temp
);
598 else gui_list
->start_item
= 0;
601 static void gui_list_select_at_offset(struct gui_list
* gui_list
, int offset
)
603 if (gui_list
->selected_size
> 1)
605 offset
*= gui_list
->selected_size
;
606 /* always select the first item of multi-line lists */
607 offset
-= offset
%gui_list
->selected_size
;
609 if (offset
== 0 && global_settings
.scroll_paginated
&&
610 (gui_list
->nb_items
> gui_list
->display
->nb_lines
- SHOW_LIST_TITLE
))
612 gui_list
->selected_item
= gui_list
->selected_item
;
615 gui_list_select_above(gui_list
, -offset
);
617 gui_list_select_below(gui_list
, offset
);
621 * Adds an item to the list (the callback will be asked for one more item)
622 * - gui_list : the list structure
624 static void gui_list_add_item(struct gui_list
* gui_list
)
626 gui_list
->nb_items
++;
627 /* if only one item in the list, select it */
628 if(gui_list
->nb_items
== 1)
629 gui_list
->selected_item
= 0;
633 * Removes an item to the list (the callback will be asked for one less item)
634 * - gui_list : the list structure
636 static void gui_list_del_item(struct gui_list
* gui_list
)
638 if(gui_list
->nb_items
> 0)
640 gui_textarea_update_nblines(gui_list
->display
);
641 int nb_lines
= gui_list
->display
->nb_lines
;
643 int dist_selected_from_end
= gui_list
->nb_items
644 - gui_list
->selected_item
- 1;
645 int dist_start_from_end
= gui_list
->nb_items
646 - gui_list
->start_item
- 1;
647 if(dist_selected_from_end
== 0)
649 /* Oops we are removing the selected item,
650 select the previous one */
651 gui_list
->selected_item
--;
653 gui_list
->nb_items
--;
655 /* scroll the list if needed */
656 if( (dist_start_from_end
< nb_lines
) && (gui_list
->start_item
!= 0) )
657 gui_list
->start_item
--;
661 #ifdef HAVE_LCD_BITMAP
664 * Makes all the item in the list scroll by one step to the right.
665 * Should stop increasing the value when reaching the widest item value
668 static void gui_list_scroll_right(struct gui_list
* gui_list
)
670 /* FIXME: This is a fake right boundry limiter. there should be some
671 * callback function to find the longest item on the list in pixels,
672 * to stop the list from scrolling past that point */
673 gui_list
->offset_position
+=offset_step
;
674 if (gui_list
->offset_position
> 1000)
675 gui_list
->offset_position
= 1000;
679 * Makes all the item in the list scroll by one step to the left.
680 * stops at starting position.
682 static void gui_list_scroll_left(struct gui_list
* gui_list
)
684 gui_list
->offset_position
-=offset_step
;
685 if (gui_list
->offset_position
< 0)
686 gui_list
->offset_position
= 0;
688 void gui_list_screen_scroll_step(int ofs
)
693 void gui_list_screen_scroll_out_of_view(bool enable
)
696 offset_out_of_view
= true;
698 offset_out_of_view
= false;
700 #endif /* HAVE_LCD_BITMAP */
703 * Set the title and title icon of the list. Setting title to NULL disables
704 * both the title and icon. Use NOICON if there is no icon.
706 static void gui_list_set_title(struct gui_list
* gui_list
,
707 char * title
, enum themable_icons icon
)
709 gui_list
->title
= title
;
710 gui_list
->title_icon
= icon
;
712 #ifdef HAVE_LCD_BITMAP
713 gui_list
->display
->getstringsize(title
, &gui_list
->title_width
, NULL
);
715 gui_list
->title_width
= strlen(title
);
718 gui_list
->title_width
= 0;
723 * Synchronized lists stuffs
725 void gui_synclist_init(
726 struct gui_synclist
* lists
,
727 list_get_name callback_get_item_name
,
736 gui_list_init(&(lists
->gui_list
[i
]),
737 callback_get_item_name
,
738 data
, scroll_all
, selected_size
);
739 gui_list_set_display(&(lists
->gui_list
[i
]), &(screens
[i
]));
743 void gui_synclist_set_nb_items(struct gui_synclist
* lists
, int nb_items
)
748 gui_list_set_nb_items(&(lists
->gui_list
[i
]), nb_items
);
749 #ifdef HAVE_LCD_BITMAP
750 lists
->gui_list
[i
].offset_position
= 0;
754 int gui_synclist_get_nb_items(struct gui_synclist
* lists
)
756 return gui_list_get_nb_items(&((lists
)->gui_list
[0]));
758 int gui_synclist_get_sel_pos(struct gui_synclist
* lists
)
760 return gui_list_get_sel_pos(&((lists
)->gui_list
[0]));
762 void gui_synclist_set_icon_callback(struct gui_synclist
* lists
,
763 list_get_icon icon_callback
)
768 gui_list_set_icon_callback(&(lists
->gui_list
[i
]), icon_callback
);
772 void gui_synclist_draw(struct gui_synclist
* lists
)
776 gui_list_draw(&(lists
->gui_list
[i
]));
779 void gui_synclist_select_item(struct gui_synclist
* lists
, int item_number
)
783 gui_list_select_item(&(lists
->gui_list
[i
]), item_number
);
786 static void gui_synclist_select_next_page(struct gui_synclist
* lists
,
787 enum screen_type screen
)
791 gui_list_select_at_offset(&(lists
->gui_list
[i
]),
792 screens
[screen
].nb_lines
);
795 static void gui_synclist_select_previous_page(struct gui_synclist
* lists
,
796 enum screen_type screen
)
800 gui_list_select_at_offset(&(lists
->gui_list
[i
]),
801 -screens
[screen
].nb_lines
);
804 void gui_synclist_add_item(struct gui_synclist
* lists
)
808 gui_list_add_item(&(lists
->gui_list
[i
]));
811 void gui_synclist_del_item(struct gui_synclist
* lists
)
815 gui_list_del_item(&(lists
->gui_list
[i
]));
818 void gui_synclist_limit_scroll(struct gui_synclist
* lists
, bool scroll
)
822 gui_list_limit_scroll(&(lists
->gui_list
[i
]), scroll
);
825 void gui_synclist_set_title(struct gui_synclist
* lists
,
826 char * title
, enum themable_icons icon
)
830 gui_list_set_title(&(lists
->gui_list
[i
]), title
, icon
);
833 void gui_synclist_flash(struct gui_synclist
* lists
)
837 gui_list_flash(&(lists
->gui_list
[i
]));
840 #ifdef HAVE_LCD_BITMAP
841 static void gui_synclist_scroll_right(struct gui_synclist
* lists
)
845 gui_list_scroll_right(&(lists
->gui_list
[i
]));
848 static void gui_synclist_scroll_left(struct gui_synclist
* lists
)
852 gui_list_scroll_left(&(lists
->gui_list
[i
]));
854 #endif /* HAVE_LCD_BITMAP */
856 unsigned gui_synclist_do_button(struct gui_synclist
* lists
,
857 unsigned button
,enum list_wrap wrap
)
859 #ifdef HAVE_LCD_BITMAP
860 static bool scrolling_left
= false;
862 static int next_item_modifier
= 1;
863 static int last_accel_tick
= 0;
866 if (global_settings
.list_accel_start_delay
)
868 int start_delay
= global_settings
.list_accel_start_delay
* (HZ
/2);
869 int accel_wait
= global_settings
.list_accel_wait
* HZ
/2;
871 if (get_action_statuscode(NULL
)&ACTION_REPEAT
)
873 if (!last_accel_tick
)
874 last_accel_tick
= current_tick
+ start_delay
;
875 else if (current_tick
>=
876 last_accel_tick
+ accel_wait
)
878 last_accel_tick
= current_tick
;
879 next_item_modifier
++;
882 else if (last_accel_tick
)
884 next_item_modifier
= 1;
892 gui_synclist_limit_scroll(lists
, false);
895 gui_synclist_limit_scroll(lists
, true);
897 case LIST_WRAP_UNLESS_HELD
:
898 if (button
== ACTION_STD_PREVREPEAT
||
899 button
== ACTION_STD_NEXTREPEAT
||
900 button
== ACTION_LISTTREE_PGUP
||
901 button
== ACTION_LISTTREE_PGDOWN
)
902 gui_synclist_limit_scroll(lists
, true);
903 else gui_synclist_limit_scroll(lists
, false);
909 #ifdef HAVE_VOLUME_IN_LIST
910 case ACTION_LIST_VOLUP
:
911 global_settings
.volume
+= 2;
912 /* up two because the falthrough brings it down one */
913 case ACTION_LIST_VOLDOWN
:
914 global_settings
.volume
--;
918 case ACTION_STD_PREV
:
919 case ACTION_STD_PREVREPEAT
:
921 gui_list_select_at_offset(&(lists
->gui_list
[i
]), -next_item_modifier
);
922 if (queue_count(&button_queue
) < FRAMEDROP_TRIGGER
)
923 gui_synclist_draw(lists
);
925 return ACTION_STD_PREV
;
927 case ACTION_STD_NEXT
:
928 case ACTION_STD_NEXTREPEAT
:
930 gui_list_select_at_offset(&(lists
->gui_list
[i
]), next_item_modifier
);
931 if (queue_count(&button_queue
) < FRAMEDROP_TRIGGER
)
932 gui_synclist_draw(lists
);
934 return ACTION_STD_NEXT
;
936 #ifdef HAVE_LCD_BITMAP
937 case ACTION_TREE_ROOT_INIT
:
938 /* After this button press ACTION_TREE_PGLEFT is allowed
939 to skip to root. ACTION_TREE_ROOT_INIT must be defined in the
940 keymaps as a repeated button press (the same as the repeated
941 ACTION_TREE_PGLEFT) with the pre condition being the non-repeated
943 if (lists
->gui_list
[0].offset_position
== 0)
945 scrolling_left
= false;
946 return ACTION_STD_CANCEL
;
948 case ACTION_TREE_PGRIGHT
:
949 gui_synclist_scroll_right(lists
);
950 gui_synclist_draw(lists
);
951 return ACTION_TREE_PGRIGHT
;
952 case ACTION_TREE_PGLEFT
:
953 if(!scrolling_left
&& (lists
->gui_list
[0].offset_position
== 0))
954 return ACTION_STD_CANCEL
;
955 gui_synclist_scroll_left(lists
);
956 gui_synclist_draw(lists
);
957 scrolling_left
= true; /* stop ACTION_TREE_PAGE_LEFT
959 return ACTION_TREE_PGLEFT
;
962 /* for pgup / pgdown, we are obliged to have a different behaviour depending
963 * on the screen for which the user pressed the key since for example, remote
964 * and main screen doesn't have the same number of lines */
965 case ACTION_LISTTREE_PGUP
:
968 #ifdef HAVE_REMOTE_LCD
969 get_action_statuscode(NULL
)&ACTION_REMOTE
?
973 gui_synclist_select_previous_page(lists
, screen
);
974 gui_synclist_draw(lists
);
977 return ACTION_STD_NEXT
;
979 case ACTION_LISTTREE_PGDOWN
:
982 #ifdef HAVE_REMOTE_LCD
983 get_action_statuscode(NULL
)&ACTION_REMOTE
?
987 gui_synclist_select_next_page(lists
, screen
);
988 gui_synclist_draw(lists
);
991 return ACTION_STD_PREV
;