Finally fully implemented the vertical scrolling; also, added more comments to the program for better understandability
This commit is contained in:
		| @@ -8,10 +8,10 @@ This project is the completely rewritten successor of my old (and now archived) | |||||||
| ## Roadmap | ## Roadmap | ||||||
|  |  | ||||||
| - [x] forward, backward and select button | - [x] forward, backward and select button | ||||||
| - [ ] support for horizontal and vertical scrolling | - [x] support for horizontal and vertical scrolling | ||||||
| - [x] support for both 2x16 and 4x20 LCDs | - [x] support for both 2x16 and 4x20 LCDs | ||||||
| - [x] a reliable order of the menu items | - [x] a reliable order of the menu items | ||||||
| - [ ] good documentation for all of this (maybe through examples) | - [x] good documentation for all of this (maybe through examples) | ||||||
| - [x] show an exit screen when a specific exit code is returned by a callback function | - [x] show an exit screen when a specific exit code is returned by a callback function | ||||||
| - [ ] make the menu itself exitable (to enable stuff like submenus, etc.) | - [ ] make the menu itself exitable (to enable stuff like submenus, etc.) | ||||||
| - [x] make the project a valid python package  | - [x] make the project a valid python package  | ||||||
|   | |||||||
							
								
								
									
										61
									
								
								__init__.py
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								__init__.py
									
									
									
									
									
								
							| @@ -63,10 +63,10 @@ class lcdMenu: | |||||||
