Device rotation issue


#1

I have used the introjucer (very helpful, btw!) to build / layout several component classes, each of which display different views of my app (MainMenu, Setup, CalculateNutrition, BuildMeal, AddFood, etc.). Each of these contains a number of subcomponent labels, combo boxes, etc. that are positioned and sized using the percentage of parent modes. All of this works swimmingly (had to use that word-ha) for running the same layout across laptop, ipad, iphone, etc. including when I rotate the screen between landscape and portrait.

.... Except in this one case where I'm probably not understanding some fundamental.

If I create a component class like so, things are sized correctly :

        BuildMeal* pBuildMeal = new BuildMeal (m_pMainWindow);

        const Rectangle<int> rectangleBounds = getBoundsInParent ();

        pBuildMeal->setBounds (rectangleBounds);

        addAndMakeVisible (pBuildMeal);

        m_pMainWindow->setContentOwned(pBuildMeal, true);

This allocates the new view and (via setContentOwned()) deletes the previously displayed component.  This model works great for scaling and rotating appropriately on the device as it transitions between landscape and portrait.

However, sometimes I want to do all of the above minus the setContentOwned() call because I want to briefly overlay (or partially overlay) what is displayed but not delete it since I will return to it shortly thereafter. In that case the display looks correct until I transition from portrait to landscape (or vice versa). When the device is moved all of the content turns, but the component class on top (the one added without the call to setContentOwned() does not resize to fill the screen as it should resulting in seeing the other content that is underneath it.

For example, BuildMeal is created and displayed (as per above). Then the BuildMeal instance create and makes visible the AddFood class. All of this while in portrait. Then the device is tilted to landscape. BuildMeal rotates and resizes perfectly, but the AddFood only rotates but does not resize so is too small and then I can see part of the BuildMeal display that is no longer covered up.

I assume this is occuring because some call that is made automatically by the main window to the content it owns (BuildMeal) is not occurring for the overlay content (AddFood) that it does not own.  I've tried manually calling the resized(), moved(), parentSizeChanged() methods on the overlay content when the same is called in the main window owned content, but this doesn't solve the problem.

Btw, all of this is done with setFullScreen (true) in the main window.


#2

ANSWER TO MY OWN QUESTION ABOVE: I *think* the fundamental issue here is that the subcomponent that is not owned by the MainWindow is unaware that the bounds have changed (width became height & height became width) when transitioning between landscape and portrait. So, the magic to make this work is to not only propagate the resized() call to the subcomponent (which I was already doing), but prior to that also call getBounds() in the MainWindow-owned component and use the result to call setBounds() in the subcomponent.

This seems to solve the issue for me at least.  

Jules / others-more-in-the-know, please correct me if I'm wrong here.

So (using the same object names as above) I added:

BuildMeal::resized()

{

....  resize code for BuildMeal ...

    if (AddFood != NULL)

    {

        Rectangle<int> r = getBounds();

        AddFood->setBounds(r);

        AddFood->resized ();

    }

}


#3

Yes, if I understand you correctly, then you would have to call resized() (or some other method) on child components if you need them to react to their parent changing.

The resized() method itself is only called on the components whose bounds actually change, and not for every sub-component inside it.