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,-)