Initial project commit

This commit is contained in:
2026-01-08 16:50:20 +00:00
commit f0c5a8b267
29596 changed files with 4861782 additions and 0 deletions

View File

@@ -0,0 +1,362 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using Codice.Client.Common;
using Codice.CM.Common;
using Codice.CM.Common.Workspaces;
using PlasticGui;
using PlasticGui.CloudDrive.Workspaces;
using PlasticGui.WorkspaceWindow.Security;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Avatar;
using Unity.PlasticSCM.Editor.UI.Tree;
#if UNITY_6000_2_OR_NEWER
using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem<int>;
#endif
namespace Unity.PlasticSCM.Editor.CloudDrive.CreateWorkspace
{
internal class CollaboratorsListView : PlasticTreeView,
SelectUserGroupDialogOperations.ISelectUserGroupDialog
{
internal CollaboratorsListView(
WorkspaceInfo wkInfo,
IProgressControls progressControls,
CollaboratorsListViewHeaderState headerState,
Action repaintAction)
{
mWkInfo = wkInfo;
mProgressControls = progressControls;
multiColumnHeader = new CollaboratorsMultiColumnHeader(this, headerState);
multiColumnHeader.canSort = true;
multiColumnHeader.sortingChanged += SortingChanged;
mUsersComparer = BuildPlasticTableComparer<SecurityMember>.Build(
PlasticTableColumn.Type.String, (s) => s.Name);
mEmptyStatePanel = new EmptyStatePanel(repaintAction);
mDelayedFilterAction = new DelayedActionBySecondsRunner(
DelayedSearchChanged, UnityConstants.SEARCH_DELAYED_INPUT_ACTION_INTERVAL);
}
internal void Refresh(string server, string projectGuid)
{
SelectUserGroupDialogOperations.LoadSecurityMembers(
server,
projectGuid,
EnumSecurityMembers.Users,
string.Empty,
false,
mbShouldFilterOnServer,
mProgressControls,
this);
}
internal List<SecurityMember> GetCollaboratorsToAdd()
{
List<SecurityMember> collaboratorsToAdd = new List<SecurityMember>();
foreach (CollaboratorsListViewItem checkedRow in mCheckedItems)
{
bool isAlreadyShared = false;
foreach (WorkspaceShareInfo share in mShares)
{
if (share.User.Data == checkedRow.User.Name)
{
isAlreadyShared = true;
break;
}
}
if (!isAlreadyShared)
collaboratorsToAdd.Add(checkedRow.User);
}
return collaboratorsToAdd;
}
internal List<SecurityMember> GetCollaboratorsToRemove()
{
List<SecurityMember> collaboratorsToRemove = new List<SecurityMember>();
foreach (SecurityMember user in mUnfilteredUsers)
{
bool isUserChecked = false;
foreach (CollaboratorsListViewItem checkedRow in mCheckedItems)
{
if (user.Name == checkedRow.User.Name)
{
isUserChecked = true;
break;
}
}
if (isUserChecked)
continue;
bool isCollaborator = false;
foreach (WorkspaceShareInfo share in mShares)
{
if (user.Name == share.User.Data)
{
isCollaborator = true;
break;
}
}
if (isCollaborator)
collaboratorsToRemove.Add(user);
}
return collaboratorsToRemove;
}
internal bool IsAnyItemChecked()
{
return mCheckedItems.Count > 0;
}
internal bool AreAllItemsChecked()
{
if (mCheckedItems.Count == 0)
return false;
return mCheckedItems.Count == mUnfilteredUsers.Count;
}
internal void CheckAllItems()
{
mCheckedItems.Clear();
foreach (CollaboratorsListViewItem row in mRows)
mCheckedItems.Add(row);
}
internal void UnCheckAllItems()
{
mCheckedItems.Clear();
}
void SelectUserGroupDialogOperations.ISelectUserGroupDialog.FillUsers(List<SecurityMember> users)
{
mUnfilteredUsers = users
.Distinct()
.Where(user => user.Name != UserInfo.Get().GetCurrentUserName())
.ToList();
mCheckedItems.Clear();
mEmptyStatePanel.UpdateContent(mUnfilteredUsers.Count == 0 ?
PlasticLocalization.Name.CollaboratorsEmptyState.GetString() : string.Empty);
Refilter();
Sort();
Reload();
if (mUnfilteredUsers.Count == 0 || mWkInfo == null)
return;
WorkspaceShareOperations.GetWorkspaceShares(
mWkInfo,
mProgressControls,
(shares) =>
{
mShares = shares;
foreach (CollaboratorsListViewItem row in mRows)
{
foreach (WorkspaceShareInfo share in shares)
{
if (share.User.Data == row.User.Name)
{
mCheckedItems.Add(row);
break;
}
}
}
});
}
void SelectUserGroupDialogOperations.ISelectUserGroupDialog.SetShouldFilterOnServer()
{
mbShouldFilterOnServer = true;
}
public override void OnGUI(Rect rect)
{
base.OnGUI(rect);
if (mRows.Count == 0 && !mEmptyStatePanel.IsEmpty())
mEmptyStatePanel.OnGUI(rect);
}
protected override IList<TreeViewItem> BuildRows(TreeViewItem rootItem)
{
RegenerateRows(mUsers, rootItem, mRows);
return mRows;
}
protected override void SearchChanged(string newSearch)
{
mDelayedFilterAction.Run();
}
protected override void RowGUI(RowGUIArgs args)
{
if (args.item is CollaboratorsListViewItem)
{
CollaboratorListViewItemGUI(
args.rowRect,
rowHeight,
(CollaboratorsListViewItem)args.item,
Repaint,
args.selected,
args.focused,
mCheckedItems);
return;
}
base.RowGUI(args);
}
void DelayedSearchChanged()
{
Refilter();
Sort();
Reload();
TableViewOperations.ScrollToSelection(this);
}
void SortingChanged(MultiColumnHeader multiColumnHeader)
{
Sort();
Reload();
}
void Sort()
{
bool sortAscending = multiColumnHeader.IsSortedAscending(0);
mUsers.Sort(mUsersComparer);
if (!sortAscending)
mUsers.Reverse();
}
void Refilter()
{
if (string.IsNullOrEmpty(searchString))
{
mUsers = mUnfilteredUsers;
return;
}
mUsers = new List<SecurityMember>();
foreach (SecurityMember user in mUnfilteredUsers)
{
if (user.Name.IndexOf(searchString, StringComparison.InvariantCultureIgnoreCase) != -1)
mUsers.Add(user);
}
}
static void RegenerateRows(
List<SecurityMember> users,
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
ClearRows(rootItem, rows);
if (users.Count == 0)
return;
for (int i = 0; i < users.Count; i++)
{
CollaboratorsListViewItem collaboratorsListViewItem =
new CollaboratorsListViewItem(i + 1, users[i]);
rootItem.AddChild(collaboratorsListViewItem);
rows.Add(collaboratorsListViewItem);
}
}
static void ClearRows(
TreeViewItem rootItem,
List<TreeViewItem> rows)
{
if (rootItem.hasChildren)
rootItem.children.Clear();
rows.Clear();
}
static void CollaboratorListViewItemGUI(
Rect rowRect,
float rowHeight,
CollaboratorsListViewItem item,
Action avatarLoadedAction,
bool isSelected,
bool isFocused,
HashSet<CollaboratorsListViewItem> checkedItems)
{
bool wasChecked = checkedItems.Any(checkedItem => checkedItem.User.Name == item.User.Name);
bool isChecked = DrawTreeViewItem.ForCheckableItemCell(
rowRect,
rowHeight,
0,
GetAvatar.ForEmail(item.User.Name, avatarLoadedAction),
null,
null,
item.User.Name,
isSelected,
isFocused,
false,
wasChecked);
if (wasChecked != isChecked)
UpdateCheckedState(checkedItems, item, isChecked);
}
static void UpdateCheckedState(
HashSet<CollaboratorsListViewItem> checkedItems,
CollaboratorsListViewItem item,
bool isChecked)
{
if (isChecked)
{
checkedItems.Add(item);
return;
}
checkedItems.RemoveWhere(checkedItem => checkedItem.User.Name == item.User.Name);
}
bool mbShouldFilterOnServer = false;
List<SecurityMember> mUnfilteredUsers = new List<SecurityMember>();
List<SecurityMember> mUsers = new List<SecurityMember>();
HashSet<CollaboratorsListViewItem> mCheckedItems = new HashSet<CollaboratorsListViewItem>();
DelayedActionBySecondsRunner mDelayedFilterAction;
List<WorkspaceShareInfo> mShares = new List<WorkspaceShareInfo>();
readonly WorkspaceInfo mWkInfo;
readonly EmptyStatePanel mEmptyStatePanel;
readonly IComparer<SecurityMember> mUsersComparer;
readonly IProgressControls mProgressControls;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a8bf7716389c4dfe840c4e747033debc
timeCreated: 1753362039

View File

@@ -0,0 +1,72 @@
using System;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI.Tree;
namespace Unity.PlasticSCM.Editor.CloudDrive.CreateWorkspace
{
internal enum CollaboratorsListColumn
{
User,
}
[Serializable]
internal class CollaboratorsListViewHeaderState : MultiColumnHeaderState, ISerializationCallbackReceiver
{
internal static CollaboratorsListViewHeaderState GetDefault()
{
return new CollaboratorsListViewHeaderState(BuildColumns());
}
static string GetColumnName(CollaboratorsListColumn column)
{
switch (column)
{
case CollaboratorsListColumn.User:
return PlasticLocalization.Name.NameColumn.GetString();
default:
return null;
}
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
if (mHeaderTitles != null)
TreeHeaderColumns.SetTitles(columns, mHeaderTitles);
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
}
static Column[] BuildColumns()
{
return new Column[]
{
new Column()
{
width = 800,
headerContent = new GUIContent(
GetColumnName(CollaboratorsListColumn.User)),
minWidth = 200,
allowToggleVisibility = false,
canSort = true,
sortingArrowAlignment = TextAlignment.Right
}
};
}
CollaboratorsListViewHeaderState(Column[] columns)
: base(columns)
{
if (mHeaderTitles == null)
mHeaderTitles = TreeHeaderColumns.GetTitles(columns);
}
[SerializeField]
string[] mHeaderTitles;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a67a7d0865a447b49e842eac00d70833
timeCreated: 1753427033

View File

@@ -0,0 +1,21 @@
using UnityEditor.IMGUI.Controls;
using Codice.CM.Common;
#if UNITY_6000_2_OR_NEWER
using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem<int>;
#endif
namespace Unity.PlasticSCM.Editor.CloudDrive.CreateWorkspace
{
internal class CollaboratorsListViewItem : TreeViewItem
{
internal SecurityMember User { get; private set; }
internal CollaboratorsListViewItem(int id, SecurityMember user) : base(id)
{
User = user;
displayName = user.Name;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a287a16eb8f0400e86cec102678ab7a5
timeCreated: 1753362080

View File

@@ -0,0 +1,57 @@
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.CloudDrive.CreateWorkspace
{
internal class CollaboratorsMultiColumnHeader : MultiColumnHeader
{
internal CollaboratorsMultiColumnHeader(
CollaboratorsListView listView,
MultiColumnHeaderState headerState)
: base(headerState)
{
mCollaboratorsListView = listView;
}
protected override void ColumnHeaderGUI(MultiColumnHeaderState.Column column, Rect headerRect, int columnIndex)
{
if (columnIndex == 0)
{
bool isAnyItemChecked = mCollaboratorsListView.IsAnyItemChecked();
bool areAllItemsChecked = mCollaboratorsListView.AreAllItemsChecked();
var checkRect = new Rect(
headerRect.x + UnityConstants.TREEVIEW_BASE_INDENT,
headerRect.y + 3 + UnityConstants.TREEVIEW_HEADER_CHECKBOX_Y_OFFSET, // Custom offset because header labels are not centered
UnityConstants.TREEVIEW_CHECKBOX_SIZE,
headerRect.height);
EditorGUI.showMixedValue = !areAllItemsChecked && isAnyItemChecked;
bool toggleValue = EditorGUI.Toggle(
checkRect,
areAllItemsChecked);
EditorGUI.showMixedValue = false;
if (toggleValue != areAllItemsChecked)
UpdateCheckedState(toggleValue);
headerRect.x = checkRect.xMax;
headerRect.xMax = column.width;
}
base.ColumnHeaderGUI(column, headerRect, columnIndex);
}
void UpdateCheckedState(bool isChecked)
{
if (isChecked)
mCollaboratorsListView.CheckAllItems();
else
mCollaboratorsListView.UnCheckAllItems();
}
readonly CollaboratorsListView mCollaboratorsListView;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 224736fab6ec4e119f1f69e2c1d7b554
timeCreated: 1753429514

View File

@@ -0,0 +1,148 @@
using System;
using UnityEditor;
using UnityEngine;
using Codice.Client.Common.WebApi;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.CloudDrive.Workspaces;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.CloudDrive.CreateWorkspace
{
class CreateWorkspaceDialog : PlasticDialog, IPlasticDialogCloser
{
protected override Rect DefaultRect
{
get
{
var baseRect = base.DefaultRect;
return new Rect(baseRect.x, baseRect.y, 850, 560);
}
}
internal static WorkspaceCreationData CreateWorkspace(
string proposedOrganization,
string proposedProject,
IPlasticWebRestApi restApi,
IPlasticAPI plasticApi,
EditorWindow parentWindow)
{
CreateWorkspaceDialog dialog = Create(
proposedOrganization,
proposedProject,
restApi,
plasticApi,
parentWindow,
null);
ResponseType dialogResult = dialog.RunModal(parentWindow);
WorkspaceCreationData result = mCreateWorkspacePanel.BuildCreationData();
result.Result = dialogResult == ResponseType.Ok;
return result;
}
internal static void CreateWorkspace(
IPlasticWebRestApi restApi,
IPlasticAPI plasticApi,
EditorWindow parentWindow,
Action<WorkspaceInfo> successOperationDelegate)
{
CreateWorkspaceDialog dialog = Create(
string.Empty,
string.Empty,
restApi,
plasticApi,
parentWindow,
successOperationDelegate);
dialog.RunModal(parentWindow);
}
void IPlasticDialogCloser.CloseDialog()
{
if (mSuccessOperationDelegate == null)
{
OkButtonAction();
return;
}
WorkspaceCreationData wkCreationData = mCreateWorkspacePanel.BuildCreationData();
wkCreationData.Result = true;
CreateWorkspaceOperation.CreateWorkspace(
wkCreationData,
PlasticGui.Plastic.API,
mProgressControls,
(createdWorkspace) =>
{
OkButtonAction();
mSuccessOperationDelegate(createdWorkspace);
});
}
static CreateWorkspaceDialog Create(
string proposedOrganization,
string proposedProject,
IPlasticWebRestApi restApi,
IPlasticAPI plasticApi,
EditorWindow parentWindow,
Action<WorkspaceInfo> successOperationDelegate)
{
var instance = CreateInstance<CreateWorkspaceDialog>();
instance.IsResizable = false;
mCreateWorkspacePanel = new CreateWorkspacePanel(
proposedOrganization,
proposedProject,
restApi,
plasticApi,
parentWindow,
instance.mProgressControls);
instance.mEnterKeyAction = instance.OkButtonAction;
instance.mEscapeKeyAction = instance.CancelButtonAction;
instance.mTitle = PlasticLocalization.Name.CreateCloudWorkspaceTitle.GetString();
instance.mSuccessOperationDelegate = successOperationDelegate;
return instance;
}
protected override string GetTitle()
{
return mTitle;
}
protected override void DoComponentsArea()
{
bool isOperationRunning = mProgressControls.ProgressData.IsWaitingAsyncResult;
mCreateWorkspacePanel.OnGUI(isOperationRunning);
}
protected override void DoOkButton()
{
if (mProgressControls.ProgressData.IsWaitingAsyncResult)
GUI.enabled = false;
if (NormalButton(PlasticLocalization.Name.CreateButton.GetString()))
{
OkButtonAction();
}
GUI.enabled = true;
}
internal override void OkButtonAction()
{
WorkspaceCreationValidation.AsyncValidation(
mCreateWorkspacePanel.BuildCreationData(), this, mProgressControls);
}
string mTitle;
Action<WorkspaceInfo> mSuccessOperationDelegate;
static CreateWorkspacePanel mCreateWorkspacePanel;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 179af60903151564bb6b3157bce93991
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,388 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using Codice.Client.Common;
using Codice.Client.Common.WebApi;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.CloudDrive.Workspaces;
using Unity.PlasticSCM.Editor.CloudDrive.ShareWorkspace;
using PlasticGui.WorkspaceWindow.Home;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.CloudDrive.CreateWorkspace
{
internal class CreateWorkspacePanel :
FillCreateWorkspaceView.ICreateWorkspaceView,
FillOrganizationsAndProjects.INotify
{
internal CreateWorkspacePanel(
string proposedOrganization,
string proposedProject,
IPlasticWebRestApi restApi,
IPlasticAPI plasticApi,
EditorWindow parentWindow,
IProgressControls progressControls)
{
mProposedOrganization = proposedOrganization;
mProposedProject = proposedProject;
mPlasticApi = plasticApi;
mParentWindow = parentWindow;
mProgressControls = progressControls;
BuildComponents(mProgressControls, parentWindow.Repaint);
FillOrganizationsAndProjects.LoadOrganizations(
restApi, plasticApi, mProgressControls, this);
}
internal WorkspaceCreationData BuildCreationData()
{
string name = CloudServer.IsUnityOrganization(mSelectedOrganization) ?
CloudProjectRepository.BuildFullyQualifiedName(
mSelectedProject, mWorkspaceName) :
mWorkspaceName;
return new WorkspaceCreationData(
mSelectedOrganization,
name,
mShareWorkspacePanel.GetCollaboratorsToAdd());
}
internal bool IsInputValid()
{
return IsInputValid(mSelectedOrganization, mSelectedProject, mWorkspaceName);
}
internal void OnGUI(bool isOperationRunning = false)
{
DoTitleArea(mExplanation);
DoEntriesArea(isOperationRunning);
GUILayout.Space(5);
mShareWorkspacePanel.OnGUI(isOperationRunning);
}
void FillOrganizationsAndProjects.INotify.OrganizationsRetrieved(
List<string> organizations)
{
mOrganizations = organizations;
string organizationToSelect = GetDefaultValue(mProposedOrganization, mOrganizations);
if (organizationToSelect == null)
return;
OnOrganizationSelected(organizationToSelect);
}
void FillOrganizationsAndProjects.INotify.ProjectsRetrieved(
List<string> projects)
{
mProjects = projects;
mSelectedProject = GetDefaultValue(mProposedProject, mProjects);
OnProjectSelected(mSelectedProject);
}
void FillCreateWorkspaceView.ICreateWorkspaceView.WorkspaceNameRetrieved(
string workspaceName)
{
mWorkspaceName = workspaceName;
mShareWorkspacePanel.Refresh(mSelectedOrganization, mSelectedProject);
}
void OnOrganizationSelected(object organization)
{
mSelectedOrganization = organization.ToString();
mSelectedProject = null;
mProjects.Clear();
mExplanation = GetExplanationText(mSelectedOrganization);
FillOrganizationsAndProjects.LoadProjects(
mSelectedOrganization, mPlasticApi, mProgressControls, this);
mParentWindow.Repaint();
}
void OnProjectSelected(object project)
{
mSelectedProject = project == null ? null : project.ToString();
mShareWorkspacePanel.Refresh(mSelectedOrganization, mSelectedProject);
FillCreateWorkspaceView.LoadWorkspaceName(
mSelectedOrganization,
mWorkspaceName ?? mProposedWorkspaceName,
mPlasticApi,
mProgressControls,
this);
mParentWindow.Repaint();
}
void DoEntriesArea(bool isOperationRunning)
{
EditorGUILayout.BeginVertical(GUILayout.MinHeight(108));
GUI.enabled = !isOperationRunning;
EntryBuilder.CreateComboBoxEntry(
PlasticLocalization.Name.OrganizationLabel.GetString(),
mSelectedOrganization,
mOrganizations,
OnOrganizationSelected,
ENTRY_WIDTH,
ENTRY_X);
GUILayout.Space(5);
if (mSelectedOrganization == null ||
CloudServer.IsUnityOrganization(mSelectedOrganization))
{
EntryBuilder.CreateComboBoxEntry(
PlasticLocalization.Name.OrganizationProjectLabel.GetString(),
mSelectedProject,
mProjects,
OnProjectSelected,
ENTRY_WIDTH,
ENTRY_X);
DoCreateOrganizationProjectLink(
mSelectedOrganization, isOperationRunning);
}
GUILayout.Space(5);
mWorkspaceName = EntryBuilder.CreateTextEntry(
PlasticLocalization.Name.CloudWorkspaceNameEntry.GetString(),
mWorkspaceName,
WKNAME_CONTROL_NAME,
ENTRY_WIDTH,
ENTRY_X);
InputValidationResult inputValidationResult =
ValidateWorkspaceNameInput(mWorkspaceName);
if (!inputValidationResult.IsValid)
DoWarningLabel(inputValidationResult.ErrorMessage, ENTRY_X);
FocusWorkspaceNameEntryIfNeeded();
GUI.enabled = true;
EditorGUILayout.EndVertical();
}
void FocusWorkspaceNameEntryIfNeeded()
{
if (mWasWorkspaceNameFocused)
return;
EditorGUI.FocusTextInControl(WKNAME_CONTROL_NAME);
mWasWorkspaceNameFocused = true;
}
static void OpenOrganizationProjectUrl(string selectedOrganization)
{
string solvedServer = ResolveServer.FromUserInput(
selectedOrganization, CmConnection.Get().UnityOrgResolver);
string genesisOrgId;
if (!CloudServer.TryGetGenesisOrgId(solvedServer, out genesisOrgId))
return;
Application.OpenURL(UnityUrl.UnityDashboard.
UnityOrganizations.GetProjectsUrl(genesisOrgId));
}
static void DoTitleArea(string explanation)
{
GUILayout.Label(PlasticLocalization.Name.CreateCloudWorkspaceTitle.GetString(),
UnityStyles.Dialog.Title);
GUILayout.Space(5);
GUILayout.Label(explanation, UnityStyles.Paragraph);
GUILayout.Space(10);
}
static void DoCreateOrganizationProjectLink(
string selectedOrganization,
bool isOperationRunning)
{
string buttonText = PlasticLocalization.Name.
CreateOrganizationProjectLabel.GetString();
if (DoButton(
buttonText,
UnityStyles.LinkLabel,
!isOperationRunning,
ENTRY_WIDTH,
ENTRY_X + ENTRY_WIDTH - PROJECT_LINK_WIDTH))
{
OpenOrganizationProjectUrl(selectedOrganization);
}
}
static bool DoButton(
string text,
GUIStyle style,
bool isEnabled,
float width,
float x = -1,
float y = -1)
{
using (new GuiEnabled(isEnabled))
{
GUIContent buttonContent = new GUIContent(text);
Rect rect = GUILayoutUtility.GetRect(
buttonContent, style,
GUILayout.MinWidth(width),
GUILayout.MaxWidth(width));
if (x != -1)
rect.x = x;
if (y != -1)
rect.y = y;
bool result = GUI.Button(rect, buttonContent, style);
return result;
}
}
static void DoWarningLabel(
string text,
float x)
{
Rect rect = GUILayoutUtility.GetRect(
new GUIContent(text),
EditorStyles.label);
rect.x = x;
GUI.Label(rect,
new GUIContent(text, Images.GetWarnIcon()),
UnityStyles.HeaderWarningLabel);
}
static InputValidationResult ValidateWorkspaceNameInput(string workspaceName)
{
InputValidationResult result = new InputValidationResult();
result.IsValid = InputValidator.IsValidRepositoryName(
workspaceName,
PlasticLocalization.Name.CloudWorkspaceNameEmpty.GetString(),
out result.ErrorMessage);
return result;
}
static string GetDefaultValue(string proposedValue, List<string> values)
{
if (values.Count == 0)
return null;
if (proposedValue != null && values.Contains(proposedValue))
return proposedValue;
return values[0];
}
static string GetExplanationText(string selectedOrganization)
{
return PlasticLocalization.Name.CreateCloudWorkspaceExplanation.GetString(
CloudServer.IsUnityOrganization(selectedOrganization) ?
PlasticLocalization.Name.CreateCloudWorkspaceExplanationSelectForUnityOrg.GetString() :
PlasticLocalization.Name.CreateCloudWorkspaceExplanationSelectForCloudOrg.GetString());
}
static bool IsInputValid(
string selectedOrganization,
string selectedProject,
string workspaceName)
{
if (string.IsNullOrEmpty(selectedOrganization))
return false;
if (CloudServer.IsUnityOrganization(selectedOrganization) &&
string.IsNullOrEmpty(selectedProject))
return false;
return ValidateWorkspaceNameInput(workspaceName).IsValid;
}
void BuildComponents(IProgressControls progressControls, Action repaintAction)
{
mExplanation = PlasticLocalization.Name.CreateCloudWorkspaceExplanation.GetString(
PlasticLocalization.Name.CreateCloudWorkspaceExplanationSelectForUnityOrg.GetString());
CalculateProposedOrganizationProjectIfNeeded();
mProposedWorkspaceName = Application.productName;
mShareWorkspacePanel = new ShareWorkspacePanel(null, progressControls, repaintAction);
}
void CalculateProposedOrganizationProjectIfNeeded()
{
if (!string.IsNullOrEmpty(mProposedOrganization) ||
!string.IsNullOrEmpty(mProposedProject))
return;
GetProposedOrganizationProject.Values proposedOrganizationProject =
GetProposedOrganizationProject.FromCloudProjectSettings();
if (proposedOrganizationProject == null)
return;
mProposedOrganization = proposedOrganizationProject.Organization;
mProposedProject = proposedOrganizationProject.Project;
}
class InputValidationResult
{
internal string ErrorMessage;
internal bool IsValid;
}
bool mWasWorkspaceNameFocused;
string mExplanation;
string mProposedOrganization;
string mProposedProject;
string mProposedWorkspaceName;
string mSelectedOrganization;
string mSelectedProject;
string mWorkspaceName;
List<string> mOrganizations = new List<string>();
List<string> mProjects = new List<string>();
ShareWorkspacePanel mShareWorkspacePanel;
readonly IProgressControls mProgressControls;
readonly EditorWindow mParentWindow;
readonly IPlasticAPI mPlasticApi;
const float PROJECT_LINK_WIDTH = 192;
const float ENTRY_WIDTH = 400;
const float ENTRY_X = 175f;
const float LAYOUT_MAX_WIDTH = 800;
const string WKNAME_CONTROL_NAME = "CreateWorkspaceView.WorkspaceNameTextField";
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: abdd7cad9f7d58546ac746130105711a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,173 @@
using System;
using UnityEditor;
using UnityEngine;
using Codice.Client.Common.WebApi;
using Codice.CM.Common;
using PlasticGui;
using PlasticGui.CloudDrive.Workspaces;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Progress;
namespace Unity.PlasticSCM.Editor.CloudDrive.CreateWorkspace
{
internal class CreateWorkspaceView :
IPlasticDialogCloser
{
internal interface ICreateWorkspaceListener
{
void OnWorkspaceCreated(
WorkspaceCreationData wkCreationData, WorkspaceInfo createdWorkspace);
}
internal CreateWorkspaceView(
IPlasticWebRestApi restApi,
IPlasticAPI plasticApi,
ICreateWorkspaceListener listener,
EditorWindow parentWindow)
{
mPlasticApi = plasticApi;
mCreateWorkspaceListener = listener;
mParentWindow = parentWindow;
mProgressControls = new ProgressControlsForViews();
mCreateWorkspacePanel = new CreateWorkspacePanel(
string.Empty,
string.Empty,
restApi,
plasticApi,
parentWindow,
mProgressControls);
}
internal void Update()
{
mProgressControls.UpdateProgress(mParentWindow);
}
internal void OnGUI()
{
mCreateWorkspacePanel.OnGUI(mProgressControls.IsOperationRunning());
GUILayout.Space(15);
DoCreateWorkspaceArea(
mCreateWorkspacePanel.IsInputValid(),
mProgressControls,
CreateWorkspaceButtonValidationAction);
GUILayout.Space(15);
DoNotificationArea(mProgressControls.ProgressData);
}
void IPlasticDialogCloser.CloseDialog()
{
mWkCreationData.Result = true;
CreateWorkspaceOperation.CreateWorkspace(
mWkCreationData, mPlasticApi, mProgressControls,
(createdWorkspace) =>
{
mCreateWorkspaceListener.OnWorkspaceCreated(mWkCreationData, createdWorkspace);
});
}
void CreateWorkspaceButtonValidationAction()
{
mWkCreationData = mCreateWorkspacePanel.BuildCreationData();
// It calls IPlasticDialogCloser.CloseDialog() when the validation is OK
WorkspaceCreationValidation.AsyncValidation(
mWkCreationData, this, mProgressControls);
}
static void DoCreateWorkspaceArea(
bool isInputValid,
ProgressControlsForViews progressControls,
Action createWorkspaceButtonValidationAction)
{
Rect rect = EditorGUILayout.BeginHorizontal(GUILayout.Height(24));
bool isButtonEnabled = isInputValid && !progressControls.IsOperationRunning();
bool isButtonClicked = DoButton(
PlasticLocalization.Name.CreateCloudWorkspaceButton.GetString(),
GUI.skin.button,
isButtonEnabled,
CREATE_WORKSPACE_BUTTON_WIDTH,
CREATE_WORKSPACE_BUTTON_MARGIN,
rect.y + 2);
GUILayout.Space(5);
if (progressControls.IsOperationRunning())
DoProgress(progressControls.ProgressData);
EditorGUILayout.EndHorizontal();
if (isButtonClicked)
createWorkspaceButtonValidationAction();
}
static bool DoButton(
string text,
GUIStyle style,
bool isEnabled,
float width,
float x = -1,
float y = -1)
{
using (new GuiEnabled(isEnabled))
{
GUIContent buttonContent = new GUIContent(text);
Rect rect = GUILayoutUtility.GetRect(
buttonContent, style,
GUILayout.MinWidth(width),
GUILayout.MaxWidth(width));
if (x != -1)
rect.x = x;
if (y != -1)
rect.y = y;
bool result = GUI.Button(rect, buttonContent, style);
return result;
}
}
static void DoProgress(
ProgressControlsForViews.Data data)
{
if (string.IsNullOrEmpty(data.ProgressMessage))
return;
DrawProgressForViews.ForIndeterminateProgressSpinner(data);
}
static void DoNotificationArea(
ProgressControlsForViews.Data data)
{
if (string.IsNullOrEmpty(data.NotificationMessage))
return;
DrawProgressForViews.ForNotificationArea(data);
}
WorkspaceCreationData mWkCreationData;
readonly CreateWorkspacePanel mCreateWorkspacePanel;
readonly EditorWindow mParentWindow;
readonly ProgressControlsForViews mProgressControls;
readonly ICreateWorkspaceListener mCreateWorkspaceListener;
readonly IPlasticAPI mPlasticApi;
const float CREATE_WORKSPACE_BUTTON_MARGIN = 32;
const float CREATE_WORKSPACE_BUTTON_WIDTH = 160;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a4dab1ebc3086c245ad199490a29637f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: