Using CompentBoundsConstrainer with native window decoration


#1

I need to use a ComponentBoundsConstrainer to enforce a fixed aspect ratio on my ResizableWindow. While this works fine when using the juce title bar, I’m having trouble when switching to the native title bar.

On Windows 7, if I drag the corners of the window and release the mouse, the new window bounds are slightly off, and while dragging the constrainer sometimes changes the position and size of the window. If I resize at a window edge, the window resizes fine will dragging, but after releasing the mouse button the component switches back to its original position.

On Mac the problem is less obvious (because you can’t resize on the edge) but looks similar: while resizing with the (native) corner-resizer the window bounds sometimes switch to a wrong size.

This is not specific to my app, but also reproducable in the juce demo (today’s git) if I change the MainDemoWindow to use a constrainer:

    setResizable (true, false); // resizability is a property of ResizableWindow

    setUsingNativeTitleBar(true);
    ComponentBoundsConstrainer* constrainer = new ComponentBoundsConstrainer();
    constrainer->setFixedAspectRatio(1.5);
    setConstrainer(constrainer);

If I add a juce corner-resizer with “setResizable (true, true)”, resizing works fine as long as I only use the corner-resizer, but the same issues apply if I resize the window by its native border.

Is the ComponentBoundsConstrainer not meant to be used in combination with “native” resizing, or am I just doing something wrong?


#2

Thanks, I don’t think I’ve ever tested aspect-ratio constraints in a native window, I’ll take a look and sort it out…


#3

Thanks for making those changes, I just tested it (on Windows) and resizing works much better now.

There’s just a couple of problems left if I constrain the aspect ratio and the min. onscreen amounts at the same time. The main window of our app has a “portrait” aspect ratio on which the layout depends, and we want to ensure it’s not resized beyond the top and bottom edge of the desktop, so I use “setMinimumOnscreenAmounts(0xffffff, 64, 0xffffff, 64);”

all these issues appear (at least on win7, did not check on the mac yet) the moment you hit the upper/lower desktop edge while resizing

with native title bars:

  • if I resize the window on the right edge, the onscreen-amounts-constraint is enforced after the aspectRatio, so the user ends up with a window that’s wider than it shold be
  • while resizing via one of the corners, the constrainer quickly switches between enforcing either the onscreen amounts or the aspect ratio

using juce title bars, its a bit different:

  • if dragged on the right side, the aspectRatio is kept, but the onscreen-amounts is not enforced
  • if dragged on the corner, the window-border flickers until I release the mouse. After releasing, the onscreen-amounts is enforced, but the aspect ratio is wrong

Would it be possible to support this combination of constraints for aspect-ratio and onscreen-amounts?


#4

…one more oddity I discovered: while resizing on the right edge (only when using native title bars) the components inside the window receive mouse events.

For example I have a component near the right edge of the window: if I enlarge the window, the moment the component’s outline (as defined by its hitTest-method) is beneath the original mouse position of the window-resizing drag, mouseEnter() gets called for that component. Is there a way I can circumvent that?


#5

I did a bit of tidying up so you might want to try this again. It’s unbelievably complex though, there are a lot of edge cases (literally!) so there are probably still situations involving tricky combinations of fixed-aspect + size limits where you can get it to go wrong - if so, please have a look inside ComponentBoundsConstrainer and suggest a fix, because the logic in there was starting to hurt my brain, and I don’t really want to look at it again!

I didn’t get chance to look at the win32 mouse-event thing, I’ll do that when/if I get a free moment…


#6

Thanks for your effort! The flickering effect that I mentioned isgone, and I noticed only one regression bug: using the juce-titlebar, the minOffTop constraints is no longer constrained when moving the window.

Great news is that it’s indeed no longer possible to resize to anything other than the fixed aspect ratio.

One issue remained which I was able to work around in my app code: Just calling setMinimumOnscreenAmounts(0xffffff, 64, 0xffffff, 64) did not prevent the window from growing beyond the desktop height. I circumvented that by specifically constraining the size to the desktop height:

constrainer->setMaximumSize(desktopHeight * aspectRatio, desktopHeight);

That’ll work fine for now. I might give it a try to fix this inside checkBounds(), but I’m quite convinced that if I manage to fix it for my special scenario I’ll probably break it for someone else.


#7

Whoops! Bit of a typo there, I’ll fix that right away! Thanks!