From 08c02c48d30fabbe160d6639af7e0cfdad6a038f Mon Sep 17 00:00:00 2001
From: Rahix <rahix@rahix.de>
Date: Tue, 27 Aug 2019 21:24:14 +0200
Subject: [PATCH] feat(simple_menu): Add timeout to button_events()

Signed-off-by: Rahix <rahix@rahix.de>
---
 Documentation/pycardium/simple_menu.rst |  2 ++
 pycardium/modules/py/simple_menu.py     | 24 +++++++++++++++++++++++-
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/Documentation/pycardium/simple_menu.rst b/Documentation/pycardium/simple_menu.rst
index 36758c64..58236e2c 100644
--- a/Documentation/pycardium/simple_menu.rst
+++ b/Documentation/pycardium/simple_menu.rst
@@ -25,4 +25,6 @@ displaying menus.  You can use it like this:
 .. autoclass:: simple_menu.Menu
    :members:
 
+.. autodata:: simple_menu.TIMEOUT
+
 .. autofunction:: simple_menu.button_events
diff --git a/pycardium/modules/py/simple_menu.py b/pycardium/modules/py/simple_menu.py
index 22c80a0b..97af4e35 100644
--- a/pycardium/modules/py/simple_menu.py
+++ b/pycardium/modules/py/simple_menu.py
@@ -4,8 +4,11 @@ import display
 import sys
 import utime
 
+TIMEOUT = 0x100
+""":py:func:`~simple_menu.button_events` timeout marker."""
 
-def button_events():
+
+def button_events(timeout=None):
     """
     Iterate over button presses (event-loop).
 
@@ -28,11 +31,30 @@ def button_events():
                 pass
 
     .. versionadded:: 1.4
+
+    :param float,optional timeout:
+       Timeout after which the generator should yield in any case.  If a
+       timeout is defined, the generator will periodically yield
+       :py:data:`simple_menu.TIMEOUT`.
+
+       .. versionadded:: 1.9
     """
     yield 0
+
     v = buttons.read(buttons.BOTTOM_LEFT | buttons.BOTTOM_RIGHT | buttons.TOP_RIGHT)
     button_pressed = True if v != 0 else False
+
+    if timeout is not None:
+        timeout = int(timeout * 1000)
+        next_tick = utime.time_ms() + timeout
+
     while True:
+        if timeout is not None:
+            current_time = utime.time_ms()
+            if current_time >= next_tick:
+                next_tick += timeout
+                yield TIMEOUT
+
         v = buttons.read(buttons.BOTTOM_LEFT | buttons.BOTTOM_RIGHT | buttons.TOP_RIGHT)
 
         if v == 0:
-- 
GitLab