summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorailurux <ailuruxx@gmail.com>2024-03-10 13:20:17 +1100
committerailurux <ailuruxx@gmail.com>2024-03-10 13:20:17 +1100
commit1133d4621508b7ec6bac4ab8731f3493066ceeee (patch)
treeef9e703effe08f9fb63e26a72c2e498e8ff62012
parent20c2816a7b2497c2ab0d07a65fb640050a929371 (diff)
downloadtangara-fw-1133d4621508b7ec6bac4ab8731f3493066ceeee.tar.gz
WIP Lua Theming- style classes
-rw-r--r--lua/browser.lua4
-rw-r--r--lua/main.lua93
-rw-r--r--lua/theme_dark.lua127
-rw-r--r--lua/theme_light.lua106
-rw-r--r--lua/widgets.lua6
-rw-r--r--src/lua/lua_theme.cpp25
-rw-r--r--src/ui/include/themes.hpp2
-rw-r--r--src/ui/modal.cpp2
-rw-r--r--src/ui/screen_lua.cpp5
-rw-r--r--src/ui/themes.cpp64
10 files changed, 264 insertions, 170 deletions
diff --git a/lua/browser.lua b/lua/browser.lua
index e174a05d..055c8641 100644
--- a/lua/browser.lua
+++ b/lua/browser.lua
@@ -6,6 +6,7 @@ local queue = require("queue")
local playing = require("playing")
local styles = require("styles")
local playback = require("playback")
+local theme = require("theme")
local browser = {}
@@ -43,9 +44,10 @@ function browser.create(opts)
pad_right = 4,
pad_bottom = 2,
bg_opa = lvgl.OPA(100),
- bg_color = "#fafafa",
scrollbar_mode = lvgl.SCROLLBAR_MODE.OFF,
}
+ theme.set_style(header, "header")
+
header:Label {
text = opts.breadcrumb,
diff --git a/lua/main.lua b/lua/main.lua
index 6cdef17d..f2533387 100644
--- a/lua/main.lua
+++ b/lua/main.lua
@@ -35,97 +35,8 @@ GLOBAL_BINDINGS = {
end),
}
-local lvgl = require("lvgl")
-local my_theme = {
- base = {
- {lvgl.PART.MAIN, lvgl.Style {
- bg_opa = lvgl.OPA(0),
- text_font = font.fusion_12,
- text_color = "#000000",
- }},
- {lvgl.STATE.FOCUSED, lvgl.Style {
- bg_opa = lvgl.OPA(100),
- bg_color = "#E3F2FD",
- }},
- },
- button = {
- {lvgl.PART.MAIN, lvgl.Style {
- pad_left = 2,
- pad_right = 2,
- pad_top = 1,
- pad_bottom = 1,
- bg_color = "#ffffff",
- radius = 5,
- }},
- },
- bar = {
- {lvgl.PART.MAIN, lvgl.Style {
- bg_opa = lvgl.OPA(100),
- radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
- }},
- },
- slider = {
- {lvgl.PART.MAIN, lvgl.Style {
- bg_opa = lvgl.OPA(100),
- radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
- }},
- {lvgl.PART.INDICATOR, lvgl.Style {
- radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
- bg_color = "#2196F3",
- }},
- {lvgl.PART.KNOB, lvgl.Style {
- radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
- pad_all = 2,
- bg_color = "#ffffff",
- shadow_width = 5,
- shadow_opa = lvgl.OPA(100)
- }},
- {lvgl.STATE.FOCUSED, lvgl.Style {
- bg_color = "#BBDEFB",
- }},
- },
- switch = {
- {lvgl.PART.MAIN, lvgl.Style {
- bg_opa = lvgl.OPA(100),
- width = 28,
- height = 18,
- radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
- }},
- {lvgl.PART.INDICATOR, lvgl.Style {
- radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
- bg_color = "#9E9E9E",
- }},
- {lvgl.PART.INDICATOR | lvgl.STATE.CHECKED, lvgl.Style {
- bg_color = "#2196F3",
- }},
- {lvgl.PART.KNOB, lvgl.Style {
- radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
- pad_all = 2,
- bg_opa = lvgl.OPA(100),
- bg_color = "#ffffff",
- }},
- },
- dropdown = {
- {lvgl.PART.MAIN, lvgl.Style{
- radius = 2,
- pad_all = 2,
- border_width = 1,
- border_color = "#2196F3",
- border_side = 15, -- LV_BORDER_SIDE_FULL
- }}
- },
- dropdownlist = {
- {lvgl.PART.MAIN, lvgl.Style{
- radius = 2,
- pad_all = 2,
- border_width = 1,
- border_color = "#607D8B",
- bg_opa = lvgl.OPA(100),
- bg_color = "#ffffff"
- }}
- }
-}
-theme.set(my_theme)
+local theme_light = require("theme_dark")
+theme.set(theme_light)
local backstack = require("backstack")
local main_menu = require("main_menu")
diff --git a/lua/theme_dark.lua b/lua/theme_dark.lua
new file mode 100644
index 00000000..5c91ea1e
--- /dev/null
+++ b/lua/theme_dark.lua
@@ -0,0 +1,127 @@
+local lvgl = require("lvgl")
+local font = require("font")
+
+local background_color = "#242933"
+local background_muted = "#353c4b"
+local text_color = "#fefefe"
+local highlight_color = "#ff0077"
+
+local theme_dark = {
+ base = {
+ {lvgl.PART.MAIN, lvgl.Style {
+ bg_opa = lvgl.OPA(0),
+ text_font = font.fusion_12,
+ text_color = text_color,
+ }},
+ },
+ root = {
+ {lvgl.PART.MAIN, lvgl.Style {
+ bg_opa = lvgl.OPA(100),
+ bg_color = background_color, -- Root background color
+ }},
+ },
+ header = {
+ {lvgl.PART.MAIN, lvgl.Style {
+ bg_opa = lvgl.OPA(100),
+ bg_color = background_muted,
+ }},
+ },
+ button = {
+ {lvgl.PART.MAIN, lvgl.Style {
+ pad_left = 2,
+ pad_right = 2,
+ pad_top = 1,
+ pad_bottom = 1,
+ bg_color = background_color,
+ radius = 5,
+ }},
+ {lvgl.PART.MAIN | lvgl.STATE.FOCUSED, lvgl.Style {
+ bg_opa = lvgl.OPA(100),
+ bg_color = highlight_color,
+ }},
+ },
+ listbutton = {
+ {lvgl.PART.MAIN | lvgl.STATE.FOCUSED, lvgl.Style {
+ bg_opa = lvgl.OPA(100),
+ bg_color = highlight_color,
+ }},
+ },
+ bar = {
+ {lvgl.PART.MAIN, lvgl.Style {
+ bg_opa = lvgl.OPA(100),
+ radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
+ }},
+ },
+ slider = {
+ {lvgl.PART.MAIN, lvgl.Style {
+ bg_opa = lvgl.OPA(100),
+ bg_color = background_muted,
+ radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
+ }},
+ {lvgl.PART.INDICATOR, lvgl.Style {
+ radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
+ bg_color = highlight_color,
+ }},
+ {lvgl.PART.KNOB, lvgl.Style {
+ radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
+ pad_all = 2,
+ bg_color = background_color,
+ shadow_width = 5,
+ shadow_opa = lvgl.OPA(100)
+ }},
+ {lvgl.PART.MAIN | lvgl.STATE.FOCUSED, lvgl.Style {
+ bg_color = background_muted,
+ }},
+ {lvgl.PART.KNOB | lvgl.STATE.FOCUSED, lvgl.Style {
+ bg_color = highlight_color,
+ }},
+ },
+ switch = {
+ {lvgl.PART.MAIN, lvgl.Style {
+ bg_opa = lvgl.OPA(100),
+ width = 28,
+ height = 12,
+ radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
+ }},
+ {lvgl.PART.MAIN | lvgl.STATE.FOCUSED, lvgl.Style {
+ bg_color = background_muted,
+ }},
+ {lvgl.PART.INDICATOR, lvgl.Style {
+ radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
+ bg_color = background_muted,
+ }},
+ {lvgl.PART.INDICATOR | lvgl.STATE.CHECKED, lvgl.Style {
+ bg_color = highlight_color,
+ }},
+ {lvgl.PART.KNOB, lvgl.Style {
+ radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
+ pad_all = 2,
+ bg_opa = lvgl.OPA(100),
+ bg_color = text_color,
+ }},
+ },
+ dropdown = {
+ {lvgl.PART.MAIN, lvgl.Style{
+ radius = 2,
+ pad_all = 2,
+ border_width = 1,
+ border_color = text_color,
+ border_side = 15, -- LV_BORDER_SIDE_FULL
+ }},
+ {lvgl.PART.MAIN | lvgl.STATE.FOCUSED, lvgl.Style {
+ border_color = highlight_color,
+ }},
+ },
+ dropdownlist = {
+ {lvgl.PART.MAIN, lvgl.Style{
+ radius = 2,
+ pad_all = 2,
+ border_width = 1,
+ border_color = text_color,
+ bg_opa = lvgl.OPA(100),
+ bg_color = background_color
+ }},
+ }
+}
+
+return theme_dark
diff --git a/lua/theme_light.lua b/lua/theme_light.lua
new file mode 100644
index 00000000..637861d9
--- /dev/null
+++ b/lua/theme_light.lua
@@ -0,0 +1,106 @@
+local lvgl = require("lvgl")
+local font = require("font")
+
+local background_color = "#FFFFFF"
+local background_muted = "#FFFFFF"
+local text_color = "#000000"
+local highlight_color = "#E3F2FD"
+
+local theme_light = {
+ base = {
+ {lvgl.PART.MAIN, lvgl.Style {
+ bg_opa = lvgl.OPA(0),
+ bg_color = background_color, -- Root background color
+ text_font = font.fusion_12,
+ text_color = text_color,
+ }},
+ {lvgl.STATE.FOCUSED, lvgl.Style {
+ bg_opa = lvgl.OPA(100),
+ bg_color = highlight_color,
+ }},
+ },
+ root = {
+ {lvgl.PART.MAIN, lvgl.Style {
+ bg_opa = lvgl.OPA(100),
+ bg_color = background_color, -- Root background color
+ }},
+ },
+ button = {
+ {lvgl.PART.MAIN, lvgl.Style {
+ pad_left = 2,
+ pad_right = 2,
+ pad_top = 1,
+ pad_bottom = 1,
+ bg_color = background_color,
+ radius = 5,
+ }},
+ },
+ bar = {
+ {lvgl.PART.MAIN, lvgl.Style {
+ bg_opa = lvgl.OPA(100),
+ radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
+ }},
+ },
+ slider = {
+ {lvgl.PART.MAIN, lvgl.Style {
+ bg_opa = lvgl.OPA(100),
+ radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
+ }},
+ {lvgl.PART.INDICATOR, lvgl.Style {
+ radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
+ bg_color = highlight_color,
+ }},
+ {lvgl.PART.KNOB, lvgl.Style {
+ radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
+ pad_all = 2,
+ bg_color = background_color,
+ shadow_width = 5,
+ shadow_opa = lvgl.OPA(100)
+ }},
+ {lvgl.STATE.FOCUSED, lvgl.Style {
+ bg_color = highlight_color,
+ }},
+ },
+ switch = {
+ {lvgl.PART.MAIN, lvgl.Style {
+ bg_opa = lvgl.OPA(100),
+ width = 28,
+ height = 18,
+ radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
+ }},
+ {lvgl.PART.INDICATOR, lvgl.Style {
+ radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
+ bg_color = background_muted,
+ }},
+ {lvgl.PART.INDICATOR | lvgl.STATE.CHECKED, lvgl.Style {
+ bg_color = highlight_color,
+ }},
+ {lvgl.PART.KNOB, lvgl.Style {
+ radius = 32767, -- LV_RADIUS_CIRCLE = 0x7fff
+ pad_all = 2,
+ bg_opa = lvgl.OPA(100),
+ bg_color = background_color,
+ }},
+ },
+ dropdown = {
+ {lvgl.PART.MAIN, lvgl.Style{
+ radius = 2,
+ pad_all = 2,
+ border_width = 1,
+ border_color = "#2196F3",
+ border_side = 15, -- LV_BORDER_SIDE_FULL
+ }}
+ },
+ dropdownlist = {
+ {lvgl.PART.MAIN, lvgl.Style{
+ radius = 2,
+ pad_all = 2,
+ border_width = 1,
+ border_color = "#607D8B",
+ bg_opa = lvgl.OPA(100),
+ bg_color = background_color
+ }}
+ }
+}
+
+return theme_light
diff --git a/lua/widgets.lua b/lua/widgets.lua
index 8253041b..15212ded 100644
--- a/lua/widgets.lua
+++ b/lua/widgets.lua
@@ -5,6 +5,7 @@ local font = require("font")
local backstack = require("backstack")
local styles = require("styles")
local database = require("database")
+local theme = require("theme")
local widgets = {}
@@ -66,10 +67,7 @@ function widgets.StatusBar(parent, opts)
}
if not opts.transparent_bg then
- status_bar.root:set {
- bg_opa = lvgl.OPA(100),
- bg_color = "#fafafa",
- }
+ theme.set_style(status_bar.root, "header");
end
if opts.back_cb then
diff --git a/src/lua/lua_theme.cpp b/src/lua/lua_theme.cpp
index 7b007f4d..2fcd71e5 100644
--- a/src/lua/lua_theme.cpp
+++ b/src/lua/lua_theme.cpp
@@ -22,17 +22,19 @@
namespace lua {
-static auto set_theme(lua_State* L) -> int {
- // lv_style_t* style = luavgl_to_style(L, -1);
- // if (style == NULL) {
- // ESP_LOGI("DANIEL", "Style was null or malformed??");
- // return 0;
- // }
-
- // ESP_LOGI("DANIEL", "GOT ONE!");
- // themes::Theme::instance()->...;
+static auto set_style(lua_State* L) -> int {
+ // Get the object and class name from the stack
+ if (lua_type(L, -1) == LUA_TSTRING) {
+ std::string class_name = lua_tostring(L, -1);
+ lv_obj_t* obj = luavgl_to_obj(L, -2);
+ if (obj != NULL) {
+ ui::themes::Theme::instance()->ApplyStyle(obj, class_name);
+ }
+ }
+ return 0;
+}
- /* table is in the stack at index 't' */
+static auto set_theme(lua_State* L) -> int {
std::string class_name;
lua_pushnil(L); /* first key */
while (lua_next(L, -2) != 0) {
@@ -61,7 +63,6 @@ static auto set_theme(lua_State* L) -> int {
return 0;
} else {
ui::themes::Theme::instance()->AddStyle(class_name, selector, style);
- ESP_LOGI("DANIEL", "Got style for class %s with selector %d", class_name.c_str(), selector);
}
}
lua_pop(L, 1);
@@ -75,7 +76,7 @@ static auto set_theme(lua_State* L) -> int {
return 0;
}
-static const struct luaL_Reg kThemeFuncs[] = {{"set", set_theme}, {NULL, NULL}};
+static const struct luaL_Reg kThemeFuncs[] = {{"set", set_theme}, {"set_style", set_style}, {NULL, NULL}};
static auto lua_theme(lua_State* L) -> int {
luaL_newlib(L, kThemeFuncs);
diff --git a/src/ui/include/themes.hpp b/src/ui/include/themes.hpp
index 65462f65..09b9cdce 100644
--- a/src/ui/include/themes.hpp
+++ b/src/ui/include/themes.hpp
@@ -22,7 +22,7 @@ class Theme {
public:
void Apply(void);
void Callback(lv_obj_t* obj);
- void ApplyStyle(lv_obj_t* obj, Style style);
+ void ApplyStyle(lv_obj_t* obj, std::string style_key);
void AddStyle(std::string key, int selector, lv_style_t* style);
diff --git a/src/ui/modal.cpp b/src/ui/modal.cpp
index 88f6d3ef..ec541914 100644
--- a/src/ui/modal.cpp
+++ b/src/ui/modal.cpp
@@ -41,8 +41,6 @@ Modal::Modal(Screen* host)
lv_obj_set_style_bg_opa(root_, LV_OPA_COVER, 0);
lv_obj_set_style_bg_color(root_, lv_color_white(), 0);
- themes::Theme::instance()->ApplyStyle(root_, themes::Style::kPopup);
-
host_->modal_group(group_);
}
diff --git a/src/ui/screen_lua.cpp b/src/ui/screen_lua.cpp
index 5130b4f7..b3554241 100644
--- a/src/ui/screen_lua.cpp
+++ b/src/ui/screen_lua.cpp
@@ -8,13 +8,16 @@
#include "core/lv_obj_tree.h"
#include "lua.hpp"
+#include "themes.hpp"
#include "luavgl.h"
namespace ui {
namespace screens {
-Lua::Lua() : s_(nullptr), obj_ref_() {}
+Lua::Lua() : s_(nullptr), obj_ref_() {
+ themes::Theme::instance()->ApplyStyle(root_, "root");
+}
Lua::~Lua() {
if (s_ && obj_ref_) {
diff --git a/src/ui/themes.cpp b/src/ui/themes.cpp
index 4fd477ab..88f45b1b 100644
--- a/src/ui/themes.cpp
+++ b/src/ui/themes.cpp
@@ -44,6 +44,8 @@ void Theme::Callback(lv_obj_t* obj) {
std::string class_name;
if (lv_obj_check_type(obj, &lv_btn_class)) {
class_name = "button";
+ } else if (lv_obj_check_type(obj, &lv_list_btn_class)) {
+ class_name = "listbutton";
} else if (lv_obj_check_type(obj, &lv_bar_class)) {
class_name = "bar";
} else if (lv_obj_check_type(obj, &lv_slider_class)) {
@@ -65,65 +67,11 @@ void Theme::Callback(lv_obj_t* obj) {
}
-void Theme::ApplyStyle(lv_obj_t* obj, Style style) {
- switch (style) {
- case Style::kTopBar:
- lv_obj_set_style_pad_bottom(obj, 1, LV_PART_MAIN);
-
- lv_obj_set_style_shadow_width(obj, 6, LV_PART_MAIN);
- lv_obj_set_style_shadow_opa(obj, LV_OPA_COVER, LV_PART_MAIN);
- lv_obj_set_style_shadow_ofs_x(obj, 0, LV_PART_MAIN);
- break;
- case Style::kPopup:
- lv_obj_set_style_shadow_width(obj, 6, LV_PART_MAIN);
- lv_obj_set_style_shadow_opa(obj, LV_OPA_COVER, LV_PART_MAIN);
- lv_obj_set_style_shadow_ofs_x(obj, 0, LV_PART_MAIN);
- lv_obj_set_style_shadow_ofs_y(obj, 0, LV_PART_MAIN);
-
- lv_obj_set_style_radius(obj, 5, LV_PART_MAIN);
-
- lv_obj_set_style_bg_opa(obj, LV_OPA_COVER, LV_PART_MAIN);
- lv_obj_set_style_bg_color(obj, lv_color_white(), LV_PART_MAIN);
-
- lv_obj_set_style_pad_top(obj, 2, LV_PART_MAIN);
- lv_obj_set_style_pad_bottom(obj, 2, LV_PART_MAIN);
- lv_obj_set_style_pad_left(obj, 2, LV_PART_MAIN);
- lv_obj_set_style_pad_right(obj, 2, LV_PART_MAIN);
- break;
- case Style::kTab:
- lv_obj_set_style_radius(obj, 0, LV_PART_MAIN);
-
- lv_obj_set_style_border_width(obj, 1, LV_STATE_CHECKED);
- lv_obj_set_style_border_color(obj, lv_palette_main(LV_PALETTE_BLUE),
- LV_STATE_CHECKED);
- lv_obj_set_style_border_side(obj, LV_BORDER_SIDE_BOTTOM,
- LV_STATE_CHECKED);
- break;
- case Style::kButtonPrimary:
- lv_obj_set_style_border_width(obj, 1, LV_PART_MAIN);
- lv_obj_set_style_border_color(obj, lv_palette_main(LV_PALETTE_BLUE),
- LV_PART_MAIN);
- lv_obj_set_style_border_side(obj, LV_BORDER_SIDE_FULL, LV_PART_MAIN);
- break;
- case Style::kMenuSubheadFirst:
- case Style::kMenuSubhead:
- lv_obj_set_style_text_color(obj, lv_palette_darken(LV_PALETTE_GREY, 3),
- LV_PART_MAIN);
- lv_obj_set_style_text_align(obj, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN);
-
- lv_obj_set_style_border_width(obj, 1, LV_PART_MAIN);
- lv_obj_set_style_border_color(obj, lv_palette_lighten(LV_PALETTE_GREY, 3),
- LV_PART_MAIN);
-
- if (style == Style::kMenuSubhead) {
- lv_obj_set_style_border_side(
- obj, LV_BORDER_SIDE_TOP | LV_BORDER_SIDE_BOTTOM, LV_PART_MAIN);
- } else {
- lv_obj_set_style_border_side(obj, LV_BORDER_SIDE_BOTTOM, LV_PART_MAIN);
+void Theme::ApplyStyle(lv_obj_t* obj, std::string style_key) {
+ if (auto search = style_map.find(style_key); search != style_map.end()) {
+ for (const auto& pair : search->second) {
+ lv_obj_add_style(obj, pair.second, pair.first);
}
- break;
- default:
- break;
}
}