diff --git a/Documentation/conf.py b/Documentation/conf.py
index 7dafb1841c521151d8a63dc91f1b892e9b2193e4..ae5361ac408293b054274b0051bbad963da2a738 100644
--- a/Documentation/conf.py
+++ b/Documentation/conf.py
@@ -87,7 +87,14 @@ html_context = {
 # }}}
 
 # -- Options for Auto-Doc ---------------------------------------------------- {{{
-autodoc_mock_imports = ["sys_display", "sys_leds", "ucollections", "urandom", "utime"]
+autodoc_mock_imports = [
+    "sys_display",
+    "sys_leds",
+    "buttons",
+    "ucollections",
+    "urandom",
+    "utime",
+]
 
 autodoc_member_order = "bysource"
 # }}}
diff --git a/Documentation/index.rst b/Documentation/index.rst
index 9cf3dac8f21d710f300f77e521397381a3393b6f..5c9da507504e4d423cd7409907a22a6ec44cfb9d 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -31,6 +31,7 @@ Last but not least, if you want to start hacking the lower-level firmware, the
    pycardium/light-sensor
    pycardium/os
    pycardium/personal_state
+   pycardium/simple_menu
    pycardium/utime
    pycardium/vibra
    pycardium/pride
diff --git a/Documentation/pycardium/simple_menu.rst b/Documentation/pycardium/simple_menu.rst
new file mode 100644
index 0000000000000000000000000000000000000000..66a3a930466470bdc33f76315787c005ccc10e82
--- /dev/null
+++ b/Documentation/pycardium/simple_menu.rst
@@ -0,0 +1,26 @@
+``simple_menu`` - Draw a Menu
+=============================
+To allow quickly hacking some scripts, Pycardium has a small library for
+displaying menus.  You can use it like this:
+
+.. code-block:: python
+
+   import color
+   import simple_menu
+
+
+   class MyMenu(simple_menu.Menu):
+       color_1 = color.CAMPGREEN
+       color_2 = color.CAMPGREEN_DARK
+
+       def on_select(self, name, index):
+           print("{!r} was selected!".format(name))
+
+
+   if __name__ == "__main__":
+       MyMenu(["foo", "bar", "baz"]).run()
+
+.. autoclass:: simple_menu.Menu
+   :members:
+
+.. autofunction:: simple_menu.button_events
diff --git a/pycardium/modules/py/meson.build b/pycardium/modules/py/meson.build
index 2818ffa33cd256c331a653b0383e6c94acce5b3f..59dd24d1fa95143f80c3f728129d6a3c5c170a0d 100644
--- a/pycardium/modules/py/meson.build
+++ b/pycardium/modules/py/meson.build
@@ -5,6 +5,7 @@ python_modules = files(
   'leds.py',
   'pride.py',
   'ledfx.py',
+  'simple_menu.py',
 
   # MicroPython Standard-Library
   'col_defaultdict.py',
diff --git a/pycardium/modules/py/simple_menu.py b/pycardium/modules/py/simple_menu.py
new file mode 100644
index 0000000000000000000000000000000000000000..a86ccf7e97c98ba64abf0db90ac5c18e57b208f4
--- /dev/null
+++ b/pycardium/modules/py/simple_menu.py
@@ -0,0 +1,184 @@
+import buttons
+import color
+import display
+
+
+def button_events():
+    """
+    Iterate over button presses (event-loop).
+
+    This is just a helper function used internally by the menu.  But you can of
+    course use it for your own scripts as well.  It works like this:
+
+    .. code-block:: python
+
+        import simple_menu, buttons
+
+        for ev in simple_menu.button_events():
+            if ev == buttons.BOTTOM_LEFT:
+                # Left
+                pass
+            elif ev == buttons.BOTTOM_RIGHT:
+                # Right
+                pass
+            elif ev == buttons.TOP_RIGHT:
+                # Select
+                pass
+    """
+    yield 0
+    v = buttons.read(buttons.BOTTOM_LEFT | buttons.BOTTOM_RIGHT | buttons.TOP_RIGHT)
+    button_pressed = True if v != 0 else False
+    while True:
+        v = buttons.read(buttons.BOTTOM_LEFT | buttons.BOTTOM_RIGHT | buttons.TOP_RIGHT)
+
+        if v == 0:
+            button_pressed = False
+
+        if not button_pressed and v & buttons.BOTTOM_LEFT != 0:
+            button_pressed = True
+            yield buttons.BOTTOM_LEFT
+
+        if not button_pressed and v & buttons.BOTTOM_RIGHT != 0:
+            button_pressed = True
+            yield buttons.BOTTOM_RIGHT
+
+        if not button_pressed and v & buttons.TOP_RIGHT != 0:
+            button_pressed = True
+            yield buttons.TOP_RIGHT
+
+
+class Menu:
+    """
+    A simple menu for card10.
+
+    This menu class is supposed to be inherited from to create a menu as shown
+    in the example above.
+
+    To instanciate the menu, pass a list of entries to the constructor:
+
+    .. code-block:: python
+
+        m = Menu(os.listdir("."))
+        m.run()
+
+    Then, call :py:meth:`~simple_menu.Menu.run` to start the event loop.
+    """
+
+    color_1 = color.CHAOSBLUE
+    """Background color A."""
+    color_2 = color.CHAOSBLUE_DARK
+    """Background color B."""
+    color_text = color.WHITE
+    """Text color."""
+    color_sel = color.COMMYELLOW
+    """Color of the selector."""
+
+    def on_scroll(self, item, index):
+        """
+        Hook when the selector scrolls to a new item.
+
+        This hook is run everytime a scroll-up or scroll-down is performed.
+        Overwrite this function in your own menus if you want to do some action
+        every time a new item is scrolled onto.
+
+        :param item: The item which the selector now points to.
+        :param int index: Index into the ``entries`` list of the ``item``.
+        """
+        pass
+
+    def on_select(self, item, index):
+        """
+        Hook when an item as selected.
+
+        The given ``index`` was selected with a SELECT button press.  Overwrite
+        this function in your menu to perform an action on select.
+
+        :param item: The item which was selected.
+        :param int index: Index into the ``entries`` list of the ``item``.
+        """
+        pass
+
+    def __init__(self, entries):
+        if len(entries) == 0:
+            raise ValueError("at least one entry is required")
+
+        self.entries = entries
+        self.idx = 0
+        self.disp = display.open()
+
+    def entry2name(self, value):
+        """
+        Convert an entry object to a string representation.
+
+        Overwrite this functio if your menu items are not plain strings.
+
+        **Example**:
+
+        .. code-block:: python
+
+            class MyMenu(simple_menu.Menu):
+                def entry2name(self, value):
+                    return value[0]
+
+            MyMenu(
+                [("a", 123), ("b", 321)]
+            ).run()
+        """
+        return str(value)
+
+    def draw_entry(self, value, index, offset):
+        """
+        Draw a single entry.
+
+        This is an internal function; you can override it for customized behavior.
+
+        :param value: The value for this entry.  Use this to identify
+            different entries.
+        :param int index: A unique index per entry. Stable for a certain entry,
+            but **not** an index into ``entries``.
+        :param int offset: Y-offset for this entry.
+        """
+        self.disp.print(
+            " " + self.entry2name(value) + " " * 9,
+            posy=offset,
+            fg=self.color_text,
+            bg=self.color_1 if index % 2 == 0 else self.color_2,
+        )
+
+    def draw_menu(self, offset=0):
+        """
+        Draw the menu.
+
+        You'll probably never need to call this yourself; it is called
+        automatially in the event loop (:py:meth:`~simple_menu.Menu.run`).
+        """
+        self.disp.clear()
+
+        # Wrap around the list and draw entries from idx - 3 to idx + 4
+        for y, i in enumerate(
+            range(len(self.entries) + self.idx - 3, len(self.entries) + self.idx + 4)
+        ):
+            self.draw_entry(
+                self.entries[i % len(self.entries)], i, offset + y * 20 - 40
+            )
+
+        self.disp.line(4, 22, 11, 29, col=self.color_sel, size=2)
+        self.disp.line(3, 37, 11, 29, col=self.color_sel, size=2)
+
+        self.disp.update()
+
+    def run(self):
+        """Start the event-loop."""
+        for ev in button_events():
+            if ev == buttons.BOTTOM_RIGHT:
+                self.draw_menu(-8)
+                self.idx = (self.idx + 1) % len(self.entries)
+                self.on_scroll(self.entries[self.idx], self.idx)
+            elif ev == buttons.BOTTOM_LEFT:
+                self.draw_menu(8)
+                self.idx = (self.idx + len(self.entries) - 1) % len(self.entries)
+                self.on_scroll(self.entries[self.idx], self.idx)
+            elif ev == buttons.TOP_RIGHT:
+                self.on_select(self.entries[self.idx], self.idx)
+
+            self.draw_menu()