chore: refactor

This commit is contained in:
2026-01-31 05:04:50 +03:00
parent 4697f69dac
commit 2d015c6fb7
14 changed files with 731 additions and 279 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

After

Width:  |  Height:  |  Size: 856 KiB

View File

@@ -6,7 +6,7 @@
namespace clrsync::core
{
const std::string GIT_SEMVER = "1.0.5+git.g3cd637d";
const std::string GIT_SEMVER = "1.0.5+git.g4697f69";
const std::string version_string();
} // namespace clrsync::core

View File

@@ -1,14 +1,15 @@
set(GUI_SOURCES
main.cpp
theme/app_theme.cpp
views/color_scheme_editor.cpp
views/color_table_renderer.cpp
views/preview_renderer.cpp
controllers/theme_applier.cpp
views/template_editor.cpp
controllers/palette_controller.cpp
controllers/template_controller.cpp
views/about_window.cpp
views/settings_window.cpp
controllers/theme_applier.cpp
controllers/palette_controller.cpp
controllers/template_controller.cpp
widgets/colors.cpp
widgets/dialogs.cpp
widgets/palette_selector.cpp

View File

@@ -1,162 +1,53 @@
#include "gui/controllers/theme_applier.hpp"
#include "imgui.h"
#include "gui/theme/app_theme.hpp"
namespace theme_applier
{
static uint32_t get_color_u32(const clrsync::core::palette &current, const std::string &key)
{
const auto &col = current.get_color(key);
const uint32_t hex = col.hex();
// Convert from RRGGBBAA to AABBGGRR (ImGui format)
const uint32_t r = (hex >> 24) & 0xFF;
const uint32_t g = (hex >> 16) & 0xFF;
const uint32_t b = (hex >> 8) & 0xFF;
const uint32_t a = hex & 0xFF;
return (a << 24) | (b << 16) | (g << 8) | r;
}
void apply_to_editor(TextEditor &editor, const clrsync::core::palette &current)
{
using namespace clrsync::gui::theme;
auto get_color_u32 = [&](const std::string &key) -> uint32_t {
const auto &col = current.get_color(key);
return color_utils::to_imgui_u32(col.hex());
};
auto palette = editor.GetPalette();
palette[int(TextEditor::PaletteIndex::Default)] = get_color_u32(current, "editor_main");
palette[int(TextEditor::PaletteIndex::Keyword)] = get_color_u32(current, "editor_command");
palette[int(TextEditor::PaletteIndex::Number)] = get_color_u32(current, "editor_warning");
palette[int(TextEditor::PaletteIndex::String)] = get_color_u32(current, "editor_string");
palette[int(TextEditor::PaletteIndex::CharLiteral)] = get_color_u32(current, "editor_string");
palette[int(TextEditor::PaletteIndex::Punctuation)] = get_color_u32(current, "editor_main");
palette[int(TextEditor::PaletteIndex::Preprocessor)] =
get_color_u32(current, "editor_emphasis");
palette[int(TextEditor::PaletteIndex::Identifier)] = get_color_u32(current, "editor_main");
palette[int(TextEditor::PaletteIndex::KnownIdentifier)] = get_color_u32(current, "editor_link");
palette[int(TextEditor::PaletteIndex::PreprocIdentifier)] =
get_color_u32(current, "editor_link");
palette[int(TextEditor::PaletteIndex::Default)] = get_color_u32("editor_main");
palette[int(TextEditor::PaletteIndex::Keyword)] = get_color_u32("editor_command");
palette[int(TextEditor::PaletteIndex::Number)] = get_color_u32("editor_warning");
palette[int(TextEditor::PaletteIndex::String)] = get_color_u32("editor_string");
palette[int(TextEditor::PaletteIndex::CharLiteral)] = get_color_u32("editor_string");
palette[int(TextEditor::PaletteIndex::Punctuation)] = get_color_u32("editor_main");
palette[int(TextEditor::PaletteIndex::Preprocessor)] = get_color_u32("editor_emphasis");
palette[int(TextEditor::PaletteIndex::Identifier)] = get_color_u32("editor_main");
palette[int(TextEditor::PaletteIndex::KnownIdentifier)] = get_color_u32("editor_link");
palette[int(TextEditor::PaletteIndex::PreprocIdentifier)] = get_color_u32("editor_link");
palette[int(TextEditor::PaletteIndex::Comment)] = get_color_u32(current, "editor_comment");
palette[int(TextEditor::PaletteIndex::MultiLineComment)] =
get_color_u32(current, "editor_comment");
palette[int(TextEditor::PaletteIndex::Comment)] = get_color_u32("editor_comment");
palette[int(TextEditor::PaletteIndex::MultiLineComment)] = get_color_u32("editor_comment");
palette[int(TextEditor::PaletteIndex::Background)] =
get_color_u32(current, "editor_background");
palette[int(TextEditor::PaletteIndex::Cursor)] = get_color_u32(current, "cursor");
palette[int(TextEditor::PaletteIndex::Background)] = get_color_u32("editor_background");
palette[int(TextEditor::PaletteIndex::Cursor)] = get_color_u32("cursor");
palette[int(TextEditor::PaletteIndex::Selection)] = get_color_u32(current, "editor_selected");
palette[int(TextEditor::PaletteIndex::ErrorMarker)] = get_color_u32(current, "editor_error");
palette[int(TextEditor::PaletteIndex::Breakpoint)] = get_color_u32(current, "editor_error");
palette[int(TextEditor::PaletteIndex::Selection)] = get_color_u32("editor_selected");
palette[int(TextEditor::PaletteIndex::ErrorMarker)] = get_color_u32("editor_error");
palette[int(TextEditor::PaletteIndex::Breakpoint)] = get_color_u32("editor_error");
palette[int(TextEditor::PaletteIndex::LineNumber)] =
get_color_u32(current, "editor_line_number");
palette[int(TextEditor::PaletteIndex::LineNumber)] = get_color_u32("editor_line_number");
palette[int(TextEditor::PaletteIndex::CurrentLineFill)] =
get_color_u32(current, "surface_variant");
palette[int(TextEditor::PaletteIndex::CurrentLineFillInactive)] =
get_color_u32(current, "surface");
palette[int(TextEditor::PaletteIndex::CurrentLineEdge)] =
get_color_u32(current, "border_focused");
palette[int(TextEditor::PaletteIndex::CurrentLineFill)] = get_color_u32("surface_variant");
palette[int(TextEditor::PaletteIndex::CurrentLineFillInactive)] = get_color_u32("surface");
palette[int(TextEditor::PaletteIndex::CurrentLineEdge)] = get_color_u32("border_focused");
editor.SetPalette(palette);
}
void apply_to_imgui(const clrsync::core::palette &current)
{
auto getColor = [&](const std::string &key) -> ImVec4 {
const auto &col = current.get_color(key);
const uint32_t hex = col.hex();
return {((hex >> 24) & 0xFF) / 255.0f, ((hex >> 16) & 0xFF) / 255.0f,
((hex >> 8) & 0xFF) / 255.0f, ((hex) & 0xFF) / 255.0f};
};
ImGuiStyle &style = ImGui::GetStyle();
const ImVec4 bg = getColor("background");
const ImVec4 onBg = getColor("on_background");
const ImVec4 surface = getColor("surface");
const ImVec4 onSurface = getColor("on_surface");
const ImVec4 surfaceVariant = getColor("surface_variant");
const ImVec4 onSurfaceVariant = getColor("on_surface_variant");
const ImVec4 fg = getColor("foreground");
const ImVec4 fgInactive = getColor("editor_inactive");
const ImVec4 accent = getColor("accent");
const ImVec4 border = getColor("border");
const ImVec4 error = getColor("error");
const ImVec4 onError = getColor("on_error");
const ImVec4 success = getColor("success");
const ImVec4 onSuccess = getColor("on_success");
const ImVec4 warning = getColor("warning");
const ImVec4 onWarning = getColor("on_warning");
const ImVec4 info = getColor("info");
const ImVec4 onInfo = getColor("on_info");
style.Colors[ImGuiCol_WindowBg] = bg;
style.Colors[ImGuiCol_ChildBg] = surface;
style.Colors[ImGuiCol_PopupBg] = surface;
style.Colors[ImGuiCol_Border] = border;
style.Colors[ImGuiCol_BorderShadow] = ImVec4(0, 0, 0, 0);
style.Colors[ImGuiCol_Text] = onSurface;
style.Colors[ImGuiCol_TextDisabled] = onSurfaceVariant;
style.Colors[ImGuiCol_TextSelectedBg] = accent;
style.Colors[ImGuiCol_Header] = surfaceVariant;
style.Colors[ImGuiCol_HeaderHovered] = ImVec4(accent.x, accent.y, accent.z, 0.8f);
style.Colors[ImGuiCol_HeaderActive] = accent;
style.Colors[ImGuiCol_Button] = surfaceVariant;
style.Colors[ImGuiCol_ButtonHovered] = ImVec4(accent.x, accent.y, accent.z, 0.6f);
style.Colors[ImGuiCol_ButtonActive] = accent;
style.Colors[ImGuiCol_FrameBg] = surfaceVariant;
style.Colors[ImGuiCol_FrameBgHovered] =
ImVec4(surfaceVariant.x * 1.1f, surfaceVariant.y * 1.1f, surfaceVariant.z * 1.1f, 1.0f);
style.Colors[ImGuiCol_FrameBgActive] =
ImVec4(surfaceVariant.x * 1.2f, surfaceVariant.y * 1.2f, surfaceVariant.z * 1.2f, 1.0f);
style.Colors[ImGuiCol_TitleBg] = surface;
style.Colors[ImGuiCol_TitleBgActive] = surfaceVariant;
style.Colors[ImGuiCol_TitleBgCollapsed] = surface;
style.Colors[ImGuiCol_ScrollbarBg] = surface;
style.Colors[ImGuiCol_ScrollbarGrab] = surfaceVariant;
style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(accent.x, accent.y, accent.z, 0.6f);
style.Colors[ImGuiCol_ScrollbarGrabActive] = accent;
style.Colors[ImGuiCol_SliderGrab] = accent;
style.Colors[ImGuiCol_SliderGrabActive] =
ImVec4(accent.x * 1.2f, accent.y * 1.2f, accent.z * 1.2f, 1.0f);
style.Colors[ImGuiCol_CheckMark] = accent;
style.Colors[ImGuiCol_ResizeGrip] = surfaceVariant;
style.Colors[ImGuiCol_ResizeGripHovered] = ImVec4(accent.x, accent.y, accent.z, 0.6f);
style.Colors[ImGuiCol_ResizeGripActive] = accent;
style.Colors[ImGuiCol_Tab] = surface;
style.Colors[ImGuiCol_TabHovered] = ImVec4(accent.x, accent.y, accent.z, 0.8f);
style.Colors[ImGuiCol_TabActive] = surfaceVariant;
style.Colors[ImGuiCol_TabUnfocused] = surface;
style.Colors[ImGuiCol_TabUnfocusedActive] = surfaceVariant;
style.Colors[ImGuiCol_TabSelectedOverline] = accent;
style.Colors[ImGuiCol_TableHeaderBg] = surfaceVariant;
style.Colors[ImGuiCol_TableBorderStrong] = border;
style.Colors[ImGuiCol_TableBorderLight] =
ImVec4(border.x * 0.7f, border.y * 0.7f, border.z * 0.7f, border.w);
style.Colors[ImGuiCol_TableRowBg] = ImVec4(0, 0, 0, 0);
style.Colors[ImGuiCol_TableRowBgAlt] =
ImVec4(onSurfaceVariant.x, onSurfaceVariant.y, onSurfaceVariant.z, 0.06f);
style.Colors[ImGuiCol_Separator] = border;
style.Colors[ImGuiCol_SeparatorHovered] = accent;
style.Colors[ImGuiCol_SeparatorActive] = accent;
style.Colors[ImGuiCol_MenuBarBg] = surface;
style.Colors[ImGuiCol_DockingPreview] = ImVec4(accent.x, accent.y, accent.z, 0.7f);
style.Colors[ImGuiCol_DockingEmptyBg] = bg;
clrsync::gui::theme::set_theme(current);
}
} // namespace theme_applier

View File

@@ -7,6 +7,7 @@
namespace theme_applier
{
void apply_to_imgui(const clrsync::core::palette &pal);
void apply_to_editor(TextEditor &editor, const clrsync::core::palette &pal);
} // namespace theme_applier

View File

@@ -5,40 +5,44 @@
namespace clrsync::gui::layout
{
namespace
{
constexpr float TOPBAR_HEIGHT = 36.0f;
constexpr float TOPBAR_PADDING_X = 12.0f;
constexpr float TOPBAR_PADDING_Y = 4.0f;
constexpr float BUTTON_SPACING = 8.0f;
}
void main_layout::render_menu_bar()
{
ImGuiViewport *vp = ImGui::GetMainViewport();
const float bar_height = 30.0f;
ImGui::SetNextWindowPos(vp->Pos);
ImGui::SetNextWindowSize(ImVec2(vp->Size.x, bar_height));
ImGui::SetNextWindowSize(ImVec2(vp->Size.x, TOPBAR_HEIGHT));
ImGui::SetNextWindowViewport(vp->ID);
ImGuiWindowFlags flags = ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar |
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings;
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8, 2));
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(TOPBAR_PADDING_X, TOPBAR_PADDING_Y));
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(8, 3));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(BUTTON_SPACING, 6.0f));
ImGui::Begin("##TopBar", nullptr, flags);
ImGuiStyle &style = ImGui::GetStyle();
style.FrameBorderSize = 1.0f;
const char *settings_label = "Settings";
const char *about_label = "About";
ImGuiStyle &style = ImGui::GetStyle();
ImVec2 settings_size = ImGui::CalcTextSize(settings_label);
ImVec2 about_size = ImGui::CalcTextSize(about_label);
float total_width = settings_size.x + style.FramePadding.x * 2.0f + about_size.x +
style.FramePadding.x * 2.0f + style.ItemSpacing.x;
float pos_x = ImGui::GetWindowWidth() - total_width - style.WindowPadding.x;
float pos_x = ImGui::GetWindowWidth() - total_width - TOPBAR_PADDING_X;
float button_height = ImGui::GetFrameHeight();
float window_height = ImGui::GetWindowHeight();
@@ -47,29 +51,24 @@ void main_layout::render_menu_bar()
ImGui::SetCursorPos(ImVec2(pos_x, center_y));
if (ImGui::Button(settings_label))
{
m_show_settings = true;
}
ImGui::SameLine();
ImGui::SetCursorPosY(center_y);
if (ImGui::Button(about_label))
{
m_show_about = true;
}
ImGui::End();
ImGui::PopStyleVar(4);
}
void main_layout::setup_dockspace(bool &first_time)
{
const ImGuiViewport *viewport = ImGui::GetMainViewport();
const float topbar_height = 32.0f;
ImGui::SetNextWindowPos(ImVec2(viewport->Pos.x, viewport->Pos.y + topbar_height));
ImGui::SetNextWindowSize(ImVec2(viewport->Size.x, viewport->Size.y - topbar_height));
ImGui::SetNextWindowPos(ImVec2(viewport->Pos.x, viewport->Pos.y + TOPBAR_HEIGHT));
ImGui::SetNextWindowSize(ImVec2(viewport->Size.x, viewport->Size.y - TOPBAR_HEIGHT));
ImGui::SetNextWindowViewport(viewport->ID);
constexpr ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
@@ -80,9 +79,8 @@ void main_layout::setup_dockspace(bool &first_time)
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(8, 3));
ImGui::Begin("MainDockSpace", nullptr, flags);
ImGui::PopStyleVar(4);
ImGui::PopStyleVar(3);
ImGuiID dockspace_id = ImGui::GetID("MainDockSpace");
@@ -95,13 +93,11 @@ void main_layout::setup_dockspace(bool &first_time)
ImGui::DockBuilderSetNodeSize(dockspace_id, viewport->Size);
ImGuiID center, right;
ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Right, 0.5f, &right, &center);
ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Right, 0.40f, &right, &center);
ImGuiDockNode *center_node = ImGui::DockBuilderGetNode(center);
if (center_node)
{
center_node->LocalFlags |= ImGuiDockNodeFlags_CentralNode;
}
ImGui::DockBuilderDockWindow("Color Schemes", right);
ImGui::DockBuilderDockWindow("Color Preview", center);

