Resizing components relative to parent


#1

I am trying to add a new component within an existing component, but size the newly added component relative to the parent with setBoundsRelative().

The size of the new component is always relative to the width of the screen (1280, 800) rather than relative to the size of the parent component. My parent component’s size is 600 x 400. The newly created components size should be relative to 600 x 400. Not 1280 x 800.

I know this because I use getParentWidth() and getParentHeight() to print the parent component’s width and height, and they are the size of the desktop screen (1280, 800). Furthermore, the documentation for getParentWidth says:

  1. How is the component being “on the desktop” (what does that mean?) just by virtue of adding it within a parent component? I mean, of course it’s on the desktop, this shouldn’t nullify the fact that it was created by my 600,400 parent component, right? When I add a tabbedComponent within the 600,400 parent, I can perfectly align the tabbedComponent’s height and width relative to the parent within resized(), and the tabbedComponent is on the desktop. Why can’t I add a component within the parent and do the same thing? I think I am just confused as to the semantic meaning of “on the desktop” within juce, and looking for some clarification, so I can get around this.

  2. How do I tell juce that the new component is a child of the 600,400 component and not the 1280,800 desktop? This will then allow me to use setBoundsRelative() correctly.

:stuck_out_tongue:


#2

Can u post ur resized() method code. Cant make out just by reading the story. And the use of getParentWidth () , getParentHeight() is not necessary.


#3

You still seem incredibly muddled by the notion of parent components! It’s really very very simple - when you ADD a component using addAndMakeVisible or addChildComponent, then you make it a child of that parent component. If you just create a component, it can’t possibly have a parent until you actually add it to something!


#4

I thought I understood how parenting works, and I am adding the component to the Parent. 8) I should have mentioned that bit. I’ve tried both addAndMakeVisible and addChildComponent and setVisible - but neither seem to achieve my intent.

Here is the parent component constructor, where the tabbedComponent and the child component are created. The tabbedComponent is perfectly sized relative to the parent, but not the child component:

// parent constructor
{
    // Example tabbedComponent
    addAndMakeVisible (tabbedComponent = new TabbedComponent (TabbedButtonBar::TabsAtTop));
    tabbedComponent->setTabBarDepth (30);
    tabbedComponent->addTab (T("Summary"), Colours::white, 0, false);
    tabbedComponent->addTab (T("Start Scan"), Colours::white, 0, false);
    tabbedComponent->setCurrentTabIndex (0);

    // Adding the child component
    addAndMakeVisible (themes = new ThemeComponent());
}

void ParentComponent::resized()
{
        tabbedComponent->setBounds (proportionOfWidth (0.0658f), proportionOfHeight (0.0980f), proportionOfWidth (0.8560f), proportionOfHeight (0.7473f));
}

In the class for the Child Component, I set the size in the constructor for the child component, but this doesn’t achieve the desired effect:

{
        // Set the bounds of this child relative to it's parents size, which is 600 x 400
        setBoundsRelative(0.0547f, 0.0931f, 0.8860f, 0.7022f);
}

#5

So you’re expecting the addAndMakeVisible call to happen before the child has been constructed?!? doh!

But anyway, a child shouldn’t be resizing itself. It’s the parent’s duty to lay out its child components where it wants them, in its resized() method. Otherwise how would you be able to re-use a child component inside different parents, where it might need to be positioned differently?


#6

Ok I understand that the child shouldn’t be resizing itself and that this is the job of the parent. So I’ve changed things around but I believe I’m still back to the original problem - the new component still isn’t a child of the parent, and I’m obviously still missing something essential.

I’ve printed some debug to see and learn what is happening. It looks like the child is added because I can see in the constructor for it, some debug statements. But the debug statements are telling it that the parent’s size is still wrong. 1280 x 800 instead of 600 x 400.

This is the new constructor for the parent:

{
    // Some debug statements
    setSize (600, 400);
    int width = getWidth();
    int height = getHeight();
    printf("ParentComponent initial width: %d, height:  %d\n",width,height);
   
    // Add the child component
    themes = new ThemeComponent();
    addAndMakeVisible (themes,-1);

    // Add the tabbed component
    addAndMakeVisible (tabbedComponent = new TabbedComponent (TabbedButtonBar::TabsAtTop));
    tabbedComponent->setTabBarDepth (30);
    tabbedComponent->addTab (T("Summary"), Colours::white, 0, false);
    tabbedComponent->addTab (T("Start Scan"), Colours::white, 0, false);
    tabbedComponent->setCurrentTabIndex (0);
}

This is resized() for the parent component:

