/// <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)); }
private DockHintWindow(FloatWindowDockPanel toMove) { _toMove = toMove; _toSet = DockState.Float; var window = toMove.Window.Window; // Remove focus from drag target _toMove.Focus(); _toMove.Defocus(); // Focus window window.Focus(); // Calculate dragging offset and move window to the destination position var mouseScreenPosition = FlaxEngine.Input.MouseScreenPosition; // 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 Proxy.Window.MouseUp += OnMouseUp; Proxy.Window.MouseMove += OnMouseMove; Proxy.Window.LostFocus += OnLostFocus; // Start tracking mouse Proxy.Window.StartTrackingMouse(false); // Update window GUI Proxy.Window.GUI.PerformLayout(); // Update rectangles UpdateRects(); // Hide base window window.Hide(); // Enable hit window presentation Proxy.Window.RenderingEnabled = true; Proxy.Window.Show(); }
private DockHintWindow(FloatWindowDockPanel toMove) { _toMove = toMove; _toSet = DockState.Float; var window = toMove.Window.Window; // Remove focus from drag target _toMove.Focus(); _toMove.Defocus(); // Focus window window.Focus(); // Calculate dragging offset and move window to the destination position Vector2 mouse = FlaxEngine.Input.MouseScreenPosition; Vector2 baseWinPos = window.Position; _dragOffset = mouse - baseWinPos; // Get initial size _defaultWindowSize = window.Size; // Init proxy window Proxy.Init(ref _defaultWindowSize); // Bind events Proxy.Window.MouseUp += OnMouseUp; Proxy.Window.MouseMove += OnMouseMove; Proxy.Window.LostFocus += OnLostFocus; // Start tracking mouse Proxy.Window.StartTrackingMouse(false); // Update window GUI Proxy.Window.GUI.PerformLayout(); // Update rectangles UpdateRects(); // Hide base window window.Hide(); // Enable hit window presentation Proxy.Window.RenderingEnabled = true; Proxy.Window.Show(); }
/// <summary> /// Performs hit test over dock panel. /// </summary> /// <param name="position">Screen space position to test.</param> /// <param name="excluded">Floating window to omit during searching (and all docked to that one).</param> /// <returns>Dock panel that has been hit or null if nothing found.</returns> public DockPanel HitTest(ref Vector2 position, FloatWindowDockPanel excluded) { // Check all floating windows // TODO: gather windows order and take it into account when performing test for (int i = 0; i < FloatingPanels.Count; i++) { var win = FloatingPanels[i]; if (win.Visible && win != excluded) { var result = win.HitTest(ref position); if (result != null) { return(result); } } } // Base return(base.HitTest(ref position)); }
/// <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; // Hide the proxy Proxy.Hide(); if (_toMove == null) { return; } // Check if window won't be docked if (_toSet == DockState.Float) { var window = _toMove.Window.Window; Vector2 mouse = FlaxEngine.Input.MouseScreenPosition; // 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 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> /// Loads the layout from the file. /// </summary> /// <param name="path">The layout file path.</param> /// <returns>True if layout has been loaded otherwise if failed (e.g. missing file).</returns> public bool LoadLayout(string path) { if (Editor.IsHeadlessMode) { return(false); } Editor.Log(string.Format("Loading editor windows layout from \'{0}\'", path)); if (!File.Exists(path)) { Editor.LogWarning("Cannot load windows layout. File is missing."); return(false); } XmlDocument doc = new XmlDocument(); var masterPanel = Editor.UI.MasterPanel; try { doc.Load(path); var root = doc["DockPanelLayout"]; if (root == null) { Editor.LogWarning("Invalid windows layout file."); return(false); } // Reset existing layout masterPanel.ResetLayout(); // Get metadata int version = int.Parse(root.Attributes["Version"].Value, CultureInfo.InvariantCulture); var virtualDesktopBounds = Application.VirtualDesktopBounds; var virtualDesktopSafeLeftCorner = virtualDesktopBounds.Location + new Vector2(0, 23); // 23 is a window strip size var virtualDesktopSafeRightCorner = virtualDesktopBounds.BottomRight - new Vector2(50, 50); // apply some safe area switch (version) { case 4: { // Main window info if (MainWindow) { var mainWindowNode = root["MainWindow"]; Rectangle bounds = LoadBounds(mainWindowNode["Bounds"]); bool isMaximized = bool.Parse(mainWindowNode.GetAttribute("IsMaximized")); // Clamp position to match current desktop dimensions (if window was on desktop that is now inactive) if (bounds.X < virtualDesktopSafeLeftCorner.X || bounds.Y < virtualDesktopSafeLeftCorner.Y || bounds.X > virtualDesktopSafeRightCorner.X || bounds.Y > virtualDesktopSafeRightCorner.Y) { bounds.Location = virtualDesktopSafeLeftCorner; } if (isMaximized) { MainWindow.ClientPosition = bounds.Location; MainWindow.Maximize(); } else { if (Mathf.Min(bounds.Size.X, bounds.Size.Y) >= 1) { MainWindow.ClientBounds = bounds; } else { MainWindow.ClientPosition = bounds.Location; } } } // Load master panel structure var masterPanelNode = root["MasterPanel"]; if (masterPanelNode != null) { LoadPanel(masterPanelNode, masterPanel); } // Load all floating windows structure var floating = root.SelectNodes("Float"); if (floating != null) { foreach (XmlElement child in floating) { if (child == null) { continue; } // Get window properties Rectangle bounds = LoadBounds(child["Bounds"]); // Create window and floating dock panel var window = FloatWindowDockPanel.CreateFloatWindow(MainWindow.GUI, bounds.Location, bounds.Size, WindowStartPosition.Manual, string.Empty); var panel = new FloatWindowDockPanel(masterPanel, window.GUI); // Load structure LoadPanel(child, panel); // Check if no child windows loaded (due to file errors or loading problems) if (panel.TabsCount == 0 && panel.ChildPanelsCount == 0) { // Close empty window Editor.LogWarning("Empty floating window inside layout."); window.Close(); } else { // Perform layout var windowGUI = window.GUI; windowGUI.UnlockChildrenRecursive(); windowGUI.PerformLayout(); // Show window.Show(); window.Focus(); // Perform layout again windowGUI.PerformLayout(); } } } break; } default: { Editor.LogWarning("Unsupported windows layout version"); return(false); } } } catch (Exception ex) { Editor.LogWarning("Failed to load windows layout."); Editor.LogWarning(ex); return(false); } return(true); }