317
src/gui/theme/app_theme.cpp Normal file
View File

@@ -0,0 +1,317 @@
#include "app_theme.hpp"
#include <algorithm>
namespace clrsync::gui::theme
{
ImVec4 color_utils::from_hex(uint32_t hex)
{
return {
((hex >> 24) & 0xFF) / 255.0f,
((hex >> 16) & 0xFF) / 255.0f,
((hex >> 8) & 0xFF) / 255.0f,
(hex & 0xFF) / 255.0f
};
}
uint32_t color_utils::to_imgui_u32(uint32_t hex)
{
const uint32_t r = (hex >> 24) & 0xFF;
const uint32_t g = (hex >> 16) & 0xFF;
const uint32_t b = (hex >> 8) & 0xFF;
const uint32_t a = hex & 0xFF;
return (a << 24) | (b << 16) | (g << 8) | r;
}
ImVec4 color_utils::with_alpha(const ImVec4 &color, float alpha)
{
return {color.x, color.y, color.z, std::clamp(alpha, 0.0f, 1.0f)};
}
ImVec4 color_utils::lighten(const ImVec4 &color, float amount)
{
return {
std::clamp(color.x + (1.0f - color.x) * amount, 0.0f, 1.0f),
std::clamp(color.y + (1.0f - color.y) * amount, 0.0f, 1.0f),
std::clamp(color.z + (1.0f - color.z) * amount, 0.0f, 1.0f),
color.w
};
}
ImVec4 color_utils::darken(const ImVec4 &color, float amount)
{
return {
std::clamp(color.x * (1.0f - amount), 0.0f, 1.0f),
std::clamp(color.y * (1.0f - amount), 0.0f, 1.0f),
std::clamp(color.z * (1.0f - amount), 0.0f, 1.0f),
color.w
};
}
ImVec4 color_utils::blend(const ImVec4 &a, const ImVec4 &b, float t)
{
t = std::clamp(t, 0.0f, 1.0f);
return {
a.x + (b.x - a.x) * t,
a.y + (b.y - a.y) * t,
a.z + (b.z - a.z) * t,
a.w + (b.w - a.w) * t
};
}
app_theme::app_theme(const core::palette &palette)
{
apply_palette(palette);
}
ImVec4 app_theme::get_palette_color(const std::string &key,
const std::string &fallback) const
{
auto colors = m_palette.colors();
if (colors.empty())
return ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
auto it = colors.find(key);
if (it == colors.end() && !fallback.empty())
it = colors.find(fallback);
if (it != colors.end())
return color_utils::from_hex(it->second.hex());
return ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
}
void app_theme::apply_palette(const core::palette &palette)
{
m_palette = palette;
if (palette.colors().empty())
return;
const ImVec4 background = get_palette_color("background");
const ImVec4 on_background = get_palette_color("on_background");
const ImVec4 surface = get_palette_color("surface");
const ImVec4 on_surface = get_palette_color("on_surface");
const ImVec4 surface_variant = get_palette_color("surface_variant");
const ImVec4 on_surface_variant = get_palette_color("on_surface_variant");
const ImVec4 border_base = get_palette_color("border");
const ImVec4 border_focused_base = get_palette_color("border_focused");
const ImVec4 accent_base = get_palette_color("accent");
const ImVec4 accent_secondary_base = get_palette_color("accent_secondary");
const ImVec4 success_base = get_palette_color("success");
const ImVec4 on_success_base = get_palette_color("on_success");
const ImVec4 warning_base = get_palette_color("warning");
const ImVec4 on_warning_base = get_palette_color("on_warning");
const ImVec4 error_base = get_palette_color("error");
const ImVec4 on_error_base = get_palette_color("on_error");
const ImVec4 info_base = get_palette_color("info");
const ImVec4 on_info_base = get_palette_color("on_info");
m_window_bg = background;
m_child_bg = color_utils::with_alpha(surface, 0.0f); // Transparent child bg
m_popup_bg = color_utils::with_alpha(surface_variant, 0.98f);
m_modal_dim_bg = ImVec4(0.0f, 0.0f, 0.0f, 0.5f);
m_text = on_surface;
m_text_disabled = on_surface_variant;
m_text_selected_bg = color_utils::with_alpha(accent_base, 0.4f);
m_border = border_base;
m_border_focused = border_focused_base;
m_separator = border_base;
m_button = surface_variant;
m_button_hovered = color_utils::with_alpha(accent_base, 0.7f);
m_button_active = accent_base;
m_header = surface_variant;
m_header_hovered = color_utils::with_alpha(accent_base, 0.7f);
m_header_active = accent_base;
m_frame_bg = surface_variant;
m_frame_bg_hovered = color_utils::lighten(surface_variant, 0.08f);
m_frame_bg_active = color_utils::lighten(surface_variant, 0.15f);
m_tab = surface;
m_tab_hovered = color_utils::with_alpha(accent_base, 0.7f);
m_tab_active = surface_variant;
m_tab_unfocused = surface;
m_tab_unfocused_active = surface_variant;
m_scrollbar_bg = color_utils::with_alpha(surface, 0.5f);
m_scrollbar_grab = surface_variant;
m_scrollbar_grab_hovered = color_utils::with_alpha(accent_base, 0.7f);
m_scrollbar_grab_active = accent_base;
m_slider_grab = accent_base;
m_slider_grab_active = color_utils::lighten(accent_base, 0.2f);
m_table_header_bg = surface_variant;
m_table_border_strong = border_base;
m_table_border_light = color_utils::darken(border_base, 0.3f);
m_table_row_bg = ImVec4(0, 0, 0, 0);
m_table_row_bg_alt = color_utils::with_alpha(on_surface_variant, 0.04f);
m_title_bg = surface;
m_title_bg_active = surface_variant;
m_title_bg_collapsed = color_utils::with_alpha(surface, 0.75f);
m_docking_preview = color_utils::with_alpha(accent_base, 0.7f);
m_docking_empty_bg = background;
m_accent = accent_base;
m_accent_secondary = accent_secondary_base;
m_success = success_base;
m_success_hovered = color_utils::lighten(success_base, 0.2f);
m_success_active = color_utils::darken(success_base, 0.2f);
m_on_success = on_success_base;
m_warning = warning_base;
m_warning_hovered = color_utils::lighten(warning_base, 0.2f);
m_warning_active = color_utils::darken(warning_base, 0.2f);
m_on_warning = on_warning_base;
m_error = error_base;
m_error_hovered = color_utils::lighten(error_base, 0.2f);
m_error_active = color_utils::darken(error_base, 0.2f);
m_on_error = on_error_base;
m_info = info_base;
m_info_hovered = color_utils::lighten(info_base, 0.2f);
m_info_active = color_utils::darken(info_base, 0.2f);
m_on_info = on_info_base;
m_checkmark = accent_base;
m_resize_grip = color_utils::with_alpha(surface_variant, 0.5f);
m_resize_grip_hovered = color_utils::with_alpha(accent_base, 0.7f);
m_resize_grip_active = accent_base;
m_autocomplete_bg = color_utils::with_alpha(surface_variant, 0.98f);
m_autocomplete_border = border_focused_base;
m_autocomplete_selected = color_utils::with_alpha(accent_base, 0.9f);
m_autocomplete_text = on_surface;
m_autocomplete_selected_text = on_surface;
m_autocomplete_dim_text = on_surface_variant;
}
void app_theme::apply_style_vars() const
{
ImGuiStyle &style = ImGui::GetStyle();
style.WindowRounding = WINDOW_ROUNDING;
style.ChildRounding = FRAME_ROUNDING;
style.FrameRounding = FRAME_ROUNDING;
style.PopupRounding = POPUP_ROUNDING;
style.ScrollbarRounding = SCROLLBAR_ROUNDING;
style.GrabRounding = GRAB_ROUNDING;
style.TabRounding = TAB_ROUNDING;
style.FrameBorderSize = FRAME_BORDER_SIZE;
style.WindowBorderSize = WINDOW_BORDER_SIZE;
style.PopupBorderSize = POPUP_BORDER_SIZE;
style.WindowPadding = WINDOW_PADDING;
style.FramePadding = FRAME_PADDING;
style.ItemSpacing = ITEM_SPACING;
style.ItemInnerSpacing = ITEM_INNER_SPACING;
style.ScrollbarSize = 12.0f;
style.GrabMinSize = 10.0f;
style.SeparatorTextBorderSize = 1.0f;
style.IndentSpacing = 20.0f;
}
void app_theme::apply_to_imgui() const
{
apply_style_vars();
ImGuiStyle &style = ImGui::GetStyle();
style.Colors[ImGuiCol_WindowBg] = m_window_bg;
style.Colors[ImGuiCol_ChildBg] = m_child_bg;
style.Colors[ImGuiCol_PopupBg] = m_popup_bg;
style.Colors[ImGuiCol_ModalWindowDimBg] = m_modal_dim_bg;
style.Colors[ImGuiCol_Text] = m_text;
style.Colors[ImGuiCol_TextDisabled] = m_text_disabled;
style.Colors[ImGuiCol_TextSelectedBg] = m_text_selected_bg;
style.Colors[ImGuiCol_Border] = m_border;
style.Colors[ImGuiCol_BorderShadow] = ImVec4(0, 0, 0, 0);
style.Colors[ImGuiCol_Separator] = m_separator;
style.Colors[ImGuiCol_SeparatorHovered] = m_accent;
style.Colors[ImGuiCol_SeparatorActive] = m_accent;
style.Colors[ImGuiCol_Button] = m_button;
style.Colors[ImGuiCol_ButtonHovered] = m_button_hovered;
style.Colors[ImGuiCol_ButtonActive] = m_button_active;
style.Colors[ImGuiCol_Header] = m_header;
style.Colors[ImGuiCol_HeaderHovered] = m_header_hovered;
style.Colors[ImGuiCol_HeaderActive] = m_header_active;
style.Colors[ImGuiCol_FrameBg] = m_frame_bg;
style.Colors[ImGuiCol_FrameBgHovered] = m_frame_bg_hovered;
style.Colors[ImGuiCol_FrameBgActive] = m_frame_bg_active;
style.Colors[ImGuiCol_Tab] = m_tab;
style.Colors[ImGuiCol_TabHovered] = m_tab_hovered;
style.Colors[ImGuiCol_TabActive] = m_tab_active;
style.Colors[ImGuiCol_TabUnfocused] = m_tab_unfocused;
style.Colors[ImGuiCol_TabUnfocusedActive] = m_tab_unfocused_active;
style.Colors[ImGuiCol_TabSelectedOverline] = m_accent;
style.Colors[ImGuiCol_ScrollbarBg] = m_scrollbar_bg;
style.Colors[ImGuiCol_ScrollbarGrab] = m_scrollbar_grab;
style.Colors[ImGuiCol_ScrollbarGrabHovered] = m_scrollbar_grab_hovered;
style.Colors[ImGuiCol_ScrollbarGrabActive] = m_scrollbar_grab_active;
style.Colors[ImGuiCol_SliderGrab] = m_slider_grab;
style.Colors[ImGuiCol_SliderGrabActive] = m_slider_grab_active;
style.Colors[ImGuiCol_TableHeaderBg] = m_table_header_bg;
style.Colors[ImGuiCol_TableBorderStrong] = m_table_border_strong;
style.Colors[ImGuiCol_TableBorderLight] = m_table_border_light;
style.Colors[ImGuiCol_TableRowBg] = m_table_row_bg;
style.Colors[ImGuiCol_TableRowBgAlt] = m_table_row_bg_alt;
style.Colors[ImGuiCol_TitleBg] = m_title_bg;
style.Colors[ImGuiCol_TitleBgActive] = m_title_bg_active;
style.Colors[ImGuiCol_TitleBgCollapsed] = m_title_bg_collapsed;
style.Colors[ImGuiCol_MenuBarBg] = m_window_bg;
style.Colors[ImGuiCol_DockingPreview] = m_docking_preview;
style.Colors[ImGuiCol_DockingEmptyBg] = m_docking_empty_bg;
style.Colors[ImGuiCol_CheckMark] = m_checkmark;
style.Colors[ImGuiCol_ResizeGrip] = m_resize_grip;
style.Colors[ImGuiCol_ResizeGripHovered] = m_resize_grip_hovered;
style.Colors[ImGuiCol_ResizeGripActive] = m_resize_grip_active;
style.Colors[ImGuiCol_NavHighlight] = m_accent;
style.Colors[ImGuiCol_NavWindowingHighlight] = color_utils::with_alpha(m_accent, 0.7f);
style.Colors[ImGuiCol_NavWindowingDimBg] = m_modal_dim_bg;
style.Colors[ImGuiCol_PlotLines] = m_accent;
style.Colors[ImGuiCol_PlotLinesHovered] = m_accent;
style.Colors[ImGuiCol_PlotHistogram] = m_accent;
style.Colors[ImGuiCol_PlotHistogramHovered] = color_utils::lighten(m_accent, 0.2f);
}
static app_theme g_current_theme;
app_theme &current_theme()
{
return g_current_theme;
}
void set_theme(const core::palette &palette)
{
g_current_theme.apply_palette(palette);
g_current_theme.apply_to_imgui();
}
} // namespace clrsync::gui::theme

