You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							103 lines
						
					
					
						
							2.9 KiB
						
					
					
				
			
		
		
	
	
							103 lines
						
					
					
						
							2.9 KiB
						
					
					
				| #include <malloc.h>
 | |
| #include <graphics/bitmaps.h>
 | |
| #include <sys/param.h>
 | |
| #include <stdbool.h>
 | |
| #include <liquid/input_event.h>
 | |
| 
 | |
| #include "liquid.h"
 | |
| #include "graphics/drawing.h"
 | |
| #include "graphics/display_spec.h"
 | |
| 
 | |
| #include "scene_menu.h"
 | |
| 
 | |
| #if 0
 | |
| static void paint(struct MenuScene *self)
 | |
| {
 | |
|     LCD_clearDisplay(0);
 | |
| 
 | |
|     int row = 0;
 | |
|     for (int i = self->scroll_up; i < MIN(self->items_len, self->scroll_up + self->visible_lines); i++, row++) {
 | |
|         bool selected = self->selected==i;
 | |
|         LCD_setStrEx(self->items[i].label, 0, row * 8, selected?WHITE:BLACK,FONT_NORMAL|(selected?FONT_BG:0));
 | |
|     }
 | |
| }
 | |
| #endif
 | |
| 
 | |
| static void paint(struct MenuScene *self)
 | |
| {
 | |
|     LCD_clearDisplay(0);
 | |
| 
 | |
|     int row = 0;
 | |
|     for (int i = self->scroll_up; i < MIN(self->items_len, self->scroll_up + self->visible_lines); i++, row++) {
 | |
|         bool selected = self->selected==i;
 | |
|         if (selected) LCD_setRect(0, row*9, LCD_WIDTH-1, row*9 + 8, 1, 1);
 | |
|         LCD_setStrEx(self->items[i].label, 1, row * 9 + 1, !selected, (struct TextStyle) {
 | |
|             .bg = selected,
 | |
|             .max_chars = 13,
 | |
|         });
 | |
|     }
 | |
| }
 | |
| 
 | |
| static struct SceneEvent onInput(struct MenuScene *self, struct InputEvent event) {
 | |
|     switch (event.kind) {
 | |
|         case InputEventKind_Wheel:;
 | |
|             self->selected += event.wheel.direction;
 | |
|             if (self->selected < 0) {
 | |
|                 self->selected = 0;
 | |
|             }
 | |
|             else if (self->selected >= self->items_len) {
 | |
|                 self->selected = self->items_len - 1;
 | |
|             }
 | |
| 
 | |
|             // hacky scroll adjust
 | |
|             while (self->selected - self->scroll_up < 1 && self->scroll_up > 0) {
 | |
|                 self->scroll_up--;
 | |
|             }
 | |
| 
 | |
|             while (self->selected - self->scroll_up >= (self->visible_lines - 1) && self->scroll_up < self->items_len - self->visible_lines) {
 | |
|                 self->scroll_up++;
 | |
|             }
 | |
| 
 | |
|             return SceneEvent_Repaint();
 | |
| 
 | |
|         case InputEventKind_Button:
 | |
|             if (event.button.state) {
 | |
|                 if (self->onSelect) {
 | |
|                     return self->onSelect(self);
 | |
|                 }
 | |
|                 return SceneEvent_Close(0, NULL);
 | |
|             }
 | |
|             // fall through
 | |
|         default:
 | |
|             return SceneEvent_None();
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void deinit(struct MenuScene *self)
 | |
| {
 | |
|     free(self->items);
 | |
|     self->items = NULL;
 | |
| 
 | |
|     if (self->extra_deinit) {
 | |
|         self->extra_deinit((struct Scene *) self);
 | |
|         self->extra = NULL;
 | |
|     }
 | |
| }
 | |
| 
 | |
| struct MenuScene *NewScene_Menu(struct MenuItem *items, size_t items_len) {
 | |
|     struct MenuScene *scene = calloc(1, sizeof(struct MenuScene));
 | |
| 
 | |
|     scene->base.paint = (Scene_paint_t) paint;
 | |
|     scene->base.onInput = (Scene_onInput_t) onInput;
 | |
|     scene->base.deinit = (Scene_deinit_t) deinit;
 | |
| 
 | |
|     // onChildReturn is free to set by subclass
 | |
| 
 | |
|     // TODO long selected label scrolling on tick
 | |
| 
 | |
|     scene->visible_lines = 5;
 | |
|     scene->items = items;
 | |
|     scene->items_len = items_len;
 | |
| 
 | |
|     return scene;
 | |
| }
 | |
| 
 |