From 11043c9ea9a28b15b720557a8bd70c431d7658f4 Mon Sep 17 00:00:00 2001 From: Noisrev Date: Mon, 26 Dec 2022 15:11:22 +0800 Subject: [PATCH 01/18] Add a Deactivated event handler in the Navigator Window - Close the window when it is not active and activate the selected content --- .../AvalonDock/Controls/NavigatorWindow.cs | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/source/Components/AvalonDock/Controls/NavigatorWindow.cs b/source/Components/AvalonDock/Controls/NavigatorWindow.cs index ccfa3562..7deee8ca 100644 --- a/source/Components/AvalonDock/Controls/NavigatorWindow.cs +++ b/source/Components/AvalonDock/Controls/NavigatorWindow.cs @@ -98,6 +98,7 @@ internal NavigatorWindow(DockingManager manager) DataContext = this; Loaded += OnLoaded; Unloaded += OnUnloaded; + Deactivated += OnDeactivated; UpdateThemeResources(); } @@ -380,11 +381,7 @@ protected override void OnKeyUp(KeyEventArgs e) { if (!(e.Key == Key.Tab || e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.Up || e.Key == Key.Down)) { - Close(); - if (SelectedDocument != null && SelectedDocument.ActivateCommand.CanExecute(null)) - SelectedDocument.ActivateCommand.Execute(null); - if (SelectedDocument == null && SelectedAnchorable != null && SelectedAnchorable.ActivateCommand.CanExecute(null)) - SelectedAnchorable.ActivateCommand.Execute(null); + CloseAndActiveSelected(); e.Handled = true; } base.OnKeyUp(e); @@ -520,6 +517,21 @@ private void OnLoaded(object sender, RoutedEventArgs e) private void OnUnloaded(object sender, RoutedEventArgs e) => Unloaded -= OnUnloaded; + private void OnDeactivated(object sender, EventArgs e) + { + CloseAndActiveSelected(); + } + + private void CloseAndActiveSelected() + { + Deactivated -= OnDeactivated; + Close(); + if (SelectedDocument != null && SelectedDocument.ActivateCommand.CanExecute(null)) + SelectedDocument.ActivateCommand.Execute(null); + if (SelectedDocument == null && SelectedAnchorable != null && SelectedAnchorable.ActivateCommand.CanExecute(null)) + SelectedAnchorable.ActivateCommand.Execute(null); + } + private void FocusSelectedItem(ListBox list) { if (list.SelectedIndex >= 0) From e9b337d18774970eae75a30ed93101102f8011cb Mon Sep 17 00:00:00 2001 From: Dirkster99 Date: Mon, 26 Dec 2022 19:35:42 +0100 Subject: [PATCH 02/18] Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index a5be5479..64e7077a 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,14 @@ to also theme standard elements, such as, button and textblock etc. # Mile Stone History +## Fixes Added in Version 4.71.1 + +- [#413 Fix the binding error in AnchorGroupTemplate](https://github.com/Dirkster99/AvalonDock/pull/413) (thanx to [EQOH Noisrev](https://github.com/Noisrev)) + +- [#414 When apply new template, add back collection change event handler](https://github.com/Dirkster99/AvalonDock/pull/414) (thanx to [EQOH Noisrev](https://github.com/Noisrev)) + +- [#415 Improved and fix floating window activation and activation pane](https://github.com/Dirkster99/AvalonDock/pull/415) (thanx to [EQOH Noisrev](https://github.com/Noisrev)) + ## Fixes Added in Version 4.71.0 - [#399 add open/close LayoutFlayoutingWindowsControl events](https://github.com/Dirkster99/AvalonDock/pull/399) (thanx to [Denis Smirnov](https://github.com/GonzRu)) From df8109c8595a3dd7788659b19b41ba5207382713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=B6ller?= Date: Wed, 4 Jan 2023 17:43:39 +0100 Subject: [PATCH 03/18] Fixed Issue 226: Owned/maximized floating windows (LayoutFloatingWindowControl) do not restore to maximized state when the owner (DockingManager) window is restored from being minimized. --- .../Controls/LayoutFloatingWindowControl.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs index c1377a92..725cf6aa 100644 --- a/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs @@ -218,7 +218,21 @@ private set protected override void OnStateChanged(EventArgs e) { if (!_isInternalChange) - UpdateMaximizedState(WindowState == WindowState.Maximized); + { + if (WindowState == WindowState.Maximized) + { + // Forward external changes to WindowState from any state to a new Maximized state + // to the LayoutFloatingWindowControl internal representation. + UpdateMaximizedState(true); + } + else if (IsMaximized && OwnedByDockingManagerWindow) + { + // Override any external changes to WindowState when owned and in Maximized state. + // This override fixes the issue of an owned LayoutFloatingWindowControl loosing + // its Maximized state when the owner window is restored from a Minimized state. + WindowState = WindowState.Maximized; + } + } base.OnStateChanged(e); } From 895646cdf2195ec7b3739a536d99cb774ae73609 Mon Sep 17 00:00:00 2001 From: Noisrev Date: Thu, 12 Jan 2023 22:37:38 +0800 Subject: [PATCH 04/18] Improve the active item handler and add to LayoutAnchorableFloatingWindow --- .../LayoutAnchorableFloatingWindowControl.cs | 143 ++++++++++- .../LayoutDocumentFloatingWindowControl.cs | 242 +++++++++--------- 2 files changed, 255 insertions(+), 130 deletions(-) diff --git a/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs index 75f417da..381b755a 100644 --- a/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs @@ -7,10 +7,6 @@ This program is provided to you under the terms of the Microsoft Public License (Ms-PL) as published at https://opensource.org/licenses/MS-PL ************************************************************************/ -using AvalonDock.Commands; -using AvalonDock.Converters; -using AvalonDock.Layout; -using Microsoft.Windows.Shell; using System; using System.Collections.Generic; using System.ComponentModel; @@ -20,6 +16,12 @@ This program is provided to you under the terms of the Microsoft Public using System.Windows.Data; using System.Windows.Input; +using AvalonDock.Commands; +using AvalonDock.Converters; +using AvalonDock.Layout; + +using Microsoft.Windows.Shell; + namespace AvalonDock.Controls { /// @@ -244,17 +246,17 @@ protected override IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, Int switch (msg) { case Win32Helper.WM_ACTIVATE: - var anchorablePane = _model.Descendents().OfType() - .FirstOrDefault(p => p.ChildrenCount > 0 && p.SelectedContent != null); - - if (anchorablePane != null) + var isInactive = ((int)wParam & 0xFFFF) == Win32Helper.WA_INACTIVE; + if (_model.IsSinglePane) { - var isActive = !(((int)wParam & 0xFFFF) == Win32Helper.WA_INACTIVE); - anchorablePane.SelectedContent.IsActive = isActive; - - handled = true; + ActiveItemOfSinglePane(!isInactive); + } + else + { + ActiveItemOfMultiPane(!isInactive); } + handled = true; break; case Win32Helper.WM_NCRBUTTONUP: @@ -431,6 +433,123 @@ private void OnExecuteCloseWindowCommand(object parameter) #endregion CloseWindowCommand + #region ActiveItem + + private void ActiveItemOfSinglePane(bool isActive) + { + var layoutDocumentPane = _model.Descendents().OfType() + .FirstOrDefault(p => p.ChildrenCount > 0 && p.SelectedContent != null); + + if (layoutDocumentPane != null) + { + layoutDocumentPane.SelectedContent.IsActive = isActive; + } + // When the floating tool window is mixed with the floating document window + // and the document pane in the floating document window is dragged out. + + // Only the Tool panes is left in the floating document window. + // The Children Count is greater than 0 and the Selected Content is null. + + // Then we only need to activate the last active content. + else + { + ActiveTheLastActivedItemOfItems(isActive); + } + } + + private LayoutAnchorablePaneControl FindPaneControlByMousePoint() + { + var mousePosition = Win32Helper.GetMousePosition(); + var rootVisual = ((FloatingWindowContentHost)Content).RootVisual; + var areaHosts = rootVisual.FindVisualChildren(); + + foreach (var areaHost in areaHosts) + { + var rect = areaHost.GetScreenArea(); + var pos = areaHost.TransformFromDeviceDPI(mousePosition); + var b = rect.Contains(pos); + + if (b) + { + return areaHost; + } + } + + return null; + } + + private static void ActiveTheLastActivedItemOfPane(LayoutAnchorablePane pane) + { + if (pane.Children.Count > 0) + { + var index = 0; + if (pane.Children.Count > 1) + { + var tmTimeStamp = pane.Children[0].LastActivationTimeStamp; + for (var i = 1; i < pane.Children.Count; i++) + { + var item = pane.Children[i]; + if (item.LastActivationTimeStamp > tmTimeStamp) + { + tmTimeStamp = item.LastActivationTimeStamp; + index = i; + } + } + } + + pane.SelectedContentIndex = index; + } + } + + private void ActiveTheLastActivedItemOfItems(bool isActive) + { + var items = _model.Descendents().OfType().ToList(); + if (items.Count > 0) + { + var index = 0; + if (items.Count > 1) + { + var tmpTimeStamp2 = items[0].LastActivationTimeStamp; + for (var i = 1; i < items.Count; i++) + { + var item = items[i]; + if (item.LastActivationTimeStamp > tmpTimeStamp2) + { + tmpTimeStamp2 = item.LastActivationTimeStamp; + index = i; + } + } + } + + items[index].IsActive = isActive; + } + } + + private void ActiveItemOfMultiPane(bool isActive) + { + if (isActive) + { + var documentPane = FindPaneControlByMousePoint(); + if (documentPane != null) + { + var model = (LayoutAnchorablePane)documentPane.Model; + if (model.SelectedContent != null) + { + model.SelectedContent.IsActive = true; + return; + } + else + { + ActiveTheLastActivedItemOfPane(model); + return; + } + } + } + ActiveTheLastActivedItemOfItems(isActive); + } + + #endregion ActiveItem + #endregion Private Methods } } diff --git a/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs index c25e67e7..baa4ce29 100644 --- a/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs @@ -7,9 +7,6 @@ This program is provided to you under the terms of the Microsoft Public License (Ms-PL) as published at https://opensource.org/licenses/MS-PL ************************************************************************/ -using AvalonDock.Commands; -using AvalonDock.Layout; -using Microsoft.Windows.Shell; using System; using System.Collections.Generic; using System.Linq; @@ -17,6 +14,11 @@ This program is provided to you under the terms of the Microsoft Public using System.Windows.Controls.Primitives; using System.Windows.Input; +using AvalonDock.Commands; +using AvalonDock.Layout; + +using Microsoft.Windows.Shell; + namespace AvalonDock.Controls { /// @@ -113,119 +115,6 @@ private void Model_PropertyChanged(object sender, System.ComponentModel.Property if (e.PropertyName == nameof(LayoutDocumentFloatingWindow.RootPanel) && _model.RootPanel == null) InternalClose(); } - private void ActiveOfSinglePane(bool isActive) - { - var layoutDocumentPane = _model.Descendents().OfType() - .FirstOrDefault(p => p.ChildrenCount > 0 && p.SelectedContent != null); - - if (layoutDocumentPane != null) - { - layoutDocumentPane.SelectedContent.IsActive = isActive; - } - // When the floating tool window is mixed with the floating document window - // and the document pane in the floating document window is dragged out. - - // Only the Tool panes is left in the floating document window. - // The Children Count is greater than 0 and the Selected Content is null. - - // Then we only need to activate the last active content. - else - { - ActiveLastActivationOfItems(isActive); - } - } - - private LayoutDocumentPaneControl FindDocumentPaneControlByMousePoint() - { - var mousePosition = Win32Helper.GetMousePosition(); - var rootVisual = ((FloatingWindowContentHost)Content).RootVisual; - var areaHosts = rootVisual.FindVisualChildren(); - - foreach (var areaHost in areaHosts) - { - var area = areaHost.GetScreenArea(); - var pos = areaHost.TransformFromDeviceDPI(mousePosition); - var b = area.Contains(pos); - - if (b) - { - return areaHost; - } - } - - return null; - } - - private void ActiveLastActivationOfPane(LayoutDocumentPane model) - { - if (model.Children.Count > 0) - { - var index = 0; - if (model.Children.Count > 1) - { - var tmTimeStamp = model.Children[0].LastActivationTimeStamp; - for (var i = 1; i < model.Children.Count; i++) - { - var item = model.Children[i]; - if (item.LastActivationTimeStamp > tmTimeStamp) - { - tmTimeStamp = item.LastActivationTimeStamp; - index = i; - } - } - } - - model.SelectedContentIndex = index; - } - } - - private void ActiveLastActivationOfItems(bool isActive) - { - var items = _model.Descendents().OfType().ToList(); - if (items.Count > 0) - { - var index = 0; - if (items.Count > 1) - { - var tmpTimeStamp2 = items[0].LastActivationTimeStamp; - for (var i = 1; i < items.Count; i++) - { - var item = items[i]; - if (item.LastActivationTimeStamp > tmpTimeStamp2) - { - tmpTimeStamp2 = item.LastActivationTimeStamp; - index = i; - } - } - } - - items[index].IsActive = isActive; - } - } - - private void ActiveOfMultiPane(bool isActive) - { - if (isActive) - { - var documentPane = FindDocumentPaneControlByMousePoint(); - if (documentPane != null) - { - var model = (LayoutDocumentPane)documentPane.Model; - if (model.SelectedContent != null) - { - model.SelectedContent.IsActive = true; - return; - } - else - { - ActiveLastActivationOfPane(model); - return; - } - } - } - ActiveLastActivationOfItems(isActive); - } - /// protected override IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { @@ -235,11 +124,11 @@ protected override IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, Int var isInactive = ((int)wParam & 0xFFFF) == Win32Helper.WA_INACTIVE; if (_model.IsSinglePane) { - ActiveOfSinglePane(!isInactive); + ActiveItemOfSinglePane(!isInactive); } else { - ActiveOfMultiPane(!isInactive); + ActiveItemOfMultiPane(!isInactive); } handled = true; @@ -543,6 +432,123 @@ private void OnExecuteCloseWindowCommand(object parameter) #endregion CloseWindowCommand + #region ActiveItem + + private void ActiveItemOfSinglePane(bool isActive) + { + var layoutDocumentPane = _model.Descendents().OfType() + .FirstOrDefault(p => p.ChildrenCount > 0 && p.SelectedContent != null); + + if (layoutDocumentPane != null) + { + layoutDocumentPane.SelectedContent.IsActive = isActive; + } + // When the floating tool window is mixed with the floating document window + // and the document pane in the floating document window is dragged out. + + // Only the Tool panes is left in the floating document window. + // The Children Count is greater than 0 and the Selected Content is null. + + // Then we only need to activate the last active content. + else + { + ActiveTheLastActivedItemOfItems(isActive); + } + } + + private LayoutDocumentPaneControl FindPaneControlByMousePoint() + { + var mousePosition = Win32Helper.GetMousePosition(); + var rootVisual = ((FloatingWindowContentHost)Content).RootVisual; + var areaHosts = rootVisual.FindVisualChildren(); + + foreach (var areaHost in areaHosts) + { + var rect = areaHost.GetScreenArea(); + var pos = areaHost.TransformFromDeviceDPI(mousePosition); + var b = rect.Contains(pos); + + if (b) + { + return areaHost; + } + } + + return null; + } + + private static void ActiveTheLastActivedItemOfPane(LayoutDocumentPane pane) + { + if (pane.Children.Count > 0) + { + var index = 0; + if (pane.Children.Count > 1) + { + var tmTimeStamp = pane.Children[0].LastActivationTimeStamp; + for (var i = 1; i < pane.Children.Count; i++) + { + var item = pane.Children[i]; + if (item.LastActivationTimeStamp > tmTimeStamp) + { + tmTimeStamp = item.LastActivationTimeStamp; + index = i; + } + } + } + + pane.SelectedContentIndex = index; + } + } + + private void ActiveTheLastActivedItemOfItems(bool isActive) + { + var items = _model.Descendents().OfType().ToList(); + if (items.Count > 0) + { + var index = 0; + if (items.Count > 1) + { + var tmpTimeStamp2 = items[0].LastActivationTimeStamp; + for (var i = 1; i < items.Count; i++) + { + var item = items[i]; + if (item.LastActivationTimeStamp > tmpTimeStamp2) + { + tmpTimeStamp2 = item.LastActivationTimeStamp; + index = i; + } + } + } + + items[index].IsActive = isActive; + } + } + + private void ActiveItemOfMultiPane(bool isActive) + { + if (isActive) + { + var documentPane = FindPaneControlByMousePoint(); + if (documentPane != null) + { + var model = (LayoutDocumentPane)documentPane.Model; + if (model.SelectedContent != null) + { + model.SelectedContent.IsActive = true; + return; + } + else + { + ActiveTheLastActivedItemOfPane(model); + return; + } + } + } + ActiveTheLastActivedItemOfItems(isActive); + } + + #endregion + #endregion Private Methods } } From b63b9668884dc4b910f4dfd77a40e177dcfd93cc Mon Sep 17 00:00:00 2001 From: Noisrev Date: Thu, 12 Jan 2023 23:01:28 +0800 Subject: [PATCH 05/18] Fix types and variable names --- .../LayoutAnchorableFloatingWindowControl.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs index 381b755a..84743360 100644 --- a/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs @@ -437,12 +437,12 @@ private void OnExecuteCloseWindowCommand(object parameter) private void ActiveItemOfSinglePane(bool isActive) { - var layoutDocumentPane = _model.Descendents().OfType() + var layoutAnchorablePane = _model.Descendents().OfType() .FirstOrDefault(p => p.ChildrenCount > 0 && p.SelectedContent != null); - if (layoutDocumentPane != null) + if (layoutAnchorablePane != null) { - layoutDocumentPane.SelectedContent.IsActive = isActive; + layoutAnchorablePane.SelectedContent.IsActive = isActive; } // When the floating tool window is mixed with the floating document window // and the document pane in the floating document window is dragged out. @@ -529,10 +529,10 @@ private void ActiveItemOfMultiPane(bool isActive) { if (isActive) { - var documentPane = FindPaneControlByMousePoint(); - if (documentPane != null) + var anchorablePane = FindPaneControlByMousePoint(); + if (anchorablePane != null) { - var model = (LayoutAnchorablePane)documentPane.Model; + var model = (LayoutAnchorablePane)anchorablePane.Model; if (model.SelectedContent != null) { model.SelectedContent.IsActive = true; From fa58dfe01aeb1c963ee61d6f5acd82d9560d25c1 Mon Sep 17 00:00:00 2001 From: Noisrev Date: Fri, 13 Jan 2023 00:17:23 +0800 Subject: [PATCH 06/18] Improve and optimize the active item handlers --- .../LayoutAnchorableFloatingWindowControl.cs | 86 ++------------ .../LayoutDocumentFloatingWindowControl.cs | 88 ++------------ .../Controls/LayoutFloatingWindowControl.cs | 108 +++++++++++++++--- 3 files changed, 108 insertions(+), 174 deletions(-) diff --git a/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs index 84743360..29ec53a9 100644 --- a/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs @@ -435,14 +435,14 @@ private void OnExecuteCloseWindowCommand(object parameter) #region ActiveItem - private void ActiveItemOfSinglePane(bool isActive) + internal void ActiveItemOfSinglePane(bool isActive) { - var layoutAnchorablePane = _model.Descendents().OfType() + var pane = _model.Descendents().OfType() .FirstOrDefault(p => p.ChildrenCount > 0 && p.SelectedContent != null); - if (layoutAnchorablePane != null) + if (pane != null) { - layoutAnchorablePane.SelectedContent.IsActive = isActive; + pane.SelectedContent.IsActive = isActive; } // When the floating tool window is mixed with the floating document window // and the document pane in the floating document window is dragged out. @@ -457,82 +457,14 @@ private void ActiveItemOfSinglePane(bool isActive) } } - private LayoutAnchorablePaneControl FindPaneControlByMousePoint() - { - var mousePosition = Win32Helper.GetMousePosition(); - var rootVisual = ((FloatingWindowContentHost)Content).RootVisual; - var areaHosts = rootVisual.FindVisualChildren(); - - foreach (var areaHost in areaHosts) - { - var rect = areaHost.GetScreenArea(); - var pos = areaHost.TransformFromDeviceDPI(mousePosition); - var b = rect.Contains(pos); - - if (b) - { - return areaHost; - } - } - - return null; - } - - private static void ActiveTheLastActivedItemOfPane(LayoutAnchorablePane pane) - { - if (pane.Children.Count > 0) - { - var index = 0; - if (pane.Children.Count > 1) - { - var tmTimeStamp = pane.Children[0].LastActivationTimeStamp; - for (var i = 1; i < pane.Children.Count; i++) - { - var item = pane.Children[i]; - if (item.LastActivationTimeStamp > tmTimeStamp) - { - tmTimeStamp = item.LastActivationTimeStamp; - index = i; - } - } - } - - pane.SelectedContentIndex = index; - } - } - - private void ActiveTheLastActivedItemOfItems(bool isActive) - { - var items = _model.Descendents().OfType().ToList(); - if (items.Count > 0) - { - var index = 0; - if (items.Count > 1) - { - var tmpTimeStamp2 = items[0].LastActivationTimeStamp; - for (var i = 1; i < items.Count; i++) - { - var item = items[i]; - if (item.LastActivationTimeStamp > tmpTimeStamp2) - { - tmpTimeStamp2 = item.LastActivationTimeStamp; - index = i; - } - } - } - - items[index].IsActive = isActive; - } - } - - private void ActiveItemOfMultiPane(bool isActive) + internal void ActiveItemOfMultiPane(bool isActive) { if (isActive) { - var anchorablePane = FindPaneControlByMousePoint(); - if (anchorablePane != null) + var paneControl = FindPaneControlByMousePoint(); + if (paneControl != null) { - var model = (LayoutAnchorablePane)anchorablePane.Model; + var model = (LayoutAnchorablePane)paneControl.Model; if (model.SelectedContent != null) { model.SelectedContent.IsActive = true; @@ -540,7 +472,7 @@ private void ActiveItemOfMultiPane(bool isActive) } else { - ActiveTheLastActivedItemOfPane(model); + ActiveTheLastActivedItemOfPane(model); return; } } diff --git a/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs index baa4ce29..18fada33 100644 --- a/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs @@ -434,14 +434,14 @@ private void OnExecuteCloseWindowCommand(object parameter) #region ActiveItem - private void ActiveItemOfSinglePane(bool isActive) + internal void ActiveItemOfSinglePane(bool isActive) { - var layoutDocumentPane = _model.Descendents().OfType() + var pane = _model.Descendents().OfType() .FirstOrDefault(p => p.ChildrenCount > 0 && p.SelectedContent != null); - if (layoutDocumentPane != null) + if (pane != null) { - layoutDocumentPane.SelectedContent.IsActive = isActive; + pane.SelectedContent.IsActive = isActive; } // When the floating tool window is mixed with the floating document window // and the document pane in the floating document window is dragged out. @@ -456,82 +456,14 @@ private void ActiveItemOfSinglePane(bool isActive) } } - private LayoutDocumentPaneControl FindPaneControlByMousePoint() - { - var mousePosition = Win32Helper.GetMousePosition(); - var rootVisual = ((FloatingWindowContentHost)Content).RootVisual; - var areaHosts = rootVisual.FindVisualChildren(); - - foreach (var areaHost in areaHosts) - { - var rect = areaHost.GetScreenArea(); - var pos = areaHost.TransformFromDeviceDPI(mousePosition); - var b = rect.Contains(pos); - - if (b) - { - return areaHost; - } - } - - return null; - } - - private static void ActiveTheLastActivedItemOfPane(LayoutDocumentPane pane) - { - if (pane.Children.Count > 0) - { - var index = 0; - if (pane.Children.Count > 1) - { - var tmTimeStamp = pane.Children[0].LastActivationTimeStamp; - for (var i = 1; i < pane.Children.Count; i++) - { - var item = pane.Children[i]; - if (item.LastActivationTimeStamp > tmTimeStamp) - { - tmTimeStamp = item.LastActivationTimeStamp; - index = i; - } - } - } - - pane.SelectedContentIndex = index; - } - } - - private void ActiveTheLastActivedItemOfItems(bool isActive) - { - var items = _model.Descendents().OfType().ToList(); - if (items.Count > 0) - { - var index = 0; - if (items.Count > 1) - { - var tmpTimeStamp2 = items[0].LastActivationTimeStamp; - for (var i = 1; i < items.Count; i++) - { - var item = items[i]; - if (item.LastActivationTimeStamp > tmpTimeStamp2) - { - tmpTimeStamp2 = item.LastActivationTimeStamp; - index = i; - } - } - } - - items[index].IsActive = isActive; - } - } - - private void ActiveItemOfMultiPane(bool isActive) + internal void ActiveItemOfMultiPane(bool isActive) { if (isActive) { - var documentPane = FindPaneControlByMousePoint(); - if (documentPane != null) + var paneControl = FindPaneControlByMousePoint(); + if (paneControl != null) { - var model = (LayoutDocumentPane)documentPane.Model; + var model = (LayoutDocumentPane)paneControl.Model; if (model.SelectedContent != null) { model.SelectedContent.IsActive = true; @@ -539,7 +471,7 @@ private void ActiveItemOfMultiPane(bool isActive) } else { - ActiveTheLastActivedItemOfPane(model); + ActiveTheLastActivedItemOfPane(model); return; } } @@ -547,7 +479,7 @@ private void ActiveItemOfMultiPane(bool isActive) ActiveTheLastActivedItemOfItems(isActive); } - #endregion + #endregion ActiveItem #endregion Private Methods } diff --git a/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs index c1377a92..fdc308d8 100644 --- a/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs @@ -7,8 +7,6 @@ This program is provided to you under the terms of the Microsoft Public License (Ms-PL) as published at https://opensource.org/licenses/MS-PL ************************************************************************/ -using AvalonDock.Layout; -using AvalonDock.Themes; using System; using System.ComponentModel; using System.Linq; @@ -22,6 +20,9 @@ This program is provided to you under the terms of the Microsoft Public using System.Windows.Interop; using System.Windows.Media; +using AvalonDock.Layout; +using AvalonDock.Themes; + namespace AvalonDock.Controls { /// @@ -52,7 +53,7 @@ public abstract class LayoutFloatingWindowControl : Window, ILayoutControl /// /// private bool _isTotalMarginSet = false; - + #endregion fields #region Constructors @@ -491,6 +492,75 @@ internal void InternalClose(bool closeInitiatedByUser = false) Close(); } + internal T FindPaneControlByMousePoint() where T : FrameworkElement, ILayoutControl + { + var mousePosition = this.PointToScreenDPI(Mouse.GetPosition(this)); + var rootVisual = ((FloatingWindowContentHost)Content).RootVisual; + var areaHosts = rootVisual.FindVisualChildren(); + + foreach (var areaHost in areaHosts) + { + var rect = areaHost.GetScreenArea(); + var b = rect.Contains(mousePosition); + + if (b) + { + return areaHost; + } + } + + return null; + } + + internal void ActiveTheLastActivedItemOfItems(bool isActive) + { + var items = _model.Descendents().OfType().ToList(); + if (items.Count > 0) + { + var index = 0; + if (items.Count > 1) + { + var tmpTimeStamp2 = items[0].LastActivationTimeStamp; + for (var i = 1; i < items.Count; i++) + { + var item = items[i]; + if (item.LastActivationTimeStamp > tmpTimeStamp2) + { + tmpTimeStamp2 = item.LastActivationTimeStamp; + index = i; + } + } + } + + items[index].IsActive = isActive; + } + } + + internal static void ActiveTheLastActivedItemOfPane(TPane pane) + where TPane : LayoutPositionableGroup, ILayoutContentSelector + where TChild : LayoutContent + { + if (pane.Children.Count > 0) + { + var index = 0; + if (pane.Children.Count > 1) + { + var tmTimeStamp = pane.Children[0].LastActivationTimeStamp; + for (var i = 1; i < pane.Children.Count; i++) + { + var item = pane.Children[i]; + if (item.LastActivationTimeStamp > tmTimeStamp) + { + tmTimeStamp = item.LastActivationTimeStamp; + index = i; + } + } + } + + pane.SelectedContentIndex = index; + } + } + #endregion Internal Methods #region Overrides @@ -528,24 +598,24 @@ protected override void OnInitialized(EventArgs e) } protected override void OnClosing(CancelEventArgs e) - { - base.OnClosing(e); - AssureOwnerIsNotMinimized(); - } + { + base.OnClosing(e); + AssureOwnerIsNotMinimized(); + } - /// + /// /// Prevents a known bug in WPF, which wronlgy minimizes the parent window, when closing this control - /// - private void AssureOwnerIsNotMinimized() - { - try - { - Owner?.Activate(); - } - catch (Exception) - { - } - } + /// + private void AssureOwnerIsNotMinimized() + { + try + { + Owner?.Activate(); + } + catch (Exception) + { + } + } #endregion Overrides From ce7de8d94ab28e6dc364fb7717f72ca0a7cec026 Mon Sep 17 00:00:00 2001 From: Noisrev Date: Tue, 24 Jan 2023 22:02:58 +0800 Subject: [PATCH 07/18] Improve and optimize the codes of active content for floating windows * Remove the codes of active content in the floating windows * Add a common class LayoutFloatingWindowControlHelper for active/inactive the content when floating window is active or inactive --- .../LayoutAnchorableFloatingWindowControl.cs | 53 +----- .../LayoutDocumentFloatingWindowControl.cs | 53 +----- .../Controls/LayoutFloatingWindowControl.cs | 69 ------- .../LayoutFloatingWindowControlHelper.cs | 172 ++++++++++++++++++ 4 files changed, 176 insertions(+), 171 deletions(-) create mode 100644 source/Components/AvalonDock/Controls/LayoutFloatingWindowControlHelper.cs diff --git a/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs index 29ec53a9..16551443 100644 --- a/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs @@ -249,11 +249,11 @@ protected override IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, Int var isInactive = ((int)wParam & 0xFFFF) == Win32Helper.WA_INACTIVE; if (_model.IsSinglePane) { - ActiveItemOfSinglePane(!isInactive); + LayoutFloatingWindowControlHelper.ActiveTheContentOfSinglePane(this, !isInactive); } else { - ActiveItemOfMultiPane(!isInactive); + LayoutFloatingWindowControlHelper.ActiveTheContentOfMultiPane(this, !isInactive); } handled = true; @@ -433,55 +433,6 @@ private void OnExecuteCloseWindowCommand(object parameter) #endregion CloseWindowCommand - #region ActiveItem - - internal void ActiveItemOfSinglePane(bool isActive) - { - var pane = _model.Descendents().OfType() - .FirstOrDefault(p => p.ChildrenCount > 0 && p.SelectedContent != null); - - if (pane != null) - { - pane.SelectedContent.IsActive = isActive; - } - // When the floating tool window is mixed with the floating document window - // and the document pane in the floating document window is dragged out. - - // Only the Tool panes is left in the floating document window. - // The Children Count is greater than 0 and the Selected Content is null. - - // Then we only need to activate the last active content. - else - { - ActiveTheLastActivedItemOfItems(isActive); - } - } - - internal void ActiveItemOfMultiPane(bool isActive) - { - if (isActive) - { - var paneControl = FindPaneControlByMousePoint(); - if (paneControl != null) - { - var model = (LayoutAnchorablePane)paneControl.Model; - if (model.SelectedContent != null) - { - model.SelectedContent.IsActive = true; - return; - } - else - { - ActiveTheLastActivedItemOfPane(model); - return; - } - } - } - ActiveTheLastActivedItemOfItems(isActive); - } - - #endregion ActiveItem - #endregion Private Methods } } diff --git a/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs index 18fada33..44bb0a79 100644 --- a/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs @@ -124,11 +124,11 @@ protected override IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, Int var isInactive = ((int)wParam & 0xFFFF) == Win32Helper.WA_INACTIVE; if (_model.IsSinglePane) { - ActiveItemOfSinglePane(!isInactive); + LayoutFloatingWindowControlHelper.ActiveTheContentOfSinglePane(this, !isInactive); } else { - ActiveItemOfMultiPane(!isInactive); + LayoutFloatingWindowControlHelper.ActiveTheContentOfMultiPane(this, !isInactive); } handled = true; @@ -432,55 +432,6 @@ private void OnExecuteCloseWindowCommand(object parameter) #endregion CloseWindowCommand - #region ActiveItem - - internal void ActiveItemOfSinglePane(bool isActive) - { - var pane = _model.Descendents().OfType() - .FirstOrDefault(p => p.ChildrenCount > 0 && p.SelectedContent != null); - - if (pane != null) - { - pane.SelectedContent.IsActive = isActive; - } - // When the floating tool window is mixed with the floating document window - // and the document pane in the floating document window is dragged out. - - // Only the Tool panes is left in the floating document window. - // The Children Count is greater than 0 and the Selected Content is null. - - // Then we only need to activate the last active content. - else - { - ActiveTheLastActivedItemOfItems(isActive); - } - } - - internal void ActiveItemOfMultiPane(bool isActive) - { - if (isActive) - { - var paneControl = FindPaneControlByMousePoint(); - if (paneControl != null) - { - var model = (LayoutDocumentPane)paneControl.Model; - if (model.SelectedContent != null) - { - model.SelectedContent.IsActive = true; - return; - } - else - { - ActiveTheLastActivedItemOfPane(model); - return; - } - } - } - ActiveTheLastActivedItemOfItems(isActive); - } - - #endregion ActiveItem - #endregion Private Methods } } diff --git a/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs index fdc308d8..c7af3acf 100644 --- a/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs @@ -492,75 +492,6 @@ internal void InternalClose(bool closeInitiatedByUser = false) Close(); } - internal T FindPaneControlByMousePoint() where T : FrameworkElement, ILayoutControl - { - var mousePosition = this.PointToScreenDPI(Mouse.GetPosition(this)); - var rootVisual = ((FloatingWindowContentHost)Content).RootVisual; - var areaHosts = rootVisual.FindVisualChildren(); - - foreach (var areaHost in areaHosts) - { - var rect = areaHost.GetScreenArea(); - var b = rect.Contains(mousePosition); - - if (b) - { - return areaHost; - } - } - - return null; - } - - internal void ActiveTheLastActivedItemOfItems(bool isActive) - { - var items = _model.Descendents().OfType().ToList(); - if (items.Count > 0) - { - var index = 0; - if (items.Count > 1) - { - var tmpTimeStamp2 = items[0].LastActivationTimeStamp; - for (var i = 1; i < items.Count; i++) - { - var item = items[i]; - if (item.LastActivationTimeStamp > tmpTimeStamp2) - { - tmpTimeStamp2 = item.LastActivationTimeStamp; - index = i; - } - } - } - - items[index].IsActive = isActive; - } - } - - internal static void ActiveTheLastActivedItemOfPane(TPane pane) - where TPane : LayoutPositionableGroup, ILayoutContentSelector - where TChild : LayoutContent - { - if (pane.Children.Count > 0) - { - var index = 0; - if (pane.Children.Count > 1) - { - var tmTimeStamp = pane.Children[0].LastActivationTimeStamp; - for (var i = 1; i < pane.Children.Count; i++) - { - var item = pane.Children[i]; - if (item.LastActivationTimeStamp > tmTimeStamp) - { - tmTimeStamp = item.LastActivationTimeStamp; - index = i; - } - } - } - - pane.SelectedContentIndex = index; - } - } - #endregion Internal Methods #region Overrides diff --git a/source/Components/AvalonDock/Controls/LayoutFloatingWindowControlHelper.cs b/source/Components/AvalonDock/Controls/LayoutFloatingWindowControlHelper.cs new file mode 100644 index 00000000..ca2a0c0c --- /dev/null +++ b/source/Components/AvalonDock/Controls/LayoutFloatingWindowControlHelper.cs @@ -0,0 +1,172 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows; +using System.Windows.Input; + +using AvalonDock.Layout; + + +namespace AvalonDock.Controls +{ + internal static class LayoutFloatingWindowControlHelper + { + private const string Excp_NotSupportedFloatingWindowType = "Not Supported Floating Window Type: {0}"; + + public static void ActiveTheContentOfSinglePane(T fwc, bool isActive) where T : LayoutFloatingWindowControl + { + ILayoutContentSelector selector = null; + if (fwc is LayoutAnchorableFloatingWindowControl) + { + selector = fwc.Model + .Descendents() + .OfType() + .FirstOrDefault(p => p.ChildrenCount > 0 && p.SelectedContent != null); + } + else if (fwc is LayoutDocumentFloatingWindowControl) + { + selector = fwc.Model + .Descendents() + .OfType() + .FirstOrDefault(p => p.ChildrenCount > 0 && p.SelectedContent != null); + } + else + { + throw new NotSupportedException(string.Format(Excp_NotSupportedFloatingWindowType, fwc.GetType())); + } + + if (selector != null) + { + selector.SelectedContent.IsActive = isActive; + } + else + { + // When the floating tool window is mixed with the floating document window + // and the document pane in the floating document window is dragged out. + + // Only the Tool panes is left in the floating document window. + // The Children Count is greater than 0 and the Selected Content is null. + + // Then we only need to activate the last active content. + ActiveTheLastActivedContent(fwc, isActive); + } + } + + public static void ActiveTheContentOfMultiPane(T fwc, bool isActive) where T : LayoutFloatingWindowControl + { + if (isActive) + { + if (fwc is LayoutAnchorableFloatingWindowControl) + { + var paneControl = GetLayoutControlByMousePosition(fwc); + if (paneControl != null && paneControl.Model is LayoutAnchorablePane pane) + { + if (pane.SelectedContent != null) + pane.SelectedContent.IsActive = true; + else + ActiveTheLastActivedContentOfPane(pane); + + return; + } + } + else if (fwc is LayoutDocumentFloatingWindowControl) + { + var paneControl = GetLayoutControlByMousePosition(fwc); + if (paneControl != null && paneControl.Model is LayoutDocumentPane pane) + { + if (pane.SelectedContent != null) + pane.SelectedContent.IsActive = true; + else + ActiveTheLastActivedContentOfPane(pane); + + return; + } + } + else + { + throw new NotSupportedException(string.Format(Excp_NotSupportedFloatingWindowType, fwc.GetType())); + } + } + + ActiveTheLastActivedContent(fwc, isActive); + } + + public static void ActiveTheLastActivedContent(LayoutFloatingWindowControl fwc, bool isActive) + { + var items = fwc.Model.Descendents().OfType().ToList(); + var index = IndexOfLastActivedContent(items); + if (index != -1) + { + items[index].IsActive = isActive; + } + } + + public static void ActiveTheLastActivedContentOfPane(LayoutAnchorablePane anchorablePane) + { + var index = IndexOfLastActivedContent(anchorablePane.Children); + if (index != -1) + { + anchorablePane.SelectedContentIndex = index; + if (!anchorablePane.SelectedContent.IsActive) + { + anchorablePane.SelectedContent.IsActive = true; + } + } + } + + public static void ActiveTheLastActivedContentOfPane(LayoutDocumentPane documentPane) + { + var index = IndexOfLastActivedContent(documentPane.Children); + if (index != -1) + { + documentPane.SelectedContentIndex = index; + if (!documentPane.SelectedContent.IsActive) + { + documentPane.SelectedContent.IsActive = true; + } + } + } + + private static T GetLayoutControlByMousePosition(LayoutFloatingWindowControl fwc) where T : FrameworkElement, ILayoutControl + { + var mousePosition = fwc.PointToScreenDPI(Mouse.GetPosition(fwc)); + var rootVisual = ((LayoutFloatingWindowControl.FloatingWindowContentHost)fwc.Content).RootVisual; + + foreach (var areaHost in rootVisual.FindVisualChildren()) + { + var rect = areaHost.GetScreenArea(); + if (rect.Contains(mousePosition)) + { + return areaHost; + } + } + + return null; + } + + private static int IndexOfLastActivedContent(IList list) where T : LayoutContent + { + if (list.Count > 0) + { + var index = 0; + if (list.Count > 1) + { + var tmpTimeStamp = list[0].LastActivationTimeStamp; + for (var i = 1; i < list.Count; i++) + { + var item = list[i]; + if (item.LastActivationTimeStamp > tmpTimeStamp) + { + tmpTimeStamp = item.LastActivationTimeStamp; + index = i; + } + } + } + + return index; + } + + return -1; + } + } +} From 58ec1364f24e3d8b1e52466e25335c612f6e26cd Mon Sep 17 00:00:00 2001 From: Dirkster99 Date: Sun, 29 Jan 2023 18:04:17 +0100 Subject: [PATCH 08/18] AvalonDock Version 4.71.2 --- README.md | 8 ++++++++ .../AvalonDock.Themes.Aero.csproj | 10 +++++----- .../AvalonDock.Themes.Expression.csproj | 10 +++++----- .../AvalonDock.Themes.Metro.csproj | 12 ++++++------ .../AvalonDock.Themes.VS2010.csproj | 10 +++++----- .../AvalonDock.Themes.VS2013.csproj | 12 ++++++------ source/Components/AvalonDock/AvalonDock.csproj | 10 +++++----- 7 files changed, 40 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 64e7077a..3475f69b 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,14 @@ to also theme standard elements, such as, button and textblock etc. # Mile Stone History +## Fixes Added in Version 4.71.2 + +- [#416 Fix Issue #226: Restore floating windows to maximized state](https://github.com/Dirkster99/AvalonDock/pull/416) (thanx to [Michael Möller](https://github.com/moellerm)) + +- [#417 Close and active selected item when NavigatorWindow is inactive](https://github.com/Dirkster99/AvalonDock/pull/417) (thanx to [EQOH Noisrev](https://github.com/Noisrev)) + +- [#418 Add active content handler to LayoutAnchorableFloatingWindow and improve the active content handlers](https://github.com/Dirkster99/AvalonDock/pull/418) (thanx to [EQOH Noisrev](https://github.com/Noisrev)) + ## Fixes Added in Version 4.71.1 - [#413 Fix the binding error in AnchorGroupTemplate](https://github.com/Dirkster99/AvalonDock/pull/413) (thanx to [EQOH Noisrev](https://github.com/Noisrev)) diff --git a/source/Components/AvalonDock.Themes.Aero/AvalonDock.Themes.Aero.csproj b/source/Components/AvalonDock.Themes.Aero/AvalonDock.Themes.Aero.csproj index 8d4440b2..9ecdd743 100644 --- a/source/Components/AvalonDock.Themes.Aero/AvalonDock.Themes.Aero.csproj +++ b/source/Components/AvalonDock.Themes.Aero/AvalonDock.Themes.Aero.csproj @@ -6,13 +6,13 @@ sn.snk true true - 4.71.1 - 4.71.1 - 4.71.1 - 4.71.1 + 4.71.2 + 4.71.2 + 4.71.2 + 4.71.2 Open Source Dirkster.AvalonDock - 2017-2022 + 2017-2023 This assembly implements a docking layout system for WPF. https://github.com/Dirkster99/AvalonDock https://github.com/Dirkster99/AvalonDock diff --git a/source/Components/AvalonDock.Themes.Expression/AvalonDock.Themes.Expression.csproj b/source/Components/AvalonDock.Themes.Expression/AvalonDock.Themes.Expression.csproj index 5246ad64..ecbb0b0c 100644 --- a/source/Components/AvalonDock.Themes.Expression/AvalonDock.Themes.Expression.csproj +++ b/source/Components/AvalonDock.Themes.Expression/AvalonDock.Themes.Expression.csproj @@ -6,13 +6,13 @@ sn.snk true true - 4.71.1 - 4.71.1 - 4.71.1 - 4.71.1 + 4.71.2 + 4.71.2 + 4.71.2 + 4.71.2 Open Source Dirkster.AvalonDock - 2017-2022 + 2017-2023 This assembly implements a docking layout system for WPF. https://github.com/Dirkster99/AvalonDock https://github.com/Dirkster99/AvalonDock diff --git a/source/Components/AvalonDock.Themes.Metro/AvalonDock.Themes.Metro.csproj b/source/Components/AvalonDock.Themes.Metro/AvalonDock.Themes.Metro.csproj index 2283819a..9db59365 100644 --- a/source/Components/AvalonDock.Themes.Metro/AvalonDock.Themes.Metro.csproj +++ b/source/Components/AvalonDock.Themes.Metro/AvalonDock.Themes.Metro.csproj @@ -1,4 +1,4 @@ - + AvalonDock.Themes netcoreapp3.0;net5.0-windows;net40 @@ -6,13 +6,13 @@ sn.snk true true - 4.71.1 - 4.71.1 - 4.71.1 - 4.71.1 + 4.71.2 + 4.71.2 + 4.71.2 + 4.71.2 Open Source Dirkster.AvalonDock - 2017-2022 + 2017-2023 This assembly implements a docking layout system for WPF. https://github.com/Dirkster99/AvalonDock https://github.com/Dirkster99/AvalonDock diff --git a/source/Components/AvalonDock.Themes.VS2010/AvalonDock.Themes.VS2010.csproj b/source/Components/AvalonDock.Themes.VS2010/AvalonDock.Themes.VS2010.csproj index c16829a1..9251dd1d 100644 --- a/source/Components/AvalonDock.Themes.VS2010/AvalonDock.Themes.VS2010.csproj +++ b/source/Components/AvalonDock.Themes.VS2010/AvalonDock.Themes.VS2010.csproj @@ -6,13 +6,13 @@ sn.snk true true - 4.71.1 - 4.71.1 - 4.71.1 - 4.71.1 + 4.71.2 + 4.71.2 + 4.71.2 + 4.71.2 Open Source Dirkster.AvalonDock - 2017-2022 + 2017-2023 This assembly implements a docking layout system for WPF. https://github.com/Dirkster99/AvalonDock https://github.com/Dirkster99/AvalonDock diff --git a/source/Components/AvalonDock.Themes.VS2013/AvalonDock.Themes.VS2013.csproj b/source/Components/AvalonDock.Themes.VS2013/AvalonDock.Themes.VS2013.csproj index e62f5075..98ae0c52 100644 --- a/source/Components/AvalonDock.Themes.VS2013/AvalonDock.Themes.VS2013.csproj +++ b/source/Components/AvalonDock.Themes.VS2013/AvalonDock.Themes.VS2013.csproj @@ -1,4 +1,4 @@ - + AvalonDock.Themes netcoreapp3.0;net5.0-windows;net40 @@ -6,13 +6,13 @@ sn.snk true true - 4.71.1 - 4.71.1 - 4.71.1 - 4.71.1 + 4.71.2 + 4.71.2 + 4.71.2 + 4.71.2 Open Source Dirkster.AvalonDock - 2017-2022 + 2017-2023 This assembly implements a docking layout system for WPF. https://github.com/Dirkster99/AvalonDock https://github.com/Dirkster99/AvalonDock diff --git a/source/Components/AvalonDock/AvalonDock.csproj b/source/Components/AvalonDock/AvalonDock.csproj index f664aef8..72fdf0bd 100644 --- a/source/Components/AvalonDock/AvalonDock.csproj +++ b/source/Components/AvalonDock/AvalonDock.csproj @@ -6,13 +6,13 @@ true sn.snk true - 4.71.1 - 4.71.1 - 4.71.1 - 4.71.1 + 4.71.2 + 4.71.2 + 4.71.2 + 4.71.2 Open Source Dirkster.AvalonDock - 2017-2022 + 2017-2023 This assembly implements a docking layout system for WPF. https://github.com/Dirkster99/AvalonDock https://github.com/Dirkster99/AvalonDock From 3ccbfe8f3bb2f1350e4fe5c3479d19562c3bca60 Mon Sep 17 00:00:00 2001 From: Mona04 Date: Sat, 4 Feb 2023 02:39:03 +0900 Subject: [PATCH 09/18] issue #422 --- source/Components/AvalonDock/Themes/generic.xaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source/Components/AvalonDock/Themes/generic.xaml b/source/Components/AvalonDock/Themes/generic.xaml index 68df206a..b3588682 100644 --- a/source/Components/AvalonDock/Themes/generic.xaml +++ b/source/Components/AvalonDock/Themes/generic.xaml @@ -758,9 +758,7 @@ BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> + Content="{Binding LayoutItem.View, RelativeSource={RelativeSource TemplatedParent}}" /> From d43c7c6996af1304079352e85edc3f0d25cfd981 Mon Sep 17 00:00:00 2001 From: Khaos Date: Thu, 9 Feb 2023 10:46:54 +0100 Subject: [PATCH 10/18] Fix: potential NRE on close --- source/Components/AvalonDock/DockingManager.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/Components/AvalonDock/DockingManager.cs b/source/Components/AvalonDock/DockingManager.cs index a6a396d5..232dca16 100644 --- a/source/Components/AvalonDock/DockingManager.cs +++ b/source/Components/AvalonDock/DockingManager.cs @@ -1138,7 +1138,7 @@ public double GridSplitterHeight new FrameworkPropertyMetadata((Style)null)); /// - /// Gets or sets the GridSplitterVerticalStyle property. This dependency property + /// Gets or sets the GridSplitterVerticalStyle property. This dependency property /// indicates the style to apply to the LayoutGridResizerControl when displayed vertically. /// public Style GridSplitterVerticalStyle @@ -1164,7 +1164,7 @@ public Style GridSplitterVerticalStyle new FrameworkPropertyMetadata((Style)null)); /// - /// Gets or sets the GridSplitterHorizontalStyle property. This dependency property + /// Gets or sets the GridSplitterHorizontalStyle property. This dependency property /// indicates the style to apply to the LayoutGridResizerControl when displayed horizontally. /// public Style GridSplitterHorizontalStyle @@ -2292,7 +2292,7 @@ private void DocumentsSourceElementsChanged(object sender, NotifyCollectionChang foreach (var documentToRemove in documentsToRemove) { documentToRemove.Content = null; - documentToRemove.Parent.RemoveChild(documentToRemove); + documentToRemove.Parent?.RemoveChild(documentToRemove); RemoveViewFromLogicalChild(documentToRemove); } } @@ -2354,7 +2354,7 @@ private void DocumentsSourceElementsChanged(object sender, NotifyCollectionChang var documentsToRemove = GetItemsToRemoveAfterReset(DocumentsSource); foreach (var documentToRemove in documentsToRemove) { - (documentToRemove.Parent as ILayoutContainer).RemoveChild( + (documentToRemove.Parent as ILayoutContainer)?.RemoveChild( documentToRemove); RemoveViewFromLogicalChild(documentToRemove); } From e30352f789de9861a53962f1031b5f99df4d7973 Mon Sep 17 00:00:00 2001 From: Khaos Date: Thu, 9 Feb 2023 15:33:53 +0100 Subject: [PATCH 11/18] Fix floating windows still created twice --- source/Components/AvalonDock/DockingManager.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/source/Components/AvalonDock/DockingManager.cs b/source/Components/AvalonDock/DockingManager.cs index a6a396d5..be5a9df1 100644 --- a/source/Components/AvalonDock/DockingManager.cs +++ b/source/Components/AvalonDock/DockingManager.cs @@ -1138,7 +1138,7 @@ public double GridSplitterHeight new FrameworkPropertyMetadata((Style)null)); /// - /// Gets or sets the GridSplitterVerticalStyle property. This dependency property + /// Gets or sets the GridSplitterVerticalStyle property. This dependency property /// indicates the style to apply to the LayoutGridResizerControl when displayed vertically. /// public Style GridSplitterVerticalStyle @@ -1164,7 +1164,7 @@ public Style GridSplitterVerticalStyle new FrameworkPropertyMetadata((Style)null)); /// - /// Gets or sets the GridSplitterHorizontalStyle property. This dependency property + /// Gets or sets the GridSplitterHorizontalStyle property. This dependency property /// indicates the style to apply to the LayoutGridResizerControl when displayed horizontally. /// public Style GridSplitterHorizontalStyle @@ -2125,9 +2125,8 @@ private void DockingManager_Loaded(object sender, RoutedEventArgs e) } _fwHiddenList.Clear(); - // load floating windows not already loaded! (issue #59 & #254) - var items = new List(Layout.FloatingWindows.Where(fw => !_fwList.Any(fwc => fwc.Model == fw))); - foreach (var fw in items) + // load floating windows not already loaded! (issue #59 & #254 & #426) + foreach (var fw in Layout.FloatingWindows.Where(fw => !_fwList.Any(fwc => fwc.Model == fw))) CreateUIElementForModel(fw); //create the overlaywindow if it's possible From 02fa07044dfa5f474351a29930eb64ca87b53467 Mon Sep 17 00:00:00 2001 From: Calum Robinson Date: Thu, 16 Feb 2023 08:06:11 +0000 Subject: [PATCH 12/18] Add DockingManager.ShowNavigator --- source/Components/AvalonDock/DockingManager.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/source/Components/AvalonDock/DockingManager.cs b/source/Components/AvalonDock/DockingManager.cs index a6a396d5..6d2bb7d0 100644 --- a/source/Components/AvalonDock/DockingManager.cs +++ b/source/Components/AvalonDock/DockingManager.cs @@ -1383,6 +1383,22 @@ public bool AutoWindowSizeWhenOpened #endregion AutoWindowSizeWhenOpened + #region ShowNavigator + + /// dependency property. + public static readonly DependencyProperty ShowNavigatorProperty = DependencyProperty.Register(nameof(ShowNavigator), typeof(bool), typeof(DockingManager), + new FrameworkPropertyMetadata(true)); + + /// Gets/sets whether the navigator window should be shown when the user presses Control + Tab. + [Bindable(true), Description("Gets/sets whether floating windows should show the system menu when a custom context menu is not defined."), Category("FloatingWindow")] + public bool ShowNavigator + { + get => (bool)GetValue(ShowNavigatorProperty); + set => SetValue(ShowNavigatorProperty, value); + } + + #endregion ShowNavigator + #endregion Public Properties #region LogicalChildren @@ -1428,7 +1444,7 @@ private void ClearLogicalChildrenList() private bool IsNavigatorWindowActive => _navigatorWindow != null; - private bool CanShowNavigatorWindow => _layoutItems.Any(); + private bool CanShowNavigatorWindow => ShowNavigator && _layoutItems.Any(); #endregion Private Properties From a48e6897b4ad12ed61eeec84b8a31563806db7cc Mon Sep 17 00:00:00 2001 From: Roy Zwart Date: Fri, 17 Mar 2023 16:05:37 +0100 Subject: [PATCH 13/18] Fix unwanted group orientation change when using mixed orientation --- .../Controls/DocumentPaneDropTarget.cs | 41 +++++++++++++------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/source/Components/AvalonDock/Controls/DocumentPaneDropTarget.cs b/source/Components/AvalonDock/Controls/DocumentPaneDropTarget.cs index 49613e77..a404196e 100644 --- a/source/Components/AvalonDock/Controls/DocumentPaneDropTarget.cs +++ b/source/Components/AvalonDock/Controls/DocumentPaneDropTarget.cs @@ -74,18 +74,21 @@ internal DocumentPaneDropTarget(LayoutDocumentPaneControl paneControl, /// protected override void Drop(LayoutDocumentFloatingWindow floatingWindow) { - ILayoutDocumentPane targetModel = _targetPane.Model as ILayoutDocumentPane; - LayoutDocument documentActive = floatingWindow.Descendents().OfType().FirstOrDefault(); + var targetModel = (ILayoutDocumentPane)_targetPane.Model; + var documentActive = floatingWindow.Descendents().OfType().FirstOrDefault(); - // ensure paneGroup var paneGroup = targetModel.Parent as LayoutDocumentPaneGroup; + var requiredOrientation = Type == DropTargetType.DocumentPaneDockBottom || Type == DropTargetType.DocumentPaneDockTop ? + System.Windows.Controls.Orientation.Vertical : System.Windows.Controls.Orientation.Horizontal; + var allowMixedOrientation = targetModel.Root.Manager.AllowMixedOrientation; + if(paneGroup == null) { - var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement; - var layoutGroup = targetModel.Parent as ILayoutGroup; - paneGroup = new LayoutDocumentPaneGroup() + var targetModelAsPositionableElement = (ILayoutPositionableElement)targetModel; + var layoutGroup = (ILayoutGroup)targetModel.Parent; + paneGroup = new LayoutDocumentPaneGroup { - Orientation = System.Windows.Controls.Orientation.Vertical, + Orientation = requiredOrientation, DockWidth = targetModelAsPositionableElement.DockWidth, DockHeight = targetModelAsPositionableElement.DockHeight, }; @@ -93,8 +96,20 @@ protected override void Drop(LayoutDocumentFloatingWindow floatingWindow) paneGroup.Children.Add(targetModel); layoutGroup.InsertChildAt(0, paneGroup); } - var paneGroupOrientaion = paneGroup as ILayoutOrientableGroup; - + else if (allowMixedOrientation && paneGroup.Orientation != requiredOrientation && Type != DropTargetType.DocumentPaneDockInside) + { + var targetModelAsPositionableElement = (ILayoutPositionableElement)targetModel; + var newGroup = new LayoutDocumentPaneGroup + { + Orientation = requiredOrientation, + DockWidth = targetModelAsPositionableElement.DockWidth, + DockHeight = targetModelAsPositionableElement.DockHeight, + }; + + paneGroup.ReplaceChild(targetModel, newGroup); + newGroup.Children.Add(targetModel); + paneGroup = newGroup; + } switch (Type) { @@ -104,7 +119,7 @@ protected override void Drop(LayoutDocumentFloatingWindow floatingWindow) { - if (paneGroupOrientaion.Orientation != System.Windows.Controls.Orientation.Vertical) + if (!allowMixedOrientation && paneGroup.Orientation != System.Windows.Controls.Orientation.Vertical) { paneGroup.Orientation = System.Windows.Controls.Orientation.Vertical; } @@ -132,7 +147,7 @@ protected override void Drop(LayoutDocumentFloatingWindow floatingWindow) { - if(paneGroupOrientaion.Orientation != System.Windows.Controls.Orientation.Vertical) + if(!allowMixedOrientation && paneGroup.Orientation != System.Windows.Controls.Orientation.Vertical) { paneGroup.Orientation = System.Windows.Controls.Orientation.Vertical; } @@ -159,7 +174,7 @@ protected override void Drop(LayoutDocumentFloatingWindow floatingWindow) #region DropTargetType.DocumentPaneDockLeft { - if (paneGroupOrientaion.Orientation != System.Windows.Controls.Orientation.Horizontal) + if (!allowMixedOrientation && paneGroup.Orientation != System.Windows.Controls.Orientation.Horizontal) { paneGroup.Orientation = System.Windows.Controls.Orientation.Horizontal; } @@ -186,7 +201,7 @@ protected override void Drop(LayoutDocumentFloatingWindow floatingWindow) #region DropTargetType.DocumentPaneDockRight { - if (paneGroupOrientaion.Orientation != System.Windows.Controls.Orientation.Horizontal) + if (!allowMixedOrientation && paneGroup.Orientation != System.Windows.Controls.Orientation.Horizontal) { paneGroup.Orientation = System.Windows.Controls.Orientation.Horizontal; } From 982004bbc8f0be0e866d807f88f53accacc3e2ed Mon Sep 17 00:00:00 2001 From: Dirkster99 Date: Fri, 24 Mar 2023 14:29:55 +0100 Subject: [PATCH 14/18] AvalonDock Version 4.72.0 --- README.md | 12 ++++++++++++ .../AvalonDock.Themes.Aero.csproj | 10 +++++----- .../AvalonDock.Themes.Expression.csproj | 10 +++++----- .../AvalonDock.Themes.Metro.csproj | 10 +++++----- .../AvalonDock.Themes.VS2010.csproj | 10 +++++----- .../AvalonDock.Themes.VS2013.csproj | 8 ++++---- source/Components/AvalonDock/AvalonDock.csproj | 8 ++++---- 7 files changed, 40 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 3475f69b..171ad87f 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,18 @@ to also theme standard elements, such as, button and textblock etc. # Mile Stone History +## Fixes and Features Added in Version 4.72.0 + +- [#423 issue #422 DockingManager.LayoutItemTemplateSelector is applied twice because...](https://github.com/Dirkster99/AvalonDock/pull/423) (thanx to [Mona04](https://github.com/Mona04)) + +- [#425 Fix: Potential NRE on app close](https://github.com/Dirkster99/AvalonDock/pull/425) (thanx to [Khaos66](https://github.com/Khaos66)) + +- [#427 Fix floating windows still created twice](https://github.com/Dirkster99/AvalonDock/pull/427) (thanx to [Khaos66](https://github.com/Khaos66)) + +- [Add DockingManager.ShowNavigator](https://github.com/Dirkster99/AvalonDock/pull/428) (thanx to [Calum Robinson](https://github.com/calumr)) + +- [#431 Fix unwanted group orientation change when using mixed orientation](https://github.com/Dirkster99/AvalonDock/pull/431) (thanx to [KuroiRoy](https://github.com/KuroiRoy)) + ## Fixes Added in Version 4.71.2 - [#416 Fix Issue #226: Restore floating windows to maximized state](https://github.com/Dirkster99/AvalonDock/pull/416) (thanx to [Michael Möller](https://github.com/moellerm)) diff --git a/source/Components/AvalonDock.Themes.Aero/AvalonDock.Themes.Aero.csproj b/source/Components/AvalonDock.Themes.Aero/AvalonDock.Themes.Aero.csproj index 9ecdd743..125f3ef7 100644 --- a/source/Components/AvalonDock.Themes.Aero/AvalonDock.Themes.Aero.csproj +++ b/source/Components/AvalonDock.Themes.Aero/AvalonDock.Themes.Aero.csproj @@ -1,4 +1,4 @@ - + AvalonDock.Themes netcoreapp3.0;net5.0-windows;net40 @@ -6,10 +6,10 @@ sn.snk true true - 4.71.2 - 4.71.2 - 4.71.2 - 4.71.2 + 4.72.0 + 4.72.0 + 4.72.0 + 4.72.0 Open Source Dirkster.AvalonDock 2017-2023 diff --git a/source/Components/AvalonDock.Themes.Expression/AvalonDock.Themes.Expression.csproj b/source/Components/AvalonDock.Themes.Expression/AvalonDock.Themes.Expression.csproj index ecbb0b0c..d6995897 100644 --- a/source/Components/AvalonDock.Themes.Expression/AvalonDock.Themes.Expression.csproj +++ b/source/Components/AvalonDock.Themes.Expression/AvalonDock.Themes.Expression.csproj @@ -1,4 +1,4 @@ - + AvalonDock.Themes netcoreapp3.0;net5.0-windows;net40 @@ -6,10 +6,10 @@ sn.snk true true - 4.71.2 - 4.71.2 - 4.71.2 - 4.71.2 + 4.72.0 + 4.72.0 + 4.72.0 + 4.72.0 Open Source Dirkster.AvalonDock 2017-2023 diff --git a/source/Components/AvalonDock.Themes.Metro/AvalonDock.Themes.Metro.csproj b/source/Components/AvalonDock.Themes.Metro/AvalonDock.Themes.Metro.csproj index 9db59365..70e216a4 100644 --- a/source/Components/AvalonDock.Themes.Metro/AvalonDock.Themes.Metro.csproj +++ b/source/Components/AvalonDock.Themes.Metro/AvalonDock.Themes.Metro.csproj @@ -1,4 +1,4 @@ - + AvalonDock.Themes netcoreapp3.0;net5.0-windows;net40 @@ -6,10 +6,10 @@ sn.snk true true - 4.71.2 - 4.71.2 - 4.71.2 - 4.71.2 + 4.72.0 + 4.72.0 + 4.72.0 + 4.72.0 Open Source Dirkster.AvalonDock 2017-2023 diff --git a/source/Components/AvalonDock.Themes.VS2010/AvalonDock.Themes.VS2010.csproj b/source/Components/AvalonDock.Themes.VS2010/AvalonDock.Themes.VS2010.csproj index 9251dd1d..3b8692e2 100644 --- a/source/Components/AvalonDock.Themes.VS2010/AvalonDock.Themes.VS2010.csproj +++ b/source/Components/AvalonDock.Themes.VS2010/AvalonDock.Themes.VS2010.csproj @@ -1,4 +1,4 @@ - + AvalonDock.Themes netcoreapp3.0;net5.0-windows;net40 @@ -6,10 +6,10 @@ sn.snk true true - 4.71.2 - 4.71.2 - 4.71.2 - 4.71.2 + 4.72.0 + 4.72.0 + 4.72.0 + 4.72.0 Open Source Dirkster.AvalonDock 2017-2023 diff --git a/source/Components/AvalonDock.Themes.VS2013/AvalonDock.Themes.VS2013.csproj b/source/Components/AvalonDock.Themes.VS2013/AvalonDock.Themes.VS2013.csproj index 98ae0c52..454ce40f 100644 --- a/source/Components/AvalonDock.Themes.VS2013/AvalonDock.Themes.VS2013.csproj +++ b/source/Components/AvalonDock.Themes.VS2013/AvalonDock.Themes.VS2013.csproj @@ -6,10 +6,10 @@ sn.snk true true - 4.71.2 - 4.71.2 - 4.71.2 - 4.71.2 + 4.72.0 + 4.72.0 + 4.72.0 + 4.72.0 Open Source Dirkster.AvalonDock 2017-2023 diff --git a/source/Components/AvalonDock/AvalonDock.csproj b/source/Components/AvalonDock/AvalonDock.csproj index 72fdf0bd..362bf56e 100644 --- a/source/Components/AvalonDock/AvalonDock.csproj +++ b/source/Components/AvalonDock/AvalonDock.csproj @@ -6,10 +6,10 @@ true sn.snk true - 4.71.2 - 4.71.2 - 4.71.2 - 4.71.2 + 4.72.0 + 4.72.0 + 4.72.0 + 4.72.0 Open Source Dirkster.AvalonDock 2017-2023 From 0cc7cb5fa04d2ca0d28929f8c68a5bb1d3fbc2e6 Mon Sep 17 00:00:00 2001 From: frsa Date: Fri, 31 Mar 2023 15:48:30 +0200 Subject: [PATCH 15/18] Changed how the next active document is picked on document close. --- .../Components/AvalonDock/DockingManager.cs | 122 +++++++----------- 1 file changed, 45 insertions(+), 77 deletions(-) diff --git a/source/Components/AvalonDock/DockingManager.cs b/source/Components/AvalonDock/DockingManager.cs index aaeffa0e..8c7ca9d0 100644 --- a/source/Components/AvalonDock/DockingManager.cs +++ b/source/Components/AvalonDock/DockingManager.cs @@ -1870,6 +1870,36 @@ internal void RemoveFloatingWindow(LayoutFloatingWindowControl floatingWindow) LayoutFloatingWindowControlClosed?.Invoke(this, new LayoutFloatingWindowControlClosedEventArgs(floatingWindow)); } + + + internal void ExecuteCloseAllButThisCommand(LayoutContent contentSelected) + { + foreach (var contentToClose in Layout.Descendents().OfType().Where(d => d != contentSelected && (d.Parent is LayoutDocumentPane || d.Parent is LayoutDocumentFloatingWindow)).ToArray()) + Close(contentToClose); + } + + internal void ExecuteCloseAllCommand(LayoutContent contentSelected) + { + foreach (var contentToClose in Layout.Descendents().OfType().Where(d => (d.Parent is LayoutDocumentPane || d.Parent is LayoutDocumentFloatingWindow)).ToArray()) + Close(contentToClose); + } + + internal void ExecuteCloseCommand(LayoutAnchorable anchorable) + { + if (!(anchorable is LayoutAnchorable model)) return; + + AnchorableClosingEventArgs closingArgs = null; + AnchorableClosing?.Invoke(this, closingArgs = new AnchorableClosingEventArgs(model)); + if (closingArgs?.Cancel == true) + return; + + if (model.CloseAnchorable()) + { + RemoveViewFromLogicalChild(model); + AnchorableClosed?.Invoke(this, new AnchorableClosedEventArgs(model)); + } + } + internal void ExecuteCloseCommand(LayoutDocument document) { if (DocumentClosing != null) @@ -1879,10 +1909,8 @@ internal void ExecuteCloseCommand(LayoutDocument document) if (argsClosing.Cancel) return; } - // - // Determine the index of the document that will be removed. - // - int indexOfDocumentToRemove = GetIndexOfDocument(document); + // Get the document to activate after the close. + LayoutDocument documentToActivate = GetDocumentToActivate(document); if (!document.CloseDocument()) return; @@ -1894,98 +1922,38 @@ internal void ExecuteCloseCommand(LayoutDocument document) //get rid of the closed document content document.Content = null; - int indexOfDocumentToSelect = indexOfDocumentToRemove - 1; - - if (indexOfDocumentToSelect < 0) - { - indexOfDocumentToSelect = 0; - } - // - // Determine the new active document and activate it. + // Activate the document determined to be the next active document. // This doesn't only update the layout, but also all related (dependency) properties. // - LayoutDocument layoutDocument = GetDocumentOnIndex(indexOfDocumentToSelect); - - if (layoutDocument != null) + if (documentToActivate != null) { - layoutDocument.IsActive = true; + documentToActivate.IsActive = true; } } - private LayoutDocument GetDocumentOnIndex(int indexToFind) + private LayoutDocument GetDocumentToActivate(LayoutDocument previousDocument) { - if (indexToFind < 0) - { - throw new ArgumentOutOfRangeException(nameof(indexToFind)); - } + ILayoutContainer parentContainer = previousDocument.Parent; + IEnumerable siblingDocuments = parentContainer?.Children.OfType() ?? Enumerable.Empty(); - int index = 0; - - foreach (LayoutDocument layoutDocument in this.Layout.Descendents().OfType()) + foreach (var childPair in siblingDocuments.Zip(siblingDocuments.Skip(1), Tuple.Create)) { - if (index == indexToFind) + if (childPair.Item2 == previousDocument) { - return layoutDocument; + return childPair.Item1; } - - index++; } - return null; - } - - private int GetIndexOfDocument(LayoutDocument documentToFind) - { - if (documentToFind == null) - { - throw new ArgumentNullException(nameof(documentToFind)); - } - - int index = 0; - - foreach (LayoutDocument layoutDocument in this.Layout.Descendents().OfType()) + foreach (LayoutDocument document in this.Layout.Descendents().OfType()) { - if (layoutDocument == documentToFind) + if (document.IsSelected) { - return index; + return document; } - - index++; } - // - // Not found. - // - return -1; - } - - internal void ExecuteCloseAllButThisCommand(LayoutContent contentSelected) - { - foreach (var contentToClose in Layout.Descendents().OfType().Where(d => d != contentSelected && (d.Parent is LayoutDocumentPane || d.Parent is LayoutDocumentFloatingWindow)).ToArray()) - Close(contentToClose); - } - - internal void ExecuteCloseAllCommand(LayoutContent contentSelected) - { - foreach (var contentToClose in Layout.Descendents().OfType().Where(d => (d.Parent is LayoutDocumentPane || d.Parent is LayoutDocumentFloatingWindow)).ToArray()) - Close(contentToClose); - } - - internal void ExecuteCloseCommand(LayoutAnchorable anchorable) - { - if (!(anchorable is LayoutAnchorable model)) return; - - AnchorableClosingEventArgs closingArgs = null; - AnchorableClosing?.Invoke(this, closingArgs = new AnchorableClosingEventArgs(model)); - if (closingArgs?.Cancel == true) - return; - - if (model.CloseAnchorable()) - { - RemoveViewFromLogicalChild(model); - AnchorableClosed?.Invoke(this, new AnchorableClosedEventArgs(model)); - } + return null; } internal void ExecuteHideCommand(LayoutAnchorable anchorable) From 31cf051dd808e71ec314885f35c1a88da9bc4327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benny=20B=C3=BCrger?= Date: Fri, 28 Apr 2023 15:07:18 +0200 Subject: [PATCH 16/18] NullCheck for DragPoint --- .../Controls/LayoutAnchorableFloatingWindowControl.cs | 2 ++ .../Controls/LayoutDocumentFloatingWindowControl.cs | 2 ++ .../Components/AvalonDock/Controls/TransformExtentions.cs | 7 +++++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs index 16551443..b9d6e0a4 100644 --- a/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs @@ -149,6 +149,8 @@ bool IOverlayWindowHost.HitTestScreen(Point dragPoint) bool HitTest(Point dragPoint) { + if (dragPoint == default(Point)) + return false; var detectionRect = new Rect(this.PointToScreenDPIWithoutFlowDirection(new Point()), this.TransformActualSizeToAncestor()); return detectionRect.Contains(dragPoint); } diff --git a/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs index 44bb0a79..e75d1aa6 100644 --- a/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs @@ -224,6 +224,8 @@ bool IOverlayWindowHost.HitTestScreen(Point dragPoint) bool HitTest(Point dragPoint) { + if (dragPoint == default(Point)) + return false; var detectionRect = new Rect(this.PointToScreenDPIWithoutFlowDirection(new Point()), this.TransformActualSizeToAncestor()); return detectionRect.Contains(dragPoint); } diff --git a/source/Components/AvalonDock/Controls/TransformExtentions.cs b/source/Components/AvalonDock/Controls/TransformExtentions.cs index 4b576366..768601ce 100644 --- a/source/Components/AvalonDock/Controls/TransformExtentions.cs +++ b/source/Components/AvalonDock/Controls/TransformExtentions.cs @@ -1,4 +1,4 @@ -/************************************************************************ +/************************************************************************ AvalonDock Copyright (C) 2007-2013 Xceed Software Inc. @@ -59,7 +59,10 @@ public static Rect GetScreenArea(this FrameworkElement element) public static Point TransformToDeviceDPI(this Visual visual, Point pt) { - Matrix m = PresentationSource.FromVisual(visual).CompositionTarget.TransformToDevice; + var compositionTarget = PresentationSource.FromVisual(visual).CompositionTarget; + if (compositionTarget == null) + return default; + Matrix m = compositionTarget.TransformToDevice; return new Point(pt.X / m.M11, pt.Y / m.M22); } From f80e1802f81b341bb1e023bee207c0670d4b0350 Mon Sep 17 00:00:00 2001 From: Dirkster99 Date: Wed, 16 Aug 2023 12:05:22 +0200 Subject: [PATCH 17/18] AvalonDock Version 4.72.1 --- .../AvalonDock.Themes.Aero/AvalonDock.Themes.Aero.csproj | 8 ++++---- .../AvalonDock.Themes.Expression.csproj | 8 ++++---- .../AvalonDock.Themes.Metro.csproj | 8 ++++---- .../AvalonDock.Themes.VS2010.csproj | 8 ++++---- .../AvalonDock.Themes.VS2013.csproj | 8 ++++---- source/Components/AvalonDock/AvalonDock.csproj | 8 ++++---- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/source/Components/AvalonDock.Themes.Aero/AvalonDock.Themes.Aero.csproj b/source/Components/AvalonDock.Themes.Aero/AvalonDock.Themes.Aero.csproj index 125f3ef7..33b4310a 100644 --- a/source/Components/AvalonDock.Themes.Aero/AvalonDock.Themes.Aero.csproj +++ b/source/Components/AvalonDock.Themes.Aero/AvalonDock.Themes.Aero.csproj @@ -6,10 +6,10 @@ sn.snk true true - 4.72.0 - 4.72.0 - 4.72.0 - 4.72.0 + 4.72.1 + 4.72.1 + 4.72.1 + 4.72.1 Open Source Dirkster.AvalonDock 2017-2023 diff --git a/source/Components/AvalonDock.Themes.Expression/AvalonDock.Themes.Expression.csproj b/source/Components/AvalonDock.Themes.Expression/AvalonDock.Themes.Expression.csproj index d6995897..d7ed522c 100644 --- a/source/Components/AvalonDock.Themes.Expression/AvalonDock.Themes.Expression.csproj +++ b/source/Components/AvalonDock.Themes.Expression/AvalonDock.Themes.Expression.csproj @@ -6,10 +6,10 @@ sn.snk true true - 4.72.0 - 4.72.0 - 4.72.0 - 4.72.0 + 4.72.1 + 4.72.1 + 4.72.1 + 4.72.1 Open Source Dirkster.AvalonDock 2017-2023 diff --git a/source/Components/AvalonDock.Themes.Metro/AvalonDock.Themes.Metro.csproj b/source/Components/AvalonDock.Themes.Metro/AvalonDock.Themes.Metro.csproj index 70e216a4..34203fe8 100644 --- a/source/Components/AvalonDock.Themes.Metro/AvalonDock.Themes.Metro.csproj +++ b/source/Components/AvalonDock.Themes.Metro/AvalonDock.Themes.Metro.csproj @@ -6,10 +6,10 @@ sn.snk true true - 4.72.0 - 4.72.0 - 4.72.0 - 4.72.0 + 4.72.1 + 4.72.1 + 4.72.1 + 4.72.1 Open Source Dirkster.AvalonDock 2017-2023 diff --git a/source/Components/AvalonDock.Themes.VS2010/AvalonDock.Themes.VS2010.csproj b/source/Components/AvalonDock.Themes.VS2010/AvalonDock.Themes.VS2010.csproj index 3b8692e2..844d5fde 100644 --- a/source/Components/AvalonDock.Themes.VS2010/AvalonDock.Themes.VS2010.csproj +++ b/source/Components/AvalonDock.Themes.VS2010/AvalonDock.Themes.VS2010.csproj @@ -6,10 +6,10 @@ sn.snk true true - 4.72.0 - 4.72.0 - 4.72.0 - 4.72.0 + 4.72.1 + 4.72.1 + 4.72.1 + 4.72.1 Open Source Dirkster.AvalonDock 2017-2023 diff --git a/source/Components/AvalonDock.Themes.VS2013/AvalonDock.Themes.VS2013.csproj b/source/Components/AvalonDock.Themes.VS2013/AvalonDock.Themes.VS2013.csproj index 454ce40f..cc2bf377 100644 --- a/source/Components/AvalonDock.Themes.VS2013/AvalonDock.Themes.VS2013.csproj +++ b/source/Components/AvalonDock.Themes.VS2013/AvalonDock.Themes.VS2013.csproj @@ -6,10 +6,10 @@ sn.snk true true - 4.72.0 - 4.72.0 - 4.72.0 - 4.72.0 + 4.72.1 + 4.72.1 + 4.72.1 + 4.72.1 Open Source Dirkster.AvalonDock 2017-2023 diff --git a/source/Components/AvalonDock/AvalonDock.csproj b/source/Components/AvalonDock/AvalonDock.csproj index 362bf56e..6986bf34 100644 --- a/source/Components/AvalonDock/AvalonDock.csproj +++ b/source/Components/AvalonDock/AvalonDock.csproj @@ -6,10 +6,10 @@ true sn.snk true - 4.72.0 - 4.72.0 - 4.72.0 - 4.72.0 + 4.72.1 + 4.72.1 + 4.72.1 + 4.72.1 Open Source Dirkster.AvalonDock 2017-2023 From 30599e401419ad238187a3594f5dd85acaa5546b Mon Sep 17 00:00:00 2001 From: Dirkster99 Date: Wed, 16 Aug 2023 12:18:05 +0200 Subject: [PATCH 18/18] Updated Readme.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 171ad87f..6f6d2157 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,12 @@ to also theme standard elements, such as, button and textblock etc. # Mile Stone History + +## Fixes and Features Added in Version 4.72.0 + +- [#436 Changed how the next active document is picked on document close.](https://github.com/Dirkster99/AvalonDock/pull/436) (thanx to [FredrikS fredriks123](https://github.com/fredriks123)) +- [#438 NullCheck for DragPoint](https://github.com/Dirkster99/AvalonDock/pull/438) (thanx to [Ben bbuerger](https://github.com/bbuerger)) + ## Fixes and Features Added in Version 4.72.0 - [#423 issue #422 DockingManager.LayoutItemTemplateSelector is applied twice because...](https://github.com/Dirkster99/AvalonDock/pull/423) (thanx to [Mona04](https://github.com/Mona04))