Jump to content

Auto Sizing FP Controls and Indicators


Bryan

Recommended Posts

I've been looking at the front panel for the OpenG commander for a little while this morning trying to figure out how Jim got certain controls to move, scale and even stay put when adjusting the size of the window.

I checked to see if the "Scale objects with window size" box was checked in the VI properties, but it wasn't.

How did you dood it Jim?

Link to comment
I've been looking at the front panel for the OpenG commander for a little while this morning trying to figure out how Jim got certain controls to move, scale and even stay put when adjusting the size of the window. 

I checked to see if the "Scale objects with window size" box was checked in the VI properties, but it wasn't. 

How did you dood it Jim?

5899[/snapback]

Bryan,

Actually Michael (Aivaliotis) came up with this idea. If you select the table and go to edit (menu), you will noticed that the "scale object with panel is checked". This is basically how it works.

Note: NI is doing something similar in the VI Metrics llb (LVRoot\project\prometrics.llb\VI Metrics.vi)

PJM

Link to comment

I never noticed that option before. I always thought that you had to apply it to all items on the panel, except those that are locked.

I noticed that some objects move with the window size, but don't scale with it. Is this done with a tricky combination of locks and scaling?

Link to comment
I never noticed that option before. I always thought that you had to apply it to all items on the panel, except those that are locked.

I noticed that some objects move with the window size, but don't scale with it. Is this done with a tricky combination of locks and scaling?

5904[/snapback]

Damn! my secret has been revealed. PJM, you know better than to reveal a magicians secrets. If you're told how the lady is cut in half, it's not so exciting.

Yes, well, a few years ago and with lot's of experimentation time on my hands, I discovered the secret to cool panel behaviors. The Window Size settings in the VI properties that allow you to scale all objects as the window resizes is CRAP. Don't ever use that, you will only end up with distorted overlapping front panel controls everytime you resize your panel.

The key to the fancy autosizing panel stuff is using the Scale Object with Panel option from the Edit menu. Actually this setting has been there since LV5.1 but few people ever use it. Perhaps because nobody ever explained its usage.

post-2-1125448653.gif?width=400

You can only use this setting for one object at a time. However this is enough for most situations. The key is to focus attention on one central object that is important to you. In the case of Commander, It's the multicolumn listbox. In your case it may be a text box or even more exciting: a picture control.

You will notice that once it's enabled, the object will always size towards the bottom and to the right. This means you need to anchor your panel to the topleft origin. This can be easily done with a property node upon startup. This isn't critical but will make editing easier. Also, make sure to limit the minimum size of your panel. This will give you a stable size from where your panel can grow. When you edit the panel you should save it to this minimum size so all future edits start from this reference.

post-2-1125449343.gif?width=400

Once this basic setting is defined and you central resizable object is set, you can then go crazy with the surrounding buttons and other objects. The trick to using that is knowing how the scalable oobject affects its surroundings. The objects stretch and move along with the resizable object. Here's a video that shows how 3 buttons re-position themselves as the panel resizes, very annoying eh?

You need to group all the buttons together but that is not enough. You must anchor them to the left or to the right of the resizable object by grouping them with a dummy object. This can be done with a decoration as shown in the video below (zipped for size):

As you can see, this can now be a powerfull tool once you understand the behavior of the resizable object and how the surrounding objects relate to it. If you want to elaborate on the above technique you can group some objects to the left and some to the right depending on how you want things to move related to your central object. Another good idea is to lock your central resizable object to your panel because this will prevent it from sliding around.

Link to comment
Damn! my secret has been revealed. PJM, you know better than to reveal a magicians secrets. If you're told how the lady is cut in half, it's not so exciting.

5914[/snapback]

Michael,

Did you noticed I only told Bryan about the "Scale objects with window size", but nothing about the objects anchoring or the widow size (which are really the tricks to make this usefull)? :)

By the way, I spent the better part of a saturday to figure out how you did it.

