mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
fix(bar): let capsule foreground style neutral scripted widget colors
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include "lualib.h"
|
||||
#include "shell/bar/widgets/scripted_widget.h"
|
||||
|
||||
#include <string_view>
|
||||
#include <variant>
|
||||
|
||||
namespace {
|
||||
@@ -17,6 +18,13 @@ namespace {
|
||||
return w;
|
||||
}
|
||||
|
||||
std::string_view optionalStringArg(lua_State* L, int index) {
|
||||
if (lua_gettop(L) < index || lua_isnil(L, index)) {
|
||||
return {};
|
||||
}
|
||||
return luaL_checkstring(L, index);
|
||||
}
|
||||
|
||||
int luau_setText(lua_State* L) {
|
||||
const char* text = luaL_checkstring(L, 1);
|
||||
if (auto* w = getWidget(L))
|
||||
@@ -34,14 +42,14 @@ namespace {
|
||||
int luau_setColor(lua_State* L) {
|
||||
const char* role = luaL_checkstring(L, 1);
|
||||
if (auto* w = getWidget(L))
|
||||
w->luaSetColor(role);
|
||||
w->luaSetColor(role, optionalStringArg(L, 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int luau_setGlyphColor(lua_State* L) {
|
||||
const char* role = luaL_checkstring(L, 1);
|
||||
if (auto* w = getWidget(L))
|
||||
w->luaSetGlyphColor(role);
|
||||
w->luaSetGlyphColor(role, optionalStringArg(L, 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ namespace {
|
||||
ss << f.rdbuf();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ScriptedWidget::ScriptedWidget(std::string scriptPath, const WidgetConfig* config, FileWatcher* fileWatcher)
|
||||
@@ -142,18 +143,14 @@ void ScriptedWidget::doLayout(Renderer& renderer, float containerWidth, float co
|
||||
if (!m_flex)
|
||||
return;
|
||||
|
||||
auto textColor = m_textColorRole ? colorSpecFromRole(*m_textColorRole)
|
||||
: widgetForegroundOr(colorSpecFromRole(ColorRole::OnSurface));
|
||||
m_label->setColor(textColor);
|
||||
m_label->setColor(resolveScriptColor(m_textColor));
|
||||
m_label->setVisible(!m_label->text().empty());
|
||||
if (m_label->visible()) {
|
||||
m_label->measure(renderer);
|
||||
}
|
||||
|
||||
if (m_glyphVisible) {
|
||||
auto glyphColor = m_glyphColorRole ? colorSpecFromRole(*m_glyphColorRole)
|
||||
: widgetForegroundOr(colorSpecFromRole(ColorRole::OnSurface));
|
||||
m_glyph->setColor(glyphColor);
|
||||
m_glyph->setColor(resolveScriptColor(m_glyphColor));
|
||||
m_glyph->measure(renderer);
|
||||
}
|
||||
|
||||
@@ -189,18 +186,24 @@ void ScriptedWidget::luaSetGlyph(std::string_view name) {
|
||||
m_dirty |= changed;
|
||||
}
|
||||
|
||||
void ScriptedWidget::luaSetColor(std::string_view role) {
|
||||
auto parsed = colorRoleFromToken(role);
|
||||
if (parsed != m_textColorRole) {
|
||||
m_textColorRole = parsed;
|
||||
void ScriptedWidget::luaSetColor(std::string_view role, std::string_view mode) {
|
||||
ScriptColorState next{.role = colorRoleFromToken(role), .mode = scriptColorModeFromToken(mode)};
|
||||
if (!next.role.has_value()) {
|
||||
next.mode = ScriptColorMode::Auto;
|
||||
}
|
||||
if (next != m_textColor) {
|
||||
m_textColor = next;
|
||||
m_dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptedWidget::luaSetGlyphColor(std::string_view role) {
|
||||
auto parsed = colorRoleFromToken(role);
|
||||
if (parsed != m_glyphColorRole) {
|
||||
m_glyphColorRole = parsed;
|
||||
void ScriptedWidget::luaSetGlyphColor(std::string_view role, std::string_view mode) {
|
||||
ScriptColorState next{.role = colorRoleFromToken(role), .mode = scriptColorModeFromToken(mode)};
|
||||
if (!next.role.has_value()) {
|
||||
next.mode = ScriptColorMode::Auto;
|
||||
}
|
||||
if (next != m_glyphColor) {
|
||||
m_glyphColor = next;
|
||||
m_dirty = true;
|
||||
}
|
||||
}
|
||||
@@ -232,6 +235,24 @@ ScriptedWidget::IpcDispatchResult ScriptedWidget::dispatchIpcEvent(std::string_v
|
||||
return IpcDispatchResult::Handled;
|
||||
}
|
||||
|
||||
ColorSpec ScriptedWidget::resolveScriptColor(const ScriptColorState& state) const noexcept {
|
||||
if (m_widgetForeground.has_value()) {
|
||||
return *m_widgetForeground;
|
||||
}
|
||||
const ColorSpec fallback = colorSpecFromRole(ColorRole::OnSurface);
|
||||
if (!state.role.has_value()) {
|
||||
return widgetForegroundOr(fallback);
|
||||
}
|
||||
if (state.mode == ScriptColorMode::Script || *state.role != ColorRole::OnSurface) {
|
||||
return colorSpecFromRole(*state.role);
|
||||
}
|
||||
return widgetForegroundOr(fallback);
|
||||
}
|
||||
|
||||
ScriptedWidget::ScriptColorMode ScriptedWidget::scriptColorModeFromToken(std::string_view token) noexcept {
|
||||
return token == "script" ? ScriptColorMode::Script : ScriptColorMode::Auto;
|
||||
}
|
||||
|
||||
void ScriptedWidget::startUpdateTimer() {
|
||||
m_updateTimer.startRepeating(std::chrono::milliseconds(m_updateIntervalMs), [this] {
|
||||
m_dirty = false;
|
||||
@@ -258,8 +279,8 @@ void ScriptedWidget::teardownScriptWatch() {
|
||||
void ScriptedWidget::reloadScript() {
|
||||
m_updateTimer.stop();
|
||||
m_glyphVisible = false;
|
||||
m_textColorRole = std::nullopt;
|
||||
m_glyphColorRole = std::nullopt;
|
||||
m_textColor = {};
|
||||
m_glyphColor = {};
|
||||
m_updateIntervalMs = 250;
|
||||
if (m_glyph)
|
||||
m_glyph->setVisible(false);
|
||||
|
||||
@@ -36,8 +36,8 @@ public:
|
||||
|
||||
void luaSetText(std::string_view text);
|
||||
void luaSetGlyph(std::string_view name);
|
||||
void luaSetColor(std::string_view role);
|
||||
void luaSetGlyphColor(std::string_view role);
|
||||
void luaSetColor(std::string_view role, std::string_view mode);
|
||||
void luaSetGlyphColor(std::string_view role, std::string_view mode);
|
||||
void luaSetVisible(bool visible);
|
||||
void luaSetUpdateInterval(float ms);
|
||||
[[nodiscard]] IpcDispatchResult dispatchIpcEvent(std::string_view event, std::string_view payload);
|
||||
@@ -46,9 +46,24 @@ public:
|
||||
[[nodiscard]] const std::unordered_map<std::string, WidgetSettingValue>& settings() const { return m_settings; }
|
||||
|
||||
private:
|
||||
enum class ScriptColorMode {
|
||||
Auto,
|
||||
Script,
|
||||
};
|
||||
|
||||
struct ScriptColorState {
|
||||
std::optional<ColorRole> role;
|
||||
ScriptColorMode mode = ScriptColorMode::Auto;
|
||||
|
||||
bool operator==(const ScriptColorState&) const = default;
|
||||
};
|
||||
|
||||
void doLayout(Renderer& renderer, float containerWidth, float containerHeight) override;
|
||||
void doUpdate(Renderer& renderer) override;
|
||||
|
||||
[[nodiscard]] ColorSpec resolveScriptColor(const ScriptColorState& state) const noexcept;
|
||||
[[nodiscard]] static ScriptColorMode scriptColorModeFromToken(std::string_view token) noexcept;
|
||||
|
||||
void reloadScript();
|
||||
void setupScriptWatch();
|
||||
void teardownScriptWatch();
|
||||
@@ -65,8 +80,8 @@ private:
|
||||
Flex* m_flex = nullptr;
|
||||
Glyph* m_glyph = nullptr;
|
||||
Label* m_label = nullptr;
|
||||
std::optional<ColorRole> m_textColorRole;
|
||||
std::optional<ColorRole> m_glyphColorRole;
|
||||
ScriptColorState m_textColor;
|
||||
ScriptColorState m_glyphColor;
|
||||
int m_updateIntervalMs = 250;
|
||||
bool m_dirty = false;
|
||||
bool m_isVertical = false;
|
||||
|
||||
Reference in New Issue
Block a user