325 lines
11 KiB
C#
325 lines
11 KiB
C#
using System;
|
|
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
using PlasticGui;
|
|
using Unity.PlasticSCM.Editor.AssetsOverlays.Cache;
|
|
using Unity.PlasticSCM.Editor.UI;
|
|
|
|
namespace Unity.PlasticSCM.Editor.AssetsOverlays
|
|
{
|
|
internal static class DrawAssetOverlay
|
|
{
|
|
internal static void Initialize(
|
|
IAssetStatusCache cache,
|
|
Action repaintProjectWindow)
|
|
{
|
|
mAssetStatusCache = cache;
|
|
mRepaintProjectWindow = repaintProjectWindow;
|
|
|
|
EditorApplication.projectWindowItemOnGUI += OnProjectWindowItemGUI;
|
|
|
|
mRepaintProjectWindow();
|
|
}
|
|
|
|
internal static void Dispose()
|
|
{
|
|
EditorApplication.projectWindowItemOnGUI -= OnProjectWindowItemGUI;
|
|
|
|
if (mRepaintProjectWindow != null)
|
|
mRepaintProjectWindow();
|
|
}
|
|
|
|
internal static void ClearCache()
|
|
{
|
|
mAssetStatusCache.Clear();
|
|
mRepaintProjectWindow();
|
|
}
|
|
|
|
internal static AssetStatus GetStatusesToDraw(AssetStatus status)
|
|
{
|
|
if (status.HasFlag(AssetStatus.Checkout) &&
|
|
status.HasFlag(AssetStatus.Locked))
|
|
return status & ~AssetStatus.Checkout;
|
|
|
|
if (status.HasFlag(AssetStatus.DeletedOnServer) &&
|
|
status.HasFlag(AssetStatus.LockedRemote))
|
|
return status & ~AssetStatus.LockedRemote;
|
|
|
|
return status;
|
|
}
|
|
|
|
internal static string GetStatusString(AssetStatus statusValue)
|
|
{
|
|
switch (statusValue)
|
|
{
|
|
case AssetStatus.Private:
|
|
return PlasticLocalization.GetString(
|
|
PlasticLocalization.Name.Private);
|
|
case AssetStatus.Ignored:
|
|
return PlasticLocalization.GetString(
|
|
PlasticLocalization.Name.StatusIgnored);
|
|
case AssetStatus.Added:
|
|
return PlasticLocalization.GetString(
|
|
PlasticLocalization.Name.StatusAdded);
|
|
case AssetStatus.Checkout:
|
|
return PlasticLocalization.GetString(
|
|
PlasticLocalization.Name.StatusCheckout);
|
|
case AssetStatus.OutOfDate:
|
|
return PlasticLocalization.GetString(
|
|
PlasticLocalization.Name.StatusOutOfDate);
|
|
case AssetStatus.Conflicted:
|
|
return PlasticLocalization.GetString(
|
|
PlasticLocalization.Name.StatusConflicted);
|
|
case AssetStatus.DeletedOnServer:
|
|
return PlasticLocalization.GetString(
|
|
PlasticLocalization.Name.StatusDeletedOnServer);
|
|
case AssetStatus.Locked:
|
|
return PlasticLocalization.GetString(
|
|
PlasticLocalization.Name.StatusLockedMe);
|
|
case AssetStatus.LockedRemote:
|
|
return PlasticLocalization.GetString(
|
|
PlasticLocalization.Name.StatusLockedRemote);
|
|
}
|
|
|
|
return string.Empty;
|
|
}
|
|
|
|
internal static string GetTooltipText(
|
|
AssetStatus statusValue,
|
|
LockStatusData lockStatusData)
|
|
{
|
|
string statusText = GetStatusString(statusValue);
|
|
|
|
if (lockStatusData == null)
|
|
return statusText;
|
|
|
|
// example:
|
|
// Changed by:
|
|
// * dani_pen@hotmail.com
|
|
// * workspace wkLocal"
|
|
|
|
char bulletCharacter = '\u25cf';
|
|
|
|
string line1 = PlasticLocalization.GetString(
|
|
PlasticLocalization.Name.AssetOverlayTooltipStatus, statusText);
|
|
|
|
string line2 = string.Format("{0} {1}",
|
|
bulletCharacter,
|
|
lockStatusData.LockedBy);
|
|
|
|
string line3 = string.Format("{0} {1}",
|
|
bulletCharacter,
|
|
PlasticLocalization.GetString(
|
|
PlasticLocalization.Name.AssetOverlayTooltipWorkspace,
|
|
lockStatusData.WorkspaceName));
|
|
|
|
return string.Format(
|
|
"{0}" + Environment.NewLine +
|
|
"{1}" + Environment.NewLine +
|
|
"{2}",
|
|
line1,
|
|
line2,
|
|
line3);
|
|
}
|
|
|
|
static void OnProjectWindowItemGUI(string guid, Rect selectionRect)
|
|
{
|
|
if (string.IsNullOrEmpty(guid))
|
|
return;
|
|
|
|
if (Event.current.type != EventType.Repaint)
|
|
return;
|
|
|
|
AssetStatus statusesToDraw = GetStatusesToDraw(
|
|
mAssetStatusCache.GetStatusForGuid(guid));
|
|
|
|
foreach (AssetStatus status in Enum.GetValues(typeof(AssetStatus)))
|
|
{
|
|
if (status == AssetStatus.None)
|
|
continue;
|
|
|
|
if (!statusesToDraw.HasFlag(status))
|
|
continue;
|
|
|
|
LockStatusData lockStatusData =
|
|
ClassifyAssetStatus.IsLockedRemote(status) ?
|
|
mAssetStatusCache.GetLockStatusData(guid) :
|
|
null;
|
|
|
|
string tooltipText = GetTooltipText(
|
|
status,
|
|
lockStatusData);
|
|
|
|
DrawOverlayIcon.ForStatus(
|
|
selectionRect,
|
|
status,
|
|
tooltipText);
|
|
}
|
|
}
|
|
|
|
internal static class DrawOverlayIcon
|
|
{
|
|
internal static void ForStatus(
|
|
Rect selectionRect,
|
|
AssetStatus status,
|
|
string tooltipText)
|
|
{
|
|
Texture overlayIcon = GetOverlayIcon(status);
|
|
|
|
if (overlayIcon == null)
|
|
return;
|
|
|
|
Rect overlayRect = GetOverlayRect(
|
|
selectionRect, overlayIcon, status);
|
|
|
|
GUI.DrawTexture(
|
|
overlayRect, overlayIcon, ScaleMode.ScaleToFit);
|
|
|
|
Rect tooltipRect = GetTooltipRect(selectionRect, overlayRect);
|
|
|
|
GUI.Label(tooltipRect, new GUIContent(string.Empty, tooltipText));
|
|
}
|
|
|
|
internal static Texture GetOverlayIcon(AssetStatus status)
|
|
{
|
|
switch (status)
|
|
{
|
|
case AssetStatus.Ignored:
|
|
return Images.GetImage(Images.Name.Ignored);
|
|
case AssetStatus.Private:
|
|
return Images.GetPrivatedOverlayIcon();
|
|
case AssetStatus.Added:
|
|
return Images.GetAddedOverlayIcon();
|
|
case AssetStatus.Checkout:
|
|
return Images.GetCheckedOutOverlayIcon();
|
|
case AssetStatus.OutOfDate:
|
|
return Images.GetOutOfSyncOverlayIcon();
|
|
case AssetStatus.Conflicted:
|
|
return Images.GetConflictedOverlayIcon();
|
|
case AssetStatus.DeletedOnServer:
|
|
return Images.GetDeletedRemoteOverlayIcon();
|
|
case AssetStatus.Locked:
|
|
return Images.GetLockedLocalOverlayIcon();
|
|
case AssetStatus.LockedRemote:
|
|
return Images.GetLockedRemoteOverlayIcon();
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
static Rect Inflate(Rect rect, float width, float height)
|
|
{
|
|
return new Rect(
|
|
rect.x - width,
|
|
rect.y - height,
|
|
rect.width + 2 * width,
|
|
rect.height + 2 * height);
|
|
}
|
|
|
|
static Rect GetOverlayRect(
|
|
Rect selectionRect,
|
|
Texture overlayIcon,
|
|
AssetStatus status)
|
|
{
|
|
OverlayAlignment alignment = GetIconPosition(status);
|
|
|
|
if (selectionRect.width > selectionRect.height)
|
|
return GetOverlayRectForSmallestSize(
|
|
selectionRect, overlayIcon, alignment);
|
|
|
|
return GetOverlayRectForOtherSizes(
|
|
selectionRect, overlayIcon, alignment);
|
|
}
|
|
|
|
static Rect GetTooltipRect(
|
|
Rect selectionRect,
|
|
Rect overlayRect)
|
|
{
|
|
if (selectionRect.width > selectionRect.height)
|
|
{
|
|
return overlayRect;
|
|
}
|
|
|
|
return Inflate(overlayRect, 3, 3);
|
|
}
|
|
|
|
static Rect GetOverlayRectForSmallestSize(
|
|
Rect selectionRect,
|
|
Texture overlayIcon,
|
|
OverlayAlignment alignment)
|
|
{
|
|
float xOffset = IsLeftAligned(alignment) ? -5 : 5;
|
|
float yOffset = IsTopAligned(alignment) ? -4 : 4;
|
|
|
|
return new Rect(
|
|
selectionRect.x + xOffset,
|
|
selectionRect.y + yOffset,
|
|
OVERLAY_ICON_SIZE,
|
|
OVERLAY_ICON_SIZE);
|
|
}
|
|
|
|
static Rect GetOverlayRectForOtherSizes(
|
|
Rect selectionRect,
|
|
Texture overlayIcon,
|
|
OverlayAlignment alignment)
|
|
{
|
|
float xOffset = IsLeftAligned(alignment) ?
|
|
0 : selectionRect.width - overlayIcon.width;
|
|
|
|
float yOffset = IsTopAligned(alignment) ?
|
|
0 : selectionRect.height - overlayIcon.height - 12;
|
|
|
|
return new Rect(
|
|
selectionRect.x + xOffset,
|
|
selectionRect.y + yOffset,
|
|
OVERLAY_ICON_SIZE,
|
|
OVERLAY_ICON_SIZE);
|
|
}
|
|
|
|
static OverlayAlignment GetIconPosition(AssetStatus status)
|
|
{
|
|
if (status == AssetStatus.Checkout ||
|
|
status == AssetStatus.Locked)
|
|
return OverlayAlignment.TopLeft;
|
|
|
|
if (status == AssetStatus.DeletedOnServer ||
|
|
status == AssetStatus.LockedRemote)
|
|
return OverlayAlignment.TopRight;
|
|
|
|
if (status == AssetStatus.OutOfDate)
|
|
return OverlayAlignment.BottomRight;
|
|
|
|
return OverlayAlignment.BottomLeft;
|
|
}
|
|
|
|
static bool IsLeftAligned(OverlayAlignment alignment)
|
|
{
|
|
return alignment == OverlayAlignment.BottomLeft ||
|
|
alignment == OverlayAlignment.TopLeft;
|
|
}
|
|
|
|
static bool IsTopAligned(OverlayAlignment alignment)
|
|
{
|
|
return alignment == OverlayAlignment.TopLeft ||
|
|
alignment == OverlayAlignment.TopRight;
|
|
}
|
|
|
|
enum OverlayAlignment
|
|
{
|
|
TopLeft,
|
|
BottomLeft,
|
|
TopRight,
|
|
BottomRight
|
|
}
|
|
}
|
|
|
|
static IAssetStatusCache mAssetStatusCache;
|
|
static Action mRepaintProjectWindow;
|
|
|
|
const float OVERLAY_ICON_SIZE = 16;
|
|
}
|
|
}
|
|
|