LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

"Latch" boolean mechanical action in an XControl

So, the very first thought that came to mind when I first heard of XControls was the ability to create a latching boolean button that highlights itself when the mouse is over it.  However, this has turned out to be more difficult than I thought it should be.  The Facade VI only runs if it needs to (i.e. only if one of the events in the event structure actually fires).  This is inherently incompatible with the "latch" action, since the Facade VI must run twice any time the button is clicked (once to register the click, and once to reset the button), but there is no "event" to generate the reset.

I've attached the bare bones XControl (with a demo VI) to show what I'm talking about.  As it is, once the user clicks the button once, the output stays true forever.

I've tried various things to get it to reset.  The best one was to set the "Data Changed?" value true in the "Timeout" event.  This seemed to work at first, but in fact it depends on one of the other events firing in order to actually get a "Timeout" event (i.e. if I clicked the button but didn't move the mouse, the XControl output stayed true until I moved the mouse off the button, which fired the "Mouse Leave" event).  I could add a "Mouse Move" event, so that all the user had to do was move the mouse after clicking the button, but this still isn't 100% reliable.

I also tried turning off the "latch" mechanical action, and writing False to the "Value (Signaling)" property of the button, inside the Facade VI to the right of the while loop (after the "Timeout" event has been processed), but it appears that this just causes the Facade VI to re-fire immediately, and a True only rarely makes it out of the XControl (i.e. "Data Out" goes True then False before the terminal on the block diagram of the normal VI is actually read).

Any suggestions?

Thanks,

Jaegen

0 Kudos
Message 1 of 9
(3,300 Views)
Jaegen,

I've attached a modified version of your example which appears to latch.  Take a look at it and see if I understood your application correctly.

What I did was to switch the Mechanical Action of the button to "Latch until Released" and modify the Facade VI to always output the current value of the button on Data Out (instead of using the shift register).

Regards,

Simon H
Applications Engineer
National Instruments
0 Kudos
Message 2 of 9
(3,267 Views)
Simon,
 
It appears that you didn't attach the correct version, since the attachment doesn't seem to correspond to your description of what you did.
 
However, I understand what you mean, and I modified it to test this out.  Once I had it setup correctly, this did sort of behave the way I want, but there still are some flaws:
 
I would like the XControl button to behave exactly like a normal boolean button with mechanical action set to "Latch When Released".  In your solution, if the user holds the mouse button down, the value out of the terminal will stay True for more than one loop iteration.  I want the value to only ever be True for one iteration at a time.  I would also like the value to be True only after the user releases the mouse button, which this solution doesn't accomplish.  I don't see any way of achieving this without some way of forcing the facade VI to always run on the loop iteration after outputting a True.
 
I've attached a version which behaves exactly as I would like, but I had to write False to a local variable of the XControl whenever it reads true - I don't want to have to do this.
 
Any further suggestions?
 
Jaegen
0 Kudos
Message 3 of 9
(3,254 Views)
I don't believe this will be directly possible. The issue here is that XControls have no notification of when their terminal on the block diagram gets read. Therefore, there's no way of knowing when to latch. There are various odd workarounds you could consider:

Have the Stop button XControl output an Event Registration Refnum for a registered user event instead of a simple boolean value. The client VI that uses the XControl wouldn't wire the value directly into the terminal condition of the while loop or anything like that, but would register for an event that the latching XControl could fire. Here you are gauranteed latching action and one-and-only-one "event".

Another option (also fairly undesirable but a little easier to accomplish) would be to create a custom property or method and only read the value of the stop button XControl through that instead of using the terminal. You could mirror the Data information in the Display State information, so you always have an up-to-date representation available to read in the property node or invoke node. Furthermore (and here's the catch), the Display State Change event case always fires after executing a custom method or property node, so you'll be able to determine that you should latch at that time in the XControl.

Neither of these are good ideas, because the end-user would have to divine how to use this control properly. If anyone has a better idea, I'm all ears!
Jarrod S.
National Instruments
Message 4 of 9
(3,249 Views)

Thanks for the ideas.  I'd figured that the best work around was going to be to add a custom property which I write to after reading a True, but the idea to only ever read a property is interesting.  You're right though, it's rather unintuitive.

Here's a related question:  For a cluster of ~50 highlighting buttons, what is the difference in efficiency between handling the "Mouse Enter" and "Mouse Leave" events manually on the VI's block diagram versus having 50 XControls which highlight themselves (with the necessary custom property workaround to reset them)?  I'm currently registering for the two events for the entire array of control refnums out of the Cluster's "Controls[]" property, so I only have 2 event cases, not 100 - is this going to be a lot more efficient than having 50 Facade VIs in memory waiting to fire?

Thanks,

Jaegen

 

0 Kudos
Message 5 of 9
(3,211 Views)
You're correct that it will be much more efficient to have two event cases controlling 50 buttons, instead of 50 different XControls. XControls behave essentially like reentrant VIs, so separate copies of them are made for each instance. I'm not sure this cause too much of a difference besides an increased memory footprint, but that can bad enough for some applications.

A fairly easy approach you might take is to simply embed all the button-related events in a subVI that can run in the background. You could, for instance, put all 50 latching booleans in a cluster and the pass the cluster reference to the subVI. The subVI can then extract the control references and register the mouse enter/leave events and execute the correct code in those cases.

Here's an example of what I mean. It still requires some knowledge on the part of the client programmer, but it effectively modularizes this into one component that can be dropped onto the block diagram with ease. You can even add this code (the cluster control, its reference, and the subVI) to the functions palette so the user could drop it all at once. See here for more details. Let me know what you think.
Jarrod S.
National Instruments
Download All
0 Kudos
Message 6 of 9
(3,205 Views)

With regard to the XControl Latch issue, I'm surprised to see that this doesn't have a satisfactory workaround after so long. Surely this is an issue for a lot of users of XControls - should it be a product suggestion? Boolean latch operations are pretty useful!

 

Thanks for the efforts of the AEs on the thread. I tried Jarrod's second workaround, but reading a property did not trigger the {Display State Changed} event and I don't seem to be able to configure inputs and outputs to a method on LabVIEW 2011 (all controls are greyed out!).

 

For my application I'm going to ditch the XControl and use code in my top-level VI to achieve what I wanted. I'd be interested to hear if this is a common complaint, or if Jaegen and I are the only people ever to have wanted this...

0 Kudos
Message 7 of 9
(2,057 Views)

It doesn't seem that the idea has been submitted to our Idea Exchange (http://forums.ni.com/t5/LabVIEW-Idea-Exchange/idb-p/labviewideas). This original thread was going on in 2006, before the Idea Exchange existed. If you think it's something worth pursuing, you can submit it there and see if it gains traction. From my experience, I haven't firsthand heard of people discussing this issue, but I can see how it would be useful. In assembling the VIs, I'm pretty much where Jaegan is and can't get much further. It might not be a bad idea to submit it to the Exchange.

Ravi A.
National Instruments | Applications Engineer
0 Kudos
Message 8 of 9
(2,039 Views)

System booleans already have the behavior you are trying to code.  They change with mouse-over; and you can customize the appearance of the various states.

"If you weren't supposed to push it, it wouldn't be a button."
0 Kudos
Message 9 of 9
(1,438 Views)