235
src/gui/theme/app_theme.hpp Normal file
View File

@@ -0,0 +1,235 @@
#ifndef CLRSYNC_GUI_THEME_APP_THEME_HPP
#define CLRSYNC_GUI_THEME_APP_THEME_HPP
#include "core/palette/palette.hpp"
#include "imgui.h"
#include <string>
namespace clrsync::gui::theme
{
struct color_utils
{
static ImVec4 from_hex(uint32_t hex);
static uint32_t to_imgui_u32(uint32_t hex);
static ImVec4 with_alpha(const ImVec4 &color, float alpha);
static ImVec4 lighten(const ImVec4 &color, float amount);
static ImVec4 darken(const ImVec4 &color, float amount);
static ImVec4 blend(const ImVec4 &a, const ImVec4 &b, float t);
};
class app_theme
{
public:
app_theme() = default;
explicit app_theme(const core::palette &palette);
void apply_palette(const core::palette &palette);
ImVec4 window_bg() const { return m_window_bg; }
ImVec4 child_bg() const { return m_child_bg; }
ImVec4 popup_bg() const { return m_popup_bg; }
ImVec4 modal_dim_bg() const { return m_modal_dim_bg; }
ImVec4 text() const { return m_text; }
ImVec4 text_disabled() const { return m_text_disabled; }
ImVec4 text_selected_bg() const { return m_text_selected_bg; }
ImVec4 border() const { return m_border; }
ImVec4 border_focused() const { return m_border_focused; }
ImVec4 separator() const { return m_separator; }
ImVec4 button() const { return m_button; }
ImVec4 button_hovered() const { return m_button_hovered; }
ImVec4 button_active() const { return m_button_active; }
ImVec4 header() const { return m_header; }
ImVec4 header_hovered() const { return m_header_hovered; }
ImVec4 header_active() const { return m_header_active; }
ImVec4 frame_bg() const { return m_frame_bg; }
ImVec4 frame_bg_hovered() const { return m_frame_bg_hovered; }
ImVec4 frame_bg_active() const { return m_frame_bg_active; }
ImVec4 tab() const { return m_tab; }
ImVec4 tab_hovered() const { return m_tab_hovered; }
ImVec4 tab_active() const { return m_tab_active; }
ImVec4 tab_unfocused() const { return m_tab_unfocused; }
ImVec4 tab_unfocused_active() const { return m_tab_unfocused_active; }
ImVec4 scrollbar_bg() const { return m_scrollbar_bg; }
ImVec4 scrollbar_grab() const { return m_scrollbar_grab; }
ImVec4 scrollbar_grab_hovered() const { return m_scrollbar_grab_hovered; }
ImVec4 scrollbar_grab_active() const { return m_scrollbar_grab_active; }
ImVec4 slider_grab() const { return m_slider_grab; }
ImVec4 slider_grab_active() const { return m_slider_grab_active; }
ImVec4 table_header_bg() const { return m_table_header_bg; }
ImVec4 table_border_strong() const { return m_table_border_strong; }
ImVec4 table_border_light() const { return m_table_border_light; }
ImVec4 table_row_bg() const { return m_table_row_bg; }
ImVec4 table_row_bg_alt() const { return m_table_row_bg_alt; }
ImVec4 title_bg() const { return m_title_bg; }
ImVec4 title_bg_active() const { return m_title_bg_active; }
ImVec4 title_bg_collapsed() const { return m_title_bg_collapsed; }
ImVec4 docking_preview() const { return m_docking_preview; }
ImVec4 docking_empty_bg() const { return m_docking_empty_bg; }
ImVec4 accent() const { return m_accent; }
ImVec4 accent_secondary() const { return m_accent_secondary; }
ImVec4 success() const { return m_success; }
ImVec4 success_hovered() const { return m_success_hovered; }
ImVec4 success_active() const { return m_success_active; }
ImVec4 on_success() const { return m_on_success; }
ImVec4 warning() const { return m_warning; }
ImVec4 warning_hovered() const { return m_warning_hovered; }
ImVec4 warning_active() const { return m_warning_active; }
ImVec4 on_warning() const { return m_on_warning; }
ImVec4 error() const { return m_error; }
ImVec4 error_hovered() const { return m_error_hovered; }
ImVec4 error_active() const { return m_error_active; }
ImVec4 on_error() const { return m_on_error; }
ImVec4 info() const { return m_info; }
ImVec4 info_hovered() const { return m_info_hovered; }
ImVec4 info_active() const { return m_info_active; }
ImVec4 on_info() const { return m_on_info; }
ImVec4 checkmark() const { return m_checkmark; }
ImVec4 resize_grip() const { return m_resize_grip; }
ImVec4 resize_grip_hovered() const { return m_resize_grip_hovered; }
ImVec4 resize_grip_active() const { return m_resize_grip_active; }
ImVec4 autocomplete_bg() const { return m_autocomplete_bg; }
ImVec4 autocomplete_border() const { return m_autocomplete_border; }
ImVec4 autocomplete_selected() const { return m_autocomplete_selected; }
ImVec4 autocomplete_text() const { return m_autocomplete_text; }
ImVec4 autocomplete_selected_text() const { return m_autocomplete_selected_text; }
ImVec4 autocomplete_dim_text() const { return m_autocomplete_dim_text; }
static constexpr float WINDOW_ROUNDING = 6.0f;
static constexpr float FRAME_ROUNDING = 4.0f;
static constexpr float POPUP_ROUNDING = 6.0f;
static constexpr float SCROLLBAR_ROUNDING = 4.0f;
static constexpr float GRAB_ROUNDING = 4.0f;
static constexpr float TAB_ROUNDING = 4.0f;
static constexpr float FRAME_BORDER_SIZE = 1.0f;
static constexpr float WINDOW_BORDER_SIZE = 1.0f;
static constexpr float POPUP_BORDER_SIZE = 1.0f;
static constexpr ImVec2 WINDOW_PADDING{10.0f, 10.0f};
static constexpr ImVec2 FRAME_PADDING{8.0f, 5.0f};
static constexpr ImVec2 ITEM_SPACING{8.0f, 6.0f};
static constexpr ImVec2 ITEM_INNER_SPACING{6.0f, 4.0f};
void apply_to_imgui() const;
void apply_style_vars() const;
private:
ImVec4 get_palette_color(const std::string &key,
const std::string &fallback = "") const;
core::palette m_palette;
ImVec4 m_window_bg{0.067f, 0.067f, 0.067f, 1.0f};
ImVec4 m_child_bg{0.067f, 0.067f, 0.067f, 1.0f};
ImVec4 m_popup_bg{0.098f, 0.098f, 0.098f, 0.98f};
ImVec4 m_modal_dim_bg{0.0f, 0.0f, 0.0f, 0.5f};
ImVec4 m_text{0.83f, 0.83f, 0.83f, 1.0f};
ImVec4 m_text_disabled{0.52f, 0.60f, 0.60f, 1.0f};
ImVec4 m_text_selected_bg{0.60f, 0.52f, 0.32f, 0.5f};
ImVec4 m_border{0.14f, 0.14f, 0.14f, 1.0f};
ImVec4 m_border_focused{0.18f, 0.18f, 0.18f, 1.0f};
ImVec4 m_separator{0.14f, 0.14f, 0.14f, 1.0f};
ImVec4 m_button{0.098f, 0.098f, 0.098f, 1.0f};
ImVec4 m_button_hovered{0.60f, 0.52f, 0.32f, 0.7f};
ImVec4 m_button_active{0.60f, 0.52f, 0.32f, 1.0f};
ImVec4 m_header{0.098f, 0.098f, 0.098f, 1.0f};
ImVec4 m_header_hovered{0.60f, 0.52f, 0.32f, 0.7f};
ImVec4 m_header_active{0.60f, 0.52f, 0.32f, 1.0f};
ImVec4 m_frame_bg{0.098f, 0.098f, 0.098f, 1.0f};
ImVec4 m_frame_bg_hovered{0.12f, 0.12f, 0.12f, 1.0f};
ImVec4 m_frame_bg_active{0.14f, 0.14f, 0.14f, 1.0f};
ImVec4 m_tab{0.067f, 0.067f, 0.067f, 1.0f};
ImVec4 m_tab_hovered{0.60f, 0.52f, 0.32f, 0.7f};
ImVec4 m_tab_active{0.098f, 0.098f, 0.098f, 1.0f};
ImVec4 m_tab_unfocused{0.067f, 0.067f, 0.067f, 1.0f};
ImVec4 m_tab_unfocused_active{0.098f, 0.098f, 0.098f, 1.0f};
ImVec4 m_scrollbar_bg{0.067f, 0.067f, 0.067f, 0.5f};
ImVec4 m_scrollbar_grab{0.14f, 0.14f, 0.14f, 1.0f};
ImVec4 m_scrollbar_grab_hovered{0.60f, 0.52f, 0.32f, 0.7f};
ImVec4 m_scrollbar_grab_active{0.60f, 0.52f, 0.32f, 1.0f};
ImVec4 m_slider_grab{0.60f, 0.52f, 0.32f, 1.0f};
ImVec4 m_slider_grab_active{0.72f, 0.62f, 0.38f, 1.0f};
ImVec4 m_table_header_bg{0.098f, 0.098f, 0.098f, 1.0f};
ImVec4 m_table_border_strong{0.14f, 0.14f, 0.14f, 1.0f};
ImVec4 m_table_border_light{0.10f, 0.10f, 0.10f, 1.0f};
ImVec4 m_table_row_bg{0.0f, 0.0f, 0.0f, 0.0f};
ImVec4 m_table_row_bg_alt{0.83f, 0.83f, 0.83f, 0.04f};
ImVec4 m_title_bg{0.067f, 0.067f, 0.067f, 1.0f};
ImVec4 m_title_bg_active{0.098f, 0.098f, 0.098f, 1.0f};
ImVec4 m_title_bg_collapsed{0.067f, 0.067f, 0.067f, 0.75f};
ImVec4 m_docking_preview{0.60f, 0.52f, 0.32f, 0.7f};
ImVec4 m_docking_empty_bg{0.067f, 0.067f, 0.067f, 1.0f};
ImVec4 m_accent{0.60f, 0.52f, 0.32f, 1.0f};
ImVec4 m_accent_secondary{0.60f, 0.52f, 0.32f, 1.0f};
ImVec4 m_success{0.40f, 0.54f, 0.32f, 1.0f};
ImVec4 m_success_hovered{0.48f, 0.65f, 0.38f, 1.0f};
ImVec4 m_success_active{0.32f, 0.43f, 0.26f, 1.0f};
ImVec4 m_on_success{0.82f, 0.82f, 0.82f, 1.0f};
ImVec4 m_warning{0.71f, 0.47f, 0.22f, 1.0f};
ImVec4 m_warning_hovered{0.85f, 0.56f, 0.26f, 1.0f};
ImVec4 m_warning_active{0.57f, 0.38f, 0.17f, 1.0f};
ImVec4 m_on_warning{0.82f, 0.82f, 0.82f, 1.0f};
ImVec4 m_error{0.67f, 0.31f, 0.29f, 1.0f};
ImVec4 m_error_hovered{0.80f, 0.37f, 0.35f, 1.0f};
ImVec4 m_error_active{0.53f, 0.25f, 0.23f, 1.0f};
ImVec4 m_on_error{0.82f, 0.82f, 0.82f, 1.0f};
ImVec4 m_info{0.23f, 0.54f, 0.55f, 1.0f};
ImVec4 m_info_hovered{0.27f, 0.65f, 0.66f, 1.0f};
ImVec4 m_info_active{0.18f, 0.43f, 0.44f, 1.0f};
ImVec4 m_on_info{0.82f, 0.82f, 0.82f, 1.0f};
ImVec4 m_checkmark{0.60f, 0.52f, 0.32f, 1.0f};
ImVec4 m_resize_grip{0.14f, 0.14f, 0.14f, 0.5f};
ImVec4 m_resize_grip_hovered{0.60f, 0.52f, 0.32f, 0.7f};
ImVec4 m_resize_grip_active{0.60f, 0.52f, 0.32f, 1.0f};
ImVec4 m_autocomplete_bg{0.098f, 0.098f, 0.098f, 0.98f};
ImVec4 m_autocomplete_border{0.25f, 0.25f, 0.28f, 1.0f};
ImVec4 m_autocomplete_selected{0.60f, 0.52f, 0.32f, 0.9f};
ImVec4 m_autocomplete_text{0.85f, 0.85f, 0.9f, 1.0f};
ImVec4 m_autocomplete_selected_text{1.0f, 1.0f, 1.0f, 1.0f};
ImVec4 m_autocomplete_dim_text{0.52f, 0.60f, 0.60f, 1.0f};
};
app_theme &current_theme();
void set_theme(const core::palette &palette);
} // namespace clrsync::gui::theme
#endif // CLRSYNC_GUI_THEME_APP_THEME_HPP

