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_name : pointer to a function that associates a label
67 * to a given item number
68 * - 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;
101 #ifdef HAVE_LCD_COLOR
102 gui_list
->title_color
= -1;
103 gui_list
->callback_get_item_color
= NULL
;
107 /* this toggles the selection bar or cursor */
108 void gui_synclist_hide_selection_marker(struct gui_synclist
* lists
, bool hide
)
112 lists
->gui_list
[i
].show_selection_marker
= !hide
;
116 * Attach the scrolling list to a screen
117 * (The previous screen attachement is lost)
118 * - gui_list : the list structure
119 * - display : the screen to attach
121 static void gui_list_set_display(struct gui_list
* gui_list
, struct screen
* display
)
123 if(gui_list
->display
!= 0) /* we switched from a previous display */
124 gui_list
->display
->stop_scroll();
125 gui_list
->display
= display
;
126 #ifdef HAVE_LCD_CHARCELLS
127 display
->double_height(false);
129 gui_list_select_at_offset(gui_list
, 0);
133 * One call on 2, the selected lune will either blink the cursor or
134 * invert/display normal the selected line
135 * - gui_list : the list structure
137 static void gui_list_flash(struct gui_list
* gui_list
)
139 struct screen
* display
=gui_list
->display
;
140 gui_list
->cursor_flash_state
=!gui_list
->cursor_flash_state
;
141 int selected_line
=gui_list
->selected_item
-gui_list
->start_item
+SHOW_LIST_TITLE
;
142 #ifdef HAVE_LCD_BITMAP
143 int line_ypos
=display
->getymargin()+display
->char_height
*selected_line
;
144 if (global_settings
.invert_cursor
)
146 int line_xpos
=display
->getxmargin();
147 display
->set_drawmode(DRMODE_COMPLEMENT
);
148 display
->fillrect(line_xpos
, line_ypos
, display
->width
,
149 display
->char_height
);
150 display
->set_drawmode(DRMODE_SOLID
);
151 display
->invertscroll(0, selected_line
);
155 int cursor_xpos
=(global_settings
.scrollbar
&&
156 display
->nb_lines
< gui_list
->nb_items
)?1:0;
157 screen_put_cursorxy(display
, cursor_xpos
, selected_line
,
158 gui_list
->cursor_flash_state
);
160 display
->update_rect(0, line_ypos
,display
->width
,
161 display
->char_height
);
163 screen_put_cursorxy(display
, 0, selected_line
,
164 gui_list
->cursor_flash_state
);
165 gui_textarea_update(display
);
170 #ifdef HAVE_LCD_BITMAP
171 static int gui_list_get_item_offset(struct gui_list
* gui_list
, int item_width
,
174 struct screen
* display
=gui_list
->display
;
177 if (offset_out_of_view
)
179 item_offset
= gui_list
->offset_position
;
183 /* if text is smaller then view */
184 if (item_width
<= display
->width
- text_pos
)
190 /* if text got out of view */
191 if (gui_list
->offset_position
>
192 item_width
- (display
->width
- text_pos
))
193 item_offset
= item_width
- (display
->width
- text_pos
);
195 item_offset
= gui_list
->offset_position
;
204 * Draws the list on the attached screen
205 * - gui_list : the list structure
207 static void gui_list_draw_smart(struct gui_list
*gui_list
)
209 struct screen
* display
=gui_list
->display
;
211 bool draw_icons
= (gui_list
->callback_get_item_icon
!= NULL
&& global_settings
.show_icons
);
215 static int last_lines
[NB_SCREENS
] = {0};
216 #ifdef HAVE_LCD_BITMAP
218 int old_margin
= display
->getxmargin();
221 bool partial_draw
= false;
223 #ifdef HAVE_LCD_BITMAP
224 display
->setfont(FONT_UI
);
225 gui_textarea_update_nblines(display
);
227 /* Speed up UI by drawing the changed contents only. */
228 if (gui_list
== last_list_displayed
[gui_list
->display
->screen_type
]
229 && gui_list
->last_displayed_start_item
== gui_list
->start_item
230 && gui_list
->selected_size
== 1)
235 lines
= display
->nb_lines
- SHOW_LIST_TITLE
;
236 if (last_lines
[display
->screen_type
] != lines
)
238 gui_list_select_at_offset(gui_list
, 0);
239 last_lines
[display
->screen_type
] = lines
;
244 end
= gui_list
->last_displayed_selected_item
- gui_list
->start_item
;
245 i
= gui_list
->selected_item
- gui_list
->start_item
;
259 gui_textarea_clear(display
);
261 end
= display
->nb_lines
;
262 gui_list
->last_displayed_start_item
= gui_list
->start_item
;
263 last_list_displayed
[gui_list
->display
->screen_type
] = gui_list
;
266 gui_list
->last_displayed_selected_item
= gui_list
->selected_item
;
268 /* position and draw the list title & icon */
269 if (SHOW_LIST_TITLE
&& !partial_draw
)
271 if (gui_list
->title_icon
!= NOICON
&& draw_icons
)
273 screen_put_icon(display
, 0, 0, gui_list
->title_icon
);
274 #ifdef HAVE_LCD_BITMAP
275 text_pos
= get_icon_width(display
->screen_type
)+2; /* pixels */
277 text_pos
= 1; /* chars */
285 #ifdef HAVE_LCD_BITMAP
286 int title_style
= STYLE_DEFAULT
;
287 #ifdef HAVE_LCD_COLOR
288 if (gui_list
->title_color
>= 0)
290 title_style
|= STYLE_COLORED
;
291 title_style
|= gui_list
->title_color
;
294 screen_set_xmargin(display
, text_pos
); /* margin for title */
295 item_offset
= gui_list_get_item_offset(gui_list
, gui_list
->title_width
,
297 if (item_offset
> gui_list
->title_width
- (display
->width
- text_pos
))
298 display
->puts_style_offset(0, 0, gui_list
->title
,
299 title_style
, item_offset
);
301 display
->puts_scroll_style_offset(0, 0, gui_list
->title
,
302 title_style
, item_offset
);
304 display
->puts_scroll(text_pos
, 0, gui_list
->title
);
308 /* Adjust the position of icon, cursor, text for the list */
309 #ifdef HAVE_LCD_BITMAP
310 gui_textarea_update_nblines(display
);
313 draw_scrollbar
= (global_settings
.scrollbar
&&
314 lines
< gui_list
->nb_items
);
316 draw_cursor
= !global_settings
.invert_cursor
&&
317 gui_list
->show_selection_marker
;
318 text_pos
= 0; /* here it's in pixels */
319 if(draw_scrollbar
|| SHOW_LIST_TITLE
) /* indent if there's
322 text_pos
+= SCROLLBAR_WIDTH
;
325 text_pos
+= get_icon_width(display
->screen_type
) + 2;
328 text_pos
+= get_icon_width(display
->screen_type
) + 2;
332 text_pos
= 2; /* here it's in chars */
337 #ifdef HAVE_LCD_BITMAP
338 screen_set_xmargin(display
, text_pos
); /* margin for list */
344 if (end
< display
->nb_lines
)
348 for (i
= start
; i
< end
; i
++)
351 char entry_buffer
[MAX_PATH
];
352 unsigned char *entry_name
;
353 int current_item
= gui_list
->start_item
+
354 (SHOW_LIST_TITLE
? i
-1 : i
);
356 /* When there are less items to display than the
357 * current available space on the screen, we stop*/
358 if(current_item
>= gui_list
->nb_items
)
360 s
= gui_list
->callback_get_item_name(current_item
,
363 entry_name
= P2STR(s
);
365 #ifdef HAVE_LCD_BITMAP
366 int style
= STYLE_DEFAULT
;
367 /* position the string at the correct offset place */
369 display
->getstringsize(entry_name
, &item_width
, &h
);
370 item_offset
= gui_list_get_item_offset(gui_list
, item_width
, text_pos
);
373 #ifdef HAVE_LCD_COLOR
374 /* if the list has a color callback */
375 if (gui_list
->callback_get_item_color
)
377 int color
= gui_list
->callback_get_item_color(current_item
,
379 /* if color selected */
382 style
|= STYLE_COLORED
;
388 if(gui_list
->show_selection_marker
&&
389 current_item
>= gui_list
->selected_item
&&
390 current_item
< gui_list
->selected_item
+ gui_list
->selected_size
)
391 {/* The selected item must be displayed scrolling */
392 #ifdef HAVE_LCD_BITMAP
393 if (global_settings
.invert_cursor
)/* Display inverted-line-style*/
395 style
|= STYLE_INVERT
;
397 else /* if (!global_settings.invert_cursor) */
399 if (current_item
% gui_list
->selected_size
!= 0)
402 /* if the text is smaller than the viewport size */
403 if (item_offset
> item_width
- (display
->width
- text_pos
))
406 display
->puts_style_offset(0, i
, entry_name
,
411 display
->puts_scroll_style_offset(0, i
, entry_name
,
415 display
->puts_scroll(text_pos
, i
, entry_name
);
420 screen_put_icon_with_offset(display
, 0, i
,
421 (draw_scrollbar
|| SHOW_LIST_TITLE
)?
428 if(gui_list
->scroll_all
)
430 #ifdef HAVE_LCD_BITMAP
431 display
->puts_scroll_style_offset(0, i
, entry_name
,
434 display
->puts_scroll(text_pos
, i
, entry_name
);
439 #ifdef HAVE_LCD_BITMAP
440 display
->puts_style_offset(0, i
, entry_name
,
443 display
->puts(text_pos
, i
, entry_name
);
450 enum themable_icons icon
;
451 icon
= gui_list
->callback_get_item_icon(current_item
, gui_list
->data
);
452 if(icon
> Icon_NOICON
)
454 #ifdef HAVE_LCD_BITMAP
455 int x
= draw_cursor
?1:0;
456 int x_off
= (draw_scrollbar
|| SHOW_LIST_TITLE
) ? SCROLLBAR_WIDTH
: 0;
457 screen_put_icon_with_offset(display
, x
, i
,
460 screen_put_icon(display
, 1, i
, icon
);
466 #ifdef HAVE_LCD_BITMAP
467 /* Draw the scrollbar if needed*/
470 int y_start
= gui_textarea_get_ystart(display
);
472 y_start
+= display
->char_height
;
473 int scrollbar_y_end
= display
->char_height
*
475 gui_scrollbar_draw(display
, 0, y_start
, SCROLLBAR_WIDTH
-1,
476 scrollbar_y_end
- y_start
, gui_list
->nb_items
,
477 gui_list
->start_item
,
478 gui_list
->start_item
+ lines
, VERTICAL
);
481 screen_set_xmargin(display
, old_margin
);
484 gui_textarea_update(display
);
488 * Force a full screen update.
490 static void gui_list_draw(struct gui_list
*gui_list
)
492 last_list_displayed
[gui_list
->display
->screen_type
] = NULL
;
493 return gui_list_draw_smart(gui_list
);
497 * Selects an item in the list
498 * - gui_list : the list structure
499 * - item_number : the number of the item which will be selected
501 static void gui_list_select_item(struct gui_list
* gui_list
, int item_number
)
503 if( item_number
> gui_list
->nb_items
-1 || item_number
< 0 )
505 gui_list
->selected_item
= item_number
;
506 gui_list_select_at_offset(gui_list
, 0);
509 /* select an item above the current one */
510 static void gui_list_select_above(struct gui_list
* gui_list
,
511 int items
, int nb_lines
)
513 gui_list
->selected_item
-= items
;
515 /* in bottom "3rd" of the screen, so dont move the start item.
516 by 3rd I mean above SCROLL_LIMIT lines above the end of the screen */
517 if (items
&& gui_list
->start_item
+ SCROLL_LIMIT
< gui_list
->selected_item
)
519 if (gui_list
->show_selection_marker
== false)
521 gui_list
->start_item
-= items
;
522 if (gui_list
->start_item
< 0)
523 gui_list
->start_item
= 0;
527 if (gui_list
->selected_item
< 0)
529 if(gui_list
->limit_scroll
)
531 gui_list
->selected_item
= 0;
532 gui_list
->start_item
= 0;
536 gui_list
->selected_item
+= gui_list
->nb_items
;
537 if (global_settings
.scroll_paginated
)
539 gui_list
->start_item
= gui_list
->nb_items
- nb_lines
;
543 if (gui_list
->nb_items
> nb_lines
)
545 if (global_settings
.scroll_paginated
)
547 if (gui_list
->start_item
> gui_list
->selected_item
)
548 gui_list
->start_item
= MAX(0, gui_list
->start_item
- nb_lines
);
552 int top_of_screen
= gui_list
->selected_item
- SCROLL_LIMIT
;
553 int temp
= MIN(top_of_screen
, gui_list
->nb_items
- nb_lines
);
554 gui_list
->start_item
= MAX(0, temp
);
557 else gui_list
->start_item
= 0;
558 if (gui_list
->selected_size
> 1)
560 if (gui_list
->start_item
+ nb_lines
== gui_list
->selected_item
)
561 gui_list
->start_item
++;
564 /* select an item below the current one */
565 static void gui_list_select_below(struct gui_list
* gui_list
,
566 int items
, int nb_lines
)
570 gui_list
->selected_item
+= items
;
571 bottom
= gui_list
->nb_items
- nb_lines
;
573 /* always move the screen if selection isnt "visible" */
574 if (items
&& gui_list
->show_selection_marker
== false)
578 gui_list
->start_item
= MIN(bottom
, gui_list
->start_item
+
582 /* in top "3rd" of the screen, so dont move the start item */
584 (gui_list
->start_item
+ nb_lines
- SCROLL_LIMIT
> gui_list
->selected_item
)
585 && (gui_list
->selected_item
< gui_list
->nb_items
))
587 if (gui_list
->show_selection_marker
== false)
591 gui_list
->start_item
= MIN(bottom
,
592 gui_list
->start_item
+ items
);
597 if (gui_list
->selected_item
>= gui_list
->nb_items
)
599 if(gui_list
->limit_scroll
)
601 gui_list
->selected_item
= gui_list
->nb_items
-gui_list
->selected_size
;
602 gui_list
->start_item
= MAX(0,gui_list
->nb_items
- nb_lines
);
606 gui_list
->selected_item
= 0;
607 gui_list
->start_item
= 0;
612 if (gui_list
->nb_items
> nb_lines
)
614 if (global_settings
.scroll_paginated
)
616 if (gui_list
->start_item
+ nb_lines
<= gui_list
->selected_item
)
617 gui_list
->start_item
= MIN(bottom
, gui_list
->selected_item
);
621 int top_of_screen
= gui_list
->selected_item
+ SCROLL_LIMIT
- nb_lines
;
622 int temp
= MAX(0, top_of_screen
);
623 gui_list
->start_item
= MIN(bottom
, temp
);
626 else gui_list
->start_item
= 0;
629 static void gui_list_select_at_offset(struct gui_list
* gui_list
, int offset
)
631 /* do this here instead of in both select_above and select_below */
632 int nb_lines
= gui_list
->display
->nb_lines
;
636 if (gui_list
->selected_size
> 1)
638 offset
*= gui_list
->selected_size
;
639 /* always select the first item of multi-line lists */
640 offset
-= offset
%gui_list
->selected_size
;
642 if (offset
== 0 && global_settings
.scroll_paginated
&&
643 (gui_list
->nb_items
> nb_lines
))
645 int bottom
= gui_list
->nb_items
- nb_lines
;
646 gui_list
->start_item
= MIN(gui_list
->selected_item
, bottom
);
649 gui_list_select_above(gui_list
, -offset
, nb_lines
);
651 gui_list_select_below(gui_list
, offset
, nb_lines
);
655 * Adds an item to the list (the callback will be asked for one more item)
656 * - gui_list : the list structure
658 static void gui_list_add_item(struct gui_list
* gui_list
)
660 gui_list
->nb_items
++;
661 /* if only one item in the list, select it */
662 if(gui_list
->nb_items
== 1)
663 gui_list
->selected_item
= 0;
667 * Removes an item to the list (the callback will be asked for one less item)
668 * - gui_list : the list structure
670 static void gui_list_del_item(struct gui_list
* gui_list
)
672 if(gui_list
->nb_items
> 0)
674 gui_textarea_update_nblines(gui_list
->display
);
675 int nb_lines
= gui_list
->display
->nb_lines
;
677 int dist_selected_from_end
= gui_list
->nb_items
678 - gui_list
->selected_item
- 1;
679 int dist_start_from_end
= gui_list
->nb_items
680 - gui_list
->start_item
- 1;
681 if(dist_selected_from_end
== 0)
683 /* Oops we are removing the selected item,
684 select the previous one */
685 gui_list
->selected_item
--;
687 gui_list
->nb_items
--;
689 /* scroll the list if needed */
690 if( (dist_start_from_end
< nb_lines
) && (gui_list
->start_item
!= 0) )
691 gui_list
->start_item
--;
695 #ifdef HAVE_LCD_BITMAP
698 * Makes all the item in the list scroll by one step to the right.
699 * Should stop increasing the value when reaching the widest item value
702 static void gui_list_scroll_right(struct gui_list
* gui_list
)
704 /* FIXME: This is a fake right boundry limiter. there should be some
705 * callback function to find the longest item on the list in pixels,
706 * to stop the list from scrolling past that point */
707 gui_list
->offset_position
+=offset_step
;
708 if (gui_list
->offset_position
> 1000)
709 gui_list
->offset_position
= 1000;
713 * Makes all the item in the list scroll by one step to the left.
714 * stops at starting position.
716 static void gui_list_scroll_left(struct gui_list
* gui_list
)
718 gui_list
->offset_position
-=offset_step
;
719 if (gui_list
->offset_position
< 0)
720 gui_list
->offset_position
= 0;
722 void gui_list_screen_scroll_step(int ofs
)
727 void gui_list_screen_scroll_out_of_view(bool enable
)
730 offset_out_of_view
= true;
732 offset_out_of_view
= false;
734 #endif /* HAVE_LCD_BITMAP */
737 * Set the title and title icon of the list. Setting title to NULL disables
738 * both the title and icon. Use NOICON if there is no icon.
740 static void gui_list_set_title(struct gui_list
* gui_list
,
741 char * title
, enum themable_icons icon
)
743 gui_list
->title
= title
;
744 gui_list
->title_icon
= icon
;
746 #ifdef HAVE_LCD_BITMAP
747 gui_list
->display
->getstringsize(title
, &gui_list
->title_width
, NULL
);
749 gui_list
->title_width
= strlen(title
);
752 gui_list
->title_width
= 0;
757 * Synchronized lists stuffs
759 void gui_synclist_init(
760 struct gui_synclist
* lists
,
761 list_get_name callback_get_item_name
,
770 gui_list_init(&(lists
->gui_list
[i
]),
771 callback_get_item_name
,
772 data
, scroll_all
, selected_size
);
773 gui_list_set_display(&(lists
->gui_list
[i
]), &(screens
[i
]));
777 void gui_synclist_set_nb_items(struct gui_synclist
* lists
, int nb_items
)
782 gui_list_set_nb_items(&(lists
->gui_list
[i
]), nb_items
);
783 #ifdef HAVE_LCD_BITMAP
784 lists
->gui_list
[i
].offset_position
= 0;
788 int gui_synclist_get_nb_items(struct gui_synclist
* lists
)
790 return gui_list_get_nb_items(&((lists
)->gui_list
[0]));
792 int gui_synclist_get_sel_pos(struct gui_synclist
* lists
)
794 return gui_list_get_sel_pos(&((lists
)->gui_list
[0]));
796 void gui_synclist_set_icon_callback(struct gui_synclist
* lists
,
797 list_get_icon icon_callback
)
802 gui_list_set_icon_callback(&(lists
->gui_list
[i
]), icon_callback
);
806 void gui_synclist_draw(struct gui_synclist
* lists
)
810 gui_list_draw(&(lists
->gui_list
[i
]));
813 void gui_synclist_select_item(struct gui_synclist
* lists
, int item_number
)
817 gui_list_select_item(&(lists
->gui_list
[i
]), item_number
);
820 static void gui_synclist_select_next_page(struct gui_synclist
* lists
,
821 enum screen_type screen
)
825 gui_list_select_at_offset(&(lists
->gui_list
[i
]),
826 screens
[screen
].nb_lines
);
829 static void gui_synclist_select_previous_page(struct gui_synclist
* lists
,
830 enum screen_type screen
)
834 gui_list_select_at_offset(&(lists
->gui_list
[i
]),
835 -screens
[screen
].nb_lines
);
838 void gui_synclist_add_item(struct gui_synclist
* lists
)
842 gui_list_add_item(&(lists
->gui_list
[i
]));
845 void gui_synclist_del_item(struct gui_synclist
* lists
)
849 gui_list_del_item(&(lists
->gui_list
[i
]));
852 void gui_synclist_limit_scroll(struct gui_synclist
* lists
, bool scroll
)
856 gui_list_limit_scroll(&(lists
->gui_list
[i
]), scroll
);
859 void gui_synclist_set_title(struct gui_synclist
* lists
,
860 char * title
, enum themable_icons icon
)
864 gui_list_set_title(&(lists
->gui_list
[i
]), title
, icon
);
867 void gui_synclist_flash(struct gui_synclist
* lists
)
871 gui_list_flash(&(lists
->gui_list
[i
]));
874 #ifdef HAVE_LCD_BITMAP
875 static void gui_synclist_scroll_right(struct gui_synclist
* lists
)
879 gui_list_scroll_right(&(lists
->gui_list
[i
]));
882 static void gui_synclist_scroll_left(struct gui_synclist
* lists
)
886 gui_list_scroll_left(&(lists
->gui_list
[i
]));
888 #endif /* HAVE_LCD_BITMAP */
890 extern intptr_t get_action_data(void);
892 unsigned gui_synclist_do_button(struct gui_synclist
* lists
,
893 unsigned button
,enum list_wrap wrap
)
895 #ifdef HAVE_LCD_BITMAP
896 static bool scrolling_left
= false;
900 #ifdef HAVE_SCROLLWHEEL
901 int next_item_modifier
= button_apply_acceleration(get_action_data(),
902 WHEEL_ACCELERATION_FACTOR
);
904 static int next_item_modifier
= 1;
905 static int last_accel_tick
= 0;
907 if (global_settings
.list_accel_start_delay
)
909 int start_delay
= global_settings
.list_accel_start_delay
* (HZ
/2);
910 int accel_wait
= global_settings
.list_accel_wait
* HZ
/2;
912 if (get_action_statuscode(NULL
)&ACTION_REPEAT
)
914 if (!last_accel_tick
)
915 last_accel_tick
= current_tick
+ start_delay
;
916 else if (current_tick
>=
917 last_accel_tick
+ accel_wait
)
919 last_accel_tick
= current_tick
;
920 next_item_modifier
++;
923 else if (last_accel_tick
)
925 next_item_modifier
= 1;
934 gui_synclist_limit_scroll(lists
, false);
937 gui_synclist_limit_scroll(lists
, true);
939 case LIST_WRAP_UNLESS_HELD
:
940 if (button
== ACTION_STD_PREVREPEAT
||
941 button
== ACTION_STD_NEXTREPEAT
||
942 button
== ACTION_LISTTREE_PGUP
||
943 button
== ACTION_LISTTREE_PGDOWN
)
944 gui_synclist_limit_scroll(lists
, true);
945 else gui_synclist_limit_scroll(lists
, false);
951 #ifdef HAVE_VOLUME_IN_LIST
952 case ACTION_LIST_VOLUP
:
953 global_settings
.volume
+= 2;
954 /* up two because the falthrough brings it down one */
955 case ACTION_LIST_VOLDOWN
:
956 global_settings
.volume
--;
960 case ACTION_STD_PREV
:
961 case ACTION_STD_PREVREPEAT
:
963 gui_list_select_at_offset(&(lists
->gui_list
[i
]), -next_item_modifier
);
964 #ifndef HAVE_SCROLLWHEEL
965 if (queue_count(&button_queue
) < FRAMEDROP_TRIGGER
)
968 gui_synclist_draw(lists
);
971 return ACTION_STD_PREV
;
973 case ACTION_STD_NEXT
:
974 case ACTION_STD_NEXTREPEAT
:
976 gui_list_select_at_offset(&(lists
->gui_list
[i
]), next_item_modifier
);
977 #ifndef HAVE_SCROLLWHEEL
978 if (queue_count(&button_queue
) < FRAMEDROP_TRIGGER
)
981 gui_synclist_draw(lists
);
984 return ACTION_STD_NEXT
;
986 #ifdef HAVE_LCD_BITMAP
987 case ACTION_TREE_ROOT_INIT
:
988 /* After this button press ACTION_TREE_PGLEFT is allowed
989 to skip to root. ACTION_TREE_ROOT_INIT must be defined in the
990 keymaps as a repeated button press (the same as the repeated
991 ACTION_TREE_PGLEFT) with the pre condition being the non-repeated
993 if (lists
->gui_list
[0].offset_position
== 0)
995 scrolling_left
= false;
996 return ACTION_STD_CANCEL
;
998 case ACTION_TREE_PGRIGHT
:
999 gui_synclist_scroll_right(lists
);
1000 gui_synclist_draw(lists
);
1001 return ACTION_TREE_PGRIGHT
;
1002 case ACTION_TREE_PGLEFT
:
1003 if(!scrolling_left
&& (lists
->gui_list
[0].offset_position
== 0))
1004 return ACTION_STD_CANCEL
;
1005 gui_synclist_scroll_left(lists
);
1006 gui_synclist_draw(lists
);
1007 scrolling_left
= true; /* stop ACTION_TREE_PAGE_LEFT
1009 return ACTION_TREE_PGLEFT
;
1012 /* for pgup / pgdown, we are obliged to have a different behaviour depending
1013 * on the screen for which the user pressed the key since for example, remote
1014 * and main screen doesn't have the same number of lines */
1015 case ACTION_LISTTREE_PGUP
:
1018 #ifdef HAVE_REMOTE_LCD
1019 get_action_statuscode(NULL
)&ACTION_REMOTE
?
1023 gui_synclist_select_previous_page(lists
, screen
);
1024 gui_synclist_draw(lists
);
1027 return ACTION_STD_NEXT
;
1029 case ACTION_LISTTREE_PGDOWN
:
1032 #ifdef HAVE_REMOTE_LCD
1033 get_action_statuscode(NULL
)&ACTION_REMOTE
?
1037 gui_synclist_select_next_page(lists
, screen
);
1038 gui_synclist_draw(lists
);
1041 return ACTION_STD_PREV
;