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,65 @@
using System;
using UnityEngine;
namespace Unity.PlasticSCM.Editor.UI.Tree
{
internal abstract class CenteredContentPanel
{
internal CenteredContentPanel(Action repaintAction)
{
mRepaintAction = repaintAction;
}
internal void OnGUI(Rect rect)
{
if (Event.current.type == EventType.Repaint && mLastValidRect != rect)
{
mLastValidRect = rect;
mRepaintAction();
}
GUILayout.BeginArea(mLastValidRect);
DrawGUI();
GUILayout.EndArea();
}
protected abstract void DrawGUI();
protected static void CenterContent(params Action[] contents)
{
CenterVertical(() =>
{
foreach (Action content in contents)
{
CenterHorizontal(() =>
{
content();
});
}
});
}
static void CenterVertical(Action content)
{
GUILayout.BeginVertical();
GUILayout.FlexibleSpace();
content();
GUILayout.FlexibleSpace();
GUILayout.EndVertical();
}
static void CenterHorizontal(Action content)
{
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
content();
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
protected readonly Action mRepaintAction;
Rect mLastValidRect;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 19dca01e5c6a4d808cee50ff17837de5
timeCreated: 1746194632

View File

@@ -0,0 +1,397 @@
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
#if UNITY_6000_2_OR_NEWER
using TreeView = UnityEditor.IMGUI.Controls.TreeView<int>;
#endif
namespace Unity.PlasticSCM.Editor.UI.Tree
{
internal static class DrawTreeViewItem
{
internal enum TextTrimming
{
None,
Path,
}
internal static void InitializeStyles()
{
if (EditorStyles.label == null)
return;
TreeView.DefaultStyles.label = UnityStyles.Tree.Label;
TreeView.DefaultStyles.boldLabel = UnityStyles.Tree.BoldLabel;
}
internal static void ForIndentedItem(
Rect rowRect,
int depth,
string label,
string infoLabel,
bool isSelected,
bool isFocused)
{
float indent = GetIndent(depth);
rowRect.x += indent;
rowRect.width -= indent;
//add a little indentation
rowRect.x += 5;
rowRect.width -= 5;
TreeView.DefaultGUI.Label(rowRect, label, isSelected, isFocused);
if (!string.IsNullOrEmpty(infoLabel))
DrawInfolabel(rowRect, label, infoLabel);
}
internal static void ForIndentedItemWithIcon(
Rect rowRect,
float rowHeight,
int depth,
string label,
string infoLabel,
Texture icon,
bool isSelected,
bool isFocused)
{
float indent = GetIndent(depth);
rowRect.x += indent;
rowRect.width -= indent;
rowRect = DrawIconLeft(
rowRect, rowHeight, icon, null, null);
TreeView.DefaultGUI.Label(rowRect, label, isSelected, isFocused);
if (!string.IsNullOrEmpty(infoLabel))
DrawInfolabel(rowRect, label, infoLabel);
}
internal static bool ForCheckableIndentedItem(
Rect rowRect,
int depth,
string label,
string infoLabel,
bool isSelected,
bool isFocused,
bool wasChecked,
bool hadCheckedChildren,
bool hadPartiallyCheckedChildren)
{
float indent = GetIndent(depth);
rowRect.x += indent;
rowRect.width -= indent;
Rect checkRect = GetCheckboxRect(rowRect);
if (!wasChecked && (hadCheckedChildren || hadPartiallyCheckedChildren))
EditorGUI.showMixedValue = true;
bool isChecked = EditorGUI.Toggle(checkRect, wasChecked);
EditorGUI.showMixedValue = false;
rowRect.x = checkRect.xMax - 4;
rowRect.width -= checkRect.width;
//add a little indentation
rowRect.x += 5;
rowRect.width -= 5;
TreeView.DefaultGUI.Label(rowRect, label, isSelected, isFocused);
if (!string.IsNullOrEmpty(infoLabel))
DrawInfolabel(rowRect, label, infoLabel);
return isChecked;
}
internal static void ForItemCell(
Rect rect,
float rowHeight,
int depth,
Texture icon,
string iconTooltip,
Texture overlayIcon,
string label,
bool isSelected,
bool isFocused,
bool isBoldText,
bool isSecondaryLabel,
TextTrimming textTrimming = TextTrimming.None)
{
float indent = GetIndent(depth);
rect.x += indent;
rect.width -= indent;
rect = DrawIconLeft(
rect, rowHeight, icon, iconTooltip, overlayIcon);
if (isSecondaryLabel)
{
ForSecondaryLabel(rect, label, isSelected, isFocused, isBoldText, textTrimming);
return;
}
ForLabel(rect, label, isSelected, isFocused, isBoldText, textTrimming);
}
internal static bool ForCheckableItemCell(
Rect rect,
float rowHeight,
int depth,
Texture icon,
string iconTooltip,
Texture overlayIcon,
string label,
bool isSelected,
bool isFocused,
bool isHighlighted,
bool wasChecked,
DrawTreeViewItem.TextTrimming textTrimming = TextTrimming.None)
{
float indent = GetIndent(depth);
rect.x += indent;
rect.width -= indent;
Rect checkRect = GetCheckboxRect(rect);
bool isChecked = EditorGUI.Toggle(checkRect, wasChecked);
rect.x = checkRect.xMax;
rect.width -= checkRect.width;
rect = DrawIconLeft(
rect, rowHeight, icon, iconTooltip, overlayIcon);
GUIStyle style = isHighlighted ?
UnityStyles.Tree.BoldLabel :
UnityStyles.Tree.Label;
if (Event.current.type != UnityEngine.EventType.Repaint)
return isChecked;
GUIContent content = GetGUIContent(label, style, rect, textTrimming);
DrawLabel(
content,
style,
rect,
false,
true,
isSelected,
isFocused);
return isChecked;
}
internal static Rect DrawIconLeft(
Rect rect,
float rowHeight,
Texture icon,
string iconTooltip,
Texture overlayIcon)
{
if (icon == null)
return rect;
float iconWidth = UnityConstants.TREEVIEW_ICON_SIZE * ((float)icon.width / icon.height);;
Rect iconRect = new Rect(rect.x, rect.y, iconWidth, rowHeight);
EditorGUI.LabelField(iconRect, new GUIContent(icon, iconTooltip), UnityStyles.Tree.IconStyle);
if (overlayIcon != null)
{
Rect overlayIconRect = GetOverlayRect.ForPendingChanges(iconRect);
GUI.DrawTexture(
overlayIconRect, overlayIcon,
ScaleMode.ScaleToFit);
}
rect.x += iconRect.width;
rect.width -= iconRect.width;
return rect;
}
static void DrawInfolabel(
Rect rect,
string label,
string infoLabel)
{
Vector2 labelSize = ((GUIStyle)UnityStyles.Tree.Label)
.CalcSize(new GUIContent(label));
rect.x += labelSize.x;
GUI.Label(rect, infoLabel, UnityStyles.Tree.InfoLabel);
}
static Rect GetCheckboxRect(Rect rect)
{
return new Rect(
rect.x,
rect.y + UnityConstants.TREEVIEW_CHECKBOX_Y_OFFSET,
UnityConstants.TREEVIEW_CHECKBOX_SIZE,
rect.height);
}
static float GetIndent(int depth)
{
return 16 * (depth + 1);
}
internal static void ForSecondaryLabelRightAligned(
Rect rect,
string label,
bool isSelected,
bool isFocused,
bool isBoldText,
TextTrimming textTrimming = TextTrimming.None)
{
if (Event.current.type != EventType.Repaint)
return;
GUIStyle style = isBoldText ?
UnityStyles.Tree.SecondaryLabelBoldRightAligned :
UnityStyles.Tree.SecondaryLabelRightAligned;
GUIContent content = GetGUIContent(label, style, rect, textTrimming);
DrawLabel(
content,
style,
rect,
false,
true,
isSelected,
isFocused);
}
internal static void ForSecondaryLabel(
Rect rect,
string label,
bool isSelected,
bool isFocused,
bool isBoldText,
TextTrimming textTrimming = TextTrimming.None)
{
if (Event.current.type != EventType.Repaint)
return;
GUIStyle style = isBoldText ?
UnityStyles.Tree.SecondaryBoldLabel :
UnityStyles.Tree.SecondaryLabel;
if (isBoldText)
style.normal.textColor = Color.red;
GUIContent content = GetGUIContent(label, style, rect, textTrimming);
DrawLabel(
content,
style,
rect,
false,
true,
isSelected,
isFocused);
}
internal static void ForLabel(
Rect rect,
GUIContent content,
bool isSelected,
bool isFocused,
bool isBoldText)
{
if (Event.current.type != EventType.Repaint)
return;
GUIStyle style = isBoldText ? UnityStyles.Tree.BoldLabel: UnityStyles.Tree.Label;
DrawLabel(
content,
style,
rect,
false,
true,
isSelected,
isFocused);
}
internal static void ForLabel(
Rect rect,
string label,
bool isSelected,
bool isFocused,
bool isBoldText,
TextTrimming textTrimming = TextTrimming.None)
{
if (Event.current.type != EventType.Repaint)
return;
label = TruncateLabelIfNeeded(label);
GUIStyle style = isBoldText ? UnityStyles.Tree.BoldLabel: UnityStyles.Tree.Label;
GUIContent content = GetGUIContent(label, style, rect, textTrimming);
DrawLabel(
content,
style,
rect,
false,
true,
isSelected,
isFocused);
}
static void DrawLabel(
GUIContent content,
GUIStyle style,
Rect rect,
bool isHover,
bool isActive,
bool isSelected,
bool isFocused)
{
style.Draw(
rect, content, isHover, isActive, isSelected, isFocused);
}
static GUIContent GetGUIContent(string label, GUIStyle style, Rect rect, TextTrimming textTrimming)
{
if (textTrimming == TextTrimming.Path)
{
string truncatedLabel = PathTrimming.TruncatePath(
label,
rect.width,
CalcTextSize.FromStyle(style),
out var wasTrimmed);
return new GUIContent(truncatedLabel, wasTrimmed ? label : null);
}
return new GUIContent(label);
}
static string TruncateLabelIfNeeded(string label)
{
if (string.IsNullOrEmpty(label))
return label;
if (label.Length <= MAX_LABEL_LENGTH)
return label;
return label.Substring(0, MAX_LABEL_LENGTH) + "...";
}
const int MAX_LABEL_LENGTH = 1024;
}
}

View File

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

View File

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using Codice.Client.Common;
namespace Unity.PlasticSCM.Editor.UI.Tree
{
internal class EmptyStatePanel : CenteredContentPanel
{
internal string Text { get { return mText; } }
internal EmptyStatePanel(Action repaintAction)
: base(repaintAction)
{
}
internal bool IsEmpty()
{
return string.IsNullOrEmpty(mText);
}
internal void UpdateContent(
string contentText,
bool bDrawOkIcon = false,
MultiLinkLabelData multiLinkLabelData = null)
{
mText = contentText;
mbDrawOkIcon = bDrawOkIcon;
mMultiLinkLabelData = multiLinkLabelData;
}
protected override void DrawGUI()
{
CenterContent(BuildDrawActions(
mbDrawOkIcon, mText, mMultiLinkLabelData).ToArray());
}
static List<Action> BuildDrawActions(
bool hasOkIcon,
string text,
MultiLinkLabelData multiLinkLabelData)
{
List<Action> result = new List<Action>()
{
() =>
{
if (hasOkIcon)
GUILayout.Label(Images.GetStepOkIcon(), UnityStyles.EmptyState.Icon);
GUILayout.Label(text, UnityStyles.EmptyState.Label);
}
};
if (multiLinkLabelData == null)
return result;
result.Add(
() =>
{
DrawTextBlockWithLink.ForMultiLinkLabel(
multiLinkLabelData,
UnityStyles.EmptyState.LabelForMultiLinkLabel,
UnityStyles.EmptyState.LinkForMultiLinkLabel);
});
return result;
}
bool mbDrawOkIcon;
string mText;
MultiLinkLabelData mMultiLinkLabelData;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3787875fc84246d0a47d8c123d4ea5fc
timeCreated: 1746194665

View File

@@ -0,0 +1,162 @@
using UnityEngine;
using Codice.Client.BaseCommands;
using Codice.Client.Commands;
using Codice.CM.Common;
using Codice.ThemeImages;
using PlasticGui.WorkspaceWindow.Merge;
using PlasticGui.WorkspaceWindow.PendingChanges;
using Unity.PlasticSCM.Editor.AssetsOverlays;
using GluonIncomingChangeInfo = PlasticGui.Gluon.WorkspaceWindow.Views.IncomingChanges.IncomingChangeInfo;
using GluonIncomingChangeCategory = PlasticGui.Gluon.WorkspaceWindow.Views.IncomingChanges.IncomingChangeCategory;
namespace Unity.PlasticSCM.Editor.UI.Tree
{
static class GetChangesOverlayIcon
{
internal static Texture ForPlasticMergeChange(
MergeChangeInfo mergeChange,
bool isSolvedConflict)
{
if (mergeChange.CategoryType == MergeChangesCategory.Type.FileConflicts ||
mergeChange.CategoryType == MergeChangesCategory.Type.DirectoryConflicts)
return ForConflict(isSolvedConflict);
if (mergeChange.IsXLink())
return ForXLink();
if (mergeChange.CategoryType == MergeChangesCategory.Type.Deleted)
return ForDeletedOnServer();
if (mergeChange.CategoryType == MergeChangesCategory.Type.Changed)
return ForOutOfDate();
if (mergeChange.CategoryType == MergeChangesCategory.Type.Added)
return ForAdded();
return null;
}
internal static Texture ForGluonIncomingChange(
GluonIncomingChangeInfo incomingChange,
bool isSolvedConflict)
{
if (incomingChange.CategoryType == GluonIncomingChangeCategory.Type.Conflicted)
return ForConflict(isSolvedConflict);
if (incomingChange.IsXLink())
return ForXLink();
if (incomingChange.CategoryType == GluonIncomingChangeCategory.Type.Deleted)
return ForDeletedOnServer();
if (incomingChange.CategoryType == GluonIncomingChangeCategory.Type.Changed)
return ForOutOfDate();
if (incomingChange.CategoryType == GluonIncomingChangeCategory.Type.Added)
return ForAdded();
return null;
}
internal static Texture ForPendingChange(
ChangeInfo changeInfo,
bool isConflict)
{
if (isConflict)
return ForConflicted();
ItemIconImageType type = ChangeInfoView.
GetIconImageType(changeInfo);
if (ChangeTypesOperator.AreAllSet(
changeInfo.ChangeTypes, ChangeTypes.Added))
return ForAdded();
if (type.HasFlag(ItemIconImageType.Ignored))
return ForIgnored();
if (type.HasFlag(ItemIconImageType.Deleted))
return ForDeleted();
if (ChangeTypesOperator.ContainsAny(
changeInfo.ChangeTypes,
ChangeTypes.Moved |
ChangeTypes.LocallyMoved))
return ForMoved();
if (type.HasFlag(ItemIconImageType.CheckedOut) ||
type.HasFlag(ItemIconImageType.Changed))
return ForCheckedOut();
if (type.HasFlag(ItemIconImageType.Private))
return ForPrivate();
return null;
}
static Texture ForConflict(bool isResolved)
{
if (isResolved)
return ForConflictResolved();
return ForConflicted();
}
static Texture ForXLink()
{
return Images.GetImage(Images.Name.XLink);
}
static Texture ForIgnored()
{
return Images.GetIgnoredOverlayIcon();
}
static Texture ForPrivate()
{
return Images.GetPrivateOverlayIcon();
}
static Texture ForAdded()
{
return Images.GetAddedOverlayIcon();
}
static Texture ForDeleted()
{
return Images.GetDeletedLocalOverlayIcon();
}
static Texture ForMoved()
{
return Images.GetMovedOverlayIcon();
}
static Texture ForCheckedOut()
{
return Images.GetCheckedOutOverlayIcon();
}
static Texture ForDeletedOnServer()
{
return Images.GetDeletedRemoteOverlayIcon();
}
static Texture ForOutOfDate()
{
return Images.GetOutOfSyncOverlayIcon();
}
static Texture ForConflicted()
{
return Images.GetConflictedOverlayIcon();
}
static Texture ForConflictResolved()
{
return Images.GetConflictResolvedOverlayIcon();
}
}
}

View File

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

View File

@@ -0,0 +1,40 @@
using System.Collections.Generic;
using System.Linq;
namespace Unity.PlasticSCM.Editor.UI.Tree
{
internal class ListViewItemIds<I>
{
internal void Clear()
{
mCacheByInfo.Clear();
}
internal List<KeyValuePair<I, int>> GetInfoItems()
{
return mCacheByInfo.ToList();
}
internal bool TryGetInfoItemId(I info, out int itemId)
{
return mCacheByInfo.TryGetValue(info, out itemId);
}
internal int AddInfoItem(I info)
{
int itemId = GetNextItemId();
mCacheByInfo.Add(info, itemId);
return itemId;
}
int GetNextItemId()
{
return mCacheByInfo.Count + 1;
}
Dictionary<I, int> mCacheByInfo = new Dictionary<I, int>();
}
}

View File

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

View File

@@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
#if UNITY_6000_2_OR_NEWER
using TreeView = UnityEditor.IMGUI.Controls.TreeView<int>;
using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem<int>;
using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState<int>;
#endif
namespace Unity.PlasticSCM.Editor.UI.Tree
{
internal class PlasticTreeView : TreeView
{
internal PlasticTreeView(bool showCustomBackground = true)
: base(new TreeViewState())
{
mShowCustomBackground = showCustomBackground;
rowHeight = UnityConstants.TREEVIEW_ROW_HEIGHT;
treeViewRect = new Rect(0, 0, 0, rowHeight);
showAlternatingRowBackgrounds = false;
}
public override IList<TreeViewItem> GetRows()
{
return mRows;
}
internal Rect GetTreeViewRect()
{
return treeViewRect;
}
internal Rect GetRowRectByIndex(int rowIndex)
{
return GetRowRect(rowIndex);
}
internal bool HasKeyboardFocus()
{
if (PlasticApp.IsUnitTesting)
return true;
return treeViewControlID == GUIUtility.keyboardControl && GUI.enabled;
}
protected override TreeViewItem BuildRoot()
{
return new TreeViewItem(0, -1, string.Empty);
}
protected override void BeforeRowsGUI()
{
if (!mShowCustomBackground)
return;
int firstRowVisible;
int lastRowVisible;
GetFirstAndLastVisibleRows(out firstRowVisible, out lastRowVisible);
GUI.DrawTexture(new Rect(0,
firstRowVisible * rowHeight,
GetRowRect(0).width + 1000,
(lastRowVisible * rowHeight) + 1000),
Images.GetTreeviewBackgroundTexture());
DrawTreeViewItem.InitializeStyles();
base.BeforeRowsGUI();
}
readonly bool mShowCustomBackground;
protected List<TreeViewItem> mRows = new List<TreeViewItem>();
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 869a0fefec364e959e534cc842837d91
timeCreated: 1741852440

View File

@@ -0,0 +1,85 @@
using System.Collections.Generic;
using UnityEditor.IMGUI.Controls;
#if UNITY_6000_2_OR_NEWER
using TreeView = UnityEditor.IMGUI.Controls.TreeView<int>;
using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem<int>;
#endif
namespace Unity.PlasticSCM.Editor.UI.Tree
{
internal static class TableViewOperations
{
internal static int GetFirstSelectedRow(
TreeView treeView)
{
IList<int> selectedIds = treeView.GetSelection();
if (selectedIds.Count == 0)
return -1;
return selectedIds[0];
}
internal static void SelectFirstRow(
TreeView treeView)
{
IList<TreeViewItem> rows = treeView.GetRows();
if (rows.Count == 0)
return;
SetSelectionAndScroll(
treeView, new List<int> { rows[0].id });
}
internal static void SelectDefaultRow(
TreeView treeView, int defaultRow)
{
int rowCount = treeView.GetRows().Count;
if (defaultRow == -1 || rowCount == 0)
return;
if (defaultRow >= rowCount)
defaultRow = rowCount - 1;
SetSelectionAndScroll(
treeView, new List<int> { defaultRow });
}
internal static void SetSelectionAndScroll(
TreeView treeView, List<int> idsToSelect)
{
treeView.SetSelection(
idsToSelect,
TreeViewSelectionOptions.FireSelectionChanged |
TreeViewSelectionOptions.RevealAndFrame);
}
internal static void ScrollToSelection(
TreeView treeView)
{
if (!treeView.HasSelection())
return;
int itemId = treeView.GetSelection()[0];
if (!IsVisible(itemId, treeView))
return;
treeView.FrameItem(itemId);
}
static bool IsVisible(int id, TreeView treeView)
{
foreach (TreeViewItem item in treeView.GetRows())
{
if (item.id == id)
return true;
}
return false;
}
}
}

View File

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

View File

@@ -0,0 +1,62 @@
using UnityEditor.IMGUI.Controls;
using UnityEngine;
namespace Unity.PlasticSCM.Editor.UI.Tree
{
internal static class TreeHeaderColumns
{
internal static void SetTitles(
MultiColumnHeaderState.Column[] columns, string[] headerTitles)
{
for (int i = 0; i < headerTitles.Length; i++)
columns[i].headerContent = new GUIContent(headerTitles[i]);
}
internal static void SetVisibilities(
MultiColumnHeaderState.Column[] columns, bool[] visibilities)
{
for (int i = 0; i < visibilities.Length; i++)
columns[i].allowToggleVisibility = visibilities[i];
}
internal static void SetWidths(
MultiColumnHeaderState.Column[] columns, float[] widths)
{
for (int i = 0; i < widths.Length; i++)
columns[i].width = widths[i];
}
internal static string[] GetTitles(
MultiColumnHeaderState.Column[] columns)
{
string[] titles = new string[columns.Length];
for (int i = 0; i < columns.Length; i++)
titles[i] = columns[i].headerContent.text;
return titles;
}
internal static bool[] GetVisibilities(
MultiColumnHeaderState.Column[] columns)
{
bool[] visibilities = new bool[columns.Length];
for (int i = 0; i < columns.Length; i++)
visibilities[i] = columns[i].allowToggleVisibility;
return visibilities;
}
internal static float[] GetWidths(
MultiColumnHeaderState.Column[] columns)
{
float[] widths = new float[columns.Length];
for (int i = 0; i < columns.Length; i++)
widths[i] = columns[i].width;
return widths;
}
}
}

View File

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

View File

@@ -0,0 +1,142 @@
using System;
using System.Globalization;
using System.Linq;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using Codice.LogWrapper;
namespace Unity.PlasticSCM.Editor.UI.Tree
{
internal static class TreeHeaderSettings
{
internal static void Load(
MultiColumnHeaderState headerState,
string treeSettingsName,
int defaultSortColumnIdx,
bool defaultSortedAscending = true,
int[] defaultColumnVisibilities = null)
{
int[] visibleColumns;
float[] columnWidths;
GetColumnsSettings(treeSettingsName, headerState.columns.Length,
out visibleColumns, out columnWidths);
if (visibleColumns.Length > 0)
headerState.visibleColumns = visibleColumns;
else if (defaultColumnVisibilities != null)
headerState.visibleColumns = defaultColumnVisibilities;
if (headerState.columns.Length == columnWidths.Length)
TreeHeaderColumns.SetWidths(headerState.columns, columnWidths);
if (defaultSortColumnIdx == UnityConstants.UNSORT_COLUMN_ID)
return;
var sortColumnIdx = EditorPrefs.GetInt(
GetSettingKey(treeSettingsName, SORT_COLUMN_INDEX_KEY),
defaultSortColumnIdx);
if (sortColumnIdx < 0 || sortColumnIdx >= headerState.columns.Length)
sortColumnIdx = defaultSortColumnIdx;
var sortColumnAscending = EditorPrefs.GetBool(
GetSettingKey(treeSettingsName, SORT_ASCENDING_KEY),
defaultSortedAscending);
headerState.sortedColumnIndex = sortColumnIdx;
headerState.columns[sortColumnIdx].sortedAscending = sortColumnAscending;
}
internal static void Save(
MultiColumnHeaderState headerState,
string treeSettingsName)
{
int[] visibleColumns = headerState.visibleColumns;
float[] columnWidths = TreeHeaderColumns.GetWidths(headerState.columns);
EditorPrefs.SetString(
GetSettingKey(treeSettingsName, VISIBLE_COLUMNS_KEY),
string.Join(",", visibleColumns.Select(idx => idx.ToString()).ToArray()));
EditorPrefs.SetString(
GetSettingKey(treeSettingsName, COLUMNS_WIDTHS_KEY),
string.Join(",", columnWidths
.Select(w => w.ToString(CultureInfo.InvariantCulture))
.ToArray()));
int sortColumnIdx = headerState.sortedColumnIndex;
if (sortColumnIdx == UnityConstants.UNSORT_COLUMN_ID)
return;
bool sortColumnAscending = headerState.
columns[headerState.sortedColumnIndex].sortedAscending;
EditorPrefs.SetInt(
GetSettingKey(treeSettingsName, SORT_COLUMN_INDEX_KEY),
sortColumnIdx);
EditorPrefs.SetBool(
GetSettingKey(treeSettingsName, SORT_ASCENDING_KEY),
sortColumnAscending);
}
internal static void Clear(string treeSettingsName)
{
EditorPrefs.DeleteKey(
GetSettingKey(treeSettingsName, VISIBLE_COLUMNS_KEY));
EditorPrefs.DeleteKey(
GetSettingKey(treeSettingsName, COLUMNS_WIDTHS_KEY));
EditorPrefs.DeleteKey(
GetSettingKey(treeSettingsName, SORT_COLUMN_INDEX_KEY));
EditorPrefs.DeleteKey(
GetSettingKey(treeSettingsName, SORT_ASCENDING_KEY));
}
static void GetColumnsSettings(string treeSettingsName,
int headerColumnsLenght,
out int[] visibleColumns,
out float[] columnWidths)
{
try
{
visibleColumns = EditorPrefs.GetString(
GetSettingKey(treeSettingsName, VISIBLE_COLUMNS_KEY), string.Empty)
.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
.Select(idx => int.Parse(idx))
.Where(idx => idx >= 0 && idx < headerColumnsLenght)
.ToArray();
columnWidths = EditorPrefs.GetString(
GetSettingKey(treeSettingsName, COLUMNS_WIDTHS_KEY), string.Empty)
.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
.Select(w => float.Parse(w, CultureInfo.InvariantCulture))
.ToArray();
}
catch (Exception ex)
{
mLog.ErrorFormat("Unable to read TreeHeaderSettings: {0}",
ex.Message);
mLog.DebugFormat("Stack tracke:{0}{1}",
Environment.NewLine, ex.StackTrace);
visibleColumns = new int[0];
columnWidths = new float[0];
}
}
static string GetSettingKey(string treeSettingsName, string key)
{
return string.Format(treeSettingsName, PlayerSettings.productGUID, key);
}
static string VISIBLE_COLUMNS_KEY = "VisibleColumns";
static string COLUMNS_WIDTHS_KEY = "ColumnWidths";
static string SORT_COLUMN_INDEX_KEY = "SortColumnIdx";
static string SORT_ASCENDING_KEY = "SortAscending";
static readonly ILog mLog = PlasticApp.GetLogger("TreeHeaderSettings");
}
}

View File

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

View File

@@ -0,0 +1,28 @@
using UnityEditor.IMGUI.Controls;
using PlasticGui;
using Unity.PlasticSCM.Editor.Views.PendingChanges;
#if UNITY_6000_2_OR_NEWER
using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem<int>;
#endif
namespace Unity.PlasticSCM.Editor.UI.Tree
{
internal static class TreeViewItemExtensions
{
internal static IPlasticTreeNode GetPlasticTreeNode(this TreeViewItem item)
{
if (item is ChangelistTreeViewItem)
{
return ((ChangelistTreeViewItem)item).Changelist;
}
if (item is ChangeCategoryTreeViewItem)
{
return ((ChangeCategoryTreeViewItem)item).Category;
}
return ((ChangeTreeViewItem)item).ChangeInfo;
}
}
}

View File

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

View File

@@ -0,0 +1,113 @@
using System.Collections.Generic;
using System.Linq;
namespace Unity.PlasticSCM.Editor.UI.Tree
{
internal class TreeViewItemIds<T>
{
internal TreeViewItemIds()
{
mKeysById = new Dictionary<string, int>();
mItemsById = new Dictionary<int, T>();
}
internal bool TryGetItemIdByKey(string key, out int itemId)
{
return mKeysById.TryGetValue(key, out itemId);
}
internal bool TryGetItemById(int itemId, out T item)
{
return mItemsById.TryGetValue(itemId, out item);
}
internal int AddItemIdByKey(string key)
{
int itemId = GetNextItemId();
mKeysById.Add(key, itemId);
return itemId;
}
internal void AddItemById(int itemId, T item)
{
mItemsById[itemId] = item;
}
internal void ClearItems()
{
mItemsById.Clear();
}
int GetNextItemId()
{
return mKeysById.Count + 1;
}
readonly Dictionary<string, int> mKeysById;
readonly Dictionary<int, T> mItemsById;
}
internal class TreeViewItemIds<C, I>
{
internal void Clear()
{
mCacheByCategories.Clear();
mCacheByInfo.Clear();
}
internal List<int> GetCategoryIds()
{
return new List<int>(mCacheByCategories.Values);
}
internal List<KeyValuePair<C, int>> GetCategoryItems()
{
return mCacheByCategories.ToList();
}
internal List<KeyValuePair<I, int>> GetInfoItems()
{
return mCacheByInfo.ToList();
}
internal bool TryGetCategoryItemId(C category, out int itemId)
{
return mCacheByCategories.TryGetValue(category, out itemId);
}
internal bool TryGetInfoItemId(I info, out int itemId)
{
return mCacheByInfo.TryGetValue(info, out itemId);
}
internal int AddCategoryItem(C category)
{
int itemId = GetNextItemId();
mCacheByCategories.Add(category, itemId);
return itemId;
}
internal int AddInfoItem(I info)
{
int itemId = GetNextItemId();
mCacheByInfo.Add(info, itemId);
return itemId;
}
int GetNextItemId()
{
return mCacheByCategories.Count
+ mCacheByInfo.Count
+ 1;
}
readonly Dictionary<C, int> mCacheByCategories = new Dictionary<C, int>();
readonly Dictionary<I, int> mCacheByInfo = new Dictionary<I, int>();
}
}

View File

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

View File

@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
#if UNITY_6000_2_OR_NEWER
using TreeView = UnityEditor.IMGUI.Controls.TreeView<int>;
#endif
using PlasticGui;
namespace Unity.PlasticSCM.Editor.UI.Tree
{
internal class TreeViewSessionState
{
internal static void Save(
TreeView treeView,
string uncheckedKey)
{
var rows = treeView.GetRows();
if (!rows.Any())
return;
List<string> uncheckedRows = new List<string>();
for (int i = 0; i < rows.Count; i++)
{
bool? isChecked = CheckableItems.GetIsCheckedValue(
rows[i].GetPlasticTreeNode());
if (!isChecked.HasValue)
continue;
if (string.IsNullOrEmpty(rows[i].displayName))
continue;
if (!isChecked.Value)
uncheckedRows.Add(rows[i].displayName);
}
SessionState.SetString(uncheckedKey, string.Join(":", uncheckedRows));
}
internal static void Restore(
TreeView treeView,
string uncheckedKey)
{
var rows = treeView.GetRows();
if (!rows.Any())
return;
string uncheckedRows = SessionState.GetString(
uncheckedKey, string.Empty);
if (string.IsNullOrEmpty(uncheckedRows))
return;
string[] uncheckedArray = uncheckedRows.Split(':');
for (int i = 0; i < rows.Count; i++)
{
if (string.IsNullOrEmpty(rows[i].displayName))
continue;
if (uncheckedArray.Contains(rows[i].displayName))
{
CheckableItems.SetCheckedValue(
rows[i].GetPlasticTreeNode(), false);
continue;
}
CheckableItems.SetCheckedValue(
rows[i].GetPlasticTreeNode(), true);
}
// Clear session state after the every update
SessionState.EraseString(uncheckedKey);
}
}
}

View File

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