Moveable objects in JUCE component

opengl
projucer
gui
windows

#1

I am working with Projucer and i want to add objects to my component with a buttonclick. When they are added to the Component, i want to drag them arround and measure thier position. Is there a simple way to do this in JUCE?

I have got three Components:

  • Program
  • View
  • Data

In my Program component I have got a JUCE-Viewport with the View component showing. The Data component is initialized in the View. With a Buttonklick in the Program component I want to add an image to the View component where I can drag it arround. In the Data Component i want to read the positions form the View´s Objects.

My Question is, how can I make dragable Objects in a JUCE component while runtime. I do not want full code provided, but I did not found anything in the internet.


#2

That should not be too difficult. Check out the Juce Pluginhost (it’s in the examples folder)
The graph editor allows to insert plugins and drag them around on the panel.
You can just borrow the relevant code from the FilterComponent struct (Line 298 in JUCE/examples/audio plugin host/Source/GraphEditorPanel.cpp)
In case your objects have their own mouse response behaviour when the layout is frozen you might want to employ the state design pattern to implement the different states.


#3

I was looking for a way of dragging components around too a while back. There’s actually an easy to use gem of a class built to do this!

https://www.juce.com/doc/classComponentDragger


#4

Interesting! I wonder why the ComponentDraqgger isn’t used to make the Pluginhost’s FilterComponent draggable.


#5

Be careful, this is a classic example of something where inexperienced coders always take the wrong approach!

The naive thing to do is to use something like a ComponentDragger or a mouseDrag callback which directly changes the component’s bounds. Yep, that’ll certainly move it around visually, which is fine if you don’t care where it ends up.

BUT if your app has any kind of state where the position of things is meaningful, or if actually use or save the positions, then you need to be smarter about it:

  • Intercept the mouse drag events and make them tell your MODEL that the position of that object has changed. But do NOT make a mouse-drag move the component itself!
  • Make sure that when you model changes, the appropriate components get their bounds updated.

The point of this is that you never use the position of a Component as part of your model’s state, you always update the GUI from the model and never make the GUI update itself in response to a user action.


#7

I don´t know which part of the class you mean, because I cannot compile the program, due to many files are missing


#8

Yeah i noticed, if another component like a label is in the component where the dragger is in, it does not bubble down. to my real dragable component.

What should i use instead of the ComponentDragger? Because i used it already to create all i need.


#9

You can attach a mouselistener to the parent component to get drag events from everything including its children, or just set the child components to ignore mouse clicks.

But please do pay attention to my post above - I don’t know what you’re trying to build, but it’s probably good advice.


#10

The problem @jules is pointing out with ComponentDragger is that it sidesteps modifying the component position to your app’s data model and just modifies the component (GUI object) directly. This will cause issues later on when trying to serialize (save to disk)/undo/redo/other trivial data model operations which will depend on the component’s position you’re modifying with the ComponentDragger.

A much better (but not as beginner-friendly) solution @jules is strongly suggesting is to follow what the plugin host example is doing: use mouse drag events in your component to set x/y position properties in your data model, then use that data model change to trigger a redraw of the GUI element.

To help you get your bearings, in the case of the plugin host example, the FilterGraph class is the “model” which handles state including reading/writing to disk and the GraphEditorPanel is the “GUI” which updates the model at runtime. It’s a very good example of a simple document-based app with draggable elements.


#11

You mean you can not compile the audio plugin host example? This should really work right out of the box.
What error messages do you get?