add elapsed time to tick handler params, add generic scrollable menu
This commit is contained in:
@@ -2,27 +2,26 @@
|
||||
#include <stdio.h>
|
||||
#include <graphics/bitmaps.h>
|
||||
|
||||
#include "scenes.h"
|
||||
#include "liquid.h"
|
||||
#include "analog.h"
|
||||
#include "graphics/nokia.h"
|
||||
#include "graphics/drawing.h"
|
||||
|
||||
#define BOOTANIM_TIME_MS 100
|
||||
|
||||
struct BootScene {
|
||||
struct Scene base;
|
||||
uint32_t cnt;
|
||||
};
|
||||
|
||||
static struct SceneEvent Boot_onTick(struct BootScene *self) {
|
||||
self->cnt += 10; // ms
|
||||
if (self->cnt == 2000) {
|
||||
static struct SceneEvent onTick(struct BootScene *self, uint32_t millis) {
|
||||
self->cnt += millis; // ms
|
||||
if (self->cnt >= BOOTANIM_TIME_MS) {
|
||||
return SceneEvent_Close(0, NULL);
|
||||
}
|
||||
|
||||
return SceneEvent_None();
|
||||
}
|
||||
|
||||
static void Boot_paint(struct BootScene *self)
|
||||
static void paint(struct BootScene *self)
|
||||
{
|
||||
LCD_clearDisplay(0);
|
||||
LCD_setBitmap(Bitmap_Get("boot_logo")->bytes);
|
||||
@@ -30,7 +29,7 @@ static void Boot_paint(struct BootScene *self)
|
||||
|
||||
struct Scene *NewScene_Boot(void) {
|
||||
struct BootScene *scene = calloc(1, sizeof(struct BootScene));
|
||||
scene->base.paint = (Scene_paint_t) Boot_paint;
|
||||
scene->base.onTick = (Scene_onTick_t) Boot_onTick;
|
||||
scene->base.paint = (Scene_paint_t) paint;
|
||||
scene->base.onTick = (Scene_onTick_t) onTick;
|
||||
return (struct Scene *) scene;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ struct CarScene {
|
||||
int32_t pos;
|
||||
};
|
||||
|
||||
static struct SceneEvent Car_onInput(struct CarScene *self, struct InputEvent event) {
|
||||
static struct SceneEvent onInput(struct CarScene *self, struct InputEvent event) {
|
||||
switch (event.kind) {
|
||||
case InputEventKind_Wheel:
|
||||
self->pos += event.wheel.delta;
|
||||
@@ -27,7 +27,7 @@ static struct SceneEvent Car_onInput(struct CarScene *self, struct InputEvent ev
|
||||
}
|
||||
}
|
||||
|
||||
static void Car_paint(struct CarScene *self)
|
||||
static void paint(struct CarScene *self)
|
||||
{
|
||||
LCD_clearDisplay(0);
|
||||
LCD_setRect(self->pos, LCD_HEIGHT/2-10, self->pos+20,LCD_HEIGHT/2+10,0,1);
|
||||
@@ -38,7 +38,7 @@ struct Scene *NewScene_Car(void) {
|
||||
struct CarScene *scene = calloc(1, sizeof(struct CarScene));
|
||||
if (!scene) return NULL;
|
||||
|
||||
scene->base.onInput = (Scene_onInput_t) Car_onInput;
|
||||
scene->base.paint = (Scene_paint_t) Car_paint;
|
||||
scene->base.onInput = (Scene_onInput_t) onInput;
|
||||
scene->base.paint = (Scene_paint_t) paint;
|
||||
return (struct Scene *) scene;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ struct DemoScene {
|
||||
uint32_t timer_prescale;
|
||||
};
|
||||
|
||||
static struct SceneEvent Demo_onInput(struct DemoScene *self, struct InputEvent event) {
|
||||
static struct SceneEvent onInput(struct DemoScene *self, struct InputEvent event) {
|
||||
switch (event.kind) {
|
||||
case InputEventKind_Wheel:
|
||||
self->pos += event.wheel.delta;
|
||||
@@ -35,11 +35,11 @@ static struct SceneEvent Demo_onInput(struct DemoScene *self, struct InputEvent
|
||||
return SceneEvent_Repaint();
|
||||
}
|
||||
|
||||
static struct SceneEvent Demo_onTick(struct DemoScene *self) {
|
||||
static struct SceneEvent onTick(struct DemoScene *self, uint32_t millis) {
|
||||
// top text anim
|
||||
self->timer_prescale += 1;
|
||||
self->timer_prescale += millis;
|
||||
|
||||
if (self->timer_prescale == 100) {
|
||||
if (self->timer_prescale == 1000) {
|
||||
self->timer_prescale = 0;
|
||||
self->timer_phase += 1;
|
||||
self->timer_phase = self->timer_phase & 0b11; // 0..3
|
||||
@@ -50,7 +50,7 @@ static struct SceneEvent Demo_onTick(struct DemoScene *self) {
|
||||
return SceneEvent_None();
|
||||
}
|
||||
|
||||
static void Demo_paint(struct DemoScene *self)
|
||||
static void paint(struct DemoScene *self)
|
||||
{
|
||||
LCD_clearDisplay(0);
|
||||
|
||||
@@ -85,8 +85,9 @@ static void Demo_paint(struct DemoScene *self)
|
||||
struct Scene *NewScene_Demo(void) {
|
||||
struct DemoScene *scene = calloc(1, sizeof(struct DemoScene));
|
||||
|
||||
scene->base.onInput = (Scene_onInput_t) Demo_onInput;
|
||||
scene->base.paint = (Scene_paint_t) Demo_paint;
|
||||
scene->base.onTick = (Scene_onTick_t) Demo_onTick;
|
||||
scene->base.onInput = (Scene_onInput_t) onInput;
|
||||
scene->base.paint = (Scene_paint_t) paint;
|
||||
scene->base.onTick = (Scene_onTick_t) onTick;
|
||||
scene->base.onInput = (Scene_onInput_t) onInput;
|
||||
return (struct Scene *) scene;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
#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 "scene_menu.h"
|
||||
|
||||
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 + 6); 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));
|
||||
}
|
||||
}
|
||||
|
||||
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 >= 5 && self->scroll_up < self->items_len - 6) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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->items = items;
|
||||
scene->items_len = items_len;
|
||||
|
||||
return scene;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* TODO file description
|
||||
*
|
||||
* Created on 2020/01/05.
|
||||
*/
|
||||
|
||||
#ifndef REFLOWER_SCENE_MENU_H
|
||||
#define REFLOWER_SCENE_MENU_H
|
||||
|
||||
#define MENUITEM_LABEL_LEN 30
|
||||
|
||||
struct MenuItem {
|
||||
char label[MENUITEM_LABEL_LEN];
|
||||
uint32_t tag;
|
||||
};
|
||||
|
||||
struct MenuScene;
|
||||
|
||||
typedef struct SceneEvent (*MenuScene_onSelect_t)(struct MenuScene *scene);
|
||||
|
||||
struct MenuScene {
|
||||
struct Scene base;
|
||||
// items array
|
||||
struct MenuItem *items;
|
||||
// items count
|
||||
size_t items_len;
|
||||
// Vertical scroll offset (how many steps is the topmost item moved above the screen)
|
||||
int32_t scroll_up;
|
||||
// Selected item number
|
||||
int32_t selected;
|
||||
// selection handler
|
||||
MenuScene_onSelect_t onSelect;
|
||||
};
|
||||
|
||||
struct MenuScene *NewScene_Menu(struct MenuItem *items, size_t items_len);
|
||||
|
||||
#endif //REFLOWER_SCENE_MENU_H
|
||||
@@ -16,29 +16,34 @@ struct RootScene {
|
||||
struct Scene base;
|
||||
};
|
||||
|
||||
static struct SceneEvent Root_init(struct RootScene *self)
|
||||
static struct SceneEvent init(struct RootScene *self)
|
||||
{
|
||||
return SceneEvent_OpenChild(NewScene_Boot(), 1);
|
||||
}
|
||||
|
||||
struct SceneEvent Root_onChildReturn(
|
||||
struct RootScene *self,
|
||||
uint32_t tag,
|
||||
int32_t status,
|
||||
void *data)
|
||||
struct SceneEvent onChildReturn(struct RootScene *self, uint32_t tag, int32_t status, void *data)
|
||||
{
|
||||
if (tag == 1) {
|
||||
return SceneEvent_OpenChild(NewScene_Demo(), 0);
|
||||
return SceneEvent_OpenChild(NewScene_MenuTest(), 0);
|
||||
}
|
||||
|
||||
// this should be unreachable
|
||||
return SceneEvent_None();
|
||||
}
|
||||
|
||||
static void paint(struct Scene *self)
|
||||
{
|
||||
LCD_clearDisplay(0);
|
||||
|
||||
LCD_setStrEx("Press DEL to enter setup", 0, 0, 1, 0x3);
|
||||
}
|
||||
|
||||
struct Scene *NewScene_Root(void) {
|
||||
struct RootScene *scene = calloc(1, sizeof(struct RootScene));
|
||||
|
||||
scene->base.init = (Scene_init_t) Root_init;
|
||||
scene->base.onChildReturn = (Scene_onChildReturn_t) Root_onChildReturn;
|
||||
scene->base.init = (Scene_init_t) init;
|
||||
scene->base.onChildReturn = (Scene_onChildReturn_t) onChildReturn;
|
||||
scene->base.paint = paint;
|
||||
|
||||
return (struct Scene *) scene;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
#include <malloc.h>
|
||||
#include <graphics/bitmaps.h>
|
||||
#include <sys/param.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "liquid.h"
|
||||
#include "graphics/drawing.h"
|
||||
|
||||
#include "scenes.h"
|
||||
#include "scene_menu.h"
|
||||
|
||||
|
||||
static struct SceneEvent onSelect(struct MenuScene *self) {
|
||||
if (self->selected == 0) {
|
||||
return SceneEvent_Close(0, NULL);
|
||||
}
|
||||
|
||||
if (self->selected == 8) {
|
||||
return SceneEvent_OpenChild(NewScene_Car(), 0);
|
||||
}
|
||||
if (self->selected == 9) {
|
||||
return SceneEvent_OpenChild(NewScene_Demo(), 0);
|
||||
}
|
||||
if (self->selected == 5) {
|
||||
self->items[5].tag++;
|
||||
snprintf(self->items[5].label, MENUITEM_LABEL_LEN, "Count = %d", self->items[5].tag);
|
||||
return SceneEvent_Repaint();
|
||||
}
|
||||
|
||||
return SceneEvent_None();
|
||||
}
|
||||
|
||||
struct Scene *NewScene_MenuTest() {
|
||||
struct MenuItem *items = calloc(10, sizeof(struct MenuItem));
|
||||
|
||||
strncpy(items[0].label, "🔙Back", MENUITEM_LABEL_LEN);
|
||||
strncpy(items[1].label, "▶#1", MENUITEM_LABEL_LEN);
|
||||
strncpy(items[2].label, "▶#2", MENUITEM_LABEL_LEN);
|
||||
strncpy(items[3].label, "▶#3", MENUITEM_LABEL_LEN);
|
||||
strncpy(items[4].label, "▶#4", MENUITEM_LABEL_LEN);
|
||||
strncpy(items[5].label, "Count = 0", MENUITEM_LABEL_LEN);
|
||||
strncpy(items[6].label, "▶#6", MENUITEM_LABEL_LEN);
|
||||
strncpy(items[7].label, "▶#7", MENUITEM_LABEL_LEN);
|
||||
strncpy(items[8].label, "Car", MENUITEM_LABEL_LEN);
|
||||
strncpy(items[9].label, "Demo Scene", MENUITEM_LABEL_LEN);
|
||||
|
||||
struct MenuScene * scene = NewScene_Menu(items, 10);
|
||||
scene->onSelect = onSelect;
|
||||
|
||||
return (struct Scene *) scene;
|
||||
}
|
||||
@@ -12,4 +12,6 @@ struct Scene *NewScene_Boot(void);
|
||||
struct Scene *NewScene_Demo(void);
|
||||
struct Scene *NewScene_Car(void);
|
||||
|
||||
struct Scene *NewScene_MenuTest(void);
|
||||
|
||||
#endif //REFLOWER_SCENES_H
|
||||
|
||||
Reference in New Issue
Block a user