X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=mware%2Fmenu.c;h=9c1149dbded7043611bc52e3276561e81a86599d;hb=39d6b2d1d9df77a019b6d2c436da87e862f9d452;hp=2aa23abd873a6a31c3d8941b1c1c8537fde5e5e3;hpb=ef9091677fa3d4fb9f903fcb5debe52d5b52a8cf;p=bertos.git diff --git a/mware/menu.c b/mware/menu.c index 2aa23abd..9c1149db 100755 --- a/mware/menu.c +++ b/mware/menu.c @@ -1,7 +1,7 @@ /*! * \file * @@ -16,6 +16,18 @@ /*#* *#* $Log$ + *#* Revision 1.7 2006/04/27 05:39:24 bernie + *#* Enhance text rendering to arbitrary x,y coords. + *#* + *#* Revision 1.6 2006/04/11 00:07:32 bernie + *#* Implemenent MF_SAVESEL flag. + *#* + *#* Revision 1.5 2006/03/22 09:49:51 bernie + *#* Simplifications from project_grl. + *#* + *#* Revision 1.4 2006/03/20 17:48:35 bernie + *#* Implement support for ROM menus. + *#* *#* Revision 1.3 2006/02/20 14:34:32 bernie *#* Include appconfig.h before using its definitions. *#* @@ -69,7 +81,6 @@ *#*/ #include "menu.h" - #include #include #include @@ -77,12 +88,15 @@ #include #include #include +#include /* strcpy() */ #if CPU_HARVARD #include /* strncpy_P() */ #endif -#include /* strcpy() */ +#if CONFIG_MENU_SMOOTH +#include +#endif #if CONFIG_MENU_MENUBAR #include "menubar.h" @@ -94,7 +108,6 @@ #define PTRMSG(x) ((const char *)x) #endif - /* Temporary fake defines for ABORT stuff... */ #define abort_top 0 #define PUSH_ABORT false @@ -102,22 +115,30 @@ #define DO_ABORT do {} while(0) -#ifdef _DEBUG -/*! +/** * Count the items present in a menu. */ -static int UNUSED_FUNC menu_count(const struct Menu *menu) +static int menu_count(const struct Menu *menu) { int cnt = 0; - struct MenuItem *item; - for (item = menu->items; item->label; ++item) - cnt++; + for (cnt = 0; /*NOP*/; ++cnt) + { + const MenuItem *item = &menu->items[cnt]; +#if CPU_HARVARD + MenuItem ram_item; + if (menu->flags & MF_ROMITEMS) + { + memcpy_P(&ram_item, item, sizeof(ram_item)); + item = &ram_item; + } +#endif + if (!(item->label || item->hook)) + break; + } return cnt; } -#endif /* _DEBUG */ - #if CONFIG_MENU_MENUBAR @@ -130,7 +151,17 @@ static void menu_update_menubar( struct MenuBar *mb, int selected) { - int item_flags = menu->items[selected].flags; + int item_flags; +#if CPU_HARVARD + if (menu->flags & MF_ROMITEMS) + { + ASSERT(sizeof(menu->items[selected].flags) == sizeof(int)); + item_flags = pgm_read_int(&menu->items[selected].flags); + } + else +#endif + item_flags = menu->items[selected].flags; + const_iptr_t newlabel = (const_iptr_t)LABEL_OK; if (item_flags & MIF_DISABLED) @@ -149,8 +180,8 @@ static void menu_update_menubar( #endif /* CONFIG_MENU_MENUBAR */ -/*! - * Show a menu on the LCD display. +/** + * Show a menu on the display. */ static void menu_layout( const struct Menu *menu, @@ -158,20 +189,68 @@ static void menu_layout( int items_per_page, int selected) { - const MenuItem *item; int ypos, cnt; const char * PROGMEM title = PTRMSG(menu->title); + Bitmap *bm = menu->bitmap; - ypos = menu->startrow; + ypos = bm->cr.ymin; if (title) - text_xprintf(menu->bitmap, ypos++, 0, STYLEF_BOLD | TEXT_FILL, title); + { + text_xyprintf(bm, 0, ypos, STYLEF_UNDERLINE | STYLEF_BOLD | TEXT_CENTER | TEXT_FILL, title); + ypos += bm->font->height; + } + +#if CONFIG_MENU_SMOOTH + static coord_t yoffset = 0; + static int old_first_item = 0; + static mtime_t old_time = 0; //UNUSED + static int speed; + coord_t old_ymin = bm->cr.ymin; + + gfx_setClipRect(bm, + bm->cr.xmin, bm->cr.ymin + ypos, + bm->cr.xmax, bm->cr.ymax); + + if (old_first_item != first_item) + { + speed = ABS(old_first_item - first_item) * 3; + + if (old_first_item > first_item) + { + yoffset += speed; + if (yoffset > bm->font->height) + { + yoffset = 0; + --old_first_item; + } + } + else + { + yoffset -= speed; + if (yoffset < -bm->font->height) + { + yoffset = 0; + ++old_first_item; + } + } + first_item = old_first_item; + } + ypos += yoffset; +#endif - for ( - cnt = 0, item = &menu->items[first_item]; - cnt < items_per_page; - ++cnt, ++item) + for (cnt = 0; cnt < items_per_page; ++cnt) { + const MenuItem *item = &menu->items[first_item + cnt]; +#if CPU_HARVARD + MenuItem ram_item; + if (menu->flags & MF_ROMITEMS) + { + memcpy_P(&ram_item, item, sizeof(ram_item)); + item = &ram_item; + } +#endif + /* Check for end of menu */ if (!(item->label || item->hook)) break; @@ -180,21 +259,31 @@ static void menu_layout( if (!(item->flags & MIF_HIDDEN)) { #if CPU_HARVARD - text_xprintf_P + text_xyprintf_P #else - text_xprintf + text_xyprintf #endif ( - menu->bitmap, ypos++, 0, + bm, 0, ypos, (first_item + cnt == selected) ? (STYLEF_INVERT | TEXT_FILL) : TEXT_FILL, - (item->flags & MIF_RAMLABEL) ? PSTR("%s%s") : PSTR("%S%s"), + (item->flags & MIF_RAMLABEL) ? PSTR("%s%S") : PSTR("%S%S"), PTRMSG(item->label), (item->flags & MIF_TOGGLE) ? ( (item->flags & MIF_CHECKED) ? PSTR(":ON") : PSTR(":OFF") ) : ( (item->flags & MIF_CHECKED) ? PSTR("\04") : PSTR("") ) ); + ypos += bm->font->height; } } + +#if CONFIG_MENU_SMOOTH + /* Restore old cliprect */ + gfx_setClipRect(bm, + bm->cr.xmin, old_ymin, + bm->cr.xmax, bm->cr.ymax); + + lcd_blitBitmap(&lcd_bitmap); +#endif } @@ -233,33 +322,59 @@ static void menu_doselect(const struct Menu *menu, struct MenuItem *item) } -/*! - * Return the previous visible item (rolls back to the last item) +/** + * Return the next visible item (rolls back to the first item) */ -static int menu_next_visible_item(const struct Menu *menu, int index, int total) +static int menu_next_visible_item(const struct Menu *menu, int index) { + int total = menu_count(menu); + int item_flags; + do { if (++index >= total) index = 0; + +#if CPU_HARVARD + if (menu->flags & MF_ROMITEMS) + { + ASSERT(sizeof(menu->items[index].flags) == sizeof(int)); + item_flags = pgm_read_int(&menu->items[index].flags); + } + else +#endif + item_flags = menu->items[index].flags; } - while (menu->items[index].flags & MIF_HIDDEN); + while (item_flags & MIF_HIDDEN); return index; } -/*! - * Return the next visible item (rolls back to the first item) +/** + * Return the previous visible item (rolls back to the last item) */ -static int menu_prev_visible_item(const struct Menu *menu, int index, int total) +static int menu_prev_visible_item(const struct Menu *menu, int index) { + int total = menu_count(menu); + int item_flags; + do { if (--index < 0) index = total - 1; + +#if CPU_HARVARD + if (menu->flags & MF_ROMITEMS) + { + ASSERT(sizeof(menu->items[index].flags) == sizeof(int)); + item_flags = pgm_read_int(&menu->items[index].flags); + } + else +#endif + item_flags = menu->items[index].flags; } - while (menu->items[index].flags & MIF_HIDDEN); + while (item_flags & MIF_HIDDEN); return index; } @@ -270,7 +385,7 @@ static int menu_prev_visible_item(const struct Menu *menu, int index, int total) */ iptr_t menu_handle(const struct Menu *menu) { - uint8_t entries, visible_entries, items_per_page; + uint8_t items_per_page; uint8_t first_item, selected; #if CONFIG_MENU_MENUBAR @@ -293,34 +408,18 @@ iptr_t menu_handle(const struct Menu *menu) #endif /* CONFIG_MENU_MENUBAR */ - /* Compute total number of items in menu (entries) and - * the number of visible entries, which excludes items - * without a label. - */ - { - struct MenuItem *item; - - entries = 0; - visible_entries = 0; - - for (item = menu->items; (item->label || item->hook); ++item) - { - ++entries; - if (!(item->flags & MIF_HIDDEN)) - ++visible_entries; - } - } - items_per_page = (menu->bitmap->height / menu->bitmap->font->height) - - menu->startrow #if CONFIG_MENU_MENUBAR - 1 /* menu bar labels */ #endif - (menu->title ? 1 : 0); /* Selected item should be a visible entry */ - first_item = selected = menu_next_visible_item(menu, -1, entries); + first_item = selected = menu_next_visible_item(menu, menu->selected - 1); + + /* Clear screen */ + text_clear(menu->bitmap); for(;;) { @@ -330,39 +429,60 @@ iptr_t menu_handle(const struct Menu *menu) * Keep selected item visible */ while (selected < first_item) - first_item = menu_prev_visible_item(menu, first_item, entries); + first_item = menu_prev_visible_item(menu, first_item); while (selected >= first_item + items_per_page) - first_item = menu_next_visible_item(menu, first_item, entries); + first_item = menu_next_visible_item(menu, first_item); - /* Clear screen */ - text_clear(menu->bitmap); menu_layout(menu, first_item, items_per_page, selected); -#if CONFIG_MENU_MENUBAR - menu_update_menubar(menu, &mb, selected); -#endif + #if CONFIG_MENU_MENUBAR + menu_update_menubar(menu, &mb, selected); + #endif +#if CONFIG_MENU_SMOOTH + key = kbd_peek(); +#else key = kbd_get(); +#endif if (key & K_OK) { struct MenuItem *item = &(menu->items[selected]); +#if CPU_HARVARD + MenuItem ram_item; + if (menu->flags & MF_ROMITEMS) + { + memcpy_P(&ram_item, item, sizeof(ram_item)); + item = &ram_item; + } +#endif menu_doselect(menu, item); /* Return userdata as result */ if (!menu->flags & MF_STICKY) + { + /* Store currently selected item before leaving. */ + if (menu->flags & MF_SAVESEL) + CONST_CAST(struct Menu *, menu)->selected = selected; return item->userdata; + } + + /* Clear screen */ + text_clear(menu->bitmap); } else if (key & K_UP) { - selected = menu_prev_visible_item(menu, selected, entries); + selected = menu_prev_visible_item(menu, selected); } else if (key & K_DOWN) { - selected = menu_next_visible_item(menu, selected, entries); + selected = menu_next_visible_item(menu, selected); } else if (key & K_CANCEL && !(menu->flags & MF_TOPLEVEL)) { + /* Store currently selected item before leaving. */ + if (menu->flags & MF_SAVESEL) + CONST_CAST(struct Menu *, menu)->selected = selected; return 0; } } @@ -381,6 +501,7 @@ iptr_t menu_handle(const struct Menu *menu) int menu_setFlags(struct Menu *menu, int idx, int flags) { ASSERT(idx < menu_count(menu)); + ASSERT(!(menu->flags & MF_ROMITEMS)); int old = menu->items[idx].flags; menu->items[idx].flags |= flags; @@ -400,6 +521,7 @@ int menu_setFlags(struct Menu *menu, int idx, int flags) int menu_clearFlags(struct Menu *menu, int idx, int flags) { ASSERT(idx < menu_count(menu)); + ASSERT(!(menu->flags & MF_ROMITEMS)); int old = menu->items[idx].flags; menu->items[idx].flags &= ~flags;