update libs
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 144a518ff26df1e41845217c0f0002d7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,170 @@
|
||||
using AssetStoreTools.Uploader.Data;
|
||||
using AssetStoreTools.Validator.Data;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AssetStoreTools.Uploader.UI.Elements
|
||||
{
|
||||
internal abstract class ValidationElementBase : VisualElement
|
||||
{
|
||||
// Data
|
||||
protected IWorkflow Workflow;
|
||||
|
||||
// UI
|
||||
protected VisualElement ResultsBox;
|
||||
protected Image ResultsBoxImage;
|
||||
protected Label ResultsBoxLabel;
|
||||
|
||||
protected ValidationElementBase(IWorkflow workflow)
|
||||
{
|
||||
Workflow = workflow;
|
||||
Create();
|
||||
}
|
||||
|
||||
private void Create()
|
||||
{
|
||||
CreateInfoRow();
|
||||
CreateResultsBox();
|
||||
}
|
||||
|
||||
private void CreateInfoRow()
|
||||
{
|
||||
VisualElement validatorButtonRow = new VisualElement();
|
||||
validatorButtonRow.AddToClassList("package-content-option-box");
|
||||
|
||||
VisualElement validatorLabelHelpRow = new VisualElement();
|
||||
validatorLabelHelpRow.AddToClassList("package-content-option-label-help-row");
|
||||
|
||||
Label validatorLabel = new Label { text = "Validation" };
|
||||
Image validatorLabelTooltip = new Image
|
||||
{
|
||||
tooltip = "You can use the Asset Store Validator to check your package for common publishing issues"
|
||||
};
|
||||
|
||||
var validateButton = new Button(Validate) { name = "ValidateButton", text = "Validate" };
|
||||
|
||||
validatorLabelHelpRow.Add(validatorLabel);
|
||||
validatorLabelHelpRow.Add(validatorLabelTooltip);
|
||||
|
||||
validatorButtonRow.Add(validatorLabelHelpRow);
|
||||
validatorButtonRow.Add(validateButton);
|
||||
|
||||
Add(validatorButtonRow);
|
||||
}
|
||||
|
||||
private void CreateResultsBox()
|
||||
{
|
||||
ResultsBox = new Box { name = "InfoBox" };
|
||||
ResultsBox.style.display = DisplayStyle.None;
|
||||
ResultsBox.AddToClassList("validation-result-box");
|
||||
|
||||
ResultsBoxImage = new Image();
|
||||
ResultsBoxLabel = new Label { name = "ValidationLabel" };
|
||||
|
||||
ResultsBox.Add(ResultsBoxImage);
|
||||
ResultsBox.Add(ResultsBoxLabel);
|
||||
|
||||
Add(ResultsBox);
|
||||
}
|
||||
|
||||
protected virtual bool ConfirmValidation()
|
||||
{
|
||||
// Child classes can implement pre-validation prompts
|
||||
return true;
|
||||
}
|
||||
|
||||
private void Validate()
|
||||
{
|
||||
if (!ConfirmValidation())
|
||||
return;
|
||||
|
||||
var validationResult = Workflow.Validate();
|
||||
|
||||
if (validationResult.Status == ValidationStatus.Cancelled)
|
||||
return;
|
||||
|
||||
if (validationResult.Status != ValidationStatus.RanToCompletion)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Validation failed", $"Package validation failed: {validationResult.Exception.Message}", "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
DisplayResult(validationResult);
|
||||
}
|
||||
|
||||
private void DisplayResult(ValidationResult result)
|
||||
{
|
||||
ResultsBox.style.display = DisplayStyle.Flex;
|
||||
UpdateValidationResultImage(result);
|
||||
UpdateValidationResultLabel(result);
|
||||
}
|
||||
|
||||
public void HideResult()
|
||||
{
|
||||
ResultsBox.style.display = DisplayStyle.None;
|
||||
}
|
||||
|
||||
protected void UpdateValidationResultImage(ValidationResult result)
|
||||
{
|
||||
switch (GetValidationSummaryStatus(result))
|
||||
{
|
||||
case TestResultStatus.Pass:
|
||||
ResultsBoxImage.image = EditorGUIUtility.IconContent("console.infoicon@2x").image;
|
||||
break;
|
||||
case TestResultStatus.Warning:
|
||||
ResultsBoxImage.image = EditorGUIUtility.IconContent("console.warnicon@2x").image;
|
||||
break;
|
||||
case TestResultStatus.Fail:
|
||||
ResultsBoxImage.image = EditorGUIUtility.IconContent("console.erroricon@2x").image;
|
||||
break;
|
||||
default:
|
||||
ResultsBoxImage.image = EditorGUIUtility.IconContent("_Help@2x").image;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateValidationResultLabel(ValidationResult result)
|
||||
{
|
||||
var errorCount = result.Tests.Where(x => x.Result.Status == TestResultStatus.Fail).Count();
|
||||
var warningCount = result.Tests.Where(x => x.Result.Status == TestResultStatus.Warning).Count();
|
||||
|
||||
string text = string.Empty;
|
||||
if (result.HadCompilationErrors)
|
||||
{
|
||||
text += "- Package caused compilation errors\n";
|
||||
}
|
||||
if (errorCount > 0)
|
||||
{
|
||||
text += $"- Validation reported {errorCount} error(s)\n";
|
||||
}
|
||||
if (warningCount > 0)
|
||||
{
|
||||
text += $"- Validation reported {warningCount} warning(s)\n";
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
text = "No issues were found!";
|
||||
}
|
||||
else
|
||||
{
|
||||
text = text.Substring(0, text.Length - "\n".Length);
|
||||
}
|
||||
|
||||
ResultsBoxLabel.text = text;
|
||||
}
|
||||
|
||||
private TestResultStatus GetValidationSummaryStatus(ValidationResult result)
|
||||
{
|
||||
if (result.HadCompilationErrors ||
|
||||
result.Tests.Any(x => x.Result.Status == TestResultStatus.Fail))
|
||||
return TestResultStatus.Fail;
|
||||
|
||||
if (result.Tests.Any(x => x.Result.Status == TestResultStatus.Warning))
|
||||
return TestResultStatus.Warning;
|
||||
|
||||
return TestResultStatus.Pass;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cb20404763eac7144b562c18ad1c37fe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/UI/Elements/Abstractions/ValidationElementBase.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,151 @@
|
||||
using AssetStoreTools.Uploader.Data;
|
||||
using AssetStoreTools.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AssetStoreTools.Uploader.UI.Elements
|
||||
{
|
||||
internal abstract class WorkflowElementBase : VisualElement
|
||||
{
|
||||
// Data
|
||||
protected IWorkflow Workflow;
|
||||
public string Name => Workflow.Name;
|
||||
public string DisplayName => Workflow.DisplayName;
|
||||
|
||||
// UI Elements that all workflows have
|
||||
protected PathSelectionElement PathSelectionElement;
|
||||
protected PreviewGenerationElement PreviewGenerationElement;
|
||||
protected ValidationElementBase ValidationElement;
|
||||
protected PackageUploadElement UploadElement;
|
||||
|
||||
public event Action OnInteractionAvailable;
|
||||
public event Action OnInteractionUnavailable;
|
||||
|
||||
public WorkflowElementBase(IWorkflow workflow)
|
||||
{
|
||||
Workflow = workflow;
|
||||
}
|
||||
|
||||
protected void CreatePathElement(string labelText, string labelTooltip)
|
||||
{
|
||||
PathSelectionElement = new PathSelectionElement(labelText, labelTooltip);
|
||||
PathSelectionElement.OnBrowse += BrowsePath;
|
||||
Add(PathSelectionElement);
|
||||
}
|
||||
|
||||
protected void CreatePreviewGenerationElement()
|
||||
{
|
||||
PreviewGenerationElement = new PreviewGenerationElement(Workflow);
|
||||
PreviewGenerationElement.style.display = DisplayStyle.None;
|
||||
var callback = new Action(() =>
|
||||
PreviewGenerationElement.style.display = ASToolsPreferences.Instance.UseLegacyExporting
|
||||
? DisplayStyle.None
|
||||
: DisplayStyle.Flex);
|
||||
RegisterCallback<AttachToPanelEvent>((_) => { ASToolsPreferences.OnSettingsChange += callback; });
|
||||
RegisterCallback<DetachFromPanelEvent>((_) => { ASToolsPreferences.OnSettingsChange -= callback; });
|
||||
Add(PreviewGenerationElement);
|
||||
}
|
||||
|
||||
protected void CreateValidationElement(ValidationElementBase validationElement)
|
||||
{
|
||||
ValidationElement = validationElement;
|
||||
ValidationElement.style.display = DisplayStyle.None;
|
||||
Add(ValidationElement);
|
||||
}
|
||||
|
||||
protected void CreateUploadElement(IWorkflow workflow, bool exposeExportButton)
|
||||
{
|
||||
UploadElement = new PackageUploadElement(workflow, exposeExportButton);
|
||||
UploadElement.OnInteractionAvailable += EnableInteraction;
|
||||
UploadElement.OnInteractionUnavailable += DisableInteraction;
|
||||
UploadElement.style.display = DisplayStyle.None;
|
||||
Add(UploadElement);
|
||||
}
|
||||
|
||||
protected abstract void BrowsePath();
|
||||
|
||||
protected void SetPathSelectionTextField(string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return;
|
||||
|
||||
PathSelectionElement.SetPath(value);
|
||||
ValidationElement.style.display = DisplayStyle.Flex;
|
||||
UploadElement.style.display = DisplayStyle.Flex;
|
||||
|
||||
if (PreviewGenerationElement != null && !ASToolsPreferences.Instance.UseLegacyExporting)
|
||||
{
|
||||
PreviewGenerationElement.style.display = DisplayStyle.Flex;
|
||||
}
|
||||
}
|
||||
|
||||
protected void CheckForMissingMetas(IEnumerable<string> paths)
|
||||
{
|
||||
bool displayDialog = ASToolsPreferences.Instance.DisplayHiddenMetaDialog && FileUtility.IsMissingMetaFiles(paths);
|
||||
if (!displayDialog)
|
||||
return;
|
||||
|
||||
var selectedOption = EditorUtility.DisplayDialogComplex(
|
||||
"Notice",
|
||||
"Your package includes hidden folders which do not contain meta files. " +
|
||||
"Hidden folders will not be exported unless they contain meta files.\n\nWould you like meta files to be generated?",
|
||||
"Yes", "No", "No and do not display this again");
|
||||
|
||||
switch (selectedOption)
|
||||
{
|
||||
case 0:
|
||||
try
|
||||
{
|
||||
FileUtility.GenerateMetaFiles(paths);
|
||||
EditorUtility.DisplayDialog(
|
||||
"Success",
|
||||
"Meta files have been generated. Please note that further manual tweaking may be required to set up correct references",
|
||||
"OK");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
EditorUtility.DisplayDialog(
|
||||
"Error",
|
||||
$"Meta file generation failed: {e.Message}",
|
||||
"OK"
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// Do nothing
|
||||
return;
|
||||
case 2:
|
||||
ASToolsPreferences.Instance.DisplayHiddenMetaDialog = false;
|
||||
ASToolsPreferences.Instance.Save();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Is(IWorkflow workflow)
|
||||
{
|
||||
return Workflow == workflow;
|
||||
}
|
||||
|
||||
protected virtual void EnableInteraction()
|
||||
{
|
||||
PathSelectionElement.SetEnabled(true);
|
||||
ValidationElement.SetEnabled(true);
|
||||
PreviewGenerationElement?.SetEnabled(true);
|
||||
UploadElement.SetEnabled(true);
|
||||
OnInteractionAvailable?.Invoke();
|
||||
}
|
||||
|
||||
protected virtual void DisableInteraction()
|
||||
{
|
||||
PathSelectionElement.SetEnabled(false);
|
||||
ValidationElement.SetEnabled(false);
|
||||
PreviewGenerationElement?.SetEnabled(false);
|
||||
UploadElement.SetEnabled(false);
|
||||
OnInteractionUnavailable?.Invoke();
|
||||
}
|
||||
|
||||
protected abstract void Deserialize();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 45d1bf267c3ea9048bfdd75d0d19c8bd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/UI/Elements/Abstractions/WorkflowElementBase.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,102 @@
|
||||
using AssetStoreTools.Api.Models;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AssetStoreTools.Uploader.UI.Elements
|
||||
{
|
||||
internal class AccountToolbar : VisualElement
|
||||
{
|
||||
private Image _accountImage;
|
||||
private Label _accountEmailLabel;
|
||||
private Button _refreshButton;
|
||||
|
||||
public event Func<Task> OnRefresh;
|
||||
public event Action OnLogout;
|
||||
|
||||
public AccountToolbar()
|
||||
{
|
||||
Create();
|
||||
}
|
||||
|
||||
private void Create()
|
||||
{
|
||||
AddToClassList("account-toolbar");
|
||||
|
||||
// Left side of the toolbar
|
||||
VisualElement leftSideContainer = new VisualElement { name = "LeftSideContainer" };
|
||||
leftSideContainer.AddToClassList("account-toolbar-left-side-container");
|
||||
|
||||
_accountImage = new Image();
|
||||
_accountImage.AddToClassList("account-toolbar-user-image");
|
||||
|
||||
_accountEmailLabel = new Label() { name = "AccountEmail" };
|
||||
_accountEmailLabel.AddToClassList("account-toolbar-email-label");
|
||||
|
||||
leftSideContainer.Add(_accountImage);
|
||||
leftSideContainer.Add(_accountEmailLabel);
|
||||
|
||||
// Right side of the toolbar
|
||||
VisualElement rightSideContainer = new VisualElement { name = "RightSideContainer" };
|
||||
rightSideContainer.AddToClassList("account-toolbar-right-side-container");
|
||||
|
||||
// Refresh button
|
||||
_refreshButton = new Button(Refresh) { name = "RefreshButton", text = "Refresh" };
|
||||
_refreshButton.AddToClassList("account-toolbar-button-refresh");
|
||||
|
||||
// Logout button
|
||||
var logoutButton = new Button(Logout) { name = "LogoutButton", text = "Log out" };
|
||||
logoutButton.AddToClassList("account-toolbar-button-logout");
|
||||
|
||||
rightSideContainer.Add(_refreshButton);
|
||||
rightSideContainer.Add(logoutButton);
|
||||
|
||||
// Constructing the final toolbar
|
||||
Add(leftSideContainer);
|
||||
Add(rightSideContainer);
|
||||
}
|
||||
|
||||
private async void Refresh()
|
||||
{
|
||||
_refreshButton.SetEnabled(false);
|
||||
await OnRefresh?.Invoke();
|
||||
_refreshButton.SetEnabled(true);
|
||||
}
|
||||
|
||||
private void Logout()
|
||||
{
|
||||
OnLogout?.Invoke();
|
||||
}
|
||||
|
||||
public void SetUser(User user)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
_accountEmailLabel.text = string.Empty;
|
||||
_accountImage.tooltip = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
var userEmail = !string.IsNullOrEmpty(user.Username) ? user.Username : "Unknown";
|
||||
var publisherName = !string.IsNullOrEmpty(user.Name) ? user.Name : "Unknown";
|
||||
var publisherId = !string.IsNullOrEmpty(user.PublisherId) ? user.PublisherId : "Unknown";
|
||||
var userInfo =
|
||||
$"Username: {userEmail}\n" +
|
||||
$"Publisher Name: {publisherName}\n" +
|
||||
$"Publisher ID: {publisherId}";
|
||||
|
||||
_accountEmailLabel.text = userEmail;
|
||||
_accountImage.tooltip = userInfo;
|
||||
}
|
||||
|
||||
public void EnableButtons()
|
||||
{
|
||||
_refreshButton.SetEnabled(true);
|
||||
}
|
||||
|
||||
public void DisableButtons()
|
||||
{
|
||||
_refreshButton.SetEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c275be3817d1684ca1802c2738ac4d9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/UI/Elements/AccountToolbar.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,215 @@
|
||||
using AssetStoreTools.Uploader.Data;
|
||||
using AssetStoreTools.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AssetStoreTools.Uploader.UI.Elements
|
||||
{
|
||||
internal class AssetsWorkflowElement : WorkflowElementBase
|
||||
{
|
||||
// Data
|
||||
private AssetsWorkflow _workflow;
|
||||
|
||||
// UI
|
||||
private VisualElement _dependenciesToggleElement;
|
||||
private Toggle _dependenciesToggle;
|
||||
private MultiToggleSelectionElement _dependenciesElement;
|
||||
private MultiToggleSelectionElement _specialFoldersElement;
|
||||
|
||||
private const string PathSelectionTooltip = "Select the main folder of your package" +
|
||||
"\n\nAll files and folders of your package should preferably be contained within a single root folder that is named after your package" +
|
||||
"\n\nExample: 'Assets/[MyPackageName]'" +
|
||||
"\n\nNote: If your content makes use of special folders that are required to be placed in the root Assets folder (e.g. 'StreamingAssets')," +
|
||||
" you will be able to include them after selecting the main folder";
|
||||
|
||||
public AssetsWorkflowElement(AssetsWorkflow workflow) : base(workflow)
|
||||
{
|
||||
_workflow = workflow;
|
||||
|
||||
Create();
|
||||
Deserialize();
|
||||
}
|
||||
|
||||
private void Create()
|
||||
{
|
||||
CreatePathElement("Folder path", PathSelectionTooltip);
|
||||
CreateDependenciesToggleElement();
|
||||
CreateDependenciesSelectionElement();
|
||||
CreateSpecialFoldersElement();
|
||||
CreatePreviewGenerationElement();
|
||||
CreateValidationElement(new CurrentProjectValidationElement(_workflow));
|
||||
CreateUploadElement(_workflow, true);
|
||||
}
|
||||
|
||||
private void CreateDependenciesToggleElement()
|
||||
{
|
||||
_dependenciesToggleElement = new VisualElement() { name = "Dependencies Toggle" };
|
||||
_dependenciesToggleElement.AddToClassList("package-content-option-box");
|
||||
|
||||
VisualElement dependenciesLabelHelpRow = new VisualElement();
|
||||
dependenciesLabelHelpRow.AddToClassList("package-content-option-label-help-row");
|
||||
|
||||
Label dependenciesLabel = new Label { text = "Dependencies" };
|
||||
Image dependenciesLabelTooltip = new Image
|
||||
{
|
||||
tooltip = "Tick this checkbox if your package content has dependencies on Unity packages from the Package Manager"
|
||||
};
|
||||
|
||||
_dependenciesToggle = new Toggle { name = "DependenciesToggle", text = "Include Package Manifest" };
|
||||
_dependenciesToggle.AddToClassList("package-content-option-toggle");
|
||||
|
||||
var callback = new Action(() => DependencyToggleValueChange(true));
|
||||
_dependenciesToggle.RegisterValueChangedCallback((_) => DependencyToggleValueChange(true));
|
||||
RegisterCallback<AttachToPanelEvent>((_) => { ASToolsPreferences.OnSettingsChange += callback; });
|
||||
RegisterCallback<DetachFromPanelEvent>((_) => { ASToolsPreferences.OnSettingsChange -= callback; });
|
||||
|
||||
dependenciesLabelHelpRow.Add(dependenciesLabel);
|
||||
dependenciesLabelHelpRow.Add(dependenciesLabelTooltip);
|
||||
|
||||
_dependenciesToggleElement.Add(dependenciesLabelHelpRow);
|
||||
_dependenciesToggleElement.Add(_dependenciesToggle);
|
||||
|
||||
_dependenciesToggleElement.style.display = DisplayStyle.None;
|
||||
Add(_dependenciesToggleElement);
|
||||
}
|
||||
|
||||
private void CreateDependenciesSelectionElement()
|
||||
{
|
||||
_dependenciesElement = new MultiToggleSelectionElement()
|
||||
{
|
||||
DisplayElementLabel = false,
|
||||
ElementLabel = "Dependencies",
|
||||
NoSelectionLabel = "No packages match this criteria"
|
||||
};
|
||||
|
||||
var setDependencies = new Action<Dictionary<string, bool>>((dict) => _workflow.SetDependencies(dict.Where(x => x.Value).Select(x => x.Key), true));
|
||||
_dependenciesElement.OnValuesChanged += setDependencies;
|
||||
_dependenciesElement.style.display = DisplayStyle.None;
|
||||
Add(_dependenciesElement);
|
||||
}
|
||||
|
||||
private void CreateSpecialFoldersElement()
|
||||
{
|
||||
_specialFoldersElement = new MultiToggleSelectionElement()
|
||||
{
|
||||
ElementLabel = "Special Folders",
|
||||
ElementTooltip = "If your package content relies on Special Folders (e.g. StreamingAssets), please select which of these folders should be included in the package.",
|
||||
NoSelectionLabel = "No folders match this criteria."
|
||||
};
|
||||
|
||||
var setSpecialFolders = new Action<Dictionary<string, bool>>((dict) => _workflow.SetSpecialFolders(dict.Where(x => x.Value).Select(x => x.Key), true));
|
||||
_specialFoldersElement.OnValuesChanged += setSpecialFolders;
|
||||
_specialFoldersElement.style.display = DisplayStyle.None;
|
||||
Add(_specialFoldersElement);
|
||||
}
|
||||
|
||||
protected override void BrowsePath()
|
||||
{
|
||||
string absoluteExportPath = string.Empty;
|
||||
bool includeAllAssets = false;
|
||||
|
||||
if (_workflow.IsCompleteProject)
|
||||
{
|
||||
includeAllAssets = EditorUtility.DisplayDialog("Notice",
|
||||
"Your package draft is set to a category that is treated" +
|
||||
" as a complete project. Project settings will be included automatically. Would you like everything in the " +
|
||||
"'Assets' folder to be included?\n\nYou will still be able to change the selected assets before uploading",
|
||||
"Yes, include all folders and assets",
|
||||
"No, I'll select what to include manually");
|
||||
|
||||
if (includeAllAssets)
|
||||
absoluteExportPath = Application.dataPath;
|
||||
}
|
||||
|
||||
if (!includeAllAssets)
|
||||
{
|
||||
absoluteExportPath = EditorUtility.OpenFolderPanel(
|
||||
"Select folder to compress into a package", "Assets/", "");
|
||||
|
||||
if (string.IsNullOrEmpty(absoluteExportPath))
|
||||
return;
|
||||
}
|
||||
|
||||
var relativeExportPath = FileUtility.AbsolutePathToRelativePath(absoluteExportPath, ASToolsPreferences.Instance.EnableSymlinkSupport);
|
||||
if (!_workflow.IsPathValid(relativeExportPath, out var error))
|
||||
{
|
||||
EditorUtility.DisplayDialog("Invalid selection", error, "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
HandlePathSelection(relativeExportPath, true);
|
||||
CheckForMissingMetas();
|
||||
}
|
||||
|
||||
private void HandlePathSelection(string relativeExportPath, bool serialize)
|
||||
{
|
||||
if (string.IsNullOrEmpty(relativeExportPath))
|
||||
return;
|
||||
|
||||
_workflow.SetMainExportPath(relativeExportPath, serialize);
|
||||
SetPathSelectionTextField(relativeExportPath + "/");
|
||||
|
||||
_dependenciesToggleElement.style.display = DisplayStyle.Flex;
|
||||
UpdateSpecialFoldersElement();
|
||||
}
|
||||
|
||||
private void CheckForMissingMetas()
|
||||
{
|
||||
var paths = new List<string>() { _workflow.GetMainExportPath() };
|
||||
paths.AddRange(_workflow.GetSpecialFolders());
|
||||
CheckForMissingMetas(paths);
|
||||
}
|
||||
|
||||
private void DependencyToggleValueChange(bool serialize)
|
||||
{
|
||||
_workflow.SetIncludeDependencies(_dependenciesToggle.value, serialize);
|
||||
|
||||
if (_dependenciesToggle.value && !ASToolsPreferences.Instance.UseLegacyExporting)
|
||||
{
|
||||
var allDependencies = _workflow.GetAvailableDependencies();
|
||||
var selectedDependencies = allDependencies.ToDictionary(x => x, y => _workflow.GetDependencies().Any(x => x.name == y));
|
||||
_dependenciesElement.Populate(selectedDependencies);
|
||||
_dependenciesElement.style.display = DisplayStyle.Flex;
|
||||
}
|
||||
else
|
||||
{
|
||||
_dependenciesElement.style.display = DisplayStyle.None;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSpecialFoldersElement()
|
||||
{
|
||||
var availableSpecialFolders = _workflow.GetAvailableSpecialFolders();
|
||||
var selectedSpecialFolders = availableSpecialFolders.ToDictionary(x => x, y => _workflow.GetSpecialFolders().Any(x => x == y));
|
||||
_specialFoldersElement.Populate(selectedSpecialFolders);
|
||||
_specialFoldersElement.style.display = availableSpecialFolders.Count > 0 ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
}
|
||||
|
||||
protected override void EnableInteraction()
|
||||
{
|
||||
base.EnableInteraction();
|
||||
_dependenciesToggleElement.SetEnabled(true);
|
||||
_dependenciesElement.SetEnabled(true);
|
||||
_specialFoldersElement.SetEnabled(true);
|
||||
}
|
||||
|
||||
protected override void DisableInteraction()
|
||||
{
|
||||
base.DisableInteraction();
|
||||
_dependenciesToggleElement.SetEnabled(false);
|
||||
_dependenciesElement.SetEnabled(false);
|
||||
_specialFoldersElement.SetEnabled(false);
|
||||
}
|
||||
|
||||
protected override void Deserialize()
|
||||
{
|
||||
HandlePathSelection(_workflow.GetMainExportPath(), false);
|
||||
_dependenciesToggle.SetValueWithoutNotify(_workflow.GetIncludeDependencies());
|
||||
DependencyToggleValueChange(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f62ea8ab5c102e4fa574a3dcac7f6fb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/UI/Elements/AssetsWorkflowElement.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,31 @@
|
||||
using AssetStoreTools.Uploader.Data;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AssetStoreTools.Uploader.UI.Elements
|
||||
{
|
||||
internal class CurrentProjectValidationElement : ValidationElementBase
|
||||
{
|
||||
public CurrentProjectValidationElement(IWorkflow workflow) : base(workflow)
|
||||
{
|
||||
Create();
|
||||
}
|
||||
|
||||
private void Create()
|
||||
{
|
||||
CreateResultsBox();
|
||||
}
|
||||
|
||||
private void CreateResultsBox()
|
||||
{
|
||||
var _viewReportButton = new Button(ViewReport) { text = "View report" };
|
||||
_viewReportButton.AddToClassList("validation-result-view-report-button");
|
||||
|
||||
ResultsBox.Add(_viewReportButton);
|
||||
}
|
||||
|
||||
private void ViewReport()
|
||||
{
|
||||
AssetStoreTools.ShowAssetStoreToolsValidator(Workflow.LastValidationSettings, Workflow.LastValidationResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 21a1f13231b167b4c80079a2c1212101
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/UI/Elements/CurrentProjectValidationElement.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,92 @@
|
||||
using AssetStoreTools.Uploader.Data;
|
||||
using AssetStoreTools.Utility;
|
||||
using AssetStoreTools.Validator;
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AssetStoreTools.Uploader.UI.Elements
|
||||
{
|
||||
internal class ExternalProjectValidationElement : ValidationElementBase
|
||||
{
|
||||
private VisualElement _projectButtonContainer;
|
||||
|
||||
public ExternalProjectValidationElement(IWorkflow workflow) : base(workflow)
|
||||
{
|
||||
Create();
|
||||
}
|
||||
|
||||
private void Create()
|
||||
{
|
||||
CreateProjectButtonContainer();
|
||||
CreateProjectButtons();
|
||||
}
|
||||
|
||||
private void CreateProjectButtonContainer()
|
||||
{
|
||||
_projectButtonContainer = new VisualElement();
|
||||
_projectButtonContainer.AddToClassList("validation-result-view-report-button-container");
|
||||
|
||||
ResultsBox.Add(_projectButtonContainer);
|
||||
}
|
||||
|
||||
private void CreateProjectButtons()
|
||||
{
|
||||
var openButton = new Button(OpenProject) { text = "Open Project" };
|
||||
openButton.AddToClassList("validation-result-view-report-button");
|
||||
|
||||
var saveButton = new Button(SaveProject) { text = "Save Project" };
|
||||
saveButton.AddToClassList("validation-result-view-report-button");
|
||||
|
||||
_projectButtonContainer.Add(openButton);
|
||||
_projectButtonContainer.Add(saveButton);
|
||||
}
|
||||
|
||||
private void OpenProject()
|
||||
{
|
||||
try
|
||||
{
|
||||
EditorUtility.DisplayProgressBar("Waiting...", "Validation project is open. Waiting for it to exit...", 0.4f);
|
||||
var projectPath = Workflow.LastValidationResult.ProjectPath;
|
||||
ExternalProjectValidator.OpenExternalValidationProject(projectPath);
|
||||
}
|
||||
finally
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveProject()
|
||||
{
|
||||
try
|
||||
{
|
||||
var projectPath = Workflow.LastValidationResult.ProjectPath;
|
||||
var savePath = EditorUtility.SaveFolderPanel("Select a folder", Environment.GetFolderPath(Environment.SpecialFolder.Desktop), string.Empty);
|
||||
if (string.IsNullOrEmpty(savePath))
|
||||
return;
|
||||
|
||||
var saveDir = new DirectoryInfo(savePath);
|
||||
if (!saveDir.Exists || saveDir.GetFileSystemInfos().Length != 0)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Saving project failed", "Selected directory must be an empty folder", "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
EditorUtility.DisplayProgressBar("Saving...", "Saving project...", 0.4f);
|
||||
FileUtility.CopyDirectory(projectPath, savePath, true);
|
||||
}
|
||||
finally
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool ConfirmValidation()
|
||||
{
|
||||
return EditorUtility.DisplayDialog("Notice", "Pre-exported package validation is performed in a separate temporary project. " +
|
||||
"It may take some time for the temporary project to be created, which will halt any actions in the current project. " +
|
||||
"The current project will resume work after the temporary project is exited.\n\nDo you wish to proceed?", "Yes", "No");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 706f01d53c7eaf04bae07fb36684e31b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/UI/Elements/ExternalProjectValidationElement.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,116 @@
|
||||
using AssetStoreTools.Uploader.Data;
|
||||
using AssetStoreTools.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AssetStoreTools.Uploader.UI.Elements
|
||||
{
|
||||
internal class HybridPackageWorkflowElement : WorkflowElementBase
|
||||
{
|
||||
// Data
|
||||
private HybridPackageWorkflow _workflow;
|
||||
|
||||
// UI
|
||||
private MultiToggleSelectionElement _dependenciesElement;
|
||||
|
||||
public HybridPackageWorkflowElement(HybridPackageWorkflow workflow) : base(workflow)
|
||||
{
|
||||
_workflow = workflow;
|
||||
|
||||
Create();
|
||||
Deserialize();
|
||||
}
|
||||
|
||||
private void Create()
|
||||
{
|
||||
CreatePathElement("Package path", "Select a local Package you would like to export and upload to the Store.");
|
||||
CreateDependenciesElement();
|
||||
CreatePreviewGenerationElement();
|
||||
CreateValidationElement(new CurrentProjectValidationElement(_workflow));
|
||||
CreateUploadElement(_workflow, true);
|
||||
}
|
||||
|
||||
private void CreateDependenciesElement()
|
||||
{
|
||||
_dependenciesElement = new MultiToggleSelectionElement()
|
||||
{
|
||||
ElementLabel = "Dependencies",
|
||||
ElementTooltip = "Select which local package dependencies should be included when exporting." +
|
||||
"\n\nNote that only local or embedded dependencies defined in the package.json can be selected.",
|
||||
NoSelectionLabel = "No packages match this criteria"
|
||||
};
|
||||
|
||||
var setDependencies = new Action<Dictionary<string, bool>>((dict) => _workflow.SetDependencies(dict.Where(x => x.Value).Select(x => x.Key), true));
|
||||
_dependenciesElement.OnValuesChanged += setDependencies;
|
||||
Add(_dependenciesElement);
|
||||
_dependenciesElement.style.display = DisplayStyle.None;
|
||||
}
|
||||
|
||||
protected override void BrowsePath()
|
||||
{
|
||||
var absoluteExportPath = EditorUtility.OpenFilePanel("Select a package.json file", "Packages/", "json");
|
||||
if (string.IsNullOrEmpty(absoluteExportPath))
|
||||
return;
|
||||
|
||||
if (!_workflow.IsPathValid(absoluteExportPath, out var error))
|
||||
{
|
||||
EditorUtility.DisplayDialog("Invalid selection", error, "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
HandlePathSelection(absoluteExportPath, true);
|
||||
CheckForMissingMetas();
|
||||
}
|
||||
|
||||
private void HandlePathSelection(string packageManifestPath, bool serialize)
|
||||
{
|
||||
if (string.IsNullOrEmpty(packageManifestPath))
|
||||
return;
|
||||
|
||||
_workflow.SetPackage(packageManifestPath, serialize);
|
||||
var packageFolderPath = _workflow.GetPackage().assetPath;
|
||||
SetPathSelectionTextField(packageFolderPath + "/");
|
||||
|
||||
UpdateDependenciesElement();
|
||||
}
|
||||
|
||||
private void CheckForMissingMetas()
|
||||
{
|
||||
var paths = new List<string>() { _workflow.GetPackage().assetPath };
|
||||
paths.AddRange(_workflow.GetDependencies().Select(x => x.assetPath));
|
||||
CheckForMissingMetas(paths);
|
||||
}
|
||||
|
||||
private void UpdateDependenciesElement()
|
||||
{
|
||||
var availableDependencies = _workflow.GetAvailableDependencies();
|
||||
var selectedDependencies = availableDependencies.ToDictionary(x => x.name, y => _workflow.GetDependencies().Any(x => x.name == y.name));
|
||||
_dependenciesElement.Populate(selectedDependencies);
|
||||
_dependenciesElement.style.display = availableDependencies.Count > 0 ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
}
|
||||
|
||||
protected override void EnableInteraction()
|
||||
{
|
||||
base.EnableInteraction();
|
||||
_dependenciesElement.SetEnabled(true);
|
||||
}
|
||||
|
||||
protected override void DisableInteraction()
|
||||
{
|
||||
base.DisableInteraction();
|
||||
_dependenciesElement.SetEnabled(false);
|
||||
}
|
||||
|
||||
protected override void Deserialize()
|
||||
{
|
||||
var package = _workflow.GetPackage();
|
||||
if (package == null)
|
||||
return;
|
||||
|
||||
HandlePathSelection(AssetDatabase.GetAssetPath(package.GetManifestAsset()), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 34cd1e5cbe87bb546937a521bd2bc69c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/UI/Elements/HybridPackageWorkflowElement.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,52 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AssetStoreTools.Uploader.UI.Elements
|
||||
{
|
||||
internal class LoadingSpinner : VisualElement
|
||||
{
|
||||
// Data
|
||||
private int _spinIndex;
|
||||
private double _spinTimer;
|
||||
private double _spinThreshold = 0.1;
|
||||
|
||||
// UI
|
||||
private Image _spinnerImage;
|
||||
|
||||
public LoadingSpinner()
|
||||
{
|
||||
AddToClassList("loading-spinner-box");
|
||||
|
||||
_spinnerImage = new Image { name = "SpinnerImage" };
|
||||
_spinnerImage.AddToClassList("loading-spinner-image");
|
||||
|
||||
Add(_spinnerImage);
|
||||
}
|
||||
|
||||
public void Show()
|
||||
{
|
||||
EditorApplication.update += SpinnerLoop;
|
||||
style.display = DisplayStyle.Flex;
|
||||
}
|
||||
|
||||
public void Hide()
|
||||
{
|
||||
EditorApplication.update -= SpinnerLoop;
|
||||
style.display = DisplayStyle.None;
|
||||
}
|
||||
|
||||
private void SpinnerLoop()
|
||||
{
|
||||
if (_spinTimer + _spinThreshold > EditorApplication.timeSinceStartup)
|
||||
return;
|
||||
|
||||
_spinTimer = EditorApplication.timeSinceStartup;
|
||||
_spinnerImage.image = EditorGUIUtility.IconContent($"WaitSpin{_spinIndex:00}").image;
|
||||
|
||||
_spinIndex += 1;
|
||||
|
||||
if (_spinIndex > 11)
|
||||
_spinIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c7cdef91eb9a894091869ca10d9d178
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/UI/Elements/LoadingSpinner.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,187 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AssetStoreTools.Uploader.UI.Elements
|
||||
{
|
||||
internal class MultiToggleSelectionElement : VisualElement
|
||||
{
|
||||
// Data
|
||||
private Dictionary<string, bool> _selections;
|
||||
private readonly List<string> _selectionFilters = new List<string> { "All", "Selected", "Not Selected" };
|
||||
private string _activeFilter;
|
||||
|
||||
public bool DisplayElementLabel
|
||||
{
|
||||
get => _multiToggleSelectionHelpRow.style.visibility == Visibility.Visible;
|
||||
set { _multiToggleSelectionHelpRow.style.visibility = value ? Visibility.Visible : Visibility.Hidden; }
|
||||
}
|
||||
|
||||
public string ElementLabel { get => _multiToggleSelectionLabel.text; set { _multiToggleSelectionLabel.text = value; } }
|
||||
public string ElementTooltip { get => _multiToggleSelectionTooltip.tooltip; set { _multiToggleSelectionTooltip.tooltip = value; } }
|
||||
public string NoSelectionLabel { get => _noSelectionsLabel.text; set { _noSelectionsLabel.text = value; } }
|
||||
|
||||
// UI
|
||||
private VisualElement _multiToggleSelectionHelpRow;
|
||||
private Label _multiToggleSelectionLabel;
|
||||
private Image _multiToggleSelectionTooltip;
|
||||
|
||||
private ScrollView _selectionTogglesBox;
|
||||
private Label _noSelectionsLabel;
|
||||
private ToolbarMenu _filteringDropdown;
|
||||
|
||||
public event Action<Dictionary<string, bool>> OnValuesChanged;
|
||||
|
||||
public MultiToggleSelectionElement()
|
||||
{
|
||||
_activeFilter = _selectionFilters[0];
|
||||
AddToClassList("package-content-option-box");
|
||||
Create();
|
||||
}
|
||||
|
||||
private void Create()
|
||||
{
|
||||
_multiToggleSelectionHelpRow = new VisualElement();
|
||||
_multiToggleSelectionHelpRow.AddToClassList("package-content-option-label-help-row");
|
||||
|
||||
_multiToggleSelectionLabel = new Label();
|
||||
_multiToggleSelectionTooltip = new Image();
|
||||
|
||||
VisualElement fullSelectionBox = new VisualElement();
|
||||
fullSelectionBox.AddToClassList("multi-toggle-box");
|
||||
|
||||
_selectionTogglesBox = new ScrollView { name = "DependencyToggles" };
|
||||
_selectionTogglesBox.AddToClassList("multi-toggle-box-scrollview");
|
||||
|
||||
_noSelectionsLabel = new Label();
|
||||
_noSelectionsLabel.AddToClassList("multi-toggle-box-empty-label");
|
||||
|
||||
var scrollContainer = _selectionTogglesBox.Q<VisualElement>("unity-content-viewport");
|
||||
scrollContainer.Add(_noSelectionsLabel);
|
||||
|
||||
VisualElement filteringBox = new VisualElement();
|
||||
filteringBox.AddToClassList("multi-toggle-box-toolbar");
|
||||
|
||||
// Select - deselect buttons
|
||||
VisualElement selectingBox = new VisualElement();
|
||||
selectingBox.AddToClassList("multi-toggle-box-toolbar-selecting-box");
|
||||
|
||||
Button selectAllButton = new Button(SelectAllToggles)
|
||||
{
|
||||
text = "Select All"
|
||||
};
|
||||
|
||||
Button deSelectAllButton = new Button(UnselectAllToggles)
|
||||
{
|
||||
text = "Deselect All"
|
||||
};
|
||||
|
||||
selectingBox.Add(selectAllButton);
|
||||
selectingBox.Add(deSelectAllButton);
|
||||
|
||||
// Filtering dropdown
|
||||
VisualElement filteringDropdownBox = new VisualElement();
|
||||
filteringDropdownBox.AddToClassList("multi-toggle-box-toolbar-filtering-box");
|
||||
|
||||
_filteringDropdown = new ToolbarMenu { text = _selectionFilters[0] };
|
||||
|
||||
foreach (var filter in _selectionFilters)
|
||||
_filteringDropdown.menu.AppendAction(filter, (_) => { FilterDependencies(filter); });
|
||||
|
||||
filteringDropdownBox.Add(_filteringDropdown);
|
||||
|
||||
// Final adding
|
||||
filteringBox.Add(filteringDropdownBox);
|
||||
filteringBox.Add(selectingBox);
|
||||
|
||||
fullSelectionBox.Add(_selectionTogglesBox);
|
||||
fullSelectionBox.Add(filteringBox);
|
||||
|
||||
_multiToggleSelectionHelpRow.Add(_multiToggleSelectionLabel);
|
||||
_multiToggleSelectionHelpRow.Add(_multiToggleSelectionTooltip);
|
||||
|
||||
Add(_multiToggleSelectionHelpRow);
|
||||
Add(fullSelectionBox);
|
||||
}
|
||||
|
||||
public void Populate(Dictionary<string, bool> selections)
|
||||
{
|
||||
_selectionTogglesBox.Clear();
|
||||
_selections = selections;
|
||||
|
||||
EventCallback<ChangeEvent<bool>, string> callback = OnToggle;
|
||||
|
||||
foreach (var kvp in selections)
|
||||
{
|
||||
var toggle = new Toggle() { text = kvp.Key, value = kvp.Value };
|
||||
toggle.AddToClassList("multi-toggle-box-toggle");
|
||||
toggle.RegisterCallback(callback, toggle.text);
|
||||
_selectionTogglesBox.Add(toggle);
|
||||
}
|
||||
|
||||
FilterDependencies(_activeFilter);
|
||||
}
|
||||
|
||||
private void FilterDependencies(string filter)
|
||||
{
|
||||
_activeFilter = filter;
|
||||
|
||||
var allToggles = _selectionTogglesBox.Children().Cast<Toggle>().ToArray();
|
||||
var selectedIndex = _selectionFilters.FindIndex(x => x == filter);
|
||||
|
||||
switch (selectedIndex)
|
||||
{
|
||||
case 0:
|
||||
foreach (var toggle in allToggles)
|
||||
toggle.style.display = DisplayStyle.Flex;
|
||||
break;
|
||||
case 1:
|
||||
foreach (var toggle in allToggles)
|
||||
toggle.style.display = toggle.value ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
break;
|
||||
case 2:
|
||||
foreach (var toggle in allToggles)
|
||||
toggle.style.display = toggle.value ? DisplayStyle.None : DisplayStyle.Flex;
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if any toggles are displayed
|
||||
var count = allToggles.Count(toggle => toggle.style.display == DisplayStyle.Flex);
|
||||
_noSelectionsLabel.style.display = count > 0 ? DisplayStyle.None : DisplayStyle.Flex;
|
||||
|
||||
_filteringDropdown.text = filter;
|
||||
}
|
||||
|
||||
private void OnToggle(ChangeEvent<bool> evt, string text)
|
||||
{
|
||||
FilterDependencies(_activeFilter);
|
||||
_selections[text] = evt.newValue;
|
||||
OnValuesChanged?.Invoke(_selections);
|
||||
}
|
||||
|
||||
private void OnAllToggles(bool value)
|
||||
{
|
||||
var allToggles = _selectionTogglesBox.Children().Cast<Toggle>();
|
||||
foreach (var toggle in allToggles)
|
||||
toggle.SetValueWithoutNotify(value);
|
||||
|
||||
foreach (var key in _selections.Keys.ToArray())
|
||||
_selections[key] = value;
|
||||
|
||||
FilterDependencies(_activeFilter);
|
||||
OnValuesChanged?.Invoke(_selections);
|
||||
}
|
||||
|
||||
private void SelectAllToggles()
|
||||
{
|
||||
OnAllToggles(true);
|
||||
}
|
||||
|
||||
private void UnselectAllToggles()
|
||||
{
|
||||
OnAllToggles(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19e30766043794345beb432973e0eb3c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/UI/Elements/MultiToggleSelectionElement.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,137 @@
|
||||
using AssetStoreTools.Uploader.Data;
|
||||
using AssetStoreTools.Utility;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AssetStoreTools.Uploader.UI.Elements
|
||||
{
|
||||
internal class PackageContentElement : VisualElement
|
||||
{
|
||||
// Data
|
||||
private IPackageContent _content;
|
||||
private List<WorkflowElementBase> _workflowElements;
|
||||
|
||||
// UI
|
||||
private VisualElement _workflowSelectionBox;
|
||||
private ToolbarMenu _toolbarMenu;
|
||||
|
||||
public PackageContentElement(IPackageContent content)
|
||||
{
|
||||
_content = content;
|
||||
content.OnActiveWorkflowChanged += ActiveWorkflowChanged;
|
||||
|
||||
_workflowElements = new List<WorkflowElementBase>();
|
||||
|
||||
Create();
|
||||
}
|
||||
|
||||
private void Create()
|
||||
{
|
||||
AddToClassList("package-content-element");
|
||||
|
||||
CreateWorkflowSelection();
|
||||
CreateWorkflows();
|
||||
Deserialize();
|
||||
}
|
||||
|
||||
private void CreateWorkflowSelection()
|
||||
{
|
||||
_workflowSelectionBox = new VisualElement();
|
||||
_workflowSelectionBox.AddToClassList("package-content-option-box");
|
||||
|
||||
VisualElement labelHelpRow = new VisualElement();
|
||||
labelHelpRow.AddToClassList("package-content-option-label-help-row");
|
||||
|
||||
Label workflowLabel = new Label { text = "Upload type" };
|
||||
Image workflowLabelTooltip = new Image
|
||||
{
|
||||
tooltip = "Select what content you are uploading to the Asset Store"
|
||||
+ "\n\n- From Assets Folder - content located within the project's 'Assets' folder or one of its subfolders"
|
||||
+ "\n\n- Pre-exported .unitypackage - content that has already been compressed into a .unitypackage file"
|
||||
#if UNITY_ASTOOLS_EXPERIMENTAL
|
||||
+ "\n\n- Local UPM Package - content that is located within the project's 'Packages' folder. Only embedded and local packages are supported"
|
||||
#endif
|
||||
};
|
||||
|
||||
labelHelpRow.Add(workflowLabel);
|
||||
labelHelpRow.Add(workflowLabelTooltip);
|
||||
|
||||
_toolbarMenu = new ToolbarMenu();
|
||||
_toolbarMenu.AddToClassList("package-content-option-dropdown");
|
||||
|
||||
foreach (var workflow in _content.GetAvailableWorkflows())
|
||||
{
|
||||
AppendToolbarActionForWorkflow(workflow);
|
||||
}
|
||||
|
||||
_workflowSelectionBox.Add(labelHelpRow);
|
||||
_workflowSelectionBox.Add(_toolbarMenu);
|
||||
|
||||
Add(_workflowSelectionBox);
|
||||
}
|
||||
|
||||
private void AppendToolbarActionForWorkflow(IWorkflow workflow)
|
||||
{
|
||||
_toolbarMenu.menu.AppendAction(workflow.DisplayName, _ =>
|
||||
{
|
||||
_content.SetActiveWorkflow(workflow);
|
||||
});
|
||||
}
|
||||
|
||||
private void CreateWorkflows()
|
||||
{
|
||||
foreach (var workflow in _content.GetAvailableWorkflows())
|
||||
{
|
||||
WorkflowElementBase element;
|
||||
switch (workflow)
|
||||
{
|
||||
case AssetsWorkflow assetsWorkflow:
|
||||
element = new AssetsWorkflowElement(assetsWorkflow);
|
||||
break;
|
||||
case UnityPackageWorkflow unityPackageWorkflow:
|
||||
element = new UnityPackageWorkflowElement(unityPackageWorkflow);
|
||||
break;
|
||||
#if UNITY_ASTOOLS_EXPERIMENTAL
|
||||
case HybridPackageWorkflow hybridPackageWorkflow:
|
||||
element = new HybridPackageWorkflowElement(hybridPackageWorkflow);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ASDebug.LogWarning("Package Content Element received an undefined workflow");
|
||||
continue;
|
||||
}
|
||||
|
||||
element.OnInteractionAvailable += EnableInteraction;
|
||||
element.OnInteractionUnavailable += DisableInteraction;
|
||||
_workflowElements.Add(element);
|
||||
Add(element);
|
||||
}
|
||||
}
|
||||
|
||||
private void ActiveWorkflowChanged(IWorkflow workflow)
|
||||
{
|
||||
_toolbarMenu.text = workflow.DisplayName;
|
||||
foreach (var workflowElement in _workflowElements)
|
||||
{
|
||||
bool show = workflowElement.Is(workflow);
|
||||
workflowElement.style.display = show ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
}
|
||||
}
|
||||
|
||||
private void EnableInteraction()
|
||||
{
|
||||
_workflowSelectionBox.SetEnabled(true);
|
||||
}
|
||||
|
||||
private void DisableInteraction()
|
||||
{
|
||||
_workflowSelectionBox.SetEnabled(false);
|
||||
}
|
||||
|
||||
private void Deserialize()
|
||||
{
|
||||
ActiveWorkflowChanged(_content.GetActiveWorkflow());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09927e9c8fd6e074fa451add92b7ab6f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/UI/Elements/PackageContentElement.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,215 @@
|
||||
using AssetStoreTools.Api;
|
||||
using AssetStoreTools.Uploader.Data;
|
||||
using AssetStoreTools.Uploader.Services;
|
||||
using System;
|
||||
#if !UNITY_2021_1_OR_NEWER
|
||||
using UnityEditor.UIElements;
|
||||
#endif
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AssetStoreTools.Uploader.UI.Elements
|
||||
{
|
||||
internal class PackageElement : VisualElement
|
||||
{
|
||||
// Data
|
||||
private IPackage _package;
|
||||
private bool _isSelected;
|
||||
|
||||
private IPackageFactoryService _packageFactory;
|
||||
|
||||
// UI
|
||||
private Button _foldoutBox;
|
||||
private Label _expanderLabel;
|
||||
private Label _assetLabel;
|
||||
private Label _lastDateSizeLabel;
|
||||
private Image _assetImage;
|
||||
|
||||
private ProgressBar _uploadProgressBar;
|
||||
private VisualElement _uploadProgressBarBackground;
|
||||
|
||||
private PackageContentElement _contentElement;
|
||||
|
||||
public event Action OnSelected;
|
||||
|
||||
public PackageElement(IPackage package, IPackageFactoryService packageFactory)
|
||||
{
|
||||
_package = package;
|
||||
_package.OnUpdate += Refresh;
|
||||
_package.OnIconUpdate += SetPackageThumbnail;
|
||||
|
||||
_packageFactory = packageFactory;
|
||||
|
||||
_isSelected = false;
|
||||
|
||||
Create();
|
||||
}
|
||||
|
||||
private void Create()
|
||||
{
|
||||
AddToClassList("package-full-box");
|
||||
|
||||
_foldoutBox = new Button { name = "Package" };
|
||||
_foldoutBox.AddToClassList("package-foldout-box");
|
||||
if (_package.IsDraft)
|
||||
_foldoutBox.AddToClassList("package-foldout-box-draft");
|
||||
_foldoutBox.clickable.clicked += Toggle;
|
||||
|
||||
// Expander, Icon and Asset Label
|
||||
VisualElement foldoutBoxInfo = new VisualElement { name = "foldoutBoxInfo" };
|
||||
foldoutBoxInfo.AddToClassList("package-foldout-box-info");
|
||||
|
||||
VisualElement labelExpanderRow = new VisualElement { name = "labelExpanderRow" };
|
||||
labelExpanderRow.AddToClassList("package-expander-label-row");
|
||||
|
||||
_expanderLabel = new Label { name = "ExpanderLabel", text = "►" };
|
||||
_expanderLabel.AddToClassList("package-expander");
|
||||
_expanderLabel.style.display = _package.IsDraft ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
|
||||
_assetImage = new Image { name = "AssetImage" };
|
||||
_assetImage.AddToClassList("package-image");
|
||||
|
||||
VisualElement assetLabelInfoBox = new VisualElement { name = "assetLabelInfoBox" };
|
||||
assetLabelInfoBox.AddToClassList("package-label-info-box");
|
||||
|
||||
_assetLabel = new Label { name = "AssetLabel", text = _package.Name };
|
||||
_assetLabel.AddToClassList("package-label");
|
||||
|
||||
_lastDateSizeLabel = new Label { name = "AssetInfoLabel", text = FormatDateSize() };
|
||||
_lastDateSizeLabel.AddToClassList("package-info");
|
||||
|
||||
assetLabelInfoBox.Add(_assetLabel);
|
||||
assetLabelInfoBox.Add(_lastDateSizeLabel);
|
||||
|
||||
labelExpanderRow.Add(_expanderLabel);
|
||||
labelExpanderRow.Add(_assetImage);
|
||||
labelExpanderRow.Add(assetLabelInfoBox);
|
||||
|
||||
var openInBrowserButton = new Button(OpenPackageInBrowser)
|
||||
{
|
||||
name = "OpenInBrowserButton",
|
||||
tooltip = "View your package in the Publishing Portal."
|
||||
};
|
||||
openInBrowserButton.AddToClassList("package-open-in-browser-button");
|
||||
|
||||
// Header Progress bar
|
||||
_uploadProgressBar = new ProgressBar { name = "HeaderProgressBar" };
|
||||
_uploadProgressBar.AddToClassList("package-header-progress-bar");
|
||||
_uploadProgressBar.style.display = DisplayStyle.None;
|
||||
_uploadProgressBarBackground = _uploadProgressBar.Q<VisualElement>(className: "unity-progress-bar__progress");
|
||||
|
||||
// Connect it all
|
||||
foldoutBoxInfo.Add(labelExpanderRow);
|
||||
foldoutBoxInfo.Add(openInBrowserButton);
|
||||
|
||||
_foldoutBox.Add(foldoutBoxInfo);
|
||||
_foldoutBox.Add(_uploadProgressBar);
|
||||
|
||||
Add(_foldoutBox);
|
||||
}
|
||||
|
||||
private void CreateFoldoutContent()
|
||||
{
|
||||
var content = _packageFactory.CreatePackageContent(_package);
|
||||
if (content == null)
|
||||
return;
|
||||
|
||||
_contentElement = new PackageContentElement(content);
|
||||
_contentElement.style.display = DisplayStyle.None;
|
||||
Add(_contentElement);
|
||||
|
||||
SubscribeToContentWorkflowUpdates(content);
|
||||
}
|
||||
|
||||
private void SubscribeToContentWorkflowUpdates(IPackageContent content)
|
||||
{
|
||||
foreach (var workflow in content.GetAvailableWorkflows())
|
||||
{
|
||||
workflow.OnUploadStateChanged += UpdateProgressBar;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateProgressBar(UploadStatus? status, float? progress)
|
||||
{
|
||||
if (status != null)
|
||||
{
|
||||
_uploadProgressBarBackground.style.backgroundColor = PackageUploadElement.GetColorByStatus(status.Value);
|
||||
}
|
||||
|
||||
if (progress != null)
|
||||
{
|
||||
_uploadProgressBar.value = progress.Value;
|
||||
}
|
||||
}
|
||||
|
||||
private void Toggle()
|
||||
{
|
||||
if (!_package.IsDraft)
|
||||
return;
|
||||
|
||||
if (!Contains(_contentElement))
|
||||
CreateFoldoutContent();
|
||||
|
||||
var shouldExpand = !_isSelected;
|
||||
_expanderLabel.text = shouldExpand ? "▼" : "►";
|
||||
|
||||
if (shouldExpand)
|
||||
_foldoutBox.AddToClassList("package-foldout-box-expanded");
|
||||
else
|
||||
_foldoutBox.RemoveFromClassList("package-foldout-box-expanded");
|
||||
_contentElement.style.display = shouldExpand ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
|
||||
_isSelected = !_isSelected;
|
||||
ToggleProgressBar();
|
||||
|
||||
if (_isSelected)
|
||||
OnSelected?.Invoke();
|
||||
}
|
||||
|
||||
private void ToggleProgressBar()
|
||||
{
|
||||
if (!_isSelected && _uploadProgressBar.value != 0)
|
||||
_uploadProgressBar.style.display = DisplayStyle.Flex;
|
||||
else
|
||||
_uploadProgressBar.style.display = DisplayStyle.None;
|
||||
}
|
||||
|
||||
public bool Is(IPackage package)
|
||||
{
|
||||
return package == _package;
|
||||
}
|
||||
|
||||
public void Select()
|
||||
{
|
||||
if (!_isSelected)
|
||||
Toggle();
|
||||
}
|
||||
|
||||
public void Unselect()
|
||||
{
|
||||
if (_isSelected)
|
||||
Toggle();
|
||||
}
|
||||
|
||||
private void SetPackageThumbnail()
|
||||
{
|
||||
_assetImage.image = _package.Icon;
|
||||
}
|
||||
|
||||
private void Refresh()
|
||||
{
|
||||
_assetLabel.text = _package.Name;
|
||||
_lastDateSizeLabel.text = FormatDateSize();
|
||||
}
|
||||
|
||||
private string FormatDateSize()
|
||||
{
|
||||
return $"{_package.Category} | {_package.FormattedSize()} | {_package.FormattedModified()}";
|
||||
}
|
||||
|
||||
private void OpenPackageInBrowser()
|
||||
{
|
||||
Application.OpenURL($"https://publisher.unity.com/packages/{_package.VersionId}/edit/upload");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cef5f23043d318945b844bcac7a7a984
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/UI/Elements/PackageElement.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,149 @@
|
||||
using AssetStoreTools.Uploader.Data;
|
||||
using AssetStoreTools.Uploader.Services;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AssetStoreTools.Uploader.UI.Elements
|
||||
{
|
||||
internal class PackageGroupElement : VisualElement
|
||||
{
|
||||
// Data
|
||||
public string Name => _packageGroup.Name;
|
||||
private IPackageGroup _packageGroup;
|
||||
private List<PackageElement> _packageElements;
|
||||
private bool _isExpanded;
|
||||
|
||||
private IPackageFactoryService _packageFactory;
|
||||
|
||||
// UI
|
||||
private Button _groupExpanderBox;
|
||||
private VisualElement _groupContent;
|
||||
|
||||
private Label _expanderLabel;
|
||||
private Label _groupLabel;
|
||||
|
||||
public PackageGroupElement(IPackageGroup packageGroup, IPackageFactoryService packageFactory)
|
||||
{
|
||||
_packageGroup = packageGroup;
|
||||
_packageElements = new List<PackageElement>();
|
||||
_packageGroup.OnPackagesSorted += RefreshPackages;
|
||||
_packageGroup.OnPackagesFiltered += RefreshPackages;
|
||||
|
||||
_packageFactory = packageFactory;
|
||||
|
||||
Create();
|
||||
}
|
||||
|
||||
private void Create()
|
||||
{
|
||||
CreatePackageGroup();
|
||||
CreatePackageGroupContent();
|
||||
AddPackagesToGroupContent();
|
||||
}
|
||||
|
||||
protected void CreatePackageGroup()
|
||||
{
|
||||
_groupExpanderBox = new Button(OnPackageGroupClicked);
|
||||
_groupExpanderBox.AddToClassList("package-group-expander-box");
|
||||
|
||||
_expanderLabel = new Label { name = "ExpanderLabel", text = "►" };
|
||||
_expanderLabel.AddToClassList("package-group-expander");
|
||||
|
||||
_groupLabel = new Label { text = $"{_packageGroup.Name} ({_packageGroup.Packages.Count})" };
|
||||
_groupLabel.AddToClassList("package-group-label");
|
||||
FormatGroupLabel(_packageGroup.Packages.Count);
|
||||
|
||||
_groupExpanderBox.Add(_expanderLabel);
|
||||
_groupExpanderBox.Add(_groupLabel);
|
||||
|
||||
Add(_groupExpanderBox);
|
||||
}
|
||||
|
||||
private void CreatePackageGroupContent()
|
||||
{
|
||||
_groupContent = new VisualElement { name = "GroupContentBox" };
|
||||
_groupContent.AddToClassList("package-group-content-box");
|
||||
Toggle(false);
|
||||
|
||||
var groupSeparator = new VisualElement { name = "GroupSeparator" };
|
||||
groupSeparator.AddToClassList("package-group-separator");
|
||||
|
||||
if (_packageGroup.Name.ToLower() != "draft")
|
||||
{
|
||||
_groupLabel.SetEnabled(false);
|
||||
_groupContent.AddToClassList("unity-disabled");
|
||||
groupSeparator.style.display = DisplayStyle.Flex;
|
||||
}
|
||||
|
||||
Add(_groupContent);
|
||||
Add(groupSeparator);
|
||||
}
|
||||
|
||||
private void AddPackagesToGroupContent()
|
||||
{
|
||||
foreach (var package in _packageGroup.Packages)
|
||||
{
|
||||
var packageElement = new PackageElement(package, _packageFactory);
|
||||
packageElement.OnSelected += () => OnPackageSelected(packageElement);
|
||||
_packageElements.Add(packageElement);
|
||||
}
|
||||
}
|
||||
|
||||
private void FormatGroupLabel(int displayedPackageCount)
|
||||
{
|
||||
if (_packageGroup.Packages.Count == displayedPackageCount)
|
||||
_groupLabel.text = $"{Name} ({displayedPackageCount})";
|
||||
else
|
||||
_groupLabel.text = $"{Name} ({displayedPackageCount}/{_packageGroup.Packages.Count})";
|
||||
}
|
||||
|
||||
private void RefreshPackages(List<IPackage> packages)
|
||||
{
|
||||
_groupContent.Clear();
|
||||
|
||||
foreach (var package in packages)
|
||||
{
|
||||
var correspondingElement = _packageElements.FirstOrDefault(x => x.Is(package));
|
||||
if (correspondingElement == null)
|
||||
continue;
|
||||
|
||||
_groupContent.Add(correspondingElement);
|
||||
}
|
||||
|
||||
FormatGroupLabel(packages.Count());
|
||||
}
|
||||
|
||||
private void OnPackageGroupClicked()
|
||||
{
|
||||
Toggle(!_isExpanded);
|
||||
}
|
||||
|
||||
public void Toggle(bool expand)
|
||||
{
|
||||
if (expand)
|
||||
{
|
||||
_expanderLabel.text = "▼";
|
||||
_groupContent.style.display = DisplayStyle.Flex;
|
||||
}
|
||||
else
|
||||
{
|
||||
_expanderLabel.text = "►";
|
||||
_groupContent.style.display = DisplayStyle.None;
|
||||
}
|
||||
|
||||
_isExpanded = expand;
|
||||
}
|
||||
|
||||
private void OnPackageSelected(PackageElement packageElement)
|
||||
{
|
||||
foreach (var element in _packageElements)
|
||||
{
|
||||
if (element == packageElement)
|
||||
continue;
|
||||
|
||||
element.Unselect();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41e322a1418ab824182eade111145dff
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/UI/Elements/PackageGroupElement.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,58 @@
|
||||
using AssetStoreTools.Uploader.Data;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AssetStoreTools.Uploader.UI.Elements
|
||||
{
|
||||
internal class PackageListToolbar : VisualElement
|
||||
{
|
||||
private List<IPackageGroup> _packageGroups;
|
||||
|
||||
public PackageListToolbar()
|
||||
{
|
||||
Create();
|
||||
}
|
||||
|
||||
private void Create()
|
||||
{
|
||||
AddToClassList("package-list-toolbar");
|
||||
|
||||
// Search
|
||||
var searchField = new ToolbarSearchField { name = "SearchField" };
|
||||
searchField.AddToClassList("package-search-field");
|
||||
|
||||
// Sorting menu button
|
||||
var sortMenu = new ToolbarMenu() { text = "Sort: Name ↓" };
|
||||
sortMenu.menu.AppendAction("Sort: Name ↓", (_) => { sortMenu.text = "Sort: Name ↓"; Sort(PackageSorting.Name); });
|
||||
sortMenu.menu.AppendAction("Sort: Updated ↓", (_) => { sortMenu.text = "Sort: Updated ↓"; Sort(PackageSorting.Date); });
|
||||
sortMenu.menu.AppendAction("Sort: Category ↓", (_) => { sortMenu.text = "Sort: Category ↓"; Sort(PackageSorting.Category); });
|
||||
sortMenu.AddToClassList("package-sort-menu");
|
||||
|
||||
// Finalize the bar
|
||||
Add(searchField);
|
||||
Add(sortMenu);
|
||||
|
||||
// Add Callbacks and click events
|
||||
searchField.RegisterCallback<ChangeEvent<string>>(SearchFilter);
|
||||
}
|
||||
|
||||
public void SetPackageGroups(List<IPackageGroup> packageGroups)
|
||||
{
|
||||
_packageGroups = packageGroups;
|
||||
}
|
||||
|
||||
private void SearchFilter(ChangeEvent<string> evt)
|
||||
{
|
||||
var searchString = evt.newValue.ToLower();
|
||||
foreach (var packageGroup in _packageGroups)
|
||||
packageGroup.Filter(searchString);
|
||||
}
|
||||
|
||||
public void Sort(PackageSorting sortingType)
|
||||
{
|
||||
foreach (var packageGroup in _packageGroups)
|
||||
packageGroup.Sort(sortingType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d2659328222e0e4cb36cd194e023f4b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/UI/Elements/PackageListToolbar.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,321 @@
|
||||
using AssetStoreTools.Api;
|
||||
using AssetStoreTools.Api.Responses;
|
||||
using AssetStoreTools.Exporter;
|
||||
using AssetStoreTools.Uploader.Data;
|
||||
using AssetStoreTools.Utility;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEditor;
|
||||
#if !UNITY_2021_1_OR_NEWER
|
||||
using UnityEditor.UIElements;
|
||||
#endif
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AssetStoreTools.Uploader.UI.Elements
|
||||
{
|
||||
internal class PackageUploadElement : VisualElement
|
||||
{
|
||||
// Data
|
||||
private IWorkflow _workflow;
|
||||
private bool _enableExporting;
|
||||
|
||||
// UI
|
||||
private VisualElement _exportAndUploadContainer;
|
||||
|
||||
private Button _cancelUploadButton;
|
||||
private VisualElement _uploadProgressContainer;
|
||||
private ProgressBar _uploadProgressBar;
|
||||
private VisualElement _uploadProgressBarBackground;
|
||||
|
||||
public event Action OnInteractionAvailable;
|
||||
public event Action OnInteractionUnavailable;
|
||||
|
||||
public PackageUploadElement(IWorkflow workflow, bool exposeExportButton)
|
||||
{
|
||||
_workflow = workflow;
|
||||
_enableExporting = exposeExportButton;
|
||||
|
||||
Create();
|
||||
}
|
||||
|
||||
private void Create()
|
||||
{
|
||||
AddToClassList("uploading-box");
|
||||
|
||||
CreateButtonContainer();
|
||||
CreateProgressContainer();
|
||||
}
|
||||
|
||||
private void CreateButtonContainer()
|
||||
{
|
||||
_exportAndUploadContainer = new VisualElement();
|
||||
_exportAndUploadContainer.AddToClassList("uploading-export-and-upload-container");
|
||||
|
||||
CreateExportButton();
|
||||
CreateUploadButton();
|
||||
Add(_exportAndUploadContainer);
|
||||
}
|
||||
|
||||
private void CreateExportButton()
|
||||
{
|
||||
if (!_enableExporting)
|
||||
return;
|
||||
|
||||
var _exportAndUploadButton = new Button(async () => await Export(true)) { name = "ExportButton", text = "Export" };
|
||||
_exportAndUploadButton.AddToClassList("uploading-export-button");
|
||||
|
||||
_exportAndUploadContainer.Add(_exportAndUploadButton);
|
||||
}
|
||||
|
||||
private void CreateUploadButton()
|
||||
{
|
||||
var _uploadButton = new Button(Upload) { name = "UploadButton" };
|
||||
_uploadButton.text = _enableExporting ? "Export and Upload" : "Upload";
|
||||
_uploadButton.AddToClassList("uploading-upload-button");
|
||||
|
||||
_exportAndUploadContainer.Add(_uploadButton);
|
||||
}
|
||||
|
||||
private void CreateProgressContainer()
|
||||
{
|
||||
_uploadProgressContainer = new VisualElement();
|
||||
_uploadProgressContainer.AddToClassList("uploading-progress-container");
|
||||
_uploadProgressContainer.style.display = DisplayStyle.None;
|
||||
|
||||
_uploadProgressBar = new ProgressBar { name = "UploadProgressBar" };
|
||||
_uploadProgressBar.AddToClassList("uploading-progress-bar");
|
||||
_uploadProgressBarBackground = _uploadProgressBar.Q<VisualElement>(className: "unity-progress-bar__progress");
|
||||
|
||||
_cancelUploadButton = new Button() { name = "CancelButton", text = "Cancel" };
|
||||
_cancelUploadButton.AddToClassList("uploading-cancel-button");
|
||||
|
||||
_uploadProgressContainer.Add(_uploadProgressBar);
|
||||
_uploadProgressContainer.Add(_cancelUploadButton);
|
||||
|
||||
Add(_uploadProgressContainer);
|
||||
}
|
||||
|
||||
private async Task<PackageExporterResult> Export(bool interactive)
|
||||
{
|
||||
try
|
||||
{
|
||||
DisableInteraction();
|
||||
|
||||
if (!_workflow.IsPathSet)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Exporting failed", "No path was selected. Please " +
|
||||
"select a path and try again.", "OK");
|
||||
return new PackageExporterResult() { Success = false, Exception = new Exception("No path was selected.") };
|
||||
}
|
||||
|
||||
var rootProjectPath = Constants.RootProjectPath;
|
||||
var packageNameStripped = Regex.Replace(_workflow.PackageName, "[^a-zA-Z0-9]", "");
|
||||
var outputName = $"{packageNameStripped}-{DateTime.Now:yyyy-dd-M--HH-mm-ss}";
|
||||
|
||||
string outputPath;
|
||||
if (interactive)
|
||||
{
|
||||
outputPath = EditorUtility.SaveFilePanel("Export Package", rootProjectPath,
|
||||
outputName, _workflow.PackageExtension.Remove(0, 1)); // Ignoring the '.' character since SaveFilePanel already appends it
|
||||
|
||||
if (string.IsNullOrEmpty(outputPath))
|
||||
return new PackageExporterResult() { Success = false, Exception = null };
|
||||
}
|
||||
else
|
||||
{
|
||||
outputPath = $"Temp/{outputName}{_workflow.PackageExtension}";
|
||||
}
|
||||
|
||||
var exportResult = await _workflow.ExportPackage(outputPath);
|
||||
if (!exportResult.Success)
|
||||
{
|
||||
Debug.LogError($"Package exporting failed: {exportResult.Exception}");
|
||||
EditorUtility.DisplayDialog("Exporting failed", exportResult.Exception.Message, "OK");
|
||||
}
|
||||
else if (interactive)
|
||||
Debug.Log($"Package exported to '{Path.GetFullPath(exportResult.ExportedPath).Replace("\\", "/")}'");
|
||||
|
||||
return exportResult;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (interactive)
|
||||
EnableInteraction();
|
||||
}
|
||||
}
|
||||
|
||||
private async void Upload()
|
||||
{
|
||||
DisableInteraction();
|
||||
|
||||
if (await ValidateUnityVersionsBeforeUpload() == false)
|
||||
{
|
||||
EnableInteraction();
|
||||
return;
|
||||
}
|
||||
|
||||
var exportResult = await Export(false);
|
||||
if (!exportResult.Success)
|
||||
{
|
||||
EnableInteraction();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_workflow.IsPathSet)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Uploading failed", "No path was selected. Please " +
|
||||
"select a path and try again.", "OK");
|
||||
EnableInteraction();
|
||||
return;
|
||||
}
|
||||
|
||||
_exportAndUploadContainer.style.display = DisplayStyle.None;
|
||||
_uploadProgressContainer.style.display = DisplayStyle.Flex;
|
||||
|
||||
_cancelUploadButton.clicked += Cancel;
|
||||
_workflow.OnUploadStateChanged += UpdateProgressBar;
|
||||
var response = await _workflow.UploadPackage(exportResult.ExportedPath);
|
||||
_workflow.OnUploadStateChanged -= UpdateProgressBar;
|
||||
|
||||
await OnUploadingStopped(response);
|
||||
}
|
||||
|
||||
private async Task<bool> ValidateUnityVersionsBeforeUpload()
|
||||
{
|
||||
var validationEnabled = ASToolsPreferences.Instance.UploadVersionCheck;
|
||||
if (!validationEnabled)
|
||||
return true;
|
||||
|
||||
var requiredVersionUploaded = await _workflow.ValidatePackageUploadedVersions();
|
||||
if (requiredVersionUploaded)
|
||||
return true;
|
||||
|
||||
var result = EditorUtility.DisplayDialogComplex("Asset Store Tools", $"You may upload this package, but you will need to add a package using Unity version {Constants.Uploader.MinRequiredUnitySupportVersion} " +
|
||||
"or higher to be able to submit a new asset", "Upload", "Cancel", "Upload and do not display this again");
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case 1:
|
||||
return false;
|
||||
case 2:
|
||||
ASToolsPreferences.Instance.UploadVersionCheck = false;
|
||||
ASToolsPreferences.Instance.Save();
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void UpdateProgressBar(UploadStatus? status, float? progress)
|
||||
{
|
||||
if (status != null)
|
||||
{
|
||||
_uploadProgressBarBackground.style.backgroundColor = GetColorByStatus(status.Value);
|
||||
}
|
||||
|
||||
if (progress != null)
|
||||
{
|
||||
_uploadProgressBar.value = progress.Value;
|
||||
_uploadProgressBar.title = $"{progress.Value:0.#}%";
|
||||
|
||||
if (progress == 100f && _cancelUploadButton.enabledInHierarchy)
|
||||
_cancelUploadButton.SetEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void Cancel()
|
||||
{
|
||||
_cancelUploadButton.SetEnabled(false);
|
||||
_workflow.AbortUpload();
|
||||
}
|
||||
|
||||
private async Task OnUploadingStopped(PackageUploadResponse response)
|
||||
{
|
||||
if (!response.Success && !response.Cancelled)
|
||||
{
|
||||
Debug.LogException(response.Exception);
|
||||
}
|
||||
|
||||
if (response.Success)
|
||||
{
|
||||
await _workflow.RefreshPackage();
|
||||
}
|
||||
|
||||
if (response.Status == UploadStatus.ResponseTimeout)
|
||||
{
|
||||
Debug.LogWarning($"All bytes for the package '{_workflow.PackageName}' have been uploaded, but a response " +
|
||||
$"from the server was not received. This can happen because of Firewall restrictions. " +
|
||||
$"Please make sure that a new version of your package has reached the Publishing Portal.");
|
||||
}
|
||||
|
||||
_uploadProgressBar.title = GetProgressBarTitleByStatus(response.Status);
|
||||
|
||||
_cancelUploadButton.clickable = null;
|
||||
_cancelUploadButton.clicked += Reset;
|
||||
_cancelUploadButton.text = "Done";
|
||||
_cancelUploadButton.SetEnabled(true);
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
_cancelUploadButton.clickable = null;
|
||||
_cancelUploadButton.text = "Cancel";
|
||||
|
||||
_workflow.ResetUploadStatus();
|
||||
UpdateProgressBar(UploadStatus.Default, 0f);
|
||||
|
||||
_uploadProgressContainer.style.display = DisplayStyle.None;
|
||||
_exportAndUploadContainer.style.display = DisplayStyle.Flex;
|
||||
EnableInteraction();
|
||||
}
|
||||
|
||||
public static Color GetColorByStatus(UploadStatus status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
default:
|
||||
case UploadStatus.Default:
|
||||
return new Color(0.13f, 0.59f, 0.95f);
|
||||
case UploadStatus.Success:
|
||||
case UploadStatus.ResponseTimeout:
|
||||
return new Color(0f, 0.50f, 0.14f);
|
||||
case UploadStatus.Cancelled:
|
||||
return new Color(0.78f, 0.59f, 0f);
|
||||
case UploadStatus.Fail:
|
||||
return new Color(0.69f, 0.04f, 0.04f);
|
||||
}
|
||||
}
|
||||
|
||||
private string GetProgressBarTitleByStatus(UploadStatus status)
|
||||
{
|
||||
var progressBarTitle = "Upload: ";
|
||||
switch (status)
|
||||
{
|
||||
case UploadStatus.ResponseTimeout:
|
||||
progressBarTitle += UploadStatus.Success;
|
||||
break;
|
||||
default:
|
||||
progressBarTitle += status;
|
||||
break;
|
||||
}
|
||||
|
||||
return progressBarTitle;
|
||||
}
|
||||
|
||||
private void EnableInteraction()
|
||||
{
|
||||
_exportAndUploadContainer.SetEnabled(true);
|
||||
OnInteractionAvailable?.Invoke();
|
||||
}
|
||||
|
||||
private void DisableInteraction()
|
||||
{
|
||||
_exportAndUploadContainer.SetEnabled(false);
|
||||
OnInteractionUnavailable?.Invoke();
|
||||
SetEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 242524e968bd4484eaeb154d8013f427
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/UI/Elements/PackageUploadElement.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AssetStoreTools.Uploader.UI.Elements
|
||||
{
|
||||
internal class PathSelectionElement : VisualElement
|
||||
{
|
||||
// Data
|
||||
private string _labelText;
|
||||
private string _labelTooltip;
|
||||
|
||||
public event Action OnBrowse;
|
||||
|
||||
// UI
|
||||
private TextField _pathSelectionTextField;
|
||||
|
||||
public PathSelectionElement(string labelText, string labelTooltip)
|
||||
{
|
||||
AddToClassList("package-content-option-box");
|
||||
|
||||
_labelText = labelText;
|
||||
_labelTooltip = labelTooltip;
|
||||
|
||||
Create();
|
||||
}
|
||||
|
||||
private void Create()
|
||||
{
|
||||
VisualElement labelHelpRow = new VisualElement();
|
||||
labelHelpRow.AddToClassList("package-content-option-label-help-row");
|
||||
|
||||
Label folderPathLabel = new Label { text = _labelText };
|
||||
Image folderPathLabelTooltip = new Image
|
||||
{
|
||||
tooltip = _labelTooltip
|
||||
};
|
||||
|
||||
labelHelpRow.Add(folderPathLabel);
|
||||
labelHelpRow.Add(folderPathLabelTooltip);
|
||||
|
||||
_pathSelectionTextField = new TextField();
|
||||
_pathSelectionTextField.AddToClassList("package-content-option-textfield");
|
||||
_pathSelectionTextField.isReadOnly = true;
|
||||
|
||||
Button browsePathButton = new Button(Browse) { name = "BrowsePathButton", text = "Browse" };
|
||||
browsePathButton.AddToClassList("package-content-option-button");
|
||||
|
||||
Add(labelHelpRow);
|
||||
Add(_pathSelectionTextField);
|
||||
Add(browsePathButton);
|
||||
}
|
||||
|
||||
private void Browse()
|
||||
{
|
||||
OnBrowse?.Invoke();
|
||||
}
|
||||
|
||||
public void SetPath(string path)
|
||||
{
|
||||
_pathSelectionTextField.value = path;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 753d4442293e5cc4b9efcab089da4d59
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/UI/Elements/PathSelectionElement.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,109 @@
|
||||
using AssetStoreTools.Previews.Data;
|
||||
using AssetStoreTools.Uploader.Data;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace AssetStoreTools.Uploader.UI.Elements
|
||||
{
|
||||
internal class PreviewGenerationElement : VisualElement
|
||||
{
|
||||
// Data
|
||||
private IWorkflow _workflow;
|
||||
|
||||
// UI
|
||||
private VisualElement _toggleRow;
|
||||
private Toggle _previewToggle;
|
||||
|
||||
private VisualElement _buttonRow;
|
||||
private VisualElement _viewButton;
|
||||
|
||||
public PreviewGenerationElement(IWorkflow workflow)
|
||||
{
|
||||
_workflow = workflow;
|
||||
|
||||
Create();
|
||||
}
|
||||
|
||||
private void Create()
|
||||
{
|
||||
CreateInfoRow();
|
||||
CreateViewButton();
|
||||
}
|
||||
|
||||
private void CreateInfoRow()
|
||||
{
|
||||
_toggleRow = new VisualElement();
|
||||
_toggleRow.AddToClassList("package-content-option-box");
|
||||
|
||||
VisualElement toggleLabelHelpRow = new VisualElement();
|
||||
toggleLabelHelpRow.AddToClassList("package-content-option-label-help-row");
|
||||
|
||||
Label toggleLabel = new Label { text = "Asset Previews" };
|
||||
Image toggleLabelTooltip = new Image
|
||||
{
|
||||
tooltip = "Select how the previews for your assets will be generated.\n\n" +
|
||||
"Unity generates asset preview images natively up to a size of 128x128. " +
|
||||
"You can try generating previews which are of higher resolution, up to 300x300.\n\n" +
|
||||
"Note: these asset preview images will only be displayed in the 'Package Content' section of the " +
|
||||
"Asset Store listing page once the package is published, and in the package importer window that appears during the package import process.\n" +
|
||||
"They will not replace the images used for the assets in the Project window after the package gets imported."
|
||||
};
|
||||
|
||||
_previewToggle = new Toggle { name = "PreviewToggle", text = "Generate Hi-Res (experimental)" };
|
||||
_previewToggle.AddToClassList("package-content-option-toggle");
|
||||
_previewToggle.RegisterValueChangedCallback((_) => DependencyToggleValueChange());
|
||||
|
||||
toggleLabelHelpRow.Add(toggleLabel);
|
||||
toggleLabelHelpRow.Add(toggleLabelTooltip);
|
||||
|
||||
_toggleRow.Add(toggleLabelHelpRow);
|
||||
_toggleRow.Add(_previewToggle);
|
||||
|
||||
Add(_toggleRow);
|
||||
}
|
||||
|
||||
private void CreateViewButton()
|
||||
{
|
||||
_buttonRow = new VisualElement();
|
||||
_buttonRow.AddToClassList("package-content-option-box");
|
||||
_buttonRow.style.display = DisplayStyle.None;
|
||||
|
||||
var spaceFiller = new VisualElement();
|
||||
spaceFiller.AddToClassList("package-content-option-label-help-row");
|
||||
|
||||
_viewButton = new Button(ViewClicked) { text = "Inspect Previews" };
|
||||
|
||||
_buttonRow.Add(spaceFiller);
|
||||
_buttonRow.Add(_viewButton);
|
||||
|
||||
Add(_buttonRow);
|
||||
}
|
||||
|
||||
private void DependencyToggleValueChange()
|
||||
{
|
||||
_workflow.GenerateHighQualityPreviews = _previewToggle.value;
|
||||
_buttonRow.style.display = _previewToggle.value ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
}
|
||||
|
||||
private void ViewClicked()
|
||||
{
|
||||
PreviewGenerationSettings settings;
|
||||
if (_workflow.GenerateHighQualityPreviews)
|
||||
{
|
||||
settings = new CustomPreviewGenerationSettings() { InputPaths = _workflow.GetAllPaths().ToArray() };
|
||||
}
|
||||
else
|
||||
{
|
||||
settings = new NativePreviewGenerationSettings() { InputPaths = _workflow.GetAllPaths().ToArray() };
|
||||
}
|
||||
|
||||
AssetStoreTools.ShowAssetStoreToolsPreviewGenerator(settings);
|
||||
}
|
||||
|
||||
private void DisplayProgress(float value)
|
||||
{
|
||||
EditorUtility.DisplayProgressBar("Generating", "Generating previews...", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54c7971e2ad639644936d3552b4f4f49
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/UI/Elements/PreviewGenerationElement.cs
|
||||
uploadId: 724584
|
||||
@@ -0,0 +1,58 @@
|
||||
using AssetStoreTools.Uploader.Data;
|
||||
using AssetStoreTools.Utility;
|
||||
using UnityEditor;
|
||||
|
||||
namespace AssetStoreTools.Uploader.UI.Elements
|
||||
{
|
||||
internal class UnityPackageWorkflowElement : WorkflowElementBase
|
||||
{
|
||||
// Data
|
||||
private UnityPackageWorkflow _workflow;
|
||||
|
||||
public UnityPackageWorkflowElement(UnityPackageWorkflow workflow) : base(workflow)
|
||||
{
|
||||
_workflow = workflow;
|
||||
Create();
|
||||
}
|
||||
|
||||
private void Create()
|
||||
{
|
||||
CreatePathElement("Package path", "Select the .unitypackage file you would like to upload.");
|
||||
CreateValidationElement(new ExternalProjectValidationElement(_workflow));
|
||||
CreateUploadElement(_workflow, false);
|
||||
Deserialize();
|
||||
}
|
||||
|
||||
protected override void BrowsePath()
|
||||
{
|
||||
// Path retrieval
|
||||
var absolutePackagePath = EditorUtility.OpenFilePanel("Select a .unitypackage file", Constants.RootProjectPath, "unitypackage");
|
||||
|
||||
if (string.IsNullOrEmpty(absolutePackagePath))
|
||||
return;
|
||||
|
||||
var relativeExportPath = FileUtility.AbsolutePathToRelativePath(absolutePackagePath, ASToolsPreferences.Instance.EnableSymlinkSupport);
|
||||
if (!_workflow.IsPathValid(relativeExportPath, out var error))
|
||||
{
|
||||
EditorUtility.DisplayDialog("Invalid selection", error, "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
HandleUnityPackageUploadPathSelection(relativeExportPath, true);
|
||||
}
|
||||
|
||||
private void HandleUnityPackageUploadPathSelection(string selectedPackagePath, bool serialize)
|
||||
{
|
||||
if (string.IsNullOrEmpty(selectedPackagePath))
|
||||
return;
|
||||
|
||||
_workflow.SetPackagePath(selectedPackagePath, serialize);
|
||||
SetPathSelectionTextField(selectedPackagePath);
|
||||
}
|
||||
|
||||
protected override void Deserialize()
|
||||
{
|
||||
HandleUnityPackageUploadPathSelection(_workflow.GetPackagePath(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a0c8a79b7dba9e458ddc54eec30ea66
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 115
|
||||
packageName: Asset Store Publishing Tools
|
||||
packageVersion: 12.0.1
|
||||
assetPath: Packages/com.unity.asset-store-tools/Editor/Uploader/Scripts/UI/Elements/UnityPackageWorkflowElement.cs
|
||||
uploadId: 724584
|
||||
Reference in New Issue
Block a user