From d336eb30f8098f4a8f0bc27dc40358b30e57decd Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Sun, 24 Jun 2012 21:52:18 +1000 Subject: [PATCH] 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 --- apps/gui/skin_engine/skin_parser.c | 88 ++++++++++++++++++++++++++++++++ apps/gui/skin_engine/skin_touchsupport.c | 5 +- apps/gui/skin_engine/wps_internals.h | 1 + manual/appendix/wps_tags.tex | 9 ++++ wps/cabbiev2.240x320x16.mini2440.wps | 1 - wps/cabbiev2.240x400x16.wps | 1 - wps/cabbiev2.320x240x16.mrobe500.wps | 1 - wps/cabbiev2.320x480x16.wps | 1 - wps/cabbiev2.800x480x16.wps | 1 - 9 files changed, 101 insertions(+), 7 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; } diff --git a/apps/gui/skin_engine/skin_touchsupport.c b/apps/gui/skin_engine/skin_touchsupport.c index 34f616b9a3..f685cd0b70 100644 --- a/apps/gui/skin_engine/skin_touchsupport.c +++ b/apps/gui/skin_engine/skin_touchsupport.c @@ -99,7 +99,6 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset, /* reposition the touch within the area */ vx -= r->x; vy -= r->y; - switch(r->action) { @@ -107,11 +106,13 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset, case ACTION_TOUCH_VOLUME: if (edge_offset) { + struct progressbar *bar = + SKINOFFSETTOPTR(skin_buffer, r->bar); if(r->width > r->height) *edge_offset = vx*100/r->width; else *edge_offset = vy*100/r->height; - if (r->reverse_bar) + if (r->reverse_bar || (bar && bar->invert_fill_direction)) *edge_offset = 100 - *edge_offset; } temp = r; diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h index d5e77708f8..ab2bc3579e 100644 --- a/apps/gui/skin_engine/wps_internals.h +++ b/apps/gui/skin_engine/wps_internals.h @@ -215,6 +215,7 @@ struct touchregion { int value; }; long last_press; /* last tick this was pressed */ + OFFSETTYPE(struct progressbar*) bar; }; diff --git a/manual/appendix/wps_tags.tex b/manual/appendix/wps_tags.tex index 2d22b73792..14e0308940 100644 --- a/manual/appendix/wps_tags.tex +++ b/manual/appendix/wps_tags.tex @@ -676,6 +676,12 @@ display cycling round the defined sublines. See Some tags can be used to display a bar which draws according to the value of the tag. To use these tags like a bar you need to use the following parameters (\%XX should be replaced with the actual tag). + +\opt{touchscreen}{ + Volume and progress bars automatically create touch regions the same size + as the bar (slightly larger actually). This can be disabled with the + \config{notouch} option. +} \begin{tagmap} \config{\%XX(x, y, width, height, [options])} @@ -706,6 +712,9 @@ display cycling round the defined sublines. See ``slider'' option). \item[nobar] -- don't draw the bar or its frame (for use with the ``slider'' option). + \opt{touchscreen}{ + \item[notouch] -- don't create the touchregion for progress/volume bars. + } \end{description} Example: \config{\%pb(0,0,-,-,-,nofill, slider, slider\_image, invert)} -- draw diff --git a/wps/cabbiev2.240x320x16.mini2440.wps b/wps/cabbiev2.240x320x16.mini2440.wps index 8eba53e6f8..1a6c7f3f45 100644 --- a/wps/cabbiev2.240x320x16.mini2440.wps +++ b/wps/cabbiev2.240x320x16.mini2440.wps @@ -8,7 +8,6 @@ %T(46,292,84,24,menu) %T(139,292,24,24,shuffle) %T(182,292,24,24,repmode) -%T(22,254,199,13,progressbar) %X(wpsbackdrop-240x320x16.bmp) %xl(A,lock-240x320x16.bmp,11,292,2) %xl(B,battery-240x320x16.bmp,46,292,10) diff --git a/wps/cabbiev2.240x400x16.wps b/wps/cabbiev2.240x400x16.wps index eb305b11d1..59a6074563 100644 --- a/wps/cabbiev2.240x400x16.wps +++ b/wps/cabbiev2.240x400x16.wps @@ -7,7 +7,6 @@ %X(wpsbackdrop-240x400x16.bmp) %Cl(55,50,130,130,c,c) %pb(22,284,199,13,pb-240x320x16.bmp) -%T(22,284,199,13,progressbar) %T(90,238,60,20,playlist) %?Tl(2.5)<%Vd(t)|%Vd(u)> %V(0,0,240,330,1) diff --git a/wps/cabbiev2.320x240x16.mrobe500.wps b/wps/cabbiev2.320x240x16.mrobe500.wps index 1bad2bbd98..1ad14e48b8 100644 --- a/wps/cabbiev2.320x240x16.mrobe500.wps +++ b/wps/cabbiev2.320x240x16.mrobe500.wps @@ -6,7 +6,6 @@ %T(0,207,84,24,menu) %T(218,211,24,24,shuffle) %T(261,207,24,24,repmode) -%T(10,162,300,15,progressbar) %X(wpsbackdrop-320x240x16.bmp) %xl(A,lock-320x240x16.bmp,91,207,2) %xl(B,battery-320x240x16.bmp,126,207,10) diff --git a/wps/cabbiev2.320x480x16.wps b/wps/cabbiev2.320x480x16.wps index 31957a2293..1aa5672efe 100644 --- a/wps/cabbiev2.320x480x16.wps +++ b/wps/cabbiev2.320x480x16.wps @@ -63,7 +63,6 @@ # progressbar and bottom icons %V(0,360,-,-,-) %pb(20,11,280,-,pb-320x480x16.bmp) -%T(20,0,280,40,progressbar) #%?mh<%xd(Aa)|%xd(Ab)> #%?bp<%?bc<%xd(Ba)|%xd(Bb)>|%?bl<|%xd(Bc)|%xd(Bd)|%xd(Be)|%xd(Bf)|%xd(Bg)|%xd(Bh)|%xd(Bi)|%xd(Bj)>> diff --git a/wps/cabbiev2.800x480x16.wps b/wps/cabbiev2.800x480x16.wps index 07420da616..881718be03 100644 --- a/wps/cabbiev2.800x480x16.wps +++ b/wps/cabbiev2.800x480x16.wps @@ -49,7 +49,6 @@ # progressbar and bottom icons %V(0,323,-,33,-) %pb(25,0,750,-,pb-800x480x16.bmp) -%T(25,0,750,50,progressbar) # volume %V(344,400,108,60,-) -- 2.11.4.GIT