Added a time/date setting
[kugel-rb/myfork.git] / apps / menu.c
blob06034bd4d1ffa8745d629ec9811ff31c1ba4a3e6
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Robert E. Hak
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 ****************************************************************************/
19 #include <stdbool.h>
20 #include "lcd.h"
21 #include "menu.h"
22 #include "button.h"
23 #include "kernel.h"
24 #include "debug.h"
26 #ifdef HAVE_LCD_BITMAP
27 #include "icons.h"
28 #endif
30 struct menu {
31 int top;
32 int cursor;
33 struct menu_items* items;
34 int itemcount;
37 #define MAX_MENUS 4
39 #ifdef HAVE_LCD_BITMAP
40 #define MENU_LINES 8
41 #else
42 #define MENU_LINES 2
43 #endif
45 #ifdef HAVE_NEW_CHARCELL_LCD
46 #define CURSOR_CHAR "\x7e"
47 #else
48 #define CURSOR_CHAR "\x89"
49 #endif
51 static struct menu menus[MAX_MENUS];
52 static bool inuse[MAX_MENUS] = { false };
54 /* count in letter posistions, NOT pixels */
55 void put_cursorxy(int x, int y, bool on)
57 /* place the cursor */
58 if(on) {
59 #ifdef HAVE_LCD_BITMAP
60 lcd_bitmap ( bitmap_icons_6x8[Cursor],
61 x*6, y*8, 4, 8, true);
62 #elif defined(SIMULATOR)
63 /* player simulator */
64 unsigned char cursor[] = { 0x7f, 0x3e, 0x1c, 0x08 };
65 lcd_bitmap ( cursor, x*6, 12+y*16, 4, 8, true);
66 #else
67 lcd_puts(x, y, CURSOR_CHAR);
68 #endif
70 else {
71 #if defined(HAVE_LCD_BITMAP)
72 /* I use xy here since it needs to disregard the margins */
73 lcd_clearrect (x*6, y*8, 4, 8);
74 #elif defined(SIMULATOR)
75 /* player simulator in action */
76 lcd_clearrect (x*6, 12+y*16, 4, 8);
77 #else
78 lcd_puts(x, y, " ");
79 #endif
83 static void menu_draw(int m)
85 int i = 0;
87 lcd_clear_display();
88 lcd_stop_scroll();
89 #ifdef HAVE_LCD_BITMAP
90 lcd_setmargins(0,0);
91 lcd_setfont(0);
92 #endif
93 for (i = menus[m].top;
94 (i < menus[m].itemcount) && (i<menus[m].top+MENU_LINES);
95 i++) {
96 if((menus[m].cursor - menus[m].top)==(i-menus[m].top))
97 lcd_puts_scroll(1, i-menus[m].top, menus[m].items[i].desc);
98 else
99 lcd_puts(1, i-menus[m].top, menus[m].items[i].desc);
102 /* place the cursor */
103 put_cursorxy(0, menus[m].cursor - menus[m].top, true);
104 lcd_update();
108 * Move the cursor to a particular id,
109 * target: where you want it to be
111 static void put_cursor(int m, int target)
113 bool do_update = true;
115 put_cursorxy(0, menus[m].cursor - menus[m].top, false);
116 menus[m].cursor = target;
117 menu_draw(m);
119 if ( target < menus[m].top ) {
120 menus[m].top--;
121 menu_draw(m);
122 do_update = false;
124 else if ( target-menus[m].top > MENU_LINES-1 ) {
125 menus[m].top++;
126 menu_draw(m);
127 do_update = false;
130 if (do_update) {
131 put_cursorxy(0, menus[m].cursor - menus[m].top, true);
132 lcd_update();
137 int menu_init(struct menu_items* mitems, int count)
139 int i;
141 for ( i=0; i<MAX_MENUS; i++ ) {
142 if ( !inuse[i] ) {
143 inuse[i] = true;
144 break;
147 if ( i == MAX_MENUS ) {
148 DEBUGF("Out of menus!\n");
149 return -1;
151 menus[i].items = mitems;
152 menus[i].itemcount = count;
153 menus[i].top = 0;
154 menus[i].cursor = 0;
156 return i;
159 void menu_exit(int m)
161 inuse[m] = false;
164 void menu_run(int m)
166 menu_draw(m);
168 while(1) {
169 switch( button_get(true) ) {
170 #ifdef HAVE_RECORDER_KEYPAD
171 case BUTTON_UP:
172 #else
173 case BUTTON_LEFT:
174 case BUTTON_LEFT | BUTTON_REPEAT:
175 #endif
176 if (menus[m].cursor) {
177 /* move up */
178 put_cursor(m, menus[m].cursor-1);
180 break;
182 #ifdef HAVE_RECORDER_KEYPAD
183 case BUTTON_DOWN:
184 #else
185 case BUTTON_RIGHT:
186 case BUTTON_RIGHT | BUTTON_REPEAT:
187 #endif
188 if (menus[m].cursor < menus[m].itemcount-1) {
189 /* move down */
190 put_cursor(m, menus[m].cursor+1);
192 break;
194 #ifdef HAVE_RECORDER_KEYPAD
195 case BUTTON_RIGHT:
196 #endif
197 case BUTTON_PLAY:
198 /* Erase current display state */
199 lcd_stop_scroll();
200 lcd_clear_display();
202 menus[m].items[menus[m].cursor].function();
204 /* Return to previous display state */
205 menu_draw(m);
206 break;
208 #ifdef HAVE_RECORDER_KEYPAD
209 case BUTTON_LEFT:
210 case BUTTON_F1:
211 #else
212 case BUTTON_STOP:
213 case BUTTON_MENU:
214 #endif
215 lcd_stop_scroll();
216 return;
218 default:
219 break;
222 lcd_update();