Create GUI figures which scale position and size based on resolution

Hello, I have a program which first has one GUI which has a button which is pushed to call three other GUIs. I want these four GUIs to have a set layout, in that the initial GUI occupies ~1/4 of the screen on the left side, two GUIs stacked upon each other in the middle of the screen, then the final GUI on the right side. I have changed the positions for each and made it so that this layout is present using my laptop at its native screen resolution. The issue, however, is that I plan to give the program to others, and when I change the screen resolution of my laptop to one with a different aspect ratio of a smaller size, the distance between GUIs and their size remains the same. This pushes the last, right-most GUI partially off the screen. I have set all units, including font units and position units, to 'normalized' for all four GUI windows. Is there something else I have to do to have the window size scale automatically?
Thanks, Ak

8 Comments

Use
get( groot, 'Screensize' )
to dynamically get the screensize and use this in positioning calculations rather than hardcoding for a screensize. Depending on what you are doing it can still be messy, as always with having UIs look nice on different resolution screens, but if you get the maths right it will at least guarantee to be on-screen.
How would I apply this? Just call get(groot,'Screensize') within the GUI somewhere?
OCDER, it doesn't really have to do with resizing one large GUI, since, in reality, it is multiple smaller GUIs. Also, I had already set each small GUI to non-resizable. I did go through and try to see if setting the resize to proportional would translate to the GUIs as a whole resizing better, but that doesn't work unfortunately.
How are you currently setting the positions of each GUI window? You can use the line of code OCDER suggested to get the screen size, and use that to determine where each window should go.
However, this will ignore the position and size of your taskbar and other floating edge objects (like sidebars). A more robust method of getting the entire available size of the screen would be to maximize a window, and then getting its size.
Is there a demo code we can look at to see how you're resizing the GUIs? I think this just involves some clever size calculations. Start with what Adam suggested for using the screen resolution first, and then divide out the position and sizes of the GUIs. But then, I'm not sure how it works with dual-monitor setups.
My second monitor is just considered as an extension of the first in terms of size - e.g. screen resolution returns 1920 as my lateral screen size. If I position a figure at 2100 it puts it on the second monitor.
You can use
get( groot, 'MonitorPositions' )
if you want to make full use of the real estate available on a given machine, although this would involve having to do different things depending how many monitors there are. The above command gives me a 2x4 output for my monitors so taking the size of the first dimension of this result will tell you how many monitors there are, though there may be a single call function that also gives you this that I am not aware of.
As an aside, if you want to nosey into what is available (which I always do!)
get( groot )
will give a list of all the values you can query from groot.
Currently, I have the positions (for each GUI) set within the GUI Property Inspector based on the (0,0) to (1,1) scale. I understand that if I get the dimensions of the display, I could hypothetically set the position based on that, for example putting one window at 1/3 of the display from the left and 1/3 of the display off the bottom. I do not, however, know how to alter the position of a GUI without doing so within the property inspector.

Sign in to comment.

 Accepted Answer

Fig1H = figure('Units', 'normalized', 'Position', [0, 0, 0.25, 1], 'Name', 'Figure 1');
Fig2H = figure('Units', 'normalized', 'Position', [0.25, 0.5, 0.5, 0.5], 'Name', 'Figure 2');
Fig3H = figure('Units', 'normalized', 'Position', [0.25, 0, 0.5, 0.5], 'Name', 'Figure 3');
Fig4H = figure('Units', 'normalized', 'Position', [0.75, 0, 0.25, 1], 'Name', 'Figure 4');
This creates two figures with 1/4 of the width and the full height on the left and right, and two figures on top of each other at the center. Does this help already?

11 Comments

This solution uses the entire screen, ignoring sidebars and the taskbar. That may or may not be a desired result.
Although this does work, how would I apply this to preexisting GUIs as opposed to figures? I understand that a GUI opens as a figure, but I am not calling to plot a figure but instead calling a GUI function.
Rik, in my final product, I will have space between the edges of the screen and the outermost edges of the GUIs. This should prevent what you are suggesting, but if I find this is not the case I will utilize the maximize function you suggested to find the amount of available space, then compare it to total (including taskbar) space, deriving the new coordinates of the bottom/side edges of the usable window.
A GUI is just a figure with some custom buttons. You should be able to get a handle to that figure (or even use gcf in a callback or your creation function).
I have run this code (and similar versions with different numbers) within the opening function of the 1st and the other three GUIs:
CurrentFigure = gcf;
set(groot,'Units','points');
ScreenSize = get(groot,'ScreenSize');
ScreenWidth = ScreenSize(3);
ScreenHeight = ScreenSize(4);
FigXPos = .02*ScreenWidth;
FigYPos = .2275*ScreenHeight;
FigWidth = .215*ScreenWidth;
FigHeight = .6725*ScreenHeight;
set(CurrentFigure,'Units','points','Position',[FigXPos FigYPos FigWidth FigHeight])
This works perfectly for the first window. I have similar code for all four, but it falls apart once I press the button which calls the other three. The first of the three GUIs plots in the right location, then the second GUI plots in its proper location, but then the first GUI that plotted (of the three) goes and sits in the location of the second GUI. The second and third GUIs then plot slightly offset from each other where the third GUI is supposed to be plotted. It is a strange phenomenom and I don't understand why it might be happening. Could it have to do with how I call Current Figure = gcf; or with the way I set the units/position?
Once I changed CurrentFigure = gcf; to CurrentFigure = handles.figure1, it works perfectly.
Never use gcf (or gca) in proper code, especially when working with multiple windows. You should always have an explicit handle to your figures (and your axes)
@Adam Ok, will do. This is good to know! Thanks.
@Rik: "This solution uses the entire screen, ignoring sidebars and the taskbar." On my Windows 10 Matlab considers the taskbar for 'Position' set to [0,0,1,1].
@Ak K: "how would I apply this to preexisting GUIs as opposed to figures?" A GUI is a figure. If you have an existing set of figures, whose handles are stored in the array FigH:
set(FigH(1), 'Units', 'normalized', 'Position', [0, 0, 0.25, 1]);
set(FigH(2), 'Units', 'normalized', 'Position', [0.25, 0.5, 0.5, 0.5]);
set(FigH(3), 'Units', 'normalized', 'Position', [0.25, 0, 0.5, 0.5]);
set(FigH(4), 'Units', 'normalized', 'Position', [0.75, 0, 0.25, 1]);
It might be useful to implement this as menu of the figures, or as button. Then the user can maximize a figure and reset the original status easily.
@Jan, not entirely: try it with you taskbar on the side instead of top or bottom. I also have my IM program docked on the other side, so maximizing is the only way to find out how much screen real estate you have to work with. In my case the position is [0.0431 0 0.8243 0.9144] for a maximized window.
Matlab 2018a now has the WindowState property of a figure to allow users to maximize a figure according to the OS behavior.
set(FigH(1), 'WindowState', 'maximized')
ScreenPosWithoutTaskbar = get(FigH(1), 'Position');

Sign in to comment.

More Answers (0)

Categories

Find more on Creating, Deleting, and Querying Graphics Objects in Help Center and File Exchange

Products

Asked:

on 14 Jul 2018

Commented:

on 20 Jul 2018

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!