- Remove outdated `undo-state.md` - Add two code quality/optimization reports that were used to guide previous work: - `code-report.md` (optimization) - `code-report-quality.md` (stability and code health) - Add `themes.md`. - Update undo system docs and roadmap.
14 KiB
Themes in kte
Overview
kte's GUI frontend (kge) uses ImGui for rendering and supports multiple color themes. Themes define the visual appearance of the editor interface including colors for text, backgrounds, buttons, borders, and other UI elements.
Theme files are located in the themes/ directory and are header-only
C++ files that configure ImGui's style system.
Available themes
Current themes (alphabetically):
- amber — Monochrome amber/black CRT-inspired theme
- eink — E-ink inspired high-contrast theme (light/dark variants)
- everforest — Warm, forest-inspired palette
- gruvbox — Retro groove color scheme (light/dark variants)
- kanagawa-paper — Inspired by traditional Japanese art
- lcars — Star Trek LCARS interface style
- nord — Arctic, north-bluish color palette
- old-book — Sepia-toned vintage book aesthetic (light/dark variants)
- orbital — Space-themed dark palette
- plan9 — Minimalist Plan 9 from Bell Labs inspired
- solarized — Ethan Schoonover's Solarized (light/dark variants)
- weyland-yutani — Alien franchise corporate aesthetic
- zenburn — Low-contrast, easy-on-the-eyes theme
Configuration
Themes are configured via $HOME/.config/kte/kge.ini:
theme = nord
background = dark
theme— The theme name (e.g., "nord", "gruvbox", "solarized")background— Either "dark" or "light" (for themes supporting both variants)
Themes can also be switched at runtime using the :theme <name>
command.
Theme structure
Each theme is a header file in themes/ that defines one or more
functions to apply the theme. The basic structure:
- Include ThemeHelpers.h — Provides the
RGBA()helper function - Define palette — Create
ImVec4color constants usingRGBA(0xRRGGBB) - Get ImGui style — Obtain reference via
ImGui::GetStyle() - Set style parameters — Configure padding, rounding, border sizes, etc.
- Assign colors — Map palette to
ImGuiCol_*enum values
Minimal example structure
// themes/MyTheme.h
#pragma once
#include "ThemeHelpers.h"
static void
ApplyMyTheme()
{
// 1. Define color palette
const ImVec4 bg = RGBA(0x1e1e1e);
const ImVec4 fg = RGBA(0xd4d4d4);
const ImVec4 accent = RGBA(0x007acc);
// 2. Get style reference
ImGuiStyle &style = ImGui::GetStyle();
// 3. Set style parameters
style.WindowPadding = ImVec2(8.0f, 8.0f);
style.FrameRounding = 3.0f;
style.WindowBorderSize = 1.0f;
// ... additional style parameters
// 4. Assign colors
ImVec4 *colors = style.Colors;
colors[ImGuiCol_Text] = fg;
colors[ImGuiCol_WindowBg] = bg;
colors[ImGuiCol_Button] = accent;
// ... additional color assignments
}
The RGBA() helper
The RGBA() function (defined in themes/ThemeHelpers.h) converts
packed RGB hex values to ImGui's ImVec4 format:
const ImVec4 color = RGBA(0xRRGGBB); // Opaque (alpha = 1.0)
const ImVec4 color = RGBA(0xRRGGBB, 0.5f); // With custom alpha
Examples:
const ImVec4 white = RGBA(0xFFFFFF);
const ImVec4 black = RGBA(0x000000);
const ImVec4 red = RGBA(0xFF0000);
const ImVec4 blue = RGBA(0x0000FF);
const ImVec4 semi = RGBA(0x808080, 0.5f); // 50% transparent gray
ImGui color elements
Themes must define colors for ImGui's UI elements. Key ImGuiCol_*
values:
Text
ImGuiCol_Text— Main text colorImGuiCol_TextDisabled— Disabled/grayed-out textImGuiCol_TextSelectedBg— Text selection background
Windows and backgrounds
ImGuiCol_WindowBg— Window backgroundImGuiCol_ChildBg— Child window backgroundImGuiCol_PopupBg— Popup window background
Borders
ImGuiCol_Border— Border colorImGuiCol_BorderShadow— Border shadow (often transparent)
Frames (input fields, etc.)
ImGuiCol_FrameBg— Frame background (normal state)ImGuiCol_FrameBgHovered— Frame background when hoveredImGuiCol_FrameBgActive— Frame background when active/clicked
Title bars
ImGuiCol_TitleBg— Title bar (unfocused)ImGuiCol_TitleBgActive— Title bar (focused)ImGuiCol_TitleBgCollapsed— Collapsed title bar
Interactive elements
ImGuiCol_Button— Button backgroundImGuiCol_ButtonHovered— Button when hoveredImGuiCol_ButtonActive— Button when pressedImGuiCol_CheckMark— Checkmark/radio button indicatorImGuiCol_SliderGrab— Slider grab handleImGuiCol_SliderGrabActive— Slider grab when dragging
Headers and separators
ImGuiCol_Header— Header (tree nodes, collapsing headers)ImGuiCol_HeaderHovered— Header when hoveredImGuiCol_HeaderActive— Header when clickedImGuiCol_Separator— Separator lineImGuiCol_SeparatorHovered— Separator when hoveredImGuiCol_SeparatorActive— Separator when dragged
Scrollbars
ImGuiCol_ScrollbarBg— Scrollbar backgroundImGuiCol_ScrollbarGrab— Scrollbar grabImGuiCol_ScrollbarGrabHovered— Scrollbar grab when hoveredImGuiCol_ScrollbarGrabActive— Scrollbar grab when dragging
Tabs
ImGuiCol_Tab— Tab (inactive)ImGuiCol_TabHovered— Tab when hoveredImGuiCol_TabActive— Tab (active)ImGuiCol_TabUnfocused— Tab in unfocused windowImGuiCol_TabUnfocusedActive— Active tab in unfocused window
Tables
ImGuiCol_TableHeaderBg— Table header backgroundImGuiCol_TableBorderStrong— Strong table bordersImGuiCol_TableBorderLight— Light table bordersImGuiCol_TableRowBg— Table row backgroundImGuiCol_TableRowBgAlt— Alternating table row background
Navigation and overlays
ImGuiCol_MenuBarBg— Menu bar backgroundImGuiCol_ResizeGrip— Resize grip indicatorImGuiCol_ResizeGripHovered— Resize grip when hoveredImGuiCol_ResizeGripActive— Resize grip when draggingImGuiCol_DragDropTarget— Drag-and-drop target highlightImGuiCol_NavHighlight— Navigation highlightImGuiCol_NavWindowingHighlight— Window navigation highlightImGuiCol_NavWindowingDimBg— Window navigation dim backgroundImGuiCol_ModalWindowDimBg— Modal window dim background
Plots (graphs)
ImGuiCol_PlotLines— Plot line colorImGuiCol_PlotLinesHovered— Plot line when hoveredImGuiCol_PlotHistogram— Histogram colorImGuiCol_PlotHistogramHovered— Histogram when hovered
Style parameters
In addition to colors, themes can customize style parameters:
ImGuiStyle &style = ImGui::GetStyle();
// Padding and spacing
style.WindowPadding = ImVec2(8.0f, 8.0f); // Window content padding
style.FramePadding = ImVec2(6.0f, 4.0f); // Frame (input fields) padding
style.CellPadding = ImVec2(6.0f, 4.0f); // Table cell padding
style.ItemSpacing = ImVec2(6.0f, 6.0f); // Space between items
style.ItemInnerSpacing = ImVec2(6.0f, 4.0f); // Space within composite items
// Rounding
style.WindowRounding = 4.0f; // Window corner rounding
style.FrameRounding = 3.0f; // Frame corner rounding
style.PopupRounding = 4.0f; // Popup corner rounding
style.GrabRounding = 3.0f; // Grab handle rounding
style.TabRounding = 4.0f; // Tab corner rounding
// Borders
style.WindowBorderSize = 1.0f; // Window border width
style.FrameBorderSize = 1.0f; // Frame border width
// Scrollbars
style.ScrollbarSize = 14.0f; // Scrollbar width
style.GrabMinSize = 10.0f; // Minimum grab handle size
Creating a new theme
Follow these steps to add a new theme to kte:
1. Create the theme file
Create a new header file in themes/ (e.g., themes/MyTheme.h):
// themes/MyTheme.h — Brief description
#pragma once
#include "ThemeHelpers.h"
// Expects to be included from GUITheme.h after <imgui.h> and RGBA() helper
static void
ApplyMyTheme()
{
// Define your color palette
const ImVec4 background = RGBA(0x1e1e1e);
const ImVec4 foreground = RGBA(0xd4d4d4);
const ImVec4 accent = RGBA(0x007acc);
// ... more colors
ImGuiStyle &style = ImGui::GetStyle();
// Configure style parameters
style.WindowPadding = ImVec2(8.0f, 8.0f);
// ... more style settings
ImVec4 *colors = style.Colors;
// Assign all required colors
colors[ImGuiCol_Text] = foreground;
colors[ImGuiCol_WindowBg] = background;
// ... assign all other ImGuiCol_* values
}
Refer to existing themes like Nord.h for a complete example of all
required color assignments.
2. Add theme to GUITheme.h
Edit GUITheme.h to integrate your theme:
a) Add to ThemeId enum:
enum class ThemeId {
// ... existing themes
MyTheme = 13, // Use next available number
};
b) Include your theme header:
// After other theme includes
#include "themes/MyTheme.h"
c) Create wrapper class in detail namespace:
namespace detail {
// ... existing theme classes
struct MyThemeWrapper final : Theme {
[[nodiscard]] const char *Name() const override
{
return "mytheme"; // Lowercase canonical name
}
void Apply() const override
{
ApplyMyTheme();
}
ThemeId Id() override
{
return ThemeId::MyTheme;
}
};
} // namespace detail
d) Register in ThemeRegistry():
static const std::vector<std::unique_ptr<Theme>> &
ThemeRegistry()
{
static std::vector<std::unique_ptr<Theme>> reg;
if (reg.empty()) {
// Add in alphabetical order by canonical name
reg.emplace_back(std::make_unique<detail::AmberTheme>());
// ... existing themes
reg.emplace_back(std::make_unique<detail::MyThemeWrapper>());
// ... remaining themes
}
return reg;
}
3. Test your theme
Rebuild kte and test:
# Set theme in config
echo "theme = mytheme" >> ~/.config/kte/kge.ini
# Or switch at runtime
kge
:theme mytheme
Light/Dark theme variants
Some themes support both light and dark background modes. To implement this:
1. Create separate functions for each variant
// themes/MyTheme.h
#pragma once
#include "ThemeHelpers.h"
static void
ApplyMyThemeDark()
{
const ImVec4 bg = RGBA(0x1e1e1e); // Dark background
const ImVec4 fg = RGBA(0xd4d4d4); // Light text
// ... rest of dark theme
}
static void
ApplyMyThemeLight()
{
const ImVec4 bg = RGBA(0xffffff); // Light background
const ImVec4 fg = RGBA(0x1e1e1e); // Dark text
// ... rest of light theme
}
2. Check background mode in Apply()
// In GUITheme.h wrapper class
struct MyThemeWrapper final : Theme {
// ... Name() and Id() methods
void Apply() const override
{
if (gBackgroundMode == BackgroundMode::Dark)
ApplyMyThemeDark();
else
ApplyMyThemeLight();
}
};
See Solarized.h, Gruvbox.h, EInk.h, or OldBook.h for complete
examples.
Updating existing themes
To modify an existing theme:
1. Locate the theme file
Theme files are in themes/ directory. For example, Nord theme is in
themes/Nord.h.
2. Modify colors or style
Edit the ApplyXxxTheme() function:
- Update palette color definitions
- Change style parameters
- Reassign
ImGuiCol_*values
3. Rebuild and test
# Rebuild kte
cmake --build build
# Test changes
./build/kge
Changes take effect immediately on next launch or theme switch.
Best practices
When creating or updating themes:
-
Start from an existing theme — Copy a similar theme as a template (e.g.,
Nord.hfor dark themes,Solarized.hfor light/dark variants) -
Define a complete palette first — Create all color constants at the top before assigning them
-
Assign all colors — Ensure every
ImGuiCol_*value is set to avoid inheriting unexpected colors -
Use consistent naming — Follow existing conventions (e.g.,
nord0,base03, descriptive names) -
Test interactivity — Verify hover, active, and disabled states for buttons, frames, and other interactive elements
-
Consider contrast — Ensure text is readable against backgrounds; test with different content
-
Test transparency — Use alpha values carefully for overlays, dim backgrounds, and selection highlights
-
Match style to theme — Adjust rounding, padding, and borders to suit the theme's aesthetic (e.g., sharp corners for retro themes, rounded for modern)
-
Document inspiration — Note the color scheme's origin or inspiration in the file header
-
Maintain alphabetical order — When registering in
ThemeRegistry(), maintain alphabetical order by canonical name
Troubleshooting
Theme not appearing
- Check that the theme is registered in
ThemeRegistry()in alphabetical order - Verify the canonical name matches what you're using in config or commands
- Ensure the theme header is included in
GUITheme.h
Colors look wrong
- Verify hex color values are in 0xRRGGBB format (not 0xBBGGRR)
- Check alpha values for semi-transparent elements
- Ensure all
ImGuiCol_*values are assigned
Style inconsistent
- Make sure style parameters are set before color assignments
- Check that you're getting
ImGui::GetStyle()reference correctly - Verify no global style changes are overriding theme settings
References
- ImGui style reference: https://github.com/ocornut/imgui/blob/master/imgui.h
- Existing themes in
themes/directory - Color palette resources: coolors.co, colorhunt.co