summaryrefslogtreecommitdiffstats
path: root/apps/gui/skin_engine/skin_parser.c
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2012-06-24 21:52:18 +1000
committerJonathan Gordon <rockbox@jdgordon.info>2012-07-05 11:15:16 +1000
commitd336eb30f8098f4a8f0bc27dc40358b30e57decd (patch)
tree93d840e7096edf21469f6b4110ae7f49cab09c90 /apps/gui/skin_engine/skin_parser.c
parent3d0459dfadf0071112cd8406b9c210123b667e03 (diff)
downloadrockbox-d336eb30f8098f4a8f0bc27dc40358b30e57decd.tar.gz
rockbox-d336eb30f8098f4a8f0bc27dc40358b30e57decd.zip
skin_engine: Automatically create touch regions for skin bars
skin bars now automatically create the touch region the same size as the bar on touchscreen targets. This means touches will magically "just work" for reveresed bars (rtl or otherwise). ~5% padding is added on all 4 sides of the region rectangle but this may need to be tweaked. Please consider the 'progressbar' and 'volume' touchregion actions to be deprecated. Kudos to my new wife for figuring out the bleedingly obvious way to do this! Change-Id: I997a7bcaa70fce9885808aae27953c7676e9c2ff
Diffstat (limited to 'apps/gui/skin_engine/skin_parser.c')
-rw-r--r--apps/gui/skin_engine/skin_parser.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index 4de0aae3b2..8e7d79b44f 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -871,6 +871,9 @@ static int parse_progressbar_tag(struct skin_element* element,
struct skin_tag_parameter *param = get_param(element, 0);
int curr_param = 0;
char *image_filename = NULL;
+#ifdef HAVE_TOUCHSCREEN
+ bool suppress_touchregion = false;
+#endif
if (element->params_count == 0 &&
element->tag->type != SKIN_TOKEN_PROGRESSBAR)
@@ -1008,6 +1011,10 @@ static int parse_progressbar_tag(struct skin_element* element,
}
else if (!strcmp(text, "horizontal"))
pb->horizontal = true;
+#ifdef HAVE_TOUCHSCREEN
+ else if (!strcmp(text, "notouch"))
+ suppress_touchregion = true;
+#endif
else if (curr_param == 4)
image_filename = text;
@@ -1055,6 +1062,61 @@ static int parse_progressbar_tag(struct skin_element* element,
token->type = SKIN_TOKEN_LIST_SCROLLBAR;
pb->type = token->type;
+#ifdef HAVE_TOUCHSCREEN
+ if (!suppress_touchregion &&
+ (token->type == SKIN_TOKEN_VOLUMEBAR || token->type == SKIN_TOKEN_PROGRESSBAR))
+ {
+ struct touchregion *region = skin_buffer_alloc(sizeof(*region));
+ struct skin_token_list *item;
+ int wpad, hpad;
+
+ if (!region)
+ return 0;
+
+ if (token->type == SKIN_TOKEN_VOLUMEBAR)
+ region->action = ACTION_TOUCH_VOLUME;
+ else
+ region->action = ACTION_TOUCH_SCROLLBAR;
+
+ /* try to add some extra space on either end to make pressing the
+ * full bar easier. ~5% on either side
+ */
+ wpad = pb->width * 5 / 100;
+ if (wpad > 10)
+ wpad = 10;
+ hpad = pb->height * 5 / 100;
+ if (hpad > 10)
+ hpad = 10;
+
+ region->x = pb->x - wpad;
+ if (region->x < 0)
+ region->x = 0;
+ region->width = pb->width + 2 * wpad;
+ if (region->x + region->width > curr_vp->vp.x + curr_vp->vp.width)
+ region->width = curr_vp->vp.x + curr_vp->vp.width - region->x;
+
+ region->y = pb->y - hpad;
+ if (region->y < 0)
+ region->y = 0;
+ region->height = pb->height + 2 * hpad;
+ if (region->y + region->height > curr_vp->vp.y + curr_vp->vp.height)
+ region->height = curr_vp->vp.y + curr_vp->vp.height - region->y;
+
+ region->wvp = PTRTOSKINOFFSET(skin_buffer, curr_vp);
+ region->reverse_bar = false;
+ region->allow_while_locked = false;
+ region->press_length = PRESS;
+ region->last_press = 0xffff;
+ region->armed = false;
+ region->bar = PTRTOSKINOFFSET(skin_buffer, pb);
+
+ item = new_skin_token_list_item(NULL, region);
+ if (!item)
+ return WPS_ERROR_INVALID_PARAM;
+ add_to_ll_chain(&wps_data->touchregions, item);
+ }
+#endif
+
return 0;
#else
@@ -1429,6 +1491,7 @@ static int parse_touchregion(struct skin_element *element,
region->last_press = 0xffff;
region->press_length = PRESS;
region->allow_while_locked = false;
+ region->bar = -1;
action = get_param_text(element, p++);
/* figure out the action */
@@ -2324,6 +2387,31 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
#else
wps_data->wps_loaded = wps_data->tree >= 0;
#endif
+
+#ifdef HAVE_TOUCHSCREEN
+ /* Check if there are any touch regions from the skin and not just
+ * auto-created ones for bars */
+ struct skin_token_list *regions = SKINOFFSETTOPTR(skin_buffer,
+ wps_data->touchregions);
+ bool user_touch_region_found = false;
+ while (regions)
+ {
+ struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, regions->token);
+ struct touchregion *r = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+
+ if (r->action != ACTION_TOUCH_SCROLLBAR &&
+ r->action != ACTION_TOUCH_VOLUME)
+ {
+ user_touch_region_found = true;
+ break;
+ }
+ regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
+ }
+ regions = SKINOFFSETTOPTR(skin_buffer, wps_data->touchregions);
+ if (regions && !user_touch_region_found)
+ wps_data->touchregions = -1;
+#endif
+
skin_buffer = NULL;
return true;
}