Skip to content

Commit

Permalink
Improve and optimize the codes of active content for floating windows
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Wenveo committed Jan 24, 2023
1 parent fa58dfe commit ce7de8d
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 171 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -433,55 +433,6 @@ private void OnExecuteCloseWindowCommand(object parameter)

#endregion CloseWindowCommand

#region ActiveItem

internal void ActiveItemOfSinglePane(bool isActive)
{
var pane = _model.Descendents().OfType<LayoutAnchorablePane>()
.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<LayoutAnchorablePaneControl>();
if (paneControl != null)
{
var model = (LayoutAnchorablePane)paneControl.Model;
if (model.SelectedContent != null)
{
model.SelectedContent.IsActive = true;
return;
}
else
{
ActiveTheLastActivedItemOfPane<LayoutAnchorablePane, LayoutAnchorable>(model);
return;
}
}
}
ActiveTheLastActivedItemOfItems(isActive);
}

#endregion ActiveItem

#endregion Private Methods
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -432,55 +432,6 @@ private void OnExecuteCloseWindowCommand(object parameter)

#endregion CloseWindowCommand

#region ActiveItem

internal void ActiveItemOfSinglePane(bool isActive)
{
var pane = _model.Descendents().OfType<LayoutDocumentPane>()
.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<LayoutDocumentPaneControl>();
if (paneControl != null)
{
var model = (LayoutDocumentPane)paneControl.Model;
if (model.SelectedContent != null)
{
model.SelectedContent.IsActive = true;
return;
}
else
{
ActiveTheLastActivedItemOfPane<LayoutDocumentPane, LayoutContent>(model);
return;
}
}
}
ActiveTheLastActivedItemOfItems(isActive);
}

#endregion ActiveItem

#endregion Private Methods
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -492,75 +492,6 @@ internal void InternalClose(bool closeInitiatedByUser = false)
Close();
}

internal T FindPaneControlByMousePoint<T>() where T : FrameworkElement, ILayoutControl
{
var mousePosition = this.PointToScreenDPI(Mouse.GetPosition(this));
var rootVisual = ((FloatingWindowContentHost)Content).RootVisual;
var areaHosts = rootVisual.FindVisualChildren<T>();

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<LayoutContent>().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, TChild>(TPane pane)
where TPane : LayoutPositionableGroup<TChild>, 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
Expand Down
Original file line number Diff line number Diff line change
@@ -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>(T fwc, bool isActive) where T : LayoutFloatingWindowControl
{
ILayoutContentSelector selector = null;
if (fwc is LayoutAnchorableFloatingWindowControl)
{
selector = fwc.Model
.Descendents()
.OfType<LayoutAnchorablePane>()
.FirstOrDefault(p => p.ChildrenCount > 0 && p.SelectedContent != null);
}
else if (fwc is LayoutDocumentFloatingWindowControl)
{
selector = fwc.Model
.Descendents()
.OfType<LayoutDocumentPane>()
.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>(T fwc, bool isActive) where T : LayoutFloatingWindowControl
{
if (isActive)
{
if (fwc is LayoutAnchorableFloatingWindowControl)
{
var paneControl = GetLayoutControlByMousePosition<LayoutAnchorablePaneControl>(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<LayoutDocumentPaneControl>(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<LayoutContent>().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<T>(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<T>())
{
var rect = areaHost.GetScreenArea();
if (rect.Contains(mousePosition))
{
return areaHost;
}
}

return null;
}

private static int IndexOfLastActivedContent<T>(IList<T> 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;
}
}
}

0 comments on commit ce7de8d

Please sign in to comment.