Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd689841bb
|
@@ -8,6 +8,7 @@ set(COMPONENT_SRCS
|
|||||||
"scenes/scene_bootanim.c"
|
"scenes/scene_bootanim.c"
|
||||||
"scenes/scene_menu.c"
|
"scenes/scene_menu.c"
|
||||||
"scenes/scene_number.c"
|
"scenes/scene_number.c"
|
||||||
|
"scenes/scene_string.c"
|
||||||
"scenes/scene_manual_menu.c"
|
"scenes/scene_manual_menu.c"
|
||||||
"scenes/scene_popup_menu.c"
|
"scenes/scene_popup_menu.c"
|
||||||
"scenes/scene_popup_test.c"
|
"scenes/scene_popup_test.c"
|
||||||
|
|||||||
+2
-2
@@ -82,12 +82,12 @@ static void __attribute__((noreturn)) analog_service(void *arg) {
|
|||||||
#define CORRECT -10;
|
#define CORRECT -10;
|
||||||
mv += CORRECT;
|
mv += CORRECT;
|
||||||
|
|
||||||
printf("Raw: %d ... Voltage: %dmV ...", adc_reading, mv);
|
// printf("Raw: %d ... Voltage: %dmV ...", adc_reading, mv);
|
||||||
|
|
||||||
float volts = mv * 0.001f;
|
float volts = mv * 0.001f;
|
||||||
|
|
||||||
float celsius = v_to_c(volts);
|
float celsius = v_to_c(volts);
|
||||||
printf("Celsius: %.1f°C\n", celsius);
|
// printf("Celsius: %.1f°C\n", celsius);
|
||||||
|
|
||||||
measurement_celsius = celsius;
|
measurement_celsius = celsius;
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -90,7 +90,7 @@ void fire_regulate(float cels) {
|
|||||||
if (pid.ctlMode == PID_MANUAL) {
|
if (pid.ctlMode == PID_MANUAL) {
|
||||||
pwm_set(0);
|
pwm_set(0);
|
||||||
} else {
|
} else {
|
||||||
printf("PID in %.2f°C, out %.3f, I %.3f\n", cels, pid.Output, pid.ITerm);
|
// printf("PID in %.2f°C, out %.3f, I %.3f\n", cels, pid.Output, pid.ITerm);
|
||||||
pwm_set(pid.Output);
|
pwm_set(pid.Output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,7 +126,7 @@ static void pwm_set(float duty)
|
|||||||
{
|
{
|
||||||
uint32_t max_duty = (1 << PWM_BIT_NUM);// - 1
|
uint32_t max_duty = (1 << PWM_BIT_NUM);// - 1
|
||||||
uint32_t dutycycle = lroundf((duty) * (float)max_duty);
|
uint32_t dutycycle = lroundf((duty) * (float)max_duty);
|
||||||
printf("Dutycycle %d\n", dutycycle);
|
// printf("Dutycycle %d\n", dutycycle);
|
||||||
|
|
||||||
ESP_ERROR_CHECK( ledc_set_duty(LEDC_HIGH_SPEED_MODE, PWM_CHANNEL, dutycycle) );
|
ESP_ERROR_CHECK( ledc_set_duty(LEDC_HIGH_SPEED_MODE, PWM_CHANNEL, dutycycle) );
|
||||||
ESP_ERROR_CHECK( ledc_update_duty(LEDC_HIGH_SPEED_MODE, PWM_CHANNEL) );
|
ESP_ERROR_CHECK( ledc_update_duty(LEDC_HIGH_SPEED_MODE, PWM_CHANNEL) );
|
||||||
|
|||||||
@@ -61,8 +61,8 @@ struct TextStyle {
|
|||||||
bool bg; //!< Fill the characters background with the opposite color
|
bool bg; //!< Fill the characters background with the opposite color
|
||||||
enum TextSize size; //!< Character size
|
enum TextSize size; //!< Character size
|
||||||
enum TextAlign align; //!< Alignment (works only for single line)
|
enum TextAlign align; //!< Alignment (works only for single line)
|
||||||
int limit; //!< Number of characters to print from the string, if > 0
|
size_t limit; //!< Number of characters to print from the string, if > 0
|
||||||
int skip; //!< Characters to skip before printing
|
size_t skip; //!< Characters to skip before printing
|
||||||
int spacing_x; //!< Additional X spacing
|
int spacing_x; //!< Additional X spacing
|
||||||
int spacing_y; //!< Additional Y spacing
|
int spacing_y; //!< Additional Y spacing
|
||||||
bool nowrap; //!< Stop painting when the right edge of the screen is reached
|
bool nowrap; //!< Stop painting when the right edge of the screen is reached
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
#include "graphics/display_spec.h"
|
#include "graphics/display_spec.h"
|
||||||
|
|
||||||
#include "scenes.h"
|
#include "scenes.h"
|
||||||
#include "scene_menu.h"
|
|
||||||
|
|
||||||
struct Priv {
|
struct Priv {
|
||||||
int _placeholder;
|
int _placeholder;
|
||||||
@@ -35,6 +34,16 @@ static struct SceneEvent onSelect(struct MenuScene *self) {
|
|||||||
else if (self->selected == 2) {
|
else if (self->selected == 2) {
|
||||||
return SceneEvent_OpenChild(NewScene_PopupTest(), 1);
|
return SceneEvent_OpenChild(NewScene_PopupTest(), 1);
|
||||||
}
|
}
|
||||||
|
else if (self->selected == 3) {
|
||||||
|
struct StringSceneOpts *opts = calloc(1, sizeof(struct StringSceneOpts));
|
||||||
|
strcpy(opts->value, "");
|
||||||
|
return SceneEvent_OpenChild(NewScene_String(opts), 1);
|
||||||
|
}
|
||||||
|
else if (self->selected == 4) {
|
||||||
|
struct StringSceneOpts *opts = calloc(1, sizeof(struct StringSceneOpts));
|
||||||
|
strcpy(opts->value, "AHOJ");
|
||||||
|
return SceneEvent_OpenChild(NewScene_String(opts), 1);
|
||||||
|
}
|
||||||
|
|
||||||
return SceneEvent_None();
|
return SceneEvent_None();
|
||||||
}
|
}
|
||||||
@@ -65,6 +74,8 @@ void print_labels(struct MenuItem *items) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
strncpy(items[2].label, "▶Item with popup", MENUITEM_LABEL_LEN);
|
strncpy(items[2].label, "▶Item with popup", MENUITEM_LABEL_LEN);
|
||||||
|
strncpy(items[3].label, "▶Empty str", MENUITEM_LABEL_LEN);
|
||||||
|
strncpy(items[4].label, "▶Filled str", MENUITEM_LABEL_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void paint(struct MenuScene *self)
|
static void paint(struct MenuScene *self)
|
||||||
@@ -94,11 +105,11 @@ static void paint(struct MenuScene *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Scene *NewScene_MenuManual() {
|
struct Scene *NewScene_MenuManual() {
|
||||||
struct MenuItem *items = calloc(3, sizeof(struct MenuItem));
|
struct MenuItem *items = calloc(5, sizeof(struct MenuItem));
|
||||||
|
|
||||||
print_labels(items);
|
print_labels(items);
|
||||||
|
|
||||||
struct MenuScene * scene = NewScene_Menu(items, 3);
|
struct MenuScene * scene = NewScene_Menu(items, 5);
|
||||||
scene->onSelect = onSelect;
|
scene->onSelect = onSelect;
|
||||||
|
|
||||||
scene->x = XLINE;
|
scene->x = XLINE;
|
||||||
|
|||||||
@@ -0,0 +1,209 @@
|
|||||||
|
#include <malloc.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <common_utils/utils.h>
|
||||||
|
|
||||||
|
#include "liquid.h"
|
||||||
|
#include "liquid/input_event.h"
|
||||||
|
#include "graphics/drawing.h"
|
||||||
|
#include "graphics/display_spec.h"
|
||||||
|
#include "scene_string.h"
|
||||||
|
|
||||||
|
enum Focus {
|
||||||
|
FOC_CHAR,
|
||||||
|
FOC_CHAR_EDIT,
|
||||||
|
FOC_SUBMIT,
|
||||||
|
FOC_CANCEL,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StringScene {
|
||||||
|
struct Scene base;
|
||||||
|
struct StringSceneOpts *opts;
|
||||||
|
int editedchar;
|
||||||
|
int length;
|
||||||
|
enum Focus foc;
|
||||||
|
};
|
||||||
|
|
||||||
|
// !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
|
||||||
|
const char SYMBOLS[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
|
|
||||||
|
static void onWheel(struct StringScene *self, struct InputEvent event);
|
||||||
|
static struct SceneEvent onButton(struct StringScene *self, struct InputEvent event);
|
||||||
|
|
||||||
|
static void ensureCharNotNull(struct StringScene *self);
|
||||||
|
static void trimTailSpaces(struct StringScene *self);
|
||||||
|
|
||||||
|
static struct SceneEvent onInput(struct StringScene *self, struct InputEvent event) {
|
||||||
|
switch (event.kind) {
|
||||||
|
case InputEventKind_Wheel:
|
||||||
|
onWheel(self, event);
|
||||||
|
return SceneEvent_Repaint();
|
||||||
|
case InputEventKind_Button:
|
||||||
|
return onButton(self, event);
|
||||||
|
default:
|
||||||
|
return SceneEvent_None();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct SceneEvent onButton(struct StringScene *self, struct InputEvent event)
|
||||||
|
{
|
||||||
|
if (event.button.state) {
|
||||||
|
switch (self->foc) {
|
||||||
|
case FOC_CHAR:
|
||||||
|
printf("start char edit\n");
|
||||||
|
self->foc = FOC_CHAR_EDIT;
|
||||||
|
ensureCharNotNull(self);
|
||||||
|
return SceneEvent_Repaint();
|
||||||
|
|
||||||
|
case FOC_CHAR_EDIT:
|
||||||
|
if (self->editedchar == self->length) {
|
||||||
|
printf("submit last char\n");
|
||||||
|
|
||||||
|
if (self->opts->value[self->editedchar] == ' ') {
|
||||||
|
printf("empty, go to -> submit\n");
|
||||||
|
self->foc = FOC_SUBMIT;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("not empty, advance and keep editing\n");
|
||||||
|
self->length += 1;
|
||||||
|
self->editedchar += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("exit char edit\n");
|
||||||
|
self->foc = FOC_CHAR;
|
||||||
|
}
|
||||||
|
return SceneEvent_Repaint();
|
||||||
|
|
||||||
|
case FOC_SUBMIT:
|
||||||
|
return SceneEvent_Close(1, NULL); // TODO copy str
|
||||||
|
case FOC_CANCEL:
|
||||||
|
return SceneEvent_Close(0, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SceneEvent_None();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void onWheel(struct StringScene *self, struct InputEvent event)
|
||||||
|
{
|
||||||
|
switch (self->foc) {
|
||||||
|
case FOC_CHAR:
|
||||||
|
self->editedchar += event.wheel.direction;
|
||||||
|
printf("Move cursor %d\n", event.wheel.direction);
|
||||||
|
|
||||||
|
if (self->editedchar < 0) {
|
||||||
|
self->editedchar = 0;
|
||||||
|
self->foc = FOC_CANCEL;
|
||||||
|
printf("chars -> cancel\n");
|
||||||
|
}
|
||||||
|
else if (self->editedchar > self->length) {
|
||||||
|
self->editedchar = self->length;
|
||||||
|
self->foc = FOC_SUBMIT;
|
||||||
|
printf("chars -> submit\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("move within chars\n");
|
||||||
|
ensureCharNotNull(self);
|
||||||
|
}
|
||||||
|
trimTailSpaces(self);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FOC_CHAR_EDIT:;
|
||||||
|
// FIXME this looks buggy
|
||||||
|
const char *pos = strchr(SYMBOLS, self->opts->value[self->editedchar]) + event.wheel.direction;
|
||||||
|
if (pos < SYMBOLS) {
|
||||||
|
pos = SYMBOLS + strlen(SYMBOLS) - 1;
|
||||||
|
} else if (*pos == 0) {
|
||||||
|
pos = SYMBOLS;
|
||||||
|
}
|
||||||
|
self->opts->value[self->editedchar] = *pos;
|
||||||
|
printf("char %d change: %c\n", self->editedchar, *pos);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FOC_SUBMIT:
|
||||||
|
if (event.wheel.direction > 0) {
|
||||||
|
printf("submit -> cancel\n");
|
||||||
|
self->foc = FOC_CANCEL;
|
||||||
|
} else {
|
||||||
|
printf("submit -> last char\n");
|
||||||
|
self->foc = FOC_CHAR;
|
||||||
|
self->editedchar = self->length;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FOC_CANCEL:
|
||||||
|
if (event.wheel.direction > 0) {
|
||||||
|
printf("cancel -> first char\n");
|
||||||
|
self->foc = FOC_CHAR;
|
||||||
|
self->editedchar = 0;
|
||||||
|
} else {
|
||||||
|
printf("cancel -> submit\n");
|
||||||
|
self->foc = FOC_SUBMIT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void paint(struct StringScene *self)
|
||||||
|
{
|
||||||
|
struct StringSceneOpts *opts = self->opts;
|
||||||
|
LCD_clearDisplay(0);
|
||||||
|
|
||||||
|
ensureCharNotNull(self);
|
||||||
|
|
||||||
|
LCD_setStrEx(opts->value, 1, 1, BLACK, (struct TextStyle) {
|
||||||
|
.limit = MAX(self->editedchar+1, self->length),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (self->foc == FOC_CHAR) {
|
||||||
|
LCD_setRect(self->editedchar*6, 8, self->editedchar*6+5, 8, false, BLACK);
|
||||||
|
} else if (self->foc == FOC_CHAR_EDIT) {
|
||||||
|
LCD_setRect(self->editedchar*6, 8, self->editedchar*6+5, 9, false, BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
LCD_setStrEx("Ok", 50, 15, self->foc == FOC_SUBMIT ? WHITE : BLACK, (struct TextStyle) {.size = FONT_BOLD, .bg=1});
|
||||||
|
LCD_setStrEx("Cancel", 1, 15, self->foc == FOC_CANCEL ? WHITE : BLACK, (struct TextStyle) {.size = FONT_BOLD, .bg=1});
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ensureCharNotNull(struct StringScene *self)
|
||||||
|
{
|
||||||
|
struct StringSceneOpts *opts = self->opts;
|
||||||
|
// ensure there is something to draw
|
||||||
|
if (!opts->value[self->editedchar]) {
|
||||||
|
opts->value[self->editedchar] = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void trimTailSpaces(struct StringScene *self)
|
||||||
|
{
|
||||||
|
int pos = self->length;
|
||||||
|
while (pos > 0 && self->opts->value[pos - 1] == ' ') {
|
||||||
|
pos--;
|
||||||
|
}
|
||||||
|
self->length = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deinit(struct StringScene *self)
|
||||||
|
{
|
||||||
|
free(self->opts);
|
||||||
|
self->opts = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Scene *NewScene_String(struct StringSceneOpts *opts) {
|
||||||
|
struct StringScene *scene = calloc(1, sizeof(struct StringScene));
|
||||||
|
if (!scene) return NULL;
|
||||||
|
|
||||||
|
scene->opts = opts;
|
||||||
|
scene->base.onInput = (Scene_onInput_t) onInput;
|
||||||
|
scene->base.paint = (Scene_paint_t) paint;
|
||||||
|
scene->base.deinit = (Scene_deinit_t) deinit;
|
||||||
|
|
||||||
|
scene->length = strlen(opts->value);
|
||||||
|
scene->foc = scene->length==0? FOC_CHAR_EDIT : FOC_CHAR;
|
||||||
|
scene->editedchar = 0;
|
||||||
|
|
||||||
|
ensureCharNotNull(scene);
|
||||||
|
|
||||||
|
return (struct Scene *) scene;
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* TODO file description
|
||||||
|
*
|
||||||
|
* Created on 2020/01/05.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef REFLOWER_SCENE_STR_H
|
||||||
|
#define REFLOWER_SCENE_STR_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define STR_EDIT_VALUE_MAXLEN 17
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options passed to the StringScene constructor
|
||||||
|
*/
|
||||||
|
struct StringSceneOpts {
|
||||||
|
// Screen title
|
||||||
|
char label[15];
|
||||||
|
// Value
|
||||||
|
char value[STR_EDIT_VALUE_MAXLEN];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create string picker.
|
||||||
|
*
|
||||||
|
* "opts" must be on heap and will be internally mutated.
|
||||||
|
* The scene frees them on exit, returning the selected value as data (heap string), or NULL on cancel.
|
||||||
|
*
|
||||||
|
* @param opts
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
struct Scene *NewScene_String(struct StringSceneOpts *opts);
|
||||||
|
|
||||||
|
#endif //REFLOWER_SCENE_STR_H
|
||||||
@@ -17,6 +17,7 @@ struct Scene *NewScene_PopupTest();
|
|||||||
|
|
||||||
#include "scene_menu.h"
|
#include "scene_menu.h"
|
||||||
#include "scene_number.h"
|
#include "scene_number.h"
|
||||||
|
#include "scene_string.h"
|
||||||
|
|
||||||
struct MenuScene *NewScene_PopupMenu(struct MenuItem *items, size_t items_len);
|
struct MenuScene *NewScene_PopupMenu(struct MenuItem *items, size_t items_len);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user