A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections.Generic;
3
4using UnityEditor;
5using UnityEditor.IMGUI.Controls;
6using UnityEngine;
7
8using Codice.CM.Common;
9using PlasticGui;
10using PlasticGui.WorkspaceWindow.Locks;
11using Unity.PlasticSCM.Editor.UI;
12using Unity.PlasticSCM.Editor.UI.Tree;
13
14namespace Unity.PlasticSCM.Editor.Views.Locks
15{
16 internal sealed class LocksListView :
17 PlasticTreeView,
18 FillLocksTable.IShowContentView,
19 FillLocksTable.ILocksList
20 {
21 internal GenericMenu Menu { get { return mMenu.Menu; } }
22 internal string EmptyStateMessage { get { return mEmptyStateData.Content.text; } }
23
24 internal LocksListView(
25 RepositorySpec repSpec,
26 LocksListHeaderState headerState,
27 List<string> columnNames,
28 LocksViewMenu menu,
29 Action selectionChangedAction,
30 Action repaintAction)
31 {
32 mRepSpec = repSpec;
33 mColumnNames = columnNames;
34 mMenu = menu;
35 mSelectionChangedAction = selectionChangedAction;
36 mRepaintAction = repaintAction;
37
38 mLocksSelector = new LocksSelector(this, mListViewItemIds);
39
40 mCooldownFilterAction = new CooldownWindowDelayer(
41 DelayedSearchChanged, UnityConstants.SEARCH_DELAYED_INPUT_ACTION_INTERVAL);
42
43 mCooldownSelectionAction = new CooldownWindowDelayer(
44 DelayedSelectionChanged, UnityConstants.SELECTION_DELAYED_INPUT_ACTION_INTERVAL);
45
46 SetupTreeView(headerState);
47 }
48
49 public override void OnGUI(Rect rect)
50 {
51 base.OnGUI(rect);
52
53 mEmptyStateData.UpdateValidRect(rect, Event.current.type, mRepaintAction);
54
55 if (mRows.Count == 0)
56 DrawTreeViewEmptyState.For(mEmptyStateData);
57
58 Event e = Event.current;
59
60 if (e.type != EventType.KeyDown)
61 return;
62
63 bool isProcessed = mMenu.ProcessKeyActionIfNeeded(e);
64
65 if (isProcessed)
66 e.Use();
67 }
68
69 protected override IList<TreeViewItem> BuildRows(
70 TreeViewItem rootItem)
71 {
72 if (mLocksList == null)
73 {
74 ClearRows(rootItem, mRows);
75
76 return mRows;
77 }
78
79 RegenerateRows(
80 mListViewItemIds,
81 mLocksList,
82 rootItem,
83 mRows);
84
85 return mRows;
86 }
87
88 protected override void SearchChanged(string newSearch)
89 {
90 mCooldownFilterAction.Ping();
91 }
92
93 protected override void SelectionChanged(IList<int> selectedIds)
94 {
95 mCooldownSelectionAction.Ping();
96 }
97
98 protected override void ContextClickedItem(int id)
99 {
100 mMenu.Popup();
101 Repaint();
102 }
103
104 protected override void RowGUI(RowGUIArgs args)
105 {
106 if (args.item is LocksListViewItem)
107 {
108 LocksListViewItemGUI(
109 mRepSpec,
110 rowHeight,
111 ((LocksListViewItem)args.item).LockInfo,
112 args,
113 Repaint);
114 return;
115 }
116
117 base.RowGUI(args);
118 }
119
120 internal void OnDisable()
121 {
122 TreeHeaderSettings.Save(
123 multiColumnHeader.state,
124 UnityConstants.LOCKS_TABLE_SETTINGS_NAME);
125 }
126
127 internal List<LockInfo> GetSelectedLocks()
128 {
129 return mLocksSelector.GetSelectedLocks();
130 }
131
132 void FillLocksTable.IShowContentView.ShowContentPanel()
133 {
134 mEmptyStateData.UpdateText(string.Empty);
135
136 Reload();
137
138 mLocksSelector.RestoreSelectedLocks();
139 }
140
141 void FillLocksTable.IShowContentView.ShowEmptyStatePanel(string explanationText)
142 {
143 mEmptyStateData.UpdateText(explanationText);
144
145 Reload();
146 }
147
148 void FillLocksTable.IShowContentView.ShowErrorPanel(string errorText)
149 {
150 Debug.LogErrorFormat(
151 PlasticLocalization.Name.LoadLocksErrorExplanation.GetString(),
152 errorText);
153
154 mEmptyStateData.UpdateText(
155 PlasticLocalization.Name.LoadLocksError.GetString());
156
157 mLocksList = null;
158 mListViewItemIds.Clear();
159
160 Reload();
161 }
162
163 void FillLocksTable.ILocksList.Fill(LockInfoList lockInfoList, Filter filter)
164 {
165 mLocksSelector.SaveSelectedLocks();
166
167 mListViewItemIds.Clear();
168
169 mLocksList = lockInfoList;
170
171 Filter();
172 Sort();
173 }
174
175 void Filter()
176 {
177 if (mLocksList == null)
178 return;
179
180 mLocksList.Filter(new Filter(searchString));
181 }
182
183 void Sort()
184 {
185 if (mLocksList == null)
186 return;
187
188 int sortedColumnIdx = multiColumnHeader.state.sortedColumnIndex;
189 bool sortAscending = multiColumnHeader.IsSortedAscending(sortedColumnIdx);
190
191 mLocksList.Sort(mColumnNames[sortedColumnIdx], sortAscending);
192 }
193
194 void DelayedSearchChanged()
195 {
196 Filter();
197
198 Reload();
199
200 TableViewOperations.ScrollToSelection(this);
201 }
202
203 void DelayedSelectionChanged()
204 {
205 mSelectionChangedAction();
206 }
207
208 void SortingChanged(MultiColumnHeader header)
209 {
210 Sort();
211
212 Reload();
213 }
214
215 void SetupTreeView(LocksListHeaderState headerState)
216 {
217 TreeHeaderSettings.Load(
218 headerState,
219 UnityConstants.LOCKS_TABLE_SETTINGS_NAME,
220 (int)LocksListColumn.ModificationDate,
221 false);
222
223 multiColumnHeader = new MultiColumnHeader(headerState);
224 multiColumnHeader.canSort = true;
225 multiColumnHeader.sortingChanged += SortingChanged;
226 }
227
228 static void RegenerateRows(
229 ListViewItemIds<LockInfo> listViewItemIds,
230 LockInfoList locksList,
231 TreeViewItem rootItem,
232 List<TreeViewItem> rows)
233 {
234 ClearRows(rootItem, rows);
235
236 if (locksList == null)
237 return;
238
239 foreach (LockInfo lockInfo in locksList.GetLocks())
240 {
241 int objectId;
242 if (!listViewItemIds.TryGetInfoItemId(lockInfo, out objectId))
243 objectId = listViewItemIds.AddInfoItem(lockInfo);
244
245 LocksListViewItem lockListViewItem =
246 new LocksListViewItem(objectId, lockInfo);
247
248 rootItem.AddChild(lockListViewItem);
249 rows.Add(lockListViewItem);
250 }
251 }
252
253 static void ClearRows(
254 TreeViewItem rootItem,
255 List<TreeViewItem> rows)
256 {
257 if (rootItem.hasChildren)
258 rootItem.children.Clear();
259
260 rows.Clear();
261 }
262
263 static void LocksListViewItemGUI(
264 RepositorySpec repSpec,
265 float rowHeight,
266 LockInfo item,
267 RowGUIArgs args,
268 Action avatarLoadedAction)
269 {
270 for (var visibleColumnIdx = 0; visibleColumnIdx < args.GetNumVisibleColumns(); visibleColumnIdx++)
271 {
272 var cellRect = args.GetCellRect(visibleColumnIdx);
273
274 if (visibleColumnIdx == 0)
275 {
276 cellRect.x += UnityConstants.FIRST_COLUMN_WITHOUT_ICON_INDENT;
277 cellRect.width -= UnityConstants.FIRST_COLUMN_WITHOUT_ICON_INDENT;
278 }
279
280 var column = (LocksListColumn) args.GetColumn(visibleColumnIdx);
281
282 DrawLocksListViewItem.ForCell(
283 repSpec,
284 cellRect,
285 rowHeight,
286 item,
287 column,
288 avatarLoadedAction,
289 args.selected,
290 args.focused);
291 }
292 }
293
294
295 ListViewItemIds<LockInfo> mListViewItemIds = new ListViewItemIds<LockInfo>();
296
297 LockInfoList mLocksList;
298
299 readonly EmptyStateData mEmptyStateData = new EmptyStateData();
300 readonly CooldownWindowDelayer mCooldownFilterAction;
301 readonly CooldownWindowDelayer mCooldownSelectionAction;
302 readonly LocksSelector mLocksSelector;
303 readonly Action mSelectionChangedAction;
304 readonly Action mRepaintAction;
305 readonly LocksViewMenu mMenu;
306 readonly List<string> mColumnNames;
307 readonly RepositorySpec mRepSpec;
308 }
309}