Adaug proiectul Unity

This commit is contained in:
2026-11-01 23:39:55 +02:00
parent cb14d9d37d
commit 863eac8f2c
23463 changed files with 5412601 additions and 0 deletions
@@ -0,0 +1,32 @@
using System;
using Unity.PlasticSCM.Editor.UI.UndoRedo;
using UnityEditor;
using UnityEngine;
#if !UNITY_6000_3_OR_NEWER
using EditorGUI = Unity.PlasticSCM.Editor.UnityInternals.UnityEditor.EditorGUI;
#endif
namespace Unity.PlasticSCM.Editor.Views.Properties
{
class CommentTextArea : UndoRedoTextArea
{
internal CommentTextArea(Action repaint)
: base(repaint, string.Empty) { }
internal void OnGUI(float height)
{
Rect position = GUILayoutUtility.GetRect(
GUIContent.none,
EditorStyles.textArea,
GUILayout.Height(height),
GUILayout.ExpandWidth(true));
OnGUIInternal(
() => EditorGUI.ScrollableTextAreaInternal(position, mText, ref mScrollPosition, EditorStyles.textArea),
() => { });
}
Vector2 mScrollPosition;
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 135807053f9344668425b329212cc99c
timeCreated: 1770291466
@@ -0,0 +1,178 @@
using System;
using UnityEditor;
using UnityEngine;
using PlasticGui;
using Unity.PlasticSCM.Editor.UI;
namespace Unity.PlasticSCM.Editor.Views.Properties
{
internal class CommentsPanel
{
internal bool IsEditing { get; private set; }
internal string EditedComment => mCommentTextArea?.Text;
internal bool IsDirty => IsEditing && EditedComment != mOriginalComment;
internal CommentsPanel(
Action repaintAction)
{
mRepaintAction = repaintAction;
mCommentTextArea = new CommentTextArea(mRepaintAction);
}
internal void SetComment(string comment)
{
mComment = comment;
}
internal void EnterEditMode()
{
DoEnterEditMode(mComment);
}
internal void RestoreDraft(string draftText)
{
DoEnterEditMode(draftText);
}
internal void CancelEditMode()
{
IsEditing = false;
mCommentTextArea.Text = null;
mOriginalComment = null;
}
internal void ExitEditMode(string comment)
{
mComment = comment;
IsEditing = false;
mCommentTextArea.Text = null;
mOriginalComment = null;
}
internal void ClearInfo()
{
mNeedsCommentScroll = false;
mCommentScrollPosition = Vector2.zero;
mCommentTextHeight = 0f;
mViewAvailableWidth = 0f;
mComment = null;
// Reset edit state
IsEditing = false;
mCommentTextArea.Text = null;
mOriginalComment = null;
}
internal void OnGUI()
{
if (mComment == null && !IsEditing)
return;
if (IsEditing)
{
DrawEditMode();
return;
}
DrawReadOnlyMode();
}
void DrawReadOnlyMode()
{
GUIContent commentContent = new GUIContent(
mComment == string.Empty ?
PlasticLocalization.Name.NoCommentSet.GetString() :
mComment);
// Get the available width
Rect availableWidthRect = GUILayoutUtility.GetRect(
0,
0,
GUILayout.ExpandWidth(true));
GUIStyle commentsStyle = mComment == string.Empty
? UnityStyles.PropertiesPanel.EmptyComment
: UnityStyles.PropertiesPanel.Comment;
bool needsScroll = mNeedsCommentScroll;
// Max height is 6 lines of text
float maxCommentHeight = commentsStyle.lineHeight * 6;
// calculate the text height only if we have a valid width
// so the layout pass has already happened
if (Event.current.type == EventType.Repaint && availableWidthRect.width > 1)
{
mViewAvailableWidth = availableWidthRect.width;
mCommentTextHeight = commentsStyle.CalcHeight(
commentContent,
mViewAvailableWidth);
needsScroll = mCommentTextHeight >= maxCommentHeight;
}
// Use cached height, or maxHeight as fallback
float scrollViewHeight = Mathf.Min(
mCommentTextHeight > 0 ? mCommentTextHeight : maxCommentHeight,
maxCommentHeight);
if (mNeedsCommentScroll)
{
mCommentScrollPosition = GUILayout.BeginScrollView(
mCommentScrollPosition,
GUILayout.Height(scrollViewHeight));
}
Rect textRect = GUILayoutUtility.GetRect(
commentContent,
commentsStyle,
GUILayout.ExpandHeight(true));
EditorGUI.SelectableLabel(textRect, commentContent.text, commentsStyle);
if (mNeedsCommentScroll)
GUILayout.EndScrollView();
else
GUILayout.Space(3);
if (mNeedsCommentScroll != needsScroll)
{
mNeedsCommentScroll = needsScroll;
mRepaintAction();
}
}
void DrawEditMode()
{
mCommentTextArea.OnGUI(EDIT_TEXTAREA_HEIGHT);
}
void DoEnterEditMode(string comment)
{
if (IsEditing)
return;
IsEditing = true;
mOriginalComment = mComment ?? string.Empty;
mCommentTextArea.Text = comment;
mCommentTextArea.SetFocusAndSelectAll();
}
readonly Action mRepaintAction;
string mComment;
string mOriginalComment;
Vector2 mCommentScrollPosition = Vector2.zero;
bool mNeedsCommentScroll;
float mCommentTextHeight = 0f;
float mViewAvailableWidth = 0f;
CommentTextArea mCommentTextArea;
const float EDIT_TEXTAREA_HEIGHT = 90f;
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7ff4088388844bb9bf6b1e832be44c0b
timeCreated: 1763563421
@@ -0,0 +1,657 @@
using System;
using UnityEditor;
using UnityEngine;
using Codice.Client.Common.Threading;
using Codice.CM.Common;
using Codice.Utils;
using PlasticGui;
using PlasticGui.WorkspaceWindow.BranchExplorer;
using Unity.PlasticSCM.Editor.UI;
using Unity.PlasticSCM.Editor.UI.Avatar;
using Unity.PlasticSCM.Editor.Views.Attributes;
namespace Unity.PlasticSCM.Editor.Views.Properties
{
internal class PropertiesPanel
{
internal PropertiesPanel(
Action repaintAction,
IWorkspaceWindow workspaceWindow,
EditorWindow window)
{
mRepaintAction = repaintAction;
mCommentsFoldout = SessionState.GetBool(
COMMENTS_FOLDOUT_KEY, defaultValue: true);
mAttributesFoldout = SessionState.GetBool(
ATTRIBUTES_FOLDOUT_KEY, defaultValue: true);
mCommentsPanel = new CommentsPanel(
repaintAction);
mAttributesPanel = new AttributesPanel(
repaintAction,
workspaceWindow,
window);
}
internal void ClearInfo()
{
PersistCommentDraftIfNeeded();
mCommentsPanel.ClearInfo();
mAttributesPanel.Clear();
mSelectedObject = null;
mRepSpec = null;
mRepositoryName = null;
mReplicationSource = null;
mRepaintAction();
}
internal void UpdateInfo(
RepObjectInfo selectedObject,
RepositorySpec repSpec)
{
PersistCommentDraftIfNeeded();
mSelectedObject = selectedObject;
mRepSpec = repSpec;
mCommentsPanel.ClearInfo();
mAttributesPanel.Clear();
mCommentsPanel.SetComment(GetComment(mSelectedObject));
TryRestoreCommentDraft();
mAttributesPanel.UpdateRepositorySpec(mRepSpec);
mAttributesPanel.UpdateInfo(mSelectedObject.Id);
mRepositoryName = RepObjectPropertiesView.GetRepositoryName(mRepSpec);
mReplicationSource = null;
FetchReplicationSource();
mRepaintAction();
}
internal void Update()
{
mAttributesPanel.Update();
if (mSelectedObject == null ||
mRepSpec == null ||
mLastRefreshVersion == PropertiesRefreshNotifier.Version)
return;
// if the version is different, it means that there was
// change that requires refreshing the properties
mLastRefreshVersion = PropertiesRefreshNotifier.Version;
RefreshCommentAndAttributes();
}
internal void OnGUI()
{
if (mSelectedObject == null || mRepSpec == null)
return;
EditorGUILayout.BeginVertical(UnityStyles.Inspector.HeaderBackgroundStyle);
GUILayout.Space(5);
Texture image = GetImage(mSelectedObject, mRepSpec, () =>
{
mRepaintAction();
});
string title = GetTitle(mSelectedObject);
string description = GetDescription(mSelectedObject, mRepSpec);
DrawPropertiesArea(
image,
title,
description,
mRepositoryName,
mReplicationSource);
DrawCommentsFoldoutHeader();
if (mCommentsFoldout)
{
mCommentsPanel.OnGUI();
}
GUILayout.Space(5);
DrawAttributesFoldoutHeader();
if (mAttributesFoldout)
{
mAttributesPanel.OnGUI();
}
GUILayout.Space(5);
EditorGUILayout.EndVertical();
}
void DrawCommentsFoldoutHeader()
{
bool isEditable = IsObjectEditable();
Rect headerRect = GUILayoutUtility.GetRect(
GUIContent.none,
EditorStyles.foldout,
GUILayout.ExpandWidth(true),
GUILayout.Height(EditorGUIUtility.singleLineHeight));
float buttonSpacing = 4f;
float rightPadding = 4f;
float buttonsWidth = 0f;
string editText = PlasticLocalization.Name.EditButton.GetString();
string saveText = PlasticLocalization.Name.SaveButton.GetString();
string cancelText = PlasticLocalization.Name.CancelButton.GetString();
GUIContent editContent = new GUIContent(editText);
GUIContent saveContent = new GUIContent(saveText);
GUIContent cancelContent = new GUIContent(cancelText);
Vector2 editSize = EditorStyles.miniButton.CalcSize(editContent);
Vector2 saveSize = EditorStyles.miniButton.CalcSize(saveContent);
Vector2 cancelSize = EditorStyles.miniButton.CalcSize(cancelContent);
if (isEditable)
{
buttonsWidth = mCommentsPanel.IsEditing
? saveSize.x + buttonSpacing + cancelSize.x + rightPadding
: editSize.x + rightPadding;
}
// Draw foldout in the remaining space on the left
Rect foldoutRect = new Rect(
headerRect.x,
headerRect.y,
headerRect.width - buttonsWidth,
headerRect.height);
bool previousCommentsFoldout = mCommentsFoldout;
mCommentsFoldout = EditorGUI.Foldout(
foldoutRect,
mCommentsFoldout,
PlasticLocalization.Name.CommentsLabelSingular.GetString(),
toggleOnLabelClick: true);
if (previousCommentsFoldout != mCommentsFoldout)
SessionState.SetBool(COMMENTS_FOLDOUT_KEY, mCommentsFoldout);
if (!isEditable)
return;
DrawEditableHeader(
headerRect,
rightPadding,
cancelSize,
buttonSpacing,
saveSize,
saveContent,
cancelContent,
editSize,
editContent);
}
void DrawEditableHeader(Rect headerRect, float rightPadding, Vector2 cancelSize, float buttonSpacing, Vector2 saveSize,
GUIContent saveContent, GUIContent cancelContent, Vector2 editSize, GUIContent editContent)
{
if (mCommentsPanel.IsEditing)
{
DrawEditingHeader(
headerRect,
rightPadding,
cancelSize,
buttonSpacing,
saveSize,
saveContent,
cancelContent);
return;
}
Rect editRect = new Rect(
headerRect.xMax - rightPadding - editSize.x,
headerRect.y,
editSize.x,
headerRect.height);
if (GUI.Button(editRect, editContent, EditorStyles.miniButton))
{
mCommentsPanel.EnterEditMode();
// expand the foldout when entering edit mode
mCommentsFoldout = true;
SessionState.SetBool(COMMENTS_FOLDOUT_KEY, true);
}
}
void DrawEditingHeader(Rect headerRect, float rightPadding, Vector2 cancelSize, float buttonSpacing, Vector2 saveSize,
GUIContent saveContent, GUIContent cancelContent)
{
using (new GuiEnabled(!mIsSavingComment))
{
Rect saveRect = new Rect(
headerRect.xMax - rightPadding - cancelSize.x - buttonSpacing - saveSize.x,
headerRect.y,
saveSize.x,
headerRect.height);
Rect cancelRect = new Rect(
headerRect.xMax - rightPadding - cancelSize.x,
headerRect.y,
cancelSize.x,
headerRect.height);
if (GUI.Button(saveRect, saveContent, EditorStyles.miniButton))
SaveComment();
if (GUI.Button(cancelRect, cancelContent, EditorStyles.miniButton))
CancelEdit();
}
}
void DrawAttributesFoldoutHeader()
{
if (!mAttributesPanel.IsAvailable())
return;
Rect foldoutRect = GUILayoutUtility.GetRect(
GUIContent.none,
EditorStyles.foldout,
GUILayout.ExpandWidth(true),
GUILayout.Height(EditorGUIUtility.singleLineHeight));
bool previousAttributesFoldout = mAttributesFoldout;
mAttributesFoldout = EditorGUI.Foldout(
foldoutRect,
mAttributesFoldout,
PlasticLocalization.Name.Attributes.GetString(),
toggleOnLabelClick: true);
if (previousAttributesFoldout != mAttributesFoldout)
SessionState.SetBool(ATTRIBUTES_FOLDOUT_KEY, mAttributesFoldout);
}
void SaveComment()
{
mIsSavingComment = true;
string newComment = mCommentsPanel.EditedComment;
IThreadWaiter waiter = ThreadWaiter.GetWaiter();
waiter.Execute(
threadOperationDelegate: delegate
{
PlasticGui.Plastic.API.UpdateObjectComment(mRepSpec, mSelectedObject, newComment);
},
afterOperationDelegate: delegate
{
mIsSavingComment = false;
if (waiter.Exception != null)
{
ExceptionsHandler.DisplayException(waiter.Exception);
mRepaintAction();
return;
}
ClearCommentDraft();
mCommentsPanel.ExitEditMode(newComment);
PropertiesRefreshNotifier.Notify();
mLastRefreshVersion = PropertiesRefreshNotifier.Version;
mRepaintAction();
});
}
void CancelEdit()
{
ClearCommentDraft();
mCommentsPanel.CancelEditMode();
mRepaintAction();
}
bool IsObjectEditable()
{
return mSelectedObject != null
&& mSelectedObject.Id != -1
&& mRepSpec != null;
}
void PersistCommentDraftIfNeeded()
{
if (!mCommentsPanel.IsEditing || !mCommentsPanel.IsDirty)
return;
if (mSelectedObject == null)
return;
string commentDraftKey = GetCommentDraftKey(mSelectedObject);
SessionState.SetString(commentDraftKey, mCommentsPanel.EditedComment);
}
void TryRestoreCommentDraft()
{
if (mSelectedObject == null)
return;
string commentDraftKey = GetCommentDraftKey(mSelectedObject);
string commentDraft = SessionState.GetString(commentDraftKey, null);
if (string.IsNullOrEmpty(commentDraft))
return;
mCommentsPanel.SetComment(GetComment(mSelectedObject));
mCommentsPanel.RestoreDraft(commentDraft);
mCommentsFoldout = true;
SessionState.SetBool(COMMENTS_FOLDOUT_KEY, true);
}
void ClearCommentDraft()
{
if (mSelectedObject == null)
return;
string commentDraftKey = GetCommentDraftKey(mSelectedObject);
SessionState.EraseString(commentDraftKey);
}
static void DrawPropertiesArea(
Texture image,
string title,
string description,
string repositoryName,
string replicationSource)
{
GUILayout.BeginHorizontal();
GUILayout.Space(7);
DrawImage(image);
GUILayout.Space(5);
GUILayout.BeginVertical();
// Get the available width
Rect availableWidthRect = GUILayoutUtility.GetRect(
0,
0,
GUILayout.ExpandWidth(true));
DrawTitleWithRepositoryName(
title, repositoryName, availableWidthRect.width);
GUILayout.Space(3);
DrawSelectableLabel(
description,
UnityStyles.PropertiesPanel.Description,
availableWidthRect.width);
if (!string.IsNullOrEmpty(replicationSource))
{
GUILayout.Space(2);
string replicationLine = string.Format("{0}: {1}",
PlasticLocalization.Name.ReplicationSource.GetString(),
replicationSource);
DrawSelectableLabel(
replicationLine,
UnityStyles.PropertiesPanel.Description,
availableWidthRect.width);
}
GUILayout.Space(5);
GUILayout.EndVertical();
GUILayout.EndHorizontal();
}
static string GetCommentDraftKey(RepObjectInfo repObject)
{
return string.Format(
COMMENT_DRAFT_KEY_FORMAT,
repObject.GUID.ToString());
}
static void DrawTitleWithRepositoryName(
string title,
string repositoryName,
float availableWidth)
{
GUIStyle titleStyle = UnityStyles.PropertiesPanel.Title;
GUIStyle repoStyle = UnityStyles.PropertiesPanel.Description;
Vector2 titleSize = titleStyle.CalcSize(new GUIContent(title));
float titleWidth = Mathf.Min(titleSize.x, availableWidth);
if (string.IsNullOrEmpty(repositoryName))
{
DrawSelectableLabel(title, titleStyle, availableWidth);
return;
}
Vector2 repoSize = repoStyle.CalcSize(
new GUIContent(repositoryName));
float lineHeight = Mathf.Max(titleSize.y, repoSize.y);
Rect lineRect = GUILayoutUtility.GetRect(
availableWidth, lineHeight, titleStyle);
Rect titleArea = new Rect(
lineRect.x, lineRect.y,
titleWidth, lineHeight);
float verticalOffset = lineHeight - repoSize.y;
Rect repoArea = new Rect(
lineRect.x + titleWidth + 4,
lineRect.y + verticalOffset,
repoSize.x,
repoSize.y);
EditorGUI.SelectableLabel(titleArea, title, titleStyle);
EditorGUI.SelectableLabel(repoArea, repositoryName, repoStyle);
}
static void DrawImage(Texture image)
{
if (image == null)
return;
Rect imageRect = GUILayoutUtility.GetRect(
IMAGE_SIZE, IMAGE_SIZE,
GUILayout.ExpandWidth(false), GUILayout.ExpandHeight(false));
imageRect.y += 3;
GUI.DrawTexture(imageRect, image, ScaleMode.ScaleToFit);
}
static void DrawSelectableLabel(string text, GUIStyle style, float availableWidth)
{
Vector2 objectNameContentSize = style.CalcSize(new GUIContent(text));
float objectNameClampedWidth = Mathf.Min(objectNameContentSize.x, availableWidth);
Rect objectNameRect = GUILayoutUtility.GetRect(
objectNameClampedWidth,
objectNameContentSize.y,
style);
EditorGUI.SelectableLabel(objectNameRect, text, style);
}
static Texture GetImage(
RepObjectInfo selectedObject,
RepositorySpec repSpec,
Action avatarLoadedAction)
{
if (selectedObject is ChangesetInfo)
{
string userName = PlasticGui.Plastic.API.GetUserName(
repSpec.Server, selectedObject.Owner);
Texture2D image = GetAvatar.ForEmail(userName, avatarLoadedAction);
return image;
}
if (selectedObject is BranchInfo)
return Images.GetBranchIcon();
if (selectedObject is MarkerInfo)
return Images.GetLabelIcon();
return null;
}
static string GetTitle(RepObjectInfo selectedObject)
{
if (selectedObject is ChangesetInfo changeset)
{
if (changeset.ChangesetId == -1)
{
return PlasticLocalization.Name
.BranchExplorerCheckoutChangesetTitle.GetString();
}
string objectName = changeset.ChangesetId < 0 ?
PlasticLocalization.Name.Shelve.GetString() :
PlasticLocalization.Name.Changeset.GetString();
return string.Concat(
Math.Abs(changeset.ChangesetId),
" ",
"(",
objectName,
")");
}
if (selectedObject is BranchInfo branch)
{
return string.Concat(
branch.Name,
" ",
"(",
PlasticLocalization.Name.Branch.GetString(),
")");
}
if (selectedObject is MarkerInfo marker)
{
return string.Concat(
marker.Name,
" ",
"(",
PlasticLocalization.Name.Label.GetString(),
")");
}
return null;
}
static string GetDescription(
RepObjectInfo selectedObject,
RepositorySpec repSpec)
{
string userName = PlasticGui.Plastic.API.GetUserName(
repSpec.Server, selectedObject.Owner);
string result = PlasticLocalization.Name.DiffHeaderDetailsStringFormat.GetString(
userName,
selectedObject.LocalTimeStamp);
if (selectedObject is ChangesetInfo changesetInfo)
result += " | " + ShortGuid.Get(changesetInfo.GUID.ToString());
return result;
}
internal static string FilterReplicationSource(
string replicationSource)
{
if (string.IsNullOrEmpty(replicationSource) ||
replicationSource == PlasticLocalization.GetString(
PlasticLocalization.Name.NoReplicationSources))
return null;
return replicationSource;
}
static string GetComment(RepObjectInfo selectedObject)
{
if (selectedObject == null)
return string.Empty;
return selectedObject.Comment;
}
void FetchReplicationSource()
{
RepositorySpec repSpec = mRepSpec;
RepObjectInfo selectedObject = mSelectedObject;
IThreadWaiter waiter = ThreadWaiter.GetWaiter();
waiter.Execute(
threadOperationDelegate: delegate
{
string replicationSource =
RepObjectPropertiesView.GetReplicationSource(
repSpec, selectedObject);
mReplicationSource = FilterReplicationSource(
replicationSource);
},
afterOperationDelegate: delegate
{
if (waiter.Exception != null)
{
mReplicationSource = null;
mRepaintAction();
return;
}
mRepaintAction();
});
}
void RefreshCommentAndAttributes()
{
mCommentsPanel.SetComment(GetComment(mSelectedObject));
mAttributesPanel.Refresh();
FetchReplicationSource();
mRepaintAction();
}
readonly CommentsPanel mCommentsPanel;
readonly AttributesPanel mAttributesPanel;
readonly Action mRepaintAction;
RepObjectInfo mSelectedObject;
RepositorySpec mRepSpec;
string mRepositoryName;
string mReplicationSource;
long mLastRefreshVersion = PropertiesRefreshNotifier.Version;
bool mCommentsFoldout;
bool mIsSavingComment = false;
bool mAttributesFoldout;
const int IMAGE_SIZE = 32;
const string COMMENT_DRAFT_KEY_FORMAT = "CommentDraft|{0}";
const string COMMENTS_FOLDOUT_KEY = "PropertiesPanel.CommentsFoldout";
const string ATTRIBUTES_FOLDOUT_KEY = "PropertiesPanel.AttributesFoldout";
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b10d1c0a975d47f2840062c1a1fbe6a9
timeCreated: 1763454152
@@ -0,0 +1,14 @@
namespace Unity.PlasticSCM.Editor.Views.Properties
{
internal static class PropertiesRefreshNotifier
{
internal static long Version => mVersion;
internal static void Notify()
{
mVersion++;
}
static long mVersion;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4acf41ca020194d509c7c940c75913b0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: