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
This commit is contained in:
Jonathan Gordon 2011-03-01 12:31:03 +00:00
parent 735ea2fd1f
commit 485ff79584
6 changed files with 105 additions and 29 deletions

View file

@ -196,6 +196,7 @@ enum {
ACTION_SETTINGS_DECREPEAT, ACTION_SETTINGS_DECREPEAT,
ACTION_SETTINGS_DECBIGSTEP, ACTION_SETTINGS_DECBIGSTEP,
ACTION_SETTINGS_RESET, ACTION_SETTINGS_RESET,
ACTION_SETTINGS_SET, /* Used by touchscreen targets */
/* bookmark screen */ /* bookmark screen */
ACTION_BMS_DELETE, ACTION_BMS_DELETE,

View file

@ -937,7 +937,8 @@ static const struct touchaction touchactions[] = {
{"mute", ACTION_TOUCH_MUTE }, {"mute", ACTION_TOUCH_MUTE },
/* generic settings changers */ /* 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 */ /* WPS specific actions */
{"browse", ACTION_WPS_BROWSE }, {"browse", ACTION_WPS_BROWSE },
@ -952,6 +953,7 @@ static const struct touchaction touchactions[] = {
{"presets", ACTION_FM_PRESET}, {"presets", ACTION_FM_PRESET},
#endif #endif
}; };
bool cfg_string_to_int(int setting_id, int* out, const char* str);
static int parse_touchregion(struct skin_element *element, static int parse_touchregion(struct skin_element *element,
struct wps_token *token, struct wps_token *token,
@ -966,26 +968,9 @@ static int parse_touchregion(struct skin_element *element,
const char vol_string[] = "volume"; const char vol_string[] = "volume";
char temp[20]; 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 * 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)); 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->wvp = curr_vp;
region->armed = false; region->armed = false;
region->reverse_bar = false; region->reverse_bar = false;
region->data = NULL; region->value = 0;
region->last_press = 0xffff; region->last_press = 0xffff;
action = element->params[p++].data.text; action = element->params[p++].data.text;
@ -1055,7 +1040,8 @@ static int parse_touchregion(struct skin_element *element,
{ {
region->action = touchactions[i].action; region->action = touchactions[i].action;
if (region->action == ACTION_SETTINGS_INC || 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) if (element->params_count < p+1)
{ {
@ -1072,7 +1058,50 @@ static int parse_touchregion(struct skin_element *element,
break; break;
if (j==nb_settings) if (j==nb_settings)
return WPS_ERROR_INVALID_PARAM; 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 =
&region->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; break;

View file

@ -27,6 +27,7 @@
#include "misc.h" #include "misc.h"
#include "option_select.h" #include "option_select.h"
#include "sound.h" #include "sound.h"
#include "settings_list.h"
/** Disarms all touchregions. */ /** 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_INC:
case ACTION_SETTINGS_DEC: case ACTION_SETTINGS_DEC:
{ {
const struct settings_list *setting = temp->data; const struct settings_list *setting =
option_select_next_val(setting, returncode == ACTION_SETTINGS_DEC, true); 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; returncode = ACTION_REDRAW;
} }
break; break;

View file

@ -199,12 +199,20 @@ struct touchregion {
bool armed; /* A region is armed on press. Only armed regions are triggered bool armed; /* A region is armed on press. Only armed regions are triggered
on repeat or release. */ on repeat or release. */
union { /* Extra data, action dependant */ 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; int value;
}; };
long last_press; /* last tick this was pressed */ long last_press; /* last tick this was pressed */
}; };
struct touchregion_lastpress { struct touchregion_lastpress {
struct touchregion *region; struct touchregion *region;
long timeout; long timeout;

View file

@ -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; const char* start = settings[setting_id].cfg_vals;
char* end = NULL; char* end = NULL;

View file

@ -206,10 +206,10 @@ static const struct tag_info legal_tags[] =
/* HACK Alert (jdgordon): The next two tags have hacks so we could /* HACK Alert (jdgordon): The next two tags have hacks so we could
* add a S param at the front without breaking old skins. * add a S param at the front without breaking old skins.
* [SD]D <- handled by the callback, allows SD or S or D params * [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() */ * keep in sync with parse_touchregion() and parse_lasttouch() */
{ SKIN_TOKEN_LASTTOUCH, "Tl" , "|[SD]D", SKIN_REFRESH_DYNAMIC }, { 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 }, { SKIN_TOKEN_HAVE_TOUCH, "Tp", "", FEATURE_TAG },