Activating and Controlling Subwindows

I am likely still a bit confused about how to activate and control actions directed at subwindows. In particular, I have a panel attached as an external subwindow to a graph. Here is the typical sequence I use to activate and change controls on the panel. In what follows, cw is the current window name and pn is the panel (subwindow) name.

SetActiveSubwindow $(cw + "#" + pn)
Button doButton, disable = 2
... // list of other panel controls to change
SetActiveSubwindow ##


I see that SetActiveSubwindow is supposed to be primarily for recreation macros. So, is the proper replacement for this as follows:

Button doButton win=$(cw + "#" + pn), disable = 2
... // list of other panel controls to change


I wonder in particular why the former is "unsupported" as it were. It makes coding less cumbersome than having to apply the win=... syntax to every control within a sub-window panel that should be activated.

My second question deals with moving the subwindow. Again, MoveSubWindow is noted to be primarily for recreation macros. The manual says ... "users should use layout mode for repositioning subwindows" and darn if I can find what that really means. What then is the proper replacement for the MoveSubWindow commands this segment of code:

switch( ba.eventCode )
    case 2: // mouse up
        strswitch(ba.userData)
            case "closed":
                Button XtendD win=$(cw + "#" + pn), title="v", userData="opened"
                MoveSubWindow/W=$(cw + "#" + pn) fnum=(0,0,nwidth,ndepth)
                break
            case "opened":
                Button XtendD win=$(cw + "#" + pn), title=">", userData="closed"
                MoveSubWindow/W=$(cw + "#" + pn) fnum=(0,0,cwidth,cdepth)
                break
        endswitch
        break
endswitch
jjweimer wrote:

I wonder in particular why the former is "unsupported" as it were. It makes coding less cumbersome than having to apply the win=... syntax to every control within a sub-window panel that should be activated.


I've have pretty much gotten used to using the /W flags and win keywords for pretty much every control, especially if they're in subwindows. I think it's more robust, but I see your point.

jjweimer wrote:

My second question deals with moving the subwindow.

I haven't used exterior subwindows. But how would moving an exterior subwindow work? It seems weird, but then again, haven't used them.

jjweimer wrote:

The manual says ... "users should use layout mode for repositioning subwindows" and darn if I can find what that really means.


I'm not sure either. But, I tend to frame all of my subwindows using window guides, which works pretty well. Then, when I want to move the subwindow I just redefine the relevant guides, and Igor moves the window automatically. I like this because it feels more robust than directly messing with pixels or points, and you can get features like automatic subwindow resizing 'for free'.

The guides are explained in
DisplayHelpTopic "Positioning and Guides"

Note that in the current version of Igor, you have to be careful with doing this, since Igor can generate invalid recreation macros if you start getting careless (which is really more of a bug in the present Igor). For instance, don't do this:
DefineGuide hello={FT, 20}
DefineGuide goodbye={FT, 10}
DefineGuide hello={goodbye, 10}

Because Igor will generate an invalid recreation macro and your saved experiments won't open properly.
741 wrote:
I've have pretty much gotten used to using the /W flags and win keywords for pretty much every control, especially if they're in subwindows. I think it's more robust ...


Yes, I can see that too and have started converting over my code accordingly.

741 wrote:

I haven't used exterior subwindows. But how would moving an exterior subwindow work? It seems weird, but then again, haven't used them.


For the example I gave, "moving" the exterior subwindow expands or contracts it (ie, resizes it) against the bottom of the main graph window. I do this as a way to have certain portions of the panel "disappear" when they are not needed or wanted.

jjweimer wrote:

The manual says ... "users should use layout mode for repositioning subwindows" and darn if I can find what that really means.


741 wrote:

... I tend to frame all of my subwindows using window guides, which works pretty well .... and you can get features like automatic subwindow resizing 'for free'.


I will certainly take a closer look at this. Thanks!

(edit)

It seems, window guides may be most useful (if not exclusively used) for interior subwindows. As it turns out, later in the manual, the statement is made ... "Exterior subwindows are nonresizable by default. Use ModifyPanel fixedSize=0 to allow manual resizing. If you resize a panel, the original window dimensions are lost. You can also use MoveSubwindow to resize the subwindow."

That is exactly how I am using the MoveSubwindow command in this case. So, it seems, I am OK.

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville
jjweimer wrote:
SetActiveSubwindow $(cw + "#" + pn)
Button doButton, disable = 2
... // list of other panel controls to change
SetActiveSubwindow ##


I see that SetActiveSubwindow is supposed to be primarily for recreation macros. So, is the proper replacement for this as follows:

Button doButton win=$(cw + "#" + pn), disable = 2
... // list of other panel controls to change


I wonder in particular why the former is "unsupported" as it were. It makes coding less cumbersome than having to apply the win=... syntax to every control within a sub-window panel that should be activated.

