summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
authorFranklin Wei <me@fwei.tk>2017-07-26 22:33:54 -0400
committerFranklin Wei <me@fwei.tk>2017-07-27 00:03:09 -0400
commit857b5babb9fb40781848b5581d664b228f063483 (patch)
treebdb7f0b0265fc79d352a69cf1cc3042adeccfefc /apps/plugins
parent7c87dbfba3b53c1e36733e184ce5cbeee2e7c86f (diff)
downloadrockbox-857b5babb9fb40781848b5581d664b228f063483.zip
rockbox-857b5babb9fb40781848b5581d664b228f063483.tar.gz
rockbox-857b5babb9fb40781848b5581d664b228f063483.tar.bz2
rockbox-857b5babb9fb40781848b5581d664b228f063483.tar.xz
puzzles: add number chooser for integer settings
Sure beats typing on the virtual keyboard.
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/puzzles/rockbox.c125
1 files changed, 120 insertions, 5 deletions
diff --git a/apps/plugins/puzzles/rockbox.c b/apps/plugins/puzzles/rockbox.c
index fae9c62..1df02bb 100644
--- a/apps/plugins/puzzles/rockbox.c
+++ b/apps/plugins/puzzles/rockbox.c
@@ -43,6 +43,9 @@
#define BG_R .9f /* very light gray */
#define BG_G .9f
#define BG_B .9f
+#define BG_COLOR LCD_RGBPACK((int)(255*BG_R), (int)(255*BG_G), (int)(255*BG_B))
+
+#define ERROR_COLOR LCD_RGBPACK(255, 0, 0)
#ifdef COMBINED
#define SAVE_FILE PLUGIN_GAMES_DATA_DIR "/puzzles.sav"
@@ -51,7 +54,6 @@ static char save_file_path[MAX_PATH];
#define SAVE_FILE ((const char*)save_file_path)
#endif
-#define BG_COLOR LCD_RGBPACK((int)(255*BG_R), (int)(255*BG_G), (int)(255*BG_B))
#define MURICA
@@ -927,18 +929,131 @@ static int list_choose(const char *list_str, const char *title)
}
}
-/* return value is only meaningful when type == C_STRING */
-static bool do_configure_item(config_item *cfg)
+static bool is_integer(const char *str)
+{
+ while(*str)
+ {
+ char c = *str++;
+ if(!isdigit(c) && c != '-')
+ return false;
+ }
+ return true;
+}
+
+/* max length of C_STRING config vals */
+#define MAX_STRLEN 128
+
+static void int_chooser(config_item *cfgs, int idx, int val)
{
+ config_item *cfg = cfgs + idx;
+ int old_val = val;
+
+ rb->snprintf(cfg->sval, MAX_STRLEN, "%d", val);
+
+ rb->lcd_clear_display();
+
+ while(1)
+ {
+ rb->lcd_set_foreground(LCD_WHITE);
+ rb->lcd_puts(0, 0, cfg->name);
+ rb->lcd_putsf(0, 1, "< %d >", val);
+ rb->lcd_update();
+ rb->lcd_set_foreground(ERROR_COLOR);
+
+ int d = 0;
+ int button = rb->button_get(true);
+ switch(button)
+ {
+ case BTN_RIGHT:
+ case BTN_RIGHT | BUTTON_REPEAT:
+ d = 1;
+ break;
+ case BTN_LEFT:
+ case BTN_LEFT | BUTTON_REPEAT:
+ d = -1;
+ break;
+ case BTN_FIRE:
+ /* config is already set */
+ rb->lcd_scroll_stop();
+ return;
+ case BTN_PAUSE:
+ if(val != old_val)
+ rb->splash(HZ, "Canceled.");
+ val = old_val;
+ rb->snprintf(cfg->sval, MAX_STRLEN, "%d", val);
+ rb->lcd_scroll_stop();
+ return;
+ }
+ if(d)
+ {
+ /* we try to increment the value up to this much (mainly
+ * a workaround for Unruly): */
+#define CHOOSER_MAX_INCR 2
+
+ char *ret;
+ for(int i = 0; i < CHOOSER_MAX_INCR; ++i)
+ {
+ val += d;
+ rb->snprintf(cfg->sval, MAX_STRLEN, "%d", val);
+ ret = midend_set_config(me, CFG_SETTINGS, cfgs);
+ if(!ret)
+ {
+ /* clear any error message */
+ rb->lcd_clear_display();
+ rb->lcd_scroll_stop();
+ break;
+ }
+
+ }
+
+ /* failure */
+ if(ret)
+ {
+ /* bright, annoying red */
+ rb->lcd_set_foreground(ERROR_COLOR);
+ rb->lcd_puts_scroll(0, 2, ret);
+
+ /* reset value */
+ val -= d * CHOOSER_MAX_INCR;
+ rb->snprintf(cfg->sval, MAX_STRLEN, "%d", val);
+ assert(!midend_set_config(me, CFG_SETTINGS, cfgs));
+ }
+ }
+ }
+}
+
+/* return value is only meaningful when type == C_STRING, where it
+ * indicates whether cfg->sval has been freed or otherwise altered */
+static bool do_configure_item(config_item *cfgs, int idx)
+{
+ config_item *cfg = cfgs + idx;
switch(cfg->type)
{
case C_STRING:
{
-#define MAX_STRLEN 128
char *newstr = smalloc(MAX_STRLEN);
- rb->strlcpy(newstr, cfg->sval, MAX_STRLEN);
+
rb->lcd_set_foreground(LCD_WHITE);
rb->lcd_set_background(LCD_BLACK);
+
+ if(is_integer(cfg->sval))
+ {
+ int val = atoi(cfg->sval);
+
+ /* we now free the original string and give int_chooser()
+ * a clean buffer to work with */
+ sfree(cfg->sval);
+ cfg->sval = newstr;
+
+ int_chooser(cfgs, idx, val);
+
+ rb->lcd_set_foreground(LCD_WHITE);
+ rb->lcd_set_background(LCD_BLACK);
+
+ return true;
+ }
+
+ rb->strlcpy(newstr, cfg->sval, MAX_STRLEN);
if(rb->kbd_input(newstr, MAX_STRLEN) < 0)
{
sfree(newstr);