Some checks failed
Build Android / Game (Android, Release ARM64) (push) Has been cancelled
Build iOS / Game (iOS, Release ARM64) (push) Has been cancelled
Build Linux / Editor (Linux, Development x64) (push) Has been cancelled
Build Linux / Game (Linux, Release x64) (push) Has been cancelled
Build macOS / Editor (Mac, Development ARM64) (push) Has been cancelled
Build macOS / Game (Mac, Release ARM64) (push) Has been cancelled
Build Windows / Editor (Windows, Development x64) (push) Has been cancelled
Build Windows / Game (Windows, Release x64) (push) Has been cancelled
Cooker / Cook (Mac) (push) Has been cancelled
Tests / Tests (Linux) (push) Has been cancelled
Tests / Tests (Windows) (push) Has been cancelled
727 lines
27 KiB
C#
727 lines
27 KiB
C#
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
|
|
|
using System;
|
|
using FlaxEngine;
|
|
using FlaxEngine.GUI;
|
|
|
|
namespace FlaxEditor.GUI.Docking
|
|
{
|
|
/// <summary>
|
|
/// Helper class used to handle docking windows dragging and docking.
|
|
/// </summary>
|
|
public class DockHintWindow
|
|
{
|
|
private FloatWindowDockPanel _toMove;
|
|
|
|
private Float2 _dragOffset;
|
|
private Float2 _defaultWindowSize;
|
|
private Rectangle _rectDock;
|
|
private Rectangle _rectWindow;
|
|
private Float2 _mouse;
|
|
private DockState _toSet;
|
|
private DockPanel _toDock;
|
|
private bool _lateDragOffsetUpdate;
|
|
private float _lateDragStartTimer;
|
|
|
|
private Rectangle _rLeft, _rRight, _rBottom, _rUpper, _rCenter;
|
|
|
|
private DockHintWindow(FloatWindowDockPanel toMove, bool lateDragStart)
|
|
{
|
|
_toMove = toMove;
|
|
_toSet = DockState.Float;
|
|
var window = _toMove?.Window.Window ?? Editor.Instance.Windows.MainWindow;
|
|
|
|
// Remove focus from drag target
|
|
//_toMove.Focus();
|
|
//_toMove.Defocus();
|
|
|
|
// Focus window
|
|
//window.Focus();
|
|
|
|
// Check if window is maximized and restore window.
|
|
if (window.IsMaximized)
|
|
{
|
|
// Restore window and set position to mouse.
|
|
var mousePos = window.MousePosition;
|
|
var previousSize = window.Size;
|
|
window.Restore();
|
|
window.Position = Platform.MousePosition - mousePos * window.Size / previousSize;
|
|
}
|
|
|
|
// Calculate dragging offset and move window to the destination position
|
|
var mouseClientPosition = Platform.MousePosition;
|
|
CalculateDragOffset(mouseClientPosition);
|
|
|
|
// If the _toMove window was not focused when initializing this window, the result vector only contains zeros
|
|
// and to prevent a failure, we need to perform an update for the drag offset at later time which will be done in the OnMouseMove event handler.
|
|
//if (mouseScreenPosition != Float2.Zero)
|
|
// CalculateDragOffset(mouseScreenPosition);
|
|
//else
|
|
// _lateDragOffsetUpdate = true;
|
|
|
|
|
|
|
|
// Get initial size
|
|
//_defaultWindowSize = window.Size;
|
|
|
|
// Init proxy window
|
|
/*Proxy.Init(ref _defaultWindowSize);
|
|
|
|
// Bind events
|
|
*/
|
|
|
|
//FlaxEngine.Input.MouseMove += OnMouseMove;
|
|
FlaxEngine.Scripting.Update += OnUpdate;
|
|
window.MouseUp += OnMouseUp;
|
|
/*
|
|
Proxy.Window.MouseUp += OnMouseUp;
|
|
Proxy.Window.MouseMove += OnMouseMove;
|
|
Proxy.Window.LostFocus += OnLostFocus;
|
|
_toMove.Window.Window.MouseUp += OnMouseUp; // Intercept the drag release mouse event from source window
|
|
*/
|
|
// Update window GUI
|
|
//Proxy.Window.GUI.PerformLayout();
|
|
|
|
// Update rectangles
|
|
UpdateRects();
|
|
|
|
// Enable hit window presentation
|
|
/*Proxy.Window.RenderingEnabled = true;
|
|
Proxy.Window.Show();
|
|
Proxy.Window.Focus();*/
|
|
|
|
// Hide base window
|
|
//window.Hide();
|
|
|
|
window.Show();
|
|
|
|
if (lateDragStart)
|
|
{
|
|
// The window needs some time to be fully ready for dragging
|
|
//_lateDragStartTimer = 1.5f;
|
|
window.StartDragging(_dragOffset);
|
|
}
|
|
else
|
|
window.StartDragging(_dragOffset);
|
|
|
|
Dispose();
|
|
|
|
//window.Show();
|
|
//window.BringToFront();
|
|
//window.Focus();
|
|
//toMove.OnShow();
|
|
|
|
// Perform layout again
|
|
//windowGUI.PerformLayout();
|
|
|
|
|
|
// Start tracking mouse
|
|
//Proxy.Window.StartTrackingMouse(false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Releases unmanaged and - optionally - managed resources.
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
// End tracking mouse
|
|
/*Proxy.Window.EndTrackingMouse();
|
|
|
|
// Disable rendering
|
|
Proxy.Window.RenderingEnabled = false;
|
|
|
|
// Unbind events
|
|
Proxy.Window.MouseUp -= OnMouseUp;
|
|
Proxy.Window.MouseMove -= OnMouseMove;
|
|
Proxy.Window.LostFocus -= OnLostFocus;
|
|
if (_toMove?.Window?.Window)
|
|
_toMove.Window.Window.MouseUp -= OnMouseUp;
|
|
|
|
// Hide the proxy
|
|
Proxy.Hide();*/
|
|
|
|
RemoveDockHints();
|
|
|
|
//FlaxEngine.Input.MouseMove -= OnMouseMove;
|
|
var window = _toMove?.Window?.Window ?? Editor.Instance.Windows.MainWindow;
|
|
FlaxEngine.Scripting.Update -= OnUpdate;
|
|
window.MouseUp -= OnMouseUp;
|
|
|
|
if (_toMove == null)
|
|
return;
|
|
|
|
_toMove.Window?.Window.StopDragging();
|
|
|
|
// Check if window won't be docked
|
|
if (_toSet == DockState.Float)
|
|
{
|
|
if (window == null)
|
|
return;
|
|
var mouse = Platform.MousePosition;
|
|
|
|
// Move base window
|
|
window.Position = mouse - _dragOffset;
|
|
|
|
// Show base window
|
|
window.Show();
|
|
}
|
|
else
|
|
{
|
|
bool hasNoChildPanels = _toMove.ChildPanelsCount == 0;
|
|
|
|
// Check if window has only single tab
|
|
if (hasNoChildPanels && _toMove.TabsCount == 1)
|
|
{
|
|
// Dock window
|
|
_toMove.GetTab(0).Show(_toSet, _toDock);
|
|
}
|
|
// Check if dock as tab and has no child panels
|
|
else if (hasNoChildPanels && _toSet == DockState.DockFill)
|
|
{
|
|
// Dock all tabs
|
|
while (_toMove.TabsCount > 0)
|
|
{
|
|
_toMove.GetTab(0).Show(DockState.DockFill, _toDock);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var selectedTab = _toMove.SelectedTab;
|
|
|
|
// Dock the first tab into the target location
|
|
if (_toMove.TabsCount > 0)
|
|
{
|
|
var firstTab = _toMove.GetTab(0);
|
|
firstTab.Show(_toSet, _toDock);
|
|
|
|
// Dock rest of the tabs
|
|
while (_toMove.TabsCount > 0)
|
|
{
|
|
_toMove.GetTab(0).Show(DockState.DockFill, firstTab);
|
|
}
|
|
}
|
|
|
|
// Keep selected tab being selected
|
|
selectedTab?.SelectTab();
|
|
}
|
|
|
|
// Focus target window
|
|
_toDock.Root.Focus();
|
|
}
|
|
|
|
_toMove = null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates the new dragging hit window.
|
|
/// </summary>
|
|
/// <param name="toMove">Floating dock panel to move.</param>
|
|
/// <returns>The dock hint window object.</returns>
|
|
public static DockHintWindow Create(FloatWindowDockPanel toMove)
|
|
{
|
|
if (toMove == null)
|
|
throw new ArgumentNullException();
|
|
|
|
return new DockHintWindow(toMove, false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates the new dragging hit window.
|
|
/// </summary>
|
|
/// <param name="toMove">Dock window to move.</param>
|
|
/// <returns>The dock hint window object.</returns>
|
|
public static DockHintWindow Create(DockWindow toMove)
|
|
{
|
|
if (toMove == null)
|
|
throw new ArgumentNullException();
|
|
|
|
// Show floating
|
|
toMove.ShowFloating();
|
|
|
|
// Move window to the mouse position (with some offset for caption bar)
|
|
var window = (WindowRootControl)toMove.Root;
|
|
/*var mouse = Platform.MousePosition;
|
|
window.Window.Position = mouse - new Float2(8, 8);*/
|
|
|
|
// Get floating panel
|
|
var floatingPanelToMove = window?.GetChild(0) as FloatWindowDockPanel;
|
|
|
|
return new DockHintWindow(floatingPanelToMove, true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calculates window rectangle in the dock window.
|
|
/// </summary>
|
|
/// <param name="state">Window dock state.</param>
|
|
/// <param name="rect">Dock panel rectangle.</param>
|
|
/// <returns>Calculated window rectangle.</returns>
|
|
public static Rectangle CalculateDockRect(DockState state, ref Rectangle rect)
|
|
{
|
|
Rectangle result = rect;
|
|
switch (state)
|
|
{
|
|
case DockState.DockFill:
|
|
result.Location.Y += DockPanel.DefaultHeaderHeight;
|
|
result.Size.Y -= DockPanel.DefaultHeaderHeight;
|
|
break;
|
|
case DockState.DockTop:
|
|
result.Size.Y *= DockPanel.DefaultSplitterValue;
|
|
break;
|
|
case DockState.DockLeft:
|
|
result.Size.X *= DockPanel.DefaultSplitterValue;
|
|
break;
|
|
case DockState.DockBottom:
|
|
result.Location.Y += result.Size.Y * (1 - DockPanel.DefaultSplitterValue);
|
|
result.Size.Y *= DockPanel.DefaultSplitterValue;
|
|
break;
|
|
case DockState.DockRight:
|
|
result.Location.X += result.Size.X * (1 - DockPanel.DefaultSplitterValue);
|
|
result.Size.X *= DockPanel.DefaultSplitterValue;
|
|
break;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private void CalculateDragOffset(Float2 mouseScreenPosition)
|
|
{
|
|
var baseWinPos = _toMove?.Window.Window.Position ?? Editor.Instance.Windows.MainWindow.Position;
|
|
_dragOffset = mouseScreenPosition - baseWinPos;
|
|
|
|
Editor.Log($"_dragOffset: {_dragOffset}, mouse: {mouseScreenPosition}, basewinpos: {baseWinPos}");
|
|
}
|
|
|
|
DockHintControl _dockHintDown;
|
|
DockHintControl _dockHintUp;
|
|
DockHintControl _dockHintLeft;
|
|
DockHintControl _dockHintRight;
|
|
DockHintControl _dockHintCenter;
|
|
private void AddDockHints()
|
|
{
|
|
if (_toDock == null)
|
|
return;
|
|
|
|
_dockHintDown = AddHintControl(new Float2(0.5f, 1));
|
|
_dockHintUp = AddHintControl(new Float2(0.5f, 0));
|
|
_dockHintLeft = AddHintControl(new Float2(0, 0.5f));
|
|
_dockHintRight = AddHintControl(new Float2(1, 0.5f));
|
|
_dockHintCenter = AddHintControl(new Float2(0.5f, 0.5f));
|
|
|
|
DockHintControl AddHintControl(Float2 pivot)
|
|
{
|
|
DockHintControl hintControl = _toDock.AddChild<DockHintControl>();
|
|
hintControl.Size = new Float2(Proxy.HintWindowsSize);
|
|
hintControl.BackgroundColor = Style.Current.DragWindow.AlphaMultiplied(0.6f);
|
|
hintControl.Pivot = pivot;
|
|
hintControl.PivotRelative = true;
|
|
//.SetAnchorPreset(AnchorPresets.StretchAll, true);
|
|
return hintControl;
|
|
}
|
|
}
|
|
|
|
private void RemoveDockHints()
|
|
{
|
|
if (_toDock == null)
|
|
return;
|
|
|
|
_dockHintDown?.Parent.RemoveChild(_dockHintDown);
|
|
_dockHintUp?.Parent.RemoveChild(_dockHintUp);
|
|
_dockHintLeft?.Parent.RemoveChild(_dockHintLeft);
|
|
_dockHintRight?.Parent.RemoveChild(_dockHintRight);
|
|
_dockHintCenter?.Parent.RemoveChild(_dockHintCenter);
|
|
_dockHintDown = _dockHintUp = _dockHintLeft = _dockHintRight = _dockHintCenter = null;
|
|
}
|
|
|
|
private void UpdateRects()
|
|
{
|
|
// Cache mouse position
|
|
_mouse = Platform.MousePosition;
|
|
|
|
if (_toMove == null)
|
|
return;
|
|
|
|
// Check intersection with any dock panel
|
|
var uiMouse = _mouse;
|
|
var dockPanel = _toMove.MasterPanel.HitTest(ref uiMouse, _toMove);
|
|
|
|
if (dockPanel != _toDock)
|
|
{
|
|
//Editor.Log($"UpdateRects: {_mouse}, panel: {dockPanel?.RootWindow?.Window?.Title}");
|
|
|
|
_toDock?.RootWindow.Window.RemoveDockHints();
|
|
RemoveDockHints();
|
|
|
|
_toDock = dockPanel;
|
|
_toDock?.RootWindow.Window.CreateDockHints();
|
|
AddDockHints();
|
|
}
|
|
|
|
// Check dock state to use
|
|
bool showProxyHints = _toDock != null;
|
|
bool showBorderHints = showProxyHints;
|
|
bool showCenterHint = showProxyHints;
|
|
DockHintControl hoveredHintControl = null;
|
|
Float2 hoveredSizeOverride = Float2.Zero;
|
|
if (showProxyHints)
|
|
{
|
|
// If moved window has not only tabs but also child panels disable docking as tab
|
|
if (_toMove.ChildPanelsCount > 0)
|
|
showCenterHint = false;
|
|
|
|
// Disable docking windows with one or more dock panels inside
|
|
if (_toMove.ChildPanelsCount > 0)
|
|
showBorderHints = false;
|
|
|
|
// Get dock area
|
|
_rectDock = _toDock.DockAreaBounds;
|
|
|
|
// Cache dock rectangles
|
|
var size = _rectDock.Size / Platform.DpiScale;
|
|
var offset = _toDock.PointFromScreen(_rectDock.Location);
|
|
var borderMargin = 4.0f;
|
|
var hintWindowsSize = Proxy.HintWindowsSize;
|
|
var hintWindowsSize2 = hintWindowsSize * 0.5f;
|
|
var hintPreviewSize = new Float2(Math.Max(Proxy.HintWindowsSize * 2, size.X * 0.5f), Math.Max(Proxy.HintWindowsSize * 2, size.Y * 0.5f));
|
|
var centerX = size.X * 0.5f;
|
|
var centerY = size.Y * 0.5f;
|
|
_rUpper = new Rectangle(centerX - hintWindowsSize2, borderMargin, hintWindowsSize, hintWindowsSize) + offset;
|
|
_rBottom = new Rectangle(centerX - hintWindowsSize2, size.Y - hintWindowsSize - borderMargin, hintWindowsSize, hintWindowsSize) + offset;
|
|
_rLeft = new Rectangle(borderMargin, centerY - hintWindowsSize2, hintWindowsSize, hintWindowsSize) + offset;
|
|
_rRight = new Rectangle(size.X - hintWindowsSize - borderMargin, centerY - hintWindowsSize2, hintWindowsSize, hintWindowsSize) + offset;
|
|
_rCenter = new Rectangle(centerX - hintWindowsSize2, centerY - hintWindowsSize2, hintWindowsSize, hintWindowsSize) + offset;
|
|
|
|
// Hit test
|
|
DockState toSet = DockState.Float;
|
|
if (showBorderHints)
|
|
{
|
|
if (_rUpper.Contains(_toDock.PointFromScreen(_mouse)))
|
|
{
|
|
toSet = DockState.DockTop;
|
|
hoveredHintControl = _dockHintUp;
|
|
hoveredSizeOverride = new Float2(size.X, hintPreviewSize.Y);
|
|
}
|
|
else if (_rBottom.Contains(_toDock.PointFromScreen(_mouse)))
|
|
{
|
|
toSet = DockState.DockBottom;
|
|
hoveredHintControl = _dockHintDown;
|
|
hoveredSizeOverride = new Float2(size.X, hintPreviewSize.Y);
|
|
}
|
|
else if (_rLeft.Contains(_toDock.PointFromScreen(_mouse)))
|
|
{
|
|
toSet = DockState.DockLeft;
|
|
hoveredHintControl = _dockHintLeft;
|
|
hoveredSizeOverride = new Float2(hintPreviewSize.X, size.Y);
|
|
}
|
|
else if (_rRight.Contains(_toDock.PointFromScreen(_mouse)))
|
|
{
|
|
toSet = DockState.DockRight;
|
|
hoveredHintControl = _dockHintRight;
|
|
hoveredSizeOverride = new Float2(hintPreviewSize.X, size.Y);
|
|
}
|
|
}
|
|
if (showCenterHint && _rCenter.Contains(_toDock.PointFromScreen(_mouse)))
|
|
{
|
|
toSet = DockState.DockFill;
|
|
hoveredHintControl = _dockHintCenter;
|
|
hoveredSizeOverride = new Float2(size.X, size.Y);
|
|
}
|
|
|
|
if (toSet != DockState.Float)
|
|
Editor.Log($"docking: {toSet}");
|
|
|
|
_toSet = toSet;
|
|
}
|
|
else
|
|
{
|
|
_toSet = DockState.Float;
|
|
}
|
|
|
|
// Calculate proxy/dock/window rectangles
|
|
if (_toDock == null)
|
|
{
|
|
// Floating window over nothing
|
|
//_rectWindow = new Rectangle(_mouse - _dragOffset, _defaultWindowSize);
|
|
if (hoveredHintControl != null)
|
|
hoveredHintControl.BackgroundColor = Color.Green;
|
|
}
|
|
else
|
|
{
|
|
if (hoveredHintControl != _dockHintDown)
|
|
{
|
|
_dockHintDown.Size = new Float2(Proxy.HintWindowsSize);
|
|
_dockHintDown.BackgroundColor = Style.Current.DragWindow.AlphaMultiplied(0.6f);
|
|
}
|
|
if (hoveredHintControl != _dockHintLeft)
|
|
{
|
|
_dockHintLeft.Size = new Float2(Proxy.HintWindowsSize);
|
|
_dockHintLeft.BackgroundColor = Style.Current.DragWindow.AlphaMultiplied(0.6f);
|
|
}
|
|
if (hoveredHintControl != _dockHintRight)
|
|
{
|
|
_dockHintRight.Size = new Float2(Proxy.HintWindowsSize);
|
|
_dockHintRight.BackgroundColor = Style.Current.DragWindow.AlphaMultiplied(0.6f);
|
|
}
|
|
if (hoveredHintControl != _dockHintUp)
|
|
{
|
|
_dockHintUp.Size = new Float2(Proxy.HintWindowsSize);
|
|
_dockHintUp.BackgroundColor = Style.Current.DragWindow.AlphaMultiplied(0.6f);
|
|
}
|
|
if (hoveredHintControl != _dockHintCenter)
|
|
{
|
|
_dockHintCenter.Size = new Float2(Proxy.HintWindowsSize);
|
|
_dockHintCenter.BackgroundColor = Style.Current.DragWindow.AlphaMultiplied(0.6f);
|
|
}
|
|
if (_toSet == DockState.Float)
|
|
{
|
|
// Floating window over dock panel
|
|
if (hoveredHintControl != null)
|
|
hoveredHintControl.BackgroundColor = Color.Red;
|
|
}
|
|
else
|
|
{
|
|
// Use only part of the dock panel to show hint
|
|
if (hoveredHintControl != null)
|
|
{
|
|
hoveredHintControl.BackgroundColor = Style.Current.DragWindow.AlphaMultiplied(1.0f);
|
|
hoveredHintControl.Size = hoveredSizeOverride;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (showProxyHints)
|
|
{
|
|
if (hoveredHintControl != _dockHintDown)
|
|
_dockHintDown.Location = _rBottom.Location;
|
|
if (hoveredHintControl != _dockHintLeft)
|
|
_dockHintLeft.Location = _rLeft.Location;
|
|
if (hoveredHintControl != _dockHintRight)
|
|
_dockHintRight.Location = _rRight.Location;
|
|
if (hoveredHintControl != _dockHintUp)
|
|
_dockHintUp.Location = _rUpper.Location;
|
|
if (hoveredHintControl != _dockHintCenter)
|
|
_dockHintCenter.Location = _rCenter.Location;
|
|
|
|
// Update proxy hint windows visibility
|
|
_dockHintDown.Visible = showProxyHints & showBorderHints;
|
|
_dockHintLeft.Visible = showProxyHints & showBorderHints;
|
|
_dockHintRight.Visible = showProxyHints & showBorderHints;
|
|
_dockHintUp.Visible = showProxyHints & showBorderHints;
|
|
_dockHintCenter.Visible = showProxyHints & showCenterHint;
|
|
}
|
|
|
|
// Update proxy window
|
|
//Proxy.Window.ClientBounds = _rectWindow;
|
|
}
|
|
|
|
private void OnMouseUp(ref Float2 location, MouseButton button, ref bool handled)
|
|
{
|
|
Editor.Log("DockHintWindow.OnMouseUp");
|
|
if (button == MouseButton.Left)
|
|
{
|
|
Dispose();
|
|
}
|
|
}
|
|
|
|
private void OnUpdate()
|
|
{
|
|
//Editor.Log("OnUpdate");
|
|
if (_lateDragStartTimer > 0)
|
|
{
|
|
_lateDragStartTimer -= Time.UnscaledDeltaTime;
|
|
if (_lateDragStartTimer <= 0)
|
|
_toMove.Window.Window.StartDragging(_dragOffset);
|
|
}
|
|
var mousePos = Platform.MousePosition;
|
|
if (_mouse != mousePos)
|
|
{
|
|
OnMouseMove(mousePos);
|
|
}
|
|
}
|
|
|
|
private void OnMouseMove(Float2 mousePos)
|
|
{
|
|
//Editor.Log("OnMouseMove");
|
|
// Recalculate the drag offset because the current mouse screen position was invalid when we initialized the window
|
|
if (_lateDragOffsetUpdate)
|
|
{
|
|
// Calculate dragging offset and move window to the destination position
|
|
CalculateDragOffset(mousePos);
|
|
|
|
// Reset state
|
|
_lateDragOffsetUpdate = false;
|
|
}
|
|
|
|
UpdateRects();
|
|
}
|
|
|
|
private void OnLostFocus()
|
|
{
|
|
Dispose();
|
|
}
|
|
|
|
public class DockHintControl : Control
|
|
{
|
|
public DockHintControl()
|
|
{
|
|
AnchorPreset = AnchorPresets.StretchAll;
|
|
Offsets = Margin.Zero;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Contains helper proxy windows shared across docking panels. They are used to visualize docking window locations.
|
|
/// </summary>
|
|
public static class Proxy
|
|
{
|
|
/// <summary>
|
|
/// The drag proxy window.
|
|
/// </summary>
|
|
public static Window Window;
|
|
|
|
/// <summary>
|
|
/// The left hint proxy window.
|
|
/// </summary>
|
|
public static Window Left;
|
|
|
|
/// <summary>
|
|
/// The right hint proxy window.
|
|
/// </summary>
|
|
public static Window Right;
|
|
|
|
/// <summary>
|
|
/// The up hint proxy window.
|
|
/// </summary>
|
|
public static Window Up;
|
|
|
|
/// <summary>
|
|
/// The down hint proxy window.
|
|
/// </summary>
|
|
public static Window Down;
|
|
|
|
/// <summary>
|
|
/// The center hint proxy window.
|
|
/// </summary>
|
|
public static Window Center;
|
|
|
|
/// <summary>
|
|
/// The hint windows size.
|
|
/// </summary>
|
|
public const float HintWindowsSize = 32.0f;
|
|
|
|
/// <summary>
|
|
/// Initializes the hit proxy windows. Those windows are used to indicate drag target areas (left, right, top, bottom, etc.).
|
|
/// </summary>
|
|
public static void InitHitProxy()
|
|
{
|
|
CreateProxy(ref Left, "DockHint.Left");
|
|
CreateProxy(ref Right, "DockHint.Right");
|
|
CreateProxy(ref Up, "DockHint.Up");
|
|
CreateProxy(ref Down, "DockHint.Down");
|
|
CreateProxy(ref Center, "DockHint.Center");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the hint window.
|
|
/// </summary>
|
|
/// <param name="initSize">Initial size of the proxy window.</param>
|
|
public static void Init(ref Float2 initSize)
|
|
{
|
|
if (Window == null)
|
|
{
|
|
var settings = CreateWindowSettings.Default;
|
|
settings.Title = "DockHint.Window";
|
|
settings.Size = initSize;
|
|
settings.AllowInput = true;
|
|
settings.AllowMaximize = false;
|
|
settings.AllowMinimize = false;
|
|
settings.HasBorder = false;
|
|
settings.HasSizingFrame = false;
|
|
settings.Type = WindowType.Utility;
|
|
settings.SupportsTransparency = true;
|
|
settings.ShowInTaskbar = false;
|
|
settings.ShowAfterFirstPaint = false;
|
|
settings.IsTopmost = true;
|
|
|
|
Window = Platform.CreateWindow(ref settings);
|
|
Window.Opacity = 0.6f;
|
|
Window.GUI.BackgroundColor = Style.Current.DragWindow;
|
|
}
|
|
else
|
|
{
|
|
// Resize proxy
|
|
Window.ClientSize = initSize;
|
|
}
|
|
|
|
InitHitProxy();
|
|
}
|
|
|
|
private static void CreateProxy(ref Window win, string name)
|
|
{
|
|
if (win != null)
|
|
return;
|
|
|
|
var settings = CreateWindowSettings.Default;
|
|
settings.Title = name;
|
|
settings.Size = new Float2(HintWindowsSize * Platform.DpiScale);
|
|
settings.AllowInput = false;
|
|
settings.AllowMaximize = false;
|
|
settings.AllowMinimize = false;
|
|
settings.HasBorder = false;
|
|
settings.HasSizingFrame = false;
|
|
settings.Type = WindowType.Utility;
|
|
settings.SupportsTransparency = true;
|
|
settings.ShowInTaskbar = false;
|
|
settings.ActivateWhenFirstShown = false;
|
|
settings.IsTopmost = true;
|
|
settings.ShowAfterFirstPaint = false;
|
|
|
|
win = Platform.CreateWindow(ref settings);
|
|
win.Opacity = 0.6f;
|
|
win.GUI.BackgroundColor = Style.Current.DragWindow;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Hides proxy windows.
|
|
/// </summary>
|
|
public static void Hide()
|
|
{
|
|
HideProxy(ref Window);
|
|
HideProxy(ref Left);
|
|
HideProxy(ref Right);
|
|
HideProxy(ref Up);
|
|
HideProxy(ref Down);
|
|
HideProxy(ref Center);
|
|
}
|
|
|
|
private static void HideProxy(ref Window win)
|
|
{
|
|
if (win)
|
|
{
|
|
win.Hide();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Releases proxy data and windows.
|
|
/// </summary>
|
|
public static void Dispose()
|
|
{
|
|
DisposeProxy(ref Window);
|
|
DisposeProxy(ref Left);
|
|
DisposeProxy(ref Right);
|
|
DisposeProxy(ref Up);
|
|
DisposeProxy(ref Down);
|
|
DisposeProxy(ref Center);
|
|
}
|
|
|
|
private static void DisposeProxy(ref Window win)
|
|
{
|
|
if (win)
|
|
{
|
|
win.Close(ClosingReason.User);
|
|
win = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|