LCOV - code coverage report
Current view: top level - src/gui/theme - theme.h (source / functions) Coverage Total Hit
Test: merged.info Lines: 100.0 % 89 89
Test Date: 2026-06-03 09:13:19 Functions: 91.7 % 12 11

            Line data    Source code
       1              : #pragma once
       2              : 
       3              : #include <imgui.h>
       4              : #include <cstring>
       5              : #include <cmath>
       6              : #include <cstdio>
       7              : #include <string>
       8              : 
       9              : namespace Amplitron {
      10              : 
      11              : // ============================================================
      12              : // AMPLITRON Design System
      13              : // Color palette extracted from icon.svg
      14              : // Warm vintage amp aesthetic: dark browns, golds, muted metals
      15              : // ============================================================
      16              : 
      17              : namespace Theme {
      18              : 
      19              : // --- Brand ---
      20              : constexpr const char* APP_NAME     = "Amplitron";
      21              : constexpr const char* WINDOW_TITLE = "Amplitron - Guitar Amp Simulator";
      22              : 
      23              : // --- Core Palette (from icon.svg) ---
      24              : // Cabinet / background tones
      25              : constexpr ImU32 BG_DARKEST     = IM_COL32(20, 18, 16, 255);    // #141210  app bg
      26              : constexpr ImU32 BG_DARK        = IM_COL32(28, 26, 24, 255);    // #1c1a18  cabinet body
      27              : constexpr ImU32 BG_PANEL       = IM_COL32(42, 38, 32, 255);    // #2a2620  top panel
      28              : constexpr ImU32 BG_SURFACE     = IM_COL32(50, 46, 38, 255);    // #322e26  elevated surfaces
      29              : constexpr ImU32 BG_GRILLE      = IM_COL32(26, 18, 16, 255);    // #1a1210  speaker grille
      30              : 
      31              : // Metal / borders
      32              : constexpr ImU32 BORDER_DARK    = IM_COL32(58, 54, 48, 255);    // #3a3630  subtle border
      33              : constexpr ImU32 BORDER_MID     = IM_COL32(68, 68, 68, 255);    // #444444  medium border
      34              : constexpr ImU32 BORDER_LIGHT   = IM_COL32(85, 85, 85, 255);    // #555555  bright border
      35              : constexpr ImU32 METAL_STRIP    = IM_COL32(61, 56, 48, 255);    // #3d3830  brushed metal
      36              : 
      37              : // Gold accent (brand color — knob pointers, highlights, brand text)
      38              : constexpr ImU32 ACCENT_GOLD    = IM_COL32(200, 168, 74, 255);  // #c8a84a
      39              : constexpr ImU32 ACCENT_GOLD_DIM= IM_COL32(160, 130, 55, 255);  // dimmed gold
      40              : constexpr ImU32 ACCENT_GOLD_HOT= IM_COL32(230, 200, 100, 255); // bright gold
      41              : 
      42              : // Power LED green
      43              : constexpr ImU32 LED_GREEN      = IM_COL32(45, 110, 45, 255);   // #2d6e2d
      44              : constexpr ImU32 LED_GREEN_GLOW = IM_COL32(127, 255, 127, 200); // #7fff7f
      45              : 
      46              : // Text
      47              : constexpr ImU32 TEXT_PRIMARY   = IM_COL32(220, 215, 205, 255);  // warm white
      48              : constexpr ImU32 TEXT_SECONDARY = IM_COL32(136, 136, 136, 255);  // #888
      49              : constexpr ImU32 TEXT_DIM       = IM_COL32(102, 102, 102, 255);  // #666
      50              : constexpr ImU32 TEXT_MUTED     = IM_COL32(80, 76, 68, 255);     // very dim
      51              : 
      52              : // Knobs (from icon: dark circles with gold pointers)
      53              : constexpr ImU32 KNOB_BG        = IM_COL32(26, 26, 26, 255);    // #1a1a1a
      54              : constexpr ImU32 KNOB_RING      = IM_COL32(34, 34, 34, 255);    // #222222
      55              : constexpr ImU32 KNOB_FACE      = IM_COL32(42, 42, 42, 255);    // #2a2a2a
      56              : constexpr ImU32 KNOB_HOVER     = IM_COL32(55, 52, 46, 255);    // warm hover
      57              : constexpr ImU32 KNOB_ACTIVE    = IM_COL32(68, 64, 56, 255);    // warm active
      58              : constexpr ImU32 KNOB_TRACK_OFF = IM_COL32(36, 34, 30, 255);    // unfilled arc
      59              : 
      60              : // Status
      61              : constexpr ImU32 STATUS_LIVE    = IM_COL32(50, 200, 80, 255);
      62              : constexpr ImU32 STATUS_STOPPED = IM_COL32(200, 50, 50, 255);
      63              : constexpr ImU32 STATUS_REC     = IM_COL32(255, 40, 40, 255);
      64              : 
      65              : // Meters
      66              : constexpr ImU32 METER_BG       = IM_COL32(26, 22, 18, 255);
      67              : constexpr ImU32 METER_GREEN    = IM_COL32(50, 180, 70, 255);
      68              : constexpr ImU32 METER_YELLOW   = IM_COL32(210, 170, 50, 255);
      69              : constexpr ImU32 METER_RED      = IM_COL32(220, 50, 40, 255);
      70              : 
      71              : // Signal chain
      72              : constexpr ImU32 CHAIN_LINE     = IM_COL32(58, 54, 48, 150);    // matches border
      73              : constexpr ImU32 CHAIN_JACK     = IM_COL32(160, 150, 130, 255); // warm metal
      74              : constexpr ImU32 CHAIN_DOT      = IM_COL32(120, 110, 95, 200);
      75              : 
      76              : // Pedal chrome
      77              : constexpr ImU32 PEDAL_SHADOW   = IM_COL32(0, 0, 0, 120);
      78              : constexpr ImU32 PEDAL_BORDER   = IM_COL32(70, 66, 58, 255);    // warm grey
      79              : constexpr ImU32 PEDAL_PLATE    = IM_COL32(46, 42, 36, 200);    // top plate
      80              : constexpr ImU32 SWITCH_BODY    = IM_COL32(38, 36, 32, 255);
      81              : constexpr ImU32 SWITCH_RING    = IM_COL32(68, 64, 56, 255);
      82              : constexpr ImU32 SWITCH_ACTIVE  = IM_COL32(72, 65, 42, 255);    // gold-tinted = enabled
      83              : constexpr ImU32 SWITCH_IDLE    = IM_COL32(28, 26, 22, 255);    // dark = bypassed
      84              : constexpr ImU32 LED_OFF        = IM_COL32(36, 34, 30, 255);
      85              : constexpr ImU32 PEDAL_BYPASS_OVERLAY = IM_COL32(0, 0, 0, 90);  // dim overlay when bypassed
      86              : 
      87              : // --- ImVec4 helpers (for ImGui style and TextColored) ---
      88          140 : inline ImVec4 Gold()          { return ImVec4(0.78f, 0.66f, 0.29f, 1.0f); }
      89            6 : inline ImVec4 GoldDim()       { return ImVec4(0.63f, 0.51f, 0.22f, 1.0f); }
      90           80 : inline ImVec4 GoldHot()       { return ImVec4(0.90f, 0.78f, 0.39f, 1.0f); }
      91          183 : inline ImVec4 TextPrimary()   { return ImVec4(0.86f, 0.84f, 0.80f, 1.0f); }
      92          900 : inline ImVec4 TextSecondary() { return ImVec4(0.53f, 0.53f, 0.53f, 1.0f); }
      93          964 : inline ImVec4 TextDim()       { return ImVec4(0.40f, 0.40f, 0.40f, 1.0f); }
      94           13 : inline ImVec4 Live()          { return ImVec4(0.20f, 0.78f, 0.31f, 1.0f); }
      95            4 : inline ImVec4 Stopped()       { return ImVec4(0.78f, 0.20f, 0.20f, 1.0f); }
      96           28 : inline ImVec4 RecBlink(float t) {
      97           28 :     float a = (std::sin(t * 4.0f) > 0.0f) ? 1.0f : 0.3f;
      98           28 :     return ImVec4(1.0f, 0.1f, 0.1f, a);
      99              : }
     100              : 
     101              : // --- Parameter value formatter ---
     102              : // Produces human-readable display strings with unit-aware formatting:
     103              : //   Hz  -> "440 Hz" or "1.5 kHz" (>=1000)
     104              : //   dB  -> "-6.0 dB"
     105              : //   %   -> "75%"
     106              : //   ms  -> "250 ms"
     107              : //   s   -> "1.20 s"
     108              : //   other / none -> "1.5" or "1.5 unit"
     109         5826 : inline std::string formatParameterValue(float value, const std::string& unit) {
     110         1942 :     char buf[64];
     111         5826 :     if (unit == "Hz") {
     112          534 :         if (value >= 1000.0f)
     113          252 :             snprintf(buf, sizeof(buf), "%.1f kHz", value / 1000.0f);
     114              :         else
     115          282 :             snprintf(buf, sizeof(buf), "%.0f Hz", value);
     116         5470 :     } else if (unit == "dB") {
     117         2010 :         snprintf(buf, sizeof(buf), "%.1f dB", value);
     118         3952 :     } else if (unit == "%" || unit == "pct") {
     119           12 :         snprintf(buf, sizeof(buf), "%.0f%%", value);
     120         3274 :     } else if (unit == "ms") {
     121         1500 :         snprintf(buf, sizeof(buf), "%.1f ms", value);
     122         2270 :     } else if (unit == "s") {
     123            6 :         snprintf(buf, sizeof(buf), "%.2f s", value);
     124         1766 :     } else if (!unit.empty()) {
     125          921 :         snprintf(buf, sizeof(buf), "%.1f %s", value, unit.c_str());
     126          307 :     } else {
     127          843 :         snprintf(buf, sizeof(buf), "%.1f", value);
     128              :     }
     129         7768 :     return std::string(buf);
     130              : }
     131              : 
     132              : // --- Spacing / Layout ---
     133              : constexpr float PEDAL_WIDTH         = 190.0f;
     134              : constexpr float PEDAL_HEIGHT        = 360.0f;
     135              : constexpr float KNOB_RADIUS         = 20.0f;
     136              : constexpr float KNOB_HIT_MULT       = 2.2f;
     137              : constexpr float KNOB_SPACING_X      = 85.0f;   // horizontal distance between knob columns
     138              : constexpr float KNOB_SPACING_Y      = 95.0f;   // vertical distance between knob rows
     139              : constexpr float KNOB_Y_START        = 70.0f;   // knob area top offset from pedal top
     140              : constexpr float SWITCH_BOTTOM_OFFSET = 55.0f;  // footswitch distance from pedal bottom
     141              : constexpr float ROUNDING_SM   = 4.0f;
     142              : constexpr float ROUNDING_MD   = 8.0f;
     143              : constexpr float ROUNDING_LG   = 12.0f;
     144              : 
     145              : // --- Apply the full ImGui style ---
     146            3 : inline void ApplyStyle() {
     147            3 :     ImGuiStyle& style = ImGui::GetStyle();
     148              : 
     149              :     // Rounding
     150            3 :     style.WindowRounding    = ROUNDING_MD;
     151            3 :     style.ChildRounding     = ROUNDING_SM;
     152            3 :     style.FrameRounding     = ROUNDING_SM;
     153            3 :     style.PopupRounding     = ROUNDING_SM;
     154            3 :     style.ScrollbarRounding = ROUNDING_SM;
     155            3 :     style.GrabRounding      = ROUNDING_SM;
     156            3 :     style.TabRounding       = ROUNDING_SM;
     157              : 
     158              :     // Spacing
     159            3 :     style.WindowPadding  = ImVec2(8, 8);
     160            3 :     style.FramePadding   = ImVec2(6, 4);
     161            3 :     style.ItemSpacing    = ImVec2(8, 5);
     162            3 :     style.ScrollbarSize  = 12;
     163            3 :     style.GrabMinSize    = 10;
     164              : 
     165              :     // Borders
     166            3 :     style.WindowBorderSize = 1.0f;
     167            3 :     style.ChildBorderSize  = 1.0f;
     168            3 :     style.FrameBorderSize  = 0.0f;
     169              : 
     170              :     // Colors
     171            3 :     ImVec4* c = style.Colors;
     172              : 
     173              :     // Window
     174            3 :     c[ImGuiCol_WindowBg]       = ImVec4(0.11f, 0.10f, 0.09f, 1.00f);  // #1c1a18
     175            3 :     c[ImGuiCol_ChildBg]        = ImVec4(0.08f, 0.07f, 0.06f, 0.40f);
     176            3 :     c[ImGuiCol_PopupBg]        = ImVec4(0.14f, 0.13f, 0.11f, 0.95f);
     177              : 
     178              :     // Borders
     179            3 :     c[ImGuiCol_Border]         = ImVec4(0.23f, 0.21f, 0.19f, 0.60f);
     180            3 :     c[ImGuiCol_BorderShadow]   = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
     181              : 
     182              :     // Title / Menu
     183            3 :     c[ImGuiCol_TitleBg]        = ImVec4(0.12f, 0.11f, 0.10f, 1.00f);
     184            3 :     c[ImGuiCol_TitleBgActive]  = ImVec4(0.16f, 0.15f, 0.13f, 1.00f);
     185            3 :     c[ImGuiCol_MenuBarBg]      = ImVec4(0.14f, 0.13f, 0.11f, 1.00f);
     186              : 
     187              :     // Text
     188            3 :     c[ImGuiCol_Text]           = TextPrimary();
     189            3 :     c[ImGuiCol_TextDisabled]   = TextDim();
     190              : 
     191              :     // Frame (input fields, sliders)
     192            3 :     c[ImGuiCol_FrameBg]        = ImVec4(0.16f, 0.15f, 0.13f, 1.00f);
     193            3 :     c[ImGuiCol_FrameBgHovered] = ImVec4(0.22f, 0.20f, 0.17f, 1.00f);
     194            3 :     c[ImGuiCol_FrameBgActive]  = ImVec4(0.27f, 0.25f, 0.22f, 1.00f);
     195              : 
     196              :     // Buttons — gold tinted
     197            3 :     c[ImGuiCol_Button]         = ImVec4(0.22f, 0.20f, 0.16f, 1.00f);
     198            3 :     c[ImGuiCol_ButtonHovered]  = ImVec4(0.35f, 0.30f, 0.18f, 1.00f);
     199            3 :     c[ImGuiCol_ButtonActive]   = ImVec4(0.50f, 0.42f, 0.20f, 1.00f);
     200              : 
     201              :     // Header / selectable
     202            3 :     c[ImGuiCol_Header]         = ImVec4(0.22f, 0.20f, 0.16f, 1.00f);
     203            3 :     c[ImGuiCol_HeaderHovered]  = ImVec4(0.35f, 0.30f, 0.18f, 1.00f);
     204            3 :     c[ImGuiCol_HeaderActive]   = ImVec4(0.50f, 0.42f, 0.20f, 1.00f);
     205              : 
     206              :     // Slider grab — gold
     207            3 :     c[ImGuiCol_SliderGrab]     = Gold();
     208            3 :     c[ImGuiCol_SliderGrabActive]= GoldHot();
     209              : 
     210              :     // Scrollbar
     211            3 :     c[ImGuiCol_ScrollbarBg]       = ImVec4(0.08f, 0.07f, 0.06f, 0.50f);
     212            3 :     c[ImGuiCol_ScrollbarGrab]     = ImVec4(0.25f, 0.23f, 0.20f, 1.00f);
     213            3 :     c[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.35f, 0.30f, 0.25f, 1.00f);
     214            3 :     c[ImGuiCol_ScrollbarGrabActive]  = ImVec4(0.45f, 0.38f, 0.28f, 1.00f);
     215              : 
     216              :     // Checkbox / radio
     217            3 :     c[ImGuiCol_CheckMark]      = Gold();
     218              : 
     219              :     // Separator
     220            3 :     c[ImGuiCol_Separator]      = ImVec4(0.23f, 0.21f, 0.19f, 0.50f);
     221            3 :     c[ImGuiCol_SeparatorHovered]= ImVec4(0.50f, 0.42f, 0.20f, 0.70f);
     222            3 :     c[ImGuiCol_SeparatorActive]= ImVec4(0.78f, 0.66f, 0.29f, 1.00f);
     223              : 
     224              :     // Tab
     225            3 :     c[ImGuiCol_Tab]            = ImVec4(0.16f, 0.15f, 0.13f, 1.00f);
     226            3 :     c[ImGuiCol_TabHovered]     = ImVec4(0.35f, 0.30f, 0.18f, 1.00f);
     227              : 
     228              :     // Resize grip
     229            3 :     c[ImGuiCol_ResizeGrip]         = ImVec4(0.50f, 0.42f, 0.20f, 0.20f);
     230            3 :     c[ImGuiCol_ResizeGripHovered]  = ImVec4(0.50f, 0.42f, 0.20f, 0.60f);
     231            3 :     c[ImGuiCol_ResizeGripActive]   = ImVec4(0.78f, 0.66f, 0.29f, 0.90f);
     232            3 : }
     233              : 
     234              : } // namespace Theme
     235              : 
     236              : // --- Effect Color Scheme (SOLID: Open/Closed — extend by adding entries, not modifying) ---
     237              : struct EffectColorEntry {
     238              :     const char* name;
     239              :     ImVec4 pedal_color;
     240              :     ImVec4 led_color;
     241              : };
     242              : 
     243          666 : inline const EffectColorEntry* get_effect_color(const char* effect_name) {
     244              :     // Warm-toned pedal colors that complement the Amplitron palette
     245          222 :     static const EffectColorEntry table[] = {
     246              :         {"Distortion", ImVec4(0.45f, 0.14f, 0.10f, 1.0f), ImVec4(1.0f, 0.30f, 0.20f, 1.0f)},
     247              :         {"Overdrive",  ImVec4(0.45f, 0.34f, 0.12f, 1.0f), ImVec4(0.95f, 0.75f, 0.20f, 1.0f)},
     248              :         {"Delay",      ImVec4(0.12f, 0.22f, 0.38f, 1.0f), ImVec4(0.35f, 0.60f, 0.95f, 1.0f)},
     249              :         {"Reverb",     ImVec4(0.14f, 0.28f, 0.36f, 1.0f), ImVec4(0.25f, 0.72f, 0.85f, 1.0f)},
     250              :         {"Looper",     ImVec4(0.16f, 0.16f, 0.22f, 1.0f), ImVec4(0.78f, 0.66f, 0.29f, 1.0f)},
     251              :         {"Chorus",     ImVec4(0.26f, 0.14f, 0.38f, 1.0f), ImVec4(0.65f, 0.35f, 0.95f, 1.0f)},
     252              :         {"Phaser",     ImVec4(0.22f, 0.10f, 0.34f, 1.0f), ImVec4(0.80f, 0.25f, 0.90f, 1.0f)},
     253              :         {"Flanger",    ImVec4(0.14f, 0.20f, 0.36f, 1.0f), ImVec4(0.30f, 0.70f, 1.00f, 1.0f)},
     254              :         {"Equalizer",  ImVec4(0.14f, 0.32f, 0.18f, 1.0f), ImVec4(0.25f, 0.90f, 0.40f, 1.0f)},
     255              :         {"Noise Gate", ImVec4(0.20f, 0.19f, 0.22f, 1.0f), ImVec4(0.70f, 0.70f, 0.80f, 1.0f)},
     256              :         {"Compressor", ImVec4(0.34f, 0.26f, 0.14f, 1.0f), ImVec4(0.95f, 0.65f, 0.25f, 1.0f)},
     257              :         {"MultiBand Compressor", ImVec4(0.24f, 0.30f, 0.28f, 1.0f), ImVec4(0.40f, 0.85f, 0.70f, 1.0f)},
     258              :         {"Cabinet",    ImVec4(0.26f, 0.18f, 0.10f, 1.0f), ImVec4(0.85f, 0.55f, 0.30f, 1.0f)},
     259              :         {"Octaver",       ImVec4(0.36f, 0.14f, 0.28f, 1.0f), ImVec4(0.90f, 0.35f, 0.60f, 1.0f)},
     260              :         {"Pitch Shifter", ImVec4(0.32f, 0.12f, 0.32f, 1.0f), ImVec4(0.85f, 0.40f, 0.85f, 1.0f)},
     261              :         {"Tuner",      ImVec4(0.12f, 0.24f, 0.30f, 1.0f), ImVec4(0.40f, 0.85f, 0.95f, 1.0f)},
     262              :     };
     263         5262 :     for (const auto& entry : table) {
     264         5229 :         if (std::strcmp(effect_name, entry.name) == 0) return &entry;
     265              :     }
     266              :     // Default fallback
     267              :     static const EffectColorEntry fallback =
     268              :         {"Default", ImVec4(0.20f, 0.19f, 0.17f, 1.0f), ImVec4(0.78f, 0.66f, 0.29f, 1.0f)};
     269           22 :     return &fallback;
     270          222 : }
     271              : 
     272              : } // namespace Amplitron
        

Generated by: LCOV version 2.0-1