How to Prevent Widget Autoscaling?

Started by Zetal, 14 July 2017, 21:03:46

Zetal

I've just started working with TGUI- it's realllly nice so far! The built-in menubar is particularly nice. But then, you probably already knew that.  ::)

I've been trying to figure out how to stop my menu bar from resizing to fit the % of the screen it originally matched.


    auto menuBar = tgui::MenuBar::create();
    menuBar->getRenderer()->setBackgroundColor(tgui::Color(240, 240, 240));
    menuBar->getRenderer()->setTextColor(tgui::Color(10, 10, 10));
    menuBar->setSize({ 500, 18 });
    menuBar->setTextSize(14);


This, for example, produces exactly what I want. However, when I resize the window, the menuBar becomes much larger than 18pixels, and the text becomes blurred slightly as it stretches to fit.

I was reading the documentation and saw that in 0.7 there is a 'scale' method that looked like what I want. I'm currently using 0.8 though and didn't see anything like it. Should I downgrade, or is there an alternative?

Thanks!  :)

texus

The scale function just calls setSize(getSize() * scaleFactor), which is not what you need. (I removed it from 0.8 because you can easily call setSize yourself)

What you are describing sounds like the view not being changed, if that is the case then it should affect all widgets and not just the MenuBar. Unless you call gui.setView when the window is resized, the view will remain unchanged and everything drawn to the screen will be stretched. (SFML has the exact same behavior by default, you also need to call window.setView if you want your own SFML drawings to not get stretched)

If that is not the problem then please provide some minimal and complete code that reproduces the issue so that I can try it here.

Zetal


conleec

Hello, I'm new here and a total newbie, so please stick with me.

I'm using SFML and TGUI to learn C++ and am super excited by my progress in a few days. I've managed to build and install both, and have used CLion (on a Mac) to build the two examples. Just as a curiosity I had the same question: is it possible to avoid the autoscaling of widgets when resizing the window?

So I can get my head around it, would it be possible to explain to me, using the "many_different_widgets" example, how this would be accomplished?

Thank you so much in advance. Really looking forward to my journey.

Chris Conlee

PS: I'm not a total neophyte, just FYI. I studied computer systems engineering back in the '80s, but spent more lab time with COBOL and Fortran than C or C++. Life took me in a different direction, but am getting back to it on a hobby basis.

texus

The "autoscaling" happens with your own SFML drawings too. For this you need window.setView when resizing the window. This doesn't affect TGUI however since it uses its own view, but you basically have to do the exact same thing, but just use gui.setView instead of window.setView.

So to disable the "autoscaling" for both TGUI drawing and your own SFML drawings, you can add the following code inside the event loop:
Code (cpp) Select
if (event.type == sf::Event::Resized)
{
    window.setView(sf::View(sf::FloatRect(0, 0, (float)event.size.width, (float)event.size.height)));
    gui.setView(window.getView());
}

conleec

Awesome! Now just a couple more questions, if you'd be so kind...

1) Would it be possible (once again, using the "many_different_widgets" example) to let the background image scale, but leave all the other widgets alone?

2) I'm assuming this is NOT possible, based on the library's architecture, but is there a way to clear the window WHILE resizing, so we don't see the widgets temporarily stretch before snapping back into aspect?

Purely academic, but I'm just trying to get get my head around all of this...

Thanks a million in advance.

Chris

texus

QuoteWould it be possible to let the background image scale, but leave all the other widgets alone?
It is possible. When you don't call gui.setView when resizing then you don't have any control about how it stretches when the window becomes larger. But if you change the view while resizing, you have full control over the size of widgets. What you want is to give the background picture the same size as the window no matter what size the window is. So instead of specifying a size in pixels, you should just set a relative size.
Code (cpp) Select
auto pic = tgui::Picture::create("../RedBackground.jpg");
pic->setSize("100%", "100%");
gui.add(pic);


Quoteis there a way to clear the window WHILE resizing, so we don't see the widgets temporarily stretch before snapping back into aspect?
This would be difficult (doable, but tricky). You should first understand why it stretches while resizing and only corrects itself when you stop resizing. On windows (and NOT on linux, probably also not on mac), there will always be a resize event in the event queue while resizing. This means that the window.pollEvent function will never return false during a resize. With typical code that first handles all events and then does the drawing, the window is never drawn during the resize and windows just stretches the last drawn frame. How the window looks between the moment you resize it and the moment you redraw it also depends on the OS, on windows it just seems to stretch the image.
If you run the same code on linux, it wouldn't stretch during a resize as the draw code is regularly executed while resizing and the view is thus correctly updated the whole time. So not only would fixing it on windows require some hacky method that involves rendering the screen while there are still unprocessed events, you would also have to take care not to break the code on other platforms (if you would care about running it on a non-windows machine).
Of course if you only want to clear the screen and not actually draw contents during the resize AND it only needs to run on windows, you could get away with a much more simple hack. Every time you pass through the draw code, set a boolean to true. When you receive a resize event and the boolean is true, set it to false and call both window.clear() and window.display(). That should ensure that the window is empty during the resize.

conleec

Thank you so much for your help and explanations. Very excited about learning this stuff. Just wish I had more time, what with work, but a little bit at a time I guess.

Another question, loosely related to widget autoscaling:

On my Mac Pro tower, I have a 1920 x 1080 display and on my Macbook Pro I have a retina display with a 2880 x 1800 display.

Consequently windows displayed on the Macbook Pro are VERY SMALL.

Is there an automatic method to adjust for high density displays? Or do we need to watch for that and do the math ourselves somehow?

Chris

texus

This is unrelated to TGUI, this is something that SFML deals with. I've seen such questions pop up a few time on the SFML forum, so I'm sure you will find some information there. I have no experience with retina displays and only very limited experience with mac, so I can't help with this.