View File

@@ -3,6 +3,7 @@
#include "core/config/config.hpp"
#include "core/palette/color_keys.hpp"
#include "core/theme/theme_template.hpp"
#include "gui/theme/app_theme.hpp"
#include "gui/widgets/colors.hpp"
#include "gui/widgets/dialogs.hpp"
#include "gui/ui_manager.hpp"
@@ -24,12 +25,7 @@ template_editor::template_editor(clrsync::gui::ui_manager* ui_mgr)
{
m_control_state.name = "new_template";
m_autocomplete_bg_color = ImVec4(0.12f, 0.12f, 0.15f, 0.98f);
m_autocomplete_border_color = ImVec4(0.4f, 0.4f, 0.45f, 1.0f);
m_autocomplete_selected_color = ImVec4(0.25f, 0.45f, 0.75f, 0.9f);
m_autocomplete_text_color = ImVec4(0.85f, 0.85f, 0.9f, 1.0f);
m_autocomplete_selected_text_color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
m_autocomplete_dim_text_color = ImVec4(0.6f, 0.6f, 0.7f, 1.0f);
update_autocomplete_colors();
TextEditor::LanguageDefinition lang;
lang.mName = "Template";
@@ -80,12 +76,26 @@ void template_editor::setup_callbacks()
};
}
void template_editor::update_autocomplete_colors()
{
const auto &t = clrsync::gui::theme::current_theme();
m_autocomplete_bg_color = t.autocomplete_bg();
m_autocomplete_border_color = t.autocomplete_border();
m_autocomplete_selected_color = t.autocomplete_selected();
m_autocomplete_text_color = t.autocomplete_text();
m_autocomplete_selected_text_color = t.autocomplete_selected_text();
m_autocomplete_dim_text_color = t.autocomplete_dim_text();
}
void template_editor::apply_current_palette(const clrsync::core::palette &pal)
{
m_current_palette = pal;
auto colors = pal.colors();
if (colors.empty())
return;
using namespace clrsync::gui::theme;
auto get_color_u32 = [&](const std::string &key, const std::string &fallback = "") -> uint32_t {
return clrsync::gui::widgets::palette_color_u32(pal, key, fallback);
};
@@ -97,47 +107,30 @@ void template_editor::apply_current_palette(const clrsync::core::palette &pal)
palette[int(TextEditor::PaletteIndex::Number)] = get_color_u32("editor_warning", "warning");
palette[int(TextEditor::PaletteIndex::String)] = get_color_u32("editor_string", "success");
palette[int(TextEditor::PaletteIndex::CharLiteral)] = get_color_u32("editor_string", "success");
palette[int(TextEditor::PaletteIndex::Punctuation)] =
get_color_u32("editor_main", "foreground");
palette[int(TextEditor::PaletteIndex::Preprocessor)] =
get_color_u32("editor_emphasis", "accent");
palette[int(TextEditor::PaletteIndex::Punctuation)] = get_color_u32("editor_main", "foreground");
palette[int(TextEditor::PaletteIndex::Preprocessor)] = get_color_u32("editor_emphasis", "accent");
palette[int(TextEditor::PaletteIndex::Identifier)] = get_color_u32("editor_main", "foreground");
palette[int(TextEditor::PaletteIndex::KnownIdentifier)] = get_color_u32("editor_link", "info");
palette[int(TextEditor::PaletteIndex::PreprocIdentifier)] =
get_color_u32("editor_link", "info");
palette[int(TextEditor::PaletteIndex::PreprocIdentifier)] = get_color_u32("editor_link", "info");
palette[int(TextEditor::PaletteIndex::Comment)] =
get_color_u32("editor_comment", "editor_inactive");
palette[int(TextEditor::PaletteIndex::MultiLineComment)] =
get_color_u32("editor_comment", "editor_inactive");
palette[int(TextEditor::PaletteIndex::Comment)] = get_color_u32("editor_comment", "editor_inactive");
palette[int(TextEditor::PaletteIndex::MultiLineComment)] = get_color_u32("editor_comment", "editor_inactive");
palette[int(TextEditor::PaletteIndex::Background)] =
get_color_u32("editor_background", "background");
palette[int(TextEditor::PaletteIndex::Background)] = get_color_u32("editor_background", "background");
palette[int(TextEditor::PaletteIndex::Cursor)] = get_color_u32("cursor", "accent");
palette[int(TextEditor::PaletteIndex::Selection)] =
get_color_u32("editor_selected", "surface_variant");
palette[int(TextEditor::PaletteIndex::Selection)] = get_color_u32("editor_selected", "surface_variant");
palette[int(TextEditor::PaletteIndex::ErrorMarker)] = get_color_u32("editor_error", "error");
palette[int(TextEditor::PaletteIndex::Breakpoint)] = get_color_u32("editor_error", "error");
palette[int(TextEditor::PaletteIndex::LineNumber)] =
get_color_u32("editor_line_number", "editor_inactive");
palette[int(TextEditor::PaletteIndex::LineNumber)] = get_color_u32("editor_line_number", "editor_inactive");
palette[int(TextEditor::PaletteIndex::CurrentLineFill)] = get_color_u32("surface_variant");
palette[int(TextEditor::PaletteIndex::CurrentLineFillInactive)] = get_color_u32("surface");
palette[int(TextEditor::PaletteIndex::CurrentLineEdge)] =
get_color_u32("border_focused", "border");
palette[int(TextEditor::PaletteIndex::CurrentLineEdge)] = get_color_u32("border_focused", "border");
m_editor.SetPalette(palette);
m_autocomplete_bg_color = clrsync::gui::widgets::palette_color(pal, "surface", "background");
m_autocomplete_bg_color.w = 0.98f;
m_autocomplete_border_color = clrsync::gui::widgets::palette_color(pal, "border", "surface_variant");
m_autocomplete_selected_color = clrsync::gui::widgets::palette_color(pal, "accent", "surface_variant");
m_autocomplete_text_color = clrsync::gui::widgets::palette_color(pal, "on_surface", "foreground");
m_autocomplete_selected_text_color = clrsync::gui::widgets::palette_color(pal, "on_surface", "foreground");
m_autocomplete_dim_text_color =
clrsync::gui::widgets::palette_color(pal, "on_surface_variant", "editor_inactive");
update_autocomplete_colors();
}
void template_editor::update_autocomplete_suggestions()

