Index: ../firmware/export/button.h
===================================================================
--- ../firmware/export/button.h (revision 14623)
+++ ../firmware/export/button.h (working copy)
@@ -59,5 +59,17 @@
/* Button modifiers */
#define BUTTON_REL 0x02000000
#define BUTTON_REPEAT 0x04000000
+#ifdef ACCEPT_DOUBLE_CLICK
+#define BUTTON_DBL 0x08000000
+#endif
+#ifdef ACCEPT_DOUBLE_CLICK
+#define DC_DELAY_MIN 100
+#define DC_DELAY_MAX 500
+#define DC_DELAY_DEF 300
+#define DC_DELAY_START 30
+
+void btn_set_double_click_delay(int delay);
+#endif
+
#endif /* _BUTTON_H_ */
Index: ../firmware/drivers/button.c
===================================================================
--- ../firmware/drivers/button.c (revision 14623)
+++ ../firmware/drivers/button.c (working copy)
@@ -64,6 +64,12 @@
bool phones_present = false;
#endif
+#ifdef ACCEPT_DOUBLE_CLICK
+static int double_click_interval;
+static int double_click_start;
+static int double_click_count;
+#endif
+
/* how long until repeat kicks in, in ticks */
#define REPEAT_START 30
@@ -82,6 +88,9 @@
static int repeat_count = 0;
static bool repeat = false;
static bool post = false;
+#ifdef ACCEPT_DOUBLE_CLICK
+ static int lastbtn_pushed = 0;
+#endif
#ifdef HAVE_BACKLIGHT
static bool skip_release = false;
#ifdef HAVE_REMOTE_LCD
@@ -90,7 +99,7 @@
#endif
int diff;
int btn;
-
+
#ifdef HAS_SERIAL_REMOTE
/* Post events for the remote control */
btn = remote_control_rx();
@@ -133,23 +142,66 @@
else
#endif
if(!skip_release)
+#ifdef ACCEPT_DOUBLE_CLICK
+ {
+ /* if double_click is < start then a double click was
+ * detected and queued, now we must queue the release, and dbl
+ */
+ if (lastbtn_pushed > 0 && double_click_count < double_click_start)
+ {
+ queue_post(&button_queue, BUTTON_DBL | lastbtn_pushed, 0);
+ queue_post(&button_queue, BUTTON_REL | lastbtn_pushed, 0);
+ double_click_count = double_click_interval;
+ lastbtn_pushed = 0;
+ }
+ }
+#else /* !ACCEPT_DOUBLE_CLICK */
queue_post(&button_queue, BUTTON_REL | diff, 0);
+#endif
else
skip_release = false;
-#else
+#else /* !HAVE_REMOTE_LCD */
+#ifdef ACCEPT_DOUBLE_CLICK
+ /* see above section comment */
+ if (lastbtn_pushed > 0 && double_click_count < double_click_start)
+ {
+ queue_post(&button_queue, BUTTON_DBL | lastbtn_pushed, 0);
+ queue_post(&button_queue, BUTTON_REL | lastbtn_pushed, 0);
+ double_click_count = double_click_interval;
+ lastbtn_pushed = 0;
+ }
+#else /* !ACCEPT_DOUBLE_CLICK */
queue_post(&button_queue, BUTTON_REL | diff, 0);
#endif
+#endif
}
else
{
if ( btn )
{
+#ifdef ACCEPT_DOUBLE_CLICK
+ /* check for double click */
+ /* double clicked if lastbtn == 0, and we've waited long enough */
+ if (lastbtn == 0 && btn == lastbtn_pushed && double_click_count < double_click_start)
+ {
+ /* double clicked now wait for button to be released
+ * cannot post yet, as the second click could be a hold */
+ post = false;
+ double_click_count = 0;
+ }
+ else
+#endif
/* normal keypress */
if ( btn != lastbtn )
{
post = true;
repeat = false;
repeat_speed = REPEAT_INTERVAL_START;
+#ifdef ACCEPT_DOUBLE_CLICK
+ /* diff btn - reset double click, no post */
+ post = false;
+ double_click_count = double_click_interval;
+#endif
}
else /* repeat? */
{
@@ -201,6 +253,18 @@
repeat_count = 0;
/* initial repeat */
count = REPEAT_INTERVAL_START;
+#ifdef ACCEPT_DOUBLE_CLICK
+ /* post original button press and release */
+ if (double_click_count == 0)
+ {
+ queue_post(&button_queue, btn, 0);
+ queue_post(&button_queue, BUTTON_REL | btn, 0);
+ }
+ /* post current button press */
+ queue_post(&button_queue, btn, 0);
+ /* reset double click detection */
+ double_click_count = double_click_interval;
+#endif
}
}
}
@@ -243,7 +307,9 @@
|| (btn&BUTTON_REMOTE)
#endif
)
+ {
queue_post(&button_queue, btn, 0);
+ }
else
skip_release = true;
#else /* no backlight, nothing to skip */
@@ -263,11 +329,35 @@
}
else
{
+#ifdef ACCEPT_DOUBLE_CLICK
+ /* if we've waited longer than double_click_interval
+ * then it isn't a double click, so queue the button
+ * we also know it isn't a double click if repeat is true
+ */
+ if (repeat || (lastbtn_pushed && --double_click_count <= 0))
+ {
+ /* queue both the original press if not repeating,
+ * and the release
+ */
+ if (!repeat)
+ queue_post(&button_queue, lastbtn_pushed, 0);
+ queue_post(&button_queue, BUTTON_REL | lastbtn_pushed, 0);
+ double_click_count = double_click_interval;
+ lastbtn_pushed = 0;
+ }
+#endif
repeat = false;
count = 0;
}
}
+
+#ifdef ACCEPT_DOUBLE_CLICK
+ lastbtn = btn & ~(BUTTON_REL | BUTTON_REPEAT | BUTTON_DBL);
+ if (lastbtn)
+ lastbtn_pushed = lastbtn;
+#else
lastbtn = btn & ~(BUTTON_REL | BUTTON_REPEAT);
+#endif
}
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
@@ -369,6 +459,10 @@
remote_filter_first_keypress = false;
#endif
#endif
+
+#ifdef ACCEPT_DOUBLE_CLICK
+ btn_set_double_click_delay(DC_DELAY_DEF);
+#endif
}
#ifdef HAVE_LCD_BITMAP /* only bitmap displays can be flipped */
@@ -514,3 +608,17 @@
return delta;
}
#endif /* HAVE_SCROLLWHEEL */
+
+#ifdef ACCEPT_DOUBLE_CLICK
+void btn_set_double_click_delay(int delay)
+{
+ if (delay < DC_DELAY_MIN ||
+ delay > DC_DELAY_MAX)
+ delay = DC_DELAY_DEF;
+
+ double_click_interval = delay / 10; // convert to ticks
+ double_click_start = (delay - DC_DELAY_START) / 10; // conver to ticks
+ double_click_count = double_click_interval;
+}
+#endif
+
Index: ../firmware/export/config-ipodvideo.h
===================================================================
--- ../firmware/export/config-ipodvideo.h (revision 14623)
+++ ../firmware/export/config-ipodvideo.h (working copy)
@@ -159,4 +159,7 @@
#define ICODE_ATTR_TREMOR_NOT_MDCT
+/* define this to turn on double click captures */
+#define ACCEPT_DOUBLE_CLICK
+
#endif
Index: ../apps/menus/settings_menu.c
===================================================================
--- ../apps/menus/settings_menu.c (revision 14623)
+++ ../apps/menus/settings_menu.c (working copy)
@@ -344,6 +344,10 @@
MENUITEM_SETTING(buttonlight_brightness, &global_settings.buttonlight_brightness, NULL);
#endif
+#ifdef ACCEPT_DOUBLE_CLICK
+MENUITEM_SETTING(btn_double_click_delay, &global_settings.btn_double_click_delay, NULL);
+#endif
+
MAKE_MENU(system_menu, ID2P(LANG_SYSTEM),
0, Icon_System_menu,
&start_screen,
@@ -374,8 +378,11 @@
&button_light_timeout,
#endif
#ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
- &buttonlight_brightness
+ &buttonlight_brightness,
#endif
+#ifdef ACCEPT_DOUBLE_CLICK
+ &btn_double_click_delay
+#endif
);
/* SYSTEM MENU */
Index: ../apps/settings_list.c
===================================================================
--- ../apps/settings_list.c (revision 14623)
+++ ../apps/settings_list.c (working copy)
@@ -1263,6 +1263,12 @@
3, "list_accel_wait", UNIT_SEC, 1, 10, 1,
scanaccel_formatter, scanaccel_getlang, NULL),
#endif /* HAVE_SCROLLWHEEL */
+#ifdef ACCEPT_DOUBLE_CLICK
+ INT_SETTING(0, btn_double_click_delay, LANG_DOUBLE_CLICK_DELAY, DC_DELAY_DEF,
+ "dbl click delay", UNIT_MS, DC_DELAY_MIN, DC_DELAY_MAX, 20,
+ NULL, NULL, btn_set_double_click_delay),
+#endif
+
#ifdef HAVE_USBSTACK
CHOICE_SETTING(0, usb_stack_mode, LANG_USBSTACK_MODE, 0, "usb mode",
"device,host",
Index: ../apps/settings.h
===================================================================
--- ../apps/settings.h (revision 14623)
+++ ../apps/settings.h (working copy)
@@ -748,6 +760,10 @@
int list_accel_start_delay; /* ms before we start increaseing step size */
int list_accel_wait; /* ms between increases */
#endif
+#ifdef ACCEPT_DOUBLE_CLICK
+ int btn_double_click_delay;
+#endif
+
#ifdef HAVE_USBSTACK
int usb_stack_mode; /* device or host */
unsigned char usb_stack_device_driver[32]; /* usb device driver to load */
Index: ../apps/lang/english.lang
===================================================================
--- ../apps/lang/english.lang (revision 14623)
+++ ../apps/lang/english.lang (working copy)
@@ -11027,6 +11027,20 @@
+
+ id: LANG_DOUBLE_CLICK_DELAY
+ desc: set delay in ms between clicks to detect double click
+ user:
+
+ *: "Set Double-Click Delay"
+
+
+ *: "Set Double-Click Delay"
+
+
+ *: "Set Double-Click Delay"
+
+
id: LANG_EXT_ONLY_VIEW_ALL
desc: in settings_menu
user: