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 refreshBranches, Func 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 mRefreshBranches; readonly Vector2 mSize; BranchesListModel mModel = BranchesListModel.BuildEmpty(); string mSearchTerm = string.Empty; int mLastHoveredMenuIndex = -1; } }