From 485ff795843597483264b1c9ce1a29a154aa6679 Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Tue, 1 Mar 2011 12:31:03 +0000 Subject: [PATCH] Add an ability to set a setting to a specific value with a touchscreen action. example: %T(0,0,20,12, setting_set, repeat, off) That will set the repeat mode to "off" when it is pressed. "setting_set" is the action name "repeat" is the name of the setting in the config files "off" is the value to set it to (same values as the legal values in the config files) Not all settings are supported, outright unsupported settings will fail to parse. Some settings might not work too well if they don't apply instantly (Any that work well int he quickscreen should work well here) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29483 a1c6a512-1295-4272-9138-f99709370657 --- apps/action.h | 1 + apps/gui/skin_engine/skin_parser.c | 75 ++++++++++++++++-------- apps/gui/skin_engine/skin_touchsupport.c | 42 ++++++++++++- apps/gui/skin_engine/wps_internals.h | 10 +++- apps/settings.c | 2 +- lib/skin_parser/tag_table.c | 4 +- 6 files changed, 105 insertions(+), 29 deletions(-) diff --git a/apps/action.h b/apps/action.h index e664c03fdf..a9e4de1665 100644 --- a/apps/action.h +++ b/apps/action.h @@ -196,6 +196,7 @@ enum { ACTION_SETTINGS_DECREPEAT, ACTION_SETTINGS_DECBIGSTEP, ACTION_SETTINGS_RESET, + ACTION_SETTINGS_SET, /* Used by touchscreen targets */ /* bookmark screen */ ACTION_BMS_DELETE, diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index 25734954e5..0eb966198d 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c @@ -937,7 +937,8 @@ static const struct touchaction touchactions[] = { {"mute", ACTION_TOUCH_MUTE }, /* generic settings changers */ - {"setting_inc", ACTION_SETTINGS_INC}, {"setting_dec", ACTION_SETTINGS_DEC}, + {"setting_inc", ACTION_SETTINGS_INC}, {"setting_dec", ACTION_SETTINGS_DEC}, + {"setting_set", ACTION_SETTINGS_SET}, /* WPS specific actions */ {"browse", ACTION_WPS_BROWSE }, @@ -952,6 +953,7 @@ static const struct touchaction touchactions[] = { {"presets", ACTION_FM_PRESET}, #endif }; +bool cfg_string_to_int(int setting_id, int* out, const char* str); static int parse_touchregion(struct skin_element *element, struct wps_token *token, @@ -966,26 +968,9 @@ static int parse_touchregion(struct skin_element *element, const char vol_string[] = "volume"; char temp[20]; - /* format: %T(x,y,width,height,action) + /* format: %T([label,], x,y,width,height,action[, ...]) * if action starts with & the area must be held to happen - * action is one of: - * play - play/pause playback - * stop - stop playback, exit the wps - * prev - prev track - * next - next track - * ffwd - seek forward - * rwd - seek backwards - * menu - go back to the main menu - * browse - go back to the file/db browser - * shuffle - toggle shuffle mode - * repmode - cycle the repeat mode - * quickscreen - go into the quickscreen - * contextmenu - open the context menu - * playlist - go into the playlist - * pitch - go into the pitchscreen - * volup - increase volume by one step - * voldown - decrease volume by one step - */ + */ region = (struct touchregion*)skin_buffer_alloc(sizeof(struct touchregion)); @@ -1018,7 +1003,7 @@ static int parse_touchregion(struct skin_element *element, region->wvp = curr_vp; region->armed = false; region->reverse_bar = false; - region->data = NULL; + region->value = 0; region->last_press = 0xffff; action = element->params[p++].data.text; @@ -1055,7 +1040,8 @@ static int parse_touchregion(struct skin_element *element, { region->action = touchactions[i].action; if (region->action == ACTION_SETTINGS_INC || - region->action == ACTION_SETTINGS_DEC) + region->action == ACTION_SETTINGS_DEC || + region->action == ACTION_SETTINGS_SET) { if (element->params_count < p+1) { @@ -1072,7 +1058,50 @@ static int parse_touchregion(struct skin_element *element, break; if (j==nb_settings) return WPS_ERROR_INVALID_PARAM; - region->data = (void*)&settings[j]; + region->setting_data.setting = (void*)&settings[j]; + if (region->action == ACTION_SETTINGS_SET) + { + char* text; + int temp; + struct touchsetting *setting = + ®ion->setting_data; + if (element->params_count < p+2) + return WPS_ERROR_INVALID_PARAM; + text = element->params[p+1].data.text; + switch (settings[j].flags&F_T_MASK) + { + case F_T_CUSTOM: + setting->value.text = text; + break; + case F_T_INT: + case F_T_UINT: + if (settings[j].cfg_vals == NULL) + { + setting->value.number = atoi(text); + } + else if (cfg_string_to_int(j, &temp, text)) + { + if (settings[j].flags&F_TABLE_SETTING) + setting->value.number = + settings[j].table_setting->values[temp]; + else + setting->value.number = temp; + } + else + return WPS_ERROR_INVALID_PARAM; + break; + case F_T_BOOL: + if (cfg_string_to_int(j, &temp, text)) + { + setting->value.number = temp; + } + else + return WPS_ERROR_INVALID_PARAM; + break; + default: + return WPS_ERROR_INVALID_PARAM; + } + } } } break; diff --git a/apps/gui/skin_engine/skin_touchsupport.c b/apps/gui/skin_engine/skin_touchsupport.c index 3206579adf..110e97f997 100644 --- a/apps/gui/skin_engine/skin_touchsupport.c +++ b/apps/gui/skin_engine/skin_touchsupport.c @@ -27,6 +27,7 @@ #include "misc.h" #include "option_select.h" #include "sound.h" +#include "settings_list.h" /** Disarms all touchregions. */ @@ -129,8 +130,45 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset, case ACTION_SETTINGS_INC: case ACTION_SETTINGS_DEC: { - const struct settings_list *setting = temp->data; - option_select_next_val(setting, returncode == ACTION_SETTINGS_DEC, true); + const struct settings_list *setting = + temp->setting_data.setting; + option_select_next_val(setting, + returncode == ACTION_SETTINGS_DEC, + true); + returncode = ACTION_REDRAW; + } + break; + case ACTION_SETTINGS_SET: + { + struct touchsetting *data = &temp->setting_data; + const struct settings_list *s = data->setting; + void (*f)(int) = NULL; + switch (s->flags&F_T_MASK) + { + case F_T_CUSTOM: + s->custom_setting + ->load_from_cfg(s->setting, data->value.text); + break; + case F_T_INT: + case F_T_UINT: + *(int*)s->setting = data->value.number; + if (s->flags&F_CHOICE_SETTING) + f = s->choice_setting->option_callback; + else if (s->flags&F_TABLE_SETTING) + f = s->table_setting->option_callback; + else + f = s->int_setting->option_callback; + + if (f) + f(data->value.number); + break; + case F_T_BOOL: + *(bool*)s->setting = data->value.number ? true : false; + if (s->bool_setting->option_callback) + s->bool_setting + ->option_callback(data->value.number ? true : false); + break; + } returncode = ACTION_REDRAW; } break; diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h index 28697c8b69..86d191f687 100644 --- a/apps/gui/skin_engine/wps_internals.h +++ b/apps/gui/skin_engine/wps_internals.h @@ -199,12 +199,20 @@ struct touchregion { bool armed; /* A region is armed on press. Only armed regions are triggered on repeat or release. */ union { /* Extra data, action dependant */ - void* data; + struct touchsetting { + const struct settings_list *setting; /* setting being controlled */ + union { /* Value to set the setting to for ACTION_SETTING_SET */ + int number; + char* text; + } value; + } setting_data; int value; }; long last_press; /* last tick this was pressed */ }; + + struct touchregion_lastpress { struct touchregion *region; long timeout; diff --git a/apps/settings.c b/apps/settings.c index e491c5b6f2..e9458dc601 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -231,7 +231,7 @@ void settings_load(int which) } } -static bool cfg_string_to_int(int setting_id, int* out, const char* str) +bool cfg_string_to_int(int setting_id, int* out, const char* str) { const char* start = settings[setting_id].cfg_vals; char* end = NULL; diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c index 68e4b03a4e..56f5df1911 100644 --- a/lib/skin_parser/tag_table.c +++ b/lib/skin_parser/tag_table.c @@ -206,10 +206,10 @@ static const struct tag_info legal_tags[] = /* HACK Alert (jdgordon): The next two tags have hacks so we could * add a S param at the front without breaking old skins. * [SD]D <- handled by the callback, allows SD or S or D params - * [SI]III[SI]|SS -< SIIIIS|S or IIIIS|S + * [SI]III[SI]|SN -< SIIIIS|S or IIIIS|S * keep in sync with parse_touchregion() and parse_lasttouch() */ { SKIN_TOKEN_LASTTOUCH, "Tl" , "|[SD]D", SKIN_REFRESH_DYNAMIC }, - { SKIN_TOKEN_TOUCHREGION, "T" , "[SI]III[SI]|SS", 0|NOBREAK }, + { SKIN_TOKEN_TOUCHREGION, "T" , "[SI]III[SI]|SN", 0|NOBREAK }, { SKIN_TOKEN_HAVE_TOUCH, "Tp", "", FEATURE_TAG },