289 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			289 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using System; | ||
|  | 
 | ||
|  | using UnityEditor; | ||
|  | using UnityEngine; | ||
|  | 
 | ||
|  | using Codice.CM.Common; | ||
|  | using PlasticGui; | ||
|  | using Unity.PlasticSCM.Editor.Toolbar.PopupWindow.BranchesList; | ||
|  | using Unity.PlasticSCM.Editor.Toolbar.PopupWindow.Operations; | ||
|  | using Unity.PlasticSCM.Editor.UI; | ||
|  | 
 | ||
|  | namespace Unity.PlasticSCM.Editor.Toolbar.PopupWindow | ||
|  | { | ||
|  |     internal class ControlledPopupWindow : PopupWindowContent, BranchesTreeView.IClickListener | ||
|  |     { | ||
|  |         internal ControlledPopupWindow( | ||
|  |             ControlledPopupOperations operations, | ||
|  |             Action<ControlledPopupWindow> refreshBranches, | ||
|  |             Func<BranchInfo> fetchWorkingBranch, | ||
|  |             Action repaintToolbar, | ||
|  |             Vector2 size) | ||
|  |         { | ||
|  |             mOperations = operations; | ||
|  |             mRefreshBranches = refreshBranches; | ||
|  |             mRepaintToolbar = repaintToolbar; | ||
|  |             mSize = size; | ||
|  | 
 | ||
|  |             mProgressBar = new PopupupProgressBar(Repaint); | ||
|  |             mTreeView = new BranchesTreeView(this); | ||
|  |             mTreeView.SetWorkingBranch(fetchWorkingBranch); | ||
|  | 
 | ||
|  |             mEmptyState = new NoBranchesEmptyState(CreateBranch, Repaint); | ||
|  |             mLoadingEmptyState = new LoadingEmptyState(Repaint); | ||
|  |             mErrorEmptyState = new ErrorEmptyState(RefreshBranches, Repaint); | ||
|  | 
 | ||
|  |             mDelayedFilterAction = new DelayedActionBySecondsRunner( | ||
|  |                 DelayedSearchChanged, | ||
|  |                 UnityConstants.SEARCH_DELAYED_INPUT_ACTION_INTERVAL); | ||
|  |         } | ||
|  | 
 | ||
|  |         public override Vector2 GetWindowSize() | ||
|  |         { | ||
|  |             return mSize; | ||
|  |         } | ||
|  | 
 | ||
|  |         internal void ShowProgressBar() | ||
|  |         { | ||
|  |             mProgressBar.Reset(); | ||
|  |             mProgressBar.IsVisible = true; | ||
|  |             EditorApplication.update += RepaintOnce; | ||
|  |         } | ||
|  | 
 | ||
|  |         internal void HideProgressBar() | ||
|  |         { | ||
|  |             mProgressBar.IsVisible = false; | ||
|  |             EditorApplication.update += RepaintOnce; | ||
|  |         } | ||
|  | 
 | ||
|  |         internal void SetModel(BranchesListModel model) | ||
|  |         { | ||
|  |             mModel = model; | ||
|  | 
 | ||
|  |             if (model != null) | ||
|  |             { | ||
|  |                 mTreeView.SetBranches(model.Branches); | ||
|  |                 mErrorEmptyState.SetError(model.Exception); | ||
|  |             } | ||
|  | 
 | ||
|  |             Repaint(); | ||
|  |         } | ||
|  | 
 | ||
|  |         void Repaint() | ||
|  |         { | ||
|  |             if (editorWindow == null) | ||
|  |                 return; | ||
|  | 
 | ||
|  |             editorWindow.Repaint(); | ||
|  |         } | ||
|  | 
 | ||
|  |         void RepaintOnce() | ||
|  |         { | ||
|  |             Repaint(); | ||
|  |             EditorApplication.update -= RepaintOnce; | ||
|  |         } | ||
|  | 
 | ||
|  |         public override void OnOpen() | ||
|  |         { | ||
|  |             mTreeView.Reload(); | ||
|  | 
 | ||
|  |             EditorApplication.update += mProgressBar.OnEditorApplicationUpdate; | ||
|  |         } | ||
|  | 
 | ||
|  |         public override void OnClose() | ||
|  |         { | ||
|  |             EditorApplication.update -= mProgressBar.OnEditorApplicationUpdate; | ||
|  |             RepaintToolbar(); | ||
|  |         } | ||
|  | 
 | ||
|  |         void BranchesTreeView.IClickListener.OnItemClicked(BranchTreeViewItem item) | ||
|  |         { | ||
|  |             mOperations.SwitchToBranch(item.BranchInfo, mModel.RepSpec); | ||
|  |             editorWindow.Close(); | ||
|  |         } | ||
|  | 
 | ||
|  |         void RepaintToolbar() | ||
|  |         { | ||
|  |             if (mRepaintToolbar == null) | ||
|  |                 return; | ||
|  | 
 | ||
|  |             mRepaintToolbar(); | ||
|  |         } | ||
|  | 
 | ||
|  |         void CreateBranch() | ||
|  |         { | ||
|  |             ExecuteAndClosePopup(() => mOperations.CreateBranch(mSearchTerm)); | ||
|  |         } | ||
|  | 
 | ||
|  |         void RefreshBranches() | ||
|  |         { | ||
|  |             mRefreshBranches(this); | ||
|  |         } | ||
|  | 
 | ||
|  |         void DelayedSearchChanged() | ||
|  |         { | ||
|  |             mTreeView.SetSearchString(mSearchTerm); | ||
|  |             mModel.ApplyFilter(new Filter(mSearchTerm)); | ||
|  |             mTreeView.SetBranches(mModel.Branches); | ||
|  |             mTreeView.Reload(); | ||
|  |         } | ||
|  | 
 | ||
|  |         public override void OnGUI(Rect rect) | ||
|  |         { | ||
|  |             if (Keyboard.IsKeyPressed(Event.current, KeyCode.Escape)) | ||
|  |             { | ||
|  |                 editorWindow.Close(); | ||
|  |                 return; | ||
|  |             } | ||
|  | 
 | ||
|  |             EditorGUILayout.BeginVertical(); | ||
|  | 
 | ||
|  |             GUILayout.Space(1); | ||
|  | 
 | ||
|  |             Rect checkinRect; | ||
|  | 
 | ||
|  |             if (PopupWindowDrawing.DrawMenuItem( | ||
|  |                     PlasticLocalization.Name.CheckinPendingChanges.GetString(), | ||
|  |                     null, | ||
|  |                     ToolbarOperationsShortcut.GetPendingChangesShortcutString(), | ||
|  |                     out checkinRect)) | ||
|  |             { | ||
|  |                 ExecuteAndClosePopup(mOperations.ShowPendingChangesView); | ||
|  |                 return; | ||
|  |             } | ||
|  | 
 | ||
|  |             Rect incomingChangesRect; | ||
|  | 
 | ||
|  |             if (PopupWindowDrawing.DrawMenuItem( | ||
|  |                     PlasticLocalization.Name.ViewIncomingChanges.GetString(), | ||
|  |                     Images.GetIconBranchIncomingChanges(), | ||
|  |                     ToolbarOperationsShortcut.GetIncomingChangesShortcutString(), | ||
|  |                     out incomingChangesRect)) | ||
|  |             { | ||
|  |                 ExecuteAndClosePopup(mOperations.ShowIncomingChangesView); | ||
|  |                 return; | ||
|  |             } | ||
|  | 
 | ||
|  |             Rect delimiterRect = new Rect( | ||
|  |                 incomingChangesRect.x, | ||
|  |                 incomingChangesRect.y + incomingChangesRect.height, | ||
|  |                 incomingChangesRect.width, | ||
|  |                 PopupWindowDrawing.DELIMITER_HEIGHT); | ||
|  | 
 | ||
|  |             PopupWindowDrawing.DrawDelimiterRect( | ||
|  |                 delimiterRect, | ||
|  |                 UnityStyles.Colors.SplitLineColor); | ||
|  | 
 | ||
|  |             mLastHoveredMenuIndex = PopupWindowDrawing.RepaintWhenHoveredMenuItemChanged( | ||
|  |                 editorWindow.Repaint, | ||
|  |                 mLastHoveredMenuIndex, | ||
|  |                 checkinRect, | ||
|  |                 incomingChangesRect); | ||
|  | 
 | ||
|  |             if (mProgressBar.IsVisible) | ||
|  |             { | ||
|  |                 float progressWidth = delimiterRect.width * mProgressBar.Progress; | ||
|  |                 Rect progressRect = new Rect( | ||
|  |                     delimiterRect.x, | ||
|  |                     delimiterRect.y, | ||
|  |                     progressWidth, | ||
|  |                     PopupWindowDrawing.PROGRESS_BAR_HEIGHT); | ||
|  | 
 | ||
|  |                 GUIStyle progressBarStyle = GUI.skin.FindStyle("ProgressBarBar"); | ||
|  |                 if (progressBarStyle != null) | ||
|  |                 { | ||
|  |                     GUI.DrawTexture(progressRect, progressBarStyle.normal.background); | ||
|  |                 } | ||
|  |             } | ||
|  | 
 | ||
|  |             GUILayout.Space(5); | ||
|  | 
 | ||
|  |             GUILayout.BeginHorizontal(); | ||
|  | 
 | ||
|  |             GUI.SetNextControlName("SearchField"); | ||
|  | 
 | ||
|  |             string previousSearchTerm = mSearchTerm; | ||
|  |             string newSearchTerm = GUILayout.TextField( | ||
|  |                 mSearchTerm, | ||
|  |                 UnityStyles.EditorToolbar.Popup.SearchField, | ||
|  |                 GUILayout.ExpandWidth(true)); | ||
|  | 
 | ||
|  |             EditorGUIUtility.AddCursorRect(GUILayoutUtility.GetLastRect(), MouseCursor.Text); | ||
|  |             if (GUILayout.Button( | ||
|  |                 PlasticLocalization.Name.NewBranchButton.GetString(), | ||
|  |                 GUILayout.ExpandWidth(false), | ||
|  |                 GUILayout.MinWidth(110))) | ||
|  |             { | ||
|  |                 CreateBranch(); | ||
|  |                 return; | ||
|  |             } | ||
|  | 
 | ||
|  |             if (newSearchTerm != previousSearchTerm) | ||
|  |             { | ||
|  |                 mSearchTerm = newSearchTerm; | ||
|  |                 mDelayedFilterAction.Run(); | ||
|  |             } | ||
|  | 
 | ||
|  |             GUILayout.EndHorizontal(); | ||
|  | 
 | ||
|  |             GUILayout.Space(5); | ||
|  |             DrawBranchesModel(mModel); | ||
|  | 
 | ||
|  |             EditorGUILayout.EndVertical(); | ||
|  | 
 | ||
|  |             EditorGUI.FocusTextInControl("SearchField"); | ||
|  |         } | ||
|  | 
 | ||
|  |         void DrawBranchesModel(BranchesListModel model) | ||
|  |         { | ||
|  |             Rect treeViewRect = GUILayoutUtility.GetRect( | ||
|  |                 0, | ||
|  |                 0, | ||
|  |                 GUILayout.ExpandWidth(true), | ||
|  |                 GUILayout.ExpandHeight(true)); | ||
|  | 
 | ||
|  |             if (model == null || model.IsLoading) | ||
|  |             { | ||
|  |                 mLoadingEmptyState.OnGUI(treeViewRect); | ||
|  |                 return; | ||
|  |             } | ||
|  | 
 | ||
|  |             if (model.HasErrors) | ||
|  |             { | ||
|  |                 mErrorEmptyState.OnGUI(treeViewRect); | ||
|  |                 return; | ||
|  |             } | ||
|  | 
 | ||
|  |             if (model.IsEmpty) | ||
|  |             { | ||
|  |                 mEmptyState.OnGUI(treeViewRect); | ||
|  |                 return; | ||
|  |             } | ||
|  | 
 | ||
|  |             mTreeView.OnGUI(treeViewRect); | ||
|  |         } | ||
|  | 
 | ||
|  |         void ExecuteAndClosePopup(Action action) | ||
|  |         { | ||
|  |             editorWindow.Close(); | ||
|  |             EditorDispatcher.Dispatch(action); | ||
|  |         } | ||
|  | 
 | ||
|  |         Action mRepaintToolbar; | ||
|  | 
 | ||
|  |         readonly PopupupProgressBar mProgressBar; | ||
|  |         readonly BranchesTreeView mTreeView; | ||
|  |         readonly ControlledPopupOperations mOperations; | ||
|  |         readonly NoBranchesEmptyState mEmptyState; | ||
|  |         readonly LoadingEmptyState mLoadingEmptyState; | ||
|  |         readonly ErrorEmptyState mErrorEmptyState; | ||
|  |         readonly DelayedActionBySecondsRunner mDelayedFilterAction; | ||
|  |         readonly Action<ControlledPopupWindow> mRefreshBranches; | ||
|  |         readonly Vector2 mSize; | ||
|  | 
 | ||
|  |         BranchesListModel mModel = BranchesListModel.BuildEmpty(); | ||
|  |         string mSearchTerm = string.Empty; | ||
|  |         int mLastHoveredMenuIndex = -1; | ||
|  |     } | ||
|  | } |