View File

@@ -28,6 +28,7 @@ class template_editor
void render_template_list();
void render_autocomplete(const ImVec2 &editor_pos);
void update_autocomplete_suggestions();
void update_autocomplete_colors();
void save_template();
void load_template(const std::string &name);

View File

@@ -17,7 +17,7 @@ void action_buttons::clear()
m_buttons.clear();
}
void action_buttons::render(const core::palette &theme_palette)
void action_buttons::render(const core::palette &)
{
if (m_buttons.empty())
return;
@@ -37,30 +37,16 @@ void action_buttons::render(const core::palette &theme_palette)
ImGui::SameLine();
first = false;
int style_colors_pushed = 0;
bool has_style = false;
if (button.use_error_style)
{
auto error = palette_color(theme_palette, "error");
auto error_hover = ImVec4(error.x * 1.1f, error.y * 1.1f, error.z * 1.1f, error.w);
auto error_active = ImVec4(error.x * 0.8f, error.y * 0.8f, error.z * 0.8f, error.w);
auto on_error = palette_color(theme_palette, "on_error");
ImGui::PushStyleColor(ImGuiCol_Button, error);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, error_hover);
ImGui::PushStyleColor(ImGuiCol_ButtonActive, error_active);
ImGui::PushStyleColor(ImGuiCol_Text, on_error);
style_colors_pushed = 4;
push_error_button_style();
has_style = true;
}
else if (button.use_success_style)
{
auto success = palette_color(theme_palette, "success", "accent");
auto success_hover = ImVec4(success.x * 1.1f, success.y * 1.1f, success.z * 1.1f, success.w);
auto success_active = ImVec4(success.x * 0.8f, success.y * 0.8f, success.z * 0.8f, success.w);
auto on_success = palette_color(theme_palette, "on_success", "on_surface");
ImGui::PushStyleColor(ImGuiCol_Button, success);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, success_hover);
ImGui::PushStyleColor(ImGuiCol_ButtonActive, success_active);
ImGui::PushStyleColor(ImGuiCol_Text, on_success);
style_colors_pushed = 4;
push_success_button_style();
has_style = true;
}
bool disabled = !button.enabled;
@@ -70,22 +56,18 @@ void action_buttons::render(const core::palette &theme_palette)
if (ImGui::Button(button.label.c_str()))
{
if (button.on_click)
{
button.on_click();
}
}
if (disabled)
ImGui::EndDisabled();
if (style_colors_pushed > 0)
ImGui::PopStyleColor(style_colors_pushed);
if (has_style)
pop_button_style();
if (!button.tooltip.empty() && ImGui::IsItemHovered())
{
ImGui::SetTooltip("%s", button.tooltip.c_str());
}
}
ImGui::PopStyleVar();
}

