Rockbox.org home
release
dev builds
extras
themes manual
wiki
device status forums
mailing lists
IRC bugs
patches
dev guide



Rockbox mail archive

Subject: menu/settings merging take 2!

menu/settings merging take 2!

From: Jonathan Gordon <jdgordy_at_gmail.com>
Date: Mon, 4 Sep 2006 22:29:15 +1000

hey,
Ive started this once again and I tihnk i may have got it right this time.
What I hope for this to eventually do is make adding a setting to the
menus/global_settings as simple as possible. A side effect of this is
the removal of the config block (all settings are written either to
config.cfg or data.dat).

here is what the settings.h file is starting to look like.

**********************************************************************************

#define GS(a) &global_settings.a

#define _INT(...) (int[]){__VA_ARGS__}
#define _STR(...) (*char[]){__VA_ARGS__}
#define SOUND_ITEM(var,name,setting) {F_T_INT|F_T_SOUND, GS(var), 0,
name, 1,_INT(setting), NULL }
#define BOOL_ITEM(var,name,default) {F_T_BOOL, GS(var), default, name,
0,NULL, NULL }
#define INT_ITEM(var,name,default,min,max,step,unit) {F_T_INT,
GS(var), default, name, 3,_INT(min,max,step), _INT(unit) }
#define SYSTEM_ITEM(type,var,default) {type|F_SYSTEMSETTING, GS(var),
default, #var, 0,NULL, NUL }
union storage_type {
    int int_;
    unsigned int uint_;
    bool bool_;
    char *charptr;
    unsigned char *ucharptr;
};
/* the variable type for the setting */
#define F_T_INT 1
#define F_T_UINT 2
#define F_T_BOOL 3
#define F_T_CHARPTR 4
#define F_T_UCHARPTR 5

/* we can go up to 7 types, 3 bits should be enough */
#define F_T_MASK 0x7 /* NOTE mask does not include the sign flag bit */
#define F_T_SOUND 0x8 /* this variable uses the set_sound stuff,
| with one of the above types */
                            /* values[0] = setting type */
#define F_T_CHOICE 0x10 /* this variable is a "choice" type, \
                               if this is not set then values[0] =
min, values[1] = max, values[2] = step \
                               talk_id[0] = talk unit
                                     */
#define F_LANG_STRING 0x20 /* this variable uses *strings in the
union for the values, donot try to xlate \
                               unless talk_id is NULL it will try to
talk the corresponding value there \
                               talk_id is only needed to be filled if
this is set */

#define F_SYSTEMSETTING 0x800 /* if set it will be saved in data.dat
not config.cfg */

struct settings_list {
    int flags; /* ____ ____ ____ ____ ____ S___ __LC STTT */
    union storage_type *variable; /* the variable in global_settings,
use GS() macro for this */
    union storage_type default_val;
    int cfg_name; /* lang_id of this variable in the
.cfg file */
    int nb_values; /* # of values, ignored unless
F_T_CHOICE is set */
    union {
        int *values; /* If F_T_CHOICE is not set and
(F_T_MASK!=F_T_BOOL) */
        char *strings[]; /* then values[0] = min,
[1]=max, [2]=step. */
    };
    int *talk_id;

    /* If F_T_SOUND is set then default_val, values and nb_values are
ignored */
};

const struct settings_list settings[] = {
    /* sound */
    SOUND_ITEM(volume,LANG_VOLUME,SOUND_VOLUME),
    SOUND_ITEM(balance,LANG_BALANCE,SOUND_BALANCE),
    SOUND_ITEM(bass,LANG_BASS,SOUND_BASS),
    SOUND_ITEM(treble,LANG_TREBLE,SOUND_TREBLE),
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
    SOUND_ITEM(loudness,LANG_LOUDNESS,SOUND_LOUDNESS),
    {F_T_INT|F_LANG_STRING, GS(avc), 0, LANG_AUTOVOL,0,5,
        _STR("off","20ms","2","4","8"),
        _INT(LANG_OFF,TALK_ID(20, UNIT_MS),TALK_ID(2,
UNIT_SEC),TALK_ID(4, UNIT_SEC),TALK_ID(8, UNIT_SEC))
    },
    BOOL_ITEM(superbass,LANG_SUPERBASS,false),
#endif
    {F_T_INT, GS(channel_config), 0, LANG_CHANNEL,
        _INT(LANG_CHANNEL_STEREO,LANG_CHANNEL_MONO,
        LANG_CHANNEL_CUSTOM,LANG_CHANNEL_LEFT,
        LANG_CHANNEL_RIGHT,LANG_CHANNEL_KARAOKE)
    },
    SOUND_ITEM(stereo_width,LANG_STEREO_WIDTH,SOUND_STEREO_WIDTH),

    /* playback */
    BOOL_ITEM(resume,LANG_RESUME,false),
    BOOL_ITEM(playlist_shuffle,LANG_SHUFFLE,false),
    SYSTEM_ITEM(F_T_INT,resume_index,-1),
    SYSTEM_ITEM(F_T_INT,resume_first_index,0),
    SYSTEM_ITEM(F_T_INT,resume_offset,-1),
    SYSTEM_ITEM(F_T_INT,resume_seed,-1),
    {F_T_INT, GS(repeat_mode), REPEAT_ALL, LANG_REPEAT,NUM_REPEAT_MODES,
        _INT(LANG_OFF,LANG_REPEAT_ALL,LANG_REPEAT_ONE,LANG_SHUFFLE,LANG_REPEAT_AB),NULL
    },

**************************************************************

explanation:
this array will contain every setting in global_settings. Im using a
few macros because I'm incredibly lazy and i tinhk it makes the code
much easier to read, hopefully everyone agrees :D

I intend to use this list for both the setting load/saving and the
menus, so everything that is needed for an setting will be in this
list (except I havnt worked out how to do callbacks yet.. but I havnt
started coding anything so they may not be needed).

As you can see, everything uses the lang_id instead of a char*, so the
menus and settings will get the translated string from the id, and the
load/saving of the cfg files will use the english string for that id
as the name.

I cant remember how much of the last try i sent to the ml, but each
(sub)menu will be an array of menu items, an item either being a
function, sub-menu or setting to be set. So to add a setting to a menu
all that will be needed is to add something like
SETTING_MENU_ITEM(volume), the menu will then search the settings list
untill it finds the item with the same pointer to
global_settings.volume and use the information there to load the
correct settings widget.

So, in the end, to add an item to global settings, it would be added
to the global_settings struct, to the settings list (above) and maybe
to a menu. simple? :)

any thoughts? comments? needs more explanation?
Received on 2006-09-04


Page was last modified "Jan 10 2012" The Rockbox Crew
aaa