Line data Source code
1 : #pragma once
2 :
3 : #include "common.h"
4 : #include "audio/effects/effect.h"
5 : #include <imgui.h>
6 :
7 : namespace Amplitron {
8 :
9 : class CommandHistory;
10 : class AudioEngine;
11 : class GuiMidi;
12 :
13 : /**
14 : * @brief GUI widget for a single audio effect pedal.
15 : *
16 : * Draws the pedal body, rotary knobs, footswitch, and LED indicator.
17 : * All parameter changes are tracked for undo/redo via a CommandHistory
18 : * pointer injected with set_history().
19 : */
20 86 : class PedalWidget {
21 : friend class TestAccessor;
22 : public:
23 : /**
24 : * @brief Construct a PedalWidget.
25 : * @param engine Reference to the audio engine.
26 : * @param effect Shared pointer to the effect this widget controls.
27 : * @param index Position in the signal chain (used for ImGui IDs).
28 : */
29 : PedalWidget(AudioEngine& engine, std::shared_ptr<Effect> effect, int index);
30 :
31 : /**
32 : * @brief Render the pedal widget for one frame.
33 : * @return true if the user clicked the remove button and the pedal should be deleted.
34 : */
35 : bool render(float zoom = 1.0f);
36 :
37 : /** @brief Return the current chain index. */
38 5 : int get_index() const { return index_; }
39 :
40 : /** @brief Update the chain index (e.g. after reordering). */
41 3 : void set_index(int idx) { index_ = idx; }
42 :
43 : /** @brief Return the underlying effect. */
44 801 : std::shared_ptr<Effect> get_effect() const { return effect_; }
45 :
46 : /**
47 : * @brief Inject a CommandHistory for recording undo-able parameter changes.
48 : * @param history Pointer to the shared history (may be nullptr to disable undo).
49 : */
50 104 : void set_history(CommandHistory* history) { history_ = history; }
51 :
52 : /**
53 : * @brief Inject a GuiMidi pointer for MIDI Learn integration in knob popups.
54 : * @param gm Pointer to the shared GuiMidi module (may be nullptr to disable).
55 : */
56 101 : void set_gui_midi(GuiMidi* gm) { gui_midi_ = gm; }
57 :
58 : private:
59 : /** @brief Render a single rotary knob (unused legacy helper). */
60 : void render_knob(const char* label, float* value, float min_val, float max_val,
61 : float default_val, const char* format = "%.1f");
62 :
63 : /** @brief Render a toggle switch (unused legacy helper). */
64 : void render_toggle(const char* label, bool* value);
65 :
66 : void render_amp_cabinet(ImDrawList* dl, ImVec2 p0, ImVec2 p1, float pedal_width, float pedal_height, float zoom);
67 : void render_standard_pedal(ImDrawList* dl, ImVec2 p0, ImVec2 p1, float pedal_width, bool enabled, float zoom);
68 : void render_knobs(ImDrawList* dl, ImVec2 p0, float pedal_width, bool is_amp, bool is_tuner, bool is_ir_cab, float zoom);
69 : void render_footswitch_and_extras(ImDrawList* dl, ImVec2 p0, ImVec2 p1, float pedal_width, float pedal_height, bool is_amp, bool enabled, bool& should_remove, float zoom);
70 :
71 :
72 : AudioEngine& engine_;
73 : std::shared_ptr<Effect> effect_;
74 : int index_;
75 : CommandHistory* history_ = nullptr;
76 : GuiMidi* gui_midi_ = nullptr;
77 :
78 : // Knob drag tracking for undo coalescing
79 : bool knob_was_active_ = false;
80 : int active_param_index_ = -1;
81 : float param_value_before_drag_ = 0.0f;
82 :
83 : // Popup slider tracking for accurate undo
84 : int popup_active_param_index_ = -1;
85 : float popup_param_value_before_edit_ = 0.0f;
86 :
87 : ImVec4 pedal_color_; ///< Pedal body color derived from effect type.
88 : ImVec4 led_color_; ///< LED / accent color derived from effect type.
89 :
90 : /** @brief Look up pedal_color_ and led_color_ from the theme table. */
91 : void assign_colors();
92 :
93 : /**
94 : * @brief Push a ParameterChangeCommand to the history (value already applied).
95 : * @param param_index Index of the changed parameter.
96 : * @param old_val Value before the change.
97 : * @param new_val Value after the change.
98 : */
99 : void commit_param_change(int param_index, float old_val, float new_val);
100 : };
101 :
102 : } // namespace Amplitron
|