Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add StepFrequency to RangeSelector #1584

Merged
merged 21 commits into from
Feb 21, 2018

Conversation

liakamp
Copy link
Contributor

@liakamp liakamp commented Oct 31, 2017

Issue: #1356

PR Type

Improvement on RangeSelector

[ ] Bugfix
[x ] Feature
[ ] Code style update (formatting)
[ ] Refactoring (no functional changes, no api changes)
[ ] Build or CI related changes
[x ] Documentation content changes
[x ] Sample app changes
[ ] Other... Please describe:

What is the current behavior?

the rangeselector max and min values change according to the thumb position

PR Checklist

Please check if your PR fulfills the following requirements:

  • [ x] Tested code with current supported SDKs
  • Docs have been added / updated (for bug fixes / features)
  • Sample in sample app has been added / updated (for bug fixes / features)
  • Tests for the changes have been added (for bug fixes / features) (if applicable)

What is the new behavior?

There is a DP called StepValue, and if it is set then the values and the thumbs move to the corresponding position of the next stepvalue.

Does this PR introduce a breaking change?

[ ] Yes
[x ] No

Other information

}

double newStep = Minimum + StepValue;
while (newStep < Maximum)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't this be done using math? MoveToStepValue could just use the rangeValue and play some math with it (mod and subtraction). A while loop seems unnecessary.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed: if the only point in having the stepValues list is for the MoveToStepValue method, then it should be possible to do the same in that method just with simple math!

Copy link
Contributor

@azchohfi azchohfi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs and Sample app should also be updated.

}

double newStep = Minimum + StepValue;
while (newStep < Maximum)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed: if the only point in having the stepValues list is for the MoveToStepValue method, then it should be possible to do the same in that method just with simple math!

Copy link
Member

@michael-hawker michael-hawker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest 'StepFrequency' as the name to align with the inbox Slider class.

Grid.Column="1"
Minimum="@[Minimum:Slider:0:0-100]@"
Maximum="@[Maximum:Slider:100:0-100]@"
StepValue="@[StepValue:String:1]@"/>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this type of String instead of DoubleSlider?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be a slider to pick the step frequency instead of a text field? With minimum being the DefaultStepFrequency and maximum the Maximum value of the RangeSelector?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense to me :)

@@ -606,6 +617,78 @@ private static void IsTouchOptimizedChangedCallback(DependencyObject d, Dependen
rangeSelector.ArrangeForTouch();
}

/// <summary>
/// Gets or sets the step value for range selector.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should elaborate on the behavior change that setting this property makes.

/// <value>
/// The value for step.
/// </value>
public double StepValue
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be StepFrequency to align with the naming for the inbox Slider class?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or maybe even TickFrequency, and then expose a collection for the Ticks?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Steps and Ticks are different. So, that'd expand the scope of the feature. Steps are the limits on the values, where Ticks are just visual. However, if you have both, then there's the SnapsTo property to define which one to use for actual value limiting. See Slider SnapsTo docs.

