Skip to content

Commit 6e214c8

Browse files
author
Stewart Miles
committed
Added custom window to clean up files.
Changed the Version Handler prompts to clean up obsolete files to use a custom editor window rather than the EditorUtility dialog which can exceed the screen size. Bug: 132688405 Fixes #215 Change-Id: Iefbca2ae8b7c6c0dc94758412a8cb0a48ba4ab7b
1 parent 780aef4 commit 6e214c8

File tree

3 files changed

+329
-49
lines changed

3 files changed

+329
-49
lines changed

source/VersionHandlerImpl/VersionHandlerImpl.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
<Compile Include="src\Logger.cs" />
5656
<Compile Include="src\ExecutionEnvironment.cs" />
5757
<Compile Include="src\FileUtils.cs" />
58+
<Compile Include="src\MultiSelectWindow.cs" />
5859
<Compile Include="src\ProjectSettings.cs" />
5960
<Compile Include="src\RunOnMainThread.cs" />
6061
<Compile Include="src\SettingsDialog.cs" />
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
// <copyright file="MultiSelectWindow.cs" company="Google Inc.">
2+
// Copyright (C) 2019 Google Inc. All Rights Reserved.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
// </copyright>
16+
17+
using System;
18+
using System.Collections.Generic;
19+
using UnityEditor;
20+
using UnityEngine;
21+
22+
namespace Google {
23+
24+
/// <summary>
25+
/// Window that displays a list of optionally selected items.
26+
/// </summary>
27+
public class MultiSelectWindow : EditorWindow {
28+
29+
/// <summary>
30+
/// Position of the window.
31+
/// </summary>
32+
private Vector2 scrollPosition = new Vector2(0, 0);
33+
34+
/// <summary>
35+
/// Index of each item to select mapped to the sorted set of items to display.
36+
/// </summary>
37+
private List<KeyValuePair<int, KeyValuePair<string, string>>> sortedItems;
38+
39+
/// <summary>
40+
/// Items to display for selection, the Key of each item is stored in the selection
41+
/// the Value is rendered in the view.
42+
/// </summary>
43+
public List<KeyValuePair<string, string>> AvailableItems { get; set; }
44+
45+
/// <summary>
46+
/// Set of items that have been selected.
47+
/// </summary>
48+
public HashSet<string> SelectedItems { get; set; }
49+
50+
/// <summary>
51+
/// Caption for the top of the window.
52+
/// </summary>
53+
public string Caption { get; set; }
54+
55+
/// <summary>
56+
/// Caption for the button to apply the selection.
57+
/// </summary>
58+
public string ApplyLabel { get; set; }
59+
60+
/// <summary>
61+
/// Action to execute when the selection is applied.
62+
/// </summary>
63+
public Action OnApply;
64+
65+
/// <summary>
66+
/// Caption for the button to cancel the selection.
67+
/// </summary>
68+
public string CancelLabel { get; set; }
69+
70+
/// <summary>
71+
/// Action to execute when the selection is canceled.
72+
/// </summary>
73+
public Action OnCancel;
74+
75+
/// <summary>
76+
/// Styles for unselected items in the list.
77+
/// </summary>
78+
private GUIStyle[] unselectedItemStyles;
79+
80+
/// <summary>
81+
/// Styles for selected items in the list.
82+
/// </summary>
83+
private GUIStyle[] selectedItemStyles;
84+
85+
/// <summary>
86+
/// Initialize the window.
87+
/// </summary>
88+
protected MultiSelectWindow() {
89+
Initialize();
90+
}
91+
92+
/// <summary>
93+
/// Reset the window to its default state.
94+
/// </summary>
95+
public virtual void Initialize() {
96+
AvailableItems = new List<KeyValuePair<string, string>>();
97+
InitializeSortedItems();
98+
SelectedItems = new HashSet<string>();
99+
ApplyLabel = "Apply";
100+
CancelLabel = "Cancel";
101+
scrollPosition = new Vector2(0, 0);
102+
minSize = new Vector2(300, 200);
103+
unselectedItemStyles = null;
104+
selectedItemStyles = null;
105+
}
106+
107+
/// <summary>
108+
/// Select all items.
109+
/// </summary>
110+
public virtual void SelectAll() {
111+
if (AvailableItems != null) {
112+
SelectedItems = new HashSet<string>();
113+
foreach (var item in AvailableItems) SelectedItems.Add(item.Key);
114+
} else {
115+
SelectNone();
116+
}
117+
}
118+
119+
/// <summary>
120+
/// Select no items.
121+
/// </summary>
122+
public virtual void SelectNone() {
123+
SelectedItems = new HashSet<string>();
124+
}
125+
126+
/// <summary>
127+
/// Initialize the sortedItems array from the available items.
128+
/// </summary>
129+
private void InitializeSortedItems() {
130+
sortedItems = new List<KeyValuePair<int, KeyValuePair<string, string>>>();
131+
if (AvailableItems != null) {
132+
for (int i = 0; i < AvailableItems.Count; ++i) {
133+
sortedItems.Add(new KeyValuePair<int, KeyValuePair<string, string>>(
134+
i, new KeyValuePair<string, string>(AvailableItems[i].Key,
135+
AvailableItems[i].Value)));
136+
}
137+
}
138+
}
139+
140+
/// <summary>
141+
/// Sort the set of items.
142+
/// </summary>
143+
/// <param name="direction">1 to sort ascending, -1 to sort descending.</param>
144+
public virtual void Sort(int direction) {
145+
if (AvailableItems != null) {
146+
InitializeSortedItems();
147+
sortedItems.Sort((lhs, rhs) => {
148+
return direction > 0 ?
149+
String.Compare(lhs.Value.Value, rhs.Value.Value) :
150+
String.Compare(rhs.Value.Value, lhs.Value.Value);
151+
});
152+
}
153+
}
154+
155+
/// <summary>
156+
/// Lazily configure the styles used to draw items in the window.
157+
/// Default styles in some versions of Unity are not accessible until OnGUI().
158+
/// </summary>
159+
protected virtual void InitializeStyles() {
160+
// Configure unselected styles with alternating normal states.
161+
if (unselectedItemStyles == null) {
162+
unselectedItemStyles = new GUIStyle[2];
163+
unselectedItemStyles[0] = EditorStyles.label;
164+
unselectedItemStyles[1] = EditorStyles.textField;
165+
}
166+
if (selectedItemStyles == null && unselectedItemStyles != null) {
167+
// Configure selected styles by overriding the font style.
168+
selectedItemStyles = new GUIStyle[unselectedItemStyles.Length];
169+
for (int i = 0; i < unselectedItemStyles.Length; ++i) {
170+
var style = new GUIStyle(unselectedItemStyles[i]);
171+
style.font = EditorStyles.boldLabel.font;
172+
selectedItemStyles[i] = style;
173+
}
174+
}
175+
if (AvailableItems != null && sortedItems.Count != AvailableItems.Count) {
176+
InitializeSortedItems();
177+
}
178+
}
179+
180+
/// <summary>
181+
/// Draw the window.
182+
/// </summary>
183+
protected virtual void OnGUI() {
184+
InitializeStyles();
185+
if (!String.IsNullOrEmpty(Caption)) {
186+
EditorGUILayout.BeginHorizontal();
187+
EditorGUILayout.SelectableLabel(Caption);
188+
EditorGUILayout.EndHorizontal();
189+
EditorGUILayout.Space();
190+
}
191+
EditorGUILayout.BeginVertical();
192+
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
193+
int displayIndex = 0;
194+
foreach (var indexAndItem in sortedItems) {
195+
var item = indexAndItem.Value.Key;
196+
var display = indexAndItem.Value.Value;
197+
bool selected = SelectedItems.Contains(item);
198+
EditorGUILayout.BeginHorizontal(
199+
selected ? selectedItemStyles[displayIndex % selectedItemStyles.Length] :
200+
unselectedItemStyles[displayIndex % unselectedItemStyles.Length]);
201+
bool currentlySelected = EditorGUILayout.ToggleLeft(display, selected);
202+
if (currentlySelected != selected) {
203+
if (currentlySelected) {
204+
SelectedItems.Add(item);
205+
} else {
206+
SelectedItems.Remove(item);
207+
}
208+
}
209+
EditorGUILayout.EndHorizontal();
210+
displayIndex++;
211+
}
212+
EditorGUILayout.EndScrollView();
213+
EditorGUILayout.EndVertical();
214+
EditorGUILayout.BeginHorizontal();
215+
if (GUILayout.Button("All")) SelectAll();
216+
if (GUILayout.Button("None")) SelectNone();
217+
EditorGUILayout.Space();
218+
EditorGUILayout.Space();
219+
bool cancel = GUILayout.Button(CancelLabel);
220+
bool apply = GUILayout.Button(ApplyLabel);
221+
EditorGUILayout.EndHorizontal();
222+
EditorGUILayout.Space();
223+
if (cancel || apply) {
224+
if (cancel && OnCancel != null) OnCancel();
225+
if (apply && OnApply != null) OnApply();
226+
Close();
227+
}
228+
}
229+
230+
/// <summary>
231+
/// Get the existing multi-select window or create a new one.
232+
/// </summary>
233+
/// <param name="title">Title to display on the window.</param>
234+
/// <returns>Reference to this class</returns>
235+
public static MultiSelectWindow CreateMultiSelectWindow(string title) {
236+
MultiSelectWindow window = (MultiSelectWindow)EditorWindow.GetWindow(
237+
typeof(MultiSelectWindow), true, title, true);
238+
window.Initialize();
239+
return window;
240+
}
241+
}
242+
}

0 commit comments

Comments
 (0)