载入中...
搜索中...
未找到
Theme.cpp
浏览该文件的文档.
1#include "ui/Theme.h"
2
3#include <imgui.h>
4
5#include <algorithm>
6#include <cctype>
7
8namespace eve::ui {
9namespace {
10
11Theme g_theme = Theme::dark();
12std::string g_themeName = "dark";
13float g_uiScale = 1.f;
14float g_dpiScale = 1.f;
15
16void copy4(float dst[4], const float src[4]) {
17 dst[0] = src[0];
18 dst[1] = src[1];
19 dst[2] = src[2];
20 dst[3] = src[3];
21}
22
23void setCol(ImGuiStyle &style, ImGuiCol idx, const float c[4]) {
24 style.Colors[idx] = ImVec4(c[0], c[1], c[2], c[3]);
25}
26
27std::string toLower(std::string s) {
28 for (char &ch : s) ch = static_cast<char>(std::tolower(static_cast<unsigned char>(ch)));
29 return s;
30}
31
32} // namespace
33
35 Theme t;
36 // Defaults in Theme already describe the dark preset.
37 return t;
38}
39
41 Theme t;
42 // Shared geometry / typography with dark — only the palette changes.
43 const float text[4] = {0.12f, 0.14f, 0.18f, 1.f};
44 const float textDisabled[4] = {0.45f, 0.48f, 0.52f, 1.f};
45 const float windowBg[4] = {0.94f, 0.95f, 0.97f, 1.f};
46 const float childBg[4] = {0.90f, 0.92f, 0.95f, 1.f};
47 const float popupBg[4] = {0.98f, 0.98f, 0.99f, 0.98f};
48 const float border[4] = {0.55f, 0.58f, 0.62f, 0.55f};
49 const float frameBg[4] = {0.86f, 0.88f, 0.92f, 1.f};
50 const float frameBgHovered[4] = {0.80f, 0.84f, 0.90f, 1.f};
51 const float frameBgActive[4] = {0.74f, 0.80f, 0.88f, 1.f};
52 const float titleBg[4] = {0.88f, 0.90f, 0.94f, 1.f};
53 const float titleBgActive[4] = {0.72f, 0.82f, 0.95f, 1.f};
54 const float titleBgCollapsed[4] = {0.90f, 0.92f, 0.95f, 0.85f};
55 const float button[4] = {0.26f, 0.52f, 0.90f, 0.65f};
56 const float buttonHovered[4] = {0.28f, 0.55f, 0.95f, 1.f};
57 const float buttonActive[4] = {0.18f, 0.42f, 0.82f, 1.f};
58 const float header[4] = {0.26f, 0.52f, 0.90f, 0.35f};
59 const float headerHovered[4] = {0.28f, 0.55f, 0.95f, 0.55f};
60 const float headerActive[4] = {0.26f, 0.52f, 0.90f, 0.80f};
61 const float checkMark[4] = {0.18f, 0.42f, 0.82f, 1.f};
62 const float sliderGrab[4] = {0.30f, 0.55f, 0.92f, 0.90f};
63 const float sliderGrabActive[4] = {0.22f, 0.48f, 0.88f, 1.f};
64 const float separator[4] = {0.60f, 0.62f, 0.66f, 0.55f};
65 const float scrollbarBg[4] = {0.85f, 0.87f, 0.90f, 0.60f};
66 const float scrollbarGrab[4] = {0.55f, 0.58f, 0.62f, 0.80f};
67 const float scrollbarGrabHovered[4] = {0.45f, 0.48f, 0.52f, 0.90f};
68 const float scrollbarGrabActive[4] = {0.35f, 0.38f, 0.42f, 1.f};
69
70 copy4(t.text, text);
71 copy4(t.textDisabled, textDisabled);
72 copy4(t.windowBg, windowBg);
73 copy4(t.childBg, childBg);
74 copy4(t.popupBg, popupBg);
75 copy4(t.border, border);
76 copy4(t.frameBg, frameBg);
79 copy4(t.titleBg, titleBg);
82 copy4(t.button, button);
84 copy4(t.buttonActive, buttonActive);
85 copy4(t.header, header);
87 copy4(t.headerActive, headerActive);
88 copy4(t.checkMark, checkMark);
89 copy4(t.sliderGrab, sliderGrab);
91 copy4(t.separator, separator);
92 copy4(t.scrollbarBg, scrollbarBg);
96 return t;
97}
98
99Theme &globalTheme() { return g_theme; }
100
101const std::string &globalThemeName() { return g_themeName; }
102
103void setGlobalTheme(const Theme &theme) { setGlobalTheme(theme, "custom"); }
104
105void setGlobalTheme(const Theme &theme, const std::string &name) {
106 g_theme = theme;
107 g_themeName = name.empty() ? "custom" : name;
108}
109
110bool setThemeByName(const std::string &name) {
111 const std::string key = toLower(name);
112 if (key == "dark") {
113 setGlobalTheme(Theme::dark(), "dark");
114 return true;
115 }
116 if (key == "light") {
117 setGlobalTheme(Theme::light(), "light");
118 return true;
119 }
120 return false;
121}
122
124 g_uiScale = std::clamp(scale, 0.5f, 5.f);
125}
126
127float themeUiScale() { return g_uiScale; }
128
129void setThemeDpiScale(float dpiScale) {
130 g_dpiScale = std::clamp(dpiScale, 1.f, 5.f);
131}
132
133float themeDpiScale() { return g_dpiScale; }
134
136
137void applyThemeToImGui(const Theme &theme, float uiScale) {
138 ImGuiContext *ctx = ImGui::GetCurrentContext();
139 if (!ctx) return;
140
141 uiScale = std::clamp(uiScale, 0.5f, 5.f);
142 const float s = uiScale;
143
144 ImGuiStyle &style = ImGui::GetStyle();
145
146 // Colors (independent of scale)
147 setCol(style, ImGuiCol_Text, theme.text);
148 setCol(style, ImGuiCol_TextDisabled, theme.textDisabled);
149 setCol(style, ImGuiCol_WindowBg, theme.windowBg);
150 setCol(style, ImGuiCol_ChildBg, theme.childBg);
151 setCol(style, ImGuiCol_PopupBg, theme.popupBg);
152 setCol(style, ImGuiCol_Border, theme.border);
153 setCol(style, ImGuiCol_FrameBg, theme.frameBg);
154 setCol(style, ImGuiCol_FrameBgHovered, theme.frameBgHovered);
155 setCol(style, ImGuiCol_FrameBgActive, theme.frameBgActive);
156 setCol(style, ImGuiCol_TitleBg, theme.titleBg);
157 setCol(style, ImGuiCol_TitleBgActive, theme.titleBgActive);
158 setCol(style, ImGuiCol_TitleBgCollapsed, theme.titleBgCollapsed);
159 setCol(style, ImGuiCol_Button, theme.button);
160 setCol(style, ImGuiCol_ButtonHovered, theme.buttonHovered);
161 setCol(style, ImGuiCol_ButtonActive, theme.buttonActive);
162 setCol(style, ImGuiCol_Header, theme.header);
163 setCol(style, ImGuiCol_HeaderHovered, theme.headerHovered);
164 setCol(style, ImGuiCol_HeaderActive, theme.headerActive);
165 setCol(style, ImGuiCol_CheckMark, theme.checkMark);
166 setCol(style, ImGuiCol_SliderGrab, theme.sliderGrab);
167 setCol(style, ImGuiCol_SliderGrabActive, theme.sliderGrabActive);
168 setCol(style, ImGuiCol_Separator, theme.separator);
169 setCol(style, ImGuiCol_ScrollbarBg, theme.scrollbarBg);
170 setCol(style, ImGuiCol_ScrollbarGrab, theme.scrollbarGrab);
171 setCol(style, ImGuiCol_ScrollbarGrabHovered, theme.scrollbarGrabHovered);
172 setCol(style, ImGuiCol_ScrollbarGrabActive, theme.scrollbarGrabActive);
173
174 // Geometry + typography (scaled)
175 style.WindowRounding = theme.windowRounding * s;
176 style.ChildRounding = theme.childRounding * s;
177 style.FrameRounding = theme.frameRounding * s;
178 style.PopupRounding = theme.popupRounding * s;
179 style.ScrollbarRounding = theme.scrollbarRounding * s;
180 style.GrabRounding = theme.grabRounding * s;
181 style.TabRounding = theme.tabRounding * s;
182
183 style.WindowBorderSize = theme.windowBorderSize * s;
184 style.ChildBorderSize = theme.childBorderSize * s;
185 style.PopupBorderSize = theme.popupBorderSize * s;
186 style.FrameBorderSize = theme.frameBorderSize * s;
187
188 style.WindowPadding = ImVec2(theme.windowPaddingX * s, theme.windowPaddingY * s);
189 style.FramePadding = ImVec2(theme.framePaddingX * s, theme.framePaddingY * s);
190 style.ItemSpacing = ImVec2(theme.itemSpacingX * s, theme.itemSpacingY * s);
191 style.ItemInnerSpacing = ImVec2(theme.itemInnerSpacingX * s, theme.itemInnerSpacingY * s);
192 style.IndentSpacing = theme.indentSpacing * s;
193 style.ScrollbarSize = theme.scrollbarSize * s;
194 style.GrabMinSize = theme.grabMinSize * s;
195
196 ImGuiIO &io = ImGui::GetIO();
197 // The font atlas is rasterized at `baseSize * dpiScale` so glyphs stay
198 // crisp on HiDPI displays, but ImGui already scales the whole frame by
199 // io.DisplayFramebufferScale (which is the same DPI ratio). Cancelling it
200 // here keeps the logical text size constant across display densities, so
201 // the UI no longer double-scales (appears too large) on high-res screens.
202 // FontGlobalScale carries the logical UI scale (uiScale) on top of the
203 // user's per-theme font preference (theme.fontScale).
204 const float dpi = std::clamp(g_dpiScale, 1.f, 5.f);
205 io.FontGlobalScale = theme.fontScale * (s / dpi);
206
207 if (theme.navEnableKeyboard) io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
208 else io.ConfigFlags &= ~ImGuiConfigFlags_NavEnableKeyboard;
209 if (theme.navEnableGamepad) io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
210 else io.ConfigFlags &= ~ImGuiConfigFlags_NavEnableGamepad;
211}
212
213} // namespace eve::ui
Object::Ptr theme
uint32_t c
int idx
const char * name
Definition RockMesh.cpp:21
float scale
Definition TreeMesh.cpp:122
uint32_t s
Definition Weather.cpp:28
void applyThemeToImGui(const Theme &theme)
Push tokens into ImGui style. Metrics are multiplied by uiScale (default: themeUiScale()).
Definition Theme.cpp:135
void setGlobalTheme(const Theme &theme)
Definition Theme.cpp:103
float themeDpiScale()
Definition Theme.cpp:133
void setThemeDpiScale(float dpiScale)
Definition Theme.cpp:129
bool setThemeByName(const std::string &name)
Apply a named preset ("dark" / "light"). Case-insensitive. Returns false if unknown.
Definition Theme.cpp:110
void setThemeUiScale(float scale)
Logical (point-space) UI scale. Default 1.0.
Definition Theme.cpp:123
float themeUiScale()
Definition Theme.cpp:127
const std::string & globalThemeName()
Current preset name: "dark", "light", or "custom".
Definition Theme.cpp:101
Theme & globalTheme()
Definition Theme.cpp:99
Unified UI design tokens (colors, geometry, typography). Applied to ImGui each frame via applyThemeTo...
Definition Theme.h:12
float titleBg[4]
Definition Theme.h:23
float frameBg[4]
Definition Theme.h:20
float checkMark[4]
Definition Theme.h:32
float sliderGrab[4]
Definition Theme.h:33
float scrollbarGrab[4]
Definition Theme.h:37
float buttonHovered[4]
Definition Theme.h:27
float buttonActive[4]
Definition Theme.h:28
float textDisabled[4]
Definition Theme.h:15
float separator[4]
Definition Theme.h:35
float titleBgActive[4]
Definition Theme.h:24
float popupBg[4]
Definition Theme.h:18
float header[4]
Definition Theme.h:29
float titleBgCollapsed[4]
Definition Theme.h:25
float scrollbarGrabHovered[4]
Definition Theme.h:38
float text[4]
Definition Theme.h:14
float scrollbarGrabActive[4]
Definition Theme.h:39
float frameBgActive[4]
Definition Theme.h:22
float windowBg[4]
Definition Theme.h:16
static Theme light()
Definition Theme.cpp:40
float sliderGrabActive[4]
Definition Theme.h:34
float headerHovered[4]
Definition Theme.h:30
float frameBgHovered[4]
Definition Theme.h:21
float childBg[4]
Definition Theme.h:17
float headerActive[4]
Definition Theme.h:31
float button[4]
Definition Theme.h:26
float scrollbarBg[4]
Definition Theme.h:36
static Theme dark()
Built-in presets with matching geometry; only colors differ.
Definition Theme.cpp:34
float border[4]
Definition Theme.h:19