LCOV - code coverage report
Current view: top level - src/gui/views - gui_tuner.cpp (source / functions) Coverage Total Hit
Test: merged.info Lines: 90.2 % 92 83
Test Date: 2026-06-01 11:15:25 Functions: 100.0 % 1 1

            Line data    Source code
       1              : #include "gui/views/gui_tuner.h"
       2              : #include "gui/theme/theme.h"
       3              : #include "common.h"
       4              : #include <imgui.h>
       5              : #include <cmath>
       6              : #include <cstdio>
       7              : 
       8              : namespace Amplitron {
       9              : 
      10            9 : void GuiTuner::render(bool& show) {
      11            9 :     ImGui::SetNextWindowSize(ImVec2(360, 320), ImGuiCond_FirstUseEver);
      12            9 :     bool open = show;
      13            9 :     if (!ImGui::Begin("Chromatic Tuner", &open)) {
      14            0 :         if (!open) show = false;
      15            0 :         ImGui::End();
      16            2 :         return;
      17              :     }
      18            9 :     if (!open) {
      19            3 :         show = false;
      20            3 :         ImGui::End();
      21            3 :         return;
      22              :     }
      23              : 
      24              : 
      25            6 :     const TunerProps& p = props_;
      26            6 :     ImDrawList* dl    = ImGui::GetWindowDrawList();
      27            6 :     float       win_w = ImGui::GetContentRegionAvail().x;
      28              : 
      29            6 :     if (p.has_signal && p.note_idx >= 0 && p.note_name_fn) {
      30              :         // ── Note name (large, centered) ──
      31            1 :         char note_buf[16];
      32            3 :         std::snprintf(note_buf, sizeof(note_buf), "%s%d", p.note_name_fn(p.note_idx), p.octave);
      33            3 :         ImVec2 note_size = ImGui::CalcTextSize(note_buf);
      34            3 :         float  scale     = 3.0f;
      35            3 :         float  note_w    = note_size.x * scale;
      36            3 :         ImVec2 note_pos  = ImGui::GetCursorScreenPos();
      37            3 :         note_pos.x += (win_w - note_w) * 0.5f;
      38            4 :         dl->AddText(ImGui::GetFont(), ImGui::GetFontSize() * scale,
      39            1 :                     note_pos, Theme::TEXT_PRIMARY, note_buf);
      40            3 :         ImGui::Dummy(ImVec2(0, ImGui::GetFontSize() * scale + 8));
      41              : 
      42              :         // ── Cents indicator ──
      43            3 :         float abs_cents  = std::fabs(p.cents);
      44            3 :         ImVec4 cents_col = (abs_cents < 2.0f)
      45            2 :                            ? ImVec4(0.2f, 0.9f, 0.3f, 1.0f)
      46            1 :                            : (abs_cents < 15.0f)
      47            3 :                                ? ImVec4(0.9f, 0.8f, 0.2f, 1.0f)
      48            2 :                                : ImVec4(0.9f, 0.2f, 0.2f, 1.0f);
      49            1 :         char cents_buf[32];
      50            3 :         std::snprintf(cents_buf, sizeof(cents_buf), "%+.1f cents", p.cents);
      51            3 :         ImVec2 cents_size = ImGui::CalcTextSize(cents_buf);
      52            3 :         ImGui::SetCursorPosX((win_w - cents_size.x) * 0.5f);
      53            3 :         ImGui::TextColored(cents_col, "%s", cents_buf);
      54              : 
      55            3 :         ImGui::Spacing();
      56              : 
      57              :         // ── Cents deviation bar ──
      58            3 :         float  bar_w   = win_w - 40;
      59            3 :         float  bar_h   = 14;
      60            3 :         ImVec2 bar_pos = ImGui::GetCursorScreenPos();
      61            3 :         bar_pos.x += 20;
      62            3 :         dl->AddRectFilled(bar_pos, ImVec2(bar_pos.x + bar_w, bar_pos.y + bar_h),
      63              :                           Theme::KNOB_BG, 4.0f);
      64              : 
      65            3 :         float cx = bar_pos.x + bar_w * 0.5f;
      66            3 :         dl->AddLine(ImVec2(cx, bar_pos.y - 2), ImVec2(cx, bar_pos.y + bar_h + 2),
      67              :                     Theme::TEXT_DIM, 2.0f);
      68              : 
      69            3 :         float needle_norm = clamp(p.cents / 50.0f, -1.0f, 1.0f);
      70            3 :         float needle_x    = cx + needle_norm * (bar_w * 0.5f);
      71            3 :         ImU32 needle_col  = ImGui::ColorConvertFloat4ToU32(cents_col);
      72            5 :         dl->AddRectFilled(ImVec2(needle_x - 4, bar_pos.y - 3),
      73            3 :                           ImVec2(needle_x + 4, bar_pos.y + bar_h + 3),
      74            1 :                           needle_col, 3.0f);
      75            3 :         ImGui::Dummy(ImVec2(0, bar_h + 12));
      76              : 
      77              :         // ── Frequency ──
      78            1 :         char freq_buf[32];
      79            3 :         std::snprintf(freq_buf, sizeof(freq_buf), "%.1f Hz", p.freq);
      80            3 :         float freq_w = ImGui::CalcTextSize(freq_buf).x;
      81            3 :         ImGui::SetCursorPosX((win_w - freq_w) * 0.5f);
      82            3 :         ImGui::TextColored(Theme::TextSecondary(), "%s", freq_buf);
      83              : 
      84            1 :     } else {
      85              :         // ── No signal ──
      86            3 :         const char* dash      = "---";
      87            3 :         ImVec2      dash_size = ImGui::CalcTextSize(dash);
      88            3 :         float       scale     = 3.0f;
      89            3 :         ImVec2      pos       = ImGui::GetCursorScreenPos();
      90            3 :         pos.x += (win_w - dash_size.x * scale) * 0.5f;
      91            3 :         dl->AddText(ImGui::GetFont(), ImGui::GetFontSize() * scale, pos, Theme::TEXT_DIM, dash);
      92            3 :         ImGui::Dummy(ImVec2(0, ImGui::GetFontSize() * scale + 8));
      93              : 
      94            3 :         const char* waiting   = "Play a note...";
      95            3 :         ImVec2      wt_size   = ImGui::CalcTextSize(waiting);
      96            3 :         ImGui::SetCursorPosX((win_w - wt_size.x) * 0.5f);
      97            3 :         ImGui::TextColored(Theme::TextDim(), "%s", waiting);
      98            3 :         ImGui::Dummy(ImVec2(0, 40));
      99              :     }
     100              : 
     101            6 :     ImGui::Spacing();
     102            6 :     ImGui::Separator();
     103            6 :     ImGui::Spacing();
     104              : 
     105              :     // ── Mute toggle ──
     106            6 :     if (p.mute_on) {
     107            0 :         ImGui::PushStyleColor(ImGuiCol_Button,        ImVec4(0.6f, 0.15f, 0.15f, 1.0f));
     108            0 :         ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.75f, 0.2f, 0.2f, 1.0f));
     109            0 :     } else {
     110            6 :         ImGui::PushStyleColor(ImGuiCol_Button,        ImVec4(0.15f, 0.4f, 0.15f, 1.0f));
     111            6 :         ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.2f, 0.55f, 0.2f, 1.0f));
     112              :     }
     113            6 :     float btn_w = 140;
     114            6 :     ImGui::SetCursorPosX((win_w - btn_w) * 0.5f);
     115            8 :     if (ImGui::Button(p.mute_on ? "MUTE ON" : "MUTE OFF", ImVec2(btn_w, 30))) {
     116            0 :         if (p.on_mute_changed) p.on_mute_changed(!p.mute_on);
     117            0 :     }
     118            6 :     ImGui::PopStyleColor(2);
     119              : 
     120              :     // ── A4 Reference ──
     121            6 :     ImGui::Spacing();
     122            6 :     float a4_ref = p.a4_ref;
     123            6 :     ImGui::SetNextItemWidth(win_w - 20);
     124            6 :     if (ImGui::SliderFloat("A4 Reference", &a4_ref, 430.0f, 450.0f, "%.0f Hz")) {
     125            0 :         if (p.on_a4_ref_changed) p.on_a4_ref_changed(a4_ref);
     126            0 :     }
     127              : 
     128            6 :     ImGui::End();
     129            3 : }
     130              : 
     131              : } // namespace Amplitron
        

Generated by: LCOV version 2.0-1