A game about forced loneliness, made by TACStudios
1using UnityEditor;
2using UnityEngine;
3
4using PlasticGui;
5using PlasticGui.WorkspaceWindow;
6using Unity.PlasticSCM.Editor.Developer;
7
8namespace Unity.PlasticSCM.Editor.UI.StatusBar
9{
10 internal class StatusBar
11 {
12 internal interface IIncomingChangesNotification
13 {
14 bool HasNotification { get; }
15 void OnGUI();
16 }
17
18 internal class IncomingChangesNotificationData
19 {
20 internal string InfoText { get; private set; }
21 internal string ActionText { get; private set; }
22 internal string TooltipText { get; private set; }
23 internal bool HasUpdateAction { get; private set; }
24 internal PlasticNotification.Status Status { get; private set; }
25
26 internal void UpdateData(
27 string infoText,
28 string actionText,
29 string tooltipText,
30 bool hasUpdateAction,
31 PlasticNotification.Status status)
32 {
33 InfoText = infoText;
34 ActionText = actionText;
35 TooltipText = tooltipText;
36 HasUpdateAction = hasUpdateAction;
37 Status = status;
38 }
39
40 internal void Clear()
41 {
42 InfoText = string.Empty;
43 ActionText = string.Empty;
44 TooltipText = string.Empty;
45 HasUpdateAction = false;
46 Status = PlasticNotification.Status.None;
47 }
48 }
49
50 internal interface IShelvedChangesNotification :
51 CheckShelvedChanges.IUpdateShelvedChangesNotification
52 {
53 bool HasNotification { get; }
54 void SetWorkspaceWindow(
55 WorkspaceWindow workspaceWindow);
56 void SetShelvedChangesUpdater(
57 IShelvedChangesUpdater shelvedChangesUpdater);
58 void OnGUI();
59 }
60
61 internal void Notify(INotificationContent content, MessageType type, Texture2D image)
62 {
63 mNotification = new Notification(
64 content,
65 type,
66 image);
67 mCooldownNotificationClearAction.Ping();
68 }
69
70 internal NotificationBar NotificationBar { get; private set; }
71
72 internal StatusBar()
73 {
74 mCooldownNotificationClearAction = new CooldownWindowDelayer(
75 DelayedClearNotification,
76 UnityConstants.NOTIFICATION_CLEAR_INTERVAL);
77
78 NotificationBar = new NotificationBar();
79 }
80
81 internal void Initialize(
82 WorkspaceWindow workspaceWindow,
83 IIncomingChangesNotification incomingChangesNotification,
84 IShelvedChangesNotification shelvedChangesNotification)
85 {
86 mWorkspaceWindow = workspaceWindow;
87 mIncomingChangesNotification = incomingChangesNotification;
88 mShelvedChangesNotification = shelvedChangesNotification;
89
90 if (incomingChangesNotification is IncomingChangesNotification)
91 ((IncomingChangesNotification)incomingChangesNotification).SetWorkspaceWindow(workspaceWindow);
92
93 shelvedChangesNotification.SetWorkspaceWindow(workspaceWindow);
94 }
95
96 void DelayedClearNotification()
97 {
98 mNotification = null;
99 }
100
101 internal void OnGUI()
102 {
103 if (NotificationBar.HasNotification &&
104 NotificationBar.IsVisible)
105 {
106 BeginDrawBar();
107 NotificationBar.OnGUI();
108 EndDrawBar();
109 }
110
111 BeginDrawBar();
112
113 if (NotificationBar.HasNotification)
114 {
115 DrawNotificationAvailablePanel(NotificationBar);
116 }
117
118 if (mIncomingChangesNotification.HasNotification)
119 {
120 mIncomingChangesNotification.OnGUI();
121 }
122
123 if (mShelvedChangesNotification.HasNotification)
124 {
125 if (mIncomingChangesNotification.HasNotification)
126 EditorGUILayout.Space(15);
127
128 mShelvedChangesNotification.OnGUI();
129 }
130
131 if (mNotification != null)
132 DrawNotification(mNotification);
133
134 GUILayout.FlexibleSpace();
135
136 DrawWorkspaceStatus(mWorkspaceWindow);
137
138 EndDrawBar();
139
140 Rect lastRect = GUILayoutUtility.GetLastRect();
141
142 if (MouseEntered(mIsMouseOver, lastRect))
143 {
144 mIsMouseOver = true;
145 mCooldownNotificationClearAction.Pause();
146 }
147
148 if (MouseExited(mIsMouseOver, lastRect))
149 {
150 mIsMouseOver = false;
151 mCooldownNotificationClearAction.Resume();
152 }
153 }
154
155 internal static void DrawNotification(INotificationContent notification)
156 {
157 GUILayout.BeginVertical();
158 GUILayout.FlexibleSpace();
159
160 notification.OnGUI();
161
162 GUILayout.FlexibleSpace();
163 GUILayout.EndVertical();
164 }
165
166 internal static bool DrawButton(GUIContent content)
167 {
168 GUIStyle buttonStyle = new GUIStyle(EditorStyles.miniButton);
169
170 Rect rt = GUILayoutUtility.GetRect(
171 content,
172 buttonStyle,
173 GUILayout.Width(60));
174
175 return GUI.Button(
176 rt,
177 content,
178 buttonStyle);
179 }
180
181 static void DrawNotificationAvailablePanel(
182 NotificationBar notificationBar)
183 {
184 GUILayout.BeginVertical();
185 GUILayout.FlexibleSpace();
186
187 if (GUILayout.Button(PlasticLocalization.GetString(
188 notificationBar.IsVisible ?
189 PlasticLocalization.Name.HideNotification :
190 PlasticLocalization.Name.ShowNotification)))
191 {
192 notificationBar.SetVisibility(!notificationBar.IsVisible);
193 }
194
195 GUILayout.FlexibleSpace();
196 GUILayout.EndVertical();
197 }
198
199 static void DrawNotification(Notification notification)
200 {
201 DrawIcon(notification.Image);
202 DrawNotification(notification.Content);
203 }
204
205 static void DrawWorkspaceStatus(WorkspaceWindow workspaceWindow)
206 {
207 DrawIcon(Images.GetBranchIcon());
208
209 if (workspaceWindow.WorkspaceStatus == null)
210 return;
211
212 DrawWorkspaceStatusLabel(string.Format(
213 "{0}@{1}@{2}",
214 workspaceWindow.WorkspaceStatus.ObjectSpec,
215 workspaceWindow.WorkspaceStatus.RepositoryName,
216 workspaceWindow.ServerDisplayName));
217 }
218
219 internal static void DrawIcon(Texture2D icon, int size = UnityConstants.STATUS_BAR_ICON_SIZE)
220 {
221 GUILayout.BeginVertical();
222 GUILayout.FlexibleSpace();
223
224 GUILayout.Label(
225 icon,
226 UnityStyles.StatusBar.Icon,
227 GUILayout.Height(size),
228 GUILayout.Width(size));
229
230 GUILayout.FlexibleSpace();
231 GUILayout.EndVertical();
232 }
233
234 static void DrawWorkspaceStatusLabel(string label)
235 {
236 GUILayout.BeginVertical();
237 GUILayout.FlexibleSpace();
238
239 DrawCopyableLabel.For(label, UnityStyles.StatusBar.Label);
240
241 GUILayout.FlexibleSpace();
242 GUILayout.EndVertical();
243 }
244
245 static void BeginDrawBar()
246 {
247 EditorGUILayout.BeginVertical(
248 GetBarStyle(),
249 GUILayout.Height(UnityConstants.STATUS_BAR_HEIGHT));
250 GUILayout.FlexibleSpace();
251 EditorGUILayout.BeginHorizontal();
252 }
253
254 static void EndDrawBar()
255 {
256 EditorGUILayout.EndHorizontal();
257 GUILayout.FlexibleSpace();
258 EditorGUILayout.EndVertical();
259 }
260
261 static GUIStyle GetBarStyle()
262 {
263 if (sBarTexture == null)
264 sBarTexture = new Texture2D(1, 1);
265
266 if (sBarStyle == null)
267 sBarStyle = new GUIStyle();
268
269 sBarTexture.SetPixel(0, 0, UnityStyles.Colors.BackgroundBar);
270 sBarTexture.Apply();
271 sBarStyle.normal.background = sBarTexture;
272
273 return sBarStyle;
274 }
275
276 static bool MouseEntered(
277 bool isMouseOver,
278 Rect lastRect)
279 {
280 bool isInside = lastRect.Contains(Event.current.mousePosition);
281 return isInside && !isMouseOver;
282 }
283
284 static bool MouseExited(
285 bool isMouseOver,
286 Rect lastRect)
287 {
288 bool isInside = lastRect.Contains(Event.current.mousePosition);
289 return !isInside && isMouseOver;
290 }
291
292 class Notification
293 {
294 internal INotificationContent Content { get; private set; }
295 internal MessageType MessageType { get; private set; }
296 internal Texture2D Image { get; private set; }
297
298 internal Notification(INotificationContent content, MessageType messageType, Texture2D image)
299 {
300 Content = content;
301 MessageType = messageType;
302 Image = image;
303 }
304 }
305
306 Notification mNotification;
307 WorkspaceWindow mWorkspaceWindow;
308 IIncomingChangesNotification mIncomingChangesNotification;
309 IShelvedChangesNotification mShelvedChangesNotification;
310 bool mIsMouseOver = false;
311
312 readonly CooldownWindowDelayer mCooldownNotificationClearAction;
313
314 static Texture2D sBarTexture;
315 static GUIStyle sBarStyle;
316 }
317}