10 mouse_state_(kNone), selected_(false), connect_right_(false),
11 draw_border_(false), active_modulation_(false), font_size_(12.0f),
12 show_drag_drop_(false), drag_drop_alpha_(0.0f) {
13 setWantsKeyboardFocus(
true);
15 shape.addLineSegment(Line<float>(-50.0f, -50.0f, -50.0f, -50.0f), 0.2f);
20 setInterceptsMouseClicks(
true,
false);
21 addAndMakeVisible(drag_drop_area_);
22 drag_drop_area_.setInterceptsMouseClicks(
false,
false);
40 int row = index / columns;
41 int column = index % columns;
44 int x = all_bounds.getX() + (all_bounds.getWidth() * column) / columns;
45 int right = all_bounds.getX() + (all_bounds.getWidth() * (column + 1)) / columns;
46 int width = right - x;
47 int y = all_bounds.getY() + all_bounds.getHeight() - width * (row + 1);
48 return Rectangle<int>(x, y, width, width);
52 static constexpr int kMinMeterWidth = 4;
54 int width = getWidth();
55 int meter_width = std::max<int>(kMinMeterWidth, std::round(width *
kMeterAreaRatio / 2.0f) * 2);
56 int meter_height = getHeight() - 2;
57 return Rectangle<int>(1, 1, meter_width, meter_height);
61 static constexpr int kMaxWidthHeightRatio = 3;
63 SynthSection* parent = findParentComponentOfClass<SynthSection>();
64 int widget_margin = 0;
69 int height = getHeight();
71 int widget_width = width - 2 * widget_margin;
74 int widget_x =
getMeterBounds().getRight() + (width - widget_width) / 2;
76 int max_widget_height = ceilf(widget_width * 2.0f / 3.0f);
77 int widget_y = std::max(min_y, height - widget_margin - max_widget_height);
78 int widget_height = height - widget_y - widget_margin;
79 int center_y = widget_y + widget_height / 2;
80 widget_height = std::max(widget_height, (widget_width + kMaxWidthHeightRatio - 1) / kMaxWidthHeightRatio);
81 widget_y = center_y - widget_height / 2;
82 return Rectangle<int>(widget_x, widget_y, widget_width, widget_height);
86 static constexpr float kShadowArea = 0.04f;
88 if (getWidth() == 0 || getHeight() == 0)
97 SynthSection* parent = findParentComponentOfClass<SynthSection>();
98 int rounding_amount = 0;
103 int width = getWidth();
104 int adjusted_width = connect_right_ ? width * 2 : width;
105 Rectangle<float> bounds(0, 0, adjusted_width, getHeight());
106 g.fillRoundedRectangle(bounds, rounding_amount);
109 g.fillRoundedRectangle(meter_bounds, meter_bounds.getWidth() / 2.0f);
110 float meter_width = meter_bounds.getWidth();
111 g.fillRect(meter_bounds.getX() + meter_width / 2.0f, meter_bounds.getY(), meter_width / 2, meter_bounds.getHeight());
115 g.drawRoundedRectangle(bounds.reduced(0.5f), rounding_amount, 1.0f);
118 int height = getHeight();
120 g.setFont(
Fonts::instance()->proportional_regular().withPointHeight(font_size_));
121 String text = text_override_;
126 g.drawText(text, meter_bounds.getRight(), 0, width - meter_bounds.getRight(),
127 font_area_height, Justification::centred);
129 if (connect_right_ && !selected_) {
130 int shadow_width = width * kShadowArea;
132 ColourGradient gradient(shadow_color, width, 0, shadow_color.withAlpha(0.0f), width - shadow_width, 0,
false);
133 g.setGradientFill(gradient);
134 g.fillRect(width - shadow_width, 0, shadow_width, height);
139 if (parent_ ==
nullptr) {
140 parent_ = findParentComponentOfClass<SynthGuiInterface>();
146 static constexpr float kBorder = 0.2f;
150 int left = meter_bounds.getRight();
151 int width = getWidth() - left;
153 int top = font_area_height - (font_area_height - font_size_) * 0.5f;
154 int height = getHeight() - top;
156 float size_mult = 1.0f - 2.0f * kBorder;
157 drag_drop_area_.setBounds(left + width * kBorder, top + height * kBorder,
158 width * size_mult, height * size_mult);
162 static constexpr float kDeltaAlpha = 0.15f;
165 if (show_drag_drop_) {
171 bool increase = drag_drop_alpha_ < target;
173 drag_drop_alpha_ = std::min(drag_drop_alpha_ + kDeltaAlpha, target);
175 drag_drop_alpha_ = std::max(drag_drop_alpha_ - kDeltaAlpha, target);
177 if (drag_drop_alpha_ <= 0.0f) {
178 drag_drop_alpha_ = 0.0f;
182 setColor(drag_drop_color_.withMultipliedAlpha(drag_drop_alpha_));
187 if (e.mods.isPopupMenu()) {
188 if (parent_ ==
nullptr)
191 std::vector<vital::ModulationConnection*> connections =
194 if (connections.empty())
197 mouse_state_ =
kNone;
200 std::string disconnect =
"Disconnect from ";
201 for (
int i = 0; i < connections.size(); ++i) {
206 if (connections.size() > 1)
209 SynthSection* parent = findParentComponentOfClass<SynthSection>();
210 parent->
showPopupSelector(
this, e.getPosition(), options, [=](
int selection) { disconnectIndex(selection); });
216 for (
Listener* listener : listeners_)
217 listener->modulationSelected(
this);
222 if (e.mods.isRightButtonDown())
225 if (!getLocalBounds().contains(e.getPosition()) && mouse_state_ !=
kDraggingOut) {
226 for (
Listener* listener : listeners_)
227 listener->startModulationMap(
this, e);
229 setMouseCursor(MouseCursor::DraggingHandCursor);
233 for (
Listener* listener : listeners_)
234 listener->modulationDragged(e);
241 if (!e.mods.isRightButtonDown() && mouse_state_ ==
kDraggingOut) {
242 for (
Listener* listener : listeners_)
243 listener->endModulationMap();
245 else if (!e.mods.isRightButtonDown()) {
246 for (
Listener* listener : listeners_)
247 listener->modulationClicked(
this);
249 setMouseCursor(MouseCursor::ParentCursor);
263 mouse_state_ =
kNone;
264 show_drag_drop_ =
false;
268 for (
Listener* listener : listeners_)
269 listener->modulationWheelMoved(e, wheel);
273 for (
Listener* listener : listeners_)
274 listener->modulationLostFocus(
this);
278 listeners_.push_back(listener);
282 if (parent_ ==
nullptr)
285 std::vector<vital::ModulationConnection*> connections =
290 disconnectModulation(connection);
294 disconnectModulation(connections[connection_index]);
304 active_modulation_ = active;
316 for (Listener* listener : listeners_) {
317 listener->modulationDisconnected(connection, modulations_left <= 1);
318 listener->modulationConnectionChanged();
323 if (modulations_left <= 1) {
324 for (Listener* listener : listeners_)
325 listener->modulationCleared();
static Fonts * instance()
Gets the singleton instance of the Fonts class.
Definition fonts.h:52
static String getUiSourceDisplayName(const String &original)
Returns a display name suitable for the UI given a source string.
Definition modulation_matrix.cpp:529
virtual void render(OpenGlWrapper &open_gl, bool animate)=0
Pure virtual function to render the component using OpenGL.
virtual void resized() override
Called when the component is resized.
Definition open_gl_component.cpp:121
void setComponent(Component *component)
Sets the component to be drawn into the OpenGL image. If not set, uses this component.
Definition open_gl_image_component.h:83
void setActive(bool active)
Sets whether this component is active (rendered) or not.
Definition open_gl_image_component.h:113
void setUseAlpha(bool use_alpha)
Enables or disables alpha blending for the image.
Definition open_gl_image_component.h:95
virtual void redrawImage(bool force)
Redraws the image if necessary, creating or updating the internal Image.
Definition open_gl_image_component.cpp:16
void setColor(Colour color)
Sets a color tint for the image.
Definition open_gl_image_component.h:101
static Path dragDropArrows()
Creates a drag-and-drop arrows icon path.
Definition paths.h:211
A component that draws a shape into an OpenGlImageComponent.
Definition open_gl_image_component.h:417
void setShape(Path shape)
Sets the shape to be drawn.
Definition open_gl_image_component.h:441
@ kWidgetMargin
Definition skin.h:103
@ kBodyRounding
Definition skin.h:71
@ kModulationButtonSelected
Definition skin.h:179
@ kBorder
Definition skin.h:134
@ kWidgetBackground
Definition skin.h:173
@ kBodyText
Definition skin.h:133
@ kLightenScreen
Definition skin.h:141
@ kModulationButtonUnselected
Definition skin.h:181
@ kShadow
Definition skin.h:142
std::vector< vital::ModulationConnection * > getSourceConnections(const std::string &source)
Returns all modulation connections from a particular source.
Definition synth_base.cpp:236
bool isSourceConnected(const std::string &source)
Checks if a given modulation source has any active connections.
Definition synth_base.cpp:245
void forceShowModulation(const std::string &source, bool force)
Forces a modulation source to remain active even if not currently connected.
Definition synth_base.cpp:216
int getNumModulations(const std::string &destination)
Counts how many modulations target a given parameter.
Definition synth_base.cpp:227
SynthBase * getSynth()
Returns the SynthBase instance this interface is managing.
Definition synth_gui_interface.h:85
void disconnectModulation(std::string source, std::string destination)
Disconnects a modulation from the GUI layer.
Definition synth_gui_interface.cpp:146
Base class for all synthesizer sections, providing UI layout, painting, and interaction logic.
Definition synth_section.h:193
void showPopupSelector(Component *source, Point< int > position, const PopupItems &options, std::function< void(int)> callback, std::function< void()> cancel={ })
Shows a popup selector with options.
Definition synth_section.cpp:119
float findValue(Skin::ValueId value_id) const
Finds a value in the skin overrides or from the parent if not found locally.
Definition synth_section.cpp:18
static std::string getDisplayName(const std::string &name)
Definition synth_parameters.h:212
A helper struct containing references to OpenGL context, shaders, and display scale.
Definition shaders.h:174
A structure representing a single modulation connection between a modulation source and a destination...
Definition synth_types.h:30
std::string destination_name
The name of the destination parameter.
Definition synth_types.h:74