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) | |
download | rockbox-0eb5dc649f34ca136d0160bf5d43961a2c3cea05.tar.gz rockbox-0eb5dc649f34ca136d0160bf5d43961a2c3cea05.zip |
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, | |||
1292 | token->value.i * TIMEOUT_UNIT)) | 1292 | token->value.i * TIMEOUT_UNIT)) |
1293 | return "v"; | 1293 | return "v"; |
1294 | return NULL; | 1294 | return NULL; |
1295 | case WPS_TOKEN_LASTTOUCH: | ||
1296 | #ifdef HAVE_TOUCHSCREEN | ||
1297 | if (TIME_BEFORE(current_tick, token->value.i * TIMEOUT_UNIT + | ||
1298 | touchscreen_last_touch())) | ||
1299 | return "t"; | ||
1300 | #endif | ||
1301 | return NULL; | ||
1295 | 1302 | ||
1296 | case WPS_TOKEN_SETTING: | 1303 | case WPS_TOKEN_SETTING: |
1297 | { | 1304 | { |
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) | |||
293 | { | 293 | { |
294 | viewportmanager_set_statusbar(wpsbars); | 294 | viewportmanager_set_statusbar(wpsbars); |
295 | } | 295 | } |
296 | 296 | #ifdef HAVE_TOUCHSCREEN | |
297 | static int wps_get_touchaction(struct wps_data *data) | ||
298 | { | ||
299 | short x,y; | ||
300 | short vx, vy; | ||
301 | int type = action_get_touchscreen_press(&x, &y); | ||
302 | int i; | ||
303 | struct touchregion *r; | ||
304 | if (type != BUTTON_REL) | ||
305 | return ACTION_TOUCHSCREEN; | ||
306 | for (i=0; i<data->touchregion_count; i++) | ||
307 | { | ||
308 | r = &data->touchregion[i]; | ||
309 | /* make sure this region's viewport is visible */ | ||
310 | if (r->wvp->hidden_flags&VP_DRAW_HIDDEN) | ||
311 | continue; | ||
312 | /* reposition the touch inside the viewport */ | ||
313 | vx = x - r->wvp->vp.x; | ||
314 | vy = y - r->wvp->vp.y; | ||
315 | /* check if its inside this viewport */ | ||
316 | if (vx >= 0 && vx < r->wvp->vp.x + r->wvp->vp.width && | ||
317 | vy >= 0 && vy < r->wvp->vp.y + r->wvp->vp.height) | ||
318 | { | ||
319 | /* now see if the point is inside this region */ | ||
320 | if (vx >= r->x && vx < r->x+r->width && | ||
321 | vy >= r->y && vy < r->y+r->height) | ||
322 | return r->action; | ||
323 | } | ||
324 | } | ||
325 | return ACTION_TOUCHSCREEN; | ||
326 | } | ||
327 | #endif | ||
297 | /* The WPS can be left in two ways: | 328 | /* The WPS can be left in two ways: |
298 | * a) call a function, which draws over the wps. In this case, the wps | 329 | * a) call a function, which draws over the wps. In this case, the wps |
299 | * will be still active (i.e. the below function didn't return) | 330 | * will be still active (i.e. the below function didn't return) |
@@ -393,6 +424,10 @@ long gui_wps_show(void) | |||
393 | playlist or if using the sleep timer. */ | 424 | playlist or if using the sleep timer. */ |
394 | if (!(audio_status() & AUDIO_STATUS_PLAY)) | 425 | if (!(audio_status() & AUDIO_STATUS_PLAY)) |
395 | exit = true; | 426 | exit = true; |
427 | #ifdef HAVE_TOUCHSCREEN | ||
428 | if (button == ACTION_TOUCHSCREEN) | ||
429 | button = wps_get_touchaction(gui_wps[SCREEN_MAIN].data); | ||
430 | #endif | ||
396 | /* The iPods/X5/M5 use a single button for the A-B mode markers, | 431 | /* The iPods/X5/M5 use a single button for the A-B mode markers, |
397 | defined as ACTION_WPSAB_SINGLE in their config files. */ | 432 | defined as ACTION_WPSAB_SINGLE in their config files. */ |
398 | #ifdef ACTION_WPSAB_SINGLE | 433 | #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 { | |||
88 | }; | 88 | }; |
89 | #endif | 89 | #endif |
90 | 90 | ||
91 | |||
92 | |||
91 | struct align_pos { | 93 | struct align_pos { |
92 | char* left; | 94 | char* left; |
93 | char* center; | 95 | char* center; |
@@ -297,6 +299,7 @@ enum wps_token_type { | |||
297 | 299 | ||
298 | /* buttons */ | 300 | /* buttons */ |
299 | WPS_TOKEN_BUTTON_VOLUME, | 301 | WPS_TOKEN_BUTTON_VOLUME, |
302 | WPS_TOKEN_LASTTOUCH, | ||
300 | 303 | ||
301 | /* Setting option */ | 304 | /* Setting option */ |
302 | WPS_TOKEN_SETTING, | 305 | WPS_TOKEN_SETTING, |
@@ -363,6 +366,17 @@ struct wps_viewport { | |||
363 | char label; | 366 | char label; |
364 | }; | 367 | }; |
365 | 368 | ||
369 | #ifdef HAVE_TOUCHSCREEN | ||
370 | struct touchregion { | ||
371 | struct wps_viewport* wvp;/* The viewport this region is in */ | ||
372 | short int x; /* x-pos */ | ||
373 | short int y; /* y-pos */ | ||
374 | short int width; /* width */ | ||
375 | short int height; /* height */ | ||
376 | int action; /* action this button will return */ | ||
377 | }; | ||
378 | #define MAX_TOUCHREGIONS 12 | ||
379 | #endif | ||
366 | /* wps_data | 380 | /* wps_data |
367 | this struct holds all necessary data which describes the | 381 | this struct holds all necessary data which describes the |
368 | viewable content of a wps */ | 382 | viewable content of a wps */ |
@@ -399,6 +413,11 @@ struct wps_data | |||
399 | bool full_line_progressbar; | 413 | bool full_line_progressbar; |
400 | #endif | 414 | #endif |
401 | 415 | ||
416 | #ifdef HAVE_TOUCHSCREEN | ||
417 | struct touchregion touchregion[MAX_TOUCHREGIONS]; | ||
418 | short touchregion_count; | ||
419 | #endif | ||
420 | |||
402 | #ifdef HAVE_REMOTE_LCD | 421 | #ifdef HAVE_REMOTE_LCD |
403 | bool remote_wps; | 422 | bool remote_wps; |
404 | #endif | 423 | #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 { | |||
121 | unsigned char refresh_type; | 121 | unsigned char refresh_type; |
122 | const wps_tag_parse_func parse_func; | 122 | const wps_tag_parse_func parse_func; |
123 | }; | 123 | }; |
124 | 124 | static int skip_end_of_line(const char *wps_bufptr); | |
125 | /* prototypes of all special parse functions : */ | 125 | /* prototypes of all special parse functions : */ |
126 | static int parse_timeout(const char *wps_bufptr, | 126 | static int parse_timeout(const char *wps_bufptr, |
127 | struct wps_token *token, struct wps_data *wps_data); | 127 | struct wps_token *token, struct wps_data *wps_data); |
@@ -131,7 +131,7 @@ static int parse_dir_level(const char *wps_bufptr, | |||
131 | struct wps_token *token, struct wps_data *wps_data); | 131 | struct wps_token *token, struct wps_data *wps_data); |
132 | static int parse_setting(const char *wps_bufptr, | 132 | static int parse_setting(const char *wps_bufptr, |
133 | struct wps_token *token, struct wps_data *wps_data); | 133 | struct wps_token *token, struct wps_data *wps_data); |
134 | 134 | ||
135 | #ifdef HAVE_LCD_BITMAP | 135 | #ifdef HAVE_LCD_BITMAP |
136 | static int parse_viewport_display(const char *wps_bufptr, | 136 | static int parse_viewport_display(const char *wps_bufptr, |
137 | struct wps_token *token, struct wps_data *wps_data); | 137 | struct wps_token *token, struct wps_data *wps_data); |
@@ -156,7 +156,18 @@ static int parse_albumart_load(const char *wps_bufptr, | |||
156 | static int parse_albumart_conditional(const char *wps_bufptr, | 156 | static int parse_albumart_conditional(const char *wps_bufptr, |
157 | struct wps_token *token, struct wps_data *wps_data); | 157 | struct wps_token *token, struct wps_data *wps_data); |
158 | #endif /* HAVE_ALBUMART */ | 158 | #endif /* HAVE_ALBUMART */ |
159 | 159 | #ifdef HAVE_TOUCHSCREEN | |
160 | static int parse_touchregion(const char *wps_bufptr, | ||
161 | struct wps_token *token, struct wps_data *wps_data); | ||
162 | #else | ||
163 | static int fulline_tag_not_supported(const char *wps_bufptr, | ||
164 | struct wps_token *token, struct wps_data *wps_data) | ||
165 | { | ||
166 | (void)token; (void)wps_data; | ||
167 | return skip_end_of_line(wps_bufptr); | ||
168 | } | ||
169 | #define parse_touchregion fulline_tag_not_supported | ||
170 | #endif | ||
160 | #ifdef CONFIG_RTC | 171 | #ifdef CONFIG_RTC |
161 | #define WPS_RTC_REFRESH WPS_REFRESH_DYNAMIC | 172 | #define WPS_RTC_REFRESH WPS_REFRESH_DYNAMIC |
162 | #else | 173 | #else |
@@ -337,7 +348,10 @@ static const struct wps_tag all_tags[] = { | |||
337 | #endif | 348 | #endif |
338 | 349 | ||
339 | { WPS_TOKEN_SETTING, "St", WPS_REFRESH_DYNAMIC, parse_setting }, | 350 | { WPS_TOKEN_SETTING, "St", WPS_REFRESH_DYNAMIC, parse_setting }, |
340 | 351 | ||
352 | { WPS_TOKEN_LASTTOUCH, "Tl", WPS_REFRESH_DYNAMIC, parse_timeout }, | ||
353 | { WPS_NO_TOKEN, "T", 0, parse_touchregion }, | ||
354 | |||
341 | { WPS_TOKEN_UNKNOWN, "", 0, NULL } | 355 | { WPS_TOKEN_UNKNOWN, "", 0, NULL } |
342 | /* the array MUST end with an empty string (first char is \0) */ | 356 | /* the array MUST end with an empty string (first char is \0) */ |
343 | }; | 357 | }; |
@@ -1142,6 +1156,70 @@ static int parse_albumart_conditional(const char *wps_bufptr, | |||
1142 | }; | 1156 | }; |
1143 | #endif /* HAVE_ALBUMART */ | 1157 | #endif /* HAVE_ALBUMART */ |
1144 | 1158 | ||
1159 | #ifdef HAVE_TOUCHSCREEN | ||
1160 | |||
1161 | struct touchaction {char* s; int action;}; | ||
1162 | static struct touchaction touchactions[] = { | ||
1163 | {"play", ACTION_WPS_PLAY }, {"stop", ACTION_WPS_STOP }, | ||
1164 | {"prev", ACTION_WPS_SKIPPREV }, {"next", ACTION_WPS_SKIPNEXT }, | ||
1165 | {"menu", ACTION_WPS_MENU }, {"browse", ACTION_WPS_BROWSE } | ||
1166 | }; | ||
1167 | static int parse_touchregion(const char *wps_bufptr, | ||
1168 | struct wps_token *token, struct wps_data *wps_data) | ||
1169 | { | ||
1170 | (void)token; | ||
1171 | unsigned i; | ||
1172 | struct touchregion *region; | ||
1173 | const char *ptr = wps_bufptr; | ||
1174 | const char *action; | ||
1175 | int x,y,w,h; | ||
1176 | |||
1177 | /* format: %T|x|y|width|height|action| | ||
1178 | * action is one of: | ||
1179 | * play - play/pause playback | ||
1180 | * stop - stop playback, exit the wps | ||
1181 | * prev - prev track | ||
1182 | * next - next track | ||
1183 | * ffwd | ||
1184 | * rwd | ||
1185 | * menu - go back to the main menu | ||
1186 | * browse - go back to the file/db browser | ||
1187 | */ | ||
1188 | |||
1189 | if ((wps_data->touchregion_count +1 >= MAX_TOUCHREGIONS) || (*ptr != '|')) | ||
1190 | return WPS_ERROR_INVALID_PARAM; | ||
1191 | ptr++; | ||
1192 | |||
1193 | if (!(ptr = parse_list("dddds", NULL, '|', ptr, &x, &y, &w, &h, &action))) | ||
1194 | return WPS_ERROR_INVALID_PARAM; | ||
1195 | |||
1196 | /* Check there is a terminating | */ | ||
1197 | if (*ptr != '|') | ||
1198 | return WPS_ERROR_INVALID_PARAM; | ||
1199 | |||
1200 | /* should probably do some bounds checking here with the viewport... but later */ | ||
1201 | region = &wps_data->touchregion[wps_data->touchregion_count]; | ||
1202 | region->action = ACTION_NONE; | ||
1203 | region->x = x; | ||
1204 | region->y = y; | ||
1205 | region->width = w; | ||
1206 | region->height = h; | ||
1207 | region->wvp = &wps_data->viewports[wps_data->num_viewports]; | ||
1208 | i = 0; | ||
1209 | while ((region->action == ACTION_NONE) && | ||
1210 | (i < sizeof(touchactions)/sizeof(*touchactions))) | ||
1211 | { | ||
1212 | if (!strncmp(touchactions[i].s, action, strlen(touchactions[i].s))) | ||
1213 | region->action = touchactions[i].action; | ||
1214 | i++; | ||
1215 | } | ||
1216 | if (region->action == ACTION_NONE) | ||
1217 | return WPS_ERROR_INVALID_PARAM; | ||
1218 | wps_data->touchregion_count++; | ||
1219 | return skip_end_of_line(wps_bufptr); | ||
1220 | } | ||
1221 | #endif | ||
1222 | |||
1145 | /* Parse a generic token from the given string. Return the length read */ | 1223 | /* Parse a generic token from the given string. Return the length read */ |
1146 | static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) | 1224 | static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) |
1147 | { | 1225 | { |