Commit 1c847220 authored by jang dong hyeok's avatar jang dong hyeok
Browse files

.

parent 076f0c68
.unity-tab-view {
flex-grow: 1;
}
.unity-tab-view__content-container {
flex: 1 1 auto;
}
.unity-tab-view__toolbar {
flex-direction: row;
border-bottom-width: 1px;
}
.dark .unity-tab-view__toolbar {
border-color: var(--divider-dark);
}
.light .unity-tab-view__toolbar {
border-color: var(--divider-light);
}
.unity-text-button.unity-tab-view__tab-header {
background-color: rgba(0, 0, 0, 0);
border-color: rgba(0, 0, 0, 0);
border-width: 0;
border-bottom-width: 2px;
padding: 3px 0 2px;
margin-right: var(--standard-margin);
}
.unity-text-button.unity-tab-view__tab-header.active {
border-color: #357CC0;
background-color: var(--no-color);
}
.dark .unity-text-button.unity-tab-view__tab-header.active:active {
background-color: var(--no-color);
}
.light .unity-text-button.unity-tab-view__tab-header.active:active {
background-color: var(--no-color);
}
/* TextButton Styles */
.unity-text-button {
border-width: 0;
padding: 3px 5px 2px;
margin: 0;
}
.dark .unity-text-button:focus {
background-color: var(--dark-button-hover-focus-bg-color);
}
.light .unity-text-button:focus {
background-color: var(--light-button-hover-focus-bg-color);
}
.dark .unity-text-button:active,
.dark .unity-text-button:hover:active {
background-color: var(--dark-button-active-bg-color);
}
.light .unity-text-button:active,
.light .unity-text-button:hover:active {
background-color: var(--light-button-active-bg-color);
}
/* ToggleableChangeEntry Styles */
.toggleable-change-list-element__toggle {
padding: 0;
margin: 0 var(--half-standard-margin) 0 var(--quarter-standard-margin);
}
/* TopBar Styles */
.top-bar {
flex: var(--fixed-size);
}
.top-bar__icon {
width: var(--icon-size);
height: var(--icon-size);
margin-right: var(--icon-standard-margin);
}
.top-bar__container,
.top-bar__back {
align-items: center;
}
.top-bar__overflow-button {
margin-right: 0;
}
.top-bar__back-button {
margin-right: var(--icon-standard-margin);
}
.top-bar__back {
margin-right: var(--standard-margin);
}
.dark .top-bar__icon {
background-image: resource("Packages/com.unity.collab-proxy/Editor/Collaborate/Assets/Icons/collaborate-dark.png");
}
.light .top-bar__icon {
background-image: resource("Packages/com.unity.collab-proxy/Editor/Collaborate/Assets/Icons/collaborate-light.png");
}
/* Global Styles */
/* can't use :root here for some reason -- the variables get lost when switching between changes and history tabs */
* {
--standard-margin: 8px;
--half-standard-margin: 4px;
--quarter-standard-margin: 2px;
--standard-padding: var(--standard-margin);
--icon-size: 16px;
--half-icon-size: 8px;
--large-icon-size: 22px;
--half-large-icon-size: 11px;
--icon-standard-margin: var(--half-standard-margin);
--list-entry-height: 25px;
--list-entry-path-font-size: 10px;
--dark-list-entry-path-text-color: #949494;
--light-list-entry-path-text-color: #6B6B6B;
--profile-icon-font-size: 13px;
--no-color: rgba(0, 0, 0, 0);
--dark-placeholder-text-color: #7D7D7D;
--light-placeholder-text-color: #7D7D7D;
/* Colours used for custom buttons that don't have a border */
--dark-button-hover-focus-bg-color: #303030;
--light-button-hover-focus-bg-color: #B2B2B2;
--dark-button-active-bg-color: #484848;
--light-button-active-bg-color: #8F8F8F;
--divider-dark: #5F5F5F;
--divider-light: #9A9A9A;
--fixed-size: 0 0 auto;
}
.hidden {
display: none;
}
.divider-horizontal {
height: 1px;
}
.dark .divider-horizontal {
background-color: var(--divider-dark);
}
.light .divider-horizontal {
background-color: var(--divider-light);
}
.divider-vertical {
width: 1px;
}
.dark .divider-vertical {
background-color: var(--divider-dark);
}
.light .divider-vertical {
background-color: var(--divider-light);
}
.row {
flex-direction: row;
}
.column {
flex-direction: column;
}
.grow {
flex-grow: 1;
}
using System;
namespace Unity.Cloud.Collaborate.Assets
{
internal static class UiConstants
{
public const int ChangesListViewItemHeight = 24;
public const int HistoryListViewItemHeight = 24;
// USS classes
public const string ussDark = "dark";
public const string ussLight = "light";
public const string ussHidden = "hidden";
public const string ussDefaultInset = "default-inset";
public const string ussActive = "active";
}
}
using System;
using UnityEngine;
namespace Unity.Cloud.Collaborate.Common {
[Serializable]
internal class ArrayContainer<T>
{
[SerializeField] public T[] Values = new T[0];
}
}
using System;
using UnityEditorInternal;
using UnityEngine;
namespace Unity.Cloud.Collaborate.Common {
[AttributeUsage(AttributeTargets.Class)]
internal sealed class LocationAttribute : Attribute
{
public enum Location { PreferencesFolder, LibraryFolder }
string m_RelativePath;
readonly Location m_Location;
string m_FilePath;
public string FilePath {
get {
if (m_FilePath != null) return m_FilePath;
if (m_RelativePath[0] == '/')
m_RelativePath = m_RelativePath.Substring(1);
if (m_Location == Location.PreferencesFolder)
m_FilePath = $"{InternalEditorUtility.unityPreferencesFolder}/{m_RelativePath}";
else if (m_Location == Location.LibraryFolder)
m_FilePath = $"Library/Collab/{m_RelativePath}";
return m_FilePath;
}
}
public LocationAttribute(string relativePath, Location location)
{
//Guard.ArgumentNotNullOrWhiteSpace(relativePath, "relativePath");
m_RelativePath = relativePath;
m_Location = location;
}
}
}
# Unity Collaborate Common Code
This directory contains common classes and logic for the package.
## Overview
This is the structure of the directory:
```none
<root>
├── LocationAttribute.cs
└── ScriptableObjectSingleton.cs
```
`LocationAttribute.cs` attribute used to specify where to cache the ScriptableObjectSingleton.
`ScriptableObjectSingleton.cs` public version of the ScriptableSingleton class in Unity and modified from the
GitHubForUnity implementation of it.
using System;
using System.IO;
using System.Linq;
using JetBrains.Annotations;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.Assertions;
using Object = UnityEngine.Object;
namespace Unity.Cloud.Collaborate.Common
{
internal class ScriptableObjectSingleton<T> : ScriptableObject where T : ScriptableObject
{
static T s_Instance;
public static T Instance
{
get
{
if (s_Instance == null)
CreateAndLoad();
return s_Instance;
}
}
protected ScriptableObjectSingleton()
{
if (s_Instance != null)
{
Debug.LogError("Singleton already exists!");
}
else
{
s_Instance = this as T;
Assert.IsFalse(s_Instance == null);
}
}
static void CreateAndLoad()
{
Assert.IsTrue(s_Instance == null);
var filePath = GetFilePath();
if (!string.IsNullOrEmpty(filePath) && File.Exists(filePath))
{
InternalEditorUtility.LoadSerializedFileAndForget(filePath);
}
if (s_Instance == null)
{
var inst = CreateInstance<T>() as ScriptableObjectSingleton<T>;
Assert.IsFalse(inst == null);
inst.hideFlags = HideFlags.HideAndDontSave;
inst.Save();
}
Assert.IsFalse(s_Instance == null);
}
protected void Save()
{
if (s_Instance == null)
{
Debug.LogError("Cannot save singleton, no instance!");
return;
}
var locationFilePath = GetFilePath();
var directoryName = Path.GetDirectoryName(locationFilePath);
if (directoryName == null) return;
Directory.CreateDirectory(directoryName);
InternalEditorUtility.SaveToSerializedFileAndForget(new Object[]{ s_Instance }, locationFilePath, true);
}
[CanBeNull]
static string GetFilePath()
{
var attr = typeof(T).GetCustomAttributes(true)
.OfType<LocationAttribute>()
.FirstOrDefault();
return attr?.FilePath;
}
}
}
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using UnityEngine;
namespace Unity.Cloud.Collaborate.Common
{
//http://answers.unity3d.com/answers/809221/view.html
[Serializable]
internal class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, ISerializationCallbackReceiver
{
[SerializeField]
List<TKey> m_Keys = new List<TKey>();
[SerializeField]
List<TValue> m_Values = new List<TValue>();
public SerializableDictionary()
{
}
public SerializableDictionary(IDictionary<TKey, TValue> input) : base(input)
{
}
// Save the dictionary to lists
public void OnBeforeSerialize()
{
m_Keys.Clear();
m_Values.Clear();
foreach (var pair in this)
{
m_Keys.Add(pair.Key);
m_Values.Add(pair.Value);
}
}
// load dictionary from lists
public void OnAfterDeserialize()
{
Clear();
if (m_Keys.Count != m_Values.Count)
{
throw new SerializationException($"there are {m_Keys.Count} keys and {m_Values.Count} " +
"values after deserialization. Make sure that both key and value types are serializable.");
}
for (var i = 0; i < m_Keys.Count; i++)
{
Add(m_Keys[i], m_Values[i]);
}
}
}
}
using System;
namespace Unity.Cloud.Collaborate.Common {
[Serializable]
internal class StringArrayContainer : ArrayContainer<string>
{}
}
using System;
using JetBrains.Annotations;
using Unity.Cloud.Collaborate.Views.Adapters;
using Unity.Cloud.Collaborate.Views.Adapters.ListAdapters;
using UnityEngine.Assertions;
using UnityEngine.UIElements;
namespace Unity.Cloud.Collaborate.Components
{
internal class AdapterListView : VisualElement, IAdapterObserver
{
public const string UssClassName = "unity-adapter-list-view";
public const string ListViewUssClassName = UssClassName + "__list-view";
IAdapter m_Adapter;
readonly ListView m_ListView;
public AdapterListView()
{
AddToClassList(UssClassName);
m_ListView = new ListView();
m_ListView.style.flexGrow = new StyleFloat(1);
m_ListView.AddToClassList(ListViewUssClassName);
Add(m_ListView);
}
/// <summary>
/// Set the adapter for the list.
/// </summary>
/// <param name="adapter">Adapter for the list to use.</param>
/// <typeparam name="T">The type of the list entries.</typeparam>
public void SetAdapter<T>(BaseListAdapter<T> adapter) where T : VisualElement
{
Assert.IsNull(m_Adapter, "There cannot be more than one adapter at a time.");
m_Adapter = adapter;
m_Adapter.RegisterObserver(this);
m_ListView.makeItem = m_Adapter.MakeItem;
m_ListView.bindItem = m_Adapter.BindItem;
m_ListView.itemHeight = m_Adapter.Height;
NotifyDataSetChanged();
}
/// <summary>
/// Remove adapter from the list.
/// </summary>
public void RemoveAdapter()
{
Assert.IsNotNull(m_Adapter, "Cannot remove a non-existent adapter.");
m_Adapter.DeregisterObserver(this);
m_ListView.makeItem = null;
m_ListView.bindItem = null;
m_ListView.itemHeight = 0;
m_ListView.itemsSource = null;
m_Adapter = null;
}
/// <summary>
/// Set the selection type of the list.
/// </summary>
public SelectionType SelectionType
{
set => m_ListView.selectionType = value;
get => m_ListView.selectionType;
}
/// <summary>
/// Notify that the data in this list has changed.
/// </summary>
public void NotifyDataSetChanged()
{
// TODO: pagination support would be done here if it happens.
// Feed the ListView a dummy list of the correct length.
m_ListView.itemsSource = new bool[m_Adapter.GetEntryCount()];
}
public void ScrollToIndex(int idx)
{
m_ListView.ScrollToItem(idx);
}
[UsedImplicitly]
public new class UxmlFactory : UxmlFactory<AdapterListView> { }
}
}
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using Unity.Cloud.Collaborate.Assets;
using Unity.Cloud.Collaborate.UserInterface;
using UnityEditor;
using UnityEngine.UIElements;
namespace Unity.Cloud.Collaborate.Components
{
[UsedImplicitly]
internal class AlertBox : VisualElement
{
/// <summary>
/// Describes the severity of the alert. Used to set the icon.
/// </summary>
public enum AlertLevel
{
Info,
Warning,
Alert
}
public const string UssClassName = "alert-box";
public const string IconUssClassName = UssClassName + "__icon";
public const string TextUssClassName = UssClassName + "__text";
public const string ButtonUssClassName = UssClassName + "__button";
static readonly string k_LayoutPath = $"{CollaborateWindow.LayoutPath}/{nameof(AlertBox)}.uxml";
static readonly string k_StylePath = $"{CollaborateWindow.StylePath}/{nameof(AlertBox)}.uss";
readonly Button m_Button;
readonly VisualElement m_Icon;
readonly TextElement m_Text;
// Uss classes to set which icon is displayed.
const string k_UssIconInfo = "icon-info";
const string k_UssIconWarning = "icon-warning";
const string k_UssIconAlert = "icon-alert";
/// <summary>
/// Queue of alerts to be displayed.
/// </summary>
readonly SortedSet<AlertEntry> m_AlertEntryList;
/// <summary>
/// Initialize the box and hide it.
/// </summary>
public AlertBox()
{
// Get the layout
AddToClassList(UssClassName);
AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(k_LayoutPath).CloneTree(this);
styleSheets.Add(AssetDatabase.LoadAssetAtPath<StyleSheet>(k_StylePath));
// Initialise fields
m_Icon = this.Q<VisualElement>(className: IconUssClassName);
m_Text = this.Q<TextElement>(className: TextUssClassName);
m_Button = this.Q<Button>(className: ButtonUssClassName);
m_AlertEntryList = new SortedSet<AlertEntry>();
// No alerts to display, so this hides the box.
UpdateAlertBox();
}
/// <summary>
/// Queue an alert to be displayed. Displayed immediately if there is currently none. If there is an existing
/// alert with the same name, it will be replaced with the latest one.
/// </summary>
/// <param name="id">Unique ID for the queued alert.</param>
/// <param name="level">Level of important of the alert.</param>
/// <param name="message">Message to be displayed.</param>
/// <param name="button">Info to populate optional button.</param>
public void QueueAlert([NotNull] string id, AlertLevel level, [NotNull] string message, (string text, Action action)? button = null)
{
// Search for existing alert.
var oldActive = m_AlertEntryList.Count == 0 ? (AlertEntry?)null : m_AlertEntryList.Max;
// Create new alert entry.
var entry = new AlertEntry(id, level, message, button == null
? (AlertEntry.AlertButton?)null
: new AlertEntry.AlertButton { Text = button.Value.text, Action = button.Value.action });
m_AlertEntryList.Add(entry);
UpdateAlertBox(oldActive?.Button?.Action);
}
/// <summary>
/// Remove existing alert. If current active one, switch to next one, or hide if none queued.
/// </summary>
/// <param name="id">Unique ID for the alert.</param>
public void DequeueAlert([NotNull] string id)
{
var oldAlert = m_AlertEntryList.Max;
m_AlertEntryList.RemoveWhere(e => e.Id == id);
UpdateAlertBox(oldAlert.Button?.Action);
}
/// <summary>
/// Display alert at the front of the queue, or hide if there are none.
/// </summary>
void UpdateAlertBox(Action previousButtonAction = null)
{
// Remove old event if it exists.
if (previousButtonAction != null)
{
m_Button.clickable.clicked -= previousButtonAction;
}
if (m_AlertEntryList.Count == 0)
{
m_Button.text = string.Empty;
m_Button.AddToClassList(UiConstants.ussHidden);
AddToClassList(UiConstants.ussHidden);
}
else
{
var activeAlert = m_AlertEntryList.Max;
m_Text.text = activeAlert.Message;
// Update state of optional button
if (activeAlert.Button?.Action != null)
{
m_Button.clickable.clicked += activeAlert.Button.Value.Action;
m_Button.text = activeAlert.Button.Value.Text;
m_Button.RemoveFromClassList(UiConstants.ussHidden);
}
else
{
m_Button.text = string.Empty;
m_Button.AddToClassList(UiConstants.ussHidden);
}
SetAlertLevel(activeAlert.Level);
RemoveFromClassList(UiConstants.ussHidden);
}
}
/// <summary>
/// Set the icon to the given severity level.
/// </summary>
/// <param name="level">Level of severity to make the icon.</param>
void SetAlertLevel(AlertLevel level)
{
// Remove old level
m_Icon.RemoveFromClassList(k_UssIconInfo);
m_Icon.RemoveFromClassList(k_UssIconWarning);
m_Icon.RemoveFromClassList(k_UssIconAlert);
// Set new one
switch (level)
{
case AlertLevel.Info:
m_Icon.AddToClassList(k_UssIconInfo);
break;
case AlertLevel.Warning:
m_Icon.AddToClassList(k_UssIconWarning);
break;
case AlertLevel.Alert:
m_Icon.AddToClassList(k_UssIconAlert);
break;
default:
throw new ArgumentOutOfRangeException(nameof(level), level, null);
}
}
struct AlertEntry : IComparable<AlertEntry>
{
public readonly string Id;
public readonly AlertLevel Level;
public readonly string Message;
public AlertButton? Button;
public AlertEntry(string id, AlertLevel level, string message, AlertButton? button)
{
Id = id;
Level = level;
Message = message;
Button = button;
}
public struct AlertButton
{
public string Text;
public Action Action;
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
public override bool Equals(object obj)
{
return obj is AlertEntry other && Id == other.Id;
}
public int CompareTo(AlertEntry other)
{
var value = Level.CompareTo(other.Level);
// If same level, compare by id.
return value != 0
? value
: string.Compare(Id, other.Id, StringComparison.Ordinal);
}
}
[UsedImplicitly]
public new class UxmlFactory : UxmlFactory<AlertBox> { }
}
}
using System;
using JetBrains.Annotations;
using Unity.Cloud.Collaborate.Assets;
using Unity.Cloud.Collaborate.UserInterface;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace Unity.Cloud.Collaborate.Components
{
// Hopefully these features will eventually be in the default TextField eventually.
internal class BetterTextField : TextField
{
/// <summary>
/// USS class name of elements of this type.
/// </summary>
public const string UssClassName = "unity-better-text-field";
/// <summary>
/// USS class name of placeholder elements of this type.
/// </summary>
public const string PlaceholderUssClassName = UssClassName + "__placeholder";
static readonly string k_StylePath = $"{CollaborateWindow.StylePath}/{nameof(BetterTextField)}.uss";
readonly Label m_PlaceholderLabel;
/// <summary>
/// Notify external subscribers that value of text property changed.
/// </summary>
public Action<string> OnValueChangedHandler;
public BetterTextField()
{
AddToClassList(UssClassName);
styleSheets.Add(AssetDatabase.LoadAssetAtPath<StyleSheet>(k_StylePath));
// Add and configure placeholder
m_PlaceholderLabel = new Label { pickingMode = PickingMode.Ignore };
m_PlaceholderLabel.AddToClassList(PlaceholderUssClassName);
Add(m_PlaceholderLabel);
RegisterCallback<FocusInEvent>(e => HidePlaceholder());
RegisterCallback<FocusOutEvent>(e =>
{
if (string.IsNullOrEmpty(text))
{
ShowPlaceholder();
}
});
this.RegisterValueChangedCallback(e => OnValueChangedHandler?.Invoke(e.newValue));
}
void UpdatePlaceholderVisibility()
{
if (string.IsNullOrEmpty(value))
{
// Value can be set before the focus control is initialised.
if (focusController?.focusedElement != this)
{
ShowPlaceholder();
}
}
else
{
HidePlaceholder();
}
}
void HidePlaceholder()
{
m_PlaceholderLabel?.AddToClassList(UiConstants.ussHidden);
}
void ShowPlaceholder()
{
m_PlaceholderLabel?.RemoveFromClassList(UiConstants.ussHidden);
}
public override string value
{
get => base.value;
set
{
// Catch case of value being set programatically.
base.value = value;
UpdatePlaceholderVisibility();
}
}
public string Placeholder
{
get => m_PlaceholderLabel.text;
set => m_PlaceholderLabel.text = value;
}
public override void SetValueWithoutNotify(string newValue)
{
base.SetValueWithoutNotify(newValue);
UpdatePlaceholderVisibility();
}
[UsedImplicitly]
public new class UxmlFactory : UxmlFactory<BetterTextField, UxmlTraits> { }
public new class UxmlTraits : TextField.UxmlTraits
{
readonly UxmlStringAttributeDescription m_Hint = new UxmlStringAttributeDescription { name = "placeholder" };
public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
{
base.Init(ve, bag, cc);
var field = (BetterTextField)ve;
field.Placeholder = m_Hint.GetValueFromBag(bag, cc);
}
}
}
}
using System;
using JetBrains.Annotations;
using Unity.Cloud.Collaborate.Assets;
using UnityEngine.UIElements;
namespace Unity.Cloud.Collaborate.Components
{
internal class ChangeEntryGroup : VisualElement
{
readonly AdapterListView m_ListView;
readonly ChangesGroupHeader m_GroupHeader;
readonly ListNotice m_ListNotice;
[NotNull]
string m_Title = string.Empty;
bool m_Searching;
int m_SelectedEntryCount;
int m_EntryCount;
public ChangeEntryGroup([NotNull] AdapterListView adapterListView)
{
m_ListView = adapterListView;
m_GroupHeader = new ChangesGroupHeader();
m_ListNotice = new ListNotice();
m_ListNotice.AddToClassList(UiConstants.ussHidden);
Add(m_GroupHeader);
Add(m_ListView);
Add(m_ListNotice);
}
[NotNull]
public string Title
{
set
{
m_Title = value;
UpdateTitle();
}
get => m_Title;
}
public bool Searching
{
set
{
m_Searching = value;
UpdateListNoticeText();
}
get => m_Searching;
}
public int NumberMenuItems
{
set => m_GroupHeader.SetEnableOverflowMenu(value != 0);
}
public int EntryCount
{
set
{
m_EntryCount = value;
UpdateListNotice();
}
get => m_EntryCount;
}
public int SelectedEntryCount
{
set
{
m_SelectedEntryCount = value;
UpdateTitle();
}
get => m_SelectedEntryCount;
}
void UpdateListNoticeText()
{
m_ListNotice.Text = Searching ? StringAssets.noticeNoResultsForQuery : StringAssets.noticeNoChangesToDisplay;
}
void UpdateTitle()
{
m_GroupHeader.UpdateGroupName(Searching
? StringAssets.searchResults
: string.Format(StringAssets.changeGroupHeaderFormat, Title, SelectedEntryCount));
}
void UpdateListNotice()
{
if (m_EntryCount != 0)
{
m_ListNotice.AddToClassList(UiConstants.ussHidden);
m_ListView.RemoveFromClassList(UiConstants.ussHidden);
}
else
{
m_ListNotice.RemoveFromClassList(UiConstants.ussHidden);
m_ListView.AddToClassList(UiConstants.ussHidden);
}
}
public void SetOverflowCallback(Action<float, float> callback)
{
m_GroupHeader.OnOverflowButtonClicked += callback;
}
public void ScrollTo(int idx)
{
m_ListView.ScrollToIndex(idx);
}
}
}
using System.IO;
using JetBrains.Annotations;
using Unity.Cloud.Collaborate.UserInterface;
using UnityEditor;
using UnityEngine.UIElements;
namespace Unity.Cloud.Collaborate.Components.ChangeListEntries
{
[UsedImplicitly]
internal class BaseChangeListElement : VisualElement
{
public const string UssClassName = "base-change-list-element";
public const string FileNameUssClassName = UssClassName + "__file-name";
public const string FilePathUssClassName = UssClassName + "__file-path";
public const string IconsUssClassName = UssClassName + "__icons";
public const string ButtonsUssClassName = UssClassName + "__buttons";
// Styling class names
public const string IconUssClassName = UssClassName + "__icon";
public const string ButtonUssClassName = UssClassName + "__button";
static readonly string k_LayoutPath = $"{CollaborateWindow.LayoutPath}/{nameof(BaseChangeListElement)}.uxml";
static readonly string k_StylePath = $"{CollaborateWindow.StylePath}/{nameof(BaseChangeListElement)}.uss";
protected readonly Label m_FileName;
protected readonly Label m_FilePath;
public readonly VisualElement icons;
public readonly VisualElement buttons;
public BaseChangeListElement()
{
// Get the layout
AddToClassList(UssClassName);
AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(k_LayoutPath).CloneTree(this);
styleSheets.Add(AssetDatabase.LoadAssetAtPath<StyleSheet>(k_StylePath));
// Initialise fields
m_FileName = this.Q<Label>(className: FileNameUssClassName);
m_FilePath = this.Q<Label>(className: FilePathUssClassName);
icons = this.Q<VisualElement>(className: IconsUssClassName);
buttons = this.Q<VisualElement>(className: ButtonsUssClassName);
}
public void UpdateFilePath([NotNull] string path)
{
var directoryName = Path.GetDirectoryName(path);
m_FileName.text = Path.GetFileName(path);
m_FilePath.text = directoryName;
m_FilePath.tooltip = directoryName;
}
public virtual void ClearData()
{
m_FileName.text = null;
m_FileName.tooltip = null;
m_FilePath.text = null;
m_FilePath.tooltip = null;
}
[UsedImplicitly]
public new class UxmlFactory : UxmlFactory<BaseChangeListElement> { }
}
}
using System;
using JetBrains.Annotations;
using UnityEngine.UIElements;
namespace Unity.Cloud.Collaborate.Components.ChangeListEntries
{
internal class ChangeListElement : BaseChangeListElement
{
public new const string UssClassName = "change-list-element";
public const string StatusIconUssClassName = UssClassName + "__icon";
public const string DiffButtonUssClassName = UssClassName + "__diff-button";
public const string DiscardButtonUssClassName = UssClassName + "__revert-button";
public readonly IconButton discardButton;
public readonly IconButton diffButton;
public readonly VisualElement statusIcon;
public ChangeListElement()
{
AddToClassList(UssClassName);
// Setup icons
statusIcon = new VisualElement();
statusIcon.AddToClassList(IconUssClassName);
statusIcon.AddToClassList(StatusIconUssClassName);
icons.Add(statusIcon);
// Setup buttons
diffButton = new IconButton();
diffButton.AddToClassList(IconButton.DiffUssCLassName);
diffButton.AddToClassList(ButtonUssClassName);
diffButton.AddToClassList(DiffButtonUssClassName);
discardButton = new IconButton();
discardButton.AddToClassList(IconButton.UndoUssClassName);
discardButton.AddToClassList(ButtonUssClassName);
discardButton.AddToClassList(DiscardButtonUssClassName);
buttons.Add(diffButton);
buttons.Add(discardButton);
}
public override void ClearData()
{
base.ClearData();
diffButton.UnregisterClickEvents();
discardButton.UnregisterClickEvents();
statusIcon.ClearClassList();
statusIcon.AddToClassList(IconUssClassName);
statusIcon.AddToClassList(StatusIconUssClassName);
}
[UsedImplicitly]
public new class UxmlFactory : UxmlFactory<ChangeListElement> { }
}
}
using System;
using JetBrains.Annotations;
using Unity.Cloud.Collaborate.Assets;
using UnityEngine.UIElements;
namespace Unity.Cloud.Collaborate.Components.ChangeListEntries
{
internal class ConflictedChangeListElement : BaseChangeListElement
{
public new const string UssClassName = "conflicted-change-list-element";
public const string StatusIconUssClassName = UssClassName + "__icon";
public const string ShowButtonUssClassName = UssClassName + "__show-button";
public const string ChooseMergeButtonUssClassName = UssClassName + "__choose-merge-button";
public const string ChooseRemoteButtonUssClassName = UssClassName + "__choose-remote-button";
public const string ChooseMineButtonUssClassName = UssClassName + "__choose-mine-button";
public readonly VisualElement statusIcon;
public readonly IconButton showButton;
public readonly IconButton chooseMergeButton;
public readonly IconButton chooseRemoteButton;
public readonly IconButton chooseMineButton;
public ConflictedChangeListElement()
{
AddToClassList(UssClassName);
// Setup icons
statusIcon = new VisualElement();
statusIcon.AddToClassList(IconUssClassName);
statusIcon.AddToClassList(StatusIconUssClassName);
icons.Add(statusIcon);
// Setup buttons
showButton = new IconButton();
showButton.AddToClassList(IconButton.ShowUssClassName);
showButton.AddToClassList(ButtonUssClassName);
showButton.AddToClassList(ShowButtonUssClassName);
showButton.tooltip = StringAssets.viewDiff;
chooseMergeButton = new IconButton();
chooseMergeButton.AddToClassList(IconButton.MergeUssClassName);
chooseMergeButton.AddToClassList(ButtonUssClassName);
chooseMergeButton.AddToClassList(ChooseMergeButtonUssClassName);
chooseMergeButton.tooltip = StringAssets.useMergeTool;
chooseMineButton = new IconButton();
chooseMineButton.AddToClassList(IconButton.ChooseMineUssClassName);
chooseMineButton.AddToClassList(ButtonUssClassName);
chooseMineButton.AddToClassList(ChooseMineButtonUssClassName);
chooseMineButton.tooltip = StringAssets.useMyChanges;
chooseRemoteButton = new IconButton();
chooseRemoteButton.AddToClassList(IconButton.ChooseRemoteUssClassName);
chooseRemoteButton.AddToClassList(ButtonUssClassName);
chooseRemoteButton.AddToClassList(ChooseRemoteButtonUssClassName);
chooseRemoteButton.tooltip = StringAssets.useRemoteChanges;
buttons.Add(showButton);
buttons.Add(chooseMergeButton);
buttons.Add(chooseMineButton);
buttons.Add(chooseRemoteButton);
}
public override void ClearData()
{
base.ClearData();
showButton.UnregisterClickEvents();
chooseMergeButton.UnregisterClickEvents();
chooseRemoteButton.UnregisterClickEvents();
chooseMineButton.UnregisterClickEvents();
statusIcon.ClearClassList();
statusIcon.AddToClassList(IconUssClassName);
statusIcon.AddToClassList(StatusIconUssClassName);
}
[UsedImplicitly]
public new class UxmlFactory : UxmlFactory<ConflictedChangeListElement> { }
}
}
using System;
using JetBrains.Annotations;
using UnityEngine;
using UnityEngine.UIElements;
namespace Unity.Cloud.Collaborate.Components.ChangeListEntries
{
internal class HistoryChangeListElement : BaseChangeListElement
{
public new const string UssClassName = "history-change-list-element";
public const string StatusIconUssClassName = UssClassName + "__icon";
public const string RevertButtonUssClassName = UssClassName + "__revert-button";
public readonly VisualElement statusIcon;
public readonly IconButton revertButton;
public HistoryChangeListElement()
{
AddToClassList(UssClassName);
// Setup icons
statusIcon = new VisualElement();
statusIcon.AddToClassList(IconUssClassName);
statusIcon.AddToClassList(StatusIconUssClassName);
icons.Add(statusIcon);
// Setup buttons
revertButton = new IconButton();
revertButton.AddToClassList(IconButton.UndoUssClassName);
revertButton.AddToClassList(ButtonUssClassName);
revertButton.AddToClassList(RevertButtonUssClassName);
buttons.Add(revertButton);
}
public override void ClearData()
{
base.ClearData();
revertButton.UnregisterClickEvents();
statusIcon.ClearClassList();
statusIcon.AddToClassList(IconUssClassName);
statusIcon.AddToClassList(StatusIconUssClassName);
}
[UsedImplicitly]
public new class UxmlFactory : UxmlFactory<HistoryChangeListElement> { }
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment