blob: 7267afe193939681f62d735e9d9bbcbe28ad4ea7 [file] [log] [blame]
Daniel Stenberg1c0c8612002-05-17 12:22:24 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Robert E. Hak
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
Björn Stenberg2ac05722002-05-26 17:03:17 +000019#include <stdbool.h>
Daniel Stenberg1c0c8612002-05-17 12:22:24 +000020#include "lcd.h"
21#include "menu.h"
Björn Stenbergb21a3bd2002-05-21 14:25:45 +000022#include "button.h"
23#include "kernel.h"
24#include "debug.h"
Björn Stenbergcd225732002-08-11 09:17:47 +000025#include "panic.h"
Daniel Stenberg1c0c8612002-05-17 12:22:24 +000026
Daniel Stenbergbf603f92002-06-14 08:47:44 +000027#ifdef HAVE_LCD_BITMAP
28#include "icons.h"
29#endif
Björn Stenbergcd225732002-08-11 09:17:47 +000030#ifdef LOADABLE_FONTS
31#include "ajf.h"
32#endif
Björn Stenberg2ac05722002-05-26 17:03:17 +000033struct menu {
Björn Stenbergf76cee72002-05-28 15:35:33 +000034 int top;
Björn Stenberg2ac05722002-05-26 17:03:17 +000035 int cursor;
36 struct menu_items* items;
37 int itemcount;
38};
39
40#define MAX_MENUS 4
41
Björn Stenbergf76cee72002-05-28 15:35:33 +000042#ifdef HAVE_LCD_BITMAP
Robert Hak4164f582002-06-16 23:27:58 +000043#define MENU_LINES 8
Björn Stenbergf76cee72002-05-28 15:35:33 +000044#else
45#define MENU_LINES 2
46#endif
47
Björn Stenberg9314a682002-05-31 09:04:51 +000048#ifdef HAVE_NEW_CHARCELL_LCD
49#define CURSOR_CHAR "\x7e"
50#else
51#define CURSOR_CHAR "\x89"
52#endif
Björn Stenberg9314a682002-05-31 09:04:51 +000053
Björn Stenberg2ac05722002-05-26 17:03:17 +000054static struct menu menus[MAX_MENUS];
55static bool inuse[MAX_MENUS] = { false };
Daniel Stenberg1c0c8612002-05-17 12:22:24 +000056
Daniel Stenbergbf603f92002-06-14 08:47:44 +000057/* count in letter posistions, NOT pixels */
58void put_cursorxy(int x, int y, bool on)
59{
Björn Stenbergcd225732002-08-11 09:17:47 +000060#ifdef LOADABLE_FONTS
61 int fh;
62 unsigned char* font = lcd_getcurrentldfont();
63 fh = ajf_get_fontheight(font);
64#else
65 int fh = 8;
66#endif
67
Daniel Stenbergbf603f92002-06-14 08:47:44 +000068 /* place the cursor */
69 if(on) {
70#ifdef HAVE_LCD_BITMAP
71 lcd_bitmap ( bitmap_icons_6x8[Cursor],
Björn Stenbergcd225732002-08-11 09:17:47 +000072 x*6, y*fh, 4, 8, true);
Daniel Stenberge35f8eb2002-06-15 11:39:36 +000073#elif defined(SIMULATOR)
Daniel Stenbergc4be1ee2002-06-19 13:00:14 +000074 /* player simulator */
Daniel Stenberge35f8eb2002-06-15 11:39:36 +000075 unsigned char cursor[] = { 0x7f, 0x3e, 0x1c, 0x08 };
Daniel Stenberg7cdf5c82002-08-09 09:13:00 +000076 lcd_bitmap ( cursor, x*6, 12+y*16, 4, 8, true);
Daniel Stenbergbf603f92002-06-14 08:47:44 +000077#else
78 lcd_puts(x, y, CURSOR_CHAR);
79#endif
80 }
81 else {
Daniel Stenbergc4be1ee2002-06-19 13:00:14 +000082#if defined(HAVE_LCD_BITMAP)
Daniel Stenbergbf603f92002-06-14 08:47:44 +000083 /* I use xy here since it needs to disregard the margins */
Björn Stenbergcd225732002-08-11 09:17:47 +000084 lcd_clearrect (x*6, y*fh, 4, 8);
Daniel Stenbergc4be1ee2002-06-19 13:00:14 +000085#elif defined(SIMULATOR)
86 /* player simulator in action */
Daniel Stenberg7cdf5c82002-08-09 09:13:00 +000087 lcd_clearrect (x*6, 12+y*16, 4, 8);
Daniel Stenbergbf603f92002-06-14 08:47:44 +000088#else
89 lcd_puts(x, y, " ");
90#endif
91 }
92}
93
Björn Stenbergf76cee72002-05-28 15:35:33 +000094static void menu_draw(int m)
95{
96 int i = 0;
Björn Stenbergcd225732002-08-11 09:17:47 +000097#ifdef LOADABLE_FONTS
98 int menu_lines;
99 int fh;
100 unsigned char* font = lcd_getcurrentldfont();
101 fh = ajf_get_fontheight(font);
102 menu_lines = LCD_HEIGHT/fh;
103#else
104 int menu_lines = MENU_LINES;
105#endif
Björn Stenbergf76cee72002-05-28 15:35:33 +0000106
Linus Nielsen Feltzing8fa02172002-08-02 07:59:25 +0000107 lcd_clear_display();
108 lcd_stop_scroll();
Björn Stenbergf76cee72002-05-28 15:35:33 +0000109#ifdef HAVE_LCD_BITMAP
110 lcd_setmargins(0,0);
111 lcd_setfont(0);
112#endif
113 for (i = menus[m].top;
Björn Stenbergcd225732002-08-11 09:17:47 +0000114 (i < menus[m].itemcount) && (i<menus[m].top+menu_lines);
Björn Stenbergf76cee72002-05-28 15:35:33 +0000115 i++) {
Linus Nielsen Feltzing8fa02172002-08-02 07:59:25 +0000116 if((menus[m].cursor - menus[m].top)==(i-menus[m].top))
117 lcd_puts_scroll(1, i-menus[m].top, menus[m].items[i].desc);
118 else
119 lcd_puts(1, i-menus[m].top, menus[m].items[i].desc);
Björn Stenbergf76cee72002-05-28 15:35:33 +0000120 }
Robert Hakc501ac72002-05-30 08:06:42 +0000121
Daniel Stenbergbf603f92002-06-14 08:47:44 +0000122 /* place the cursor */
123 put_cursorxy(0, menus[m].cursor - menus[m].top, true);
Björn Stenbergf76cee72002-05-28 15:35:33 +0000124 lcd_update();
125}
126
Björn Stenbergb21a3bd2002-05-21 14:25:45 +0000127/*
128 * Move the cursor to a particular id,
129 * target: where you want it to be
130 */
Björn Stenberg2ac05722002-05-26 17:03:17 +0000131static void put_cursor(int m, int target)
Daniel Stenberg1c0c8612002-05-17 12:22:24 +0000132{
Robert Hakc501ac72002-05-30 08:06:42 +0000133 bool do_update = true;
Björn Stenbergcd225732002-08-11 09:17:47 +0000134#ifdef LOADABLE_FONTS
135 int menu_lines;
136 int fh;
137 unsigned char* font = lcd_getcurrentldfont();
138 fh = ajf_get_fontheight(font);
139 menu_lines = LCD_HEIGHT/fh;
140#else
141 int menu_lines = MENU_LINES;
142#endif
Daniel Stenbergbf603f92002-06-14 08:47:44 +0000143 put_cursorxy(0, menus[m].cursor - menus[m].top, false);
Robert Hakc501ac72002-05-30 08:06:42 +0000144 menus[m].cursor = target;
Linus Nielsen Feltzing8fa02172002-08-02 07:59:25 +0000145 menu_draw(m);
Björn Stenbergf76cee72002-05-28 15:35:33 +0000146
147 if ( target < menus[m].top ) {
148 menus[m].top--;
149 menu_draw(m);
Robert Hakc501ac72002-05-30 08:06:42 +0000150 do_update = false;
Björn Stenbergf76cee72002-05-28 15:35:33 +0000151 }
Björn Stenbergcd225732002-08-11 09:17:47 +0000152 else if ( target-menus[m].top > menu_lines-1 ) {
Björn Stenbergf76cee72002-05-28 15:35:33 +0000153 menus[m].top++;
154 menu_draw(m);
Robert Hakc501ac72002-05-30 08:06:42 +0000155 do_update = false;
Björn Stenbergf76cee72002-05-28 15:35:33 +0000156 }
Robert Hakc501ac72002-05-30 08:06:42 +0000157
158 if (do_update) {
Daniel Stenbergbf603f92002-06-14 08:47:44 +0000159 put_cursorxy(0, menus[m].cursor - menus[m].top, true);
Robert Hakc501ac72002-05-30 08:06:42 +0000160 lcd_update();
161 }
162
Daniel Stenberg1c0c8612002-05-17 12:22:24 +0000163}
164
Björn Stenberg2ac05722002-05-26 17:03:17 +0000165int menu_init(struct menu_items* mitems, int count)
Daniel Stenberg1c0c8612002-05-17 12:22:24 +0000166{
Björn Stenberg2ac05722002-05-26 17:03:17 +0000167 int i;
168
169 for ( i=0; i<MAX_MENUS; i++ ) {
170 if ( !inuse[i] ) {
171 inuse[i] = true;
172 break;
173 }
174 }
175 if ( i == MAX_MENUS ) {
176 DEBUGF("Out of menus!\n");
177 return -1;
178 }
179 menus[i].items = mitems;
180 menus[i].itemcount = count;
Björn Stenbergf76cee72002-05-28 15:35:33 +0000181 menus[i].top = 0;
Björn Stenberg2ac05722002-05-26 17:03:17 +0000182 menus[i].cursor = 0;
183
184 return i;
Daniel Stenberg1c0c8612002-05-17 12:22:24 +0000185}
186
Björn Stenberg2ac05722002-05-26 17:03:17 +0000187void menu_exit(int m)
Daniel Stenberg1c0c8612002-05-17 12:22:24 +0000188{
Björn Stenberg2ac05722002-05-26 17:03:17 +0000189 inuse[m] = false;
Daniel Stenberg1c0c8612002-05-17 12:22:24 +0000190}
191
Björn Stenberg2ac05722002-05-26 17:03:17 +0000192void menu_run(int m)
Robert Hak7ec9aa32002-05-18 11:41:37 +0000193{
Björn Stenberg2ac05722002-05-26 17:03:17 +0000194 menu_draw(m);
Björn Stenbergb21a3bd2002-05-21 14:25:45 +0000195
196 while(1) {
Björn Stenberg856a13a2002-05-28 12:10:12 +0000197 switch( button_get(true) ) {
Björn Stenbergb21a3bd2002-05-21 14:25:45 +0000198#ifdef HAVE_RECORDER_KEYPAD
199 case BUTTON_UP:
Björn Stenbergcbc71792002-08-10 09:04:55 +0000200 case BUTTON_UP | BUTTON_REPEAT:
Robert Hak7ec9aa32002-05-18 11:41:37 +0000201#else
Björn Stenbergb21a3bd2002-05-21 14:25:45 +0000202 case BUTTON_LEFT:
Linus Nielsen Feltzing8fa02172002-08-02 07:59:25 +0000203 case BUTTON_LEFT | BUTTON_REPEAT:
Robert Hak7ec9aa32002-05-18 11:41:37 +0000204#endif
Björn Stenberg4caebab2002-05-29 14:25:06 +0000205 if (menus[m].cursor) {
Björn Stenbergb21a3bd2002-05-21 14:25:45 +0000206 /* move up */
Björn Stenberg2ac05722002-05-26 17:03:17 +0000207 put_cursor(m, menus[m].cursor-1);
Björn Stenbergb21a3bd2002-05-21 14:25:45 +0000208 }
209 break;
Robert Hakdfba2102002-05-21 08:47:34 +0000210
Björn Stenbergb21a3bd2002-05-21 14:25:45 +0000211#ifdef HAVE_RECORDER_KEYPAD
212 case BUTTON_DOWN:
Björn Stenbergcbc71792002-08-10 09:04:55 +0000213 case BUTTON_DOWN | BUTTON_REPEAT:
Björn Stenbergb21a3bd2002-05-21 14:25:45 +0000214#else
215 case BUTTON_RIGHT:
Linus Nielsen Feltzing8fa02172002-08-02 07:59:25 +0000216 case BUTTON_RIGHT | BUTTON_REPEAT:
Björn Stenbergb21a3bd2002-05-21 14:25:45 +0000217#endif
Björn Stenberg4caebab2002-05-29 14:25:06 +0000218 if (menus[m].cursor < menus[m].itemcount-1) {
Björn Stenbergb21a3bd2002-05-21 14:25:45 +0000219 /* move down */
Björn Stenberg2ac05722002-05-26 17:03:17 +0000220 put_cursor(m, menus[m].cursor+1);
Björn Stenbergb21a3bd2002-05-21 14:25:45 +0000221 }
222 break;
223
224#ifdef HAVE_RECORDER_KEYPAD
225 case BUTTON_RIGHT:
226#endif
227 case BUTTON_PLAY:
228 /* Erase current display state */
Linus Nielsen Feltzing8fa02172002-08-02 07:59:25 +0000229 lcd_stop_scroll();
Björn Stenbergb21a3bd2002-05-21 14:25:45 +0000230 lcd_clear_display();
231
Björn Stenberg2ac05722002-05-26 17:03:17 +0000232 menus[m].items[menus[m].cursor].function();
Björn Stenbergb21a3bd2002-05-21 14:25:45 +0000233
234 /* Return to previous display state */
Björn Stenberg2ac05722002-05-26 17:03:17 +0000235 menu_draw(m);
Björn Stenbergb21a3bd2002-05-21 14:25:45 +0000236 break;
237
238#ifdef HAVE_RECORDER_KEYPAD
239 case BUTTON_LEFT:
Linus Nielsen Feltzinga552f4c2002-07-27 19:53:26 +0000240 case BUTTON_F1:
Björn Stenbergb21a3bd2002-05-21 14:25:45 +0000241#else
242 case BUTTON_STOP:
Björn Stenberg60fad542002-05-29 12:28:08 +0000243 case BUTTON_MENU:
Björn Stenbergb21a3bd2002-05-21 14:25:45 +0000244#endif
Linus Nielsen Feltzing8fa02172002-08-02 07:59:25 +0000245 lcd_stop_scroll();
Björn Stenbergb21a3bd2002-05-21 14:25:45 +0000246 return;
247
248 default:
249 break;
250 }
251
252 lcd_update();
253 }
Robert Hak7ec9aa32002-05-18 11:41:37 +0000254}