Switching behaviour from dragable/resizeable to normal

r

Are you setting the bounds of the editor in your parent’s resized() function along with the panel? (last thing I can think of- it literally just works out of the box and I can’t think of anything else that would stop it working for you)

I sure am. By the way, when I said it’s obviously not working, I meant to say it’s obvious that I can’t get it to work rather than it not working. In case there is still something I’m doing wrong I’ve pasting in the relevant code from my example. Perhaps there is something silly I’m doing!

MainComponent::MainComponent()
{
panel = new PanelComponent();
addAndMakeVisible(panel);
editor = new ComponentLayoutEditor();
editor->setTargetComponent(panel);
editor->toFront(true);
addAndMakeVisible(editor);
}

void MainComponent::resized()
{
panel->setBounds(0, 0, 300, 300);
editor->setBounds(0, 0, 300, 300);
}

void PanelComponent::mouseDown(const MouseEvent &e)
{
PopupMenu popMenu;
popMenu.addItem (1, “Edit”);
popMenu.addItem (2, “Lock”);

PopupMenu popMenuControls;
popMenuControls.addItem(3, "Button");
popMenuControls.addItem(4, "Slider");
popMenuControls.addItem(5, "CombobBox");
popMenu.addSubMenu("Controls", popMenuControls);
    
if(popMenu.show() == 3){
	control = new TextButton(T("my button"));
	control->setBounds (e.x, e.y, 70, 30);
	addAndMakeVisible(control);
}

}

Hopefully you can spot something odd in my code, otherwise it’s back to the drawing board!

Okay, two last things:

1: the editor must be added to the parent component BEFORE you set the panel as the target; why? Because until they’re both added to the same parent component, they don’t meet the hierarchy criteria. This should have hit an assert though.

2: you must have a way of toggling the editor on and off. A button is no use if you can’t click it! When you toggle the editor, it will rebuild its overlay thingamabobs. If it’s just on all the time, this will never happen unless it’s told to, so you won’t get them. Ever! A call to editor->updateFrames() will do the trick (you could do this when you add a new component, though you’d want to test to see if the editor isEnabed() first. Oh, and in case it wasn’t obvious, setEnabled(bool) is how you switch it on or off.

Thanks again for the help. One thing that sounds the alarm bells is where you say: “A call to editor->updateFrames() will do the trick (you could do this when you add a new component,…”. My ‘editor’ component is a child of my MainComponent class therefore is not accessible within my ‘PanelComponent’ class methods as my PanelComponent is also a child of my MainComponent. I got better results when editor was a child of PanelComponent?

Well that’s not really a problem, is it. You can set up some means of communicating that your app needs to rebuild the editor overlays, regardless of how the components are arranged! I’m afraid I don’t have Internet on by computer at the moment, else I’d write you something to make it easier :frowning: [I Have to write these replies on my phone! It is torturous! ;)]

One obvious thing you could do is assume that your panel requires the editor. If it has the means to add a button from a menu, it’s probably safe to assume that it’s a useless feature if you can’t arrange them; thus, you have a dependency, so it’s safe to store a pointer to the editor in your panel. Assign it at the same time as when you setTargetComponent() [or alternatively, give your panel an attachLayoutEditor() function which calls setTargetComponent automatically on the editor passed in] and you have a means to call updateFrames directly

I guess the logical thing for me to do is make a LayoutEditingParent or something, which- like DocumentWindow, takes a ‘content component’ but secretly has it’s own ComponetLayoutEditor in front. That’d certainly make things easier to explain! If I find a way to upload a file transferred onto my phone, then I’ll sort one out for you. If not… I hope my other suggestions have helped!

Good luck

I can’t believe you’re corresponding by phone! Please don’t worry about this until it’s convenient for you. Greetings by the way from the Linux Audio Conference in sunny Parma!

Well, it is an iPhone so it’s not so bad :slight_smile: just moved house so still awaiting connection.

Time, I think, for beers in the sun! {while the idea still occurs to me due to not being sat at a real computer!}

Enjoy, thanks again for your help on this.

Regards.

I think I’ve tried everything I can think of now and still I’m getting nothing. What platform are you using? I’m using windows XP but I can’t see how that would be the problem, or could?

i have the internet! so when i get a chance, i’ll knock up a far-easier-to-use version for you :slight_smile:

Here’s a link to the new code files. [on my skydrive space, should hopefully work okay].

I’ve not tested extensively, but what i tried worked :slight_smile: [although i haven’t updated juce in a while].

I’ve given you an extra couple of classes.

ComponentLayoutContainer
This is the main doodad. You create one of these, and you call…

layoutContainer->setContentComponent(myPanelComponent);

… and it should just work.

Another handy-helpy-treat i put in is…

layoutContainer->setUsesBar(true);

…which will give it a built-in control bar with handy EDIT button hooked up. [size=75]You can subclass ComponentLayoutContainerBar to add more controls to it (though you might just want to rewrite that part of it because i was literally chucking ideas in with little thought!) - you’d obviously also need to subclass ComponentLayoutContainer to make sure the right bar gets created…[/size]

I’ve added a few static helpers to make some things easier/less scary. One will simply return a pointer to the CopmonentLayoutContainer parent of a component, if it is indeed a child of it. This means you can call, for example, from your panel component:

ComponentLayoutContainer* parent = ComponentLayoutContainer::findParent (this);

… which will only return a valid pointer if its immediate parent is a ComponentLayoutContainer. That’s a just-in-case; perhaps more usefully, there’s this one:

ComponentLayoutContainer::updatesFramesFor(this);

… which, again, you can call from your panel component; if the parent is a ComponentLayoutContainer, this will call updateFrames on the associated editor. I.e. this is how you could notify when you add a new widget from your PopupMenu.

Hope this helps! [+works]

Great, I’ll let you know how I get on with it. I’m fairly busy at work this weather so I might not get a chance to try it for a few days, either way I’ll let you know.

No problem :slight_smile:

I just re-read my post, and figured i’d add a few extra comments to clarify things - i’d hate for you to get confused and struggle to make sense of it!

Basically, all you need to do is create the ComponentLayoutContainer, add it to your window, and set your panel component as the container’s content component. If you set the container to use a bar (i certainly recommend it at least for the first time you try it), you’ll immediately have a built-in way to toggle the editor.

The buttons/widgets/etc that you place on your panel do not have to be modified in any way to use the editor. Simply click the ‘edit’ button, and they’ll be movable and resizable. [and click it again and they’ll be fixed and functional]

I have a few more ideas for it, but i’ll wait and see how you get on before i do any more :slight_smile:

I have it working with a simple project and it’s behaving just as I would expect from the descriptions in your posts. Now to get it going with a more advanced project I have lying around, thanks again for all the help.

glad to both hear it and be of service :slight_smile: