Switching behaviour from dragable/resizeable to normal


#1

I have a simple button component that when created is both drag-able and resizeable. I want to be able to call a method that turns this behaviour off so that button can be used as normal. I’ve tried deleting the ResizableBorderComponent and ComponentDragger from my button class. I’ve also tried not painted these objects when in ‘use’ mode as opposed to ‘edit’ mode. I can easily prevent dragging and resizing and I can also remove the rectangle from around the button but I can’t get it to behave as a regular button. Any ideas? The button component is derived from TextButton.


#2

Sounds like a bit of a hack.

If I had to do this, I’d probably create a special invisible component that can be added to the button, so that it fills it up and covers it, and that does the dragging. Then you can add and remove this component to make your button draggable. You could probably manage to write something like that which would work on any existing component, rather than needing a specially written subclass.


#3

check this out.

i’m sure you could tweak it to only affect specific components (perhaps using a component property to identify components you want to be editable? who knows!)


#4

This looks perfect only I can’t seem to get it to work! I have the following simple class in which I place the ComponentLayoutEditor:

#ifndef ControlsClass_H
#define ControlsClass_H

#include “juce.h”
#include “juce_amalgamated.h”
#include “utilities.h”
#include “ComponentLayoutEditor.h”

class ResizableTextButton : public TextButton,
public CabbageUtilities
{
public:
ComponentLayoutEditor* editor;
ResizableTextButton(String name) : TextButton(name)
{
editor = new ComponentLayoutEditor();
editor->setTargetComponent(this);
addAndMakeVisible(editor);
}

void resized(){}

void paint(Graphics& g) {
TextButton::paint(g);
}

};

#endif//ControlsClass_H

Then in my main window I create an object of the above class, and enable the editor component of that class but it still appears as a regular button, here’s the code:

ResizableTextButton* control = new ResizableTextButton(T("my button"));
control->setBounds (cAttr.left, cAttr.top, cAttr.width, cAttr.height);
control->editor->setEnabled(true);
control->addButtonListener(this);
addAndMakeVisible(control);

Must be something obvious I’m doing wrong, any ideas?


#5

too tired to explain, but it looks like you’ve misinterpreted how the thing works.

milestone week at work means i can no longer form useful sentences.
however, perhaps this graphic i just knocked up will help explain how the system should be used…


#6

I’ll need the study the diagram! Still not sure how this is supposed to be put together but I’ll give it another whirl tomorrow. Cheers,

Rory.


#7

that’s okay, sorry i don’t have the energy to put more effort in! If you look at the diagram, and study my description in the thread i linked you to, you should understand it.

the important thing to notice is that you don’t need to subclass button at all; it will work on ANY component type WITHOUT MODIFICATION.


#8

I have a main component which every other component will be placed on top of. You state that ‘The only prerequisite is that the editor component is a sibling of the component being edited’ so my editable GUI components and the editor must be members of my main component class, is that right? I’ve tried so many combinations now that I’m starting to see ComponentLayoutEditors in my sleep! I’ll keep plying away at it…


#9

If I’m reading haydxn right, your main component will need to contain two child components, the first being a panel that contains your widgets, and the second being the editor overlay.

Obviously the editor panel will need to be brought to the front so that it is ‘above’ the component panel.


#10

Thanks everyone, I’m getting there now, I think. It’s still not right, but I’m starting to see signs of progress in my understanding of how this works. Thanks again for your patience.


#11

… i guess that bolded bit there can be misinterpreted :slight_smile: by “the component being edited” i mean “the component whose contents are being edited, i.e. the one whose children you wish to manipulate”. [there, y’see, my sentences aren’t turning out very well at all!]

basically, valley’s info there is bang on.


#12

I’m getting places here with this albeit frightfully slow. I’m happy to continue trying to figure this out myself however I have a quick question, do I need a separate editorlayout component for each button/slider/knob/etc? I hadn’t imagined so but I can’t seem to get multiple resizeable components without using multiple layouteditors…


#13

Ok, here’s what I’m doing. I think I’m following the correct approach?

In my main component’s constructor I do the following:

panel = new PanelComponent();
addAndMakeVisible(panel);
editor = new ComponentLayoutEditor();
editor->setTargetComponent(panel);
editor->toFront(true);

In my panel component I have a popup menu that drops a button onto my panel. Obviously this isn’t working. If however I make the editor component a child of my panel and create a new editorcomponent for every button it at least gives me a resizeable box to play with although the behaviour of each one is dodgy. Any more suggestions?


#14

having an editor component for each button is absolutely not what you should be doing. absolutely! not! do not!

i recommend you read through all of the replies to the thread i linked you to… the answer to your problem is in there!

[and i apologise for not having updated the code in my original post with the suggestion! :s :slight_smile: ]


#15

Will do! Thanks again for pointing me in the right direction.

Rory.


#16

When you suggest that the answer is contained in previous posts do you mean the following: ‘The only prerequisite is that the editor component is a sibling of the component being edited’. Doing that now gives me better results. The first button I drop onto my panel is editable so long as I call editor->setTargetComponent(this); in my Panel::InsertButton() routine. The next button I drop in is not editable however. I’m sure I’m getting close with this, I just can’t figure out where to place my call to editor->setTargetComponent(this);, if I call it after I create my editorLayout component object I don’t get an editable box??? Any further hints? Thanks again…


#17

Nope, the answer is in one of the replies…

specifically :

[quote=“kraken”]cool :slight_smile:
i would only suggest making this patch:

[code]ComponentLayoutEditor::ComponentLayoutEditor ()
: target (0)
{
setColour (ComponentLayoutEditor::aliasIdleColour,Colours::lightgrey.withAlpha(0.2f));
setColour (ComponentLayoutEditor::aliasHoverColour,Colours::white.withAlpha(0.5f));

setInterceptsMouseClicks (false, true);
}[/code]

this way you can intercept the mouse events on the underlying component and show a regular popup menu if you want to (the easy way to add components to edit) :)[/quote]


#18

I already had that included??


#19

[quote=“Rory”]Ok, here’s what I’m doing. I think I’m following the correct approach?

In my main component’s constructor I do the following:

panel = new PanelComponent();
addAndMakeVisible(panel);
editor = new ComponentLayoutEditor();
editor->setTargetComponent(panel);
editor->toFront(true);

In my panel component I have a popup menu that drops a button onto my panel. Obviously this isn’t working. [/quote]

sorry, this comment made it seem like you’d missed it out. Why is it ‘obviously’ not working then? What do you mean by that?

[edit: just noticed that you don’t have an addAndMakeVisible(editor); call… not sure if you just forgot to paste that into your post tho]


#20

I mean it’s obviously not working in that I cannot move or resize the component and no edit box is drawn around it. Just so we’re clear, I’ve reverted back so that my panel is parent to all buttons and both panel and layouteditor are children of my main component. I’ve tried many different arrangments but with the one outlined above I don’t see any box. I do call addAndMakeVisible(editor);, just forgot to paste it in…