summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2011-09-11 10:44:17 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2011-09-11 10:44:17 +0000
commit3d0317a273a99f277d88c491181ba220db9dd2b0 (patch)
tree53f10f49995065ec24aa5656d5c01dd76b8f88e1
parent93a600fdab817ccfc2c8f9301d9190aed3552ad6 (diff)
downloadrockbox-3d0317a273a99f277d88c491181ba220db9dd2b0.tar.gz
rockbox-3d0317a273a99f277d88c491181ba220db9dd2b0.zip
Rework how the skin gets the list item text to save some ram. Also allow the %LI and %LT tags to take 2 optional parameters to get a different items text/icon:
%LT(offset, nowrap) - get the text for the "being drawn"+offset item (offset being + or -). if the second param is "nowrap" (Without quotes) the text will be blank if the item would need to wrap. Same for the icon e.g: %LT(-1) %LT << %LT(1, nowrap) will display: Four Five << Six (or nothing if Five is the last item) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30502 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/gui/bitmap/list-skinned.c57
-rw-r--r--apps/gui/list.h4
-rw-r--r--apps/gui/skin_engine/skin_parser.c25
-rw-r--r--apps/gui/skin_engine/skin_tokens.c13
-rw-r--r--apps/gui/skin_engine/wps_internals.h5
-rw-r--r--lib/skin_parser/tag_table.c4
6 files changed, 82 insertions, 26 deletions
diff --git a/apps/gui/bitmap/list-skinned.c b/apps/gui/bitmap/list-skinned.c
index 2f3ca2bd2d..5f53784ccc 100644
--- a/apps/gui/bitmap/list-skinned.c
+++ b/apps/gui/bitmap/list-skinned.c
@@ -43,9 +43,8 @@
#include "appevents.h"
static struct listitem_viewport_cfg *listcfg[NB_SCREENS] = {NULL};
-static const char *current_item_text_ptr;
-static char current_item_text[MAX_PATH];
-static enum themable_icons current_item_icon;
+struct gui_synclist *current_list;
+
void skinlist_set_cfg(enum screen_type screen,
struct listitem_viewport_cfg *cfg)
{
@@ -54,7 +53,7 @@ void skinlist_set_cfg(enum screen_type screen,
if (listcfg[screen])
screens[screen].scroll_stop(&listcfg[screen]->selected_item_vp.vp);
listcfg[screen] = cfg;
- current_item_text_ptr = "";
+ current_list = NULL;
}
}
@@ -64,15 +63,41 @@ static bool skinlist_is_configured(enum screen_type screen,
return (listcfg[screen] != NULL) &&
(!list || (list && list->selected_size == 1));
}
-
-const char* skinlist_get_item_text(void)
+static int current_drawing_line;
+static int offset_to_item(int offset, bool wrap)
+{
+ int item = current_drawing_line + offset;
+ if (!current_list)
+ return -1;
+ if (item < 0)
+ {
+ if (!wrap)
+ return -1;
+ else
+ item = (item + current_list->nb_items) % current_list->nb_items;
+ }
+ else if (item >= current_list->nb_items && !wrap)
+ return -1;
+ else
+ item = item % current_list->nb_items;
+ return item;
+}
+const char* skinlist_get_item_text(int offset, bool wrap, char* buf, size_t buf_size)
{
- const char* ret = P2STR((unsigned char*)current_item_text_ptr);
- return ret;
+ int item = offset_to_item(offset, wrap);
+ if (item < 0 || !current_list)
+ return NULL;
+ const char* ret = current_list->callback_get_item_name(
+ item, current_list->data, buf, buf_size);
+ return P2STR((unsigned char*)ret);
}
-enum themable_icons skinlist_get_item_icon(void)
+
+enum themable_icons skinlist_get_item_icon(int offset, bool wrap)
{
- return current_item_icon;
+ int item = offset_to_item(offset, wrap);
+ if (item < 0 || !current_list || current_list->callback_get_item_icon == NULL)
+ return Icon_NOICON;
+ return current_list->callback_get_item_icon(item, current_list->data);
}
static bool is_selected = false;
@@ -130,6 +155,7 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list)
struct gui_wps wps;
if (!skinlist_is_configured(screen, list))
return false;
+ current_list = list;
wps.display = display;
wps.data = listcfg[screen]->data;
display_lines = skinlist_get_line_count(screen, list);
@@ -146,14 +172,9 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list)
struct skin_viewport* skin_viewport;
if (list_start_item+cur_line+1 > list->nb_items)
break;
+ current_drawing_line = list_start_item+cur_line;
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, MAX_PATH);
- 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;
@@ -219,9 +240,7 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list)
}
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);
+ current_drawing_line = list->selected_item;
#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
/* Abuse the callback to force the sbs to update */
send_event(LCD_EVENT_ACTIVATION, NULL);
diff --git a/apps/gui/list.h b/apps/gui/list.h
index b54e7d7f5b..7c64987abb 100644
--- a/apps/gui/list.h
+++ b/apps/gui/list.h
@@ -189,8 +189,8 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list);
bool skinlist_is_selected_item(void);
void skinlist_set_cfg(enum screen_type screen,
struct listitem_viewport_cfg *cfg);
-const char* skinlist_get_item_text(void);
-enum themable_icons skinlist_get_item_icon(void);
+const char* skinlist_get_item_text(int offset, bool wrap, char* buf, size_t buf_size);
+enum themable_icons skinlist_get_item_icon(int offset, bool wrap);
bool skinlist_needs_scrollbar(enum screen_type screen);
void skinlist_get_scrollbar(int* nb_item, int* first_shown, int* last_shown);
int skinlist_get_line_count(enum screen_type screen, struct gui_synclist *list);
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index 0db19645bc..dd34d84e9f 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -485,6 +485,27 @@ static int parse_viewport_gradient_setup(struct skin_element *element,
}
#endif
+static int parse_listitem(struct skin_element *element,
+ struct wps_token *token,
+ struct wps_data *wps_data)
+{
+ (void)wps_data;
+ struct listitem *li = (struct listitem *)skin_buffer_alloc(sizeof(struct listitem));
+ if (!li)
+ return 1;
+ token->value.data = li;
+ if (element->params_count == 0)
+ li->offset = 0;
+ else
+ {
+ li->offset = element->params[0].data.number;
+ if (element->params_count > 1)
+ li->wrap = strcasecmp(element->params[1].data.text, "nowrap") != 0;
+ else
+ li->wrap = true;
+ }
+ return 0;
+}
static int parse_listitemviewport(struct skin_element *element,
struct wps_token *token,
@@ -1827,6 +1848,10 @@ static int skin_element_callback(struct skin_element* element, void* data)
case SKIN_TOKEN_TRACK_ENDING:
function = parse_timeout_tag;
break;
+ case SKIN_TOKEN_LIST_ITEM_TEXT:
+ case SKIN_TOKEN_LIST_ITEM_ICON:
+ function = parse_listitem;
+ break;
#ifdef HAVE_LCD_BITMAP
case SKIN_TOKEN_DISABLE_THEME:
case SKIN_TOKEN_ENABLE_THEME:
diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c
index 371db46017..a4f0814945 100644
--- a/apps/gui/skin_engine/skin_tokens.c
+++ b/apps/gui/skin_engine/skin_tokens.c
@@ -922,14 +922,21 @@ const char *get_token_value(struct gui_wps *gwps,
snprintf(buf, buf_size, "%d",sb_get_icon(gwps->display->screen_type));
return buf;
case SKIN_TOKEN_LIST_ITEM_TEXT:
- return skinlist_get_item_text();
+ {
+ struct listitem *li = (struct listitem *)token->value.data;
+ return skinlist_get_item_text(li->offset, li->wrap, buf, buf_size);
+ }
case SKIN_TOKEN_LIST_ITEM_IS_SELECTED:
return skinlist_is_selected_item()?"s":"";
case SKIN_TOKEN_LIST_ITEM_ICON:
+ {
+ struct listitem *li = (struct listitem *)token->value.data;
+ int icon = skinlist_get_item_icon(li->offset, li->wrap);
if (intval)
- *intval = skinlist_get_item_icon();
- snprintf(buf, buf_size, "%d",skinlist_get_item_icon());
+ *intval = icon;
+ snprintf(buf, buf_size, "%d", icon);
return buf;
+ }
case SKIN_TOKEN_LIST_NEEDS_SCROLLBAR:
return skinlist_needs_scrollbar(gwps->display->screen_type) ? "s" : "";
#endif
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h
index 7d7afe95b1..244d08595e 100644
--- a/apps/gui/skin_engine/wps_internals.h
+++ b/apps/gui/skin_engine/wps_internals.h
@@ -294,6 +294,11 @@ struct substring {
struct wps_token *token;
};
+struct listitem {
+ bool wrap;
+ short offset;
+};
+
#ifdef HAVE_SKIN_VARIABLES
struct skin_var {
const char *label;
diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c
index b93aa28c32..aa18dd4cca 100644
--- a/lib/skin_parser/tag_table.c
+++ b/lib/skin_parser/tag_table.c
@@ -188,9 +188,9 @@ static const struct tag_info legal_tags[] =
{ SKIN_TOKEN_VIEWPORT_CUSTOMLIST, "Vp" , "IC", SKIN_REFRESH_DYNAMIC|NOBREAK },
{ SKIN_TOKEN_LIST_TITLE_TEXT, "Lt" , "", SKIN_REFRESH_DYNAMIC },
- { SKIN_TOKEN_LIST_ITEM_TEXT, "LT", "", SKIN_REFRESH_DYNAMIC },
+ { SKIN_TOKEN_LIST_ITEM_TEXT, "LT", "|IS", SKIN_REFRESH_DYNAMIC },
{ SKIN_TOKEN_LIST_TITLE_ICON, "Li" , "", SKIN_REFRESH_DYNAMIC },
- { SKIN_TOKEN_LIST_ITEM_ICON, "LI", "", SKIN_REFRESH_DYNAMIC },
+ { SKIN_TOKEN_LIST_ITEM_ICON, "LI", "|IS", SKIN_REFRESH_DYNAMIC },
{ SKIN_TOKEN_LIST_ITEM_CFG, "Lb" , "Sii|S", SKIN_REFRESH_STATIC },
{ SKIN_TOKEN_LIST_ITEM_IS_SELECTED, "Lc" , "", SKIN_REFRESH_DYNAMIC },
{ SKIN_TOKEN_LIST_NEEDS_SCROLLBAR, "LB", BAR_PARAMS, SKIN_REFRESH_DYNAMIC },