mirror of
https://github.com/Ralim/IronOS.git
synced 2025-07-23 20:30:38 +02:00
Compare commits
9 Commits
3496c6c20b
...
Refactorin
Author | SHA1 | Date | |
---|---|---|---|
|
7a0308dbf4 | ||
|
c31fb5725b | ||
|
7535a64bc7 | ||
|
b599dec278 | ||
|
3a05d695f8 | ||
|
45639e5c23 | ||
|
da7dbd4b55 | ||
|
62fb6d5209 | ||
|
d9350fdc73 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -178,3 +178,4 @@ CoreCompileInputs.cache
|
|||||||
.vscode/settings.json
|
.vscode/settings.json
|
||||||
source/compile_commands.json
|
source/compile_commands.json
|
||||||
.idea/
|
.idea/
|
||||||
|
source/UI/layout_96x16.cpp
|
||||||
|
@@ -9,13 +9,13 @@ WORKDIR /build
|
|||||||
# musl-dev is required for the multi lang firmwares
|
# musl-dev is required for the multi lang firmwares
|
||||||
# clang is required for clang-format (for dev)
|
# clang is required for clang-format (for dev)
|
||||||
ARG APK_COMPS="gcc-riscv-none-elf gcc-arm-none-eabi newlib-riscv-none-elf \
|
ARG APK_COMPS="gcc-riscv-none-elf gcc-arm-none-eabi newlib-riscv-none-elf \
|
||||||
newlib-arm-none-eabi"
|
newlib-arm-none-eabi"
|
||||||
ARG APK_PYTHON="python3 py3-pip black"
|
ARG APK_PYTHON="python3 py3-pip black"
|
||||||
ARG APK_MISC="findutils make git"
|
ARG APK_MISC="findutils make git"
|
||||||
ARG APK_DEV="musl-dev clang bash clang-extra-tools"
|
ARG APK_DEV="musl-dev clang bash clang-extra-tools"
|
||||||
|
|
||||||
# PIP packages
|
# PIP packages
|
||||||
ARG PIP_PKGS='bdflib'
|
ARG PIP_PKGS='bdflib pyyaml'
|
||||||
|
|
||||||
RUN apk add --no-cache ${APK_COMPS} ${APK_PYTHON} ${APK_MISC} ${APK_DEV}
|
RUN apk add --no-cache ${APK_COMPS} ${APK_PYTHON} ${APK_MISC} ${APK_DEV}
|
||||||
|
|
||||||
|
@@ -169,6 +169,7 @@ void OLED::drawChar(const uint16_t charCode, const FontStyle fontStyle) {
|
|||||||
case FontStyle::SMALL:
|
case FontStyle::SMALL:
|
||||||
case FontStyle::LARGE:
|
case FontStyle::LARGE:
|
||||||
default:
|
default:
|
||||||
|
// TODO handle 4 lines
|
||||||
if (charCode == '\x01' && cursor_y == 0) { // 0x01 is used as new line char
|
if (charCode == '\x01' && cursor_y == 0) { // 0x01 is used as new line char
|
||||||
setCursor(0, 8);
|
setCursor(0, 8);
|
||||||
return;
|
return;
|
||||||
@@ -431,6 +432,57 @@ void OLED::setInverseDisplay(bool inverse) {
|
|||||||
OLED_Setup_Array[21].val = normalInverseCmd;
|
OLED_Setup_Array[21].val = normalInverseCmd;
|
||||||
I2C_CLASS::I2C_RegisterWrite(DEVICEADDR_OLED, 0x80, normalInverseCmd);
|
I2C_CLASS::I2C_RegisterWrite(DEVICEADDR_OLED, 0x80, normalInverseCmd);
|
||||||
}
|
}
|
||||||
|
void OLED::printBounded(const char *str, const uint8_t x, const uint8_t y, const uint8_t w, const uint8_t h, FontStyle fontStyle) {
|
||||||
|
setCursor(x, y);
|
||||||
|
|
||||||
|
const uint8_t *next = reinterpret_cast<const uint8_t *>(str);
|
||||||
|
// Determine font size by newline magic marker
|
||||||
|
if (fontStyle == FontStyle::FROM_TEXT) {
|
||||||
|
fontStyle = FontStyle::SMALL;
|
||||||
|
if (next[0] == 0x01) {
|
||||||
|
fontStyle = FontStyle::LARGE;
|
||||||
|
next++;
|
||||||
|
}
|
||||||
|
} else if (fontStyle == FontStyle::FROM_HEIGHT) {
|
||||||
|
if (h > get_fontstyle_height(FontStyle::SMALL)) {
|
||||||
|
fontStyle = FontStyle::LARGE;
|
||||||
|
} else {
|
||||||
|
fontStyle = FontStyle::SMALL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we walk and print
|
||||||
|
while (next[0]) {
|
||||||
|
uint16_t index;
|
||||||
|
if (next[0] <= 0xF0) {
|
||||||
|
index = next[0];
|
||||||
|
next++;
|
||||||
|
} else {
|
||||||
|
if (!next[1]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
index = (next[0] - 0xF0) * 0xFF - 15 + next[1];
|
||||||
|
next += 2;
|
||||||
|
}
|
||||||
|
if (index > 0x01) {
|
||||||
|
// Not a newline or terminator
|
||||||
|
// Need to make sure we clip
|
||||||
|
if (cursor_x >= (x + w)) {
|
||||||
|
// About to write out of bounds, wrap
|
||||||
|
if (fontStyle == FontStyle::SMALL) {
|
||||||
|
cursor_y += 8;
|
||||||
|
} else {
|
||||||
|
cursor_y += 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cursor_y >= y + h) {
|
||||||
|
// Clipping off bottom, yeet
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
drawChar(index, fontStyle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// print a string to the current cursor location, len chars MAX
|
// print a string to the current cursor location, len chars MAX
|
||||||
void OLED::print(const char *const str, FontStyle fontStyle, uint8_t len) {
|
void OLED::print(const char *const str, FontStyle fontStyle, uint8_t len) {
|
||||||
@@ -493,6 +545,25 @@ void OLED::drawHex(uint32_t x, FontStyle fontStyle, uint8_t digits) {
|
|||||||
drawChar(value + 2, fontStyle);
|
drawChar(value + 2, fontStyle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void OLED::printNumberBounded(const uint16_t num, bool noLeaderZeros, const uint8_t x, const uint8_t y, const uint8_t w, const uint8_t h) {
|
||||||
|
// Print the number to the screen, bounded by the given dimension
|
||||||
|
FontStyle fontStyle = get_fontstyle_fromHeight(h);
|
||||||
|
uint8_t places = w / get_fontstyle_width(fontStyle);
|
||||||
|
if (places > 5)
|
||||||
|
places = 5;
|
||||||
|
char buffer[7] = {0, 0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
uint16_t number = num;
|
||||||
|
|
||||||
|
for (int i = places; i >= 0; i--) {
|
||||||
|
buffer[i] = 2 /*Skew past null and newline*/ + number % 10;
|
||||||
|
number /= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (noLeaderZeros)
|
||||||
|
stripLeaderZeros(buffer, places);
|
||||||
|
printBounded(buffer, x, y, w, h, FontStyle::FROM_HEIGHT);
|
||||||
|
}
|
||||||
// maximum places is 5
|
// maximum places is 5
|
||||||
void OLED::printNumber(uint16_t number, uint8_t places, FontStyle fontStyle, bool noLeaderZeros) {
|
void OLED::printNumber(uint16_t number, uint8_t places, FontStyle fontStyle, bool noLeaderZeros) {
|
||||||
char buffer[7] = {0};
|
char buffer[7] = {0};
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#ifndef OLED_HPP_
|
#ifndef OLED_HPP_
|
||||||
#define OLED_HPP_
|
#define OLED_HPP_
|
||||||
#include "Font.h"
|
#include "Font.h"
|
||||||
|
#include "FontUtils.h"
|
||||||
#include "cmsis_os.h"
|
#include "cmsis_os.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include <BSP.h>
|
#include <BSP.h>
|
||||||
@@ -61,12 +62,6 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
#define FRAMEBUFFER_START 17
|
#define FRAMEBUFFER_START 17
|
||||||
|
|
||||||
enum class FontStyle {
|
|
||||||
SMALL,
|
|
||||||
LARGE,
|
|
||||||
EXTRAS,
|
|
||||||
};
|
|
||||||
|
|
||||||
class OLED {
|
class OLED {
|
||||||
public:
|
public:
|
||||||
enum DisplayState : bool { OFF = false, ON = true };
|
enum DisplayState : bool { OFF = false, ON = true };
|
||||||
@@ -106,8 +101,13 @@ public:
|
|||||||
static void setBrightness(uint8_t contrast);
|
static void setBrightness(uint8_t contrast);
|
||||||
static void setInverseDisplay(bool inverted);
|
static void setInverseDisplay(bool inverted);
|
||||||
static int16_t getCursorX() { return cursor_x; }
|
static int16_t getCursorX() { return cursor_x; }
|
||||||
static void print(const char *string, FontStyle fontStyle, uint8_t length = 255); // Draw a string to the current location, with selected font; optionally - with MAX length only
|
|
||||||
static void printWholeScreen(const char *string);
|
static void printBounded(const char *str, const uint8_t x, const uint8_t y, const uint8_t w, const uint8_t h, FontStyle fontStyle = FontStyle::FROM_TEXT);
|
||||||
|
static void printNumberBounded(const uint16_t num, bool noLeaderZeros, const uint8_t x, const uint8_t y, const uint8_t w, const uint8_t h);
|
||||||
|
|
||||||
|
static void print(const char *string, FontStyle fontStyle,
|
||||||
|
uint8_t length = 255); // Draw a string to the current location, with selected font; optionally - with MAX length only
|
||||||
|
static void printWholeScreen(const char *string);
|
||||||
// Set the cursor location by pixels
|
// Set the cursor location by pixels
|
||||||
static void setCursor(int16_t x, int16_t y) {
|
static void setCursor(int16_t x, int16_t y) {
|
||||||
cursor_x = x;
|
cursor_x = x;
|
||||||
|
13
source/Core/Inc/FontUtils.h
Normal file
13
source/Core/Inc/FontUtils.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
enum class FontStyle {
|
||||||
|
SMALL,
|
||||||
|
LARGE,
|
||||||
|
EXTRAS,
|
||||||
|
FROM_TEXT, // Magically pick from the text
|
||||||
|
FROM_HEIGHT, // Pick font to best fill the height
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr uint8_t get_fontstyle_height(const FontStyle font);
|
||||||
|
constexpr uint8_t get_fontstyle_width(const FontStyle font);
|
||||||
|
constexpr FontStyle get_fontstyle_fromHeight(const uint8_t height);
|
14
source/Core/Src/FontUtils.cpp
Normal file
14
source/Core/Src/FontUtils.cpp
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#include "FontUtils.h"
|
||||||
|
constexpr uint8_t get_fontstyle_height(const FontStyle font) {
|
||||||
|
if (font == FontStyle::SMALL)
|
||||||
|
return 8;
|
||||||
|
return 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr uint8_t get_fontstyle_width(const FontStyle font) {
|
||||||
|
if (font == FontStyle::SMALL)
|
||||||
|
return 6;
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr FontStyle get_fontstyle_fromHeight(const uint8_t height) { return (height <= 8) ? FontStyle::SMALL : FontStyle::LARGE; }
|
@@ -171,6 +171,7 @@ SOURCE_DRIVERS_DIR = ./Core/Drivers
|
|||||||
INC_PD_DRIVERS_DIR = ./Core/Drivers/usb-pd/include
|
INC_PD_DRIVERS_DIR = ./Core/Drivers/usb-pd/include
|
||||||
PD_DRIVER_TESTS_DIR = ./Core/Drivers/usb-pd/tests
|
PD_DRIVER_TESTS_DIR = ./Core/Drivers/usb-pd/tests
|
||||||
PD_DRIVER_DIR = ./Core/Drivers/usb-pd
|
PD_DRIVER_DIR = ./Core/Drivers/usb-pd
|
||||||
|
UI_DIR = ./UI
|
||||||
|
|
||||||
|
|
||||||
# Find-all's used for formatting; have to exclude external modules
|
# Find-all's used for formatting; have to exclude external modules
|
||||||
@@ -419,6 +420,7 @@ INCLUDES = -I$(APP_INC_DIR) \
|
|||||||
-I$(FRTOS_INC_DIR) \
|
-I$(FRTOS_INC_DIR) \
|
||||||
-I$(DRIVER_INC_DIR) \
|
-I$(DRIVER_INC_DIR) \
|
||||||
-I$(BSP_INC_DIR) \
|
-I$(BSP_INC_DIR) \
|
||||||
|
-I$(UI_DIR) \
|
||||||
-I$(THREADS_INC_DIR) \
|
-I$(THREADS_INC_DIR) \
|
||||||
-I$(THREADS_OP_MODES_INC_DIR) \
|
-I$(THREADS_OP_MODES_INC_DIR) \
|
||||||
-I$(THREADS_OP_MODES_TOOLS_INC_DIR) \
|
-I$(THREADS_OP_MODES_TOOLS_INC_DIR) \
|
||||||
@@ -433,6 +435,7 @@ EXCLUDED_DIRS := -path $(PINECILV2_VENDOR_BSP_ES8388_DIR) \
|
|||||||
-o -path $(PINECILV2_VENDOR_BSP_USB_DIR) \
|
-o -path $(PINECILV2_VENDOR_BSP_USB_DIR) \
|
||||||
|
|
||||||
SOURCE := $(shell find $(SOURCE_THREADS_DIR) -type f -name '*.c') \
|
SOURCE := $(shell find $(SOURCE_THREADS_DIR) -type f -name '*.c') \
|
||||||
|
$(shell find $(UI_DIR) -type f -name '*.c') \
|
||||||
$(shell find $(SOURCE_CORE_DIR) -type f -name '*.c') \
|
$(shell find $(SOURCE_CORE_DIR) -type f -name '*.c') \
|
||||||
$(shell find $(SOURCE_DRIVERS_DIR) -type f -name '*.c') \
|
$(shell find $(SOURCE_DRIVERS_DIR) -type f -name '*.c') \
|
||||||
$(shell find $(DEVICE_BSP_DIR) -type d \( $(EXCLUDED_DIRS) \) -prune -false -o -type f -name '*.c')\
|
$(shell find $(DEVICE_BSP_DIR) -type d \( $(EXCLUDED_DIRS) \) -prune -false -o -type f -name '*.c')\
|
||||||
@@ -441,6 +444,7 @@ $(SOURCE_BRIEFLZ_DIR)/depack.c
|
|||||||
# We exclude the USB-PD stack tests $(PD_DRIVER_TESTS_DIR)
|
# We exclude the USB-PD stack tests $(PD_DRIVER_TESTS_DIR)
|
||||||
SOURCE_CPP := $(shell find $(SOURCE_THREADS_DIR) -type f -name '*.cpp') \
|
SOURCE_CPP := $(shell find $(SOURCE_THREADS_DIR) -type f -name '*.cpp') \
|
||||||
$(shell find $(SOURCE_CORE_DIR) -type f -name '*.cpp') \
|
$(shell find $(SOURCE_CORE_DIR) -type f -name '*.cpp') \
|
||||||
|
$(shell find $(UI_DIR) -type f -name '*.cpp') \
|
||||||
$(shell find $(SOURCE_DRIVERS_DIR) -path $(PD_DRIVER_TESTS_DIR) -prune -false -o -type f -name '*.cpp') \
|
$(shell find $(SOURCE_DRIVERS_DIR) -path $(PD_DRIVER_TESTS_DIR) -prune -false -o -type f -name '*.cpp') \
|
||||||
$(shell find $(DEVICE_BSP_DIR) -type d \( $(EXCLUDED_DIRS) \) -prune -false -o -type f -name '*.cpp') \
|
$(shell find $(DEVICE_BSP_DIR) -type d \( $(EXCLUDED_DIRS) \) -prune -false -o -type f -name '*.cpp') \
|
||||||
$(shell find $(SOURCE_MIDDLEWARES_DIR) -type f -name '*.cpp')
|
$(shell find $(SOURCE_MIDDLEWARES_DIR) -type f -name '*.cpp')
|
||||||
|
8
source/UI/UI.cpp
Normal file
8
source/UI/UI.cpp
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#include "UI.h"
|
||||||
|
#include "OLED.hpp"
|
||||||
|
void ui_render_screen(screenLayout_t *screen, ScreenContext_t *context) {
|
||||||
|
// Walk the struct associated to the screen, calling render for each element of the screen
|
||||||
|
// Then start OLED refresh
|
||||||
|
|
||||||
|
OLED::refresh();
|
||||||
|
}
|
16
source/UI/UI.h
Normal file
16
source/UI/UI.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "UI_Layouts.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
int32_t i32;
|
||||||
|
void *ptr;
|
||||||
|
} screen_arg_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
screen_arg_t args[4];
|
||||||
|
} ScreenContext_t;
|
||||||
|
|
||||||
|
//
|
||||||
|
void ui_render_screen(screenLayout_t *screen, ScreenContext_t *context);
|
||||||
|
void ui_render_element(const ElementTypes_t element, const ElementSettings_t *settings, screen_arg_t *args);
|
77
source/UI/UI_Elements.cpp
Normal file
77
source/UI/UI_Elements.cpp
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
#include "UI_Elements.h"
|
||||||
|
#include "FontUtils.h"
|
||||||
|
#include "OLED.hpp"
|
||||||
|
#include "UI.h"
|
||||||
|
void render_Text(const ElementSettings_t *settings, screen_arg_t *args);
|
||||||
|
void render_Number(const ElementSettings_t *settings, screen_arg_t *args);
|
||||||
|
void render_Image(const ElementSettings_t *settings, screen_arg_t *args);
|
||||||
|
void render_PowerSource(const ElementSettings_t *settings, screen_arg_t *args);
|
||||||
|
void render_Temperature(const ElementSettings_t *settings, screen_arg_t *args);
|
||||||
|
void render_InputVoltage(const ElementSettings_t *settings, screen_arg_t *args);
|
||||||
|
void render_ScrollBar(const ElementSettings_t *settings, screen_arg_t *args);
|
||||||
|
void render_CheckBox(const ElementSettings_t *settings, screen_arg_t *args);
|
||||||
|
void render_TextScroller(const ElementSettings_t *settings, screen_arg_t *args);
|
||||||
|
|
||||||
|
void ui_render_element(const ElementTypes_t element, const ElementSettings_t *settings, screen_arg_t *args) {
|
||||||
|
switch (element) {
|
||||||
|
case ElementTypes_t::Text:
|
||||||
|
render_Text(settings, args);
|
||||||
|
break;
|
||||||
|
case ElementTypes_t::Number:
|
||||||
|
render_Number(settings, args);
|
||||||
|
break;
|
||||||
|
case ElementTypes_t::Image:
|
||||||
|
render_Image(settings, args);
|
||||||
|
break;
|
||||||
|
case ElementTypes_t::PowerSource:
|
||||||
|
render_PowerSource(settings, args);
|
||||||
|
break;
|
||||||
|
case ElementTypes_t::Temperature:
|
||||||
|
render_Temperature(settings, args);
|
||||||
|
break;
|
||||||
|
case ElementTypes_t::InputVoltage:
|
||||||
|
render_InputVoltage(settings, args);
|
||||||
|
break;
|
||||||
|
case ElementTypes_t::ScrollBar:
|
||||||
|
render_ScrollBar(settings, args);
|
||||||
|
break;
|
||||||
|
case ElementTypes_t::CheckBox:
|
||||||
|
render_CheckBox(settings, args);
|
||||||
|
break;
|
||||||
|
case ElementTypes_t::TextScroller:
|
||||||
|
render_TextScroller(settings, args);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_Text(const ElementSettings_t *settings, screen_arg_t *args) {
|
||||||
|
// Draw text clipped into bounds
|
||||||
|
// Args shall be a pointer to an encoded string
|
||||||
|
OLED::printBounded((const char *)args->ptr, settings->position.x, settings->position.y, settings->size.w, settings->size.h);
|
||||||
|
}
|
||||||
|
void render_Number(const ElementSettings_t *settings, screen_arg_t *args) {
|
||||||
|
// Arg is an int32 of the number to display
|
||||||
|
OLED::printNumberBounded(args->i32, true, settings->position.x, settings->position.y, settings->size.w, settings->size.h);
|
||||||
|
}
|
||||||
|
void render_Image(const ElementSettings_t *settings, screen_arg_t *args) {
|
||||||
|
// arg is a pointer to the raw image data to display
|
||||||
|
OLED::drawArea(settings->position.x, settings->position.y, settings->size.w, settings->size.h, (uint8_t *)args->ptr);
|
||||||
|
}
|
||||||
|
void render_PowerSource(const ElementSettings_t *settings, screen_arg_t *args) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
void render_Temperature(const ElementSettings_t *settings, screen_arg_t *args) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
void render_InputVoltage(const ElementSettings_t *settings, screen_arg_t *args) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
void render_ScrollBar(const ElementSettings_t *settings, screen_arg_t *args) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
void render_CheckBox(const ElementSettings_t *settings, screen_arg_t *args) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
void render_TextScroller(const ElementSettings_t *settings, screen_arg_t *args) {
|
||||||
|
//
|
||||||
|
}
|
26
source/UI/UI_Elements.h
Normal file
26
source/UI/UI_Elements.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
Text, // Basic text splat, using re-encoded strings
|
||||||
|
Number, // Draws numbers using best size for the height (always one line)
|
||||||
|
Image, // Pre-rendered bitmap that can be memcpy'ed in
|
||||||
|
PowerSource, // Draws a battery icon, or text for voltage, or DC power plug
|
||||||
|
Temperature, // Draws the number with temperature symbol following (height picks font)
|
||||||
|
InputVoltage, // Draws the number with V following and also 1 dp(height picks font)
|
||||||
|
ScrollBar, // Draws a vertical scrollbar, number sets percentage 0-100
|
||||||
|
CheckBox, // Draws checkbox, ticked = number!=0
|
||||||
|
TextScroller, // Renders text, scrolling with time
|
||||||
|
} ElementTypes_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct {
|
||||||
|
uint8_t x;
|
||||||
|
uint8_t y;
|
||||||
|
} position;
|
||||||
|
struct {
|
||||||
|
uint8_t w;
|
||||||
|
uint8_t h;
|
||||||
|
} size;
|
||||||
|
|
||||||
|
} ElementSettings_t;
|
26
source/UI/UI_Layouts.h
Normal file
26
source/UI/UI_Layouts.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "UI_Elements.h"
|
||||||
|
typedef enum {
|
||||||
|
SimplifiedHome, // Basic home
|
||||||
|
SimplifiedHomeWarning, // Home with temp warning
|
||||||
|
DetailedHome, // Detailed home view
|
||||||
|
DetailedHomeWarning, // Home with temp warning
|
||||||
|
DebugView, // Debugging metrics
|
||||||
|
settingsCategory, // Settings category with icon
|
||||||
|
SettingsEntryBool, // Tickbox setting
|
||||||
|
SettingsEntry3Number, // Settings adjust with 3 number digits
|
||||||
|
SettingsEntry2Number, // Settings adjust with 2 number digits
|
||||||
|
SettingsEntry1Number, // Settings adjust with 2 number digits
|
||||||
|
SettingsEntry1Text, // Setting with single text char for state
|
||||||
|
ScrollingText, // Scrolling large text (warnings, help text)
|
||||||
|
SolderingMode, // Basic soldering mode
|
||||||
|
DetailedSolderingMode, // Detailed soldering mode
|
||||||
|
NumberAdjust, // Number adjust of number with <> either side
|
||||||
|
} screenLayout_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct {
|
||||||
|
ElementTypes_t elementType;
|
||||||
|
ElementSettings_t elementSettings;
|
||||||
|
} elements[5];
|
||||||
|
} ScreenLayoutRecord_t;
|
15
source/UI/UI_Screens.h
Normal file
15
source/UI/UI_Screens.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "UI_Layouts.h"
|
||||||
|
|
||||||
|
typedef void (*render_prep_fn)();
|
||||||
|
typedef void (*tick_fn)();
|
||||||
|
typedef void (*button_handler_fn)();
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// on_enter
|
||||||
|
// on_exit
|
||||||
|
tick_fn tick;
|
||||||
|
render_prep_fn render_prepare;
|
||||||
|
screenLayout_t layout; // Render layout used
|
||||||
|
button_handler_fn handle_button;
|
||||||
|
} Screen_t;
|
78
source/UI/generate_ui.py
Executable file
78
source/UI/generate_ui.py
Executable file
@@ -0,0 +1,78 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
Read in the yaml config files in this folder
|
||||||
|
For each config file, generate a cpp file defining each layout
|
||||||
|
"""
|
||||||
|
|
||||||
|
import yaml
|
||||||
|
from string import Template
|
||||||
|
|
||||||
|
|
||||||
|
def element_to_str(element) -> str:
|
||||||
|
template = Template(
|
||||||
|
"""
|
||||||
|
{
|
||||||
|
.elementType = ElementTypes_t::$type,
|
||||||
|
.elementSettings={
|
||||||
|
.position ={
|
||||||
|
.x=$x,
|
||||||
|
.y=$y,
|
||||||
|
},
|
||||||
|
.size ={
|
||||||
|
.w=$w,
|
||||||
|
.h=$h,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
return template.substitute(
|
||||||
|
x=element["position"]["x"],
|
||||||
|
y=element["position"]["y"],
|
||||||
|
w=element["size"]["w"],
|
||||||
|
h=element["size"]["h"],
|
||||||
|
type=element["type"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def layout_to_str(layout):
|
||||||
|
inner_elements = "".join(element_to_str(x) for x in layout["elements"])
|
||||||
|
template = Template(
|
||||||
|
"""{
|
||||||
|
.elements =
|
||||||
|
{
|
||||||
|
$elements
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
return template.substitute(elements=inner_elements)
|
||||||
|
|
||||||
|
|
||||||
|
def layouts_to_cpp(layout_file_path, output_file_path):
|
||||||
|
with open(layout_file_path, "r") as file:
|
||||||
|
with open(output_file_path, "w") as output:
|
||||||
|
layout_defs = yaml.safe_load(file)
|
||||||
|
|
||||||
|
header = """
|
||||||
|
#include "UI.h"
|
||||||
|
#include "UI_Elements.h"
|
||||||
|
|
||||||
|
const ScreenLayoutRecord_t screenLayouts[] = {
|
||||||
|
"""
|
||||||
|
output.write(header)
|
||||||
|
|
||||||
|
for layout_name in layout_defs["layouts"]:
|
||||||
|
layout = layout_defs["layouts"][layout_name]
|
||||||
|
# Now we convert this layout into a structure definition
|
||||||
|
element_entry = layout_to_str(layout)
|
||||||
|
output.write(element_entry)
|
||||||
|
footer = """
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
output.write(footer)
|
||||||
|
|
||||||
|
|
||||||
|
layouts_to_cpp("layout_96x16.yaml", "layout_96x16.cpp")
|
270
source/UI/layout_96x16.yaml
Normal file
270
source/UI/layout_96x16.yaml
Normal file
@@ -0,0 +1,270 @@
|
|||||||
|
layouts:
|
||||||
|
SimplifiedHome:
|
||||||
|
mirrorOnRotate: true
|
||||||
|
elements:
|
||||||
|
- type: Image
|
||||||
|
position:
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 42
|
||||||
|
h: 16
|
||||||
|
- type: Image
|
||||||
|
position:
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 42
|
||||||
|
h: 16
|
||||||
|
- type: PowerSource
|
||||||
|
position:
|
||||||
|
x: 84
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 12
|
||||||
|
h: 16
|
||||||
|
|
||||||
|
simplifiedHomeWarning:
|
||||||
|
mirrorOnRotate: true
|
||||||
|
elements:
|
||||||
|
- type: Text
|
||||||
|
position:
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 42
|
||||||
|
h: 16
|
||||||
|
- type: Image
|
||||||
|
position:
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 42
|
||||||
|
h: 16
|
||||||
|
- type: PowerSource
|
||||||
|
position:
|
||||||
|
x: 84
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 12
|
||||||
|
h: 16
|
||||||
|
detailedHome:
|
||||||
|
elements:
|
||||||
|
- type: Temperature
|
||||||
|
position:
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 48
|
||||||
|
h: 16
|
||||||
|
- type: Temperature
|
||||||
|
position:
|
||||||
|
x: 48
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 32
|
||||||
|
h: 8
|
||||||
|
- type: InputVoltage
|
||||||
|
position:
|
||||||
|
x: 48
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 32
|
||||||
|
h: 8
|
||||||
|
detailedHomeWarning:
|
||||||
|
elements:
|
||||||
|
- type: Temperature
|
||||||
|
position:
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 48
|
||||||
|
h: 16
|
||||||
|
- type: InputVoltage
|
||||||
|
position:
|
||||||
|
x: 48
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 32
|
||||||
|
h: 8
|
||||||
|
|
||||||
|
SebugMenu:
|
||||||
|
elements:
|
||||||
|
- type: Text
|
||||||
|
position:
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 96
|
||||||
|
h: 8
|
||||||
|
- type: Text
|
||||||
|
position:
|
||||||
|
x: 0
|
||||||
|
y: 8
|
||||||
|
size:
|
||||||
|
w: 48
|
||||||
|
h: 8
|
||||||
|
- type: Number
|
||||||
|
position:
|
||||||
|
x: 48
|
||||||
|
y: 8
|
||||||
|
size:
|
||||||
|
w: 48
|
||||||
|
h: 8
|
||||||
|
SettingsCategory:
|
||||||
|
elements:
|
||||||
|
- type: Text
|
||||||
|
position:
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 78
|
||||||
|
h: 16
|
||||||
|
- type: Image
|
||||||
|
position:
|
||||||
|
x: 79
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 16
|
||||||
|
h: 16
|
||||||
|
- type: ScrollBar
|
||||||
|
position:
|
||||||
|
x: 95
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 1
|
||||||
|
h: 16
|
||||||
|
SettingsEntryBool:
|
||||||
|
elements:
|
||||||
|
- type: Text
|
||||||
|
position:
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 78
|
||||||
|
h: 16
|
||||||
|
- type: CheckBox
|
||||||
|
position:
|
||||||
|
x: 79
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 16
|
||||||
|
h: 16
|
||||||
|
- type: ScrollBar
|
||||||
|
position:
|
||||||
|
x: 95
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 1
|
||||||
|
h: 16
|
||||||
|
|
||||||
|
SettingsEntry3Number:
|
||||||
|
elements:
|
||||||
|
- type: Text
|
||||||
|
position:
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 78
|
||||||
|
h: 16
|
||||||
|
- type: Number
|
||||||
|
position:
|
||||||
|
x: 79
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 36
|
||||||
|
h: 16
|
||||||
|
- type: ScrollBar
|
||||||
|
position:
|
||||||
|
x: 95
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 1
|
||||||
|
h: 16
|
||||||
|
|
||||||
|
SettingsEntry2Number:
|
||||||
|
elements:
|
||||||
|
- type: Text
|
||||||
|
position:
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 78
|
||||||
|
h: 16
|
||||||
|
- type: Number
|
||||||
|
position:
|
||||||
|
x: 79
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 36
|
||||||
|
h: 16
|
||||||
|
- type: ScrollBar
|
||||||
|
position:
|
||||||
|
x: 95
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 1
|
||||||
|
h: 16
|
||||||
|
SettingsEntry1Number:
|
||||||
|
elements:
|
||||||
|
- type: Text
|
||||||
|
position:
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 78
|
||||||
|
h: 16
|
||||||
|
- type: Number
|
||||||
|
position:
|
||||||
|
x: 79
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 36
|
||||||
|
h: 16
|
||||||
|
- type: ScrollBar
|
||||||
|
position:
|
||||||
|
x: 95
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 1
|
||||||
|
h: 16
|
||||||
|
SettingsEntry1Text:
|
||||||
|
elements:
|
||||||
|
- type: Text
|
||||||
|
position:
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 78
|
||||||
|
h: 16
|
||||||
|
- type: Number
|
||||||
|
position:
|
||||||
|
x: 79
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 36
|
||||||
|
h: 16
|
||||||
|
- type: ScrollBar
|
||||||
|
position:
|
||||||
|
x: 95
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 1
|
||||||
|
h: 16
|
||||||
|
ScrollingText:
|
||||||
|
elements:
|
||||||
|
- type: TextScroller
|
||||||
|
position:
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
size:
|
||||||
|
w: 96
|
||||||
|
h: 16
|
||||||
|
# SolderingMode:
|
||||||
|
# elements:
|
||||||
|
# DetailedSolderingMode:
|
||||||
|
# elements:
|
||||||
|
# NumberAdjust:
|
||||||
|
# elements:
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user