From 23a8f9ab5d7ac2290007da37c27a3fc0303bc402 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sat, 29 Nov 2014 15:42:51 +0100 Subject: [PATCH] Fix scrollbar values. --- Perspex.Controls/Primitives/Track.cs | 37 +++++++++++++++--------- Perspex.Layout/Layoutable.cs | 12 ++++++++ Perspex.Themes.Default/ScrollBarStyle.cs | 15 ++++++++++ TestApplication/Program.cs | 1 - 4 files changed, 50 insertions(+), 15 deletions(-) diff --git a/Perspex.Controls/Primitives/Track.cs b/Perspex.Controls/Primitives/Track.cs index 1ead64e517..1ebb6714fe 100644 --- a/Perspex.Controls/Primitives/Track.cs +++ b/Perspex.Controls/Primitives/Track.cs @@ -118,18 +118,24 @@ namespace Perspex.Controls.Primitives if (thumb != null) { var range = this.Maximum - this.Minimum; - var thumbsize = this.ViewportSize / range; + var thumbFraction = this.ViewportSize / range; + var valueFraction = this.Value / range; + + if (double.IsNaN(thumbFraction)) + { + thumbFraction = 0; + } if (this.Orientation == Orientation.Horizontal) { - var width = finalSize.Width * thumbsize; - var x = finalSize.Width * (this.Value / range); + var width = finalSize.Width * thumbFraction; + var x = (finalSize.Width - thumb.ActualSize.Width) * valueFraction; thumb.Arrange(new Rect(x, 0, width, finalSize.Height)); } else { - var height = finalSize.Height * thumbsize; - var y = finalSize.Height * (this.Value / range); + var height = finalSize.Height * thumbFraction; + var y = (finalSize.Height - thumb.ActualSize.Height) * valueFraction; thumb.Arrange(new Rect(0, y, finalSize.Width, height)); } } @@ -139,23 +145,26 @@ namespace Perspex.Controls.Primitives private void ThumbDragged(object sender, VectorEventArgs e) { - var range = this.Maximum - this.Minimum; - var value = this.Value; + double range = this.Maximum - this.Minimum; + double value = this.Value; + double offset; if (this.Orientation == Orientation.Horizontal) { - value += e.Vector.X * (range / this.ActualSize.Width); - + offset = e.Vector.X / ((this.ActualSize.Width - this.Thumb.ActualSize.Width) / range); } else { - value += e.Vector.Y * (range / this.ActualSize.Height); + offset = e.Vector.Y * (range / (this.ActualSize.Height - this.Thumb.ActualSize.Height)); } - value = Math.Max(value, this.Minimum); - value = Math.Min(value, this.Maximum - this.ViewportSize); - - this.Value = value; + if (!double.IsNaN(offset) && !double.IsInfinity(offset)) + { + value += offset; + value = Math.Max(value, this.Minimum); + value = Math.Min(value, this.Maximum); + this.Value = value; + } } } } diff --git a/Perspex.Layout/Layoutable.cs b/Perspex.Layout/Layoutable.cs index 073501f79e..130de93420 100644 --- a/Perspex.Layout/Layoutable.cs +++ b/Perspex.Layout/Layoutable.cs @@ -125,6 +125,11 @@ namespace Perspex.Layout public void Measure(Size availableSize) { + if (double.IsNaN(availableSize.Width) || double.IsNaN(availableSize.Height)) + { + throw new InvalidOperationException("Cannot call Measure using a size with NaN values."); + } + availableSize = availableSize.Deflate(this.Margin); this.DesiredSize = this.MeasureCore(availableSize).Constrain(availableSize); @@ -137,6 +142,13 @@ namespace Perspex.Layout public void Arrange(Rect rect) { + if (rect.Width < 0 || rect.Height < 0 || + double.IsInfinity(rect.Width) || double.IsInfinity(rect.Height) || + double.IsNaN(rect.Width) || double.IsNaN(rect.Height)) + { + throw new InvalidOperationException("Invalid Arrange rectangle."); + } + this.Log().Debug( "Arrange of {0} (#{1:x8}) gave {2} ", this.GetType().Name, diff --git a/Perspex.Themes.Default/ScrollBarStyle.cs b/Perspex.Themes.Default/ScrollBarStyle.cs index ad904b08a1..21c5ba10a7 100644 --- a/Perspex.Themes.Default/ScrollBarStyle.cs +++ b/Perspex.Themes.Default/ScrollBarStyle.cs @@ -34,6 +34,13 @@ namespace Perspex.Themes.Default new Setter(ScrollBar.HeightProperty, 10.0), }, }, + new Style(x => x.OfType().Class(":horizontal").Template().Id("thumb")) + { + Setters = new[] + { + new Setter(Thumb.MinWidthProperty, 10.0), + }, + }, new Style(x => x.OfType().Class(":vertical")) { Setters = new[] @@ -42,6 +49,13 @@ namespace Perspex.Themes.Default new Setter(ScrollBar.WidthProperty, 10.0), }, }, + new Style(x => x.OfType().Class(":vertical").Template().Id("thumb")) + { + Setters = new[] + { + new Setter(Thumb.MinHeightProperty, 10.0), + }, + }, }); } @@ -59,6 +73,7 @@ namespace Perspex.Themes.Default [~Track.OrientationProperty] = control[~ScrollBar.OrientationProperty], Thumb = new Thumb { + Id = "thumb", Template = ControlTemplate.Create(this.ThumbTemplate), }, }, diff --git a/TestApplication/Program.cs b/TestApplication/Program.cs index 5f988249c7..6f745f678e 100644 --- a/TestApplication/Program.cs +++ b/TestApplication/Program.cs @@ -273,7 +273,6 @@ namespace TestApplication new ScrollBar { Orientation = Orientation.Vertical, - ViewportSize = 25, Value = 25, Height = 300, [Grid.ColumnProperty] = 0,