diff --git a/docs/screenshots/installed.png b/docs/screenshots/installed.png index e4061cec..43335614 100644 Binary files a/docs/screenshots/installed.png and b/docs/screenshots/installed.png differ diff --git a/docs/screenshots/online.png b/docs/screenshots/online.png index 2e0c6bda..57868972 100644 Binary files a/docs/screenshots/online.png and b/docs/screenshots/online.png differ diff --git a/docs/screenshots/updates.png b/docs/screenshots/updates.png index 0c5ef97c..1e5cc12a 100644 Binary files a/docs/screenshots/updates.png and b/docs/screenshots/updates.png differ diff --git a/docs/screenshots/updates_showdowngrades.png b/docs/screenshots/updates_showdowngrades.png index 0a68c63c..54aa949f 100644 Binary files a/docs/screenshots/updates_showdowngrades.png and b/docs/screenshots/updates_showdowngrades.png differ diff --git a/src/NuGetForUnity/Editor/Ui/NugetWindow.cs b/src/NuGetForUnity/Editor/Ui/NugetWindow.cs index d0db9011..b41928a4 100644 --- a/src/NuGetForUnity/Editor/Ui/NugetWindow.cs +++ b/src/NuGetForUnity/Editor/Ui/NugetWindow.cs @@ -22,22 +22,6 @@ namespace NugetForUnity.Ui /// public class NugetWindow : EditorWindow, ISerializationCallbackReceiver { - private const string ArrowTipUp = "\u2227"; - - private const string ArrowTipDown = "\u2228"; - - [CanBeNull] - private static GUIStyle cachedHeaderStyle; - - [CanBeNull] - private static GUIStyle cachedBackgroundStyle; - - [CanBeNull] - private static GUIStyle cachedFoldoutStyle; - - [CanBeNull] - private static GUIStyle cachedContrastStyle; - private readonly Dictionary foldouts = new Dictionary(); /// @@ -70,10 +54,14 @@ public class NugetWindow : EditorWindow, ISerializationCallbackReceiver /// private readonly HashSet selectedPackageUpdates = new HashSet(new NugetPackageIdEqualityComparer()); + private readonly GUIContent showDowngradesContent = new GUIContent("Show Downgrades"); + + private readonly GUIContent showPrereleaseContent = new GUIContent("Show Prerelease"); + /// /// The titles of the tabs in the window. /// - private readonly string[] tabTitles = { "Online", "Installed", "Updates" }; + private readonly GUIContent[] tabTitles = { new GUIContent("Online"), new GUIContent("Installed"), new GUIContent("Updates") }; /// /// For each package this contains the currently selected version / the state of the version drop-down. @@ -85,6 +73,8 @@ public class NugetWindow : EditorWindow, ISerializationCallbackReceiver /// private List availablePackages = new List(); + private readonly StringBuilder cachedStringBuilder = new StringBuilder(); + /// /// The currently selected tab in the window. /// @@ -109,7 +99,7 @@ public class NugetWindow : EditorWindow, ISerializationCallbackReceiver /// /// The search term to search the installed packages for. /// - private string installedSearchTerm = "Search"; + private string installedSearchTerm; [CanBeNull] private string lastInstalledSearchTerm; @@ -123,7 +113,7 @@ public class NugetWindow : EditorWindow, ISerializationCallbackReceiver /// /// The search term to search the online packages for. /// - private string onlineSearchTerm = "Search"; + private string onlineSearchTerm; /// /// The current position of the scroll bar in the GUI. @@ -149,6 +139,10 @@ public class NugetWindow : EditorWindow, ISerializationCallbackReceiver private bool showImplicitlyInstalled; + private bool showInstalled = true; + + private bool showOnlinePackages = true; + /// /// True to show beta and alpha package versions. False to only show stable versions. /// @@ -157,18 +151,13 @@ public class NugetWindow : EditorWindow, ISerializationCallbackReceiver /// /// True if packages selected for install should be displayed on Online tab, false if availablePackages should be displayed. /// - private bool showPackagesToInstall; + private bool showPackagesToInstall = true; /// /// True to show beta and alpha package versions. False to only show stable versions. /// private bool showPrereleaseUpdates; - /// - /// The current position of the scroll bar for packages selected for installation. - /// - private Vector2 toInstallScrollPosition; - /// /// The list of package updates available, based on the already installed packages. /// @@ -177,7 +166,7 @@ public class NugetWindow : EditorWindow, ISerializationCallbackReceiver /// /// The search term to search the update packages for. /// - private string updatesSearchTerm = "Search"; + private string updatesSearchTerm; /// /// Gets the filtered list of package updates available. @@ -187,7 +176,7 @@ private List FilteredUpdatePackages get { IEnumerable result; - if (string.IsNullOrWhiteSpace(updatesSearchTerm) || updatesSearchTerm == "Search") + if (string.IsNullOrWhiteSpace(updatesSearchTerm)) { result = updatePackages; } @@ -231,7 +220,7 @@ private List FilteredInstalledPackages } lastInstalledSearchTerm = installedSearchTerm; - if (string.IsNullOrWhiteSpace(installedSearchTerm) || installedSearchTerm == "Search") + if (string.IsNullOrWhiteSpace(installedSearchTerm)) { filteredInstalledPackages = InstalledPackagesManager.InstalledPackages.ToList(); } @@ -339,7 +328,16 @@ protected static void DisplayPreferences() /// protected void OnGUI() { - var selectedTab = (NugetWindowTab)GUILayout.Toolbar((int)currentTab, tabTitles); + EditorGUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); + var selectedTab = (NugetWindowTab)GUILayout.Toolbar( + (int)currentTab, + tabTitles, + null, + GUI.ToolbarButtonSize.FitToContents, + GUILayout.Height(25f)); + GUILayout.FlexibleSpace(); + EditorGUILayout.EndHorizontal(); if (selectedTab != currentTab) { @@ -364,137 +362,19 @@ protected void OnGUI() private static void GUILayoutLink(string url) { - var hyperLinkStyle = new GUIStyle(GUI.skin.label) { stretchWidth = false, richText = true }; - var colorFormatString = "{0}"; - - var underline = new string('_', url.Length); - - var formattedUrl = string.Format(CultureInfo.InvariantCulture, colorFormatString, url); - var formattedUnderline = string.Format(CultureInfo.InvariantCulture, colorFormatString, underline); - var urlRect = GUILayoutUtility.GetRect(new GUIContent(url), hyperLinkStyle); - - // Update rect for indentation - { - var indentedUrlRect = EditorGUI.IndentedRect(urlRect); - var delta = indentedUrlRect.x - urlRect.x; - indentedUrlRect.width += delta; - urlRect = indentedUrlRect; - } - - GUI.Label(urlRect, formattedUrl, hyperLinkStyle); - GUI.Label(urlRect, formattedUnderline, hyperLinkStyle); - - EditorGUIUtility.AddCursorRect(urlRect, MouseCursor.Link); - if (urlRect.Contains(Event.current.mousePosition)) - { - if (Event.current.type == EventType.MouseUp) - { - Application.OpenURL(url); - } - } - } - - /// - /// From here: http://forum.unity3d.com/threads/changing-the-background-color-for-beginhorizontal.66015/. - /// - /// The color to fill the texture with. - /// The generated texture. - private static Texture2D CreateSingleColorTexture(Color color) - { - const int width = 16; - const int height = 16; - var pix = new Color32[width * height]; - Color32 color32 = color; - for (var index = 0; index < pix.Length; index++) - { - pix[index] = color32; - } - - var result = new Texture2D(width, height); - result.SetPixels32(pix); - result.Apply(); - - return result; - } - - /// - /// Creates a GUI style with a contrasting background color based upon if the Unity Editor is the free (light) skin or the Pro (dark) skin. - /// - /// A GUI style with the appropriate background color set. - private static GUIStyle GetContrastStyle() - { - if (cachedContrastStyle != null) - { - return cachedContrastStyle; - } - - cachedContrastStyle = new GUIStyle(); - var backgroundColor = EditorGUIUtility.isProSkin ? new Color(0.3f, 0.3f, 0.3f) : new Color(0.6f, 0.6f, 0.6f); - cachedContrastStyle.normal.background = CreateSingleColorTexture(backgroundColor); - - return cachedContrastStyle; - } - - /// - /// Creates a GUI style with a background color the same as the editor's current background color. - /// - /// A GUI style with the appropriate background color set. - private static GUIStyle GetBackgroundStyle() - { - if (cachedBackgroundStyle != null) - { - return cachedBackgroundStyle; - } - - cachedBackgroundStyle = new GUIStyle(); - var backgroundColor = EditorGUIUtility.isProSkin ? new Color32(56, 56, 56, 255) : new Color32(194, 194, 194, 255); - cachedBackgroundStyle.normal.background = CreateSingleColorTexture(backgroundColor); - - return cachedBackgroundStyle; - } - - private static GUIStyle GetHeaderStyle() - { - if (cachedHeaderStyle != null) - { - return cachedHeaderStyle; - } - - cachedHeaderStyle = new GUIStyle(); - var backgroundColor = EditorGUIUtility.isProSkin ? new Color(0.1f, 0.1f, 0.1f) : new Color(0.4f, 0.4f, 0.4f); - cachedHeaderStyle.alignment = TextAnchor.MiddleLeft; - cachedHeaderStyle.normal.background = CreateSingleColorTexture(backgroundColor); - cachedHeaderStyle.normal.textColor = Color.white; + var rect = EditorGUILayout.GetControlRect(); + rect.yMin -= 2f; + rect.xMin += 30f; - return cachedHeaderStyle; - } - - private static GUIStyle GetFoldoutStyle() - { - if (cachedFoldoutStyle != null) + if (GUI.Button(rect, url, Styles.LinkLabelStyle)) { - return cachedFoldoutStyle; + Application.OpenURL(url); } - - cachedFoldoutStyle = new GUIStyle(EditorStyles.foldout) - { - focused = { textColor = Color.white }, - onFocused = { textColor = Color.white }, - active = { textColor = Color.white }, - onActive = { textColor = Color.white }, - alignment = TextAnchor.MiddleLeft, - }; - - return cachedFoldoutStyle; } private static void DrawNoDataAvailableInfo(string message) { - EditorStyles.label.fontStyle = FontStyle.Bold; - EditorStyles.label.fontSize = 14; - EditorGUILayout.LabelField(message, GUILayout.Height(20)); - EditorStyles.label.fontSize = 10; - EditorStyles.label.fontStyle = FontStyle.Normal; + EditorGUILayout.LabelField(message, Styles.BoldLabelStyle, GUILayout.Height(20)); } /// @@ -578,15 +458,14 @@ private void UpdateOnlinePackages() { var stopwatch = new Stopwatch(); stopwatch.Start(); - var searchTerm = onlineSearchTerm != "Search" ? onlineSearchTerm : string.Empty; // we just block the main thread - availablePackages = Task.Run(() => ConfigurationManager.SearchAsync(searchTerm, showOnlinePrerelease, numberToGet, numberToSkip)) + availablePackages = Task.Run(() => ConfigurationManager.SearchAsync(onlineSearchTerm, showOnlinePrerelease, numberToGet, numberToSkip)) .GetAwaiter() .GetResult(); NugetLogger.LogVerbose( "Searching '{0}' in all active package sources returned: {1} packages after {2} ms", - searchTerm, + onlineSearchTerm, availablePackages.Count, stopwatch.ElapsedMilliseconds); @@ -682,23 +561,28 @@ private void DrawInstalled() private void DrawPackagesSplittedByManuallyInstalled(List packages) { - var headerStyle = GetHeaderStyle(); - - var rectangle = EditorGUILayout.GetControlRect(true, 20f, headerStyle); - EditorGUI.LabelField(rectangle, " Installed packages", headerStyle); - if (packages.Exists(package => package.IsManuallyInstalled)) - { - DrawPackages(packages.Where(package => package.IsManuallyInstalled), true); - } - else + var foldoutRect = EditorGUILayout.GetControlRect(true, 20f).AddY(-1f); + EditorGUI.DrawRect(foldoutRect.Expand(2f), Styles.FoldoutHeaderColor); + EditorGUI.DrawRect(foldoutRect.ExpandX(2f).AddY(-2f).SetHeight(1f), Styles.LineColor); + EditorGUI.DrawRect(foldoutRect.ExpandX(2f).AddY(foldoutRect.height + 1f).SetHeight(1f), Styles.LineColor); + showInstalled = EditorGUI.Foldout(foldoutRect, showInstalled, "Installed packages", true); + if (showInstalled) { - DrawNoDataAvailableInfo("There are no explicitly installed packages."); + if (packages.Exists(package => package.IsManuallyInstalled)) + { + DrawPackages(packages.Where(package => package.IsManuallyInstalled), true); + } + else + { + DrawNoDataAvailableInfo("There are no explicitly installed packages."); + } } - rectangle = EditorGUILayout.GetControlRect(true, 20f, headerStyle); - EditorGUI.LabelField(rectangle, string.Empty, headerStyle); - - showImplicitlyInstalled = EditorGUI.Foldout(rectangle, showImplicitlyInstalled, "Implicitly installed packages", true, GetFoldoutStyle()); + foldoutRect = EditorGUILayout.GetControlRect(true, 20f); + EditorGUI.DrawRect(foldoutRect.Expand(2f), Styles.FoldoutHeaderColor); + EditorGUI.DrawRect(foldoutRect.ExpandX(2f).AddY(-2f).SetHeight(1f), Styles.LineColor); + EditorGUI.DrawRect(foldoutRect.ExpandX(2f).AddY(foldoutRect.height + 1f).SetHeight(1f), Styles.LineColor); + showImplicitlyInstalled = EditorGUI.Foldout(foldoutRect, showImplicitlyInstalled, "Implicitly installed packages", true); if (showImplicitlyInstalled) { DrawPackages(packages.Where(package => !package.IsManuallyInstalled), true); @@ -711,88 +595,84 @@ private void DrawPackagesSplittedByManuallyInstalled(List package private void DrawOnline() { DrawOnlineHeader(); - var headerStyle = GetHeaderStyle(); - - if (selectedPackageInstalls.Count > 0) - { - DrawSelectedForInstallationHeader(headerStyle); - } // display all of the packages scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition); EditorGUILayout.BeginVertical(); - IEnumerable packagesToShow; - - if (selectedPackageInstalls.Count > 0 && showPackagesToInstall) - { - packagesToShow = availablePackages.Where(p => selectedPackageInstalls.Contains(p)); - } - else + if (selectedPackageInstalls.Count > 0) { - packagesToShow = availablePackages.Where(p => !selectedPackageInstalls.Contains(p)); + DrawSelectedForInstallationHeader(); + if (showPackagesToInstall) + { + DrawPackages(availablePackages.Where(p => selectedPackageInstalls.Contains(p)), true); + } } - DrawPackages(packagesToShow, true); - // If user deselected all the packages revert to showing available packages if (selectedPackageInstalls.Count == 0) { - showPackagesToInstall = false; + showOnlinePackages = true; } - var showMoreStyle = GetHeaderStyle(); - EditorGUILayout.BeginVertical(showMoreStyle); + if (selectedPackageInstalls.Count > 0) + { + var foldoutRect = EditorGUILayout.GetControlRect(false, 22f); + EditorGUI.DrawRect(foldoutRect.Expand(2f), Styles.FoldoutHeaderColor); + EditorGUI.DrawRect(foldoutRect.ExpandX(2f).AddY(-2f).SetHeight(1f), Styles.LineColor); + EditorGUI.DrawRect(foldoutRect.ExpandX(2f).AddY(foldoutRect.height + 1f).SetHeight(1f), Styles.LineColor); + showOnlinePackages = EditorGUI.Foldout(foldoutRect, showOnlinePackages, "Online packages", true); + } - if (showPackagesToInstall) + if (showOnlinePackages) { - var arrow = !showPackagesToInstall ? ArrowTipUp : ArrowTipDown; - if (GUILayout.Button($" {arrow} Online packages", headerStyle, GUILayout.Height(25f))) - { - showPackagesToInstall = !showPackagesToInstall; - } + DrawPackages(availablePackages.Where(p => !selectedPackageInstalls.Contains(p)), true); } + GUILayout.Space(3f); + // allow the user to display more results - if (!showPackagesToInstall && GUILayout.Button("Show More", GUILayout.Width(120))) + using (new EditorGUILayout.HorizontalScope()) { - numberToSkip += numberToGet; - availablePackages.AddRange( - Task.Run( - () => ConfigurationManager.SearchAsync( - onlineSearchTerm != "Search" ? onlineSearchTerm : string.Empty, - showOnlinePrerelease, - numberToGet, - numberToSkip)) - .GetAwaiter() - .GetResult()); + GUILayout.FlexibleSpace(); + if (showOnlinePackages && GUILayout.Button("Show More", GUILayout.Width(120))) + { + numberToSkip += numberToGet; + availablePackages.AddRange( + Task.Run(() => ConfigurationManager.SearchAsync(onlineSearchTerm, showOnlinePrerelease, numberToGet, numberToSkip)) + .GetAwaiter() + .GetResult()); + } + + GUILayout.FlexibleSpace(); } - EditorGUILayout.EndVertical(); + GUILayout.Space(4f); EditorGUILayout.EndVertical(); EditorGUILayout.EndScrollView(); } - private void DrawSelectedForInstallationHeader(GUIStyle headerStyle) + private void DrawSelectedForInstallationHeader() { - var rectangle = GUILayoutUtility.GetRect(GUIContent.none, headerStyle, GUILayout.Height(25f)); - - EditorGUI.LabelField(rectangle, string.Empty, headerStyle); - - var arrow = showPackagesToInstall ? ArrowTipUp : ArrowTipDown; - rectangle.width -= 150f; - if (GUI.Button(rectangle, $" {arrow} Selected for installation: {selectedPackageInstalls.Count}", headerStyle)) - { - showPackagesToInstall = !showPackagesToInstall; - } - - rectangle.x += rectangle.width; - rectangle.width = 148f; - rectangle.y += 2f; - rectangle.height -= 6f; - - if (GUI.Button(rectangle, "Install All Selected")) + var foldoutRect = EditorGUILayout.GetControlRect(false, 22f).AddY(-1f); + + EditorGUI.DrawRect(foldoutRect.Expand(2f), Styles.FoldoutHeaderColor); + EditorGUI.DrawRect(foldoutRect.ExpandX(2f).AddY(-2f).SetHeight(1f), Styles.LineColor); + EditorGUI.DrawRect(foldoutRect.ExpandX(2f).AddY(foldoutRect.height + 1f).SetHeight(1f), Styles.LineColor); + foldoutRect.width -= 150f; + showPackagesToInstall = EditorGUI.Foldout( + foldoutRect, + showPackagesToInstall, + $"Selected for installation: {selectedPackageInstalls.Count}", + true); + + foldoutRect.x += foldoutRect.width; + foldoutRect.width = 148f; + foldoutRect.y += 2f; + foldoutRect.height -= 4f; + + if (GUI.Button(foldoutRect, "Install All Selected")) { foreach (var package in selectedPackageInstalls) { @@ -806,31 +686,18 @@ private void DrawSelectedForInstallationHeader(GUIStyle headerStyle) UpdateInstalledPackages(); UpdateUpdatePackages(); } - - if (!showPackagesToInstall) - { - arrow = !showPackagesToInstall ? ArrowTipUp : ArrowTipDown; - if (GUILayout.Button($" {arrow} Online packages", headerStyle, GUILayout.Height(25f))) - { - showPackagesToInstall = !showPackagesToInstall; - } - } } private void DrawPackages(IEnumerable packages, bool canBeSelected = false) { - var backgroundStyle = GetBackgroundStyle(); - var contrastStyle = GetContrastStyle(); + var backgroundStyle = Styles.BackgroundStyle; foreach (var package in packages) { using (new EditorGUILayout.VerticalScope(backgroundStyle)) { - DrawPackage(package, backgroundStyle, contrastStyle, canBeSelected); + DrawPackage(package, backgroundStyle, canBeSelected); } - - // swap styles - (backgroundStyle, contrastStyle) = (contrastStyle, backgroundStyle); } } @@ -839,59 +706,53 @@ private void DrawPackages(IEnumerable packages, bool canBeSelecte /// private void DrawOnlineHeader() { - var headerStyle = GetHeaderStyle(); - - EditorGUILayout.BeginVertical(headerStyle); + using (new EditorGUILayout.VerticalScope(Styles.BackgroundStyle)) { - EditorGUILayout.BeginHorizontal(); + using (new EditorGUILayout.HorizontalScope(EditorStyles.toolbar)) { - var showPrereleaseTemp = EditorGUILayout.Toggle("Show Prerelease", showOnlinePrerelease); + var showPrereleaseTemp = GUILayout.Toggle( + showOnlinePrerelease, + showPrereleaseContent, + EditorStyles.toolbarButton, + GUILayout.Width(120f)); if (showPrereleaseTemp != showOnlinePrerelease) { showOnlinePrerelease = showPrereleaseTemp; UpdateOnlinePackages(); } + GUILayout.FlexibleSpace(); DrawSelectFromClipboardButton(); DrawMandatoryButtons(); } - EditorGUILayout.EndHorizontal(); - - var enterPressed = Event.current.Equals(Event.KeyboardEvent("return")); - - EditorGUILayout.BeginHorizontal(); + using (new EditorGUILayout.HorizontalScope(Styles.ToolbarStyle)) { - var oldFontSize = GUI.skin.textField.fontSize; - GUI.skin.textField.fontSize = 25; - onlineSearchTerm = EditorGUILayout.TextField(onlineSearchTerm, GUILayout.Height(30)); + var enterPressed = Event.current.Equals(Event.KeyboardEvent("return")); - if (GUILayout.Button("Search", GUILayout.Width(100), GUILayout.Height(28))) + // draw search field + onlineSearchTerm = EditorGUILayout.TextField(onlineSearchTerm, Styles.SearchFieldStyle, GUILayout.Height(20)); + + if (GUILayout.Button("Search", GUILayout.Width(100), GUILayout.Height(20))) { // the search button emulates the Enter key enterPressed = true; } - GUI.skin.textField.fontSize = oldFontSize; - } - - EditorGUILayout.EndHorizontal(); - - // search only if the enter key is pressed - if (enterPressed) - { - // reset the number to skip - numberToSkip = 0; - UpdateOnlinePackages(); + // search only if the enter key is pressed + if (enterPressed) + { + // reset the number to skip + numberToSkip = 0; + UpdateOnlinePackages(); + } } } - - EditorGUILayout.EndVertical(); } private void DrawSelectFromClipboardButton() { - if (GUILayout.Button("Select all from clipboard", GUILayout.Width(170f))) + if (GUILayout.Button("Select all from clipboard", EditorStyles.toolbarButton, GUILayout.Width(170f))) { var packageIds = GUIUtility.systemCopyBuffer.Split('\n', ',').Select(p => p.Trim()).ToList(); try @@ -934,17 +795,15 @@ private void DrawSelectFromClipboardButton() /// private void DrawInstalledHeader() { - var headerStyle = GetHeaderStyle(); - - EditorGUILayout.BeginVertical(headerStyle); + using (new EditorGUILayout.VerticalScope(Styles.HeaderStyle)) { - EditorGUILayout.BeginHorizontal(); + using (new EditorGUILayout.HorizontalScope(EditorStyles.toolbar)) { GUILayout.FlexibleSpace(); if (InstalledPackagesManager.InstalledPackages.Any()) { - if (GUILayout.Button("Uninstall All", GUILayout.Width(100))) + if (GUILayout.Button("Uninstall All", EditorStyles.toolbarButton, GUILayout.Width(100))) { NugetPackageUninstaller.UninstallAll(); UpdateInstalledPackages(); @@ -954,7 +813,7 @@ private void DrawInstalledHeader() if (selectedPackageUninstalls.Count > 0) { - if (GUILayout.Button("Uninstall Selected", GUILayout.Width(120))) + if (GUILayout.Button("Uninstall Selected", EditorStyles.toolbarButton, GUILayout.Width(120))) { NugetPackageUninstaller.UninstallAll(selectedPackageUninstalls.ToList()); UpdateInstalledPackages(); @@ -965,21 +824,11 @@ private void DrawInstalledHeader() DrawMandatoryButtons(); } - EditorGUILayout.EndHorizontal(); - - EditorGUILayout.BeginHorizontal(); + using (new EditorGUILayout.HorizontalScope(Styles.ToolbarStyle)) { - var oldFontSize = GUI.skin.textField.fontSize; - GUI.skin.textField.fontSize = 25; - installedSearchTerm = EditorGUILayout.TextField(installedSearchTerm, GUILayout.Height(30)); - - GUI.skin.textField.fontSize = oldFontSize; + installedSearchTerm = EditorGUILayout.TextField(installedSearchTerm, Styles.SearchFieldStyle, GUILayout.Height(20)); } - - EditorGUILayout.EndHorizontal(); } - - EditorGUILayout.EndVertical(); } /// @@ -987,34 +836,37 @@ private void DrawInstalledHeader() /// private void DrawUpdatesHeader() { - var headerStyle = GetHeaderStyle(); - - EditorGUILayout.BeginVertical(headerStyle); + using (new EditorGUILayout.VerticalScope(Styles.HeaderStyle)) { - EditorGUILayout.BeginHorizontal(); + using (new EditorGUILayout.HorizontalScope(EditorStyles.toolbar)) { - EditorGUILayout.BeginVertical(); + var showPrereleaseTemp = GUILayout.Toggle( + showPrereleaseUpdates, + showPrereleaseContent, + EditorStyles.toolbarButton, + GUILayout.Width(120f)); + if (showPrereleaseTemp != showPrereleaseUpdates) { - var showPrereleaseTemp = EditorGUILayout.Toggle("Show Prerelease", showPrereleaseUpdates); - if (showPrereleaseTemp != showPrereleaseUpdates) - { - showPrereleaseUpdates = showPrereleaseTemp; - UpdateUpdatePackages(); - } + showPrereleaseUpdates = showPrereleaseTemp; + UpdateUpdatePackages(); + } - var showDowngradesTemp = EditorGUILayout.Toggle("Show Downgrades", showDowngrades); - if (showDowngradesTemp != showDowngrades) - { - versionDropdownDataPerPackage.Clear(); - showDowngrades = showDowngradesTemp; - } + var showDowngradesTemp = GUILayout.Toggle( + showDowngrades, + showDowngradesContent, + EditorStyles.toolbarButton, + GUILayout.Width(120f)); + if (showDowngradesTemp != showDowngrades) + { + versionDropdownDataPerPackage.Clear(); + showDowngrades = showDowngradesTemp; } - EditorGUILayout.EndVertical(); + GUILayout.FlexibleSpace(); if (updatePackages.Count > 0) { - if (!showDowngrades && GUILayout.Button("Update All", GUILayout.Width(100))) + if (!showDowngrades && GUILayout.Button("Update All", EditorStyles.toolbarButton, GUILayout.Width(100))) { NugetPackageUpdater.UpdateAll(updatePackages, InstalledPackagesManager.InstalledPackages); UpdateInstalledPackages(); @@ -1024,7 +876,10 @@ private void DrawUpdatesHeader() var workingSelections = SelectedPackages; if (workingSelections.Count > 0) { - if (GUILayout.Button(showDowngrades ? "Downgrade Selected" : "Update Selected", GUILayout.Width(120))) + if (GUILayout.Button( + showDowngrades ? "Downgrade Selected" : "Update Selected", + EditorStyles.toolbarButton, + GUILayout.Width(120))) { NugetPackageUpdater.UpdateAll(workingSelections, InstalledPackagesManager.InstalledPackages); UpdateInstalledPackages(); @@ -1036,21 +891,11 @@ private void DrawUpdatesHeader() DrawMandatoryButtons(); } - EditorGUILayout.EndHorizontal(); - - EditorGUILayout.BeginHorizontal(); + using (new EditorGUILayout.HorizontalScope(Styles.ToolbarStyle)) { - var oldFontSize = GUI.skin.textField.fontSize; - GUI.skin.textField.fontSize = 25; - updatesSearchTerm = EditorGUILayout.TextField(updatesSearchTerm, GUILayout.Height(30)); - - GUI.skin.textField.fontSize = oldFontSize; + updatesSearchTerm = EditorGUILayout.TextField(updatesSearchTerm, Styles.SearchFieldStyle, GUILayout.Height(20)); } - - EditorGUILayout.EndHorizontal(); } - - EditorGUILayout.EndVertical(); } /// @@ -1058,12 +903,12 @@ private void DrawUpdatesHeader() /// private void DrawMandatoryButtons() { - if (GUILayout.Button("Refresh", GUILayout.Width(60))) + if (GUILayout.Button("Refresh", EditorStyles.toolbarButton, GUILayout.Width(60))) { Refresh(true); } - if (GUILayout.Button("Preferences", GUILayout.Width(80))) + if (GUILayout.Button("Preferences", EditorStyles.toolbarButton, GUILayout.Width(80))) { SettingsService.OpenUserPreferences("Preferences/NuGet For Unity"); GetWindow().Close(); @@ -1074,17 +919,20 @@ private void DrawMandatoryButtons() /// Draws the given . /// /// The to draw. - /// The normal style of the package section. - /// The contrast style of the package section. + /// The normal style of the package section. /// If a check-box should be shown. - private void DrawPackage(INugetPackage package, GUIStyle packageStyle, GUIStyle contrastStyle, bool canBeSelected = false) + private void DrawPackage(INugetPackage package, GUIStyle backgroundStyle, bool canBeSelected = false) { var installedPackages = InstalledPackagesManager.InstalledPackages; var installed = installedPackages.FirstOrDefault(p => p.Id.Equals(package.Id, StringComparison.OrdinalIgnoreCase)); var isAlreadyImportedInEngine = UnityPreImportedLibraryResolver.IsAlreadyImportedInEngine(package.Id, false); + GUILayout.Space(7f); + using (new EditorGUILayout.HorizontalScope()) { + GUILayout.Space(7f); + // The Unity GUI system (in the Editor) is terrible. This probably requires some explanation. // Every time you use a Horizontal block, Unity appears to divide the space evenly. // (i.e. 2 components have half of the window width, 3 components have a third of the window width, etc) @@ -1093,7 +941,7 @@ private void DrawPackage(INugetPackage package, GUIStyle packageStyle, GUIStyle using (new EditorGUILayout.HorizontalScope()) { const int iconSize = 32; - var paddingX = Math.Max(EditorStyles.label.padding.horizontal, 3); + var paddingX = 5f; var rect = GUILayoutUtility.GetRect(0, iconSize); rect.y += Math.Max(EditorStyles.label.padding.vertical, 3); if (canBeSelected) @@ -1146,30 +994,10 @@ private void DrawPackage(INugetPackage package, GUIStyle packageStyle, GUIStyle // text is allowed to get the half of the available space rest is for buttons and version label rect.width = (position.width - rect.x) / 2; - EditorStyles.label.fontStyle = FontStyle.Bold; - EditorStyles.label.fontSize = 16; - - var idSize = EditorStyles.label.CalcSize(new GUIContent(package.Id)); - GUI.Label(rect, package.Id, EditorStyles.label); + var labelStyle = Styles.PackageNameLabelStyle; + var idSize = labelStyle.CalcSize(new GUIContent(package.Id)); + GUI.Label(rect, package.Id, labelStyle); rect.x += Mathf.Min(idSize.x, rect.width) + paddingX; - - EditorStyles.label.fontSize = 10; - EditorStyles.label.fontStyle = FontStyle.Normal; - rect.y += EditorStyles.label.fontSize / 2f; - - if (package.Authors.Count > 0) - { - var authorLabel = $"by {string.Join(", ", package.Authors)}"; - var size = EditorStyles.label.CalcSize(new GUIContent(authorLabel)); - GUI.Label(rect, authorLabel, EditorStyles.label); - rect.x += size.x + paddingX; - } - - if (package.TotalDownloads > 0) - { - var downloadLabel = $"{package.TotalDownloads:#,#} downloads"; - GUI.Label(rect, downloadLabel, EditorStyles.label); - } } GUILayout.FlexibleSpace(); @@ -1182,9 +1010,7 @@ private void DrawPackage(INugetPackage package, GUIStyle packageStyle, GUIStyle // Show the version selection dropdown only on Updates tab OR on Online tab if the package is not installed and not already in Unity if (currentTab == NugetWindowTab.UpdatesTab || - (currentTab == NugetWindowTab.OnlineTab && - installed == null && - !isAlreadyImportedInEngine)) + (currentTab == NugetWindowTab.OnlineTab && installed == null && !isAlreadyImportedInEngine)) { if (package.Versions.Count <= 1) { @@ -1290,14 +1116,36 @@ private void DrawPackage(INugetPackage package, GUIStyle packageStyle, GUIStyle } } - EditorGUILayout.Space(); + // authors + { + var rect = EditorGUILayout.GetControlRect().AddX(10f); + var labelStyle = Styles.AuthorsLabelStyle; + + rect.y += labelStyle.fontSize / 2f; + + if (package.Authors.Count > 0) + { + var authorLabel = $"by {string.Join(", ", package.Authors)}"; + var size = labelStyle.CalcSize(new GUIContent(authorLabel)); + GUI.Label(rect, authorLabel, labelStyle); + rect.x += size.x; + } + + if (package.TotalDownloads > 0) + { + var downloadLabel = $"{package.TotalDownloads:#,#} downloads"; + GUI.Label(rect, downloadLabel, labelStyle); + } + } + + GUILayout.Space(7f); + using (new EditorGUILayout.HorizontalScope()) { using (new EditorGUILayout.VerticalScope()) { // Show the package details - EditorStyles.label.wordWrap = true; - EditorStyles.label.fontStyle = FontStyle.Normal; + var labelStyle = Styles.DescriptionLabelStyle; var summary = package.Summary; if (string.IsNullOrEmpty(summary)) @@ -1315,7 +1163,11 @@ private void DrawPackage(INugetPackage package, GUIStyle packageStyle, GUIStyle summary = $"{summary.Substring(0, 237)}..."; } - EditorGUILayout.LabelField(summary); + var summaryRect = EditorGUILayout.GetControlRect( + true, + labelStyle.CalcHeight(new GUIContent(summary), EditorGUIUtility.currentViewWidth - 20f) + 5f) + .AddX(10f); + EditorGUI.LabelField(summaryRect, summary, labelStyle); var detailsFoldoutId = $"{package.Id}.Details"; if (!foldouts.TryGetValue(detailsFoldoutId, out var detailsFoldout)) @@ -1323,28 +1175,37 @@ private void DrawPackage(INugetPackage package, GUIStyle packageStyle, GUIStyle foldouts[detailsFoldoutId] = detailsFoldout; } - detailsFoldout = EditorGUILayout.Foldout(detailsFoldout, "Details"); + GUILayout.Space(2f); + + var detailsFoldoutRect = EditorGUILayout.GetControlRect().AddX(10f); + detailsFoldout = EditorGUI.Foldout(detailsFoldoutRect, detailsFoldout, "Details", true); foldouts[detailsFoldoutId] = detailsFoldout; if (detailsFoldout) { - EditorGUI.indentLevel++; + EditorGUI.indentLevel += 2; if (!string.IsNullOrEmpty(package.Description)) { EditorGUILayout.LabelField("Description", EditorStyles.boldLabel); - EditorGUILayout.LabelField(package.Description); + var descriptionContent = new GUIContent(package.Description); + var descriptionRect = EditorGUILayout.GetControlRect( + true, + labelStyle.CalcHeight(descriptionContent, EditorGUIUtility.currentViewWidth - 20f) + 12f); + EditorGUI.LabelField(descriptionRect, descriptionContent, labelStyle); + GUILayout.Space(4f); } if (!string.IsNullOrEmpty(package.ReleaseNotes)) { EditorGUILayout.LabelField("Release Notes", EditorStyles.boldLabel); EditorGUILayout.LabelField(package.ReleaseNotes); + GUILayout.Space(4f); } // Show project URL link if (!string.IsNullOrEmpty(package.ProjectUrl)) { - EditorGUILayout.LabelField("Project Url", EditorStyles.boldLabel); + EditorGUILayout.LabelField("Project URL", EditorStyles.boldLabel); GUILayoutLink(package.ProjectUrl); GUILayout.Space(4f); } @@ -1355,23 +1216,21 @@ private void DrawPackage(INugetPackage package, GUIStyle packageStyle, GUIStyle var frameworkDependencies = package.CurrentFrameworkDependencies; if (frameworkDependencies.Count > 0) { - EditorStyles.label.wordWrap = true; - EditorStyles.label.fontStyle = FontStyle.Italic; - var builder = new StringBuilder(); + EditorGUILayout.LabelField("Dependencies", EditorStyles.boldLabel); + labelStyle.fontStyle = FontStyle.Italic; + cachedStringBuilder.Clear(); foreach (var dependency in frameworkDependencies) { - builder.Append($" {dependency.Id} {dependency.Version};"); + cachedStringBuilder.AppendLine($"{dependency.Id} {dependency.Version}"); } - EditorGUILayout.Space(); - EditorGUILayout.LabelField($"Depends on:{builder}"); - EditorStyles.label.fontStyle = FontStyle.Normal; + EditorGUILayout.LabelField(cachedStringBuilder.ToString(), labelStyle); + labelStyle.fontStyle = FontStyle.Normal; } } else { - EditorGUILayout.Space(); EditorGUILayout.LabelField("Loading dependencies..."); } @@ -1379,124 +1238,122 @@ private void DrawPackage(INugetPackage package, GUIStyle packageStyle, GUIStyle var cloneButtonBoxStyle = new GUIStyle("box") { stretchWidth = false, margin = { top = 0, bottom = 0 }, padding = { bottom = 4 } }; - var normalButtonBoxStyle = new GUIStyle(cloneButtonBoxStyle) { normal = { background = packageStyle.normal.background } }; + var normalButtonBoxStyle = new GUIStyle(cloneButtonBoxStyle) { normal = { background = backgroundStyle.normal.background } }; var showCloneWindow = openCloneWindows.Contains(package); - cloneButtonBoxStyle.normal.background = showCloneWindow ? contrastStyle.normal.background : packageStyle.normal.background; + cloneButtonBoxStyle.normal.background = backgroundStyle.normal.background; // Create a similar style for the 'Clone' window var cloneWindowStyle = new GUIStyle(cloneButtonBoxStyle) { padding = new RectOffset(6, 6, 2, 6) }; - // Show button bar - using (new EditorGUILayout.HorizontalScope()) + if (package.RepositoryType == RepositoryType.Git || package.RepositoryType == RepositoryType.TfsGit) { - if (package.RepositoryType == RepositoryType.Git || package.RepositoryType == RepositoryType.TfsGit) + if (!string.IsNullOrEmpty(package.RepositoryUrl)) { - if (!string.IsNullOrEmpty(package.RepositoryUrl)) + var buttonRect = EditorGUILayout.GetControlRect(); + buttonRect.width = 116f; + buttonRect.xMin += 31f; + + // Show the clone button + if (GUI.Button(buttonRect, "Clone")) { - using (new EditorGUILayout.HorizontalScope()) - { - var cloneButtonStyle = new GUIStyle(GUI.skin.button); - cloneButtonStyle.normal = showCloneWindow ? cloneButtonStyle.active : cloneButtonStyle.normal; - if (GUILayout.Button("Clone", cloneButtonStyle, GUILayout.ExpandWidth(false))) - { - showCloneWindow = !showCloneWindow; - } + showCloneWindow = !showCloneWindow; + } - if (showCloneWindow) - { - openCloneWindows.Add(package); - } - else - { - openCloneWindows.Remove(package); - } - } + if (showCloneWindow) + { + openCloneWindows.Add(package); + } + else + { + openCloneWindows.Remove(package); } } + } - if (!string.IsNullOrEmpty(package.LicenseUrl) && package.LicenseUrl != "http://your_license_url_here") + if (!string.IsNullOrEmpty(package.LicenseUrl) && package.LicenseUrl != "http://your_license_url_here") + { + var buttonRect = EditorGUILayout.GetControlRect(); + buttonRect.width = 116f; + buttonRect.xMin += 31f; + + // Show the license button + if (GUI.Button(buttonRect, "View License")) { - // Create a box around the license button to keep it aligned with Clone button - using (new EditorGUILayout.HorizontalScope(normalButtonBoxStyle)) - { - // Show the license button - if (GUILayout.Button("View License", GUILayout.ExpandWidth(false))) - { - Application.OpenURL(package.LicenseUrl); - } - } + Application.OpenURL(package.LicenseUrl); } } if (showCloneWindow) { - using (new EditorGUILayout.VerticalScope(cloneWindowStyle)) + var oldIndent = EditorGUI.indentLevel; + EditorGUI.indentLevel = 0; + + using (new EditorGUILayout.HorizontalScope()) { - // Clone latest label - using (new EditorGUILayout.HorizontalScope()) + GUILayout.Space(23f); + using (new EditorGUILayout.VerticalScope(cloneWindowStyle)) { - GUILayout.Space(20f); + // Clone latest label EditorGUILayout.LabelField("clone latest"); - } - // Clone latest row - using (new EditorGUILayout.HorizontalScope()) - { - if (GUILayout.Button("Copy", GUILayout.ExpandWidth(false))) + // Clone latest row + using (new EditorGUILayout.HorizontalScope()) { - GUI.FocusControl(package.Id + package.Version + "repoUrl"); - GUIUtility.systemCopyBuffer = package.RepositoryUrl; - } + if (GUILayout.Button("Copy", GUILayout.ExpandWidth(false))) + { + GUI.FocusControl(package.Id + package.Version + "repoUrl"); + GUIUtility.systemCopyBuffer = package.RepositoryUrl; + } - GUI.SetNextControlName(package.Id + package.Version + "repoUrl"); - EditorGUILayout.TextField(package.RepositoryUrl); - } + GUI.SetNextControlName(package.Id + package.Version + "repoUrl"); + EditorGUILayout.TextField(package.RepositoryUrl); + } - // Clone @ commit label - GUILayout.Space(4f); - using (new EditorGUILayout.HorizontalScope()) - { - GUILayout.Space(20f); + // Clone @ commit label + GUILayout.Space(4f); EditorGUILayout.LabelField("clone @ commit"); - } - // Clone @ commit row - using (new EditorGUILayout.HorizontalScope()) - { - // Create the three commands a user will need to run to get the repo @ the commit. Intentionally leave off the last newline for better UI appearance - var commands = string.Format( - CultureInfo.InvariantCulture, - "git clone {0} {1} --no-checkout{2}cd {1}{2}git checkout {3}", - package.RepositoryUrl, - package.Id, - Environment.NewLine, - package.RepositoryCommit); - - if (GUILayout.Button("Copy", GUILayout.ExpandWidth(false))) + // Clone @ commit row + using (new EditorGUILayout.HorizontalScope()) { - GUI.FocusControl(package.Id + package.Version + "commands"); + // Create the three commands a user will need to run to get the repo @ the commit. Intentionally leave off the last newline for better UI appearance + var commands = string.Format( + CultureInfo.InvariantCulture, + "git clone {0} {1} --no-checkout{2}cd {1}{2}git checkout {3}", + package.RepositoryUrl, + package.Id, + Environment.NewLine, + package.RepositoryCommit); + + if (GUILayout.Button("Copy", GUILayout.ExpandWidth(false))) + { + GUI.FocusControl(package.Id + package.Version + "commands"); - // Add a newline so the last command will execute when pasted to the CL - GUIUtility.systemCopyBuffer = commands + Environment.NewLine; - } + // Add a newline so the last command will execute when pasted to the CL + GUIUtility.systemCopyBuffer = commands + Environment.NewLine; + } - using (new EditorGUILayout.VerticalScope()) - { - GUI.SetNextControlName(package.Id + package.Version + "commands"); - EditorGUILayout.TextArea(commands); + using (new EditorGUILayout.VerticalScope()) + { + GUI.SetNextControlName(package.Id + package.Version + "commands"); + EditorGUILayout.TextArea(commands); + } } } } + + EditorGUI.indentLevel = oldIndent; } - EditorGUI.indentLevel--; + EditorGUI.indentLevel -= 2; } - EditorGUILayout.Separator(); - EditorGUILayout.Separator(); + EditorGUILayout.Space(); } } + + EditorGUI.DrawRect(EditorGUILayout.GetControlRect(false, 1f), Styles.LineColor); } private sealed class VersionDropdownData diff --git a/src/NuGetForUnity/Editor/Ui/RectHelper.cs b/src/NuGetForUnity/Editor/Ui/RectHelper.cs new file mode 100644 index 00000000..3f603c0c --- /dev/null +++ b/src/NuGetForUnity/Editor/Ui/RectHelper.cs @@ -0,0 +1,99 @@ +using UnityEngine; + +namespace NugetForUnity +{ + /// + /// Extension methods for manipulating Rect objects. + /// + internal static class RectHelper + { + /// + /// Expands the boundaries of the Rect by a specified value in all directions. + /// + /// The rect to update. + /// The value to add. + /// The updated Rect. + public static Rect Expand(this Rect rect, float value) + { + rect.xMin -= value; + rect.xMax += value; + rect.yMin -= value; + rect.yMax += value; + return rect; + } + + /// + /// Expands the Rect horizontally by a specified value. + /// + /// The rect to update. + /// The value to add. + /// The updated Rect. + public static Rect ExpandX(this Rect rect, float value) + { + rect.xMin -= value; + rect.xMax += value; + return rect; + } + + /// + /// Expands the Rect vertically by a specified value. + /// + /// The rect to update. + /// The value to add. + /// The updated Rect. + public static Rect ExpandY(this Rect rect, float value) + { + rect.yMin -= value; + rect.yMax += value; + return rect; + } + + /// + /// Adds a specified value to the X-coordinate of the Rect. + /// + /// The rect to update. + /// The value to add. + /// The updated Rect. + public static Rect AddX(this Rect rect, float value) + { + rect.x += value; + return rect; + } + + /// + /// Adds a specified value to the Y-coordinate of the Rect. + /// + /// The rect to update. + /// The value to add. + /// The updated Rect. + public static Rect AddY(this Rect rect, float value) + { + rect.y += value; + return rect; + } + + /// + /// Sets the width of the Rect to a specified value. + /// + /// The rect to update. + /// The value to set. + /// The updated Rect. + public static Rect SetWidth(this Rect rect, float value) + { + rect.width = value; + return rect; + } + + /// + /// Sets the height of the Rect to a specified value. + /// + /// The rect to update. + /// The value to set. + /// The updated Rect. + public static Rect SetHeight(this Rect rect, float value) + { + rect.height = value; + return rect; + } + } +} diff --git a/src/NuGetForUnity/Editor/Ui/RectHelper.cs.meta b/src/NuGetForUnity/Editor/Ui/RectHelper.cs.meta new file mode 100644 index 00000000..018ca6ab --- /dev/null +++ b/src/NuGetForUnity/Editor/Ui/RectHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 73c0f3296afeb46a0b82c2fd75d2eabb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/NuGetForUnity/Editor/Ui/Styles.cs b/src/NuGetForUnity/Editor/Ui/Styles.cs new file mode 100644 index 00000000..7651a4e3 --- /dev/null +++ b/src/NuGetForUnity/Editor/Ui/Styles.cs @@ -0,0 +1,293 @@ +using UnityEditor; +using UnityEngine; + +namespace NugetForUnity.Ui +{ + /// + /// Collection of GUIStyle. + /// + internal static class Styles + { + private static GUIStyle cachedSearchFieldStyle; + + private static GUIStyle cachedHeaderStyle; + + private static GUIStyle cachedToolbarStyle; + + private static GUIStyle cachedBackgroundStyle; + + private static GUIStyle cachedBoldLabelStyle; + + private static GUIStyle cachedAuthorsLabelStyle; + + private static GUIStyle cachedDescriptionLabelStyle; + + private static GUIStyle cachedLinkLabelStyle; + + private static GUIStyle cachedPackageNameLabelStyle; + + /// + /// Gets the color used for lines used as seperators. + /// + public static Color LineColor + { + get + { + if (EditorGUIUtility.isProSkin) + { + return new Color(0.05f, 0.05f, 0.05f); + } + + return new Color(0.6f, 0.6f, 0.6f); + } + } + + /// + /// Gets the color used for package authors. + /// + public static Color AuthorsTextColor + { + get + { + if (EditorGUIUtility.isProSkin) + { + return new Color(0.55f, 0.55f, 0.55f); + } + + return new Color(0.45f, 0.45f, 0.45f); + } + } + + /// + /// Gets the color used for the foldout header. + /// + public static Color FoldoutHeaderColor + { + get + { + if (EditorGUIUtility.isProSkin) + { + return new Color(0.2f, 0.2f, 0.2f); + } + + return new Color(0.85f, 0.85f, 0.85f); + } + } + + /// + /// Gets a GUI style with a background color the same as the editor's current background color. + /// + public static GUIStyle BackgroundStyle + { + get + { + if (cachedBackgroundStyle != null) + { + return cachedBackgroundStyle; + } + + cachedBackgroundStyle = new GUIStyle(); + var backgroundColor = EditorGUIUtility.isProSkin ? new Color32(56, 56, 56, 255) : new Color32(194, 194, 194, 255); + cachedBackgroundStyle.normal.background = CreateSingleColorTexture(backgroundColor); + + return cachedBackgroundStyle; + } + } + + /// + /// Gets the GUI style used for the header of the NuGet window. + /// + public static GUIStyle HeaderStyle + { + get + { + if (cachedHeaderStyle != null) + { + return cachedHeaderStyle; + } + + cachedHeaderStyle = new GUIStyle(); + var backgroundColor = EditorGUIUtility.isProSkin ? new Color(0.1f, 0.1f, 0.1f) : new Color(0.4f, 0.4f, 0.4f); + cachedHeaderStyle.alignment = TextAnchor.MiddleLeft; + cachedHeaderStyle.normal.background = CreateSingleColorTexture(backgroundColor); + cachedHeaderStyle.normal.textColor = Color.white; + + return cachedHeaderStyle; + } + } + + /// + /// Gets the GUI style used for the toolbar of the NuGet window. + /// + public static GUIStyle ToolbarStyle + { + get + { + if (cachedToolbarStyle != null) + { + return cachedToolbarStyle; + } + + cachedToolbarStyle = new GUIStyle(EditorStyles.toolbar) { fixedHeight = 25f }; + + return cachedToolbarStyle; + } + } + + /// + /// Gets the GUI style used for the package search field. + /// + public static GUIStyle SearchFieldStyle + { + get + { + if (cachedSearchFieldStyle != null) + { + return cachedSearchFieldStyle; + } + + var original = GetStyle("ToolbarSearchTextField"); + cachedSearchFieldStyle = new GUIStyle(original) { fontSize = 12, fixedHeight = 20f }; + + return cachedSearchFieldStyle; + } + } + + /// + /// Gets the GUI style used for bold labels. + /// + public static GUIStyle BoldLabelStyle + { + get + { + if (cachedBoldLabelStyle != null) + { + return cachedBoldLabelStyle; + } + + cachedBoldLabelStyle = new GUIStyle(EditorStyles.label) { fontSize = 12, fontStyle = FontStyle.Bold }; + + return cachedBoldLabelStyle; + } + } + + /// + /// Gets the GUI style used for authors labels. + /// + public static GUIStyle AuthorsLabelStyle + { + get + { + if (cachedAuthorsLabelStyle != null) + { + return cachedAuthorsLabelStyle; + } + + cachedAuthorsLabelStyle = new GUIStyle(EditorStyles.label) { fontSize = 10, fontStyle = FontStyle.Normal }; + + cachedAuthorsLabelStyle.normal.textColor = AuthorsTextColor; + cachedAuthorsLabelStyle.focused.textColor = AuthorsTextColor; + cachedAuthorsLabelStyle.hover.textColor = AuthorsTextColor; + + return cachedAuthorsLabelStyle; + } + } + + /// + /// Gets the GUI style used for description labels. + /// + public static GUIStyle DescriptionLabelStyle + { + get + { + if (cachedDescriptionLabelStyle != null) + { + return cachedDescriptionLabelStyle; + } + + cachedDescriptionLabelStyle = new GUIStyle(EditorStyles.label) + { + wordWrap = true, fontStyle = FontStyle.Normal, alignment = TextAnchor.UpperLeft, + }; + + return cachedDescriptionLabelStyle; + } + } + + /// + /// Gets the GUI style used for package name labels. + /// + public static GUIStyle PackageNameLabelStyle + { + get + { + if (cachedPackageNameLabelStyle != null) + { + return cachedPackageNameLabelStyle; + } + + cachedPackageNameLabelStyle = new GUIStyle(EditorStyles.label) { fontSize = 15, fontStyle = FontStyle.Bold }; + + return cachedPackageNameLabelStyle; + } + } + + /// + /// Gets the GUI style used for labels representing a URL / clickable LINK. + /// + public static GUIStyle LinkLabelStyle + { + get + { + if (cachedLinkLabelStyle != null) + { + return cachedLinkLabelStyle; + } + + cachedLinkLabelStyle = GetStyle("LinkLabel"); + return cachedLinkLabelStyle; + } + } + + /// + /// From here: http://forum.unity3d.com/threads/changing-the-background-color-for-beginhorizontal.66015/. + /// + /// The color to fill the texture with. + /// The generated texture. + private static Texture2D CreateSingleColorTexture(Color color) + { + const int width = 16; + const int height = 16; + var pix = new Color32[width * height]; + Color32 color32 = color; + for (var index = 0; index < pix.Length; index++) + { + pix[index] = color32; + } + + var result = new Texture2D(width, height); + result.SetPixels32(pix); + result.Apply(); + + return result; + } + + private static GUIStyle GetStyle(string styleName) + { + var style = GUI.skin.FindStyle(styleName); + + if (style == null) + { + style = EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector).FindStyle(styleName); + } + + if (style == null) + { + Debug.LogError("Missing built-in guistyle " + styleName); + style = new GUIStyle(); + } + + return style; + } + } +} diff --git a/src/NuGetForUnity/Editor/Ui/Styles.cs.meta b/src/NuGetForUnity/Editor/Ui/Styles.cs.meta new file mode 100644 index 00000000..b8d05ffe --- /dev/null +++ b/src/NuGetForUnity/Editor/Ui/Styles.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ac224d45c07fd442aa7f80b508c340e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: