flex-users / flexlib

Open Source Flex components library.
github.com/flex-users/flexlib
MIT License
204 stars 91 forks source link

Sliders with multiple thumbs and unlocked regions don't dispatch SliderEvent.CHANGE after the track is dragged if the last thumb value is unchanged #331

Open nicoulaj opened 13 years ago

nicoulaj commented 13 years ago

Originally filed by william.bowers on 2010-09-23T07:18:06

Sorry about the super long title, but that's the shortest way I could think to explain it.

What steps will reproduce the problem? Do this: 1a. Fire up the included mxml file "TestSliders.mxml" to see the issue (it uses mx:WindowedApplication, but will work with mx:Application too).

Or this: 1b. Make your own:

Then do this (the actual test):

  1. With the app running, and the thumbs at each end, drag the track toward the maximum value ('right' for an HSlider and 'up' for a VSlider).
  2. If you do this when the second thumb is already at the maximum value the SliderEvent.CHANGE event will not fire. Any other interaction with the slider will produce the expected result (that I've seen, at least).

What is the expected output? What do you see instead? I expect the SliderEvent.CHANGE event to be fired when this happens, like it does if you were to drag the track toward the minimum value. Instead, it does not fire.

What version of the product are you using? On what operating system? I'm using r236 (a fresh checkout) on OS X Snow Leopard (10.6.4).

Please provide any additional information below. As indicated by the comments in the code (like on ExtendedSlider.counter, line 88, for example) some stuff had to be done so that dragging more than one thumb at a time (using the track) would only fire one SliderEvent.CHANGE event. In SliderBase.setValueAt(), line 2449, isProgrammatic is used to (I assume), in this case, make sure that only the change to the last thumb would actually fire the event and 'Math.abs(oldValue - value) > 0.002' is used to make sure the thumb value actually changed. The reason this isn't working is because when you drag the track toward the maximum value when the last thumb is already at maximum that thumb doesn't actually change value, so 'Math.abs(oldValue - value) > 0.002' is going to be false, and the event won't be dispatched. Even though the other thumb changed value, they wouldn't make it past 'if (!isProgrammatic)' because they are not the last thumb.

The included patch moves 'Math.abs(oldValue - value) > 0.002' outside of 'if (!isProgrammatic)' so every thumb gets checked. If any thumb value has changed valuesChanged gets set to true. Inside 'if (!isProgrammatic)', when the last thumb is set, it checks to see if valuesChanged is true instead of 'Math.abs(oldValue - value) > 0.002', making sure the event is fired if any of the thumbs haven't changed value.

I've made sure this doesn't make the SliderEvent.CHANGE event fire more than once per drag of the track.