PJM

Link to comment
But how is the lady cut in half?

5918[/snapback]

Well, since you asked...

When the person is placed in the box, her head sticks out one end and her feet stick out the other. The magician then spins the box, and when the feet are pointed away from the audience the assistant retracts her real feet and replaces them with a pair of fake feet. The lady is a contortionist, so she folds her legs into the upper part of the box and the magician "saws her in half." Because we saw the lady stick her feet through the holes, we assume they must be her feet the entire time, and the illusion is completely baffling!

Link to comment

I have a couple of questions. Perhaps I misunderstood some of your instructions:

You said to lock your central, resizable object. If I do this, the object will then not resize with the window. Did I miss something?

Also, you said to anchor your panel to the origin (i.e. FP.Origin = 0,0). I've done this, but it seems that my resizable object "walks" down in vertical height each time the window is resized vertically.

I should also mention that I have 2 objects I would like to be resizable. I grouped the 2 together before setting it as resizable. Would this be the cause for the behavior I'm seeing?

Finally, is there a way to force objects to resize vertically, but not horizontally (and vice versa) with the panel. Sort of like locking it's "resizability" in one axis.

I'm probably looking at doing some things that LabVIEW doesn't yet have the ability to do.

Link to comment
I should also mention that I have 2 objects I would like to be resizable.  I grouped the 2 together before setting it as resizable.  Would this be the cause for the behavior I'm seeing?

This can't be done. The resize object only works for a single object. Grouping them doesn't work... sorry.

Finally, is there a way to force objects to resize vertically, but not horizontally (and vice versa) with the panel.  Sort of like locking it's "resizability" in one axis. 

I'm probably looking at doing some things that LabVIEW doesn't yet have the ability to do.

5945[/snapback]

Well, the instructions mentioned give you some capabilities with zero programming. Of course if you tap into the panel resize event and want to do some programming then you can do whatever you want. Anything is possible in LabVIEW once you use this event.

Link to comment
This can't be done. The resize object only works for a single object. Grouping them doesn't work... sorry.

Well, the instructions mentioned give you some capabilities with zero programming. Of course if you tap into the panel resize event and want to do some programming then you can do whatever you want. Anything is possible in LabVIEW once you use this event.

5992[/snapback]

The panel resize event is tricky tu use. Tens or hundreds of events are fired while the user resizes the panel. If you make something that forces the panel to redraw, it is funny to see the panel keeping redrawing well after the user has left the mouse until all events are serviced. You have to catch when the mouse button up but since the handle to resize the panel is "outside" the panel, it does not fire a mouse button event in the event structure. You have to use the mouse device functions to detect the mouse button up.

Indeed, this feature is a blessing...

Link to comment
The panel resize event is tricky tu use. Tens or hundreds of events are fired while the user resizes the panel. If you make something that forces the panel to redraw, it is funny to see the panel keeping redrawing well after the user has left the mouse until all events are serviced. You have to catch when the mouse button up but since the handle to resize the panel is "outside" the panel, it does not fire a mouse button event in the event structure. You have to use the mouse device functions to detect the mouse button up.

Indeed, this feature is a blessing...

6032[/snapback]

Yes, your solution is good. Here is another one which is easier to implement and actually works quite nice. BTW, this is also used somewhere in Commander I think:

http://forums.lavausergroup.org/index.php?showtopic=67

Link to comment
  • 1 year later...
I'm not finding the scale object option in the Edit menu in LV8x. Am I missing something -- literally?

My guess is that the scaling property now belongs to the pane and not the panel, so the relevant option might have been moved or even removed from the editor's UI, but I don't have LV 8. You might wish to search the LV help.

While on this topic, I was working recently with a guy using VS.Net and he showed me some of the resizing option MS provides with that IDE and I got to thinking - what would it take to make a generic "resizer" in LV?