Probably the answer is partly just style, but using the method you show first has the remote possibility that something may intervene somewhere in the lines between calls to SetActiveSubwindow that changes the active subwindow. That is particularly likely if there are a lot of lines and you go back later and add something. The use of the win= keyword and /W flags can't be subverted that way.
Quote:
My second question deals with moving the subwindow. Again, MoveSubWindow is noted to be primarily for recreation macros. The manual says ... "users should use layout mode for repositioning subwindows" and darn if I can find what that really means. What then is the proper replacement for the MoveSubWindow commands this segment of code:

There is nothing wrong with using MoveSubwindow. Sometimes we say things like that to discourage less-knowledgeable programmers from using problematic operations and functions. Some things are just bound to be baffling until you've had some experience with some of the gotchas. But I personally have found that guides provide simple solutions to things that you would often use MoveSubWindow for, and that require a lot of opaque coding to accomplish. In particular, adding area to a subwindow control panel when you open up a disclosure in the parent window can be handled quite nicely with a guide attached to the side of the parent window.

Heh- your response to 741 snuck in while I was composing this...

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
johnweeks wrote:
...Heh- your response to 741 snuck in while I was composing this...


Yes, and I found the MoveSubwindow note that I added in edit while you were responding.

In the meantime, I see the disadvantages of using the SetActiveSubWindow syntax and have been converted to the /W=... syntax. I've killed a bug or two in my coding this way as it turns out.

I would appreciate a specific example on how to do guides for external subwindows, perhaps based on the case at hand. The panel is positioned with the command

NewPanel/W=(0,0,nwidth,ndepth)/N=$pn/K=2/EXT=2/HOST=# as "Scroll Traces"


where nwidth = 255 and ndepth = 120. It is expanded or collapsed with the commands below

strswitch(ba.userData)
    case "closed":
        Button XtendD win=$(cw + "#" + pn), title="v", userData="opened"
        MoveSubWindow/W=$(cw + "#" + pn) fnum=(0,0,nwidth,ndepth)
        break
    case "opened":
        Button XtendD win=$(cw + "#" + pn), title=">", userData="closed"
        MoveSubWindow/W=$(cw + "#" + pn) fnum=(0,0,cwidth,cdepth)
        break
endswitch


where cwidth = 255 and cdepth = 20. How would the equivalent be done with guides?

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville
jjweimer wrote:
How would the equivalent be done with guides?


Guides serve to anchor stuff to the window frame, either in absolute distances or proportionally. Redefining a guide shifts the anchor to a different position with respect to the frame, but does not resize the window in any way.

So for your application this might actually be somewhat more annoying since you'd need to do two things: resize the window and redefine the guides. Initially the guides would be defined in such a way that the object is outside the window (and this is guaranteed to be so even if the user resizes the window), and then when you want the widget to show you resize the window and redefine them to shift it into view.

For instance:
// invisible
DefineGuide left={FR, 10}
// visible
DefineGuide left={FL, 10}


I'm using this strategy in two ways: one is to do something similar as you, where I 'reveal' part of the window in response to a user click, using a combination of DefineGuide and MoveWindow, and the second strategy is in a tabcontrol, where clicking a different tab causes a different panel to 'fly in' simply because I redefine the guides it's attached to.

But I suspect all of this is kind of moot since you're using an exterior subwindow.
jjweimer wrote:
I would appreciate a specific example on how to do guides for external subwindows,

The Multipeak Fit 2 package uses guides in an external subwindow. Look at Example Experiments->Curve Fitting->Multipeak Fit 2 Demo. The Options disclosure at the bottom of the panel expands a subwindow by simply having the bottom of the subwindow attached to the bottom guide.

The code in question is in the function MPF2_DiscloseOptions(). You will see that I call MoveSubWindow to change the size of the main external panel. For some reason (probably afternoon coding :) I move the top guide for that P3 subwindow in order to change the size of P3. I think if I were to do it right now, I would have the UGH3 guide be relative to the top of the main panel so it would stay fixed. Then the call to MoveSubWindow would be all that's required (I think).

In the Global Fit package control panel, the controls in the bottom part of the window are all contained in a subwindow that's stuck to the left, right, and bottom edges of the main control panel. So when you resize the control panel, those statically positioned controls just go along for the ride with no code required.

I also use guides to position a subpanel inside a tab control. Then resizing the window is relatively easy- you have to handle the resize to change the size of the tab control; the content subpanels inside the tab controls follow the guides. Of course, controls within the contents of the tabs still have to be repositioned with code. (I've been lobbying Larry to make it possible to stick controls to the window guides. Probably won't happen for a long time.)

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
johnweeks wrote:
... The code in question is in the function MPF2_DiscloseOptions(). ...


Thanks. It seems, the MoveSubWindow command is the simplest way to handle resizing an external panel even without resorting to the use of guides.

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville
jjweimer wrote:
Thanks. It seems, the MoveSubWindow command is the simplest way to handle resizing an external panel even without resorting to the use of guides.

I meant to say something about that. Since external panels are in a separate window (it's a separate window that is made by our internal code to "stick" to another window) you can't use guides to position an external panel. You *have* to use MoveSubWindow().

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com