From 41d1e3b1056c5da21adbed295ec3776db124fba5 Mon Sep 17 00:00:00 2001 From: Curtis Wensley Date: Thu, 6 Jul 2023 12:40:44 -0700 Subject: [PATCH] Setting e.Cancel = true in Splitter.PositionChanging event should cancel any changes --- src/Eto.Mac/Forms/Controls/SplitterHandler.cs | 8 +- .../Forms/Controls/SplitterHandler.cs | 7 +- src/Eto.Wpf/Forms/Controls/SplitterHandler.cs | 398 +++++++++--------- src/Eto/Forms/Controls/Splitter.cs | 4 +- .../UnitTests/Forms/Controls/SplitterTests.cs | 28 ++ 5 files changed, 245 insertions(+), 200 deletions(-) mode change 100644 => 100755 src/Eto/Forms/Controls/Splitter.cs diff --git a/src/Eto.Mac/Forms/Controls/SplitterHandler.cs b/src/Eto.Mac/Forms/Controls/SplitterHandler.cs index 07a73b927..05ab467d1 100644 --- a/src/Eto.Mac/Forms/Controls/SplitterHandler.cs +++ b/src/Eto.Mac/Forms/Controls/SplitterHandler.cs @@ -296,9 +296,13 @@ public override void DidResizeSubviews(NSNotification notification) var mainFrame = h.Control.Frame; if (mainFrame.Width <= 1 || mainFrame.Height <= 1) return; - h.position = h.Control.IsVertical ? (int)subview.Frame.Width : (int)subview.Frame.Height; + var newPosition = h.Control.IsVertical ? (int)subview.Frame.Width : (int)subview.Frame.Height; h.TriggerChangeStarted(); - h.Callback.OnPositionChanged(h.Widget, EventArgs.Empty); + if (newPosition != h.position) + { + h.position = newPosition; + h.Callback.OnPositionChanged(h.Widget, EventArgs.Empty); + } } } diff --git a/src/Eto.WinForms/Forms/Controls/SplitterHandler.cs b/src/Eto.WinForms/Forms/Controls/SplitterHandler.cs index a19daadd7..f0bc32f8d 100644 --- a/src/Eto.WinForms/Forms/Controls/SplitterHandler.cs +++ b/src/Eto.WinForms/Forms/Controls/SplitterHandler.cs @@ -161,6 +161,9 @@ private void CheckSplitterPos(bool userMoved) newPosition = lastPosition; } + // always set splitter distance + Control.SplitterDistance = newPosition; + if (lastPosition != newPosition) { if (Control.IsHandleCreated) @@ -170,9 +173,9 @@ private void CheckSplitterPos(bool userMoved) position = newPosition; Callback.OnPositionChanged(Widget, EventArgs.Empty); } - - Control.SplitterDistance = newPosition; } + + lastPosition = newPosition; if (userMoved) diff --git a/src/Eto.Wpf/Forms/Controls/SplitterHandler.cs b/src/Eto.Wpf/Forms/Controls/SplitterHandler.cs index 6a4b7bb18..4aa00cc0f 100755 --- a/src/Eto.Wpf/Forms/Controls/SplitterHandler.cs +++ b/src/Eto.Wpf/Forms/Controls/SplitterHandler.cs @@ -16,19 +16,20 @@ protected override sw.Size MeasureOverride(sw.Size constraint) public class SplitterHandler : WpfContainer, Splitter.IHandler { - readonly swc.GridSplitter splitter; - readonly swc.DockPanel pane1; - readonly swc.DockPanel pane2; - Orientation orientation; - SplitterFixedPanel fixedPanel; - int? position; - int splitterWidth = 5; - double relative = double.NaN; - bool panel1Visible, panel2Visible; - int panel1MinimumSize, panel2MinimumSize; - Control panel1, panel2; - PropertyChangeNotifier panel1VisibilityNotifier; - PropertyChangeNotifier panel2VisibilityNotifier; + readonly swc.GridSplitter _splitter; + readonly swc.DockPanel _pane1; + readonly swc.DockPanel _pane2; + Orientation _orientation; + SplitterFixedPanel _fixedPanel; + int? _position; + int _splitterWidth = 5; + double _relative = double.NaN; + bool _panel1Visible, _panel2Visible; + int _panel1MinimumSize, _panel2MinimumSize; + Control _panel1, _panel2; + PropertyChangeNotifier _panel1VisibilityNotifier; + PropertyChangeNotifier _panel2VisibilityNotifier; + bool _positionChanged; public override sw.Size MeasureOverride(sw.Size constraint, Func measure) @@ -44,8 +45,8 @@ private sw.Size BetterMeasure(sw.Size constraint) if (FixedPanel == SplitterFixedPanel.Panel2) { // provide our own measuring when FixedPanel is Panel2, as WPF gets it wrong sometimes - var panel1Size = panel1?.GetContainerControl()?.DesiredSize ?? sw.Size.Empty; - var panel2Size = panel2?.GetContainerControl()?.DesiredSize ?? sw.Size.Empty; + var panel1Size = _panel1?.GetContainerControl()?.DesiredSize ?? sw.Size.Empty; + var panel2Size = _panel2?.GetContainerControl()?.DesiredSize ?? sw.Size.Empty; if (Orientation == Orientation.Horizontal) size.Width = Math.Max(size.Width, panel1Size.Width + panel2Size.Width + SplitterWidth); else @@ -66,28 +67,28 @@ public SplitterHandler() Control.RowDefinitions.Add(new swc.RowDefinition { Height = sw.GridLength.Auto }); Control.RowDefinitions.Add(new swc.RowDefinition()); - splitter = new swc.GridSplitter + _splitter = new swc.GridSplitter { //Background = sw.SystemColors.ControlLightLightBrush, ResizeBehavior = swc.GridResizeBehavior.PreviousAndNext }; - pane1 = new swc.DockPanel { LastChildFill = true }; - pane2 = new swc.DockPanel { LastChildFill = true }; + _pane1 = new swc.DockPanel { LastChildFill = true }; + _pane2 = new swc.DockPanel { LastChildFill = true }; - Control.Children.Add(pane1); - Control.Children.Add(splitter); - Control.Children.Add(pane2); + Control.Children.Add(_pane1); + Control.Children.Add(_splitter); + Control.Children.Add(_pane2); UpdateOrientation(); Control.Loaded += Control_Loaded; Control.SizeChanged += (sender, e) => ResetMinMax(); - panel1VisibilityNotifier = new PropertyChangeNotifier(sw.UIElement.VisibilityProperty); - panel1VisibilityNotifier.ValueChanged += HandlePanel1IsVisibleChanged; + _panel1VisibilityNotifier = new PropertyChangeNotifier(sw.UIElement.VisibilityProperty); + _panel1VisibilityNotifier.ValueChanged += HandlePanel1IsVisibleChanged; - panel2VisibilityNotifier = new PropertyChangeNotifier(sw.UIElement.VisibilityProperty); - panel2VisibilityNotifier.ValueChanged += HandlePanel2IsVisibleChanged; + _panel2VisibilityNotifier = new PropertyChangeNotifier(sw.UIElement.VisibilityProperty); + _panel2VisibilityNotifier.ValueChanged += HandlePanel2IsVisibleChanged; } private void Control_Loaded(object sender, sw.RoutedEventArgs e) @@ -111,9 +112,9 @@ public override void AttachEvent(string id) PositionChangedEnabled--; break; case Splitter.PositionChangingEvent: - splitter.DragStarted += splitter_DragStarted; - splitter.DragCompleted += splitter_DragCompleted; - splitter.DragDelta += splitter_DragDelta; + _splitter.DragStarted += splitter_DragStarted; + _splitter.DragCompleted += splitter_DragCompleted; + _splitter.DragDelta += splitter_DragDelta; break; case Splitter.PositionChangeStartedEvent: case Splitter.PositionChangeCompletedEvent: @@ -127,7 +128,13 @@ public override void AttachEvent(string id) private void splitter_DragDelta(object sender, DragDeltaEventArgs e) { + _positionChanged = false; + var pos = Position; e.Handled = HandlePositionChanging(e.HorizontalChange, e.VerticalChange); + if (e.Handled && !_positionChanged) + { + Position = pos; + } } private void splitter_DragCompleted(object sender, DragCompletedEventArgs e) @@ -139,7 +146,7 @@ private void splitter_DragCompleted(object sender, DragCompletedEventArgs e) private void splitter_DragStarted(object sender, DragStartedEventArgs e) { Callback.OnPositionChangeStarted(Widget, EventArgs.Empty); - HandlePositionChanging(e.HorizontalOffset, e.VerticalOffset); + e.Handled = HandlePositionChanging(e.HorizontalOffset, e.VerticalOffset); } void HandlePositionChanged(object sender, sw.DependencyPropertyChangedEventArgs e) @@ -147,7 +154,7 @@ void HandlePositionChanged(object sender, sw.DependencyPropertyChangedEventArgs if (PositionChangedEnabled > 0) return; // we use actual width vs. width itself, so we have to use the value passed in - var old = position; + var old = _position; var pos = (sw.GridLength)e.NewValue; if (pos.GridUnitType != sw.GridUnitType.Pixel) return; @@ -169,16 +176,16 @@ void HandlePositionChanged(object sender, sw.DependencyPropertyChangedEventArgs { return; } + _position = newPosition; + Callback.OnPositionChanged(Widget, EventArgs.Empty); + _position = old; } - position = newPosition; - Callback.OnPositionChanged(Widget, EventArgs.Empty); - position = old; } bool HandlePositionChanging(double horizontal, double vertical, [System.Runtime.CompilerServices.CallerMemberName] string source = null) { var position = DoublePosition; - if (orientation == Orientation.Horizontal) + if (_orientation == Orientation.Horizontal) position += horizontal; else position += vertical; @@ -188,15 +195,16 @@ bool HandlePositionChanging(double horizontal, double vertical, [System.Runtime. var intPosition = (int)Math.Round(position); - if (intPosition == Position) - return false; // Console.WriteLine($"Source: {source}, {intPosition}"); var args = new SplitterPositionChangingEventArgs(intPosition); Callback.OnPositionChanging(Widget, args); if (args.Cancel) return true; - - if (fixedPanel == SplitterFixedPanel.None) + + if (intPosition == Position) + return false; + + if (_fixedPanel == SplitterFixedPanel.None) { Callback.OnPositionChanged(Widget, EventArgs.Empty); } @@ -213,18 +221,18 @@ int PositionChangedEnabled void SetInitialPosition() { - panel1Visible = panel1?.Visible ?? false; - panel2Visible = panel2?.Visible ?? false; + _panel1Visible = _panel1?.Visible ?? false; + _panel2Visible = _panel2?.Visible ?? false; // controls should be stretched to fit panels - SetStretch(panel1); - SetStretch(panel2); + SetStretch(_panel1); + SetStretch(_panel2); UpdateColumnSizing(false); - if (position != null) + if (_position != null) { - var pos = position.Value; - if (fixedPanel != SplitterFixedPanel.Panel1) + var pos = _position.Value; + if (_fixedPanel != SplitterFixedPanel.Panel1) { var size = GetAvailableSize(false); var want = GetAvailableSize(true); @@ -242,25 +250,25 @@ void SetInitialPosition() } SetPosition(pos); } - else if (!double.IsNaN(relative)) + else if (!double.IsNaN(_relative)) { - SetRelative(relative); + SetRelative(_relative); } - else if (fixedPanel == SplitterFixedPanel.Panel1) + else if (_fixedPanel == SplitterFixedPanel.Panel1) { - var size1 = panel1?.GetPreferredSize() ?? SizeF.Empty; - SetRelative(orientation == Orientation.Horizontal ? size1.Width : size1.Height); + var size1 = _panel1?.GetPreferredSize() ?? SizeF.Empty; + SetRelative(_orientation == Orientation.Horizontal ? size1.Width : size1.Height); } - else if (fixedPanel == SplitterFixedPanel.Panel2) + else if (_fixedPanel == SplitterFixedPanel.Panel2) { - var size2 = panel2?.GetPreferredSize() ?? SizeF.Empty; - SetRelative(orientation == Orientation.Horizontal ? size2.Width : size2.Height); + var size2 = _panel2?.GetPreferredSize() ?? SizeF.Empty; + SetRelative(_orientation == Orientation.Horizontal ? size2.Width : size2.Height); } else { - var size1 = panel1?.GetPreferredSize() ?? SizeF.Empty; - var size2 = panel2?.GetPreferredSize() ?? SizeF.Empty; - SetRelative(orientation == Orientation.Horizontal + var size1 = _panel1?.GetPreferredSize() ?? SizeF.Empty; + var size2 = _panel2?.GetPreferredSize() ?? SizeF.Empty; + SetRelative(_orientation == Orientation.Horizontal ? size1.Width / (double)(size1.Width + size2.Width) : size1.Height / (double)(size1.Height + size2.Height)); } @@ -282,53 +290,53 @@ static void SetStretch(Control panel) void UpdateOrientation() { - if (orientation == Orientation.Horizontal) + if (_orientation == Orientation.Horizontal) { - splitter.ResizeDirection = swc.GridResizeDirection.Columns; - splitter.HorizontalAlignment = sw.HorizontalAlignment.Left; - splitter.VerticalAlignment = sw.VerticalAlignment.Stretch; + _splitter.ResizeDirection = swc.GridResizeDirection.Columns; + _splitter.HorizontalAlignment = sw.HorizontalAlignment.Left; + _splitter.VerticalAlignment = sw.VerticalAlignment.Stretch; - splitter.SetValue(swc.Grid.RowSpanProperty, 3); - pane1.SetValue(swc.Grid.RowSpanProperty, 3); - pane2.SetValue(swc.Grid.RowSpanProperty, 3); + _splitter.SetValue(swc.Grid.RowSpanProperty, 3); + _pane1.SetValue(swc.Grid.RowSpanProperty, 3); + _pane2.SetValue(swc.Grid.RowSpanProperty, 3); - splitter.SetValue(swc.Grid.ColumnSpanProperty, 1); - pane1.SetValue(swc.Grid.ColumnSpanProperty, 1); - pane2.SetValue(swc.Grid.ColumnSpanProperty, 1); + _splitter.SetValue(swc.Grid.ColumnSpanProperty, 1); + _pane1.SetValue(swc.Grid.ColumnSpanProperty, 1); + _pane2.SetValue(swc.Grid.ColumnSpanProperty, 1); - swc.Grid.SetColumn(splitter, 1); - swc.Grid.SetRow(splitter, 0); - swc.Grid.SetColumn(pane2, 2); - swc.Grid.SetRow(pane2, 0); + swc.Grid.SetColumn(_splitter, 1); + swc.Grid.SetRow(_splitter, 0); + swc.Grid.SetColumn(_pane2, 2); + swc.Grid.SetRow(_pane2, 0); - splitter.Width = splitterWidth; - splitter.Height = double.NaN; + _splitter.Width = _splitterWidth; + _splitter.Height = double.NaN; } else { - splitter.ResizeDirection = swc.GridResizeDirection.Rows; - splitter.HorizontalAlignment = sw.HorizontalAlignment.Stretch; - splitter.VerticalAlignment = sw.VerticalAlignment.Top; - pane2.VerticalAlignment = sw.VerticalAlignment.Stretch; + _splitter.ResizeDirection = swc.GridResizeDirection.Rows; + _splitter.HorizontalAlignment = sw.HorizontalAlignment.Stretch; + _splitter.VerticalAlignment = sw.VerticalAlignment.Top; + _pane2.VerticalAlignment = sw.VerticalAlignment.Stretch; - splitter.SetValue(swc.Grid.RowSpanProperty, 1); - pane1.SetValue(swc.Grid.RowSpanProperty, 1); - pane2.SetValue(swc.Grid.RowSpanProperty, 1); + _splitter.SetValue(swc.Grid.RowSpanProperty, 1); + _pane1.SetValue(swc.Grid.RowSpanProperty, 1); + _pane2.SetValue(swc.Grid.RowSpanProperty, 1); - splitter.SetValue(swc.Grid.ColumnSpanProperty, 3); - pane1.SetValue(swc.Grid.ColumnSpanProperty, 3); - pane2.SetValue(swc.Grid.ColumnSpanProperty, 3); + _splitter.SetValue(swc.Grid.ColumnSpanProperty, 3); + _pane1.SetValue(swc.Grid.ColumnSpanProperty, 3); + _pane2.SetValue(swc.Grid.ColumnSpanProperty, 3); - swc.Grid.SetColumn(splitter, 0); - swc.Grid.SetRow(splitter, 1); - swc.Grid.SetColumn(pane2, 0); - swc.Grid.SetRow(pane2, 2); + swc.Grid.SetColumn(_splitter, 0); + swc.Grid.SetRow(_splitter, 1); + swc.Grid.SetColumn(_pane2, 0); + swc.Grid.SetRow(_pane2, 2); - splitter.Width = double.NaN; - splitter.Height = splitterWidth; + _splitter.Width = double.NaN; + _splitter.Height = _splitterWidth; } - UpdateColumnSizing(position.HasValue || !double.IsNaN(relative)); + UpdateColumnSizing(_position.HasValue || !double.IsNaN(_relative)); } public override Color BackgroundColor @@ -339,7 +347,7 @@ public override Color BackgroundColor void UpdateColumnSizing(bool updatePosition) { - if (updatePosition && position == null && double.IsNaN(relative)) + if (updatePosition && _position == null && double.IsNaN(_relative)) UpdateRelative(); //SetLength(1, sw.GridLength.Auto); @@ -365,10 +373,10 @@ void UpdateColumnSizing(bool updatePosition) void SetPositionOrRelative() { - if (position.HasValue) - SetPosition(position.Value); - else if (!double.IsNaN(relative)) - SetRelative(relative); + if (_position.HasValue) + SetPosition(_position.Value); + else if (!double.IsNaN(_relative)) + SetRelative(_relative); else SetHiddenPanels(); } @@ -377,7 +385,7 @@ public Orientation Orientation { get { - switch (splitter.ResizeDirection) + switch (_splitter.ResizeDirection) { case swc.GridResizeDirection.Columns: return Orientation.Horizontal; @@ -389,14 +397,14 @@ public Orientation Orientation } set { - orientation = value; + _orientation = value; UpdateOrientation(); } } public SplitterFixedPanel FixedPanel { - get { return fixedPanel; } + get { return _fixedPanel; } set { if (Control.IsLoaded) @@ -404,14 +412,14 @@ public SplitterFixedPanel FixedPanel if (HasHiddenPanels) UpdateRelativePosition(value); else - position = Position; + _position = Position; } else if (WasLoaded) UpdateRelativePosition(value); - fixedPanel = value; + _fixedPanel = value; - if (fixedPanel == SplitterFixedPanel.None) + if (_fixedPanel == SplitterFixedPanel.None) { // positionchanged events get triggered here when the fixed panel is none HandleEvent(Splitter.PositionChangingEvent); @@ -423,21 +431,21 @@ public SplitterFixedPanel FixedPanel private void UpdateRelativePosition(SplitterFixedPanel newFixedPanel) { - if (double.IsNaN(relative)) + if (double.IsNaN(_relative)) return; // translate relative position from old fixed panel to new fixed panel - var width = orientation == Orientation.Horizontal ? Control.ActualWidth : Control.ActualHeight; - switch (fixedPanel) + var width = _orientation == Orientation.Horizontal ? Control.ActualWidth : Control.ActualHeight; + switch (_fixedPanel) { case SplitterFixedPanel.Panel1: switch (newFixedPanel) { case SplitterFixedPanel.Panel2: - relative = width - relative - SplitterWidth; + _relative = width - _relative - SplitterWidth; break; case SplitterFixedPanel.None: - relative = relative / width; + _relative = _relative / width; break; } break; @@ -445,10 +453,10 @@ private void UpdateRelativePosition(SplitterFixedPanel newFixedPanel) switch (newFixedPanel) { case SplitterFixedPanel.Panel1: - relative = width - relative - SplitterWidth; + _relative = width - _relative - SplitterWidth; break; case SplitterFixedPanel.None: - relative = (width - relative) / width; + _relative = (width - _relative) / width; break; } break; @@ -456,10 +464,10 @@ private void UpdateRelativePosition(SplitterFixedPanel newFixedPanel) switch (newFixedPanel) { case SplitterFixedPanel.Panel1: - relative = width * relative; + _relative = width * _relative; break; case SplitterFixedPanel.Panel2: - relative = width - (width * relative); + _relative = width - (width * _relative); break; } break; @@ -470,11 +478,11 @@ double DoublePosition { get { - if (position != null) - return position.Value; + if (_position != null) + return _position.Value; if (!Control.IsLoaded && !WasLoaded) return 0; - if (splitter.ResizeDirection == swc.GridResizeDirection.Columns) + if (_splitter.ResizeDirection == swc.GridResizeDirection.Columns) return Control.ColumnDefinitions[0].ActualWidth; return Control.RowDefinitions[0].ActualHeight; } @@ -491,16 +499,16 @@ public int Position public int SplitterWidth { - get { return splitterWidth; } + get { return _splitterWidth; } set { - if (splitterWidth == value) + if (_splitterWidth == value) return; - splitterWidth = value; - if (orientation == Orientation.Horizontal) - splitter.Width = value; + _splitterWidth = value; + if (_orientation == Orientation.Horizontal) + _splitter.Width = value; else - splitter.Height = value; + _splitter.Height = value; } } @@ -516,26 +524,26 @@ double GetAvailableSize(bool desired) var size = UserPreferredSize; var pick = Orientation == Orientation.Horizontal ? size.Width : size.Height; if (pick >= 0) - return pick - splitterWidth; + return pick - _splitterWidth; } var width = Orientation == Orientation.Horizontal ? Control.ActualWidth : Control.ActualHeight; if (double.IsNaN(width)) width = Orientation == Orientation.Horizontal ? Control.Width : Control.Height; - return width - splitterWidth; + return width - _splitterWidth; } void UpdateRelative() { var pos = Position; - if (fixedPanel == SplitterFixedPanel.Panel1) - relative = pos; + if (_fixedPanel == SplitterFixedPanel.Panel1) + _relative = pos; else { var sz = GetAvailableSize(); - if (fixedPanel == SplitterFixedPanel.Panel2) - relative = sz <= 0 ? 0 : sz - pos; + if (_fixedPanel == SplitterFixedPanel.Panel2) + _relative = sz <= 0 ? 0 : sz - pos; else - relative = sz <= 0 ? 0.5 : pos / (double)sz; + _relative = sz <= 0 ? 0.5 : pos / (double)sz; } } @@ -543,13 +551,13 @@ public double RelativePosition { get { - if (double.IsNaN(relative) || Widget.Loaded) + if (double.IsNaN(_relative) || Widget.Loaded) UpdateRelative(); - return relative; + return _relative; } set { - if (relative == value) + if (_relative == value) return; SetRelative(value); Callback.OnPositionChanged(Widget, EventArgs.Empty); @@ -558,7 +566,7 @@ public double RelativePosition double GetSize(int panel) { - if (splitter.ResizeDirection == swc.GridResizeDirection.Columns) + if (_splitter.ResizeDirection == swc.GridResizeDirection.Columns) return Control.ColumnDefinitions[panel].ActualWidth; else return Control.RowDefinitions[panel].ActualHeight; @@ -567,7 +575,7 @@ double GetSize(int panel) sw.GridLength GetLength(int panel) { - if (splitter.ResizeDirection == swc.GridResizeDirection.Columns) + if (_splitter.ResizeDirection == swc.GridResizeDirection.Columns) return Control.ColumnDefinitions[panel].Width; else return Control.RowDefinitions[panel].Height; @@ -575,7 +583,7 @@ sw.GridLength GetLength(int panel) void SetLength(int panel, sw.GridLength value) { - if (splitter.ResizeDirection == swc.GridResizeDirection.Columns) + if (_splitter.ResizeDirection == swc.GridResizeDirection.Columns) Control.ColumnDefinitions[panel].Width = value; else Control.RowDefinitions[panel].Height = value; @@ -583,21 +591,21 @@ void SetLength(int panel, sw.GridLength value) bool HasHiddenPanels { - get { return panel1 == null || !panel1.Visible || panel2 == null || !panel2.Visible; } + get { return _panel1 == null || !_panel1.Visible || _panel2 == null || !_panel2.Visible; } } bool SetHiddenPanels() { if (!Widget.Loaded) return false; - if (panel1 == null || !panel1.Visible) + if (_panel1 == null || !_panel1.Visible) { SetLength(0, new sw.GridLength(0, sw.GridUnitType.Pixel)); SetLength(1, new sw.GridLength(0, sw.GridUnitType.Pixel)); SetLength(2, new sw.GridLength(1, sw.GridUnitType.Star)); return true; } - if (panel2 == null || !panel2.Visible) + if (_panel2 == null || !_panel2.Visible) { SetLength(0, new sw.GridLength(1, sw.GridUnitType.Star)); SetLength(1, new sw.GridLength(0, sw.GridUnitType.Pixel)); @@ -611,27 +619,28 @@ void SetPosition(int newPosition) { if (SetHiddenPanels()) return; + _positionChanged = true; SetLength(1, sw.GridLength.Auto); if (!Control.IsLoaded) { - position = newPosition; - relative = double.NaN; + _position = newPosition; + _relative = double.NaN; SetLength(0, new sw.GridLength(Math.Max(0, newPosition), sw.GridUnitType.Pixel)); SetLength(2, new sw.GridLength(1, sw.GridUnitType.Star)); return; } - position = null; + _position = null; var size = GetAvailableSize(false); - relative = fixedPanel == SplitterFixedPanel.Panel1 ? Math.Max(0, newPosition) - : fixedPanel == SplitterFixedPanel.Panel2 ? Math.Max(0, size - newPosition) + _relative = _fixedPanel == SplitterFixedPanel.Panel1 ? Math.Max(0, newPosition) + : _fixedPanel == SplitterFixedPanel.Panel2 ? Math.Max(0, size - newPosition) : size <= 0 ? 0.5 : Math.Max(0.0, Math.Min(1.0, newPosition / (double)size)); - if (fixedPanel == SplitterFixedPanel.Panel1) + if (_fixedPanel == SplitterFixedPanel.Panel1) { SetLength(0, new sw.GridLength(Math.Max(0, newPosition), sw.GridUnitType.Pixel)); SetLength(2, new sw.GridLength(1, sw.GridUnitType.Star)); } - else if (fixedPanel == SplitterFixedPanel.Panel2) + else if (_fixedPanel == SplitterFixedPanel.Panel2) { SetLength(0, new sw.GridLength(1, sw.GridUnitType.Star)); SetLength(2, new sw.GridLength(Math.Max(0, size - newPosition), sw.GridUnitType.Pixel)); @@ -647,24 +656,25 @@ void SetRelative(double newRelative) { if (SetHiddenPanels()) return; - position = null; - relative = newRelative; + _positionChanged = true; + _position = null; + _relative = newRelative; PositionChangedEnabled++; SetLength(1, sw.GridLength.Auto); - if (fixedPanel == SplitterFixedPanel.Panel1) + if (_fixedPanel == SplitterFixedPanel.Panel1) { - SetLength(0, new sw.GridLength(Math.Max(0, relative), sw.GridUnitType.Pixel)); + SetLength(0, new sw.GridLength(Math.Max(0, _relative), sw.GridUnitType.Pixel)); SetLength(2, new sw.GridLength(1, sw.GridUnitType.Star)); } - else if (fixedPanel == SplitterFixedPanel.Panel2) + else if (_fixedPanel == SplitterFixedPanel.Panel2) { SetLength(0, new sw.GridLength(1, sw.GridUnitType.Star)); - SetLength(2, new sw.GridLength(Math.Max(0, relative), sw.GridUnitType.Pixel)); + SetLength(2, new sw.GridLength(Math.Max(0, _relative), sw.GridUnitType.Pixel)); } else { - SetLength(0, new sw.GridLength(Math.Max(0, relative), sw.GridUnitType.Star)); - SetLength(2, new sw.GridLength(Math.Max(0, 1 - relative), sw.GridUnitType.Star)); + SetLength(0, new sw.GridLength(Math.Max(0, _relative), sw.GridUnitType.Star)); + SetLength(2, new sw.GridLength(Math.Max(0, 1 - _relative), sw.GridUnitType.Star)); } PositionChangedEnabled--; } @@ -672,33 +682,33 @@ void SetRelative(double newRelative) public override void SetScale(bool xscale, bool yscale) { base.SetScale(xscale, yscale); - var control = panel1.GetWpfFrameworkElement(); + var control = _panel1.GetWpfFrameworkElement(); if (control != null) control.SetScale(true, true); - control = panel2.GetWpfFrameworkElement(); + control = _panel2.GetWpfFrameworkElement(); if (control != null) control.SetScale(true, true); } public Control Panel1 { - get { return panel1; } + get { return _panel1; } set { - panel1VisibilityNotifier.PropertySource = null; + _panel1VisibilityNotifier.PropertySource = null; - panel1 = value; - pane1.Children.Clear(); - if (panel1 != null) + _panel1 = value; + _pane1.Children.Clear(); + if (_panel1 != null) { - var control = panel1.GetWpfFrameworkElement(); - SetStretch(panel1); + var control = _panel1.GetWpfFrameworkElement(); + SetStretch(_panel1); if (Widget.Loaded) control.SetScale(true, true); - pane1.Children.Add(control.ContainerControl); - panel1VisibilityNotifier.PropertySource = control.ContainerControl; - HandlePanelVisibleChanged(ref panel1Visible, panel1); + _pane1.Children.Add(control.ContainerControl); + _panel1VisibilityNotifier.PropertySource = control.ContainerControl; + HandlePanelVisibleChanged(ref _panel1Visible, _panel1); } else { @@ -709,23 +719,23 @@ public Control Panel1 public Control Panel2 { - get { return panel2; } + get { return _panel2; } set { - panel2VisibilityNotifier.PropertySource = null; + _panel2VisibilityNotifier.PropertySource = null; - panel2 = value; - pane2.Children.Clear(); - if (panel2 != null) + _panel2 = value; + _pane2.Children.Clear(); + if (_panel2 != null) { - var control = panel2.GetWpfFrameworkElement(); - SetStretch(panel2); + var control = _panel2.GetWpfFrameworkElement(); + SetStretch(_panel2); if (Widget.Loaded) control.SetScale(true, true); - pane2.Children.Add(control.ContainerControl); + _pane2.Children.Add(control.ContainerControl); - panel2VisibilityNotifier.PropertySource = control.ContainerControl; - HandlePanelVisibleChanged(ref panel2Visible, panel2); + _panel2VisibilityNotifier.PropertySource = control.ContainerControl; + HandlePanelVisibleChanged(ref _panel2Visible, _panel2); } else { @@ -736,12 +746,12 @@ public Control Panel2 void HandlePanel2IsVisibleChanged(object sender, sw.DependencyPropertyChangedEventArgs e) { - HandlePanelVisibleChanged(ref panel2Visible, panel2); + HandlePanelVisibleChanged(ref _panel2Visible, _panel2); } void HandlePanel1IsVisibleChanged(object sender, sw.DependencyPropertyChangedEventArgs e) { - HandlePanelVisibleChanged(ref panel1Visible, panel1); + HandlePanelVisibleChanged(ref _panel1Visible, _panel1); } void HandlePanelVisibleChanged(ref bool isVisible, Control panel) @@ -751,31 +761,31 @@ void HandlePanelVisibleChanged(ref bool isVisible, Control panel) isVisible = panel.Visible; if (!panel.Visible) { - position = null; - if ((panel1 != null && panel1.Visible) || (panel2 != null && panel2.Visible)) + _position = null; + if ((_panel1 != null && _panel1.Visible) || (_panel2 != null && _panel2.Visible)) UpdateRelative(); SetHiddenPanels(); } - else if (!double.IsNaN(relative)) + else if (!double.IsNaN(_relative)) { - SetRelative(relative); + SetRelative(_relative); } } } public override void Remove(sw.FrameworkElement child) { - if (pane1.Children.Contains(child)) + if (_pane1.Children.Contains(child)) { - panel1VisibilityNotifier.PropertySource = null; - panel1 = null; - pane1.Children.Remove(child); + _panel1VisibilityNotifier.PropertySource = null; + _panel1 = null; + _pane1.Children.Remove(child); } - else if (pane2.Children.Contains(child)) + else if (_pane2.Children.Contains(child)) { - panel2VisibilityNotifier.PropertySource = null; - panel2 = null; - pane2.Children.Remove(child); + _panel2VisibilityNotifier.PropertySource = null; + _panel2 = null; + _pane2.Children.Remove(child); } } @@ -791,8 +801,8 @@ private void ResetMinMax() { if (Orientation == Orientation.Horizontal) { - Control.ColumnDefinitions[0].MinWidth = panel1MinimumSize; - Control.ColumnDefinitions[2].MinWidth = panel2MinimumSize; + Control.ColumnDefinitions[0].MinWidth = _panel1MinimumSize; + Control.ColumnDefinitions[2].MinWidth = _panel2MinimumSize; Control.RowDefinitions[0].MinHeight = 0; Control.RowDefinitions[2].MinHeight = 0; } @@ -801,7 +811,7 @@ private void ResetMinMax() Control.ColumnDefinitions[0].MinWidth = 0; Control.ColumnDefinitions[2].MinWidth = 0; Control.RowDefinitions[0].MinHeight = Panel1MinimumSize; - Control.RowDefinitions[2].MinHeight = panel2MinimumSize; + Control.RowDefinitions[2].MinHeight = _panel2MinimumSize; } if (Control.IsLoaded) @@ -835,20 +845,20 @@ private void ResetMinMax() public int Panel1MinimumSize { - get { return panel1MinimumSize; } + get { return _panel1MinimumSize; } set { - panel1MinimumSize = value; + _panel1MinimumSize = value; ResetMinMax(); } } public int Panel2MinimumSize { - get { return panel2MinimumSize; } + get { return _panel2MinimumSize; } set { - panel2MinimumSize = value; + _panel2MinimumSize = value; ResetMinMax(); } } @@ -863,9 +873,9 @@ public override void OnUnLoad(EventArgs e) { base.OnUnLoad(e); WasLoaded = true; - if (double.IsNaN(relative) || !HasHiddenPanels) + if (double.IsNaN(_relative) || !HasHiddenPanels) UpdateRelative(); - position = null; + _position = null; } } } \ No newline at end of file diff --git a/src/Eto/Forms/Controls/Splitter.cs b/src/Eto/Forms/Controls/Splitter.cs old mode 100644 new mode 100755 index c68f0cd58..761aded84 --- a/src/Eto/Forms/Controls/Splitter.cs +++ b/src/Eto/Forms/Controls/Splitter.cs @@ -170,8 +170,8 @@ static Splitter() { EventLookup.Register(c => c.OnPositionChanged(null), Splitter.PositionChangedEvent); EventLookup.Register(c => c.OnPositionChanging(null), Splitter.PositionChangingEvent); - EventLookup.Register(c => c.OnPositionChangeStarted(null), Splitter.PositionChangingEvent); - EventLookup.Register(c => c.OnPositionChangeCompleted(null), Splitter.PositionChangingEvent); + EventLookup.Register(c => c.OnPositionChangeStarted(null), Splitter.PositionChangeStartedEvent); + EventLookup.Register(c => c.OnPositionChangeCompleted(null), Splitter.PositionChangeCompletedEvent); } /// diff --git a/test/Eto.Test/UnitTests/Forms/Controls/SplitterTests.cs b/test/Eto.Test/UnitTests/Forms/Controls/SplitterTests.cs index 61e8bae11..d846835d8 100755 --- a/test/Eto.Test/UnitTests/Forms/Controls/SplitterTests.cs +++ b/test/Eto.Test/UnitTests/Forms/Controls/SplitterTests.cs @@ -440,6 +440,34 @@ public void SplitterChangingShouldAllowRestrictingWithoutArtifacts() Assert.IsNull(outOfBounds, $"#1 - Position went out of bounds 100-200, was {outOfBounds}"); } + [Test, ManualTest] + public void SplitterShouldNotMoveWhenChangingCancelled() + { + int positionChanged = 0; + ManualForm("Splitter should not be able to move", form => + { + form.ClientSize = new Size(600, 300); + var splitter = new Splitter + { + + Panel1 = new Panel { BackgroundColor = Colors.Blue, Size = new Size(300, 200) }, + Panel2 = new Panel { BackgroundColor = Colors.Red, Size = new Size(300, 200) } + }; + + splitter.PositionChanging += (sender, e) => + { + System.Diagnostics.Debug.WriteLine($"PositionChanging, Position {splitter.Position}, NewPosition: {e.NewPosition}"); + e.Cancel = true; + }; + splitter.PositionChanged += (sender, e) => + { + positionChanged++; + }; + return splitter; + }); + Assert.AreEqual(0, positionChanged, $"#1 - PositionChanged should not fire"); + } + [TestCase(Orientation.Horizontal)] [TestCase(Orientation.Vertical)] public void ZeroRelativePositionShouldNotCrash(Orientation orientation)