Jump to content

Ignore multiple increment/decrement events


EricLarsen

Recommended Posts

This question has probably been discussed ad-infinitum elsewhere, but I can't find a good answer.

I'd like to ignore multiple value change events on a numeric control and only generate an action based on the latest value of the control. This article discusses how to ignore events that involves a single "mouse up", such as continuously holding down the Increment or decrement button. However, I (and most of my users) typically change a control with multiple clicks on the increment/decrement buttons. It would be nice to come up with a simple drop in solution that would only generate an event after the user has stopped clicking. And since I may have dozens of controls on the User Interface, the simpler, the better.

I've hit a brick wall for a solution. Any ideas?

Link to comment

To be clear, you want to be able to ignore multiple increments/decrements until the user stops clicking, but keep count of all those increments/decrements so that the appropriate value is put in the control? So if the control starts at 10, the user clicks on increment 30 times, after the user stops clicking increment the control goes from 10 to 40. Yes?

Link to comment

To be clear, you want to be able to ignore multiple increments/decrements until the user stops clicking, but keep count of all those increments/decrements so that the appropriate value is put in the control? So if the control starts at 10, the user clicks on increment 30 times, after the user stops clicking increment the control goes from 10 to 40. Yes?

Let's say the value is 10, and the user clicks the increment button 30 times. I'd like the user to see the control change to 11,12, 13.... so there is visual feedback that the clicks are working. However, only when the user stops clicking at 40, and doesn't click the control again for 1 second or so, then an event is generated that sends the value of 40 to an instrument.

Link to comment

Let's say the value is 10, and the user clicks the increment button 30 times. I'd like the user to see the control change to 11,12, 13.... so there is visual feedback that the clicks are working. However, only when the user stops clicking at 40, and doesn't click the control again for 1 second or so, then an event is generated that sends the value of 40 to an instrument.

That's good, because I wasn't really sure how you were going to get what I thought you were talking about to work...

You said there may be dozens of controls. Do they all have to be updated before an event is generated? Or do you want an event generated after each control is updated?

Link to comment

HI Cat. Hows tricks?

Let's say the value is 10, and the user clicks the increment button 30 times. I'd like the user to see the control change to 11,12, 13.... so there is visual feedback that the clicks are working. However, only when the user stops clicking at 40, and doesn't click the control again for 1 second or so, then an event is generated that sends the value of 40 to an instrument.

If I understand correctly (which is quite rare) could you use the "mouse leave"event case so that your "send to instrument" function only fires when they move outside the control (i.e stopped clicking and gone elsewhere).

The advantage of that is you can attach all your controls to a single event case and use the events control ref to wheedle out the control and value.

Link to comment

HI Cat. Hows tricks?

Peachy, thanks for asking!

If I understand correctly (which is quite rare) could you use the "mouse leave"event case so that your "send to instrument" function only fires when they move outside the control

Shaun's idea is a good start, but you need to be careful about your users just dragging their mouse over controls and firing events unintentionally.

You requested simple, and since it sounds like your users are click-happy, "simple" involves a "Go" button. The user gets finishes clicking on a control and hits the Go button. Monitor all your controls and keep track of which one was changed last. Send a message with the value of that control. This also has the benefit of not requiring monitoring anything but changes -- the required value can be typed in and not clicked-to. More controls can be easily added by just appending them to the monitor event case.

Too simple??

send msg on control update.vi

Link to comment

You said there may be dozens of controls. Do they all have to be updated before an event is generated? Or do you want an event generated after each control is updated?

Ideally I'd like an event generated after each control is updated.

If I understand correctly (which is quite rare) could you use the "mouse leave"event case so that your "send to instrument" function only fires when they move outside the control (i.e stopped clicking and gone elsewhere).

The advantage of that is you can attach all your controls to a single event case and use the events control ref to wheedle out the control and value.

I'm afraid that probably wouldn't work. A user could change a control, then walk away with the mouse still hovering over the control. Then it wouldn't generate the mouse leave event.

You requested simple, and since it sounds like your users are click-happy, "simple" involves a "Go" button. The user gets finishes clicking on a control and hits the Go button. Monitor all your controls and keep track of which one was changed last. Send a message with the value of that control.

In this case, it would only be a matter of time before a user changes the control, then forgets to push the go button. Then I'm getting a late night phone call wondering why the furnace was set to 210C is only running at 200C.

Link to comment

Ideally I'd like an event generated after each control is updated.

I'm afraid that probably wouldn't work. A user could change a control, then walk away with the mouse still hovering over the control. Then it wouldn't generate the mouse leave event.

In this case, it would only be a matter of time before a user changes the control, then forgets to push the go button. Then I'm getting a late night phone call wondering why the furnace was set to 210C is only running at 200C.

Try this one. I set the filter to 1000ms.

event_multiple click.vi

You'll need to adapt it to multiple controls.

Link to comment

In this case, it would only be a matter of time before a user changes the control, then forgets to push the go button. Then I'm getting a late night phone call wondering why the furnace was set to 210C is only running at 200C.

And your reply is that they shouldn't be using un-trained operators :rolleyes:

But I see what your after.

I think you will just have to filter the changes. Although I had a quick look at the slider example you referenced and I certainly wouldn't have done it that way :ph34r:

