Skip to content

Commit 4a1383e

Browse files
committed
fix: Fixed flickering window width when opening the dropdown
Also refactored DropdownWindow a bit
1 parent 85f834a commit 4a1383e

File tree

3 files changed

+102
-72
lines changed

3 files changed

+102
-72
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
namespace TypeReferences.Editor.TypeDropdown
2+
{
3+
using System;
4+
using SolidUtilities.Editor.Extensions;
5+
using SolidUtilities.Editor.Helpers;
6+
using SolidUtilities.Extensions;
7+
using UnityEngine;
8+
using Util;
9+
10+
internal partial class DropdownWindow
11+
{
12+
private PreventExpandingHeight _preventExpandingHeight;
13+
private float _contentHeight;
14+
private float _optimalWidth;
15+
private Rect _positionOnCreation;
16+
private bool _positionWasSetAfterCreation;
17+
18+
public static float CalculateOptimalWidth(string[] selectionPaths)
19+
{
20+
float windowWidth = PopupHelper.CalculatePopupWidth(
21+
selectionPaths,
22+
DropdownStyle.DefaultLabelStyle,
23+
(int) DropdownStyle.GlobalOffset,
24+
(int) DropdownStyle.IndentWidth,
25+
false);
26+
27+
return windowWidth < DropdownStyle.MinWindowWidth ? DropdownStyle.MinWindowWidth : windowWidth;
28+
}
29+
30+
private Rect GetWindowRect(Vector2 windowPosition, float windowHeight)
31+
{
32+
var windowSize = new Vector2(_optimalWidth, GetWindowHeight(windowHeight));
33+
windowPosition.x = GetWindowXPosition(windowPosition.x, windowSize.x);
34+
windowPosition.y = GetWindowYPosition(windowPosition.y, windowSize.y);
35+
return new Rect(windowPosition, windowSize);
36+
}
37+
38+
private float GetWindowHeight(float windowHeight)
39+
{
40+
// If given less than 100f, the window will re-position to the top left corner. If given 0f on MacOS,
41+
// the window may not appear at all. Thus, the minimal value is 100f.
42+
const float minHeightOnStart = 100f;
43+
return windowHeight < 100f ? minHeightOnStart : windowHeight;
44+
}
45+
46+
private float GetWindowYPosition(float requestedYPosition, float windowHeight)
47+
{
48+
float distanceToBottomBorder = EditorGUIUtilityHelper.GetMainWindowPosition().yMax - requestedYPosition;
49+
50+
if (distanceToBottomBorder < windowHeight)
51+
{
52+
return EditorGUIUtilityHelper.GetMainWindowPosition().yMax - windowHeight;
53+
}
54+
55+
return requestedYPosition;
56+
}
57+
58+
private float GetWindowXPosition(float requestedXPosition, float windowWidth)
59+
{
60+
// If the window width is smaller than the distance from cursor to the right border of the window, the
61+
// window will not appear because the cursor is outside of the window and OnGUI will never be called.
62+
float screenWidth = EditorGUIUtilityHelper.GetScreenWidth();
63+
requestedXPosition -=
64+
8f; // This will make the window appear so that foldout arrows are precisely below the cursor.
65+
float distanceToRightBorder = screenWidth - requestedXPosition;
66+
67+
if (windowWidth > distanceToRightBorder)
68+
{
69+
requestedXPosition = screenWidth - windowWidth;
70+
}
71+
72+
return requestedXPosition;
73+
}
74+
75+
private void AdjustSizeIfNeeded()
76+
{
77+
float widthToSet = -1f;
78+
float heightToSet = -1f;
79+
80+
if (_optimalWidth.DoesNotEqualApproximately(position.width))
81+
widthToSet = _optimalWidth;
82+
83+
float wantedHeight = Math.Min(_contentHeight, DropdownStyle.MaxWindowHeight);
84+
85+
if (_preventExpandingHeight && wantedHeight != 0f &&
86+
wantedHeight.DoesNotEqualApproximately(position.height))
87+
heightToSet = wantedHeight;
88+
89+
if (widthToSet == -1f && heightToSet == -1f)
90+
return;
91+
92+
this.Resize(widthToSet, heightToSet);
93+
}
94+
}
95+
}

Editor/TypeDropdown/DropdownWindow.Position.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Editor/TypeDropdown/DropdownWindow.cs