void ColorComponent::resized()
{
        tabbedComponent->setBounds (proportionOfWidth (0.0658f), proportionOfHeight (0.0980f), proportionOfWidth (0.8560f), proportionOfHeight (0.7473f));
        //themes->setBounds (proportionOfWidth (0.0547f), proportionOfHeight (0.0931f), proportionOfWidth (0.8860f), proportionOfHeight (0.7022f));
        //themes->setBoundsRelative(0.0547f, 0.0931f, 0.8860f, 0.7022f);
}

Here is the constructor for the child component:

{
        int gpWidth = getParentWidth();
        int gpHeight = getParentHeight();
        int x = getX();
        int y = getY();
        int childWidth = getWidth();
        int childHeight = getHeight();
        printf("parents width:  %d\n",gpWidth);
        printf("parents height:  %d\n",gpHeight);
        printf("X co-ordinate:  %d\n",x);
        printf("Y co-ordinate:  %d\n",y);
        printf("ChildComponent getWidth():  %d\n",childWidth);
        printf("ChildComponent getHeight():  %d\n",childHeight);
}

I’ve commented out the resized() statement for the child component because it’s getting a runtime error, but I can see from the debug output statements that, within the constructor for the child, the child isn’t seeing the size of the parent correctly. It’s seeing it as 1280 x 800 and not 600 x 400.

Here is the output:

./testapp
ParentComponent initial width: 600, height: 400
parents width: 1280
parents height: 800
X co-ordinate: 0
Y co-ordinate: 0
ChildComponent getWidth(): 0
ChildComponent getHeight(): 0


#7

:roll: Like I already told you, how do you think the child could possibly have been added to its parent BEFORE its constructor has been called?? Think about the order in which things happen!!


#8

Jules,

Thanks for your comments. I guess I’m not communicating properly or understanding you, because I did change the code so that the constructor for the child is before the line that adds it to the parent, like this:
// calls the constructor for the child
themes = new ThemeComponent();

// adds the child to the parent
addAndMakeVisible (themes);

But judging from my debug statements, the child still isn’t seeing the intended parent that I want it to see.

I think what I am trying to do can’t really be done in this way and needs to be done in a different way.

I was trying to create a component to pop up inside of an already created component. I could do this, but the newly created component couldn’t be centered properly inside of the 600x400 default size of the component. The newly created component only looked correctly sized when I maximized the parent component. Here is what I am talking about:

Child component is a blank grey component that should be covering the tabbedComponent, but you can see below that it doesn’t look correctly aligned relative to the size of the parent, and cover up the tabbedComponent.
[attachment=1]ss1.png[/attachment]

But when you maximize the parent component, the child component perfectly covers up the tabbedComponent.
[attachment=0]ss2.png[/attachment]

I’m just assuming that you can’t create a child component inside of an already created component as a popup component. You can do this, but it won’t be a child of the parent component. I’m assuming that the only way to do what I am trying to do is to use setContentComponent or just create a new DocumentWindow that pops up inside of the parent component.


#9

How can I possibly explain this any more simply…!?

You’re creating a child component and THEN, after it has been constructed, you can add it to the parent.

So while you’re constructing it, it has not yet been added to the parent. It has no parent yet. It is still parent-less. Right?

So, in the child’s constructor, when you ask it about its parent’s size, it DOES NOT YET HAVE A PARENT! But you still seem mystified by the fact that it can’t magically tell you the size of the parent that you’ve not yet given it!


#10

I finally got it! Thank you for being patient! My debug statements were inside of the constructor so there was no possible way it would have known it’s parents size before it was added :smiley: Only after the child constructor ends and andAndMakeVisible() runs from the parent would the child possibly know the size of its parents! :mrgreen: So I’ll add a button inside of the child that will test to know it’s parents size with the debug statements.

So I guess I will need to uncomment my resize statement for the child that is inside of the Parent:
void ParentComponent::resized()
{
tabbedComponent->setBounds (proportionOfWidth (0.0658f), proportionOfHeight (0.0980f), proportionOfWidth (0.8560f), proportionOfHeight (0.7473f));
//themes->setBoundsRelative(0.0547f, 0.0931f, 0.8860f, 0.7022f);
}

Because when it is uncommented I get this runtime error:
./testapp
ERROR: Program executed illegal instruction… terminating

Probably because I am trying to resize it outside of a bound that is possible.


#11

Hallelujah!


#12

:shock:


#13

Hey thank you very much once again for all of your help.


#14

Thats wat i asked in the beginning… Post ur resized() method code… U dint had a proper rezied() method for the child component. And Jules has given awesome resized() method to set the bounds of child components. And i have seen most of the people still set the bounds in constructor.


#15

Yes, setting the bounds in the constructor for the child component was a crucial error. So now I know that the parent should always set the bounds for children in resized(). Thanks.