I haven't had time to think about it seriously, but here are some of my thoughts so far -

  • Each panel object has some tags describing its properties (resizable height\width, anchored to top-left\top-right of the container, etc). As far as I could tell, tags can be attached to any panel object.
  • To do the actual resizing we would need either a seperate process or to use the Panel Resize event and call the resizing VI in it.
  • Since each control's size needs to be controlled by a property node, we basically need a class for each control class in the VI Server hierarchy. We might need some special handling for things like graphs.
  • How do we enumerate the controls to get their properties at run-time? If you do it recursively throughout the panel, this is usually a rather lengthy process, which makes it impractical, even if you only do it when you start running the caller. Keeping the control refnums from the edit time is probably useless, since those numbers probably change each time, but I haven't checked it.
  • Would everything work smoothly (tags in executables, newer versions of LV)?
  • Is it even worth it? So far, I didn't get to do too many programs in which resizing the window was a necessary option. Obviously, in some areas this is required more, but maybe the technique outlined here is enough?

Anyway, as I said, these are only initial thoughts since I haven't had a chance to properly examine the topic, but since this thread was bumped, I thought I'd mention it and see if anyone had any relevant thoughts.

Link to comment
My guess is that the scaling property now belongs to the pane and not the panel, so the relevant option might have been moved or even removed from the editor's UI, but I don't have LV 8. You might wish to search the LV help

Thanks for the tip but, when I tried to get/set "Pane" for an ActiveX container via a reference node for it I get an error code of 1057 from the "To more specific..." operator.

Link to comment
How about right click on the control and then "Scale..." or "Fit..."?

Nope, that has no effect regardless of how it's set. But what does help is to use a property node to set the container bounds of the ActiveX containter to a set value AFTER making any control call to WMP (eg Play, Pause).

It's very strange to me but that's just because I don't understand it, I'm sure.

Any other ideas? I'm sure there's something I'm just "leaving out".

Link to comment
The panel resize event is tricky tu use. Tens or hundreds of events are fired while the user resizes the panel. If you make something that forces the panel to redraw, it is funny to see the panel keeping redrawing well after the user has left the mouse until all events are serviced. You have to catch when the mouse button up but since the handle to resize the panel is "outside" the panel, it does not fire a mouse button event in the event structure. You have to use the mouse device functions to detect the mouse button up.

You could also do something like this:

  1. On your event loop, create a boolean shift register whose value is a boolean. Initially the value is FALSE.
  2. Set the timeout of the event structure to 150 milliseconds.
  3. In the panel resize event case, turn off panel drawing. Then set the boolean to TRUE.
  4. In the timeout event case, test the boolean. If the boolean is TRUE then update the control sizes and then enable panel drawing again. If the boolean is FALSE, then do nothing.

The result is that as long as panel size events come quickly then the timeout event will never fire. When the panel resize events quit coming then you can update. At 150 ms, you'll still get nice smooth drags if the user pauses. This does turn the event structure into one that polls every 150 ms, but since it does nothing except test a boolean, it shouldn't be a burden to your CPU.

I suspect that you could get rid of the polling behavior by being clever about posting a user event with a timestamp but I'd have to play with it to get it right. Something about a shift register with a timestamp that the resize event updates, then posts a update UI event. As long as the current value of the shift register is before the value of the timestamp when the user event fires then the user event updates the panel sizes, otherwise it does nothing. Or something like that.

Link to comment
I suspect that you could get rid of the polling behavior by being clever about posting a user event with a timestamp but I'd have to play with it to get it right. Something about a shift register with a timestamp that the resize event updates, then posts a update UI event. As long as the current value of the shift register is before the value of the timestamp when the user event fires then the user event updates the panel sizes, otherwise it does nothing. Or something like that.

A more elegant approach is to pass the timeout value in an SR. In the Window Resize event, put 150 into the SR and in the timeout case change it to -1. That way, you simply return the value to -1 after you update the display. All the other events can simply pass the value of the SR.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.