One thing you could do is build an array of the controls that are clicked and the latest value for that control and put that in the on change event case (the same on-change would be used for all controls). You would need to look up the control reference on each click and if it doesn't exist, add it. This is fairly trivial. Then, in the time-out case (set it to a few seconds for example) unwind the array using a for loop and read the control(s) that have changed and send the value to the the instrument(s). If nothing has been clicked, then the for loop won't execute when the time out expires. If some controls have been clicked (the timeout will be reset every click automagicaly) , then they will have an entry and the for loop will iterate through them.

Well. That's one way at least.

You could also use Cats previous method and start a timer when the user clicks on a control. Then, if the timer times-out,, activate a really annoying sounder (add flashing lights too) and a dialogue box saying "Press The GO Button Idiot". Finally, send an e-mail to the logged in users supervisor telling him that the operator needs scheduling for re-training as he cannot follow simple on screen instructions.

I guarantee you will only be called out once late at night :lol:

Edited by ShaunR
Link to comment

You could also use Cats previous method and start a timer when the user clicks on a control. Then, if the timer times-out,, activate a really annoying sounder (add flashing lights too) and a dialogue box saying "Press The GO Button Idiot". Finally, send an e-mail to the logged in users supervisor telling him that the operator needs scheduling for re-training as he cannot follow simple on screen instructions.

I'm thinking a light that goes red as soon as any change has been made to any control. It doesn't go green until a message gets sent. Visual cues are great things in a UI.

But I like the email to the supervisor idea. :yes::lol:

Link to comment

I've hit a brick wall for a solution. Any ideas?

I've used a lossy-queue (size 1) to filter events that are sent to fast, pushing new events with the Lossy-Enqueue primitive.

If the consumer loop can keep up with the event loop, all events will be handled. If the consumer loop runs behind, older events will be discarded, but the last event will always be handled.

/J

Link to comment

I gotta ask...

Why is sending a message for each increment or decrement undesireable?

In general, each time the user changes the value of a control, a command gets sent to an instrument. For example, if the user changes a furnace setpoint from 200 to 201, a serial command gets sent a furnace controller, which takes a finite amount of time. There isn't any reason to tell the furnace controller to goto 201, then 202, then 203..... Generating serial commands too fast to some of these instruments can cause communication problems. Sure, there are ways to prevent this from happening by ensuring the code you use to communicate with the controller doesn't overwhelm it. But it just seems to me like this is a common enough UI issue that there should be a universal way to deal with it.

Link to comment

In general, each time the user changes the value of a control, a command gets sent to an instrument. For example, if the user changes a furnace setpoint from 200 to 201, a serial command gets sent a furnace controller, which takes a finite amount of time. There isn't any reason to tell the furnace controller to goto 201, then 202, then 203

I would think that if the furnace was set to 200 and the user wanted it to go to 205, they would just type "205" into the control. But maybe there's no keyboard, or your example was a trivial one compared to the real controls that are being set?

Link to comment

But it just seems to me like this is a common enough UI issue that there should be a universal way to deal with it.

I think that depends on your point of view. I have used "lazy" instruments before.But generally my design philosophy involves hardware several layers below the user interface, modularised and loosely coupled. This enables me (amongst other things) to bolt on different user interfaces to the same back-end Peculiarities of a device are handled by the modules and/or driver. I re-use many of the modules and wouldn't want to keep putting instrument specific code in to the user interface.

Link to comment

But it just seems to me like this is a common enough UI issue that there should be a universal way to deal with it.

Except it's not a UI issue. The UI is perfectly capable of dispatching multiple Value Change messages in rapid succession. The issue is with your furnace's inability to handle messages as quickly as they can be sent. The solution code belongs where the issue exists, not necessarily where the issue is seen.

What happens when someone asks for an automated furnace controller to run arbitrary temp profiles defined by the user? You'll have to reimplement the same code to make sure the user's profile isn't sending messages too quickly. Write it once as part of your furnace's Set Temp method and be done with it.

If you need a really quick and easy solution, do what Cat suggested and remove the Increment/Decrement buttons.

I re-use many of the modules and wouldn't want to keep putting instrument specific code in to the user interface.

That's why I asked the question. ;)

Link to comment

Except it's not a UI issue. The UI is perfectly capable of dispatching multiple Value Change messages in rapid succession. The issue is with your furnace's inability to handle messages as quickly as they can be sent. The solution code belongs where the issue exists, not necessarily where the issue is seen.

You make a good point here. But I don't think I'd want to make a blanket statement that you never want to implement something like this in a UI. Therefore I whipped up this little VI that does what I was thinking about. It borrows heavily from François' example. Just another tool for the tool box.

I always try to be the first time when a new user / program is activated. The human brain is very inventive how to solve an issue.

Yep, I get to experience that particular joy next week when I start training operators on my new UI. It's always a bit humbling when you get to find how easily your foolproof software can be fooled.

User Input.llb

Link to comment

You make a good point here. But I don't think I'd want to make a blanket statement that you never want to implement something like this in a UI. Therefore I whipped up this little VI that does what I was thinking about. It borrows heavily from François' example. Just another tool for the tool box.

Yep, I get to experience that particular joy next week when I start training operators on my new UI. It's always a bit humbling when you get to find how easily your foolproof software can be fooled.

Why not simply decouple the UI part from the Instrument part using a notifier?

Shane

Ps This way the delay is determined by the instrument and is not hard-wired in the code (I have simulated different delays for different functions in this example).

User Input Delay Example_Intaris.vi

Edited by shoneill
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.