Line data Source code
1 : #include "gui/pedalboard/pedal_widget.h"
2 : #include "gui/views/gui_midi.h"
3 : #include "midi/midi_manager.h"
4 : #include "audio/engine/audio_engine.h"
5 : #include "gui/theme/theme.h"
6 : #include "gui/components/knob.h"
7 :
8 : #include <cmath>
9 : #include <algorithm>
10 :
11 : namespace Amplitron {
12 :
13 195 : void PedalWidget::render_knobs(ImDrawList* dl, ImVec2 p0, float pedal_width, bool is_amp, bool is_tuner, bool is_ir_cab, float zoom) {
14 195 : float knob_y_start = p0.y + Theme::KNOB_Y_START * zoom;
15 195 : if (is_ir_cab) knob_y_start = p0.y + 180 * zoom;
16 195 : auto& params = effect_->params();
17 258 : int num_params = is_tuner ? 0 : static_cast<int>(params.size());
18 195 : int param_offset = 0;
19 195 : if (is_amp) {
20 15 : param_offset = 1;
21 15 : num_params = std::max(0, num_params - 1);
22 5 : }
23 :
24 195 : float knob_radius = Theme::KNOB_RADIUS * zoom;
25 195 : float knob_spacing_x = Theme::KNOB_SPACING_X * zoom;
26 195 : float knob_spacing_y = Theme::KNOB_SPACING_Y * zoom;
27 :
28 195 : float knob_grid_left = p0.x + (pedal_width - 2.0f * knob_spacing_x) * 0.5f;
29 :
30 786 : for (int i = 0; i < num_params && i < 6; ++i) {
31 591 : int pi = i + param_offset;
32 591 : int col = i % 2;
33 591 : int row = i / 2;
34 :
35 591 : bool is_last_alone = (i == num_params - 1) && (num_params % 2 == 1);
36 591 : float kx = is_last_alone
37 319 : ? p0.x + (pedal_width - knob_spacing_x) * 0.5f
38 408 : : knob_grid_left + col * knob_spacing_x;
39 591 : float ky = knob_y_start + row * knob_spacing_y;
40 :
41 591 : ImVec2 knob_center = ImVec2(kx + knob_spacing_x * 0.5f, ky + knob_radius + 2 * zoom);
42 :
43 197 : char label[64];
44 591 : snprintf(label, sizeof(label), "##knob_%s_%d_%d", effect_->name(), index_, pi);
45 :
46 591 : KnobProps props;
47 591 : props.name = params[pi].name;
48 591 : props.value = params[pi].value;
49 591 : props.min_val = params[pi].min_val;
50 591 : props.max_val = params[pi].max_val;
51 591 : props.default_val = params[pi].default_val;
52 591 : props.unit = params[pi].unit;
53 591 : props.tooltip = params[pi].tooltip;
54 :
55 : // MIDI learn integration
56 591 : if (gui_midi_) {
57 549 : props.is_learning = gui_midi_->midi().is_learning() &&
58 370 : gui_midi_->midi().learn_effect_name() == effect_->name() &&
59 18 : gui_midi_->midi().learn_param_name() == params[pi].name;
60 895 : props.midi_info = gui_midi_->get_mapping_info(effect_->name(), params[pi].name);
61 :
62 : // Capture pointers for lambda closures
63 537 : std::string eff_name = effect_->name();
64 537 : std::string param_name = params[pi].name;
65 537 : GuiMidi* gm = gui_midi_;
66 :
67 1253 : props.on_midi_learn_param = [gm, eff_name, param_name]() {
68 0 : gm->manager().start_learn(MidiTargetType::EffectParam, eff_name, param_name);
69 358 : };
70 1253 : props.on_midi_clear_param = [gm, eff_name, param_name]() {
71 0 : gm->manager().remove_mapping_for_param(eff_name, param_name);
72 358 : };
73 1253 : props.on_midi_learn_bypass = [gm, eff_name]() {
74 0 : gm->manager().start_learn(MidiTargetType::EffectBypass, eff_name, "");
75 358 : };
76 1253 : props.on_midi_clear_bypass = [gm, eff_name]() {
77 0 : int remove_idx = -1;
78 0 : const auto& mappings = gm->manager().mappings();
79 0 : for (int i = 0; i < static_cast<int>(mappings.size()); ++i) {
80 0 : if (mappings[i].target_type == MidiTargetType::EffectBypass &&
81 0 : mappings[i].effect_name == eff_name) {
82 0 : remove_idx = i;
83 0 : break;
84 : }
85 0 : }
86 0 : if (remove_idx >= 0) {
87 0 : gm->manager().remove_mapping(remove_idx);
88 0 : }
89 358 : };
90 537 : }
91 :
92 591 : props.led_color = led_color_;
93 :
94 : // Events committed back to effect and engine
95 985 : props.on_value_changed = [this, pi](float new_val) {
96 0 : effect_->params()[pi].value = new_val;
97 0 : engine_.push_param_change(index_, pi, new_val);
98 394 : };
99 985 : props.on_value_committed = [this, pi](float old_val, float new_val) {
100 0 : commit_param_change(pi, old_val, new_val);
101 394 : };
102 :
103 591 : KnobComponent::render(label, props, zoom, knob_center);
104 591 : }
105 195 : }
106 :
107 : } // namespace Amplitron
|