|         # fill the custom character fields in the displays memory |         # fill the custom character fields in the displays memory | ||||||
|         self.lcd.custom_char(0, bytearray([0x04,0x0A,0x11,0x00,0x00,0x00,0x00,0x00]))  # arrow up |         self.lcd.custom_char(0, bytearray([0x04,0x0A,0x11,0x00,0x00,0x00,0x00,0x00]))  # arrow up | ||||||
|         self.lcd.custom_char(1, bytearray([0x00,0x00,0x00,0x00,0x00,0x11,0x0A,0x04]))  # arrow down |         self.lcd.custom_char(1, bytearray([0x00,0x00,0x00,0x00,0x00,0x11,0x0A,0x04]))  # arrow down | ||||||
|         self.lcd.custom_char(2, bytearray([0x04,0x0A,0x11,0x00,0x00,0x11,0x0A,0x04]))  # arrow up and down (variant 5 from above) |         self.lcd.custom_char(2, bytearray([0x04,0x0A,0x11,0x00,0x00,0x11,0x0A,0x04]))  # arrow up and down | ||||||
|         self.lcd.custom_char(3, bytearray([0x11,0x0A,0x04,0x00,0x00,0x04,0x0A,0x11]))  # no options (variant 3 from above) |         self.lcd.custom_char(3, bytearray([0x11,0x0A,0x04,0x00,0x00,0x04,0x0A,0x11]))  # no options | ||||||
|         self.lcd.custom_char(4, bytearray([0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x08]))  # line with a fork (to show the current selection - h scrolling) |         self.lcd.custom_char(4, bytearray([0x08,0x08,0x08,0x0F,0x08,0x08,0x08,0x08]))  # line with a fork (to show the current selection - v scrolling) | ||||||
|         self.lcd.custom_char(5, bytearray([0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08]))  # line without a fork (to show unselected items - h scrolling) |         self.lcd.custom_char(5, bytearray([0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08]))  # line without a fork (to show unselected items - v scrolling) | ||||||
|         self.lcd.custom_char(6, bytearray([0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x00]))  # three dots in a row |         self.lcd.custom_char(6, bytearray([0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x00]))  # three dots in a row | ||||||
|          |          | ||||||
|         # now show it off! |         # now show it off! | ||||||
| @@ -97,31 +97,28 @@ class lcdMenu: | |||||||
|                 # maybe the following could be done with a crazy math formula - but I want to keep it simpler! |                 # maybe the following could be done with a crazy math formula - but I want to keep it simpler! | ||||||
|                 # as there aren't enough menu items after the current selection to fill the display, we have to... |                 # as there aren't enough menu items after the current selection to fill the display, we have to... | ||||||
|                 # ... calculate where to place the current selection, how many items there are before it and how many after it |                 # ... calculate where to place the current selection, how many items there are before it and how many after it | ||||||
|                 """ |                 menu_items_cut = self.menu_items[:lines_for_display:-1][::-1]  # cut the menu_items list to the relevant last n ones maintaining order (n = number of lines for display) | ||||||
|                 if lines_for_display > len(self.menu_items):  # if it is because of an overall small number of menu items (less than we can display) |                 current_pos_in_cut = -len(self.menu_items) + self.current_selection + lines_for_display  # calculate the current index of the selection in the new cut | ||||||
|                     for i in range(len(self.menu_items)): |                 # draw all the lines | ||||||
|                         if i < self.current_selection: |                 for i in range(lines_for_display): | ||||||
|                             self.lcd.putstr(chr(5)+" "+self.menu_items[i][0][0:lw-4]) |                     if i == current_pos_in_cut:  # if drawing the currently selected item | ||||||
|                             self.lcd.putstr(" "*(lw-4-len(self.menu_items[i][0][0:lw-4]))) |                         self.lcd.putstr(f"{chr(4)} {menu_items_cut[i][0][0:lw-4]}") | ||||||
|                             if len(self.menu_items) <= 1: |                         self.lcd.putstr(" " * ((lw-4)-len(menu_items_cut[i][0][0:lw-4])))  # fit the line | ||||||
|                                 self.lcd.putstr(" " + chr(3))  # no options icon (as there's only one menu item!) |  | ||||||
|                             elif self.current_selection == 0 and not self.cycle: |  | ||||||
|                                 self.lcd.putstr(" "+chr(1)) |  | ||||||
|                             elif self.current_selection == (len(self.menu_items)-1) and not self.cycle: |  | ||||||
|                                 self.lcd.putstr(" "+chr(0)) |  | ||||||
|                     else: |                     else: | ||||||
|                                 self.lcd.putstr(" "+chr(2)) |                         self.lcd.putstr(f"{chr(5)} {menu_items_cut[i][0][0:lw-4]}") | ||||||
|                         elif i == self.current_selection: |                         self.lcd.putstr(" " * ((lw-4)-len(menu_items_cut[i][0][0:lw-4])))  # fit the line | ||||||
|                             self.lcd.putstr(chr(5)+" "+self.menu_items[i][0][0:lw-4]) |                     # now the arrow | ||||||
|                             self.lcd.putstr(" "*(lw-4-len(self.menu_items[i][0][0:lw-4]))) |                     if i == 0:  # if the first element is drawn, think about printing or not printing the up arrow | ||||||
|                         elif i > self.current_selection: |                         if self.current_selection == 0 and not self.cycle:  # first item selected and no cycling | ||||||
|  |                             self.lcd.putstr("  ")  # leave the line with spaces | ||||||
|  |                         else: | ||||||
|  |                             self.lcd.putstr(" " + chr(0)) | ||||||
|  |                     elif i == lines_for_display-1:  # if the last element is drawn, print a down arrow? | ||||||
|  |                         if self.current_selection == (len(self.menu_items)-1) and not self.cycle:  # first item selected and no cycling | ||||||
|  |                             self.lcd.putstr("  ")  # leave the line with spaces | ||||||
|  |                         else: | ||||||
|  |                             self.lcd.putstr(" " + chr(1))  # arrow down | ||||||
|                          |                          | ||||||
|                          |  | ||||||
|                     print("Im here!") |  | ||||||
|                 else:  # if it is because we reached the end of a (possibly) long menu list -> we have enough items to fill all the available lines |  | ||||||
|                     print("Else here!") |  | ||||||
|                 """ |  | ||||||
|                 print("ToDo!") |  | ||||||
|             else:  # there are enough items to fill the display after the current selection |             else:  # there are enough items to fill the display after the current selection | ||||||
|                 # the first line |                 # the first line | ||||||
|                 self.lcd.putstr(f"{chr(4)} {selection_name[0:lw-4]}") |                 self.lcd.putstr(f"{chr(4)} {selection_name[0:lw-4]}") | ||||||
| @@ -129,12 +126,12 @@ class lcdMenu: | |||||||
|                  |                  | ||||||
|                 if len(self.menu_items) <= 1: |                 if len(self.menu_items) <= 1: | ||||||
|                     self.lcd.putstr(" " + chr(3))  # no options icon (as there's only one menu item!) |                     self.lcd.putstr(" " + chr(3))  # no options icon (as there's only one menu item!) | ||||||
|                 elif lines_for_display == 1:  # if there is exactly one line to display the menu entries |                 elif lines_for_display == 1:  # if there is exactly one line to display the menu entries... | ||||||
|                     if self.current_selection == 0 and not self.cycle: |                     if self.current_selection == 0 and not self.cycle:  # ...and the first element is selected and cycling is disabled so you can't go back | ||||||
|                         self.lcd.putstr(" "+chr(1)) |                         self.lcd.putstr(" "+chr(1)) | ||||||
|                     elif self.current_selection == (len(self.menu_items)-1) and not self.cycle: |                     elif self.current_selection == (len(self.menu_items)-1) and not self.cycle:  # ...as before but with the last element -> you can't go further | ||||||
|                         self.lcd.putstr(" "+chr(0)) |                         self.lcd.putstr(" "+chr(0)) | ||||||
|                     else: |                     else:  # ...or anything else (cycling or in the middle -> you can go in both directions | ||||||
|                         self.lcd.putstr(" "+chr(2)) |                         self.lcd.putstr(" "+chr(2)) | ||||||
|                 elif self.current_selection == 0 and not self.cycle:  # first item selected and no cycling |                 elif self.current_selection == 0 and not self.cycle:  # first item selected and no cycling | ||||||
|                     self.lcd.putstr("  ")  # leave the line with spaces |                     self.lcd.putstr("  ")  # leave the line with spaces | ||||||
| @@ -190,7 +187,7 @@ class lcdMenu: | |||||||
|         return_value = selection[1]() |         return_value = selection[1]() | ||||||
|          |          | ||||||
|         # show a exit when there's no specific return value |         # show a exit when there's no specific return value | ||||||
|         if not return_value:  # if the return value is None / nothing was returned |         if not return_value:  # if the return value is None / nothing was returned -> show a closing message | ||||||
|             while self.ok_btn.value() == 1: time.sleep(self.debounce_time)  # wait till ok_btn release (e.g. if the "program" is a simple send action) |             while self.ok_btn.value() == 1: time.sleep(self.debounce_time)  # wait till ok_btn release (e.g. if the "program" is a simple send action) | ||||||
|             self.lcd.move_to(0,0) |             self.lcd.move_to(0,0) | ||||||
|             if self.lcd.num_lines == 4: |             if self.lcd.num_lines == 4: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user