Lines changed: 4 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,9 @@
1111
internal enum DropdownWindowType { Dropdown, Popup }
1212

1313
/// <summary>Creates a dropdown window that shows the <see cref="SelectionTree"/> elements.</summary>
14-
internal class DropdownWindow : EditorWindow
14+
internal partial class DropdownWindow : EditorWindow
1515
{
1616
private SelectionTree _selectionTree;
17-
private PreventExpandingHeight _preventExpandingHeight;
18-
private float _contentHeight;
19-
private float _optimalWidth;
20-
21-
private Rect _positionOnCreation;
22-
private bool _positionWasSetAfterCreation;
2317

2418
public static DropdownWindow Create(SelectionTree selectionTree, int windowHeight, Vector2 windowPosition, DropdownWindowType windowType)
2519
{
@@ -64,55 +58,6 @@ private void OnCreate(SelectionTree selectionTree, float windowHeight, Vector2 w
6458
}
6559
}
6660

67-
public static float CalculateOptimalWidth(string[] selectionPaths)
68-
{
69-
float windowWidth = PopupHelper.CalculatePopupWidth(
70-
selectionPaths,
71-
DropdownStyle.DefaultLabelStyle,
72-
(int) DropdownStyle.GlobalOffset,
73-
(int) DropdownStyle.IndentWidth,
74-
false);
75-
76-
return windowWidth < DropdownStyle.MinWindowWidth ? DropdownStyle.MinWindowWidth : windowWidth;
77-
}
78-
79-
private static void ResetControl()
80-
{
81-
GUIUtility.hotControl = 0;
82-
GUIUtility.keyboardControl = 0;
83-
}
84-
85-
private Rect GetWindowRect(Vector2 windowPosition, float windowHeight)
86-
{
87-
// If the window width is smaller than the distance from cursor to the right border of the window, the
88-
// window will not appear because the cursor is outside of the window and OnGUI will never be called.
89-
float screenWidth = EditorGUIUtilityHelper.GetScreenWidth();
90-
windowPosition.x -= 8f; // This will make the window appear so that foldout arrows are precisely below the cursor.
91-
float distanceToRightBorder = screenWidth - windowPosition.x;
92-
93-
if (_optimalWidth > distanceToRightBorder)
94-
{
95-
distanceToRightBorder = _optimalWidth;
96-
windowPosition.x = screenWidth - _optimalWidth;
97-
}
98-
99-
// If given less than 100f, the window will re-position to the top left corner. If given 0f on MacOS,
100-
// the window may not appear at all. Thus, the minimal value is 100f.
101-
const float minHeightOnStart = 100f;
102-
windowHeight = windowHeight < 100f ? minHeightOnStart : windowHeight;
103-
104-
float distanceToBottomBorder = EditorGUIUtilityHelper.GetMainWindowPosition().yMax - windowPosition.y;
105-
106-
if (distanceToBottomBorder < windowHeight)
107-
{
108-
windowPosition.y = EditorGUIUtilityHelper.GetMainWindowPosition().yMax - windowHeight;
109-
}
110-
111-
var windowSize = new Vector2(distanceToRightBorder, windowHeight);
112-
113-
return new Rect(windowPosition, windowSize);
114-
}
115-
11661
private void OnGUI()
11762
{
11863
CloseOnEscPress();
@@ -136,23 +81,10 @@ private void Update()
13681

13782
private void OnLostFocus() => Close();
13883

139-
private void AdjustSizeIfNeeded()
84+
private static void ResetControl()
14085
{
141-
float widthToSet = -1f;
142-
float heightToSet = -1f;
143-
144-
if (_optimalWidth.DoesNotEqualApproximately(position.width))
145-
widthToSet = _optimalWidth;
146-
147-
float wantedHeight = Math.Min(_contentHeight, DropdownStyle.MaxWindowHeight);
148-
149-
if (_preventExpandingHeight && wantedHeight != 0f && wantedHeight.DoesNotEqualApproximately(position.height))
150-
heightToSet = wantedHeight;
151-
152-
if (widthToSet == -1f && heightToSet == -1f)
153-
return;
154-
155-
this.Resize(widthToSet, heightToSet);
86+
GUIUtility.hotControl = 0;
87+
GUIUtility.keyboardControl = 0;
15688
}
15789

15890
private void CloseOnEscPress()

0 commit comments

Comments
 (0)