{
if (rangeValue != Maximum && rangeValue != Minimum)
{
return rangeValue - Enumerable.Range((int)Minimum, (int)Maximum)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't this just be Minimum + ((int)((rangeValue - Minimum) / StepValue)) * StepValue?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or if there is a collection for Ticks exposed this should be totally replaced

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ticks are different than Steps, so with just steps, you'd still need to figure out the valid values.

return;
}

if (rangeSelector.StepValue != 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check is redundant as the function does it already.


private void ResetStepValues()
{
if (StepValue != 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to compare to 0.0, but better to probably pull out as a constant of 'DefaultStepFrequency' so it's clear what we're checking for (and use that in the property initialization too).

Grid.Column="1"
Minimum="@[Minimum:Slider:0:0-100]@"
Maximum="@[Maximum:Slider:100:0-100]@"
StepFrequency="@[StepFrequency:String:1]@"/>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make this a DoubleSlider so that they can just slide to change the step value and not guess what to type in as a string?

E.g.
@[StepFrequency:DoubleSlider:1.0:0.25-10.0]@

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes this will be a good thing to add, it will make more sense.

@@ -48,6 +48,10 @@ This is because by default, the ScrollViewer will block the thumbs of the RangeS

```

## StepValue
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to rename this to match now too.

@nmetulev
Copy link
Contributor

@liakamp, just FYI, to make sure this will be merged for 2.1, it will need to be merged today. Otherwise, it will go out with 2.2

@liakamp
Copy link
Contributor Author

liakamp commented Nov 15, 2017

@nmetulev I was testing this today and I think I should also add a limit or reject step frequency values that are more than the Maximum of the RangeSelector, so I would like to spend a bit more time on this later this week. Maybe it is a better idea to be released in 2.2

@nmetulev nmetulev modified the milestones: v2.1, v2.2 Nov 15, 2017
@nmetulev
Copy link
Contributor

Sounds good to me :)

@nmetulev
Copy link
Contributor

@liakamp, up?

@liakamp
Copy link
Contributor Author

liakamp commented Jan 22, 2018

I want feedback on the last commit where the StepFrequency resets to default if it is greater than Maximum. If you agree I'm done.

private const double Epsilon = 0.01;

private const double DefaultStepFrequency = 0.0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should default to 1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Private const should be declared at the top of the class

@@ -48,6 +48,10 @@ This is because by default, the ScrollViewer will block the thumbs of the RangeS

```

## StepFrequency

If you want to use the RangeSelector using a step value, there is a `StepValue` property to set the interval between the values on the RangeSelector. For example; if you set `StepValue` to 2, using Minimum at 0 and Maximum at 10, the range values you can set will be 0,2,4,6,8,10.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is StepValue? Is that suppose to be StepFrequency?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I missed that

@@ -606,6 +619,79 @@ private static void IsTouchOptimizedChangedCallback(DependencyObject d, Dependen
rangeSelector.ArrangeForTouch();
}

/// <summary>
/// Gets or sets the step frequency, which is the interval between the values on the RangeSelector
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest making this the same as the docs for Slider:

//
// Summary:
// Gets or sets the value part of a value range that steps should be created for.
//
// Returns:
// The value part of a value range that steps should be created for.


private void ValidateStepFrequency()
{
if (StepFrequency > Maximum)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should follow behavior of Slider StepFrequency and just be the value set by the user. Even if that value is greater than the max. When sliding we could use Math.Min(Maximum, StepFrequency)

@liakamp
Copy link
Contributor Author

liakamp commented Jan 23, 2018

one more change left, modify for Math.Min(Maximum, StepFrequency) and maybe remove some checks because of this. will add it later today

@liakamp liakamp changed the title add StepValue to RangeSelector add StepFrequency to RangeSelector Jan 23, 2018
@skendrot
Copy link
Contributor

skendrot commented Jan 24, 2018

I think we're almost there. This should behave the same as on the Slider. I am noticing differences between the two. These can be easily seen by adding a Slider to the sample page and changing the StepFrequency, the Maximum/Minimum

<TextBlock Grid.Column="0" 
            HorizontalAlignment="Left"
            VerticalAlignment="Center"
            Foreground="Black"
            Text="{Binding Value, ElementName=Slider, Converter={StaticResource StringFormatConverter}, ConverterParameter='{}{0:0.##}'}" />
<Slider x:Name="Slider"
          Grid.Column="1"
          Minimum="@[Minimum:Slider:0:0-100]@" 
          Maximum="@[Maximum:Slider:100:0-100]@" 
          StepFrequency="@[StepFrequency:DoubleSlider:1.0:0.25-10.0]@"/>

Differences noted:

  • Value does not change on Slider when StepFrequency changes
  • Slider has smooth movement even with large StepFrequency. Value will change as it reaches next value. Thumb will snap to position if released not on a StepFrequency

@liakamp
Copy link
Contributor Author

liakamp commented Jan 24, 2018

Thanks for the code snippet, I will give it a try and get back to you with changes

@nmetulev
Copy link
Contributor

ping @liakamp

@nmetulev
Copy link
Contributor

FYI, 2.2 code freeze is in one week. Do you think you will be able to do the changes before then?

@liakamp
Copy link
Contributor Author

liakamp commented Feb 19, 2018

I was preparing an unreasonably complicated solution for this, turns out all I had to do was change the thumb sync. Hope now its ready for next release.

Copy link
Contributor

@nmetulev nmetulev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great. The only concern I have is the default step frequency being 1.0 since it changes the default behavior and it would be considered a breaking change. You can probably just change the StepFrequency to Nan or 0.01

@skendrot
Copy link
Contributor

I did request the value be set to 1 to match the slider. Rarely do users need .01 accuracy on a slider.

@nmetulev
Copy link
Contributor

I agree it should be 1, but it's still changing the default behavior, don't you think? We could change it to 1 for 3.0 or we could wait for 3.0 and mark it as a minor breaking change

@skendrot
Copy link
Contributor

Yea, it would be a change to the previous behavior, but would anyone really complain? 😃
Let's make it .01 by default and move it to 1 for 3.0

@nmetulev
Copy link
Contributor

Added it to #1615 to change to 1.0 :)

@liakamp
Copy link
Contributor Author

liakamp commented Feb 20, 2018

@nmetulev can we add also to remove the IsTouchOptimized DP in v3? It is DP and not default because it would cause a breaking change - see PR #964

@nmetulev
Copy link
Contributor

@liakamp, added

@nmetulev nmetulev dismissed stale reviews from azchohfi, pedrolamas, and michael-hawker February 20, 2018 20:19

Stale review

@skendrot
Copy link
Contributor

We are almost there!!! It looks like the Slider rounds up/down to get the new value rather than if it reaches the value.
Example: Set StepFrequency to 10. If the current max value is 50, then when dragging to the right it should change to 60 when it passes halfway between 50 and 60. If you release at that point, it should snap to it's actual location, much like already happens

PS: Sorry to be that guy!

@nmetulev
Copy link
Contributor

nmetulev commented Feb 21, 2018

ping @skendrot

Copy link
Contributor

@skendrot skendrot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job!

@skendrot skendrot merged commit 73b63cf into CommunityToolkit:master Feb 21, 2018
@windowstoolkitbot
Copy link

This PR is linked to unclosed issues. Please check if one of these issues should be closed: #1356, #1615

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants