// Copyright (c) Wojciech Figat. All rights reserved. using FlaxEngine; using FlaxEngine.GUI; namespace FlaxEditor.GUI.Docking { /// /// Floating Window Dock Panel control. /// /// public class FloatWindowDockPanel : DockPanel { private class FloatWindowDecorations : WindowDecorations { private FloatWindowDockPanel _panel; public FloatWindowDecorations(FloatWindowDockPanel panel) : base(panel.RootWindow) { _panel = panel; } /// public override bool OnMouseDown(Float2 location, MouseButton button) { if (Title.Bounds.Contains(location) && button == MouseButton.Left) { _panel.BeginDrag(); return true; } return base.OnMouseDown(location, button); } #if !PLATFORM_WINDOWS /// protected override WindowHitCodes OnHitTest(ref Float2 mouse) { var hit = base.OnHitTest(ref mouse); if (hit == WindowHitCodes.Caption) { // Override the system behaviour when interacting with the caption area hit = WindowHitCodes.Client; } return hit; } #endif } private MasterDockPanel _masterPanel; private WindowRootControl _window; /// /// Gets the master panel. /// public MasterDockPanel MasterPanel => _masterPanel; /// /// Gets the window. /// public WindowRootControl Window => _window; /// /// Initializes a new instance of the class. /// /// The master panel. /// The window. public FloatWindowDockPanel(MasterDockPanel masterPanel, RootControl window) : base(null) { _masterPanel = masterPanel; _window = (WindowRootControl)window; // Link _masterPanel.FloatingPanels.Add(this); Parent = window; _window.Window.Closing += OnClosing; _window.Window.LeftButtonHit += OnLeftButtonHit; if (Utilities.Utils.UseCustomWindowDecorations()) { var decorations = Parent.AddChild(new FloatWindowDecorations(this)); decorations.SetAnchorPreset(AnchorPresets.HorizontalStretchTop, false); } } /// protected override void PerformLayoutBeforeChildren() { base.PerformLayoutBeforeChildren(); var decorations = Parent.GetChild(); if (decorations != null) { // Apply offset for the title bar foreach (var child in Children) child.Bounds = child.Bounds with { Y = decorations.Height, Height = Parent.Height - decorations.Height }; } } /// /// Begin drag operation on the window /// public void BeginDrag() { // Filter invalid events if (_window == null) return; // Create docking hint window WindowDragHelper.StartDragging(this); } /// /// Creates a floating window. /// /// Parent window handle. /// Client area location. /// Window client area size. /// Window start position. /// Initial window title. internal static Window CreateFloatWindow(RootControl parent, Float2 location, Float2 size, WindowStartPosition startPosition, string title) { // Setup initial window settings var settings = CreateWindowSettings.Default; settings.Parent = (parent as WindowRootControl)?.Window; settings.Title = title; settings.Size = size; settings.Position = location; settings.MinimumSize = new Float2(200, 150); settings.MaximumSize = Float2.Zero; // Unlimited size settings.Fullscreen = false; settings.HasBorder = true; settings.SupportsTransparency = true; settings.ActivateWhenFirstShown = true; settings.AllowInput = true; settings.AllowMinimize = true; settings.AllowMaximize = true; settings.AllowDragAndDrop = true; settings.IsTopmost = false; settings.Type = WindowType.Regular; settings.HasSizingFrame = true; settings.ShowAfterFirstPaint = false; settings.ShowInTaskbar = true; settings.StartPosition = startPosition; if (Utilities.Utils.UseCustomWindowDecorations()) { settings.HasBorder = false; //settings.HasSizingFrame = false; } // Create window return Platform.CreateWindow(ref settings); } private bool OnLeftButtonHit(WindowHitCodes hitTest) { if (hitTest == WindowHitCodes.Caption) { BeginDrag(); return true; } return false; } private void OnClosing(ClosingReason reason, ref bool cancel) { // Close all docked windows while (Tabs.Count > 0) { if (Tabs[0].Close(reason)) { // Cancel cancel = true; return; } } // Unlink _window.Window.Closing -= OnClosing; _window.Window.LeftButtonHit = null; _window = null; // Remove object FlaxEngine.Assertions.Assert.IsTrue(TabsCount == 0 && ChildPanelsCount == 0); Dispose(); } /// public override bool IsFloating => true; /// public override DockState TryGetDockState(out float splitterValue) { splitterValue = 0.5f; return DockState.Float; } /// protected override void OnLastTabRemoved() { if (ChildPanelsCount > 0) return; // Close window _window?.Close(); } /// protected override void OnSelectedTabChanged() { base.OnSelectedTabChanged(); if (_window != null && SelectedTab != null) _window.Title = SelectedTab.Title; } /// public override void OnDestroy() { _masterPanel?.FloatingPanels.Remove(this); base.OnDestroy(); } } }