Panel size vs. image size

Hello,

I have not found how to make a panel the same size as a graph (display). When I use NewPanel/K=1/W=(0,0,500,300) the size is different than when I use Display/K=1/W=(0,0,500,300). How to make two windows of the same size ?

Thanks

Hi,

I just tried this on IP9 on Mac OS X and it seems to work as expected.  What version and OS are you running?

 

Andy

Hi,

Check in miscellaneous settings under panels it might not be IP8, there is an option to change sizing.

Andy

Just for everybody who may stumble upon this thread, I would like to make clear that this is a problem of working with points (Igors often used unit of measurement) versus screen pixels. This is mainly a problem on Windows, since on Mac these two units happen to be the same. It is a good idea to keep this in mind, especially if code is intended to be cross-platform. It is best to convert all sizes to one common unit using one of the following two:

// 72 is the number of points in an inch which is constant.
Variable pixels = numPoints * (ScreenResolution/72) // Convert points to pixels
Variable points = numPixels * (72/ScreenResolution) // Convert pixels to points

NewPanel uses pixels, so to get the same size as the Display command (which is in points) one would need to write:

Variable pixConv = ScreenResolution/72
NewPanel/K=1/W=(0,0,500*pixConv,300*pixConv)

 

In reply to by chozo

chozo wrote:

NewPanel uses pixels

This is not at all clear from the manual.

Reading

DisplayHelpTopic "Control Panel Units"

followed by

DisplayHelpTopic "Interpretation of NewPanel Coordinates"

it looks like units are in most cases points.

I think this continues to be a problem with the manual, i.e., it is often not clearly stated what is really meant and sometimes even (was?) wrong. I guess this may be partly due to the fact that the Igor team works mainly on Mac where it doesn't matter. You can try for yourself and see that NewPanel clearly uses screen pixels.

I frequently use the following to try to make a panel close to the menu selection that asks for the panel to be built. It doesn't really work, but at least the panel appears on the same screen. Is there a better way?

menu "Macros"
    "Make a Panel"
end

function MakeAPanel()
    GetMouse
    v_left = pixel2panelCoordinate(v_left)
    v_top = pixel2panelCoordinate(v_top)
    NewPanel /K=1/W=(v_left,v_top,V_left+100,v_top+100)
end

function pixel2panelCoordinate(variable pixel)
    variable resolution = ScreenResolution
    return resolution > 96 ? pixel * 72/resolution : pixel
end

Sorry about hijacking the thread.

I quickly tested your example, and indeed the panel is created at the wrong position this way. You need to omit the conversion to have the panel appear at the mouse position on windows.

function MakeAPanel()
    GetMouse
    NewPanel /K=1/W=(v_left,v_top,V_left+100,v_top+100)
end

To get the same window for a graph however, you need the conversion like so:

menu "Macros"
    "Make a Graph"
end

function MakeAGraph()
    Variable pointConv = 72/ScreenResolution
    GetMouse
    v_left *= pointConv // pixels -> points
    v_top  *= pointConv
    Display /K=1/W=(v_left,v_top,V_left+100*pointConv,v_top+100*pointConv)
end

 

In reply to by chozo

Actually, mostly when I use this I use pixels. Nevertheless, the panel position is quite random, I presume because the mouse position is not reliably updated when menus are active. So I'm curious to find other ways to do it. For the most part, it works well enough to be better than hard coding a position.

From the commandline it works as expected, as you say, using pixels.

How do you summon the panel in your real-life application? Your MWE must be invoked via the macros menu or command line, which can be done without using the mouse itself. The panel always appears at the mouse location in my tests and using above code when running the macro (just one monitor on a notebook).

This is designed for menu-driven stuff.

The objective was simply to choose a location that would not be unexpected for the user.

On my mac, the actual panel position is very variable, but it at least appears on the same screen as the mouse, which is better than the alternative.

Maybe it's related to a combination of Qt and OS.

@Tony --- I would have to wonder how your code should know the mouse position other than it being "near" where the Macro menu was invoked depending on the time delay to get to the GetMouse function and how much jitter the user has in holding the mouse in one position. Or simply put, it seems like it has the same precision as someone shooting at ducks with a rubber band gun on a windy day.

Perhaps the intent is to put the panel in the same _relative_ (left, top) position regardless of the size or resolution of the monitor. Having played with this approach in the past, I ended up creating the Screen Sizer package posted here: https://www.wavemetrics.com/project/ScreenSizer. Maybe this can provide you with ideas.

 

I see. Thank you for your explanation. It might be a Mac related thing then. Maybe WM would be willing to look into this? I guess then if you would print v_left and v_top you get somewhat random numbers? When I do this I seem to get always the correct pixel position on my screen even if the mouse happens to be outside the current MDI Igor window (as long as the window is in focus, of course).

If I switch to the File menu, rather than Macros, so that the mouse is positioned a bit lower on the screen when I click the menu item, I get (left,top) coordinates like this using my primary (laptop) screen:

135  633 (near the bottom of the screen, close to the click position)
186  95
35  102 (to the left of the area occupied by the menu)
101  105
137  114

The coordinates are not simply related to the click position. They seem to be vaguely related to the menu position, which is usually good enough.

On my second screen, the coordinates lie quite far from both menu and mouse positions, somewhere in the middle of the screen. Also not too bad, I'm happy if the panel is at least drawn on the same screen.

I'd like to point out that in an attempt to make everything work similarly on Mac and Windows, and to try to transition toward using points for control panels instead of pixels, there is a weird thing on Windows where if your monitor reports 96 DPI, we use pixels; any larger resolution (120 DPI is common) causes panels to use points. So the literal "72" is only appropriate for 96 DPI.

In addition, in Igor 9 there is now the possibility that your panels use panel expansion factors (which might be panel contraction as well). So you really need to use the PanelResolution(panelname) function instead of 72.

Uhoh! As John just stated, I was blinded by my particular settings on windows (sane font sizes). Indeed, you need to convert to points for NewPanel, but NOT if you are on windows and have a font size setting other than "small". Sorry for the confusion. So the full solution to the puzzle is:

menu "Macros"
    "Make a Panel"
end

function MakeAPanel()
    Variable pntConv = (CmpStr(IgorInfo(2), "Windows") == 0 && ScreenResolution == 96)? 1 : 72/ScreenResolution
    GetMouse
    v_left *= pntConv // pixels -> points
    v_top  *= pntConv
    NewPanel /K=1/W=(v_left,v_top,V_left+100*pntConv,v_top+100*pntConv)
end