summaryrefslogtreecommitdiff
path: root/bootloader/x1000
diff options
context:
space:
mode:
Diffstat (limited to 'bootloader/x1000')
-rw-r--r--bootloader/x1000/recovery.c125
1 files changed, 78 insertions, 47 deletions
diff --git a/bootloader/x1000/recovery.c b/bootloader/x1000/recovery.c
index 4d806b26a4..3d6a079af8 100644
--- a/bootloader/x1000/recovery.c
+++ b/bootloader/x1000/recovery.c
@@ -50,77 +50,108 @@ static const struct menuitem recovery_items[] = {
50 {MENUITEM_ACTION, "Restore", &bootloader_restore}, 50 {MENUITEM_ACTION, "Restore", &bootloader_restore},
51}; 51};
52 52
53static void put_help_line(int line, const char* str1, const char* str2) 53static void recmenu_draw_item(const struct bl_listitem* item)
54{ 54{
55 int width = LCD_WIDTH / SYSFONT_WIDTH; 55 const struct menuitem* mu = &recovery_items[item->index];
56 lcd_puts(0, line, str1); 56 const char* fmt;
57 lcd_puts(width - strlen(str2), line, str2); 57
58 switch(mu->type) {
59 case MENUITEM_HEADING:
60 fmt = "[%s]";
61 break;
62
63 case MENUITEM_ACTION:
64 default:
65 if(item->index == item->list->selected_item)
66 fmt = "=> %s";
67 else
68 fmt = " %s";
69 break;
70 }
71
72 lcd_putsxyf(item->x, item->y, fmt, mu->text);
58} 73}
59 74
60void recovery_menu(void) 75static void recmenu_scroll(struct bl_list* list, int dir)
61{ 76{
62 const int n_items = sizeof(recovery_items)/sizeof(struct menuitem); 77 int start, end, step;
78
79 if(dir < 0) {
80 start = list->selected_item - 1;
81 end = -1;
82 step = -1;
83 } else if(dir > 0) {
84 start = list->selected_item + 1;
85 end = list->num_items;
86 step = 1;
87 } else {
88 return;
89 }
63 90
64 int selection = 0; 91 for(int i = start; i != end; i += step) {
65 while(recovery_items[selection].type != MENUITEM_ACTION) 92 if(recovery_items[i].action) {
66 ++selection; 93 gui_list_select(list, i);
67 94
68 while(1) { 95 /* always show one item above the selection to ensure
69 clearscreen(); 96 * the topmost heading is visible */
70 putcenter_y(0, "Rockbox recovery menu"); 97 if(list->selected_item == list->top_item && list->top_item > 0)
71 98 list->top_item--;
72 int top_line = 2;
73 99
74 /* draw the menu */ 100 break;
75 for(int i = 0; i < n_items; ++i) { 101 }
76 switch(recovery_items[i].type) { 102 }
77 case MENUITEM_HEADING: 103}
78 lcd_putsf(0, top_line+i, "[%s]", recovery_items[i].text);
79 break;
80 104
81 case MENUITEM_ACTION: 105static void put_help_line(int y, int line, const char* str1, const char* str2)
82 lcd_puts(3, top_line+i, recovery_items[i].text); 106{
83 break; 107 y += line*SYSFONT_HEIGHT;
108 lcd_putsxy(0, y, str1);
109 lcd_putsxy(LCD_WIDTH - strlen(str2)*SYSFONT_WIDTH, y, str2);
110}
84 111
85 default: 112void recovery_menu(void)
86 break; 113{
87 } 114 struct viewport vp = {
88 } 115 .x = 0, .y = SYSFONT_HEIGHT,
116 .width = LCD_WIDTH,
117 .height = LCD_HEIGHT - SYSFONT_HEIGHT*5,
118 };
119 lcd_init_viewport(&vp);
120
121 struct bl_list list;
122 gui_list_init(&list, &vp);
123 list.num_items = ARRAYLEN(recovery_items);
124 list.selected_item = 1; /* first item is a heading */
125 list.draw_item = recmenu_draw_item;
89 126
90 /* draw the selection marker */ 127 while(1) {
91 lcd_puts(0, top_line+selection, "=>"); 128 clearscreen();
129 putcenter_y(0, "Rockbox recovery menu");
92 130
93 /* draw the help text */ 131 /* draw the help text */
94 int line = (LCD_HEIGHT - SYSFONT_HEIGHT)/SYSFONT_HEIGHT - 3; 132 int ypos = LCD_HEIGHT - 4*SYSFONT_HEIGHT;
95 put_help_line(line++, BL_DOWN_NAME "/" BL_UP_NAME, "move cursor"); 133 put_help_line(ypos, 0, BL_DOWN_NAME "/" BL_UP_NAME, "move cursor");
96 put_help_line(line++, BL_SELECT_NAME, "select item"); 134 put_help_line(ypos, 1, BL_SELECT_NAME, "select item");
97 put_help_line(line++, BL_QUIT_NAME, "power off"); 135 put_help_line(ypos, 2, BL_QUIT_NAME, "power off");
136
137 /* draw the list */
138 gui_list_draw(&list);
98 139
99 lcd_update(); 140 lcd_update();
100 141
101 /* handle input */ 142 /* handle input */
102 switch(get_button(TIMEOUT_BLOCK)) { 143 switch(get_button(TIMEOUT_BLOCK)) {
103 case BL_SELECT: { 144 case BL_SELECT: {
104 if(recovery_items[selection].action) 145 if(recovery_items[list.selected_item].action)
105 recovery_items[selection].action(); 146 recovery_items[list.selected_item].action();
106 } break; 147 } break;
107 148
108 case BL_UP: 149 case BL_UP:
109 for(int i = selection-1; i >= 0; --i) { 150 recmenu_scroll(&list, -1);
110 if(recovery_items[i].action) {
111 selection = i;
112 break;
113 }
114 }
115 break; 151 break;
116 152
117 case BL_DOWN: 153 case BL_DOWN:
118 for(int i = selection+1; i < n_items; ++i) { 154 recmenu_scroll(&list, 1);
119 if(recovery_items[i].action) {
120 selection = i;
121 break;
122 }
123 }
124 break; 155 break;
125 156
126 case BL_QUIT: 157 case BL_QUIT: