/// <summary> /// Initializes the <see cref="Common.UI.DockWidgets.DragHandler"/> class. /// </summary> static DragHandler() { mDockWidget = null; mHandledByArea = null; mMouseLocation = MouseLocation.Outside; mMinimum = float.MaxValue; }
/// <summary> /// Initializes the <see cref="Common.UI.DockWidgets.DragInfoHolder"/> class. /// </summary> static DragInfoHolder() { DebugEx.Verbose("Created DragInfoHolder object"); sDockWidget = null; sMinimum = float.MaxValue; sDockingArea = null; sMouseLocation = MouseLocation.Outside; }
/// <summary> /// Initializes a new instance of the <see cref="Common.UI.DockWidgets.DockingAreaScript"/> class. /// </summary> public DockingAreaScript() : base() { mInstances.Add(this); mOrientation = DockingAreaOrientation.None; mParent = null; mChildren = new List<DockingAreaScript>(); mSizes = new List<float>(); mDockingGroupScript = null; mCachedDragCorners = null; }
/// <summary> /// Initializes a new instance of the <see cref="Common.UI.DockWidgets.DockingWindowScript"/> class. /// </summary> private DockingWindowScript() : base() { DebugEx.Verbose("Created DockingWindowScript object"); mDockWidget = null; mDockingAreaScript = null; frame = WindowFrameType.SingleFrame; backgroundColor = Assets.Common.DockWidgets.Colors.dockingWindow; }
/// <summary> /// Initializes a new instance of the <see cref="Common.UI.DockWidgets.DockingGroupScript"/> class. /// </summary> public DockingGroupScript() : base() { DebugEx.Verbose("Created DockingGroupScript object"); mParent = null; mChildren = new List<DockWidgetScript>(); mSelectedIndex = -1; mTabsTransform = null; mContentTransform = null; }
/// <summary> /// Insert dock widget into specified docking area. /// </summary> /// <param name="dockingArea">Docking area.</param> /// <param name="orientation">Orientation.</param> /// <param name="index">Index.</param> public void InsertToDockingArea(DockingAreaScript dockingArea, DockingAreaOrientation orientation = DockingAreaOrientation.Horizontal, int index = 0) { DebugEx.VerboseFormat("DockWidgetScript.InsertToDockingArea(dockingArea = {0}, orientation = {1}, index = {2})", dockingArea, orientation, index); dockingArea.InsertDockWidget(this, orientation, index); }
/// <summary> /// Handler for destroy event. /// </summary> void OnDestroy() { DebugEx.Verbose("DockingAreaScript.OnDestroy()"); if (sResizingArea == this) { #if !CURSORLESS_PLATFORM RemoveCursorIfNeeded(); sPreviousMouseLocation = MouseLocation.Outside; #endif sResizingArea = null; sMouseLocation = MouseLocation.Outside; sMouseState = MouseState.NoState; } if (!sInstances.Remove(this)) { DebugEx.Error("Failed to remove docking area"); } }
/// <summary> /// Initializes a new instance of the <see cref="Common.UI.DockWidgets.DockingAreaScript"/> class. /// </summary> public DockingAreaScript() : base() { DebugEx.Verbose("Created DockingAreaScript object"); sInstances.Add(this); mOrientation = DockingAreaOrientation.None; mParent = null; mChildren = new List<DockingAreaScript>(); mSizes = new List<float>(); mDockingGroupScript = null; mCachedDragCorners = null; mChildlessListeners = new UnityEvent(); }
/// <summary> /// Removes the docking area. /// </summary> /// <param name="dockingArea">Docking area.</param> public void RemoveDockingArea(DockingAreaScript dockingArea) { DebugEx.VerboseFormat("DockingAreaScript.RemoveDockingArea(dockingArea = {0})", dockingArea); if (dockingArea.parent == this) { int index = mChildren.IndexOf(dockingArea); if (index >= 0) { float size = mSizes[index]; mChildren.RemoveAt(index); mSizes.RemoveAt(index); if (size < 1f) { float sizeMultiplier = 1 / (1f - size); for (int i = 0; i < mSizes.Count; ++i) { mSizes[i] *= sizeMultiplier; } } else { if (mSizes.Count > 0) { float newSize = 1f / mSizes.Count; for (int i = 0; i < mSizes.Count; ++i) { mSizes[i] = newSize; } } } if (mChildren.Count == 1) { dockingArea = mChildren[0]; DockingAreaOrientation orientation = dockingArea.mOrientation; List<DockingAreaScript> children = dockingArea.mChildren; List<float> sizes = dockingArea.mSizes; DockingGroupScript dockingGroupScript = dockingArea.mDockingGroupScript; if (dockingGroupScript != null) { dockingGroupScript.parent = this; dockingGroupScript.transform.SetParent(transform, false); } else { foreach (DockingAreaScript child in children) { child.mParent = this; child.transform.SetParent(transform, false); } } dockingArea.Destroy(); mOrientation = orientation; mChildren = children; mSizes = sizes; mDockingGroupScript = dockingGroupScript; } OnResize(); } else { DebugEx.Error("Failed to remove docking area"); } } else { DebugEx.Error("Docking area belongs not to this docking area"); } }
/// <summary> /// Update is called once per frame. /// </summary> void Update() { DebugEx.VeryVeryVerbose("DockingAreaScript.Update()"); if ( mParent != null && mCachedDragCorners == null ) { switch (sMouseState) { case MouseState.NoState: { if (sLastUpdate != Time.frameCount) { sLastUpdate = Time.frameCount; sResizingArea = null; sMouseLocation = MouseLocation.Outside; } if (sResizingArea == null) { Vector3[] corners = Utils.GetWindowCorners(transform as RectTransform); float left = corners[0].x - GAP; float top = corners[0].y - GAP; float right = corners[3].x + GAP; float bottom = corners[3].y + GAP; float mouseX = Mouse.scaledX; float mouseY = Mouse.scaledY; if ( mouseX >= left && mouseX <= right && mouseY >= top && mouseY <= bottom ) { List<RaycastResult> hits = new List<RaycastResult>(); Mouse.RaycastAll(hits); bool isInSameHierarchy = false; if (hits.Count > 0) { Transform baseTransform = hits[0].gameObject.transform; Transform curTransform = transform; while (curTransform != null) { if (curTransform == baseTransform) { isInSameHierarchy = true; break; } curTransform = curTransform.parent; } } if (isInSameHierarchy) { if (mouseY <= top + GAP) { if ( mParent.mOrientation == DockingAreaOrientation.Vertical && mParent.mChildren.Count > 1 && mParent.mChildren[0] != this ) { sResizingArea = this; sMouseLocation = MouseLocation.North; } } else if (mouseY >= bottom - GAP) { if ( mParent.mOrientation == DockingAreaOrientation.Vertical && mParent.mChildren.Count > 1 && mParent.mChildren[mParent.mChildren.Count - 1] != this ) { sResizingArea = this; sMouseLocation = MouseLocation.South; } } else { if (mouseX <= left + GAP) { if ( mParent.mOrientation == DockingAreaOrientation.Horizontal && mParent.mChildren.Count > 1 && mParent.mChildren[0] != this ) { sResizingArea = this; sMouseLocation = MouseLocation.West; } } else if (mouseX >= right - GAP) { if ( mParent.mOrientation == DockingAreaOrientation.Horizontal && mParent.mChildren.Count > 1 && mParent.mChildren[mParent.mChildren.Count - 1] != this ) { sResizingArea = this; sMouseLocation = MouseLocation.East; } } else { sMouseLocation = MouseLocation.Inside; } } } } } } break; case MouseState.Resizing: { if (sResizingArea == this) { if ( mParent != null && mParent.mChildren.Count > 1 ) { int index = mParent.mChildren.IndexOf(this); if (index >= 0) { MouseLocation usedLocation = sMouseLocation; float mouseX = Mouse.scaledX; float mouseY = Mouse.scaledY; float oldWidth = 0f; float oldHeight = 0f; float newWidth = 0f; float newHeight = 0f; float oldSize = 0f; float newSize = 0f; for (int attempt = 1; attempt <= 2; ++attempt) { Vector3[] corners = Utils.GetWindowCorners(mParent.mChildren[index].transform as RectTransform); float left = corners[0].x; float top = corners[0].y; float right = corners[3].x; float bottom = corners[3].y; oldWidth = right - left; oldHeight = bottom - top; newWidth = oldWidth; newHeight = oldHeight; oldSize = mParent.mSizes[index]; newSize = oldSize; switch (usedLocation) { case MouseLocation.North: { newHeight = bottom - mouseY; newSize = newHeight / oldHeight * oldSize; } break; case MouseLocation.South: { newHeight = mouseY - top; newSize = newHeight / oldHeight * oldSize; } break; case MouseLocation.West: { newWidth = right - mouseX; newSize = newWidth / oldWidth * oldSize; } break; case MouseLocation.East: { newWidth = mouseX - left; newSize = newWidth / oldWidth * oldSize; } break; case MouseLocation.Inside: case MouseLocation.Outside: { DebugEx.ErrorFormat("Incorrect mouse location: {0}", usedLocation); } break; default: { DebugEx.ErrorFormat("Unknown mouse location: {0}", usedLocation); } break; } if ( newWidth >= oldWidth - 0.1f && newHeight >= oldHeight - 0.1f ) { break; } if (attempt == 2) { DebugEx.Fatal("Unexpected behaviour in DockingAreaScript.Update()"); return; } switch (usedLocation) { case MouseLocation.North: { usedLocation = MouseLocation.South; if (index > 0) { --index; } else { DebugEx.Fatal("Unexpected behaviour in DockingAreaScript.Update()"); return; } } break; case MouseLocation.South: { usedLocation = MouseLocation.North; if (index < mParent.mChildren.Count - 1) { ++index; } else { DebugEx.Fatal("Unexpected behaviour in DockingAreaScript.Update()"); return; } } break; case MouseLocation.West: { usedLocation = MouseLocation.East; if (index > 0) { --index; } else { DebugEx.Fatal("Unexpected behaviour in DockingAreaScript.Update()"); return; } } break; case MouseLocation.East: { usedLocation = MouseLocation.West; if (index < mParent.mChildren.Count - 1) { ++index; } else { DebugEx.Fatal("Unexpected behaviour in DockingAreaScript.Update()"); return; } } break; case MouseLocation.Inside: case MouseLocation.Outside: { DebugEx.ErrorFormat("Incorrect mouse location: {0}", usedLocation); } break; default: { DebugEx.ErrorFormat("Unknown mouse location: {0}", usedLocation); } break; } } if ( newWidth > oldWidth - 0.1f || newHeight > oldHeight - 0.1f ) { float delta = newSize - oldSize; switch (usedLocation) { case MouseLocation.North: case MouseLocation.West: { for (int i = index - 1; i >= 0; --i) { float nextSize = mParent.mSizes[i] - delta; if (nextSize < MINIMUM_SIZE) { nextSize = MINIMUM_SIZE; } float localDelta = mParent.mSizes[i] - nextSize; mParent.mSizes[i] = nextSize; delta -= localDelta; if (delta == 0f) { break; } } newSize -= delta; } break; case MouseLocation.South: case MouseLocation.East: { for (int i = index + 1; i < mParent.mChildren.Count; ++i) { float nextSize = mParent.mSizes[i] - delta; if (nextSize < MINIMUM_SIZE) { nextSize = MINIMUM_SIZE; } float localDelta = mParent.mSizes[i] - nextSize; mParent.mSizes[i] = nextSize; delta -= localDelta; if (delta == 0f) { break; } } newSize -= delta; } break; case MouseLocation.Inside: case MouseLocation.Outside: { DebugEx.ErrorFormat("Incorrect mouse location: {0}", usedLocation); } break; default: { DebugEx.ErrorFormat("Unknown mouse location: {0}", usedLocation); } break; } mParent.mSizes[index] = newSize; mParent.OnResize(); } if (InputControl.GetMouseButtonUp(MouseButton.Left)) { sMouseState = MouseState.NoState; } } else { DebugEx.Fatal("Unexpected behaviour in DockingAreaScript.Update()"); } } else { DebugEx.Fatal("Unexpected behaviour in DockingAreaScript.Update()"); } } } break; default: { DebugEx.ErrorFormat("Unknown mouse state: {0}", sMouseState); } break; } } }
/// <summary> /// Removes the docking area. /// </summary> /// <param name="dockingArea">Docking area.</param> public void RemoveDockingArea(DockingAreaScript dockingArea) { if (dockingArea.parent == this) { int index = mChildren.IndexOf(dockingArea); if (index >= 0) { mChildren.RemoveAt(index); if (mChildren.Count == 1) { dockingArea = mChildren[0]; mOrientation = dockingArea.mOrientation; mChildren = dockingArea.mChildren; mSizes = dockingArea.mSizes; mDockingGroupScript = dockingArea.mDockingGroupScript; if (mDockingGroupScript != null) { mDockingGroupScript.parent = this; mDockingGroupScript.transform.SetParent(transform, false); } else { foreach (DockingAreaScript child in mChildren) { child.mParent = this; child.transform.SetParent(transform, false); } } UnityEngine.Object.DestroyObject(dockingArea.gameObject); } OnResize(); } else { Debug.LogError("Failed to remove docking area"); } } else { Debug.LogError("Docking area belongs not to this docking area"); } }
/// <summary> /// Insert dock widget into specified docking area. /// </summary> /// <param name="dockingArea">Docking area.</param> /// <param name="orientation">Orientation.</param> /// <param name="index">Index.</param> public void InsertToDockingArea(DockingAreaScript dockingArea, DockingAreaOrientation orientation = DockingAreaOrientation.Horizontal, int index = 0) { dockingArea.InsertDockWidget(this, orientation, index); }
/// <summary> /// Creates the content. /// </summary> /// <param name="contentTransform">Content transform.</param> /// <param name="width">Width of content.</param> /// <param name="height">Height of content.</param> protected override void CreateContent(Transform contentTransform, out float width, out float height) { DebugEx.VerboseFormat("DockingWindowScript.CreateContent(contentTransform = {0})", contentTransform); width = 150f; height = 150f; //*************************************************************************** // Header GameObject //*************************************************************************** #region Header GameObject GameObject header = new GameObject("Header"); Utils.InitUIObject(header, contentTransform); //=========================================================================== // RectTransform Component //=========================================================================== #region RectTransform Component RectTransform headerTransform = header.AddComponent<RectTransform>(); Utils.AlignRectTransformTopStretch(headerTransform, 5f); #endregion //*************************************************************************** // Close GameObject //*************************************************************************** #region Close GameObject GameObject closeGameObject = new GameObject("Close"); Utils.InitUIObject(closeGameObject, header.transform); //=========================================================================== // RectTransform Component //=========================================================================== #region RectTransform Component RectTransform closeTransform = closeGameObject.AddComponent<RectTransform>(); Utils.AlignRectTransformTopRight(closeTransform, 13f, 13f, 4f, 0f); #endregion //=========================================================================== // CanvasRenderer Component //=========================================================================== #region CanvasRenderer Component closeGameObject.AddComponent<CanvasRenderer>(); #endregion //=========================================================================== // Image Component //=========================================================================== #region Image Component Image closeImage = closeGameObject.AddComponent<Image>(); closeImage.sprite = Assets.Common.DockWidgets.Textures.closeButton.sprite; closeImage.type = Image.Type.Sliced; #endregion //=========================================================================== // Button Component //=========================================================================== #region Button Component Button closeButton = closeGameObject.AddComponent<Button>(); closeButton.targetGraphic = closeImage; closeButton.transition = Selectable.Transition.SpriteSwap; closeButton.spriteState = Assets.Common.DockWidgets.SpriteStates.closeButton.spriteState; closeButton.onClick.AddListener(Close); #endregion #endregion //*************************************************************************** // Maximize GameObject //*************************************************************************** #region Maximize GameObject GameObject maximizeGameObject = new GameObject("Maximize"); Utils.InitUIObject(maximizeGameObject, header.transform); //=========================================================================== // RectTransform Component //=========================================================================== #region RectTransform Component RectTransform maximizeTransform = maximizeGameObject.AddComponent<RectTransform>(); Utils.AlignRectTransformTopRight(maximizeTransform, 13f, 13f, 20f, 0f); #endregion //=========================================================================== // CanvasRenderer Component //=========================================================================== #region CanvasRenderer Component maximizeGameObject.AddComponent<CanvasRenderer>(); #endregion //=========================================================================== // Image Component //=========================================================================== #region Image Component Image maximizeImage = maximizeGameObject.AddComponent<Image>(); maximizeImage.sprite = Assets.Common.DockWidgets.Textures.maximizeButton.sprite; maximizeImage.type = Image.Type.Sliced; #endregion //=========================================================================== // Button Component //=========================================================================== #region Button Component Button maximizeButton = maximizeGameObject.AddComponent<Button>(); maximizeButton.targetGraphic = maximizeImage; maximizeButton.transition = Selectable.Transition.SpriteSwap; maximizeButton.spriteState = Assets.Common.DockWidgets.SpriteStates.maximizeButton.spriteState; maximizeButton.onClick.AddListener(OnMaximizeClicked); #endregion #endregion #endregion //*************************************************************************** // DockingArea GameObject //*************************************************************************** #region DockingArea GameObject GameObject dockingArea = new GameObject("DockingArea"); Utils.InitUIObject(dockingArea, contentTransform); //=========================================================================== // RectTransform Component //=========================================================================== #region RectTransform Component RectTransform dockingAreaTransform = dockingArea.AddComponent<RectTransform>(); Utils.AlignRectTransformStretchStretch(dockingAreaTransform, 0f, 5f, 0f, 0f); #endregion //=========================================================================== // DockingAreaScript Component //=========================================================================== #region DockingAreaScript Component mDockingAreaScript = dockingArea.AddComponent<DockingAreaScript>(); mDockingAreaScript.AddChildlessListener(Close); mDockWidget.InsertToDockingArea(mDockingAreaScript); #endregion #endregion }