Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: install/uninstall modules from welcome window #593

Merged
merged 19 commits into from
Feb 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions Assets/Mirage/Editor/WelcomeWindow/Resources/WelcomeWindow.uss
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@
-unity-text-align: upper-left;
padding-left: 10px;
padding-right: 10px;
padding-bottom: 10px;
padding-top: 5px;
padding-bottom: 15px;
padding-top: 0;
flex: 3;
white-space: normal;
}
Expand Down Expand Up @@ -99,6 +99,14 @@ Button {
justify-content: space-between;
}

#Module {
flex-basis: 20px;
flex-direction: row;
justify-content: space-between;
align-items: center;
margin-bottom: 3px;
}

.dark-selected-tab {
background-color: rgba(53, 53, 53, 255);
border-left-color: rgba(36, 36, 36, 255);
Expand Down
21 changes: 21 additions & 0 deletions Assets/Mirage/Editor/WelcomeWindow/Resources/WelcomeWindow.uxml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<ui:VisualElement name="LeftColumnBox">
<ui:Button name="WelcomeButton" text="Welcome" class="light-selected-tab dark-selected-tab" />
<ui:Button name="QuickStartButton" text="Quick Start Guide" class="light-selected-tab dark-selected-tab" />
<ui:Button name="PackagesButton" text="Packages" class="light-selected-tab dark-selected-tab" />
<ui:Button name="FaqButton" text="FAQ" class="light-selected-tab dark-selected-tab" />
<ui:Button name="BestPracticesButton" text="Best Practices" class="light-selected-tab dark-selected-tab" />
<ui:Button name="ChangeLogButton" text="Change Log" class="light-selected-tab dark-selected-tab" />
Expand Down Expand Up @@ -59,6 +60,26 @@
<ui:VisualElement name="Spacer" />
<ui:Button name="Redirect" text="Join Discord" class="redirect" />
</ui:VisualElement>
<ui:ScrollView name="Packages" style="display: none;">
<ui:Label name="Header" text="Packages" />
<ui:Label name="Description" text="Mirage is a modular networking library. It ships with the foundation that you can build upon by installing packages." style="flex-basis: auto; flex-grow: 0; flex-shrink: 0;" />
<ui:Label text="Available Packages" display-tooltip-when-elided="True" style="padding-left: 10px; -unity-font-style: bold;" />
<ui:VisualElement name="ModulesList" style="flex-grow: 1; padding-left: 10px; padding-right: 10px;">
<ui:VisualElement name="Module" tooltip="Automatically find games within the same network.">
<ui:Label text="LAN Discovery" name="Name" />
<ui:Button text="Install" display-tooltip-when-elided="True" name="InstallButton" style="flex-shrink: 1; height: auto;" />
</ui:VisualElement>
<ui:VisualElement name="Module" tooltip="A transport that uses Facepunch&apos;s Steam SDK.">
<ui:Label text="Steam (Facepunch)" name="Name" />
<ui:Button text="Install" display-tooltip-when-elided="True" name="InstallButton" style="flex-shrink: 1; height: auto;" />
</ui:VisualElement>
<ui:VisualElement name="Module" tooltip="A transport that uses Steamworks.NET.">
<ui:Label text="Steam (Steamworks.NET)" name="Name" />
<ui:Button text="Install" display-tooltip-when-elided="True" name="InstallButton" style="flex-shrink: 1; height: auto;" />
</ui:VisualElement>
</ui:VisualElement>
<ui:VisualElement name="Spacer" />
</ui:ScrollView>
</ui:VisualElement>
</ui:Box>
</ui:UXML>
220 changes: 208 additions & 12 deletions Assets/Mirage/Editor/WelcomeWindow/WelcomeWindow.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.PackageManager;
using UnityEditor.PackageManager.Requests;
using System.Collections.Generic;

/**
* Docs used:
Expand All @@ -17,8 +20,7 @@ namespace Mirage
public class WelcomeWindow : EditorWindow
{
private Button lastClickedTab;
private StyleColor defaultButtonBackgroundColor;
private StyleColor defaultButtonBorderColor;
private readonly List<Button> installButtons = new List<Button>();

#region Setup

Expand All @@ -32,8 +34,22 @@ public class WelcomeWindow : EditorWindow
private const string SponsorUrl = "";
private const string DiscordInviteUrl = "https://discord.gg/DTBPBYvexy";
erikas-taroza marked this conversation as resolved.
Show resolved Hide resolved

private readonly List<Package> Packages = new List<Package>()
{
new Package { displayName = "LAN Discovery", packageName = "com.miragenet.discovery", gitUrl = "https://github.com/MirageNet/Discovery.git?path=/Assets/Discovery"},
new Package { displayName = "Steam (Facepunch)", packageName = "com.miragenet.steamyface", gitUrl = "https://github.com/MirageNet/SteamyFaceNG.git?path=/Assets/Mirage/Runtime/Transport/SteamyFaceMirror" },
new Package { displayName = "Steam (Steamworks.NET)", packageName = "com.miragenet.steamy", gitUrl = "https://github.com/MirageNet/FizzySteamyMirror.git?path=/Assets/Mirage/Runtime/Transport/FizzySteamyMirror" },
};

#endregion

//request for the module install
private static AddRequest installRequest;
private static RemoveRequest uninstallRequest;
private static ListRequest listRequest;

private static WelcomeWindow currentWindow;

//window size of the welcome screen
private static Vector2 windowSize = new Vector2(500, 415);
private static string screenToOpenKey = "MirageScreenToOpen";
erikas-taroza marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -90,12 +106,12 @@ private static void ShowWindowOnFirstStart()
public static void OpenWindow()
{
//create the window
WelcomeWindow window = GetWindow<WelcomeWindow>("Mirage Welcome Page");
currentWindow = GetWindow<WelcomeWindow>("Mirage Welcome Page");
//set the position and size
window.position = new Rect(new Vector2(100, 100), windowSize);
currentWindow.position = new Rect(new Vector2(100, 100), windowSize);
//set min and max sizes so we cant readjust window size
window.maxSize = windowSize;
window.minSize = windowSize;
currentWindow.maxSize = windowSize;
currentWindow.minSize = windowSize;
}

#endregion
Expand All @@ -120,11 +136,6 @@ private void OnEnable()
Label versionText = root.Q<Label>("VersionText");
versionText.text = "v" + GetVersion();

//set button default colors (used in page nav)
IStyle sampleStyle = rootVisualElement.Q<Button>("WelcomeButton").style;
defaultButtonBackgroundColor = sampleStyle.backgroundColor;
defaultButtonBorderColor = sampleStyle.borderTopColor;

#region Page buttons

ConfigureTab("WelcomeButton", "Welcome", WelcomePageUrl);
Expand All @@ -134,6 +145,7 @@ private void OnEnable()
ConfigureTab("FaqButton", "Faq", FaqUrl);
ConfigureTab("SponsorButton", "Sponsor", SponsorUrl);
ConfigureTab("DiscordButton", "Discord", DiscordInviteUrl);
ConfigurePackagesTab();

ShowTab(EditorPrefs.GetString(screenToOpenKey, "Welcome"));

Expand All @@ -153,6 +165,7 @@ private void OnDisable()
EditorPrefs.SetBool(firstTimeMirageKey, true);
}

//menu button setup
private void ConfigureTab(string tabButtonName, string tab, string url)
{
Button tabButton = rootVisualElement.Q<Button>(tabButtonName);
Expand All @@ -165,6 +178,7 @@ private void ConfigureTab(string tabButtonName, string tab, string url)
ToggleMenuButtonColor(tabButton, true);
ToggleMenuButtonColor(lastClickedTab, false);
ShowTab(tab);

lastClickedTab = tabButton;
EditorPrefs.SetString(screenToOpenKey, tab);
};
Expand All @@ -173,6 +187,7 @@ private void ConfigureTab(string tabButtonName, string tab, string url)
redirectButton.clicked += () => Application.OpenURL(url);
}

//switch between content
private void ShowTab(string screen)
{
VisualElement rightColumn = rootVisualElement.Q<VisualElement>("RightColumnBox");
Expand All @@ -195,9 +210,12 @@ private void ShowTab(string screen)
}
}

//changes the background and border color of the button
//if toggle == true, keep the button tinted
//otherwise, return the button to the default, not active, colors
private void ToggleMenuButtonColor(Button button, bool toggle)
{
if(button == null) { return; }
if (button == null) { return; }

//dark mode
if (EditorGUIUtility.isProSkin)
Expand All @@ -211,7 +229,185 @@ private void ToggleMenuButtonColor(Button button, bool toggle)
}
}

#region Packages

//configure the package tab when the tab button is pressed
private void ConfigurePackagesTab()
{
Button tabButton = rootVisualElement.Q<Button>("PackagesButton");

tabButton.EnableInClassList("dark-selected-tab", false);
tabButton.EnableInClassList("light-selected-tab", false);

tabButton.clicked += () =>
{
ToggleMenuButtonColor(tabButton, true);
ToggleMenuButtonColor(lastClickedTab, false);
ShowTab("Packages");

lastClickedTab = tabButton;
EditorPrefs.SetString(screenToOpenKey, "Packages");
};

listRequest = UnityEditor.PackageManager.Client.List(true, false);

//subscribe to ListPackageProgress for updates
EditorApplication.update += ListPackageProgress;
}

//install the package
private void InstallPackage(string packageName)
{
installRequest = UnityEditor.PackageManager.Client.Add(Packages.Find((x) => x.displayName == packageName).gitUrl);

//subscribe to InstallPackageProgress for updates
EditorApplication.update += InstallPackageProgress;
}

//uninstall the package
private void UninstallPackage(string packageName)
{
uninstallRequest = UnityEditor.PackageManager.Client.Remove(Packages.Find((x) => x.displayName == packageName).packageName);

//subscribe to UninstallPackageProgress for updates
EditorApplication.update += UninstallPackageProgress;
}

//keeps track of the package install progress
private void InstallPackageProgress()
{
if (installRequest.IsCompleted)
{
//log results
if (installRequest.Status == StatusCode.Success)
{
Debug.Log("Package install successful.");
}
else if (installRequest.Status == StatusCode.Failure)
{
Debug.LogError("Package install was unsuccessful. \n Error Code: " + installRequest.Error.errorCode + "\n Error Message: " + installRequest.Error.message);
}

EditorApplication.update -= InstallPackageProgress;

//refresh the package tab
currentWindow?.Close();
OpenWindow();
}
}

private void UninstallPackageProgress()
{
if (uninstallRequest.IsCompleted)
{
//log results
EditorApplication.update -= UninstallPackageProgress;

if (uninstallRequest.Status == StatusCode.Success)
{
Debug.Log("Package uninstall successful.");
}
else if (uninstallRequest.Status == StatusCode.Failure)
{
Debug.LogError("Package uninstall was unsuccessful. \n Error Code: " + uninstallRequest.Error.errorCode + "\n Error Message: " + uninstallRequest.Error.message);
}

//refresh the package tab
currentWindow?.Close();
OpenWindow();
}
}

private void ListPackageProgress()
{
if (listRequest.IsCompleted)
{
EditorApplication.update -= ListPackageProgress;

if (listRequest.Status == StatusCode.Success)
{
List<string> installedPackages = new List<string>();

//populate installedPackages
foreach (var package in listRequest.Result)
{
Package? miragePackage = Packages.Find((x) => x.packageName == package.name);
if (miragePackage != null)
{
installedPackages.Add(miragePackage.Value.displayName);
}
}

ConfigureInstallButtons(installedPackages);
}
//log error
else if (listRequest.Status == StatusCode.Failure)
{
Debug.LogError("There was an issue finding packages. \n Error Code: " + listRequest.Error.errorCode + "\n Error Message: " + listRequest.Error.message);
}
}
}

//configures the install button
//changes text and functionality after button press
private void ConfigureInstallButtons(List<string> installedPackages)
{
//get all the packages
foreach (VisualElement package in rootVisualElement.Q<VisualElement>("ModulesList").Children())
{
//get the button and name of the package
Button installButton = package.Q<Button>("InstallButton");
string packageName = package.Q<Label>("Name").text;
bool foundInInstalledPackages = installedPackages.Contains(packageName);

//set text
installButton.text = !foundInInstalledPackages ? "Install" : "Uninstall";

//set functionality
if (!foundInInstalledPackages)
{
installButton.clicked += () =>
{
InstallPackage(packageName);
installButton.text = "Installing";
DisableInstallButtons();
};
}
else
{
installButton.clicked += () =>
{
UninstallPackage(packageName);
installButton.text = "Uninstalling";
DisableInstallButtons();
};
}

installButtons.Add(installButton);
}
}

//prevents user from spamming install button
//spamming the button while installing/uninstalling throws errors
//buttons enabled again after window refreshes
private void DisableInstallButtons()
{
foreach (Button button in installButtons)
{
button.SetEnabled(false);
}
}

#endregion

#endregion
}

//module data type
public struct Package
{
public string displayName;
public string packageName;
public string gitUrl;
}
}