|
|
|
@ -22,7 +22,7 @@ struct InputEvent { |
|
|
|
|
union { |
|
|
|
|
struct { |
|
|
|
|
// Wheel delta
|
|
|
|
|
int8_t delta; |
|
|
|
|
int32_t delta; |
|
|
|
|
} wheel; |
|
|
|
|
struct { |
|
|
|
|
// Button state
|
|
|
|
@ -31,99 +31,206 @@ struct InputEvent { |
|
|
|
|
}; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
#define InputEvent_Wheel(delta_) ((struct InputEvent) { \ |
|
|
|
|
.kind = InputEventKind_Wheel, \
|
|
|
|
|
.wheel = { .delta = delta_ } \
|
|
|
|
|
}) |
|
|
|
|
static inline struct InputEvent InputEvent_Wheel(int32_t delta) |
|
|
|
|
{ |
|
|
|
|
return (struct InputEvent) { |
|
|
|
|
.kind = InputEventKind_Wheel, |
|
|
|
|
.wheel = {.delta = delta} |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define InputEvent_Button(state_) ((struct InputEvent) { \ |
|
|
|
|
.kind = InputEventKind_Button, \
|
|
|
|
|
.button = { .state = state_ }, \
|
|
|
|
|
}) |
|
|
|
|
/**
|
|
|
|
|
* Button event (push, release) |
|
|
|
|
* |
|
|
|
|
* @param state - pushed |
|
|
|
|
* @return event |
|
|
|
|
*/ |
|
|
|
|
static inline struct InputEvent InputEvent_Button(bool state) |
|
|
|
|
{ |
|
|
|
|
return (struct InputEvent) { |
|
|
|
|
.kind = InputEventKind_Button, |
|
|
|
|
.button = {.state = state}, |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
enum SceneEvent_Kind { |
|
|
|
|
// Close this scene.
|
|
|
|
|
// The scene is responsible for cleaning up 'private'.
|
|
|
|
|
// 'options' and the scene itself will be freed by the GUI engine.
|
|
|
|
|
SceneEventKind_Close, |
|
|
|
|
SceneEventKind_OpenChild, |
|
|
|
|
SceneEventKind_RequestRepaint, |
|
|
|
|
SceneEventKind_None, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// forward declaration
|
|
|
|
|
struct Scene; |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Scene event, returned from some scene methods. |
|
|
|
|
* |
|
|
|
|
* Use the constructor functions to create this struct. |
|
|
|
|
*/ |
|
|
|
|
struct SceneEvent { |
|
|
|
|
/** Event kind enum */ |
|
|
|
|
enum SceneEvent_Kind kind; |
|
|
|
|
union { |
|
|
|
|
/* data for Close event kind */ |
|
|
|
|
struct { |
|
|
|
|
// Status code
|
|
|
|
|
uint32_t status; |
|
|
|
|
int32_t status; |
|
|
|
|
// Return data on heap
|
|
|
|
|
void *data; |
|
|
|
|
} close; |
|
|
|
|
/* Data for Open event kind */ |
|
|
|
|
struct { |
|
|
|
|
// Scene (initialized, with options loaded in through the constructor)
|
|
|
|
|
void *scene; |
|
|
|
|
struct Scene *scene; |
|
|
|
|
// Tag used by parent to identify the open child
|
|
|
|
|
uint32_t tag; |
|
|
|
|
} open; |
|
|
|
|
}; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct Scene; |
|
|
|
|
|
|
|
|
|
#define SceneEvent_None() ((struct SceneEvent) { \ |
|
|
|
|
.kind = SceneEventKind_None\
|
|
|
|
|
}) |
|
|
|
|
/**
|
|
|
|
|
* Create empty (null object) scene event. |
|
|
|
|
* |
|
|
|
|
* @return event |
|
|
|
|
*/ |
|
|
|
|
static inline struct SceneEvent SceneEvent_None(void) |
|
|
|
|
{ |
|
|
|
|
return (struct SceneEvent) { |
|
|
|
|
.kind = SceneEventKind_None, |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define SceneEvent_Repaint() ((struct SceneEvent) { \ |
|
|
|
|
.kind = SceneEventKind_RequestRepaint\
|
|
|
|
|
}) |
|
|
|
|
/**
|
|
|
|
|
* Request scene repaint |
|
|
|
|
* |
|
|
|
|
* @return event |
|
|
|
|
*/ |
|
|
|
|
static inline struct SceneEvent SceneEvent_Repaint(void) |
|
|
|
|
{ |
|
|
|
|
return (struct SceneEvent) { |
|
|
|
|
.kind = SceneEventKind_RequestRepaint |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define SceneEvent_OpenChild(child_, tag_) ((struct SceneEvent) { \ |
|
|
|
|
.kind = SceneEventKind_OpenChild,\
|
|
|
|
|
.open = { .scene = (child_), .tag=tag_ }, \
|
|
|
|
|
}) |
|
|
|
|
/**
|
|
|
|
|
* Request a sub-scene to be opened |
|
|
|
|
* |
|
|
|
|
* @param child - child scene |
|
|
|
|
* @param tag - scene tag |
|
|
|
|
* @return event |
|
|
|
|
*/ |
|
|
|
|
static inline struct SceneEvent SceneEvent_OpenChild(struct Scene *child, uint32_t tag) { |
|
|
|
|
return (struct SceneEvent) { |
|
|
|
|
.kind = SceneEventKind_OpenChild, |
|
|
|
|
.open = { .scene = child, .tag=tag }, |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define SceneEvent_Close(status_, data_) ((struct SceneEvent) { \ |
|
|
|
|
.kind = SceneEventKind_Close,\
|
|
|
|
|
.close = { .status = (status_), .data=(data_) }, \
|
|
|
|
|
}) |
|
|
|
|
/**
|
|
|
|
|
* Close this scene, returning to parent. |
|
|
|
|
* |
|
|
|
|
* @param status - status number for the parent |
|
|
|
|
* @param data - heap-allocated data for parent, can be NULL; e.g. user input as string. |
|
|
|
|
* @return event |
|
|
|
|
*/ |
|
|
|
|
static inline struct SceneEvent SceneEvent_Close(int32_t status, void *data) |
|
|
|
|
{ |
|
|
|
|
return (struct SceneEvent) { |
|
|
|
|
.kind = SceneEventKind_Close, |
|
|
|
|
.close = {.status = status, .data=data}, |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Scene::onInput fp type - handle user input |
|
|
|
|
* |
|
|
|
|
* @param scene - self |
|
|
|
|
* @param event - the input event |
|
|
|
|
* @return follow-up scene event, can be SceneEvent_None() if not used. |
|
|
|
|
*/ |
|
|
|
|
typedef struct SceneEvent (*Scene_onInput_t)(struct Scene *scene, struct InputEvent event); |
|
|
|
|
typedef struct SceneEvent (*Scene_onChildReturn_t)(struct Scene *scene, uint32_t tag, uint32_t status, void *data); |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Scene::onChildReturn fp type |
|
|
|
|
* |
|
|
|
|
* @param scene - self |
|
|
|
|
* @param tag - child's tag |
|
|
|
|
* @param status - status code returned from the child |
|
|
|
|
* @param data - data returned from the child, must be heap-allocated if not NULL. |
|
|
|
|
* @return follow-up scene event, can be SceneEvent_None() if not used. |
|
|
|
|
*/ |
|
|
|
|
typedef struct SceneEvent (*Scene_onChildReturn_t)(struct Scene *scene, uint32_t tag, int32_t status, void *data); |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Scene::onTick fp type |
|
|
|
|
* |
|
|
|
|
* @param scene - self |
|
|
|
|
* @return follow-up scene event, can be SceneEvent_None() if not used. |
|
|
|
|
*/ |
|
|
|
|
typedef struct SceneEvent (*Scene_onTick_t)(struct Scene *scene); |
|
|
|
|
typedef void (*Scene_repaint_t)(struct Scene *scene); |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Scene::paint fp type |
|
|
|
|
* |
|
|
|
|
* @param scene - self |
|
|
|
|
*/ |
|
|
|
|
typedef void (*Scene_paint_t)(struct Scene *scene); |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Scene::free fp type. |
|
|
|
|
* Release internally allocated resources. |
|
|
|
|
* This is called by the GUI engine when the scene is closed. |
|
|
|
|
* |
|
|
|
|
* @param scene - self |
|
|
|
|
*/ |
|
|
|
|
typedef void (*Scene_free_t)(struct Scene *scene); |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Scene instance in the framework |
|
|
|
|
*/ |
|
|
|
|
struct Scene { |
|
|
|
|
/**
|
|
|
|
|
* Tag given to the scene by its parent to identify its close event. |
|
|
|
|
*/ |
|
|
|
|
uint32_t tag; |
|
|
|
|
void *options; |
|
|
|
|
void *private; |
|
|
|
|
/** Handle input */ |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handle input event. |
|
|
|
|
* Can return a follow-up scene event, e.g. repaint request. |
|
|
|
|
* Nullable field. |
|
|
|
|
*/ |
|
|
|
|
Scene_onInput_t onInput; |
|
|
|
|
/** Handle child scene return */ |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Child scene closed, handle its return value and data, if any. |
|
|
|
|
* Can return a follow-up scene event. |
|
|
|
|
* In any case, the scene will be re-painted, if it stays open and on top. |
|
|
|
|
* Nullable field. |
|
|
|
|
*/ |
|
|
|
|
Scene_onChildReturn_t onChildReturn; |
|
|
|
|
/** Periodic tick */ |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handle a periodic tick (10ms). |
|
|
|
|
* Can return a follow-up scene event, e.g. repaint request. |
|
|
|
|
* Nullable field. |
|
|
|
|
*/ |
|
|
|
|
Scene_onTick_t onTick; |
|
|
|
|
/** Periodic tick */ |
|
|
|
|
Scene_repaint_t paint; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Allocate scene and the inner private type. |
|
|
|
|
* |
|
|
|
|
* Requires <malloc.h> |
|
|
|
|
* |
|
|
|
|
* Must be used like: |
|
|
|
|
* |
|
|
|
|
* struct Scene *scene = SCENE_SAFE_ALLOC(struct private); |
|
|
|
|
* scene->onInput = ... |
|
|
|
|
* return scene; |
|
|
|
|
*/ |
|
|
|
|
#define SCENE_SAFE_ALLOC(private_type) \ |
|
|
|
|
calloc(1, sizeof(struct Scene)); \
|
|
|
|
|
if (!scene) return NULL; \
|
|
|
|
|
scene->private = calloc(1, sizeof(private_type)); \
|
|
|
|
|
if (!scene->private) return NULL; |
|
|
|
|
/**
|
|
|
|
|
* Draw the scene to the LCD buffer. |
|
|
|
|
* DO NOT write to the display yet, it will be done by the GUI engine. |
|
|
|
|
* |
|
|
|
|
* MANDATORY FIELD |
|
|
|
|
*/ |
|
|
|
|
Scene_paint_t paint; |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Release internally allocated resources, if any. Called on close. |
|
|
|
|
* Nullable field. |
|
|
|
|
*/ |
|
|
|
|
Scene_free_t free; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/** return 1 if repaint requested */ |
|
|
|
|
bool Liquid_handleInput(struct Liquid *container, struct InputEvent event); |
|
|
|
@ -131,7 +238,10 @@ bool Liquid_handleInput(struct Liquid *container, struct InputEvent event); |
|
|
|
|
/** return 1 if repaint requested */ |
|
|
|
|
bool Liquid_handleTick(struct Liquid *container); |
|
|
|
|
|
|
|
|
|
/** render the active scene */ |
|
|
|
|
void Liquid_paint(struct Liquid *container); |
|
|
|
|
struct Liquid *Liquid_start(); |
|
|
|
|
|
|
|
|
|
/** Initialize the GUI system with a root scene */ |
|
|
|
|
struct Liquid *Liquid_start(void); |
|
|
|
|
|
|
|
|
|
#endif //REFLOWER_LIQUID_H
|
|
|
|
|