lcdMenu/__init__.py

79 lines
4.2 KiB
Python

"""
lcdMenu - A micropython library, which supports vertical and horizontal scrolling through menu items on both 2x16 and 4x20 LCDs
Copyright (C) 2024 Benjamin Burkhardt <bluefox@privacynerd.de>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
class lcdMenu:
# lcd: I2C_LCD - an object of the I2C_LCD class (https://git.privacynerd.de/BlueFox/micropython-libraries/src/branch/main/PCF8574T)
# buttons: dict - a dictionary with machine.Pin objects as items with following keys
# - "prev_btn" - OPTIONAL - when pressed, select the previous menu item
# - "next_btn" - REQUIRED - when pressed, select the next menu item
# - "ok_btn" - REQUIRED - when pressed, call the callback function of the menu item
# menu_items: list - a list (-> maintains order!) containing tuples with the following format: (<ENTRY_NAME>,<CALLBACK FUNCTION>)
# scroll_direction: bool - if true, the scrolling direction is horizontal, if false, vertical
# cycle: bool - if true, start again with the first menu entry after the last one (and show the last before the first)
# hide_menu_name: bool - OPTIONAL - if true, hide the menu's name (won't work in combination with a vertical scrolling direction)
# name: str - OPTIONAL - a string with the name of the menu (can be hidden under certain circumstances)
# default_selection: int - OPTIONAL - the index of the item selected by default (starting with 0) - DON'T USE NEGATIVE INDEXES
def __init__(self, lcd, buttons: dict, menu_items: list, scroll_direction: bool, cycle: bool, hide_menu_name: bool = False, name: str = "CHOOSE", default_selection: int = 0):
self.lcd = lcd
if "prev_btn" in buttons.keys():
self.prev_btn = buttons["prev_btn"]
else:
self.prev_btn = None
self.next_btn = buttons["next_btn"]
self.ok_btn = buttons["ok_btn"]
self.menu_items = menu_items
self.scroll_direction = scroll_direction
self.cycle = cycle
self.hide_menu_name = hide_menu_name
self.name = name
self.current_selection = default_selection
def show_selection(self):
# if you scrolling vertically, I found no elegant way to hide the name (there just need's to be something up there!)
if self.scroll_direction and self.hide_menu_name:
raise TypeError("Hiding the menu name whilst having the scroll direction set to horizontal!")
# TODO: the real process
if self.scroll_direction: # if horizontal scrolling is activated
pass
else: # if vertical scrolling is activated
pass
def previous_selection(self):
self.current_selection -= 1
if self.current_selection < 0: # after the last element:
if self.cycle: # if cycling is enabled, set it to the index of the last element
self.current_selection = len(self.menu_items)-1
else: # else, go to first element
self.current_selection = 0
def next_selection(self):
self.current_selection += 1
if self.current_selection >= len(self.menu_items): # after the last element:
if self.cycle: # if cycling is enabled, go to first element
self.current_selection = 0
else: # else, set it to the index of the last element
self.current_selection = len(self.menu_items)-1
def execute_selection(self):
self.menu_items[self.current_selection][1]()
def run(self):
# TODO: add btn handlers and the actual process
pass