View File

@@ -12,20 +12,11 @@ ImVec4 palette_color(const core::palette &pal, const std::string &key,
auto it = colors.find(key);
if (it == colors.end() && !fallback.empty())
{
it = colors.find(fallback);
}
if (it != colors.end())
{
const auto &col = it->second;
const uint32_t hex = col.hex();
const float r = ((hex >> 24) & 0xFF) / 255.0f;
const float g = ((hex >> 16) & 0xFF) / 255.0f;
const float b = ((hex >> 8) & 0xFF) / 255.0f;
const float a = (hex & 0xFF) / 255.0f;
return ImVec4(r, g, b, a);
}
return theme::color_utils::from_hex(it->second.hex());
return ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
}
@@ -38,21 +29,53 @@ uint32_t palette_color_u32(const core::palette &pal, const std::string &key,
auto it = colors.find(key);
if (it == colors.end() && !fallback.empty())
{
it = colors.find(fallback);
}
if (it != colors.end())
{
const auto &col = it->second;
const uint32_t hex = col.hex();
const uint32_t r = (hex >> 24) & 0xFF;
const uint32_t g = (hex >> 16) & 0xFF;
const uint32_t b = (hex >> 8) & 0xFF;
const uint32_t a = hex & 0xFF;
return (a << 24) | (b << 16) | (g << 8) | r;
}
return theme::color_utils::to_imgui_u32(it->second.hex());
return 0xFFFFFFFF;
}
void push_success_button_style()
{
const auto &t = theme::current_theme();
ImGui::PushStyleColor(ImGuiCol_Button, t.success());
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, t.success_hovered());
ImGui::PushStyleColor(ImGuiCol_ButtonActive, t.success_active());
ImGui::PushStyleColor(ImGuiCol_Text, t.on_success());
}
void push_error_button_style()
{
const auto &t = theme::current_theme();
ImGui::PushStyleColor(ImGuiCol_Button, t.error());
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, t.error_hovered());
ImGui::PushStyleColor(ImGuiCol_ButtonActive, t.error_active());
ImGui::PushStyleColor(ImGuiCol_Text, t.on_error());
}
void push_warning_button_style()
{
const auto &t = theme::current_theme();
ImGui::PushStyleColor(ImGuiCol_Button, t.warning());
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, t.warning_hovered());
ImGui::PushStyleColor(ImGuiCol_ButtonActive, t.warning_active());
ImGui::PushStyleColor(ImGuiCol_Text, t.on_warning());
}
void push_info_button_style()
{
const auto &t = theme::current_theme();
ImGui::PushStyleColor(ImGuiCol_Button, t.info());
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, t.info_hovered());
ImGui::PushStyleColor(ImGuiCol_ButtonActive, t.info_active());
ImGui::PushStyleColor(ImGuiCol_Text, t.on_info());
}
void pop_button_style()
{
ImGui::PopStyleColor(4);
}
} // namespace clrsync::gui::widgets

View File

@@ -2,6 +2,7 @@
#define CLRSYNC_GUI_WIDGETS_COLORS_HPP
#include "core/palette/palette.hpp"
#include "gui/theme/app_theme.hpp"
#include "imgui.h"
#include <string>
@@ -14,6 +15,18 @@ ImVec4 palette_color(const core::palette &pal, const std::string &key,
uint32_t palette_color_u32(const core::palette &pal, const std::string &key,
const std::string &fallback = "");
inline const theme::app_theme &theme() { return theme::current_theme(); }
void push_success_button_style();
void push_error_button_style();
void push_warning_button_style();
void push_info_button_style();
void pop_button_style();
} // namespace clrsync::gui::widgets
#endif // CLRSYNC_GUI_WIDGETS_COLORS_HPP

View File

@@ -5,11 +5,10 @@
namespace clrsync::gui::widgets
{
void section_header(const std::string& title, const core::palette& palette)
void section_header(const std::string &title, const core::palette &)
{
ImGui::Spacing();
auto accent_color = palette_color(palette, "accent");
ImGui::TextColored(accent_color, "%s", title.c_str());
ImGui::TextColored(theme().accent(), "%s", title.c_str());
ImGui::Separator();
ImGui::Spacing();
}