first commit
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
using PlasticGui;
|
||||
using Unity.PlasticSCM.Editor.Help;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.PlasticSCM.Editor.UI.Tree
|
||||
{
|
||||
internal static class DrawTreeViewEmptyState
|
||||
{
|
||||
internal static void For(
|
||||
Rect rect,
|
||||
string text)
|
||||
{
|
||||
GUIContent content = new GUIContent(text);
|
||||
Vector2 contentSize = GetContentSize(content);
|
||||
|
||||
GUI.BeginGroup(rect);
|
||||
|
||||
DrawLabel(
|
||||
content,
|
||||
contentSize,
|
||||
(rect.width - contentSize.x) / 2,
|
||||
rect.height / 2);
|
||||
|
||||
GUI.EndGroup();
|
||||
}
|
||||
|
||||
internal static void For(
|
||||
Rect rect,
|
||||
string text,
|
||||
Texture2D icon)
|
||||
{
|
||||
GUIContent content = new GUIContent(text);
|
||||
Vector2 contentSize = GetContentSize(content);
|
||||
|
||||
GUI.BeginGroup(rect);
|
||||
|
||||
DrawLabelWithIcon(
|
||||
content,
|
||||
contentSize,
|
||||
(rect.width - contentSize.x) / 2,
|
||||
rect.height / 2,
|
||||
icon);
|
||||
|
||||
GUI.EndGroup();
|
||||
}
|
||||
|
||||
internal static void For(
|
||||
Rect rect,
|
||||
string text,
|
||||
Texture2D icon,
|
||||
ExternalLink externalLink)
|
||||
{
|
||||
GUIContent textContent = new GUIContent(text);
|
||||
Vector2 textContentSize = GetContentSize(textContent);
|
||||
|
||||
GUIContent linkContent = new GUIContent(externalLink.Label);
|
||||
Vector2 linkContentSize = GetContentSize(linkContent, EditorStyles.linkLabel);
|
||||
|
||||
float textContentOffsetY = (rect.height - (textContentSize.y + linkContentSize.y)) / 2;
|
||||
float linkContentOffsetY = textContentOffsetY + textContentSize.y;
|
||||
|
||||
GUI.BeginGroup(rect);
|
||||
|
||||
DrawLabelWithIcon(
|
||||
textContent,
|
||||
textContentSize,
|
||||
(rect.width - textContentSize.x) / 2,
|
||||
textContentOffsetY,
|
||||
icon);
|
||||
|
||||
DrawLink(
|
||||
externalLink,
|
||||
linkContent,
|
||||
linkContentSize,
|
||||
(rect.width - linkContentSize.x) / 2,
|
||||
linkContentOffsetY);
|
||||
|
||||
GUI.EndGroup();
|
||||
}
|
||||
|
||||
static void DrawLabel(
|
||||
GUIContent content,
|
||||
Vector2 contentSize,
|
||||
float offsetX,
|
||||
float offsetY)
|
||||
{
|
||||
GUI.Label(
|
||||
new Rect(offsetX, offsetY, contentSize.x, contentSize.y),
|
||||
content,
|
||||
UnityStyles.Tree.StatusLabel);
|
||||
}
|
||||
|
||||
static void DrawLabelWithIcon(
|
||||
GUIContent content,
|
||||
Vector2 contentSize,
|
||||
float offsetX,
|
||||
float offsetY,
|
||||
Texture2D icon)
|
||||
{
|
||||
int iconSize = UnityConstants.TREEVIEW_STATUS_ICON_SIZE;
|
||||
int padding = UnityConstants.TREEVIEW_STATUS_CONTENT_PADDING;
|
||||
|
||||
float iconOffsetX = offsetX - iconSize + padding;
|
||||
float contentOffsetX = offsetX + iconSize - padding;
|
||||
|
||||
GUI.DrawTexture(
|
||||
new Rect(iconOffsetX, offsetY + padding, iconSize, iconSize),
|
||||
icon,
|
||||
ScaleMode.ScaleToFit);
|
||||
|
||||
DrawLabel(
|
||||
content,
|
||||
contentSize,
|
||||
contentOffsetX,
|
||||
offsetY);
|
||||
}
|
||||
|
||||
static void DrawLink(
|
||||
ExternalLink externalLink,
|
||||
GUIContent linkContent,
|
||||
Vector2 linkContentSize,
|
||||
float offsetX,
|
||||
float offsetY)
|
||||
{
|
||||
Rect buttonPosition = new Rect(
|
||||
offsetX,
|
||||
offsetY,
|
||||
linkContentSize.x,
|
||||
linkContentSize.y);
|
||||
|
||||
EditorGUIUtility.AddCursorRect(buttonPosition, MouseCursor.Link);
|
||||
|
||||
if (GUI.Button(buttonPosition, linkContent, EditorStyles.linkLabel))
|
||||
{
|
||||
Application.OpenURL(externalLink.Url);
|
||||
}
|
||||
}
|
||||
|
||||
static Vector2 GetContentSize(GUIContent content)
|
||||
{
|
||||
return GetContentSize(content, UnityStyles.Tree.StatusLabel);
|
||||
}
|
||||
|
||||
static Vector2 GetContentSize(GUIContent content, GUIStyle guiStyle)
|
||||
{
|
||||
return guiStyle.CalcSize(content);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd26c4fb413ea6d4687ebc488ff8a8c4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,286 @@
|
||||
using UnityEditor;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.PlasticSCM.Editor.UI.Tree
|
||||
{
|
||||
internal static class DrawTreeViewItem
|
||||
{
|
||||
internal static void InitializeStyles()
|
||||
{
|
||||
if (EditorStyles.label == null)
|
||||
return;
|
||||
|
||||
TreeView.DefaultStyles.label = UnityStyles.Tree.Label;
|
||||
TreeView.DefaultStyles.boldLabel = UnityStyles.Tree.BoldLabel;
|
||||
}
|
||||
|
||||
internal static void ForCategoryItem(
|
||||
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 bool ForCheckableCategoryItem(
|
||||
Rect rowRect,
|
||||
float rowHeight,
|
||||
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, rowHeight);
|
||||
|
||||
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,
|
||||
Texture overlayIcon,
|
||||
string label,
|
||||
bool isSelected,
|
||||
bool isFocused,
|
||||
bool isBoldText,
|
||||
bool isSecondaryLabel)
|
||||
{
|
||||
float indent = GetIndent(depth);
|
||||
|
||||
rect.x += indent;
|
||||
rect.width -= indent;
|
||||
|
||||
rect = DrawIconLeft(
|
||||
rect, rowHeight, icon, overlayIcon);
|
||||
|
||||
if (isSecondaryLabel)
|
||||
{
|
||||
ForSecondaryLabel(rect, label, isSelected, isFocused, isBoldText);
|
||||
return;
|
||||
}
|
||||
|
||||
ForLabel(rect, label, isSelected, isFocused, isBoldText);
|
||||
}
|
||||
|
||||
internal static bool ForCheckableItemCell(
|
||||
Rect rect,
|
||||
float rowHeight,
|
||||
int depth,
|
||||
Texture icon,
|
||||
Texture overlayIcon,
|
||||
string label,
|
||||
bool isSelected,
|
||||
bool isFocused,
|
||||
bool isHighlighted,
|
||||
bool wasChecked)
|
||||
{
|
||||
float indent = GetIndent(depth);
|
||||
|
||||
rect.x += indent;
|
||||
rect.width -= indent;
|
||||
|
||||
Rect checkRect = GetCheckboxRect(rect, rowHeight);
|
||||
|
||||
bool isChecked = EditorGUI.Toggle(checkRect, wasChecked);
|
||||
|
||||
rect.x = checkRect.xMax;
|
||||
rect.width -= checkRect.width;
|
||||
|
||||
rect = DrawIconLeft(
|
||||
rect, rowHeight, icon, overlayIcon);
|
||||
|
||||
if (isHighlighted)
|
||||
TreeView.DefaultGUI.BoldLabel(rect, label, isSelected, isFocused);
|
||||
else
|
||||
TreeView.DefaultGUI.Label(rect, label, isSelected, isFocused);
|
||||
|
||||
return isChecked;
|
||||
}
|
||||
|
||||
internal static Rect DrawIconLeft(
|
||||
Rect rect,
|
||||
float rowHeight,
|
||||
Texture icon,
|
||||
Texture overlayIcon)
|
||||
{
|
||||
if (icon == null)
|
||||
return rect;
|
||||
|
||||
float iconWidth = rowHeight * ((float)icon.width / icon.height);
|
||||
|
||||
Rect iconRect = new Rect(rect.x, rect.y, iconWidth, rowHeight);
|
||||
|
||||
EditorGUI.LabelField(iconRect, new GUIContent(icon), UnityStyles.Tree.IconStyle);
|
||||
|
||||
if (overlayIcon != null)
|
||||
{
|
||||
Rect overlayIconRect = OverlayRect.GetOverlayRect(
|
||||
iconRect,
|
||||
OVERLAY_ICON_OFFSET);
|
||||
|
||||
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, float rowHeight)
|
||||
{
|
||||
return new Rect(
|
||||
rect.x,
|
||||
rect.y + UnityConstants.TREEVIEW_CHECKBOX_Y_OFFSET,
|
||||
UnityConstants.TREEVIEW_CHECKBOX_SIZE,
|
||||
rect.height);
|
||||
}
|
||||
|
||||
static float GetIndent(int depth)
|
||||
{
|
||||
if (depth == -1)
|
||||
return 0;
|
||||
|
||||
return 16 + (depth * 16);
|
||||
}
|
||||
|
||||
internal static void ForSecondaryLabelRightAligned(
|
||||
Rect rect,
|
||||
string label,
|
||||
bool isSelected,
|
||||
bool isFocused,
|
||||
bool isBoldText)
|
||||
{
|
||||
if (Event.current.type != EventType.Repaint)
|
||||
return;
|
||||
|
||||
if (isBoldText)
|
||||
{
|
||||
GUIStyle secondaryBoldRightAligned =
|
||||
UnityStyles.Tree.SecondaryLabelBoldRightAligned;
|
||||
secondaryBoldRightAligned.Draw(
|
||||
rect, label, false, true, isSelected, isFocused);
|
||||
return;
|
||||
}
|
||||
|
||||
GUIStyle secondaryLabelRightAligned =
|
||||
UnityStyles.Tree.SecondaryLabelRightAligned;
|
||||
secondaryLabelRightAligned.Draw(
|
||||
rect, label, false, true, isSelected, isFocused);
|
||||
}
|
||||
|
||||
internal static void ForSecondaryLabel(
|
||||
Rect rect,
|
||||
string label,
|
||||
bool isSelected,
|
||||
bool isFocused,
|
||||
bool isBoldText)
|
||||
{
|
||||
if (Event.current.type != EventType.Repaint)
|
||||
return;
|
||||
|
||||
if (isBoldText)
|
||||
{
|
||||
GUIStyle secondaryBoldLabel =
|
||||
UnityStyles.Tree.SecondaryBoldLabel;
|
||||
|
||||
secondaryBoldLabel.normal.textColor = Color.red;
|
||||
|
||||
secondaryBoldLabel.Draw(
|
||||
rect, label, false, true, isSelected, isFocused);
|
||||
return;
|
||||
}
|
||||
|
||||
GUIStyle secondaryLabel =
|
||||
UnityStyles.Tree.SecondaryLabel;
|
||||
|
||||
secondaryLabel.Draw(
|
||||
rect, label, false, true, isSelected, isFocused);
|
||||
}
|
||||
|
||||
internal static void ForLabel(
|
||||
Rect rect,
|
||||
string label,
|
||||
bool isSelected,
|
||||
bool isFocused,
|
||||
bool isBoldText)
|
||||
{
|
||||
if (Event.current.type != EventType.Repaint)
|
||||
return;
|
||||
|
||||
if (isBoldText)
|
||||
{
|
||||
GUIStyle boldLabel = UnityStyles.Tree.BoldLabel;
|
||||
boldLabel.Draw(
|
||||
rect, label, false, true, isSelected, isFocused);
|
||||
return;
|
||||
}
|
||||
|
||||
GUIStyle normalLabel = UnityStyles.Tree.Label;
|
||||
normalLabel.Draw(
|
||||
rect, label, false, true, isSelected, isFocused);
|
||||
}
|
||||
|
||||
const float OVERLAY_ICON_OFFSET = 16f;
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 595175d7af8f8234a9336a60e33b4f32
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,150 @@
|
||||
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 ForPlasticIncomingChange(
|
||||
MergeChangeInfo incomingChange,
|
||||
bool isSolvedConflict)
|
||||
{
|
||||
if (incomingChange.CategoryType == MergeChangesCategory.Type.FileConflicts ||
|
||||
incomingChange.CategoryType == MergeChangesCategory.Type.DirectoryConflicts)
|
||||
return ForConflict(isSolvedConflict);
|
||||
|
||||
if (incomingChange.IsXLink())
|
||||
return ForXLink();
|
||||
|
||||
if (incomingChange.CategoryType == MergeChangesCategory.Type.Deleted)
|
||||
return ForDeletedOnServer();
|
||||
|
||||
if (incomingChange.CategoryType == MergeChangesCategory.Type.Changed)
|
||||
return ForOutOfDate();
|
||||
|
||||
if (incomingChange.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 (type.HasFlag(ItemIconImageType.CheckedOut))
|
||||
return ForCheckedOut();
|
||||
|
||||
if (type.HasFlag(ItemIconImageType.Private))
|
||||
return ForPrivated();
|
||||
|
||||
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 ForPrivated()
|
||||
{
|
||||
return Images.GetPrivatedOverlayIcon();
|
||||
}
|
||||
|
||||
static Texture ForAdded()
|
||||
{
|
||||
return Images.GetAddedOverlayIcon();
|
||||
}
|
||||
|
||||
static Texture ForDeleted()
|
||||
{
|
||||
return Images.GetDeletedLocalOverlayIcon();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5366deaa0659eb44aa77a86d8bdc01a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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>();
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8497dad3a6163fe40a30ca297edd7b2d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,81 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
|
||||
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)
|
||||
{
|
||||
int rowCount = treeView.GetRows().Count;
|
||||
|
||||
if (rowCount == 0)
|
||||
return;
|
||||
|
||||
SetSelectionAndScroll(
|
||||
treeView, new List<int> { 1 });
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 014287a1a6b67dd4e867168699dfdc2a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c3c7b1998f264b443a5b5c67a189149a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,139 @@
|
||||
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[] visibleColumns;
|
||||
float[] columnWidths;
|
||||
|
||||
GetColumnsSettings(treeSettingsName, headerState.columns.Length,
|
||||
out visibleColumns, out columnWidths);
|
||||
|
||||
if (visibleColumns.Length > 0)
|
||||
headerState.visibleColumns = visibleColumns;
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 38b05cc5af29cf844a31910eb512e92f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,67 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Unity.PlasticSCM.Editor.UI.Tree
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
Dictionary<C, int> mCacheByCategories = new Dictionary<C, int>();
|
||||
Dictionary<I, int> mCacheByInfo = new Dictionary<I, int>();
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2986eff1677c33345b223bdaaee2d284
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user