diff --git a/apps/gui/bitmap/list-skinned.c b/apps/gui/bitmap/list-skinned.c new file mode 100644 index 0000000..0d19168 --- /dev/null +++ b/apps/gui/bitmap/list-skinned.c @@ -0,0 +1,195 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2011 by Jonathan Gordon + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "config.h" +#include "lcd.h" +#include "font.h" +#include "button.h" +#include "string.h" +#include "settings.h" +#include "kernel.h" +#include "system.h" +#include "file.h" + +#include "action.h" +#include "screen_access.h" +#include "list.h" +#include "scrollbar.h" +#include "lang.h" +#include "sound.h" +#include "misc.h" +#include "viewport.h" +#include "statusbar-skinned.h" +#include "skin_engine/skin_engine.h" +#include "appevents.h" + +static struct listitem_viewport_cfg *listcfg[NB_SCREENS] = {NULL}; +static char *current_item_text_ptr, current_item_text[2048]; +static enum themable_icons current_item_icon; +void skinlist_set_cfg(enum screen_type screen, + struct listitem_viewport_cfg *cfg) +{ + if (listcfg[screen] != cfg) + { + listcfg[screen] = cfg; + list_init(); + } +} + +char* skinlist_get_item_text(void) +{ + const char* ret = P2STR((unsigned char*)current_item_text_ptr); + return ret; +} +enum themable_icons skinlist_get_item_icon(void) +{ + return current_item_icon; +} +static bool is_selected = false; +bool skinlist_is_selected_item(void) +{ + return is_selected; +} +int skinlist_get_line_count(enum screen_type screen, struct gui_synclist *list) +{ + struct viewport *parent = (list->parent[screen]); + if (listcfg[screen] == NULL) + return -1; + if (listcfg[screen]->tile == true) + { + int rows = (parent->height / listcfg[screen]->height); + int cols = (parent->width / listcfg[screen]->width); + return rows*cols; + } + else + return (parent->height / listcfg[screen]->height); +} + + +static int current_item; +static int current_first_shown, current_last_shown; +void skinlist_get_scrollbar(int* nb_item, int* first_shown, int* last_shown) +{ + *nb_item = current_item; + *first_shown = current_first_shown; + *last_shown = current_last_shown; +} + +bool skinlist_draw(struct screen *display, struct gui_synclist *list) +{ + int cur_line, display_lines; + const int screen = display->screen_type; + struct viewport *parent = (list->parent[screen]); + char* label = NULL; + const int list_start_item = list->start_item[screen]; + struct gui_wps wps; + if (listcfg[screen] == NULL) + return false; + wps.display = display; + wps.data = listcfg[screen]->data; + display_lines = skinlist_get_line_count(screen, list); + label = listcfg[screen]->label; + display->set_viewport(parent); + display->clear_viewport(); + current_item = list->selected_item; + current_first_shown = list_start_item; + current_last_shown = list_start_item+display_lines; + if (current_last_shown >= list->nb_items) + current_last_shown = list->nb_items; + for (cur_line = 0; cur_line < display_lines; cur_line++) + { + struct skin_element* viewport; + struct skin_viewport* skin_viewport; + if (list_start_item+cur_line+1 > list->nb_items) + break; + is_selected = list->show_selection_marker && + list_start_item+cur_line == list->selected_item; + current_item_text_ptr = list->callback_get_item_name( + list_start_item+cur_line, + list->data, current_item_text, 2048); + if (list->callback_get_item_icon != NULL) + current_item_icon = list->callback_get_item_icon( + list_start_item+cur_line, list->data); + + for (viewport = listcfg[screen]->data->tree; + viewport; + viewport = viewport->next) + { + int origional_x, origional_y; + int origional_w, origional_h; + skin_viewport = (struct skin_viewport*)viewport->data; + if (viewport->children == 0 || !skin_viewport->label || + (skin_viewport->label && strcmp(label, skin_viewport->label)) + ) + continue; + + origional_x = skin_viewport->vp.x; + origional_y = skin_viewport->vp.y; + origional_w = skin_viewport->vp.width; + origional_h = skin_viewport->vp.height; + if (listcfg[screen]->tile) + { + int cols = (parent->width / listcfg[screen]->width); + int col = (list_start_item+cur_line)%cols; + int row = (list_start_item+cur_line)/cols; + + skin_viewport->vp.x = parent->x + listcfg[screen]->width*col + origional_x; + skin_viewport->vp.y = parent->y + listcfg[screen]->height*row + origional_y; + } + else + { + skin_viewport->vp.x = parent->x; + skin_viewport->vp.y = parent->y + + (listcfg[screen]->height*cur_line); + } + display->set_viewport(&skin_viewport->vp); +#ifdef HAVE_LCD_BITMAP + /* Set images to not to be displayed */ + struct skin_token_list *imglist = wps.data->images; + while (imglist) + { + struct gui_img *img = (struct gui_img *)imglist->token->value.data; + img->display = -1; + imglist = imglist->next; + } +#endif + skin_render_viewport(viewport->children[0], + &wps, skin_viewport, SKIN_REFRESH_ALL); +#ifdef HAVE_LCD_BITMAP + wps_display_images(&wps, &skin_viewport->vp); +#endif + + skin_viewport->vp.x = origional_x; + skin_viewport->vp.y = origional_y; + skin_viewport->vp.width = origional_w; + skin_viewport->vp.height = origional_h; + } + } + display->set_viewport(parent); + display->update_viewport(); + current_item_text_ptr = list->callback_get_item_name( + list->selected_item, + list->data, current_item_text, 2048); + /* Abuse the callback to force the sbs to update */ + send_event(LCD_EVENT_ACTIVATION, NULL); + return true; +} +