diff options
author | Jonathan Gordon <rockbox@jdgordon.info> | 2009-04-20 01:41:56 +0000 |
---|---|---|
committer | Jonathan Gordon <rockbox@jdgordon.info> | 2009-04-20 01:41:56 +0000 |
commit | 0eb5dc649f34ca136d0160bf5d43961a2c3cea05 (patch) | |
tree | 5082fcd0d0479979a51891e082e742e2cf769266 /apps/gui | |
parent | 88b509b7d258c820f2eeda513524acbf76dcaaf5 (diff) |
beginings of a working touchscreen interface for the WPS. 2 new tags:
%T|x|y|width|height|action| <- setup a region (relative to the current viewport) where if pressed the "action" will be done (currently play/stop/prev/next/menu/browse work, suggestions for others to add and better names welcome)
%Tl<timeout> <- used as a conditional to say if the touchscreen was touched in the last <timeout>, use this to enable/disable button viewports or something... same syntax as other timeout tags
cabbiev2 for the mr500 has been modified to demonstrate the new tags. press the pause/play button to pause playback. press the rockbox logo to get back to the menu. pretty icons needed to make this more usable :)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20753 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/gui')
-rw-r--r-- | apps/gui/gwps-common.c | 7 | ||||
-rw-r--r-- | apps/gui/gwps.c | 37 | ||||
-rw-r--r-- | apps/gui/gwps.h | 19 | ||||
-rw-r--r-- | apps/gui/wps_parser.c | 86 |
4 files changed, 144 insertions, 5 deletions
diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c index 5ab0097b2c..1fef9e02cb 100644 --- a/apps/gui/gwps-common.c +++ b/apps/gui/gwps-common.c @@ -1292,6 +1292,13 @@ static const char *get_token_value(struct gui_wps *gwps, token->value.i * TIMEOUT_UNIT)) return "v"; return NULL; + case WPS_TOKEN_LASTTOUCH: +#ifdef HAVE_TOUCHSCREEN + if (TIME_BEFORE(current_tick, token->value.i * TIMEOUT_UNIT + + touchscreen_last_touch())) + return "t"; +#endif + return NULL; case WPS_TOKEN_SETTING: { diff --git a/apps/gui/gwps.c b/apps/gui/gwps.c index 0c8a3aa2b1..26b531e332 100644 --- a/apps/gui/gwps.c +++ b/apps/gui/gwps.c @@ -293,7 +293,38 @@ void gwps_draw_statusbars(void) { viewportmanager_set_statusbar(wpsbars); } - +#ifdef HAVE_TOUCHSCREEN +static int wps_get_touchaction(struct wps_data *data) +{ + short x,y; + short vx, vy; + int type = action_get_touchscreen_press(&x, &y); + int i; + struct touchregion *r; + if (type != BUTTON_REL) + return ACTION_TOUCHSCREEN; + for (i=0; i<data->touchregion_count; i++) + { + r = &data->touchregion[i]; + /* make sure this region's viewport is visible */ + if (r->wvp->hidden_flags&VP_DRAW_HIDDEN) + continue; + /* reposition the touch inside the viewport */ + vx = x - r->wvp->vp.x; + vy = y - r->wvp->vp.y; + /* check if its inside this viewport */ + if (vx >= 0 && vx < r->wvp->vp.x + r->wvp->vp.width && + vy >= 0 && vy < r->wvp->vp.y + r->wvp->vp.height) + { + /* now see if the point is inside this region */ + if (vx >= r->x && vx < r->x+r->width && + vy >= r->y && vy < r->y+r->height) + return r->action; + } + } + return ACTION_TOUCHSCREEN; +} +#endif /* The WPS can be left in two ways: * a) call a function, which draws over the wps. In this case, the wps * will be still active (i.e. the below function didn't return) @@ -393,6 +424,10 @@ long gui_wps_show(void) playlist or if using the sleep timer. */ if (!(audio_status() & AUDIO_STATUS_PLAY)) exit = true; +#ifdef HAVE_TOUCHSCREEN + if (button == ACTION_TOUCHSCREEN) + button = wps_get_touchaction(gui_wps[SCREEN_MAIN].data); +#endif /* The iPods/X5/M5 use a single button for the A-B mode markers, defined as ACTION_WPSAB_SINGLE in their config files. */ #ifdef ACTION_WPSAB_SINGLE diff --git a/apps/gui/gwps.h b/apps/gui/gwps.h index 1042e1a795..935e015c93 100644 --- a/apps/gui/gwps.h +++ b/apps/gui/gwps.h @@ -88,6 +88,8 @@ struct progressbar { }; #endif + + struct align_pos { char* left; char* center; @@ -297,6 +299,7 @@ enum wps_token_type { /* buttons */ WPS_TOKEN_BUTTON_VOLUME, + WPS_TOKEN_LASTTOUCH, /* Setting option */ WPS_TOKEN_SETTING, @@ -363,6 +366,17 @@ struct wps_viewport { char label; }; +#ifdef HAVE_TOUCHSCREEN +struct touchregion { + struct wps_viewport* wvp;/* The viewport this region is in */ + short int x; /* x-pos */ + short int y; /* y-pos */ + short int width; /* width */ + short int height; /* height */ + int action; /* action this button will return */ +}; +#define MAX_TOUCHREGIONS 12 +#endif /* wps_data this struct holds all necessary data which describes the viewable content of a wps */ @@ -399,6 +413,11 @@ struct wps_data bool full_line_progressbar; #endif +#ifdef HAVE_TOUCHSCREEN + struct touchregion touchregion[MAX_TOUCHREGIONS]; + short touchregion_count; +#endif + #ifdef HAVE_REMOTE_LCD bool remote_wps; #endif diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c index 390df56cbb..290f370fe7 100644 --- a/apps/gui/wps_parser.c +++ b/apps/gui/wps_parser.c @@ -121,7 +121,7 @@ struct wps_tag { unsigned char refresh_type; const wps_tag_parse_func parse_func; }; - +static int skip_end_of_line(const char *wps_bufptr); /* prototypes of all special parse functions : */ static int parse_timeout(const char *wps_bufptr, struct wps_token *token, struct wps_data *wps_data); @@ -131,7 +131,7 @@ static int parse_dir_level(const char *wps_bufptr, struct wps_token *token, struct wps_data *wps_data); static int parse_setting(const char *wps_bufptr, struct wps_token *token, struct wps_data *wps_data); - + #ifdef HAVE_LCD_BITMAP static int parse_viewport_display(const char *wps_bufptr, struct wps_token *token, struct wps_data *wps_data); @@ -156,7 +156,18 @@ static int parse_albumart_load(const char *wps_bufptr, static int parse_albumart_conditional(const char *wps_bufptr, struct wps_token *token, struct wps_data *wps_data); #endif /* HAVE_ALBUMART */ - +#ifdef HAVE_TOUCHSCREEN +static int parse_touchregion(const char *wps_bufptr, + struct wps_token *token, struct wps_data *wps_data); +#else +static int fulline_tag_not_supported(const char *wps_bufptr, + struct wps_token *token, struct wps_data *wps_data) +{ + (void)token; (void)wps_data; + return skip_end_of_line(wps_bufptr); +} +#define parse_touchregion fulline_tag_not_supported +#endif #ifdef CONFIG_RTC #define WPS_RTC_REFRESH WPS_REFRESH_DYNAMIC #else @@ -337,7 +348,10 @@ static const struct wps_tag all_tags[] = { #endif { WPS_TOKEN_SETTING, "St", WPS_REFRESH_DYNAMIC, parse_setting }, - + + { WPS_TOKEN_LASTTOUCH, "Tl", WPS_REFRESH_DYNAMIC, parse_timeout }, + { WPS_NO_TOKEN, "T", 0, parse_touchregion }, + { WPS_TOKEN_UNKNOWN, "", 0, NULL } /* the array MUST end with an empty string (first char is \0) */ }; @@ -1142,6 +1156,70 @@ static int parse_albumart_conditional(const char *wps_bufptr, }; #endif /* HAVE_ALBUMART */ +#ifdef HAVE_TOUCHSCREEN + +struct touchaction {char* s; int action;}; +static struct touchaction touchactions[] = { + {"play", ACTION_WPS_PLAY }, {"stop", ACTION_WPS_STOP }, + {"prev", ACTION_WPS_SKIPPREV }, {"next", ACTION_WPS_SKIPNEXT }, + {"menu", ACTION_WPS_MENU }, {"browse", ACTION_WPS_BROWSE } +}; +static int parse_touchregion(const char *wps_bufptr, + struct wps_token *token, struct wps_data *wps_data) +{ + (void)token; + unsigned i; + struct touchregion *region; + const char *ptr = wps_bufptr; + const char *action; + int x,y,w,h; + + /* format: %T|x|y|width|height|action| + * action is one of: + * play - play/pause playback + * stop - stop playback, exit the wps + * prev - prev track + * next - next track + * ffwd + * rwd + * menu - go back to the main menu + * browse - go back to the file/db browser + */ + + if ((wps_data->touchregion_count +1 >= MAX_TOUCHREGIONS) || (*ptr != '|')) + return WPS_ERROR_INVALID_PARAM; + ptr++; + + if (!(ptr = parse_list("dddds", NULL, '|', ptr, &x, &y, &w, &h, &action))) + return WPS_ERROR_INVALID_PARAM; + + /* Check there is a terminating | */ + if (*ptr != '|') + return WPS_ERROR_INVALID_PARAM; + + /* should probably do some bounds checking here with the viewport... but later */ + region = &wps_data->touchregion[wps_data->touchregion_count]; + region->action = ACTION_NONE; + region->x = x; + region->y = y; + region->width = w; + region->height = h; + region->wvp = &wps_data->viewports[wps_data->num_viewports]; + i = 0; + while ((region->action == ACTION_NONE) && + (i < sizeof(touchactions)/sizeof(*touchactions))) + { + if (!strncmp(touchactions[i].s, action, strlen(touchactions[i].s))) + region->action = touchactions[i].action; + i++; + } + if (region->action == ACTION_NONE) + return WPS_ERROR_INVALID_PARAM; + wps_data->touchregion_count++; + return skip_end_of_line(wps_bufptr); +} +#endif + /* Parse a generic token from the given string. Return the length read */ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) { |