Line data Source code
1 : #include "gui/pedalboard/pedal_board.h"
2 : #include "gui/theme/theme.h"
3 : #include "gui/views/gui_midi.h"
4 : #include "midi/midi_manager.h"
5 :
6 : #include "audio/effects/amp_simulator.h"
7 : #include "audio/effects/cabinet_sim.h"
8 : #include "audio/effects/chorus.h"
9 : #include "audio/effects/compressor.h"
10 : #include "audio/effects/delay.h"
11 : #include "audio/effects/distortion.h"
12 : #include "audio/effects/equalizer.h"
13 : #include "audio/effects/flanger.h"
14 : #include "audio/effects/looper.h"
15 : #include "audio/effects/multiband_compressor.h"
16 : #include "audio/effects/noise_gate.h"
17 : #include "audio/effects/octaver.h"
18 : #include "audio/effects/overdrive.h"
19 : #include "audio/effects/phaser.h"
20 : #include "audio/effects/pitch_shifter.h"
21 : #include "audio/effects/reverb.h"
22 : #include "audio/effects/wah.h"
23 :
24 : #include <cstdio>
25 : #include <imgui.h>
26 :
27 : namespace Amplitron {
28 :
29 15 : void PedalBoard::render_add_pedal_menu() {
30 15 : if (ImGui::Button("+ Add Pedal")) {
31 0 : ImGui::OpenPopup("AddPedalPopup");
32 0 : }
33 :
34 15 : if (ImGui::BeginPopup("AddPedalPopup")) {
35 3 : ImGui::TextColored(Theme::Gold(), "DRIVE");
36 3 : if (ImGui::MenuItem("Overdrive")) {
37 0 : add_effect_and_show(std::make_shared<Overdrive>());
38 0 : }
39 3 : if (ImGui::MenuItem("Distortion")) {
40 0 : add_effect_and_show(std::make_shared<Distortion>());
41 0 : }
42 :
43 3 : ImGui::Separator();
44 3 : ImGui::TextColored(Theme::Live(), "DYNAMICS");
45 3 : if (ImGui::MenuItem("Noise Gate")) {
46 0 : add_effect_and_show(std::make_shared<NoiseGate>());
47 0 : }
48 3 : if (ImGui::MenuItem("Compressor")) {
49 0 : add_effect_and_show(std::make_shared<Compressor>());
50 0 : }
51 3 : if (ImGui::MenuItem("MultiBand Compressor")) {
52 0 : add_effect_and_show(std::make_shared<MultiBandCompressor>());
53 0 : }
54 :
55 3 : ImGui::Separator();
56 3 : ImGui::TextColored(ImVec4(0.35f, 0.60f, 0.95f, 1.0f), "MODULATION");
57 3 : if (ImGui::MenuItem("Chorus")) {
58 0 : add_effect_and_show(std::make_shared<Chorus>());
59 0 : }
60 3 : if (ImGui::MenuItem("Phaser")) {
61 0 : add_effect_and_show(std::make_shared<Phaser>());
62 0 : }
63 3 : if (ImGui::MenuItem("Flanger")) {
64 0 : add_effect_and_show(std::make_shared<Flanger>());
65 0 : }
66 :
67 3 : ImGui::Separator();
68 3 : ImGui::TextColored(ImVec4(0.65f, 0.35f, 0.95f, 1.0f), "TIME");
69 3 : if (ImGui::MenuItem("Delay")) {
70 0 : add_effect_and_show(std::make_shared<Delay>());
71 0 : }
72 3 : if (ImGui::MenuItem("Reverb")) {
73 0 : add_effect_and_show(std::make_shared<Reverb>());
74 0 : }
75 3 : if (ImGui::MenuItem("Looper")) {
76 0 : add_effect_and_show(std::make_shared<Looper>());
77 0 : }
78 :
79 3 : ImGui::Separator();
80 3 : ImGui::TextColored(ImVec4(0.30f, 0.75f, 0.60f, 1.0f), "FILTER");
81 3 : if (ImGui::MenuItem("Wah")) {
82 0 : add_effect_and_show(std::make_shared<WahPedal>());
83 0 : }
84 :
85 3 : ImGui::Separator();
86 3 : ImGui::TextColored(ImVec4(0.85f, 0.40f, 0.55f, 1.0f), "PITCH");
87 3 : if (ImGui::MenuItem("Octaver")) {
88 0 : add_effect_and_show(std::make_shared<Octaver>());
89 0 : }
90 3 : if (ImGui::MenuItem("Pitch Shifter")) {
91 0 : add_effect_and_show(std::make_shared<PitchShifter>());
92 0 : }
93 :
94 3 : ImGui::Separator();
95 3 : ImGui::TextColored(Theme::GoldDim(), "TONE");
96 3 : if (ImGui::MenuItem("Equalizer")) {
97 0 : add_effect_and_show(std::make_shared<Equalizer>());
98 0 : }
99 3 : if (ImGui::MenuItem("Cabinet Sim")) {
100 0 : add_effect_and_show(std::make_shared<CabinetSim>());
101 0 : }
102 :
103 3 : ImGui::Separator();
104 3 : ImGui::TextDisabled("Routing Utility Blocks");
105 :
106 : // --- NEW MODULAR DAG INSTANTIATION ENTRIES ---
107 3 : if (ImGui::MenuItem("+ Signal Splitter Node (1 In -> N-Out)")) {
108 0 : history_.execute(std::make_unique<AddGraphNodeCommand>(
109 0 : engine_, "Splitter", NodeRoutingType::Splitter, nullptr,
110 0 : ImVec2(0, 0)));
111 0 : }
112 3 : if (ImGui::MenuItem("+ Signal Mixer Node (N-In -> 1 Out)")) {
113 0 : history_.execute(std::make_unique<AddGraphNodeCommand>(
114 0 : engine_, "Mixer", NodeRoutingType::Mixer, nullptr, ImVec2(0, 0), 2));
115 0 : }
116 :
117 3 : ImGui::EndPopup();
118 1 : }
119 15 : }
120 :
121 15 : void PedalBoard::render_amp_selector() {
122 15 : const auto &models = get_amp_models();
123 15 : int amp_idx = find_amp_index();
124 :
125 15 : if (amp_idx < 0) {
126 9 : auto amp = std::make_shared<AmpSimulator>();
127 9 : amp->params()[0].value = 0.0f;
128 9 : engine_.add_effect(amp);
129 9 : rebuild_widgets();
130 9 : amp_idx = find_amp_index();
131 9 : }
132 :
133 18 : const char *current_label = "Amp";
134 18 : int current_model = 0;
135 13 : if (amp_idx >= 0) {
136 15 : auto &_fx = engine_.effects()[amp_idx];
137 15 : current_model = static_cast<int>(amp_fx->params()[0].value);
138 20 : if (current_model >= 0 && current_model < static_cast<int>(models.size())) {
139 15 : current_label = models[current_model].name;
140 5 : }
141 5 : }
142 :
143 15 : ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.35f, 0.18f, 0.08f, 1.0f));
144 15 : ImGui::PushStyleColor(ImGuiCol_ButtonHovered,
145 10 : ImVec4(0.50f, 0.25f, 0.10f, 1.0f));
146 5 : char amp_label[64];
147 15 : std::snprintf(amp_label, sizeof(amp_label), "Amp: %s", current_label);
148 15 : if (ImGui::Button(amp_label)) {
149 0 : ImGui::OpenPopup("AmpSelectorPopup");
150 0 : }
151 15 : ImGui::PopStyleColor(2);
152 :
153 15 : if (ImGui::BeginPopup("AmpSelectorPopup")) {
154 3 : ImGui::TextColored(ImVec4(0.95f, 0.55f, 0.20f, 1.0f), "AMP MODEL");
155 15 : for (int m = 0; m < static_cast<int>(models.size()); ++m) {
156 12 : bool is_selected = (current_model == m);
157 12 : if (ImGui::MenuItem(models[m].name, models[m].inspiration, is_selected)) {
158 0 : if (amp_idx >= 0) {
159 0 : engine_.effects()[amp_idx]->params()[0].value = static_cast<float>(m);
160 0 : }
161 0 : }
162 4 : }
163 3 : ImGui::EndPopup();
164 1 : }
165 15 : }
166 :
167 : // ============================================================
168 : // MIDI MENU — QUICK STATUS AND ACTIONS
169 : // ============================================================
170 18 : void PedalBoard::render_midi_menu() {
171 18 : if (!gui_midi_)
172 2 : return;
173 15 : auto &midi = gui_midi_->manager();
174 :
175 15 : if (ImGui::Button("MIDI")) {
176 0 : ImGui::OpenPopup("MidiMenuPopup");
177 0 : }
178 :
179 15 : if (ImGui::BeginPopup("MidiMenuPopup")) {
180 : // Device status
181 6 : if (midi.is_port_open()) {
182 6 : ImGui::TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "● Connected");
183 6 : ImGui::SameLine();
184 10 : ImGui::TextDisabled("(%s)", midi.current_port_name().c_str());
185 2 : } else {
186 0 : ImGui::TextColored(ImVec4(1.0f, 0.4f, 0.4f, 1.0f), "● Disconnected");
187 : }
188 :
189 6 : ImGui::Separator();
190 :
191 : // Learn mode status
192 6 : if (midi.is_learning()) {
193 3 : ImGui::TextColored(ImVec4(1.0f, 0.8f, 0.0f, 1.0f),
194 : "⚡ Learn Mode Active");
195 3 : if (ImGui::MenuItem("Cancel Learn Mode", "Esc")) {
196 0 : midi.cancel_learn();
197 0 : }
198 1 : } else {
199 3 : ImGui::TextDisabled("Right-click any knob to MIDI learn");
200 : }
201 :
202 6 : ImGui::Separator();
203 :
204 : // Quick actions
205 6 : if (ImGui::MenuItem("Clear All Mappings")) {
206 0 : show_confirm_midi_clear_ = true;
207 0 : }
208 :
209 6 : if (ImGui::MenuItem("Save Config")) {
210 0 : midi.save_config();
211 0 : }
212 :
213 6 : if (ImGui::MenuItem("Load Config")) {
214 0 : midi.load_config();
215 0 : }
216 :
217 6 : ImGui::Separator();
218 :
219 : // Show active mappings count
220 6 : auto &mappings = midi.mappings();
221 6 : ImGui::TextDisabled("%zu active mappings", mappings.size());
222 :
223 6 : ImGui::EndPopup();
224 2 : }
225 6 : }
226 :
227 : } // namespace Amplitron
|