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