diff --git a/Editor/Build/BuildCLI/AppBuildHelper.cs b/Editor/Build/BuildCLI/AppBuildHelper.cs
index b40e506..c57b21e 100644
--- a/Editor/Build/BuildCLI/AppBuildHelper.cs
+++ b/Editor/Build/BuildCLI/AppBuildHelper.cs
@@ -22,6 +22,16 @@ public static class AppBuildHelper
Debug.Log("Generate AppBuilderSetting.bytes");
+ PlayerSettings.fullScreenMode = appBuildParameter.FullScreenMode;
+ if (appBuildParameter.FullScreenMode == FullScreenMode.Windowed)
+ {
+ PlayerSettings.defaultScreenWidth = appBuildParameter.WindowedScreenSize.x;
+ PlayerSettings.defaultScreenHeight = appBuildParameter.WindowedScreenSize.y;
+ }
+
+ if (!string.IsNullOrEmpty(appBuildParameter.Version))
+ {
+ }
try
{
diff --git a/Editor/Build/BuildCLI/BuildParameter.cs b/Editor/Build/BuildCLI/BuildParameter.cs
index cfee7cb..ee26ef8 100644
--- a/Editor/Build/BuildCLI/BuildParameter.cs
+++ b/Editor/Build/BuildCLI/BuildParameter.cs
@@ -1,6 +1,7 @@
using System;
using AlicizaX;
using UnityEditor;
+using UnityEngine;
using UnityEngine.Serialization;
using YooAsset;
using YooAsset.Editor;
@@ -15,7 +16,22 @@ public class AppBuildParameter
public int ResMode;
public string FileName;
public Language Language;
- public string [] Scenes;
+ public string[] Scenes;
+
+ ///
+ /// 版本
+ ///
+ public string Version;
+
+ ///
+ /// 是否全屏
+ ///
+ public FullScreenMode FullScreenMode;
+
+ ///
+ /// 窗口化大小
+ ///
+ public Vector2Int WindowedScreenSize;
}
diff --git a/Editor/EditorIcons.cs b/Editor/EditorIcons.cs
index ca544a6..2be3d60 100644
--- a/Editor/EditorIcons.cs
+++ b/Editor/EditorIcons.cs
@@ -9,7 +9,7 @@ using System.IO;
public class EditorIcons : EditorWindow
{
- [MenuItem("Tools/Editor Icons %e", priority = -1001)]
+ [MenuItem("Tools/EditorExtension/Editor Icons %e", priority = -1001)]
public static void EditorIconsOpen()
{
#if UNITY_2018
@@ -43,9 +43,9 @@ public class EditorIcons : EditorWindow
search = EditorGUILayout.TextField(search, EditorStyles.toolbarSearchField);
#endif
if (GUILayout.Button(EditorGUIUtility.IconContent("winbtn_mac_close_h"), //SVN_DeletedLocal
- EditorStyles.toolbarButton,
- GUILayout.Width(22))
- ) search = "";
+ EditorStyles.toolbarButton,
+ GUILayout.Width(22))
+ ) search = "";
}
}
@@ -157,7 +157,7 @@ public class EditorIcons : EditorWindow
//List found = new List();
List unique = new List();
//var skip_flag = HideFlags.HideInInspector | HideFlags.HideAndDontSave;
- //int unique_to_resources = 0, skipped_empty_str = 0, skipped_flags = 0,
+ //int unique_to_resources = 0, skipped_empty_str = 0, skipped_flags = 0,
// skipped_not_persistent = 0, skipped_nulls = 0, unique_to_list = 0;
foreach (Texture2D x in Resources.FindObjectsOfTypeAll())
@@ -167,10 +167,10 @@ public class EditorIcons : EditorWindow
//if (x.hideFlags != HideFlags.HideAndDontSave && x.hideFlags != skip_flag) skipped_flags++; // skipped 27 icons
GUIContent icoContent = GetIcon(x.name);
- if (icoContent == null) continue; // skipped 14 icons
- //{
- // skipped_nulls++;
- // continue;
+ if (icoContent == null) continue; // skipped 14 icons
+ //{
+ // skipped_nulls++;
+ // continue;
//}
if (!all_icons.Contains(x.name))
@@ -211,8 +211,8 @@ public class EditorIcons : EditorWindow
if (GUILayout.Button("Save all icons to folder...", EditorStyles.miniButton)) SaveAllIcons();
GUILayout.Label("Select what icons to show", GUILayout.Width(160));
viewBigIcons = GUILayout.SelectionGrid(
- viewBigIcons ? 1 : 0, new string[] { "Small", "Big" },
- 2, EditorStyles.toolbarButton) == 1;
+ viewBigIcons ? 1 : 0, new string[] { "Small", "Big" },
+ 2, EditorStyles.toolbarButton) == 1;
if (isWide) SearchGUI();
}
@@ -236,8 +236,9 @@ public class EditorIcons : EditorWindow
List iconList;
- if (doSearch) iconList = iconContentListAll.Where(x => x.tooltip.ToLower()
- .Contains(search.ToLower())).ToList();
+ if (doSearch)
+ iconList = iconContentListAll.Where(x => x.tooltip.ToLower()
+ .Contains(search.ToLower())).ToList();
else iconList = viewBigIcons ? iconContentListBig : iconContentListSmall;
while (index < iconList.Count)
@@ -253,9 +254,9 @@ public class EditorIcons : EditorWindow
var icon = iconList[k];
if (GUILayout.Button(icon,
- iconButtonStyle,
- GUILayout.Width(buttonSize),
- GUILayout.Height(buttonSize)))
+ iconButtonStyle,
+ GUILayout.Width(buttonSize),
+ GUILayout.Height(buttonSize)))
{
EditorGUI.FocusTextInControl("");
iconSelected = icon;
@@ -291,8 +292,8 @@ public class EditorIcons : EditorWindow
GUILayout.Space(5);
darkPreview = GUILayout.SelectionGrid(
- darkPreview ? 1 : 0, new string[] { "Light", "Dark" },
- 2, EditorStyles.miniButton) == 1;
+ darkPreview ? 1 : 0, new string[] { "Light", "Dark" },
+ 2, EditorStyles.miniButton) == 1;
GUILayout.FlexibleSpace();
}
@@ -321,7 +322,6 @@ public class EditorIcons : EditorWindow
{
iconSelected = null;
}
-
}
}
@@ -394,353 +394,353 @@ public class EditorIcons : EditorWindow
public static string[] ico_list =
{
- "_Help","_Popup","aboutwindow.mainheader","ageialogo","AlphabeticalSorting","Animation.AddEvent",
- "Animation.AddKeyframe","Animation.EventMarker","Animation.FirstKey","Animation.LastKey",
- "Animation.NextKey","Animation.Play","Animation.PrevKey","Animation.Record","Animation.SequencerLink",
- "animationanimated","animationdopesheetkeyframe","animationkeyframe","animationnocurve",
- "animationvisibilitytoggleoff","animationvisibilitytoggleon","AnimationWrapModeMenu","AssemblyLock",
- "Asset Store","Audio Mixer","AvatarCompass","AvatarController.Layer","AvatarController.LayerHover",
- "AvatarController.LayerSelected","BodyPartPicker","BodySilhouette","DotFill","DotFrame","DotFrameDotted",
- "DotSelection","Head","HeadIk","HeadZoom","HeadZoomSilhouette","LeftArm","LeftFeetIk","LeftFingers",
- "LeftFingersIk","LeftHandZoom","LeftHandZoomSilhouette","LeftLeg","MaskEditor_Root","RightArm","RightFeetIk",
- "RightFingers","RightFingersIk","RightHandZoom","RightHandZoomSilhouette","RightLeg","Torso","AvatarPivot",
- "back","back@2x","beginButton-On","beginButton","blendKey","blendKeyOverlay","blendKeySelected",
- "blendSampler","blueGroove","BuildSettings.Android","BuildSettings.Android.Small","BuildSettings.Broadcom",
- "BuildSettings.Editor","BuildSettings.Editor.Small","BuildSettings.Facebook",
- "BuildSettings.Facebook.Small","BuildSettings.FlashPlayer","BuildSettings.FlashPlayer.Small",
- "BuildSettings.iPhone","BuildSettings.iPhone.Small","BuildSettings.Lumin","BuildSettings.Lumin.small",
- "BuildSettings.Metro","BuildSettings.Metro.Small","BuildSettings.N3DS","BuildSettings.N3DS.Small",
- "BuildSettings.PS4","BuildSettings.PS4.Small","BuildSettings.PSM","BuildSettings.PSM.Small",
- "BuildSettings.PSP2","BuildSettings.PSP2.Small","BuildSettings.SelectedIcon","BuildSettings.Standalone",
- "BuildSettings.Standalone.Small","BuildSettings.StandaloneBroadcom.Small",
- "BuildSettings.StandaloneGLES20Emu.Small","BuildSettings.StandaloneGLESEmu",
- "BuildSettings.StandaloneGLESEmu.Small","BuildSettings.Switch","BuildSettings.Switch.Small",
- "BuildSettings.tvOS","BuildSettings.tvOS.Small","BuildSettings.Web","BuildSettings.Web.Small",
- "BuildSettings.WebGL","BuildSettings.WebGL.Small","BuildSettings.WP8","BuildSettings.WP8.Small",
- "BuildSettings.Xbox360","BuildSettings.Xbox360.Small","BuildSettings.XboxOne",
- "BuildSettings.XboxOne.Small","BuildSettings.Xiaomi","Camera Gizmo","CheckerFloor","Clipboard",
- "ClothInspector.PaintTool","ClothInspector.PaintValue","ClothInspector.SelectTool",
- "ClothInspector.SettingsTool","ClothInspector.ViewValue","CloudConnect","Collab.Build",
- "Collab.BuildFailed","Collab.BuildSucceeded","Collab.FileAdded","Collab.FileConflict","Collab.FileDeleted",
- "Collab.FileIgnored","Collab.FileMoved","Collab.FileUpdated","Collab.FolderAdded","Collab.FolderConflict",
- "Collab.FolderDeleted","Collab.FolderIgnored","Collab.FolderMoved","Collab.FolderUpdated",
- "Collab.NoInternet","Collab","Collab.Warning","CollabConflict","CollabError","CollabNew","CollabOffline",
- "CollabProgress","CollabPull","CollabPush","ColorPicker.ColorCycle","ColorPicker.CycleColor",
- "ColorPicker.CycleSlider","ColorPicker.SliderCycle","console.erroricon.inactive.sml","console.erroricon",
- "console.erroricon.sml","console.infoicon","console.infoicon.sml","console.warnicon.inactive.sml",
- "console.warnicon","console.warnicon.sml","curvekeyframe","curvekeyframeselected",
- "curvekeyframeselectedoverlay","curvekeyframesemiselectedoverlay","curvekeyframeweighted","CustomSorting",
- "d__Popup","d_aboutwindow.mainheader","d_ageialogo","d_AlphabeticalSorting","d_Animation.AddEvent",
- "d_Animation.AddKeyframe","d_Animation.EventMarker","d_Animation.FirstKey","d_Animation.LastKey",
- "d_Animation.NextKey","d_Animation.Play","d_Animation.PrevKey","d_Animation.Record",
- "d_Animation.SequencerLink","d_animationanimated","d_animationkeyframe","d_animationnocurve",
- "d_animationvisibilitytoggleoff","d_animationvisibilitytoggleon","d_AnimationWrapModeMenu",
- "d_AS Badge Delete","d_AS Badge New","d_AssemblyLock","d_Asset Store","d_Audio Mixer",
- "d_AvatarBlendBackground","d_AvatarBlendLeft","d_AvatarBlendLeftA","d_AvatarBlendRight",
- "d_AvatarBlendRightA","d_AvatarCompass","d_AvatarPivot","d_back","d_back@2x","d_beginButton-On",
- "d_beginButton","d_blueGroove","d_BuildSettings.Android","d_BuildSettings.Android.Small",
- "d_BuildSettings.Broadcom","d_BuildSettings.FlashPlayer","d_BuildSettings.FlashPlayer.Small",
- "d_BuildSettings.iPhone","d_BuildSettings.iPhone.Small","d_BuildSettings.Lumin",
- "d_BuildSettings.Lumin.small","d_BuildSettings.PS4","d_BuildSettings.PS4.Small","d_BuildSettings.PSP2",
- "d_BuildSettings.PSP2.Small","d_BuildSettings.SelectedIcon","d_BuildSettings.Standalone",
- "d_BuildSettings.Standalone.Small","d_BuildSettings.tvOS","d_BuildSettings.tvOS.Small",
- "d_BuildSettings.Web","d_BuildSettings.Web.Small","d_BuildSettings.WebGL","d_BuildSettings.WebGL.Small",
- "d_BuildSettings.Xbox360","d_BuildSettings.Xbox360.Small","d_BuildSettings.XboxOne",
- "d_BuildSettings.XboxOne.Small","d_CheckerFloor","d_CloudConnect","d_Collab.FileAdded",
- "d_Collab.FileConflict","d_Collab.FileDeleted","d_Collab.FileIgnored","d_Collab.FileMoved",
- "d_Collab.FileUpdated","d_Collab.FolderAdded","d_Collab.FolderConflict","d_Collab.FolderDeleted",
- "d_Collab.FolderIgnored","d_Collab.FolderMoved","d_Collab.FolderUpdated","d_ColorPicker.CycleColor",
- "d_ColorPicker.CycleSlider","d_console.erroricon","d_console.erroricon.sml","d_console.infoicon",
- "d_console.infoicon.sml","d_console.warnicon","d_console.warnicon.sml","d_curvekeyframe",
- "d_curvekeyframeselected","d_curvekeyframeselectedoverlay","d_curvekeyframesemiselectedoverlay",
- "d_curvekeyframeweighted","d_CustomSorting","d_DefaultSorting","d_EditCollider","d_editcollision_16",
- "d_editconstraints_16","d_editicon.sml","d_endButton-On","d_endButton","d_eyeDropper.Large",
- "d_eyeDropper.sml","d_Favorite","d_FilterByLabel","d_FilterByType","d_FilterSelectedOnly",
- "d_FilterSelectedOnly@2x","d_forward","d_forward@2x","d_GEAR","d_Groove","d_HorizontalSplit",
- "d_icon dropdown","d_InspectorLock","d_JointAngularLimits","d_leftBracket","d_Lighting",
- "d_LightmapEditor.WindowTitle","d_LookDevCenterLight","d_LookDevCenterLight@2x","d_LookDevClose",
- "d_LookDevClose@2x","d_LookDevEnvRotation","d_LookDevEnvRotation@2x","d_LookDevMirrorViews",
- "d_LookDevMirrorViews@2x","d_LookDevMirrorViewsActive","d_LookDevMirrorViewsActive@2x",
- "d_LookDevMirrorViewsInactive","d_LookDevMirrorViewsInactive@2x","d_LookDevObjRotation",
- "d_LookDevObjRotation@2x","d_LookDevPaneOption","d_LookDevPaneOption@2x","d_LookDevResetEnv",
- "d_LookDevResetEnv@2x","d_LookDevShadow","d_LookDevShadow@2x","d_LookDevSideBySide",
- "d_LookDevSideBySide@2x","d_LookDevSingle1","d_LookDevSingle1@2x","d_LookDevSingle2",
- "d_LookDevSingle2@2x","d_LookDevSplit","d_LookDevSplit@2x","d_LookDevZone","d_LookDevZone@2x",
- "d_Mirror","d_model large","d_monologo","d_MoveTool on","d_MoveTool","d_Navigation","d_Occlusion",
- "d_P4_AddedLocal","d_P4_AddedRemote","d_P4_CheckOutLocal","d_P4_CheckOutRemote","d_P4_Conflicted",
- "d_P4_DeletedLocal","d_P4_DeletedRemote","d_P4_Local","d_P4_LockedLocal","d_P4_LockedRemote",
- "d_P4_OutOfSync","d_Particle Effect","d_PauseButton On","d_PauseButton","d_PlayButton On","d_PlayButton",
- "d_PlayButtonProfile On","d_PlayButtonProfile","d_playLoopOff","d_playLoopOn","d_preAudioAutoPlayOff",
- "d_preAudioAutoPlayOn","d_preAudioLoopOff","d_preAudioLoopOn","d_preAudioPlayOff","d_preAudioPlayOn",
- "d_PreMatCube","d_PreMatCylinder","d_PreMatLight0","d_PreMatLight1","d_PreMatSphere","d_PreMatTorus",
- "d_Preset.Context","d_PreTextureAlpha","d_PreTextureMipMapHigh","d_PreTextureMipMapLow","d_PreTextureRGB",
- "d_Profiler.Audio","d_Profiler.CPU","d_Profiler.FirstFrame","d_Profiler.GPU","d_Profiler.LastFrame",
- "d_Profiler.Memory","d_Profiler.Network","d_Profiler.NextFrame","d_Profiler.Physics","d_Profiler.PrevFrame",
- "d_Profiler.Record","d_Profiler.Rendering","d_Profiler.Video","d_ProfilerColumn.WarningCount","d_Project",
- "d_RectTool On","d_RectTool","d_RectTransformBlueprint","d_RectTransformRaw","d_redGroove","d_Refresh",
- "d_renderdoc","d_rightBracket","d_RotateTool On","d_RotateTool","d_ScaleTool On","d_ScaleTool",
- "d_SceneViewAlpha","d_SceneViewAudio","d_SceneViewFx","d_SceneViewLighting","d_SceneViewOrtho",
- "d_SceneViewRGB","d_ScrollShadow","d_Settings","d_SettingsIcon","d_SocialNetworks.FacebookShare",
- "d_SocialNetworks.LinkedInShare","d_SocialNetworks.Tweet","d_SocialNetworks.UDNOpen","d_SpeedScale",
- "d_StepButton On","d_StepButton","d_StepLeftButton-On","d_StepLeftButton","d_SVN_AddedLocal",
- "d_SVN_Conflicted","d_SVN_DeletedLocal","d_SVN_Local","d_SVN_LockedLocal","d_SVN_OutOfSync","d_tab_next",
- "d_tab_next@2x","d_tab_prev","d_tab_prev@2x","d_TerrainInspector.TerrainToolLower On",
- "d_TerrainInspector.TerrainToolLowerAlt","d_TerrainInspector.TerrainToolPlants On",
- "d_TerrainInspector.TerrainToolPlants","d_TerrainInspector.TerrainToolPlantsAlt On",
- "d_TerrainInspector.TerrainToolPlantsAlt","d_TerrainInspector.TerrainToolRaise On",
- "d_TerrainInspector.TerrainToolRaise","d_TerrainInspector.TerrainToolSetheight On",
- "d_TerrainInspector.TerrainToolSetheight","d_TerrainInspector.TerrainToolSetheightAlt On",
- "d_TerrainInspector.TerrainToolSetheightAlt","d_TerrainInspector.TerrainToolSettings On",
- "d_TerrainInspector.TerrainToolSettings","d_TerrainInspector.TerrainToolSmoothHeight On",
- "d_TerrainInspector.TerrainToolSmoothHeight","d_TerrainInspector.TerrainToolSplat On",
- "d_TerrainInspector.TerrainToolSplat","d_TerrainInspector.TerrainToolSplatAlt On",
- "d_TerrainInspector.TerrainToolSplatAlt","d_TerrainInspector.TerrainToolTrees On",
- "d_TerrainInspector.TerrainToolTrees","d_TerrainInspector.TerrainToolTreesAlt On",
- "d_TerrainInspector.TerrainToolTreesAlt","d_TimelineDigIn","d_TimelineEditModeMixOFF",
- "d_TimelineEditModeMixON","d_TimelineEditModeReplaceOFF","d_TimelineEditModeReplaceON",
- "d_TimelineEditModeRippleOFF","d_TimelineEditModeRippleON","d_TimelineSelector","d_Toolbar Minus",
- "d_Toolbar Plus More","d_Toolbar Plus","d_ToolHandleCenter","d_ToolHandleGlobal","d_ToolHandleLocal",
- "d_ToolHandlePivot","d_tranp","d_TransformTool On","d_TransformTool","d_tree_icon","d_tree_icon_branch",
- "d_tree_icon_branch_frond","d_tree_icon_frond","d_tree_icon_leaf","d_TreeEditor.AddBranches",
- "d_TreeEditor.AddLeaves","d_TreeEditor.Branch On","d_TreeEditor.Branch","d_TreeEditor.BranchFreeHand On",
- "d_TreeEditor.BranchFreeHand","d_TreeEditor.BranchRotate On","d_TreeEditor.BranchRotate",
- "d_TreeEditor.BranchScale On","d_TreeEditor.BranchScale","d_TreeEditor.BranchTranslate On",
- "d_TreeEditor.BranchTranslate","d_TreeEditor.Distribution On","d_TreeEditor.Distribution",
- "d_TreeEditor.Duplicate","d_TreeEditor.Geometry On","d_TreeEditor.Geometry","d_TreeEditor.Leaf On",
- "d_TreeEditor.Leaf","d_TreeEditor.LeafFreeHand On","d_TreeEditor.LeafFreeHand","d_TreeEditor.LeafRotate On",
- "d_TreeEditor.LeafRotate","d_TreeEditor.LeafScale On","d_TreeEditor.LeafScale",
- "d_TreeEditor.LeafTranslate On","d_TreeEditor.LeafTranslate","d_TreeEditor.Material On",
- "d_TreeEditor.Material","d_TreeEditor.Refresh","d_TreeEditor.Trash","d_TreeEditor.Wind On",
- "d_TreeEditor.Wind","d_UnityEditor.AnimationWindow","d_UnityEditor.ConsoleWindow",
- "d_UnityEditor.DebugInspectorWindow","d_UnityEditor.FindDependencies","d_UnityEditor.GameView",
- "d_UnityEditor.HierarchyWindow","d_UnityEditor.InspectorWindow","d_UnityEditor.LookDevView",
- "d_UnityEditor.ProfilerWindow","d_UnityEditor.SceneHierarchyWindow","d_UnityEditor.SceneView",
- "d_UnityEditor.Timeline.TimelineWindow","d_UnityEditor.VersionControl","d_UnityLogo","d_VerticalSplit",
- "d_ViewToolMove On","d_ViewToolMove","d_ViewToolOrbit On","d_ViewToolOrbit","d_ViewToolZoom On",
- "d_ViewToolZoom","d_VisibilityOff","d_VisibilityOn","d_VUMeterTextureHorizontal","d_VUMeterTextureVertical",
- "d_WaitSpin00","d_WaitSpin01","d_WaitSpin02","d_WaitSpin03","d_WaitSpin04","d_WaitSpin05","d_WaitSpin06",
- "d_WaitSpin07","d_WaitSpin08","d_WaitSpin09","d_WaitSpin10","d_WaitSpin11","d_WelcomeScreen.AssetStoreLogo",
- "d_winbtn_graph","d_winbtn_graph_close_h","d_winbtn_graph_max_h","d_winbtn_graph_min_h",
- "d_winbtn_mac_close","d_winbtn_mac_close_a","d_winbtn_mac_close_h","d_winbtn_mac_inact","d_winbtn_mac_max",
- "d_winbtn_mac_max_a","d_winbtn_mac_max_h","d_winbtn_mac_min","d_winbtn_mac_min_a","d_winbtn_mac_min_h",
- "d_winbtn_win_close","d_winbtn_win_close_a","d_winbtn_win_close_h","d_winbtn_win_max","d_winbtn_win_max_a",
- "d_winbtn_win_max_h","d_winbtn_win_min","d_winbtn_win_min_a","d_winbtn_win_min_h","d_winbtn_win_rest",
- "d_winbtn_win_rest_a","d_winbtn_win_rest_h","DefaultSorting","EditCollider","editcollision_16",
- "editconstraints_16","editicon.sml","endButton-On","endButton","eyeDropper.Large","eyeDropper.sml",
- "Favorite","FilterByLabel","FilterByType","FilterSelectedOnly","FilterSelectedOnly@2x","forward",
- "forward@2x","GEAR","Grid.BoxTool","Grid.Default","Grid.EraserTool","Grid.FillTool","Grid.MoveTool",
- "Grid.PaintTool","Grid.PickingTool","Grid.SelectTool","Groove","align_horizontally",
- "align_horizontally_center","align_horizontally_center_active","align_horizontally_left",
- "align_horizontally_left_active","align_horizontally_right","align_horizontally_right_active",
- "align_vertically","align_vertically_bottom","align_vertically_bottom_active","align_vertically_center",
- "align_vertically_center_active","align_vertically_top","align_vertically_top_active",
- "d_align_horizontally","d_align_horizontally_center","d_align_horizontally_center_active",
- "d_align_horizontally_left","d_align_horizontally_left_active","d_align_horizontally_right",
- "d_align_horizontally_right_active","d_align_vertically","d_align_vertically_bottom",
- "d_align_vertically_bottom_active","d_align_vertically_center","d_align_vertically_center_active",
- "d_align_vertically_top","d_align_vertically_top_active","HorizontalSplit","icon dropdown",
- "InspectorLock","JointAngularLimits","KnobCShape","KnobCShapeMini","leftBracket","Lighting",
- "LightmapEditor.WindowTitle","Lightmapping","d_greenLight","d_lightOff","d_lightRim","d_orangeLight",
- "d_redLight","greenLight","lightOff","lightRim","orangeLight","redLight","LockIcon-On","LockIcon",
- "LookDevCenterLight","LookDevCenterLightl@2x","LookDevClose","LookDevClose@2x","LookDevEnvRotation",
- "LookDevEnvRotation@2x","LookDevEyedrop","LookDevLight","LookDevLight@2x","LookDevMirrorViewsActive",
- "LookDevMirrorViewsActive@2x","LookDevMirrorViewsInactive","LookDevMirrorViewsInactive@2x",
- "LookDevObjRotation","LookDevObjRotation@2x","LookDevPaneOption","LookDevPaneOption@2x","LookDevResetEnv",
- "LookDevResetEnv@2x","LookDevShadow","LookDevShadow@2x","LookDevShadowFrame","LookDevShadowFrame@2x",
- "LookDevSideBySide","LookDevSideBySide@2x","LookDevSingle1","LookDevSingle1@2x","LookDevSingle2",
- "LookDevSingle2@2x","LookDevSplit","LookDevSplit@2x","LookDevZone","LookDevZone@2x","loop","Mirror",
- "monologo","MoveTool on","MoveTool","Navigation","Occlusion","P4_AddedLocal","P4_AddedRemote",
- "P4_BlueLeftParenthesis","P4_BlueRightParenthesis","P4_CheckOutLocal","P4_CheckOutRemote","P4_Conflicted",
- "P4_DeletedLocal","P4_DeletedRemote","P4_Local","P4_LockedLocal","P4_LockedRemote","P4_OutOfSync",
- "P4_RedLeftParenthesis","P4_RedRightParenthesis","P4_Updating","PackageBadgeDelete","PackageBadgeNew",
- "Particle Effect","PauseButton On","PauseButton","PlayButton On","PlayButton","PlayButtonProfile On",
- "PlayButtonProfile","playLoopOff","playLoopOn","playSpeed","preAudioAutoPlayOff","preAudioAutoPlayOn",
- "preAudioLoopOff","preAudioLoopOn","preAudioPlayOff","preAudioPlayOn","PreMatCube","PreMatCylinder",
- "PreMatLight0","PreMatLight1","PreMatQuad","PreMatSphere","PreMatTorus","Preset.Context","PreTextureAlpha",
- "PreTextureArrayFirstSlice","PreTextureArrayLastSlice","PreTextureMipMapHigh","PreTextureMipMapLow",
- "PreTextureRGB","AreaLight Gizmo","AreaLight Icon","Assembly Icon","AssetStore Icon","AudioMixerView Icon",
- "AudioSource Gizmo","Camera Gizmo","CGProgram Icon","ChorusFilter Icon","CollabChanges Icon",
- "CollabChangesConflict Icon","CollabChangesDeleted Icon","CollabConflict Icon","CollabCreate Icon",
- "CollabDeleted Icon","CollabEdit Icon","CollabExclude Icon","CollabMoved Icon","cs Script Icon",
- "d_AudioMixerView Icon","d_CollabChanges Icon","d_CollabChangesConflict Icon","d_CollabChangesDeleted Icon",
- "d_CollabConflict Icon","d_CollabCreate Icon","d_CollabDeleted Icon","d_CollabEdit Icon",
- "d_CollabExclude Icon","d_CollabMoved Icon","d_GridLayoutGroup Icon","d_HorizontalLayoutGroup Icon",
- "d_Prefab Icon","d_PrefabModel Icon","d_PrefabVariant Icon","d_VerticalLayoutGroup Icon",
- "DefaultSlate Icon","DirectionalLight Gizmo","DirectionalLight Icon","DiscLight Gizmo","DiscLight Icon",
- "dll Script Icon","EchoFilter Icon","Favorite Icon","Folder Icon","FolderEmpty Icon",
- "FolderFavorite Icon","GameManager Icon","GridBrush Icon","HighPassFilter Icon",
- "HorizontalLayoutGroup Icon","LensFlare Gizmo","LightingDataAssetParent Icon","LightProbeGroup Gizmo",
- "LightProbeProxyVolume Gizmo","LowPassFilter Icon","Main Light Gizmo","MetaFile Icon",
- "Microphone Icon","MuscleClip Icon","ParticleSystem Gizmo","PointLight Gizmo","Prefab Icon",
- "PrefabModel Icon","PrefabOverlayAdded Icon","PrefabOverlayModified Icon","PrefabOverlayRemoved Icon",
- "PrefabVariant Icon","Projector Gizmo","RaycastCollider Icon","ReflectionProbe Gizmo",
- "ReverbFilter Icon","SceneSet Icon","Search Icon","SoftlockProjectBrowser Icon","SpeedTreeModel Icon",
- "SpotLight Gizmo","Spotlight Icon","SpriteCollider Icon","sv_icon_dot0_pix16_gizmo",
- "sv_icon_dot10_pix16_gizmo","sv_icon_dot11_pix16_gizmo","sv_icon_dot12_pix16_gizmo",
- "sv_icon_dot13_pix16_gizmo","sv_icon_dot14_pix16_gizmo","sv_icon_dot15_pix16_gizmo",
- "sv_icon_dot1_pix16_gizmo","sv_icon_dot2_pix16_gizmo","sv_icon_dot3_pix16_gizmo",
- "sv_icon_dot4_pix16_gizmo","sv_icon_dot5_pix16_gizmo","sv_icon_dot6_pix16_gizmo",
- "sv_icon_dot7_pix16_gizmo","sv_icon_dot8_pix16_gizmo","sv_icon_dot9_pix16_gizmo",
- "AnimatorController Icon","AnimatorState Icon","AnimatorStateMachine Icon",
- "AnimatorStateTransition Icon","BlendTree Icon","AnimationWindowEvent Icon","AudioMixerController Icon",
- "DefaultAsset Icon","EditorSettings Icon","AnyStateNode Icon","HumanTemplate Icon",
- "LightingDataAsset Icon","LightmapParameters Icon","Preset Icon","SceneAsset Icon",
- "SubstanceArchive Icon","AssemblyDefinitionAsset Icon","NavMeshAgent Icon","NavMeshData Icon",
- "NavMeshObstacle Icon","OffMeshLink Icon","AnalyticsTracker Icon","Animation Icon",
- "AnimationClip Icon","AimConstraint Icon","d_AimConstraint Icon","d_LookAtConstraint Icon",
- "d_ParentConstraint Icon","d_PositionConstraint Icon","d_RotationConstraint Icon",
- "d_ScaleConstraint Icon","LookAtConstraint Icon","ParentConstraint Icon","PositionConstraint Icon",
- "RotationConstraint Icon","ScaleConstraint Icon","Animator Icon","AnimatorOverrideController Icon",
- "AreaEffector2D Icon","AudioMixerGroup Icon","AudioMixerSnapshot Icon","AudioSpatializerMicrosoft Icon",
- "AudioChorusFilter Icon","AudioClip Icon","AudioDistortionFilter Icon","AudioEchoFilter Icon",
- "AudioHighPassFilter Icon","AudioListener Icon","AudioLowPassFilter Icon","AudioReverbFilter Icon",
- "AudioReverbZone Icon","AudioSource Icon","Avatar Icon","AvatarMask Icon","BillboardAsset Icon",
- "BillboardRenderer Icon","BoxCollider Icon","BoxCollider2D Icon","BuoyancyEffector2D Icon","Camera Icon",
- "Canvas Icon","CanvasGroup Icon","CanvasRenderer Icon","CapsuleCollider Icon","CapsuleCollider2D Icon",
- "CharacterController Icon","CharacterJoint Icon","CircleCollider2D Icon","Cloth Icon",
- "CompositeCollider2D Icon","ComputeShader Icon","ConfigurableJoint Icon","ConstantForce Icon",
- "ConstantForce2D Icon","Cubemap Icon","d_Canvas Icon","d_CanvasGroup Icon","d_CanvasRenderer Icon",
- "d_GameObject Icon","d_LightProbeProxyVolume Icon","d_ParticleSystem Icon","d_ParticleSystemForceField Icon",
- "d_RectTransform Icon","d_StreamingController Icon","DistanceJoint2D Icon","EdgeCollider2D Icon",
- "d_EventSystem Icon","d_EventTrigger Icon","d_Physics2DRaycaster Icon","d_PhysicsRaycaster Icon",
- "d_StandaloneInputModule Icon","d_TouchInputModule Icon","EventSystem Icon","EventTrigger Icon",
- "HoloLensInputModule Icon","Physics2DRaycaster Icon","PhysicsRaycaster Icon","StandaloneInputModule Icon",
- "TouchInputModule Icon","SpriteShapeRenderer Icon","VisualTreeAsset Icon","d_VisualEffect Icon",
- "d_VisualEffectAsset Icon","VisualEffect Icon","VisualEffectAsset Icon","FixedJoint Icon",
- "FixedJoint2D Icon","Flare Icon","FlareLayer Icon","Font Icon","FrictionJoint2D Icon",
- "GameObject Icon","Grid Icon","GUILayer Icon","GUISkin Icon","GUIText Icon","GUITexture Icon",
- "Halo Icon","HingeJoint Icon","HingeJoint2D Icon","LensFlare Icon","Light Icon","LightProbeGroup Icon",
- "LightProbeProxyVolume Icon","LightProbes Icon","LineRenderer Icon","LODGroup Icon","Material Icon",
- "Mesh Icon","MeshCollider Icon","MeshFilter Icon","MeshRenderer Icon","Motion Icon","MovieTexture Icon",
- "NetworkAnimator Icon","NetworkDiscovery Icon","NetworkIdentity Icon","NetworkLobbyManager Icon",
- "NetworkLobbyPlayer Icon","NetworkManager Icon","NetworkManagerHUD Icon","NetworkMigrationManager Icon",
- "NetworkProximityChecker Icon","NetworkStartPosition Icon","NetworkTransform Icon",
- "NetworkTransformChild Icon","NetworkTransformVisualizer Icon","NetworkView Icon","OcclusionArea Icon",
- "OcclusionPortal Icon","ParticleSystem Icon","ParticleSystemForceField Icon","PhysicMaterial Icon",
- "PhysicsMaterial2D Icon","PlatformEffector2D Icon","d_PlayableDirector Icon","PlayableDirector Icon",
- "PointEffector2D Icon","PolygonCollider2D Icon","ProceduralMaterial Icon","Projector Icon",
- "RectTransform Icon","ReflectionProbe Icon","RelativeJoint2D Icon","d_SortingGroup Icon",
- "SortingGroup Icon","RenderTexture Icon","Rigidbody Icon","Rigidbody2D Icon","ScriptableObject Icon",
- "Shader Icon","ShaderVariantCollection Icon","SkinnedMeshRenderer Icon","Skybox Icon","SliderJoint2D Icon",
- "TrackedPoseDriver Icon","SphereCollider Icon","SpringJoint Icon","SpringJoint2D Icon","Sprite Icon",
- "SpriteMask Icon","SpriteRenderer Icon","StreamingController Icon","StyleSheet Icon","SurfaceEffector2D Icon",
- "TargetJoint2D Icon","Terrain Icon","TerrainCollider Icon","TerrainData Icon","TextAsset Icon",
- "TextMesh Icon","Texture Icon","Texture2D Icon","Tile Icon","Tilemap Icon","TilemapCollider2D Icon",
- "TilemapRenderer Icon","d_TimelineAsset Icon","TimelineAsset Icon","TrailRenderer Icon","Transform Icon",
- "SpriteAtlas Icon","AspectRatioFitter Icon","Button Icon","CanvasScaler Icon","ContentSizeFitter Icon",
- "d_AspectRatioFitter Icon","d_CanvasScaler Icon","d_ContentSizeFitter Icon","d_FreeformLayoutGroup Icon",
- "d_GraphicRaycaster Icon","d_GridLayoutGroup Icon","d_HorizontalLayoutGroup Icon","d_LayoutElement Icon",
- "d_PhysicalResolution Icon","d_ScrollViewArea Icon","d_SelectionList Icon","d_SelectionListItem Icon",
- "d_SelectionListTemplate Icon","d_VerticalLayoutGroup Icon","Dropdown Icon","FreeformLayoutGroup Icon",
- "GraphicRaycaster Icon","GridLayoutGroup Icon","HorizontalLayoutGroup Icon","Image Icon","InputField Icon",
- "LayoutElement Icon","Mask Icon","Outline Icon","PositionAsUV1 Icon","RawImage Icon","RectMask2D Icon",
- "Scrollbar Icon","ScrollRect Icon","Selectable Icon","Shadow Icon","Slider Icon","Text Icon","Toggle Icon",
- "ToggleGroup Icon","VerticalLayoutGroup Icon","VideoClip Icon","VideoPlayer Icon","VisualEffect Icon",
- "VisualEffectAsset Icon","WheelCollider Icon","WheelJoint2D Icon","WindZone Icon",
- "SpatialMappingCollider Icon","SpatialMappingRenderer Icon","WorldAnchor Icon","UssScript Icon",
- "UxmlScript Icon","VerticalLayoutGroup Icon","VideoEffect Icon","VisualEffect Gizmo",
- "VisualEffectAsset Icon","AnchorBehaviour Icon","AnchorInputListenerBehaviour Icon",
- "AnchorStageBehaviour Icon","CloudRecoBehaviour Icon","ContentPlacementBehaviour Icon",
- "ContentPositioningBehaviour Icon","CylinderTargetBehaviour Icon","d_AnchorBehaviour Icon",
- "d_AnchorInputListenerBehaviour Icon","d_AnchorStageBehaviour Icon","d_CloudRecoBehaviour Icon",
- "d_ContentPlacementBehaviour Icon","d_ContentPositioningBehaviour Icon","d_CylinderTargetBehaviour Icon",
- "d_ImageTargetBehaviour Icon","d_MidAirPositionerBehaviour Icon","d_ModelTargetBehaviour Icon",
- "d_MultiTargetBehaviour Icon","d_ObjectTargetBehaviour Icon","d_PlaneFinderBehaviour Icon",
- "d_UserDefinedTargetBuildingBehaviour Icon","d_VirtualButtonBehaviour Icon","d_VuforiaBehaviour Icon",
- "d_VuMarkBehaviour Icon","d_WireframeBehaviour Icon","ImageTargetBehaviour Icon",
- "MidAirPositionerBehaviour Icon","ModelTargetBehaviour Icon","MultiTargetBehaviour Icon",
- "ObjectTargetBehaviour Icon","PlaneFinderBehaviour Icon","UserDefinedTargetBuildingBehaviour Icon",
- "VirtualButtonBehaviour Icon","VuforiaBehaviour Icon","VuMarkBehaviour Icon","WireframeBehaviour Icon",
- "WindZone Gizmo","Profiler.Audio","Profiler.CPU","Profiler.FirstFrame","Profiler.GlobalIllumination",
- "Profiler.GPU","Profiler.Instrumentation","Profiler.LastFrame","Profiler.Memory","Profiler.NetworkMessages",
- "Profiler.NetworkOperations","Profiler.NextFrame","Profiler.Physics","Profiler.Physics2D",
- "Profiler.PrevFrame","Profiler.Record","Profiler.Rendering","Profiler.UI","Profiler.UIDetails",
- "Profiler.Video","ProfilerColumn.WarningCount","Project","RectTool On","RectTool","RectTransformBlueprint",
- "RectTransformRaw","redGroove","Refresh","renderdoc","rightBracket","RotateTool On","RotateTool",
- "SaveActive","SaveFromPlay","SavePassive","ScaleTool On","ScaleTool","SceneLoadIn","SceneLoadOut",
- "SceneSave","SceneSaveGrey","SceneViewAlpha","SceneViewAudio","SceneViewFx","SceneViewLighting",
- "SceneViewOrtho","SceneViewRGB","ScrollShadow","Settings","SettingsIcon","SocialNetworks.FacebookShare",
- "SocialNetworks.LinkedInShare","SocialNetworks.Tweet","SocialNetworks.UDNLogo","SocialNetworks.UDNOpen",
- "SoftlockInline","SpeedScale","StateMachineEditor.ArrowTip","StateMachineEditor.ArrowTipSelected",
- "StateMachineEditor.Background","StateMachineEditor.State","StateMachineEditor.StateHover",
- "StateMachineEditor.StateSelected","StateMachineEditor.StateSub","StateMachineEditor.StateSubHover",
- "StateMachineEditor.StateSubSelected","StateMachineEditor.UpButton","StateMachineEditor.UpButtonHover",
- "StepButton On","StepButton","StepLeftButton-On","StepLeftButton","sticky_arrow","sticky_p4","sticky_skin",
- "sv_icon_dot0_sml","sv_icon_dot10_sml","sv_icon_dot11_sml","sv_icon_dot12_sml","sv_icon_dot13_sml",
- "sv_icon_dot14_sml","sv_icon_dot15_sml","sv_icon_dot1_sml","sv_icon_dot2_sml","sv_icon_dot3_sml",
- "sv_icon_dot4_sml","sv_icon_dot5_sml","sv_icon_dot6_sml","sv_icon_dot7_sml","sv_icon_dot8_sml",
- "sv_icon_dot9_sml","sv_icon_name0","sv_icon_name1","sv_icon_name2","sv_icon_name3","sv_icon_name4",
- "sv_icon_name5","sv_icon_name6","sv_icon_name7","sv_icon_none","sv_label_0","sv_label_1","sv_label_2",
- "sv_label_3","sv_label_4","sv_label_5","sv_label_6","sv_label_7","SVN_AddedLocal","SVN_Conflicted",
- "SVN_DeletedLocal","SVN_Local","SVN_LockedLocal","SVN_OutOfSync","tab_next","tab_next@2x","tab_prev",
- "tab_prev@2x","TerrainInspector.TerrainToolLower On","TerrainInspector.TerrainToolLower",
- "TerrainInspector.TerrainToolLowerAlt","TerrainInspector.TerrainToolPlants On",
- "TerrainInspector.TerrainToolPlants","TerrainInspector.TerrainToolPlantsAlt On",
- "TerrainInspector.TerrainToolPlantsAlt","TerrainInspector.TerrainToolRaise On",
- "TerrainInspector.TerrainToolRaise","TerrainInspector.TerrainToolSculpt On",
- "TerrainInspector.TerrainToolSculpt","TerrainInspector.TerrainToolSetheight On",
- "TerrainInspector.TerrainToolSetheight","TerrainInspector.TerrainToolSetheightAlt On",
- "TerrainInspector.TerrainToolSetheightAlt","TerrainInspector.TerrainToolSettings On",
- "TerrainInspector.TerrainToolSettings","TerrainInspector.TerrainToolSmoothHeight On",
- "TerrainInspector.TerrainToolSmoothHeight","TerrainInspector.TerrainToolSplat On",
- "TerrainInspector.TerrainToolSplat","TerrainInspector.TerrainToolSplatAlt On",
- "TerrainInspector.TerrainToolSplatAlt","TerrainInspector.TerrainToolTrees On",
- "TerrainInspector.TerrainToolTrees","TerrainInspector.TerrainToolTreesAlt On",
- "TerrainInspector.TerrainToolTreesAlt","TestFailed","TestIgnored","TestInconclusive","TestNormal",
- "TestPassed","TestStopwatch","TimelineClipBG","TimelineClipFG","TimelineDigIn","TimelineEditModeMixOFF",
- "TimelineEditModeMixON","TimelineEditModeReplaceOFF","TimelineEditModeReplaceON","TimelineEditModeRippleOFF",
- "TimelineEditModeRippleON","TimelineSelector","Toolbar Minus","Toolbar Plus More","Toolbar Plus",
- "ToolHandleCenter","ToolHandleGlobal","ToolHandleLocal","ToolHandlePivot","tranp","TransformTool On",
- "TransformTool","tree_icon","tree_icon_branch","tree_icon_branch_frond","tree_icon_frond","tree_icon_leaf",
- "TreeEditor.AddBranches","TreeEditor.AddLeaves","TreeEditor.Branch On","TreeEditor.Branch",
- "TreeEditor.BranchFreeHand On","TreeEditor.BranchFreeHand","TreeEditor.BranchRotate On",
- "TreeEditor.BranchRotate","TreeEditor.BranchScale On","TreeEditor.BranchScale",
- "TreeEditor.BranchTranslate On","TreeEditor.BranchTranslate","TreeEditor.Distribution On",
- "TreeEditor.Distribution","TreeEditor.Duplicate","TreeEditor.Geometry On","TreeEditor.Geometry",
- "TreeEditor.Leaf On","TreeEditor.Leaf","TreeEditor.LeafFreeHand On","TreeEditor.LeafFreeHand",
- "TreeEditor.LeafRotate On","TreeEditor.LeafRotate","TreeEditor.LeafScale On","TreeEditor.LeafScale",
- "TreeEditor.LeafTranslate On","TreeEditor.LeafTranslate","TreeEditor.Material On","TreeEditor.Material",
- "TreeEditor.Refresh","TreeEditor.Trash","TreeEditor.Wind On","TreeEditor.Wind","UnityEditor.AnimationWindow",
- "UnityEditor.ConsoleWindow","UnityEditor.DebugInspectorWindow","UnityEditor.FindDependencies",
- "UnityEditor.GameView","UnityEditor.Graphs.AnimatorControllerTool","UnityEditor.HierarchyWindow",
- "UnityEditor.InspectorWindow","UnityEditor.LookDevView","UnityEditor.ProfilerWindow",
- "UnityEditor.SceneHierarchyWindow","UnityEditor.SceneView","UnityEditor.Timeline.TimelineWindow",
- "UnityEditor.VersionControl","UnityLogo","UnityLogoLarge","UpArrow","vcs_add","vcs_branch","vcs_change",
- "vcs_check","vcs_delete","vcs_document","vcs_edit","vcs_incoming","vcs_integrate","vcs_local","vcs_lock",
- "vcs_refresh","vcs_sync","vcs_unresolved","vcs_update","VerticalSplit","ViewToolMove On","ViewToolMove",
- "ViewToolOrbit On","ViewToolOrbit","ViewToolZoom On","ViewToolZoom","VisibilityOff","VisibilityOn",
- "VisualEffect Gizmo","VUMeterTextureHorizontal","VUMeterTextureVertical","WaitSpin00","WaitSpin01",
- "WaitSpin02","WaitSpin03","WaitSpin04","WaitSpin05","WaitSpin06","WaitSpin07","WaitSpin08","WaitSpin09",
- "WaitSpin10","WaitSpin11","WelcomeScreen.AssetStoreLogo","winbtn_graph","winbtn_graph_close_h",
- "winbtn_graph_max_h","winbtn_graph_min_h","winbtn_mac_close","winbtn_mac_close_a","winbtn_mac_close_h",
- "winbtn_mac_inact","winbtn_mac_max","winbtn_mac_max_a","winbtn_mac_max_h","winbtn_mac_min",
- "winbtn_mac_min_a","winbtn_mac_min_h","winbtn_win_close","winbtn_win_close_a","winbtn_win_close_h",
- "winbtn_win_max","winbtn_win_max_a","winbtn_win_max_h","winbtn_win_min","winbtn_win_min_a",
- "winbtn_win_min_h","winbtn_win_rest","winbtn_win_rest_a","winbtn_win_rest_h",
- "AvatarInspector/RightFingersIk","AvatarInspector/LeftFingersIk","AvatarInspector/RightFeetIk",
- "AvatarInspector/LeftFeetIk","AvatarInspector/RightFingers","AvatarInspector/LeftFingers",
- "AvatarInspector/RightArm","AvatarInspector/LeftArm","AvatarInspector/RightLeg","AvatarInspector/LeftLeg",
- "AvatarInspector/Head","AvatarInspector/Torso","AvatarInspector/MaskEditor_Root",
- "AvatarInspector/BodyPartPicker","AvatarInspector/BodySIlhouette","boo Script Icon","js Script Icon",
- "EyeDropper.Large","AboutWindow.MainHeader","AgeiaLogo","MonoLogo","PlayButtonProfile Anim",
- "StepButton Anim","PauseButton Anim","PlayButton Anim","MoveTool On","Icon Dropdown",
- "AvatarInspector/DotSelection","AvatarInspector/DotFrameDotted","AvatarInspector/DotFrame",
- "AvatarInspector/DotFill","AvatarInspector/RightHandZoom","AvatarInspector/LeftHandZoom",
- "AvatarInspector/HeadZoom","AvatarInspector/RightLeg","AvatarInspector/LeftLeg",
- "AvatarInspector/RightFingers","AvatarInspector/RightArm","AvatarInspector/LeftFingers",
- "AvatarInspector/LeftArm","AvatarInspector/Head","AvatarInspector/Torso",
- "AvatarInspector/RightHandZoomSilhouette","AvatarInspector/LeftHandZoomSilhouette",
- "AvatarInspector/HeadZoomSilhouette","AvatarInspector/BodySilhouette","lightMeter/redLight",
- "lightMeter/orangeLight","lightMeter/lightRim","lightMeter/greenLight","SceneviewAudio",
- "SceneviewLighting","TerrainInspector.TerrainToolSetHeight","AS Badge New","AS Badge Move",
- "AS Badge Delete","WelcomeScreen.UnityAnswersLogo","WelcomeScreen.UnityForumLogo",
- "WelcomeScreen.UnityBasicsLogo","WelcomeScreen.VideoTutLogo","WelcomeScreen.MainHeader","Icon Dropdown",
- "PrefabNormal Icon","PrefabNormal Icon","BuildSettings.BlackBerry.Small","BuildSettings.Tizen.Small",
- "BuildSettings.XBox360.Small","BuildSettings.PS3.Small","BuildSettings.SamsungTV.Small",
- "BuildSettings.BlackBerry","BuildSettings.Tizen","BuildSettings.XBox360","BuildSettings.PS3",
+ "_Help", "_Popup", "aboutwindow.mainheader", "ageialogo", "AlphabeticalSorting", "Animation.AddEvent",
+ "Animation.AddKeyframe", "Animation.EventMarker", "Animation.FirstKey", "Animation.LastKey",
+ "Animation.NextKey", "Animation.Play", "Animation.PrevKey", "Animation.Record", "Animation.SequencerLink",
+ "animationanimated", "animationdopesheetkeyframe", "animationkeyframe", "animationnocurve",
+ "animationvisibilitytoggleoff", "animationvisibilitytoggleon", "AnimationWrapModeMenu", "AssemblyLock",
+ "Asset Store", "Audio Mixer", "AvatarCompass", "AvatarController.Layer", "AvatarController.LayerHover",
+ "AvatarController.LayerSelected", "BodyPartPicker", "BodySilhouette", "DotFill", "DotFrame", "DotFrameDotted",
+ "DotSelection", "Head", "HeadIk", "HeadZoom", "HeadZoomSilhouette", "LeftArm", "LeftFeetIk", "LeftFingers",
+ "LeftFingersIk", "LeftHandZoom", "LeftHandZoomSilhouette", "LeftLeg", "MaskEditor_Root", "RightArm", "RightFeetIk",
+ "RightFingers", "RightFingersIk", "RightHandZoom", "RightHandZoomSilhouette", "RightLeg", "Torso", "AvatarPivot",
+ "back", "back@2x", "beginButton-On", "beginButton", "blendKey", "blendKeyOverlay", "blendKeySelected",
+ "blendSampler", "blueGroove", "BuildSettings.Android", "BuildSettings.Android.Small", "BuildSettings.Broadcom",
+ "BuildSettings.Editor", "BuildSettings.Editor.Small", "BuildSettings.Facebook",
+ "BuildSettings.Facebook.Small", "BuildSettings.FlashPlayer", "BuildSettings.FlashPlayer.Small",
+ "BuildSettings.iPhone", "BuildSettings.iPhone.Small", "BuildSettings.Lumin", "BuildSettings.Lumin.small",
+ "BuildSettings.Metro", "BuildSettings.Metro.Small", "BuildSettings.N3DS", "BuildSettings.N3DS.Small",
+ "BuildSettings.PS4", "BuildSettings.PS4.Small", "BuildSettings.PSM", "BuildSettings.PSM.Small",
+ "BuildSettings.PSP2", "BuildSettings.PSP2.Small", "BuildSettings.SelectedIcon", "BuildSettings.Standalone",
+ "BuildSettings.Standalone.Small", "BuildSettings.StandaloneBroadcom.Small",
+ "BuildSettings.StandaloneGLES20Emu.Small", "BuildSettings.StandaloneGLESEmu",
+ "BuildSettings.StandaloneGLESEmu.Small", "BuildSettings.Switch", "BuildSettings.Switch.Small",
+ "BuildSettings.tvOS", "BuildSettings.tvOS.Small", "BuildSettings.Web", "BuildSettings.Web.Small",
+ "BuildSettings.WebGL", "BuildSettings.WebGL.Small", "BuildSettings.WP8", "BuildSettings.WP8.Small",
+ "BuildSettings.Xbox360", "BuildSettings.Xbox360.Small", "BuildSettings.XboxOne",
+ "BuildSettings.XboxOne.Small", "BuildSettings.Xiaomi", "Camera Gizmo", "CheckerFloor", "Clipboard",
+ "ClothInspector.PaintTool", "ClothInspector.PaintValue", "ClothInspector.SelectTool",
+ "ClothInspector.SettingsTool", "ClothInspector.ViewValue", "CloudConnect", "Collab.Build",
+ "Collab.BuildFailed", "Collab.BuildSucceeded", "Collab.FileAdded", "Collab.FileConflict", "Collab.FileDeleted",
+ "Collab.FileIgnored", "Collab.FileMoved", "Collab.FileUpdated", "Collab.FolderAdded", "Collab.FolderConflict",
+ "Collab.FolderDeleted", "Collab.FolderIgnored", "Collab.FolderMoved", "Collab.FolderUpdated",
+ "Collab.NoInternet", "Collab", "Collab.Warning", "CollabConflict", "CollabError", "CollabNew", "CollabOffline",
+ "CollabProgress", "CollabPull", "CollabPush", "ColorPicker.ColorCycle", "ColorPicker.CycleColor",
+ "ColorPicker.CycleSlider", "ColorPicker.SliderCycle", "console.erroricon.inactive.sml", "console.erroricon",
+ "console.erroricon.sml", "console.infoicon", "console.infoicon.sml", "console.warnicon.inactive.sml",
+ "console.warnicon", "console.warnicon.sml", "curvekeyframe", "curvekeyframeselected",
+ "curvekeyframeselectedoverlay", "curvekeyframesemiselectedoverlay", "curvekeyframeweighted", "CustomSorting",
+ "d__Popup", "d_aboutwindow.mainheader", "d_ageialogo", "d_AlphabeticalSorting", "d_Animation.AddEvent",
+ "d_Animation.AddKeyframe", "d_Animation.EventMarker", "d_Animation.FirstKey", "d_Animation.LastKey",
+ "d_Animation.NextKey", "d_Animation.Play", "d_Animation.PrevKey", "d_Animation.Record",
+ "d_Animation.SequencerLink", "d_animationanimated", "d_animationkeyframe", "d_animationnocurve",
+ "d_animationvisibilitytoggleoff", "d_animationvisibilitytoggleon", "d_AnimationWrapModeMenu",
+ "d_AS Badge Delete", "d_AS Badge New", "d_AssemblyLock", "d_Asset Store", "d_Audio Mixer",
+ "d_AvatarBlendBackground", "d_AvatarBlendLeft", "d_AvatarBlendLeftA", "d_AvatarBlendRight",
+ "d_AvatarBlendRightA", "d_AvatarCompass", "d_AvatarPivot", "d_back", "d_back@2x", "d_beginButton-On",
+ "d_beginButton", "d_blueGroove", "d_BuildSettings.Android", "d_BuildSettings.Android.Small",
+ "d_BuildSettings.Broadcom", "d_BuildSettings.FlashPlayer", "d_BuildSettings.FlashPlayer.Small",
+ "d_BuildSettings.iPhone", "d_BuildSettings.iPhone.Small", "d_BuildSettings.Lumin",
+ "d_BuildSettings.Lumin.small", "d_BuildSettings.PS4", "d_BuildSettings.PS4.Small", "d_BuildSettings.PSP2",
+ "d_BuildSettings.PSP2.Small", "d_BuildSettings.SelectedIcon", "d_BuildSettings.Standalone",
+ "d_BuildSettings.Standalone.Small", "d_BuildSettings.tvOS", "d_BuildSettings.tvOS.Small",
+ "d_BuildSettings.Web", "d_BuildSettings.Web.Small", "d_BuildSettings.WebGL", "d_BuildSettings.WebGL.Small",
+ "d_BuildSettings.Xbox360", "d_BuildSettings.Xbox360.Small", "d_BuildSettings.XboxOne",
+ "d_BuildSettings.XboxOne.Small", "d_CheckerFloor", "d_CloudConnect", "d_Collab.FileAdded",
+ "d_Collab.FileConflict", "d_Collab.FileDeleted", "d_Collab.FileIgnored", "d_Collab.FileMoved",
+ "d_Collab.FileUpdated", "d_Collab.FolderAdded", "d_Collab.FolderConflict", "d_Collab.FolderDeleted",
+ "d_Collab.FolderIgnored", "d_Collab.FolderMoved", "d_Collab.FolderUpdated", "d_ColorPicker.CycleColor",
+ "d_ColorPicker.CycleSlider", "d_console.erroricon", "d_console.erroricon.sml", "d_console.infoicon",
+ "d_console.infoicon.sml", "d_console.warnicon", "d_console.warnicon.sml", "d_curvekeyframe",
+ "d_curvekeyframeselected", "d_curvekeyframeselectedoverlay", "d_curvekeyframesemiselectedoverlay",
+ "d_curvekeyframeweighted", "d_CustomSorting", "d_DefaultSorting", "d_EditCollider", "d_editcollision_16",
+ "d_editconstraints_16", "d_editicon.sml", "d_endButton-On", "d_endButton", "d_eyeDropper.Large",
+ "d_eyeDropper.sml", "d_Favorite", "d_FilterByLabel", "d_FilterByType", "d_FilterSelectedOnly",
+ "d_FilterSelectedOnly@2x", "d_forward", "d_forward@2x", "d_GEAR", "d_Groove", "d_HorizontalSplit",
+ "d_icon dropdown", "d_InspectorLock", "d_JointAngularLimits", "d_leftBracket", "d_Lighting",
+ "d_LightmapEditor.WindowTitle", "d_LookDevCenterLight", "d_LookDevCenterLight@2x", "d_LookDevClose",
+ "d_LookDevClose@2x", "d_LookDevEnvRotation", "d_LookDevEnvRotation@2x", "d_LookDevMirrorViews",
+ "d_LookDevMirrorViews@2x", "d_LookDevMirrorViewsActive", "d_LookDevMirrorViewsActive@2x",
+ "d_LookDevMirrorViewsInactive", "d_LookDevMirrorViewsInactive@2x", "d_LookDevObjRotation",
+ "d_LookDevObjRotation@2x", "d_LookDevPaneOption", "d_LookDevPaneOption@2x", "d_LookDevResetEnv",
+ "d_LookDevResetEnv@2x", "d_LookDevShadow", "d_LookDevShadow@2x", "d_LookDevSideBySide",
+ "d_LookDevSideBySide@2x", "d_LookDevSingle1", "d_LookDevSingle1@2x", "d_LookDevSingle2",
+ "d_LookDevSingle2@2x", "d_LookDevSplit", "d_LookDevSplit@2x", "d_LookDevZone", "d_LookDevZone@2x",
+ "d_Mirror", "d_model large", "d_monologo", "d_MoveTool on", "d_MoveTool", "d_Navigation", "d_Occlusion",
+ "d_P4_AddedLocal", "d_P4_AddedRemote", "d_P4_CheckOutLocal", "d_P4_CheckOutRemote", "d_P4_Conflicted",
+ "d_P4_DeletedLocal", "d_P4_DeletedRemote", "d_P4_Local", "d_P4_LockedLocal", "d_P4_LockedRemote",
+ "d_P4_OutOfSync", "d_Particle Effect", "d_PauseButton On", "d_PauseButton", "d_PlayButton On", "d_PlayButton",
+ "d_PlayButtonProfile On", "d_PlayButtonProfile", "d_playLoopOff", "d_playLoopOn", "d_preAudioAutoPlayOff",
+ "d_preAudioAutoPlayOn", "d_preAudioLoopOff", "d_preAudioLoopOn", "d_preAudioPlayOff", "d_preAudioPlayOn",
+ "d_PreMatCube", "d_PreMatCylinder", "d_PreMatLight0", "d_PreMatLight1", "d_PreMatSphere", "d_PreMatTorus",
+ "d_Preset.Context", "d_PreTextureAlpha", "d_PreTextureMipMapHigh", "d_PreTextureMipMapLow", "d_PreTextureRGB",
+ "d_Profiler.Audio", "d_Profiler.CPU", "d_Profiler.FirstFrame", "d_Profiler.GPU", "d_Profiler.LastFrame",
+ "d_Profiler.Memory", "d_Profiler.Network", "d_Profiler.NextFrame", "d_Profiler.Physics", "d_Profiler.PrevFrame",
+ "d_Profiler.Record", "d_Profiler.Rendering", "d_Profiler.Video", "d_ProfilerColumn.WarningCount", "d_Project",
+ "d_RectTool On", "d_RectTool", "d_RectTransformBlueprint", "d_RectTransformRaw", "d_redGroove", "d_Refresh",
+ "d_renderdoc", "d_rightBracket", "d_RotateTool On", "d_RotateTool", "d_ScaleTool On", "d_ScaleTool",
+ "d_SceneViewAlpha", "d_SceneViewAudio", "d_SceneViewFx", "d_SceneViewLighting", "d_SceneViewOrtho",
+ "d_SceneViewRGB", "d_ScrollShadow", "d_Settings", "d_SettingsIcon", "d_SocialNetworks.FacebookShare",
+ "d_SocialNetworks.LinkedInShare", "d_SocialNetworks.Tweet", "d_SocialNetworks.UDNOpen", "d_SpeedScale",
+ "d_StepButton On", "d_StepButton", "d_StepLeftButton-On", "d_StepLeftButton", "d_SVN_AddedLocal",
+ "d_SVN_Conflicted", "d_SVN_DeletedLocal", "d_SVN_Local", "d_SVN_LockedLocal", "d_SVN_OutOfSync", "d_tab_next",
+ "d_tab_next@2x", "d_tab_prev", "d_tab_prev@2x", "d_TerrainInspector.TerrainToolLower On",
+ "d_TerrainInspector.TerrainToolLowerAlt", "d_TerrainInspector.TerrainToolPlants On",
+ "d_TerrainInspector.TerrainToolPlants", "d_TerrainInspector.TerrainToolPlantsAlt On",
+ "d_TerrainInspector.TerrainToolPlantsAlt", "d_TerrainInspector.TerrainToolRaise On",
+ "d_TerrainInspector.TerrainToolRaise", "d_TerrainInspector.TerrainToolSetheight On",
+ "d_TerrainInspector.TerrainToolSetheight", "d_TerrainInspector.TerrainToolSetheightAlt On",
+ "d_TerrainInspector.TerrainToolSetheightAlt", "d_TerrainInspector.TerrainToolSettings On",
+ "d_TerrainInspector.TerrainToolSettings", "d_TerrainInspector.TerrainToolSmoothHeight On",
+ "d_TerrainInspector.TerrainToolSmoothHeight", "d_TerrainInspector.TerrainToolSplat On",
+ "d_TerrainInspector.TerrainToolSplat", "d_TerrainInspector.TerrainToolSplatAlt On",
+ "d_TerrainInspector.TerrainToolSplatAlt", "d_TerrainInspector.TerrainToolTrees On",
+ "d_TerrainInspector.TerrainToolTrees", "d_TerrainInspector.TerrainToolTreesAlt On",
+ "d_TerrainInspector.TerrainToolTreesAlt", "d_TimelineDigIn", "d_TimelineEditModeMixOFF",
+ "d_TimelineEditModeMixON", "d_TimelineEditModeReplaceOFF", "d_TimelineEditModeReplaceON",
+ "d_TimelineEditModeRippleOFF", "d_TimelineEditModeRippleON", "d_TimelineSelector", "d_Toolbar Minus",
+ "d_Toolbar Plus More", "d_Toolbar Plus", "d_ToolHandleCenter", "d_ToolHandleGlobal", "d_ToolHandleLocal",
+ "d_ToolHandlePivot", "d_tranp", "d_TransformTool On", "d_TransformTool", "d_tree_icon", "d_tree_icon_branch",
+ "d_tree_icon_branch_frond", "d_tree_icon_frond", "d_tree_icon_leaf", "d_TreeEditor.AddBranches",
+ "d_TreeEditor.AddLeaves", "d_TreeEditor.Branch On", "d_TreeEditor.Branch", "d_TreeEditor.BranchFreeHand On",
+ "d_TreeEditor.BranchFreeHand", "d_TreeEditor.BranchRotate On", "d_TreeEditor.BranchRotate",
+ "d_TreeEditor.BranchScale On", "d_TreeEditor.BranchScale", "d_TreeEditor.BranchTranslate On",
+ "d_TreeEditor.BranchTranslate", "d_TreeEditor.Distribution On", "d_TreeEditor.Distribution",
+ "d_TreeEditor.Duplicate", "d_TreeEditor.Geometry On", "d_TreeEditor.Geometry", "d_TreeEditor.Leaf On",
+ "d_TreeEditor.Leaf", "d_TreeEditor.LeafFreeHand On", "d_TreeEditor.LeafFreeHand", "d_TreeEditor.LeafRotate On",
+ "d_TreeEditor.LeafRotate", "d_TreeEditor.LeafScale On", "d_TreeEditor.LeafScale",
+ "d_TreeEditor.LeafTranslate On", "d_TreeEditor.LeafTranslate", "d_TreeEditor.Material On",
+ "d_TreeEditor.Material", "d_TreeEditor.Refresh", "d_TreeEditor.Trash", "d_TreeEditor.Wind On",
+ "d_TreeEditor.Wind", "d_UnityEditor.AnimationWindow", "d_UnityEditor.ConsoleWindow",
+ "d_UnityEditor.DebugInspectorWindow", "d_UnityEditor.FindDependencies", "d_UnityEditor.GameView",
+ "d_UnityEditor.HierarchyWindow", "d_UnityEditor.InspectorWindow", "d_UnityEditor.LookDevView",
+ "d_UnityEditor.ProfilerWindow", "d_UnityEditor.SceneHierarchyWindow", "d_UnityEditor.SceneView",
+ "d_UnityEditor.Timeline.TimelineWindow", "d_UnityEditor.VersionControl", "d_UnityLogo", "d_VerticalSplit",
+ "d_ViewToolMove On", "d_ViewToolMove", "d_ViewToolOrbit On", "d_ViewToolOrbit", "d_ViewToolZoom On",
+ "d_ViewToolZoom", "d_VisibilityOff", "d_VisibilityOn", "d_VUMeterTextureHorizontal", "d_VUMeterTextureVertical",
+ "d_WaitSpin00", "d_WaitSpin01", "d_WaitSpin02", "d_WaitSpin03", "d_WaitSpin04", "d_WaitSpin05", "d_WaitSpin06",
+ "d_WaitSpin07", "d_WaitSpin08", "d_WaitSpin09", "d_WaitSpin10", "d_WaitSpin11", "d_WelcomeScreen.AssetStoreLogo",
+ "d_winbtn_graph", "d_winbtn_graph_close_h", "d_winbtn_graph_max_h", "d_winbtn_graph_min_h",
+ "d_winbtn_mac_close", "d_winbtn_mac_close_a", "d_winbtn_mac_close_h", "d_winbtn_mac_inact", "d_winbtn_mac_max",
+ "d_winbtn_mac_max_a", "d_winbtn_mac_max_h", "d_winbtn_mac_min", "d_winbtn_mac_min_a", "d_winbtn_mac_min_h",
+ "d_winbtn_win_close", "d_winbtn_win_close_a", "d_winbtn_win_close_h", "d_winbtn_win_max", "d_winbtn_win_max_a",
+ "d_winbtn_win_max_h", "d_winbtn_win_min", "d_winbtn_win_min_a", "d_winbtn_win_min_h", "d_winbtn_win_rest",
+ "d_winbtn_win_rest_a", "d_winbtn_win_rest_h", "DefaultSorting", "EditCollider", "editcollision_16",
+ "editconstraints_16", "editicon.sml", "endButton-On", "endButton", "eyeDropper.Large", "eyeDropper.sml",
+ "Favorite", "FilterByLabel", "FilterByType", "FilterSelectedOnly", "FilterSelectedOnly@2x", "forward",
+ "forward@2x", "GEAR", "Grid.BoxTool", "Grid.Default", "Grid.EraserTool", "Grid.FillTool", "Grid.MoveTool",
+ "Grid.PaintTool", "Grid.PickingTool", "Grid.SelectTool", "Groove", "align_horizontally",
+ "align_horizontally_center", "align_horizontally_center_active", "align_horizontally_left",
+ "align_horizontally_left_active", "align_horizontally_right", "align_horizontally_right_active",
+ "align_vertically", "align_vertically_bottom", "align_vertically_bottom_active", "align_vertically_center",
+ "align_vertically_center_active", "align_vertically_top", "align_vertically_top_active",
+ "d_align_horizontally", "d_align_horizontally_center", "d_align_horizontally_center_active",
+ "d_align_horizontally_left", "d_align_horizontally_left_active", "d_align_horizontally_right",
+ "d_align_horizontally_right_active", "d_align_vertically", "d_align_vertically_bottom",
+ "d_align_vertically_bottom_active", "d_align_vertically_center", "d_align_vertically_center_active",
+ "d_align_vertically_top", "d_align_vertically_top_active", "HorizontalSplit", "icon dropdown",
+ "InspectorLock", "JointAngularLimits", "KnobCShape", "KnobCShapeMini", "leftBracket", "Lighting",
+ "LightmapEditor.WindowTitle", "Lightmapping", "d_greenLight", "d_lightOff", "d_lightRim", "d_orangeLight",
+ "d_redLight", "greenLight", "lightOff", "lightRim", "orangeLight", "redLight", "LockIcon-On", "LockIcon",
+ "LookDevCenterLight", "LookDevCenterLightl@2x", "LookDevClose", "LookDevClose@2x", "LookDevEnvRotation",
+ "LookDevEnvRotation@2x", "LookDevEyedrop", "LookDevLight", "LookDevLight@2x", "LookDevMirrorViewsActive",
+ "LookDevMirrorViewsActive@2x", "LookDevMirrorViewsInactive", "LookDevMirrorViewsInactive@2x",
+ "LookDevObjRotation", "LookDevObjRotation@2x", "LookDevPaneOption", "LookDevPaneOption@2x", "LookDevResetEnv",
+ "LookDevResetEnv@2x", "LookDevShadow", "LookDevShadow@2x", "LookDevShadowFrame", "LookDevShadowFrame@2x",
+ "LookDevSideBySide", "LookDevSideBySide@2x", "LookDevSingle1", "LookDevSingle1@2x", "LookDevSingle2",
+ "LookDevSingle2@2x", "LookDevSplit", "LookDevSplit@2x", "LookDevZone", "LookDevZone@2x", "loop", "Mirror",
+ "monologo", "MoveTool on", "MoveTool", "Navigation", "Occlusion", "P4_AddedLocal", "P4_AddedRemote",
+ "P4_BlueLeftParenthesis", "P4_BlueRightParenthesis", "P4_CheckOutLocal", "P4_CheckOutRemote", "P4_Conflicted",
+ "P4_DeletedLocal", "P4_DeletedRemote", "P4_Local", "P4_LockedLocal", "P4_LockedRemote", "P4_OutOfSync",
+ "P4_RedLeftParenthesis", "P4_RedRightParenthesis", "P4_Updating", "PackageBadgeDelete", "PackageBadgeNew",
+ "Particle Effect", "PauseButton On", "PauseButton", "PlayButton On", "PlayButton", "PlayButtonProfile On",
+ "PlayButtonProfile", "playLoopOff", "playLoopOn", "playSpeed", "preAudioAutoPlayOff", "preAudioAutoPlayOn",
+ "preAudioLoopOff", "preAudioLoopOn", "preAudioPlayOff", "preAudioPlayOn", "PreMatCube", "PreMatCylinder",
+ "PreMatLight0", "PreMatLight1", "PreMatQuad", "PreMatSphere", "PreMatTorus", "Preset.Context", "PreTextureAlpha",
+ "PreTextureArrayFirstSlice", "PreTextureArrayLastSlice", "PreTextureMipMapHigh", "PreTextureMipMapLow",
+ "PreTextureRGB", "AreaLight Gizmo", "AreaLight Icon", "Assembly Icon", "AssetStore Icon", "AudioMixerView Icon",
+ "AudioSource Gizmo", "Camera Gizmo", "CGProgram Icon", "ChorusFilter Icon", "CollabChanges Icon",
+ "CollabChangesConflict Icon", "CollabChangesDeleted Icon", "CollabConflict Icon", "CollabCreate Icon",
+ "CollabDeleted Icon", "CollabEdit Icon", "CollabExclude Icon", "CollabMoved Icon", "cs Script Icon",
+ "d_AudioMixerView Icon", "d_CollabChanges Icon", "d_CollabChangesConflict Icon", "d_CollabChangesDeleted Icon",
+ "d_CollabConflict Icon", "d_CollabCreate Icon", "d_CollabDeleted Icon", "d_CollabEdit Icon",
+ "d_CollabExclude Icon", "d_CollabMoved Icon", "d_GridLayoutGroup Icon", "d_HorizontalLayoutGroup Icon",
+ "d_Prefab Icon", "d_PrefabModel Icon", "d_PrefabVariant Icon", "d_VerticalLayoutGroup Icon",
+ "DefaultSlate Icon", "DirectionalLight Gizmo", "DirectionalLight Icon", "DiscLight Gizmo", "DiscLight Icon",
+ "dll Script Icon", "EchoFilter Icon", "Favorite Icon", "Folder Icon", "FolderEmpty Icon",
+ "FolderFavorite Icon", "GameManager Icon", "GridBrush Icon", "HighPassFilter Icon",
+ "HorizontalLayoutGroup Icon", "LensFlare Gizmo", "LightingDataAssetParent Icon", "LightProbeGroup Gizmo",
+ "LightProbeProxyVolume Gizmo", "LowPassFilter Icon", "Main Light Gizmo", "MetaFile Icon",
+ "Microphone Icon", "MuscleClip Icon", "ParticleSystem Gizmo", "PointLight Gizmo", "Prefab Icon",
+ "PrefabModel Icon", "PrefabOverlayAdded Icon", "PrefabOverlayModified Icon", "PrefabOverlayRemoved Icon",
+ "PrefabVariant Icon", "Projector Gizmo", "RaycastCollider Icon", "ReflectionProbe Gizmo",
+ "ReverbFilter Icon", "SceneSet Icon", "Search Icon", "SoftlockProjectBrowser Icon", "SpeedTreeModel Icon",
+ "SpotLight Gizmo", "Spotlight Icon", "SpriteCollider Icon", "sv_icon_dot0_pix16_gizmo",
+ "sv_icon_dot10_pix16_gizmo", "sv_icon_dot11_pix16_gizmo", "sv_icon_dot12_pix16_gizmo",
+ "sv_icon_dot13_pix16_gizmo", "sv_icon_dot14_pix16_gizmo", "sv_icon_dot15_pix16_gizmo",
+ "sv_icon_dot1_pix16_gizmo", "sv_icon_dot2_pix16_gizmo", "sv_icon_dot3_pix16_gizmo",
+ "sv_icon_dot4_pix16_gizmo", "sv_icon_dot5_pix16_gizmo", "sv_icon_dot6_pix16_gizmo",
+ "sv_icon_dot7_pix16_gizmo", "sv_icon_dot8_pix16_gizmo", "sv_icon_dot9_pix16_gizmo",
+ "AnimatorController Icon", "AnimatorState Icon", "AnimatorStateMachine Icon",
+ "AnimatorStateTransition Icon", "BlendTree Icon", "AnimationWindowEvent Icon", "AudioMixerController Icon",
+ "DefaultAsset Icon", "EditorSettings Icon", "AnyStateNode Icon", "HumanTemplate Icon",
+ "LightingDataAsset Icon", "LightmapParameters Icon", "Preset Icon", "SceneAsset Icon",
+ "SubstanceArchive Icon", "AssemblyDefinitionAsset Icon", "NavMeshAgent Icon", "NavMeshData Icon",
+ "NavMeshObstacle Icon", "OffMeshLink Icon", "AnalyticsTracker Icon", "Animation Icon",
+ "AnimationClip Icon", "AimConstraint Icon", "d_AimConstraint Icon", "d_LookAtConstraint Icon",
+ "d_ParentConstraint Icon", "d_PositionConstraint Icon", "d_RotationConstraint Icon",
+ "d_ScaleConstraint Icon", "LookAtConstraint Icon", "ParentConstraint Icon", "PositionConstraint Icon",
+ "RotationConstraint Icon", "ScaleConstraint Icon", "Animator Icon", "AnimatorOverrideController Icon",
+ "AreaEffector2D Icon", "AudioMixerGroup Icon", "AudioMixerSnapshot Icon", "AudioSpatializerMicrosoft Icon",
+ "AudioChorusFilter Icon", "AudioClip Icon", "AudioDistortionFilter Icon", "AudioEchoFilter Icon",
+ "AudioHighPassFilter Icon", "AudioListener Icon", "AudioLowPassFilter Icon", "AudioReverbFilter Icon",
+ "AudioReverbZone Icon", "AudioSource Icon", "Avatar Icon", "AvatarMask Icon", "BillboardAsset Icon",
+ "BillboardRenderer Icon", "BoxCollider Icon", "BoxCollider2D Icon", "BuoyancyEffector2D Icon", "Camera Icon",
+ "Canvas Icon", "CanvasGroup Icon", "CanvasRenderer Icon", "CapsuleCollider Icon", "CapsuleCollider2D Icon",
+ "CharacterController Icon", "CharacterJoint Icon", "CircleCollider2D Icon", "Cloth Icon",
+ "CompositeCollider2D Icon", "ComputeShader Icon", "ConfigurableJoint Icon", "ConstantForce Icon",
+ "ConstantForce2D Icon", "Cubemap Icon", "d_Canvas Icon", "d_CanvasGroup Icon", "d_CanvasRenderer Icon",
+ "d_GameObject Icon", "d_LightProbeProxyVolume Icon", "d_ParticleSystem Icon", "d_ParticleSystemForceField Icon",
+ "d_RectTransform Icon", "d_StreamingController Icon", "DistanceJoint2D Icon", "EdgeCollider2D Icon",
+ "d_EventSystem Icon", "d_EventTrigger Icon", "d_Physics2DRaycaster Icon", "d_PhysicsRaycaster Icon",
+ "d_StandaloneInputModule Icon", "d_TouchInputModule Icon", "EventSystem Icon", "EventTrigger Icon",
+ "HoloLensInputModule Icon", "Physics2DRaycaster Icon", "PhysicsRaycaster Icon", "StandaloneInputModule Icon",
+ "TouchInputModule Icon", "SpriteShapeRenderer Icon", "VisualTreeAsset Icon", "d_VisualEffect Icon",
+ "d_VisualEffectAsset Icon", "VisualEffect Icon", "VisualEffectAsset Icon", "FixedJoint Icon",
+ "FixedJoint2D Icon", "Flare Icon", "FlareLayer Icon", "Font Icon", "FrictionJoint2D Icon",
+ "GameObject Icon", "Grid Icon", "GUILayer Icon", "GUISkin Icon", "GUIText Icon", "GUITexture Icon",
+ "Halo Icon", "HingeJoint Icon", "HingeJoint2D Icon", "LensFlare Icon", "Light Icon", "LightProbeGroup Icon",
+ "LightProbeProxyVolume Icon", "LightProbes Icon", "LineRenderer Icon", "LODGroup Icon", "Material Icon",
+ "Mesh Icon", "MeshCollider Icon", "MeshFilter Icon", "MeshRenderer Icon", "Motion Icon", "MovieTexture Icon",
+ "NetworkAnimator Icon", "NetworkDiscovery Icon", "NetworkIdentity Icon", "NetworkLobbyManager Icon",
+ "NetworkLobbyPlayer Icon", "NetworkManager Icon", "NetworkManagerHUD Icon", "NetworkMigrationManager Icon",
+ "NetworkProximityChecker Icon", "NetworkStartPosition Icon", "NetworkTransform Icon",
+ "NetworkTransformChild Icon", "NetworkTransformVisualizer Icon", "NetworkView Icon", "OcclusionArea Icon",
+ "OcclusionPortal Icon", "ParticleSystem Icon", "ParticleSystemForceField Icon", "PhysicMaterial Icon",
+ "PhysicsMaterial2D Icon", "PlatformEffector2D Icon", "d_PlayableDirector Icon", "PlayableDirector Icon",
+ "PointEffector2D Icon", "PolygonCollider2D Icon", "ProceduralMaterial Icon", "Projector Icon",
+ "RectTransform Icon", "ReflectionProbe Icon", "RelativeJoint2D Icon", "d_SortingGroup Icon",
+ "SortingGroup Icon", "RenderTexture Icon", "Rigidbody Icon", "Rigidbody2D Icon", "ScriptableObject Icon",
+ "Shader Icon", "ShaderVariantCollection Icon", "SkinnedMeshRenderer Icon", "Skybox Icon", "SliderJoint2D Icon",
+ "TrackedPoseDriver Icon", "SphereCollider Icon", "SpringJoint Icon", "SpringJoint2D Icon", "Sprite Icon",
+ "SpriteMask Icon", "SpriteRenderer Icon", "StreamingController Icon", "StyleSheet Icon", "SurfaceEffector2D Icon",
+ "TargetJoint2D Icon", "Terrain Icon", "TerrainCollider Icon", "TerrainData Icon", "TextAsset Icon",
+ "TextMesh Icon", "Texture Icon", "Texture2D Icon", "Tile Icon", "Tilemap Icon", "TilemapCollider2D Icon",
+ "TilemapRenderer Icon", "d_TimelineAsset Icon", "TimelineAsset Icon", "TrailRenderer Icon", "Transform Icon",
+ "SpriteAtlas Icon", "AspectRatioFitter Icon", "Button Icon", "CanvasScaler Icon", "ContentSizeFitter Icon",
+ "d_AspectRatioFitter Icon", "d_CanvasScaler Icon", "d_ContentSizeFitter Icon", "d_FreeformLayoutGroup Icon",
+ "d_GraphicRaycaster Icon", "d_GridLayoutGroup Icon", "d_HorizontalLayoutGroup Icon", "d_LayoutElement Icon",
+ "d_PhysicalResolution Icon", "d_ScrollViewArea Icon", "d_SelectionList Icon", "d_SelectionListItem Icon",
+ "d_SelectionListTemplate Icon", "d_VerticalLayoutGroup Icon", "Dropdown Icon", "FreeformLayoutGroup Icon",
+ "GraphicRaycaster Icon", "GridLayoutGroup Icon", "HorizontalLayoutGroup Icon", "Image Icon", "InputField Icon",
+ "LayoutElement Icon", "Mask Icon", "Outline Icon", "PositionAsUV1 Icon", "RawImage Icon", "RectMask2D Icon",
+ "Scrollbar Icon", "ScrollRect Icon", "Selectable Icon", "Shadow Icon", "Slider Icon", "Text Icon", "Toggle Icon",
+ "ToggleGroup Icon", "VerticalLayoutGroup Icon", "VideoClip Icon", "VideoPlayer Icon", "VisualEffect Icon",
+ "VisualEffectAsset Icon", "WheelCollider Icon", "WheelJoint2D Icon", "WindZone Icon",
+ "SpatialMappingCollider Icon", "SpatialMappingRenderer Icon", "WorldAnchor Icon", "UssScript Icon",
+ "UxmlScript Icon", "VerticalLayoutGroup Icon", "VideoEffect Icon", "VisualEffect Gizmo",
+ "VisualEffectAsset Icon", "AnchorBehaviour Icon", "AnchorInputListenerBehaviour Icon",
+ "AnchorStageBehaviour Icon", "CloudRecoBehaviour Icon", "ContentPlacementBehaviour Icon",
+ "ContentPositioningBehaviour Icon", "CylinderTargetBehaviour Icon", "d_AnchorBehaviour Icon",
+ "d_AnchorInputListenerBehaviour Icon", "d_AnchorStageBehaviour Icon", "d_CloudRecoBehaviour Icon",
+ "d_ContentPlacementBehaviour Icon", "d_ContentPositioningBehaviour Icon", "d_CylinderTargetBehaviour Icon",
+ "d_ImageTargetBehaviour Icon", "d_MidAirPositionerBehaviour Icon", "d_ModelTargetBehaviour Icon",
+ "d_MultiTargetBehaviour Icon", "d_ObjectTargetBehaviour Icon", "d_PlaneFinderBehaviour Icon",
+ "d_UserDefinedTargetBuildingBehaviour Icon", "d_VirtualButtonBehaviour Icon", "d_VuforiaBehaviour Icon",
+ "d_VuMarkBehaviour Icon", "d_WireframeBehaviour Icon", "ImageTargetBehaviour Icon",
+ "MidAirPositionerBehaviour Icon", "ModelTargetBehaviour Icon", "MultiTargetBehaviour Icon",
+ "ObjectTargetBehaviour Icon", "PlaneFinderBehaviour Icon", "UserDefinedTargetBuildingBehaviour Icon",
+ "VirtualButtonBehaviour Icon", "VuforiaBehaviour Icon", "VuMarkBehaviour Icon", "WireframeBehaviour Icon",
+ "WindZone Gizmo", "Profiler.Audio", "Profiler.CPU", "Profiler.FirstFrame", "Profiler.GlobalIllumination",
+ "Profiler.GPU", "Profiler.Instrumentation", "Profiler.LastFrame", "Profiler.Memory", "Profiler.NetworkMessages",
+ "Profiler.NetworkOperations", "Profiler.NextFrame", "Profiler.Physics", "Profiler.Physics2D",
+ "Profiler.PrevFrame", "Profiler.Record", "Profiler.Rendering", "Profiler.UI", "Profiler.UIDetails",
+ "Profiler.Video", "ProfilerColumn.WarningCount", "Project", "RectTool On", "RectTool", "RectTransformBlueprint",
+ "RectTransformRaw", "redGroove", "Refresh", "renderdoc", "rightBracket", "RotateTool On", "RotateTool",
+ "SaveActive", "SaveFromPlay", "SavePassive", "ScaleTool On", "ScaleTool", "SceneLoadIn", "SceneLoadOut",
+ "SceneSave", "SceneSaveGrey", "SceneViewAlpha", "SceneViewAudio", "SceneViewFx", "SceneViewLighting",
+ "SceneViewOrtho", "SceneViewRGB", "ScrollShadow", "Settings", "SettingsIcon", "SocialNetworks.FacebookShare",
+ "SocialNetworks.LinkedInShare", "SocialNetworks.Tweet", "SocialNetworks.UDNLogo", "SocialNetworks.UDNOpen",
+ "SoftlockInline", "SpeedScale", "StateMachineEditor.ArrowTip", "StateMachineEditor.ArrowTipSelected",
+ "StateMachineEditor.Background", "StateMachineEditor.State", "StateMachineEditor.StateHover",
+ "StateMachineEditor.StateSelected", "StateMachineEditor.StateSub", "StateMachineEditor.StateSubHover",
+ "StateMachineEditor.StateSubSelected", "StateMachineEditor.UpButton", "StateMachineEditor.UpButtonHover",
+ "StepButton On", "StepButton", "StepLeftButton-On", "StepLeftButton", "sticky_arrow", "sticky_p4", "sticky_skin",
+ "sv_icon_dot0_sml", "sv_icon_dot10_sml", "sv_icon_dot11_sml", "sv_icon_dot12_sml", "sv_icon_dot13_sml",
+ "sv_icon_dot14_sml", "sv_icon_dot15_sml", "sv_icon_dot1_sml", "sv_icon_dot2_sml", "sv_icon_dot3_sml",
+ "sv_icon_dot4_sml", "sv_icon_dot5_sml", "sv_icon_dot6_sml", "sv_icon_dot7_sml", "sv_icon_dot8_sml",
+ "sv_icon_dot9_sml", "sv_icon_name0", "sv_icon_name1", "sv_icon_name2", "sv_icon_name3", "sv_icon_name4",
+ "sv_icon_name5", "sv_icon_name6", "sv_icon_name7", "sv_icon_none", "sv_label_0", "sv_label_1", "sv_label_2",
+ "sv_label_3", "sv_label_4", "sv_label_5", "sv_label_6", "sv_label_7", "SVN_AddedLocal", "SVN_Conflicted",
+ "SVN_DeletedLocal", "SVN_Local", "SVN_LockedLocal", "SVN_OutOfSync", "tab_next", "tab_next@2x", "tab_prev",
+ "tab_prev@2x", "TerrainInspector.TerrainToolLower On", "TerrainInspector.TerrainToolLower",
+ "TerrainInspector.TerrainToolLowerAlt", "TerrainInspector.TerrainToolPlants On",
+ "TerrainInspector.TerrainToolPlants", "TerrainInspector.TerrainToolPlantsAlt On",
+ "TerrainInspector.TerrainToolPlantsAlt", "TerrainInspector.TerrainToolRaise On",
+ "TerrainInspector.TerrainToolRaise", "TerrainInspector.TerrainToolSculpt On",
+ "TerrainInspector.TerrainToolSculpt", "TerrainInspector.TerrainToolSetheight On",
+ "TerrainInspector.TerrainToolSetheight", "TerrainInspector.TerrainToolSetheightAlt On",
+ "TerrainInspector.TerrainToolSetheightAlt", "TerrainInspector.TerrainToolSettings On",
+ "TerrainInspector.TerrainToolSettings", "TerrainInspector.TerrainToolSmoothHeight On",
+ "TerrainInspector.TerrainToolSmoothHeight", "TerrainInspector.TerrainToolSplat On",
+ "TerrainInspector.TerrainToolSplat", "TerrainInspector.TerrainToolSplatAlt On",
+ "TerrainInspector.TerrainToolSplatAlt", "TerrainInspector.TerrainToolTrees On",
+ "TerrainInspector.TerrainToolTrees", "TerrainInspector.TerrainToolTreesAlt On",
+ "TerrainInspector.TerrainToolTreesAlt", "TestFailed", "TestIgnored", "TestInconclusive", "TestNormal",
+ "TestPassed", "TestStopwatch", "TimelineClipBG", "TimelineClipFG", "TimelineDigIn", "TimelineEditModeMixOFF",
+ "TimelineEditModeMixON", "TimelineEditModeReplaceOFF", "TimelineEditModeReplaceON", "TimelineEditModeRippleOFF",
+ "TimelineEditModeRippleON", "TimelineSelector", "Toolbar Minus", "Toolbar Plus More", "Toolbar Plus",
+ "ToolHandleCenter", "ToolHandleGlobal", "ToolHandleLocal", "ToolHandlePivot", "tranp", "TransformTool On",
+ "TransformTool", "tree_icon", "tree_icon_branch", "tree_icon_branch_frond", "tree_icon_frond", "tree_icon_leaf",
+ "TreeEditor.AddBranches", "TreeEditor.AddLeaves", "TreeEditor.Branch On", "TreeEditor.Branch",
+ "TreeEditor.BranchFreeHand On", "TreeEditor.BranchFreeHand", "TreeEditor.BranchRotate On",
+ "TreeEditor.BranchRotate", "TreeEditor.BranchScale On", "TreeEditor.BranchScale",
+ "TreeEditor.BranchTranslate On", "TreeEditor.BranchTranslate", "TreeEditor.Distribution On",
+ "TreeEditor.Distribution", "TreeEditor.Duplicate", "TreeEditor.Geometry On", "TreeEditor.Geometry",
+ "TreeEditor.Leaf On", "TreeEditor.Leaf", "TreeEditor.LeafFreeHand On", "TreeEditor.LeafFreeHand",
+ "TreeEditor.LeafRotate On", "TreeEditor.LeafRotate", "TreeEditor.LeafScale On", "TreeEditor.LeafScale",
+ "TreeEditor.LeafTranslate On", "TreeEditor.LeafTranslate", "TreeEditor.Material On", "TreeEditor.Material",
+ "TreeEditor.Refresh", "TreeEditor.Trash", "TreeEditor.Wind On", "TreeEditor.Wind", "UnityEditor.AnimationWindow",
+ "UnityEditor.ConsoleWindow", "UnityEditor.DebugInspectorWindow", "UnityEditor.FindDependencies",
+ "UnityEditor.GameView", "UnityEditor.Graphs.AnimatorControllerTool", "UnityEditor.HierarchyWindow",
+ "UnityEditor.InspectorWindow", "UnityEditor.LookDevView", "UnityEditor.ProfilerWindow",
+ "UnityEditor.SceneHierarchyWindow", "UnityEditor.SceneView", "UnityEditor.Timeline.TimelineWindow",
+ "UnityEditor.VersionControl", "UnityLogo", "UnityLogoLarge", "UpArrow", "vcs_add", "vcs_branch", "vcs_change",
+ "vcs_check", "vcs_delete", "vcs_document", "vcs_edit", "vcs_incoming", "vcs_integrate", "vcs_local", "vcs_lock",
+ "vcs_refresh", "vcs_sync", "vcs_unresolved", "vcs_update", "VerticalSplit", "ViewToolMove On", "ViewToolMove",
+ "ViewToolOrbit On", "ViewToolOrbit", "ViewToolZoom On", "ViewToolZoom", "VisibilityOff", "VisibilityOn",
+ "VisualEffect Gizmo", "VUMeterTextureHorizontal", "VUMeterTextureVertical", "WaitSpin00", "WaitSpin01",
+ "WaitSpin02", "WaitSpin03", "WaitSpin04", "WaitSpin05", "WaitSpin06", "WaitSpin07", "WaitSpin08", "WaitSpin09",
+ "WaitSpin10", "WaitSpin11", "WelcomeScreen.AssetStoreLogo", "winbtn_graph", "winbtn_graph_close_h",
+ "winbtn_graph_max_h", "winbtn_graph_min_h", "winbtn_mac_close", "winbtn_mac_close_a", "winbtn_mac_close_h",
+ "winbtn_mac_inact", "winbtn_mac_max", "winbtn_mac_max_a", "winbtn_mac_max_h", "winbtn_mac_min",
+ "winbtn_mac_min_a", "winbtn_mac_min_h", "winbtn_win_close", "winbtn_win_close_a", "winbtn_win_close_h",
+ "winbtn_win_max", "winbtn_win_max_a", "winbtn_win_max_h", "winbtn_win_min", "winbtn_win_min_a",
+ "winbtn_win_min_h", "winbtn_win_rest", "winbtn_win_rest_a", "winbtn_win_rest_h",
+ "AvatarInspector/RightFingersIk", "AvatarInspector/LeftFingersIk", "AvatarInspector/RightFeetIk",
+ "AvatarInspector/LeftFeetIk", "AvatarInspector/RightFingers", "AvatarInspector/LeftFingers",
+ "AvatarInspector/RightArm", "AvatarInspector/LeftArm", "AvatarInspector/RightLeg", "AvatarInspector/LeftLeg",
+ "AvatarInspector/Head", "AvatarInspector/Torso", "AvatarInspector/MaskEditor_Root",
+ "AvatarInspector/BodyPartPicker", "AvatarInspector/BodySIlhouette", "boo Script Icon", "js Script Icon",
+ "EyeDropper.Large", "AboutWindow.MainHeader", "AgeiaLogo", "MonoLogo", "PlayButtonProfile Anim",
+ "StepButton Anim", "PauseButton Anim", "PlayButton Anim", "MoveTool On", "Icon Dropdown",
+ "AvatarInspector/DotSelection", "AvatarInspector/DotFrameDotted", "AvatarInspector/DotFrame",
+ "AvatarInspector/DotFill", "AvatarInspector/RightHandZoom", "AvatarInspector/LeftHandZoom",
+ "AvatarInspector/HeadZoom", "AvatarInspector/RightLeg", "AvatarInspector/LeftLeg",
+ "AvatarInspector/RightFingers", "AvatarInspector/RightArm", "AvatarInspector/LeftFingers",
+ "AvatarInspector/LeftArm", "AvatarInspector/Head", "AvatarInspector/Torso",
+ "AvatarInspector/RightHandZoomSilhouette", "AvatarInspector/LeftHandZoomSilhouette",
+ "AvatarInspector/HeadZoomSilhouette", "AvatarInspector/BodySilhouette", "lightMeter/redLight",
+ "lightMeter/orangeLight", "lightMeter/lightRim", "lightMeter/greenLight", "SceneviewAudio",
+ "SceneviewLighting", "TerrainInspector.TerrainToolSetHeight", "AS Badge New", "AS Badge Move",
+ "AS Badge Delete", "WelcomeScreen.UnityAnswersLogo", "WelcomeScreen.UnityForumLogo",
+ "WelcomeScreen.UnityBasicsLogo", "WelcomeScreen.VideoTutLogo", "WelcomeScreen.MainHeader", "Icon Dropdown",
+ "PrefabNormal Icon", "PrefabNormal Icon", "BuildSettings.BlackBerry.Small", "BuildSettings.Tizen.Small",
+ "BuildSettings.XBox360.Small", "BuildSettings.PS3.Small", "BuildSettings.SamsungTV.Small",
+ "BuildSettings.BlackBerry", "BuildSettings.Tizen", "BuildSettings.XBox360", "BuildSettings.PS3",
"BuildSettings.SamsungTV"
};
#endregion
}
-#endif
\ No newline at end of file
+#endif
diff --git a/Editor/ToolBar.meta b/Editor/ToolBar.meta
index 728d15b..ab63f9b 100644
--- a/Editor/ToolBar.meta
+++ b/Editor/ToolBar.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 93fb9d2834752b649891dba19cba5169
+guid: fb7e9c820d4ba2b4d836ffc849b55067
folderAsset: yes
DefaultImporter:
externalObjects: {}
diff --git a/Editor/ToolBarExtension.meta b/Editor/ToolBarExtension.meta
new file mode 100644
index 0000000..728d15b
--- /dev/null
+++ b/Editor/ToolBarExtension.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 93fb9d2834752b649891dba19cba5169
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/ToolBar/BuildSettingWindow.cs b/Editor/ToolBarExtension/BuildSettingWindow.cs
similarity index 100%
rename from Editor/ToolBar/BuildSettingWindow.cs
rename to Editor/ToolBarExtension/BuildSettingWindow.cs
diff --git a/Editor/ToolBar/BuildSettingWindow.cs.meta b/Editor/ToolBarExtension/BuildSettingWindow.cs.meta
similarity index 100%
rename from Editor/ToolBar/BuildSettingWindow.cs.meta
rename to Editor/ToolBarExtension/BuildSettingWindow.cs.meta
diff --git a/Editor/ToolBar/EditorQuickToolBar.cs b/Editor/ToolBarExtension/EditorQuickToolBar.cs
similarity index 100%
rename from Editor/ToolBar/EditorQuickToolBar.cs
rename to Editor/ToolBarExtension/EditorQuickToolBar.cs
diff --git a/Editor/ToolBar/EditorQuickToolBar.cs.meta b/Editor/ToolBarExtension/EditorQuickToolBar.cs.meta
similarity index 100%
rename from Editor/ToolBar/EditorQuickToolBar.cs.meta
rename to Editor/ToolBarExtension/EditorQuickToolBar.cs.meta
diff --git a/Editor/ToolBarExtension/LocalizationDropdownField.cs b/Editor/ToolBarExtension/LocalizationDropdownField.cs
new file mode 100644
index 0000000..f2c6550
--- /dev/null
+++ b/Editor/ToolBarExtension/LocalizationDropdownField.cs
@@ -0,0 +1,69 @@
+using System;
+using AlicizaX.Localization.Runtime;
+using AlicizaX;
+using Paps.UnityToolbarExtenderUIToolkit;
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.UIElements;
+
+[MainToolbarElement("LocalizationDropdownField", alignment: ToolbarAlign.Right, order: 0)]
+public class LocalizationDropdownField : IMGUIContainer
+{
+ private static GUIContent appConfigBtContent;
+
+ private static string[] _languageTypeNames;
+
+ public void InitializeElement()
+ {
+ var nameArray = Enum.GetNames(typeof(Language));
+ _languageTypeNames = new string[nameArray.Length - 1];
+ for (int i = 1; i < nameArray.Length; i++)
+ {
+ var name = nameArray[i];
+ _languageTypeNames[i - 1] = name;
+ }
+
+ appConfigBtContent =
+ EditorGUIUtility.TrTextContentWithIcon("", "",
+ "Settings");
+ onGUIHandler = MyGUIMethod;
+ }
+
+ private void MyGUIMethod()
+ {
+ GUILayout.BeginHorizontal();
+ string title = _languageTypeNames[GetPrefsIndex()];
+ appConfigBtContent.text = title;
+ if (EditorGUILayout.DropdownButton(appConfigBtContent, FocusType.Passive, EditorStyles.toolbarPopup, GUILayout.MaxWidth(120)))
+ {
+ DrawEditorToolDropdownMenus();
+ }
+
+ GUILayout.Space(5);
+ GUILayout.EndHorizontal();
+ }
+
+ static void DrawEditorToolDropdownMenus()
+ {
+ int index = GetPrefsIndex();
+ GenericMenu popMenu = new GenericMenu();
+ for (int i = 0; i < _languageTypeNames.Length; i++)
+ {
+ var selected = index == i;
+ var toolAttr = _languageTypeNames[i];
+ popMenu.AddItem(new GUIContent(toolAttr), selected, menuIdx => { ClickToolsSubmenu((int)menuIdx); }, i);
+ }
+
+ popMenu.ShowAsContext();
+ }
+
+ static void ClickToolsSubmenu(int menuIdx)
+ {
+ EditorPrefs.SetInt(LocalizationComponent.PrefsKey, menuIdx + 1);
+ }
+
+ static int GetPrefsIndex()
+ {
+ return EditorPrefs.GetInt(LocalizationComponent.PrefsKey, 1) - 1;
+ }
+}
diff --git a/Editor/ToolBarExtension/LocalizationDropdownField.cs.meta b/Editor/ToolBarExtension/LocalizationDropdownField.cs.meta
new file mode 100644
index 0000000..84b1b0b
--- /dev/null
+++ b/Editor/ToolBarExtension/LocalizationDropdownField.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 2295b86f78274a84a63dc65ab4a69cb1
+timeCreated: 1742364662
\ No newline at end of file
diff --git a/Editor/ToolBar/ResourceModeDropdownField.cs b/Editor/ToolBarExtension/ResourceModeDropdownField.cs
similarity index 91%
rename from Editor/ToolBar/ResourceModeDropdownField.cs
rename to Editor/ToolBarExtension/ResourceModeDropdownField.cs
index 3324846..313dd81 100644
--- a/Editor/ToolBar/ResourceModeDropdownField.cs
+++ b/Editor/ToolBarExtension/ResourceModeDropdownField.cs
@@ -23,9 +23,7 @@ namespace AlicizaX.Editor.Extension
public void InitializeElement()
{
- appConfigBtContent =
- EditorGUIUtility.TrTextContentWithIcon("Res:", "配置App运行时所需DataTable/Config/Procedure",
- "Settings");
+ appConfigBtContent = EditorGUIUtility.TrTextContentWithIcon("Res:", "配置App运行时资源模式", "Settings");
onGUIHandler = MyGUIMethod;
}
diff --git a/Editor/ToolBar/ResourceModeDropdownField.cs.meta b/Editor/ToolBarExtension/ResourceModeDropdownField.cs.meta
similarity index 100%
rename from Editor/ToolBar/ResourceModeDropdownField.cs.meta
rename to Editor/ToolBarExtension/ResourceModeDropdownField.cs.meta
diff --git a/Editor/ToolBar/SwitchSceneToolBar.cs b/Editor/ToolBarExtension/SwitchSceneToolBar.cs
similarity index 100%
rename from Editor/ToolBar/SwitchSceneToolBar.cs
rename to Editor/ToolBarExtension/SwitchSceneToolBar.cs
diff --git a/Editor/ToolBar/SwitchSceneToolBar.cs.meta b/Editor/ToolBarExtension/SwitchSceneToolBar.cs.meta
similarity index 100%
rename from Editor/ToolBar/SwitchSceneToolBar.cs.meta
rename to Editor/ToolBarExtension/SwitchSceneToolBar.cs.meta
diff --git a/Editor/Toolbar/ByAttributeMainToolbarElementRepository.cs b/Editor/Toolbar/ByAttributeMainToolbarElementRepository.cs
new file mode 100644
index 0000000..a87db80
--- /dev/null
+++ b/Editor/Toolbar/ByAttributeMainToolbarElementRepository.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Linq;
+using System.Reflection;
+using UnityEditor;
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class ByAttributeMainToolbarElementRepository : IMainToolbarElementRepository
+ {
+ public MainToolbarElement[] GetAll()
+ {
+ return TypeCache.GetTypesWithAttribute()
+ .Where(type => IsValidVisualElementType(type))
+ .Select(type => GetMainToolbarElementFromType(type))
+ .ToArray();
+ }
+
+ private MainToolbarElement GetMainToolbarElementFromType(Type type)
+ {
+ var elementInstance = (VisualElement)Activator.CreateInstance(type);
+ var attribute = type.GetCustomAttribute();
+
+ if (string.IsNullOrEmpty(elementInstance.name))
+ elementInstance.name = elementInstance.GetType().Name;
+
+ return new MainToolbarElement(attribute.Id, elementInstance, attribute.Alignment,
+ attribute.Order, attribute.UseRecommendedStyles);
+ }
+
+ private bool IsValidVisualElementType(Type type)
+ {
+ var visualElementType = typeof(VisualElement);
+
+ return visualElementType != type &&
+ visualElementType.IsAssignableFrom(type) &&
+ !type.IsAbstract;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/ByAttributeMainToolbarElementRepository.cs.meta b/Editor/Toolbar/ByAttributeMainToolbarElementRepository.cs.meta
new file mode 100644
index 0000000..e03e5a9
--- /dev/null
+++ b/Editor/Toolbar/ByAttributeMainToolbarElementRepository.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 9e664729ffc0507499365cb1b3393b91
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/ControlPanelWindow.meta b/Editor/Toolbar/ControlPanelWindow.meta
new file mode 100644
index 0000000..795b449
--- /dev/null
+++ b/Editor/Toolbar/ControlPanelWindow.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: e5d6770a557fcef47bfab9c1562f972c
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/ControlPanelWindow/MainToolbarControlPanelWindow.cs b/Editor/Toolbar/ControlPanelWindow/MainToolbarControlPanelWindow.cs
new file mode 100644
index 0000000..349d753
--- /dev/null
+++ b/Editor/Toolbar/ControlPanelWindow/MainToolbarControlPanelWindow.cs
@@ -0,0 +1,207 @@
+using System.Collections.Generic;
+using System.Linq;
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ public class MainToolbarControlPanelWindow : EditorWindow
+ {
+ private const string NATIVE_ELEMENTS_CONTAINER_NAME = "UnityNativeElementsContainer";
+ private const string NATIVE_ELEMENTS_FOLDOUT_TEXT = "Unity Native Elements";
+
+ private const string SINGLE_ELEMENTS_CONTAINER_NAME = "SingleElementsContainer";
+ private const string SINGLE_ELEMENTS_FOLDOUT_TEXT = "Single Elements";
+
+ private const string GROUP_ELEMENTS_CONTAINER_NAME = "GroupElementsContainer";
+ private const string GROUP_ELEMENTS_FOLDOUT_TEXT = "Groups";
+
+ private const float MAIN_CONTAINER_PADDING_TOP = 5;
+
+ private OrganizationalFoldableContainer _nativeElementsContainer;
+ private OrganizationalFoldableContainer _singleElementsContainer;
+ private OrganizationalFoldableContainer _groupElementsContainer;
+ private MainToolbarElementController[] _controllers;
+
+ private Button _resetOverridesButton;
+
+ private VisualElement _noElementsMessageElement;
+ private VisualElement _windowContainer;
+
+ public static void OpenWindow()
+ {
+ var window = GetWindow();
+
+ window.titleContent = new GUIContent("Main Toolbar Control Panel");
+ }
+
+ private void CreateGUI()
+ {
+ MainToolbarAutomaticExtender.OnAddedCustomContainersToToolbar += Refresh;
+ MainToolbarAutomaticExtender.OnRefresh += Refresh;
+
+ BuildFixedGUI();
+ SetDefaultView();
+
+ if (MainToolbar.IsAvailable)
+ Refresh();
+ }
+
+ private void OnDestroy()
+ {
+ MainToolbarAutomaticExtender.OnAddedCustomContainersToToolbar -= Refresh;
+ MainToolbarAutomaticExtender.OnRefresh -= Refresh;
+ }
+
+ private void Refresh()
+ {
+ BuildDynamicGUI();
+ SetCorrespondingView();
+ }
+
+ private void BuildFixedGUI()
+ {
+ _windowContainer = GetContainer();
+
+ _resetOverridesButton = new Button(GlobalActions.ResetOverridesIfUserAccepts);
+ _resetOverridesButton.text = "Reset Overrides";
+
+ _singleElementsContainer = new OrganizationalFoldableContainer(
+ SINGLE_ELEMENTS_CONTAINER_NAME, SINGLE_ELEMENTS_FOLDOUT_TEXT);
+ _groupElementsContainer = new OrganizationalFoldableContainer(
+ GROUP_ELEMENTS_CONTAINER_NAME, GROUP_ELEMENTS_FOLDOUT_TEXT);
+ _nativeElementsContainer = new OrganizationalFoldableContainer(
+ NATIVE_ELEMENTS_CONTAINER_NAME, NATIVE_ELEMENTS_FOLDOUT_TEXT);
+
+ _noElementsMessageElement = CreateNoElementsMessageElement();
+
+ rootVisualElement.Add(_resetOverridesButton);
+ rootVisualElement.Add(_windowContainer);
+ }
+
+ private void SetDefaultView()
+ {
+ _windowContainer.Add(_noElementsMessageElement);
+ }
+
+ private void SetCorrespondingView()
+ {
+ if(_controllers.Length > 0)
+ {
+ if(_windowContainer.Contains(_noElementsMessageElement))
+ _windowContainer.Remove(_noElementsMessageElement);
+
+ if (!_windowContainer.Contains(_singleElementsContainer))
+ {
+ _windowContainer.Add(_singleElementsContainer);
+ _windowContainer.Add(_groupElementsContainer);
+ _windowContainer.Add(_nativeElementsContainer);
+ }
+ }
+ else
+ {
+ if (_windowContainer.Contains(_singleElementsContainer))
+ {
+ _windowContainer.Remove(_singleElementsContainer);
+ _windowContainer.Remove(_groupElementsContainer);
+ _windowContainer.Remove(_nativeElementsContainer);
+ }
+
+ if (!_windowContainer.Contains(_noElementsMessageElement))
+ _windowContainer.Add(_noElementsMessageElement);
+ }
+ }
+
+ private void BuildDynamicGUI()
+ {
+ _controllers = CreateControllers();
+
+ var controllersOfNativeElements = _controllers
+ .Where(controller => controller.HoldsANativeElement);
+ var controllersOfGroups = _controllers
+ .Where(controller => controller.HoldsAGroup);
+ var controllersOfSingleElements = _controllers
+ .Where(controller => !controller.HoldsAGroup && !controller.HoldsANativeElement)
+ .Where(controller => SingleControllerIsNotInsideAGroupController(controller, controllersOfGroups));
+
+ _singleElementsContainer.SetControllers(controllersOfSingleElements);
+ _groupElementsContainer.SetControllers(controllersOfGroups);
+ _nativeElementsContainer.SetControllers(controllersOfNativeElements);
+ }
+
+ private static bool SingleControllerIsNotInsideAGroupController(MainToolbarElementController controller, IEnumerable controllersOfGroups)
+ {
+ foreach (var groupController in controllersOfGroups)
+ if (groupController.ContainsSubController(controller.Id))
+ return false;
+
+ return true;
+ }
+
+ private VisualElement GetContainer()
+ {
+ var scrollView = new ScrollView(ScrollViewMode.Vertical);
+
+ scrollView.style.paddingTop = MAIN_CONTAINER_PADDING_TOP;
+
+ return scrollView;
+ }
+
+ private MainToolbarElementController[] CreateControllers()
+ {
+ return GetOverridableElements()
+ .OrderBy(overridableElement => overridableElement.Id)
+ .Select(overridableElement => new MainToolbarElementController(
+ overridableElement,
+ ServicesAndRepositories.MainToolbarElementOverridesRepository,
+ GetSubElementsIfAny(overridableElement))
+ )
+ .ToArray();
+ }
+
+ private OverridableElement[] GetSubElementsIfAny(OverridableElement overridableElement)
+ {
+ if(overridableElement.VisualElement is GroupElement)
+ {
+ return MainToolbarAutomaticExtender.GetElementsOfGroup(overridableElement.Id)
+ .Select(el => new OverridableElement(
+ el.Id,
+ el.VisualElement,
+ false)
+ )
+ .ToArray();
+ }
+
+ return new OverridableElement[0];
+ }
+
+ private OverridableElement[] GetOverridableElements()
+ {
+ var nativeElements = MainToolbarAutomaticExtender.NativeElements
+ .Select(nativeElement => new OverridableElement(
+ nativeElement.Id,
+ nativeElement.VisualElement,
+ true
+ )
+ );
+
+ var customElements = MainToolbarAutomaticExtender.CustomMainToolbarElements
+ .Concat(MainToolbarAutomaticExtender.GroupElements)
+ .Select(mainToolbarElement => new OverridableElement(
+ mainToolbarElement.Id,
+ mainToolbarElement.VisualElement,
+ false
+ )
+ );
+
+ return nativeElements.Concat(customElements)
+ .ToArray();
+ }
+
+ private VisualElement CreateNoElementsMessageElement()
+ {
+ return new HelpBox("No main toolbar elements were found. To use the automatic toolbar extender define a main toolbar element. See the docs.", HelpBoxMessageType.Warning);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/ControlPanelWindow/MainToolbarControlPanelWindow.cs.meta b/Editor/Toolbar/ControlPanelWindow/MainToolbarControlPanelWindow.cs.meta
new file mode 100644
index 0000000..ca70fb2
--- /dev/null
+++ b/Editor/Toolbar/ControlPanelWindow/MainToolbarControlPanelWindow.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fef14479cdf8f5a41bb3b7f4b442484e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/ControlPanelWindow/MainToolbarElementController.cs b/Editor/Toolbar/ControlPanelWindow/MainToolbarElementController.cs
new file mode 100644
index 0000000..59fb561
--- /dev/null
+++ b/Editor/Toolbar/ControlPanelWindow/MainToolbarElementController.cs
@@ -0,0 +1,187 @@
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class MainToolbarElementController : VisualElement
+ {
+ private const string FOLDOUT_STATE_SAVE_KEY_BASE = "main-toolbar-element-controller:foldout-state:";
+ private const float LEFT_PADDING_SINGLE = 19;
+ private const float RIGHT_PADDING = 10;
+
+ private readonly IMainToolbarElementOverrideRepository _overridesRepository;
+ private Label _label;
+ private Button _button;
+ private Image _buttonIconImage;
+ private Foldout _foldout;
+
+ private StyleColor _defaultButtonColor;
+ private List _subControllers = new List();
+
+ public string Id { get; }
+ public VisualElement ControlledVisualElement { get; }
+ public bool HoldsAGroup => _foldout != null;
+ public bool HoldsANativeElement { get; private set; }
+
+ public MainToolbarElementController(OverridableElement overridableElement,
+ IMainToolbarElementOverrideRepository overridesRepository, params OverridableElement[] subElements)
+ {
+ Id = overridableElement.Id;
+ ControlledVisualElement = overridableElement.VisualElement;
+ HoldsANativeElement = overridableElement.IsNative;
+ name = Id + "-Controller";
+ _overridesRepository = overridesRepository;
+
+ _buttonIconImage = new Image();
+
+ style.flexDirection = FlexDirection.Row;
+ style.justifyContent = Justify.SpaceBetween;
+ style.paddingRight = RIGHT_PADDING;
+
+ _label = CreateLabel();
+ _button = CreateButton();
+
+ _defaultButtonColor = _button.style.backgroundColor;
+
+ UpdateButtonStatus(VisibleValueOrDefault());
+ BuildAsGroupOrSingle(subElements);
+ }
+
+ private string GetFullFoldoutStateSaveKey() => FOLDOUT_STATE_SAVE_KEY_BASE + Id;
+
+ private void SaveFoldoutState(ChangeEvent eventArgs)
+ {
+ UserSettingsPrefs.SetBool(GetFullFoldoutStateSaveKey(), eventArgs.newValue);
+ }
+
+ private bool GetSavedFoldoutState()
+ {
+ return UserSettingsPrefs.GetBool(GetFullFoldoutStateSaveKey(), false);
+ }
+
+ public bool ContainsSubController(string id)
+ {
+ return _subControllers.Any(controller => controller.Id == id);
+ }
+
+ private void BuildAsGroupOrSingle(OverridableElement[] subElements)
+ {
+ if (subElements.Length > 0)
+ BuildFoldout(subElements);
+ else
+ BuildSingleElement();
+ }
+
+ private void BuildSingleElement()
+ {
+ style.paddingLeft = LEFT_PADDING_SINGLE;
+
+ Add(_label);
+ Add(_button);
+ }
+
+ private void BuildFoldout(OverridableElement[] subElements)
+ {
+ _foldout = new Foldout() { text = _label.text };
+
+ foreach (var overridable in subElements)
+ {
+ var subController = new MainToolbarElementController(overridable, _overridesRepository);
+
+ _subControllers.Add(subController);
+
+ _foldout.Add(subController);
+ }
+
+ _foldout.value = GetSavedFoldoutState();
+ _foldout.RegisterCallback>(SaveFoldoutState);
+ _foldout.style.flexGrow = 1;
+
+ Add(_foldout);
+ Add(_button);
+ }
+
+ private bool VisibleValueOrDefault()
+ {
+ var possibleOverride = _overridesRepository.Get(Id);
+
+ if (possibleOverride == null)
+ return CurrentDisplayValueAsBool();
+
+ var overrideValue = possibleOverride.Value;
+
+ return overrideValue.Visible;
+ }
+
+ private Label CreateLabel()
+ {
+ var label = new Label(Id);
+
+ label.style.alignSelf = Align.Center;
+
+ return label;
+ }
+
+ private Button CreateButton()
+ {
+ var button = new Button(ChangeVisibilityValue);
+
+ button.Add(_buttonIconImage);
+
+ button.tooltip = "Change the visibility of element with id " + Id;
+
+ button.style.alignSelf = Align.FlexStart;
+
+ return button;
+ }
+
+ private Texture IconByVisibilityValue(bool visible)
+ {
+ if (visible)
+ return Icons.VisibilityOnOverrideIcon;
+
+ return Icons.VisibilityOffOverrideIcon;
+ }
+
+ private void ChangeVisibilityValue()
+ {
+ var currentOverrideValue = _overridesRepository.Get(Id);
+
+ bool newValue;
+
+ if (currentOverrideValue == null)
+ newValue = !CurrentDisplayValueAsBool();
+ else
+ newValue = !currentOverrideValue.Value.Visible;
+
+ _overridesRepository.Save(new MainToolbarElementOverride(Id, newValue));
+ UpdateButtonStatus(newValue);
+
+ MainToolbarAutomaticExtender.Refresh();
+ }
+
+ private bool CurrentDisplayValueAsBool()
+ {
+ if (ControlledVisualElement.style.display == DisplayStyle.None)
+ return false;
+ else
+ return true;
+ }
+
+ private void UpdateButtonStatus(bool visible)
+ {
+ _buttonIconImage.image = IconByVisibilityValue(visible);
+ _button.style.backgroundColor = GetButtonColor(visible);
+ }
+
+ private StyleColor GetButtonColor(bool visible)
+ {
+ if (visible)
+ return _defaultButtonColor;
+ else
+ return new StyleColor(Color.black);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/ControlPanelWindow/MainToolbarElementController.cs.meta b/Editor/Toolbar/ControlPanelWindow/MainToolbarElementController.cs.meta
new file mode 100644
index 0000000..63b2445
--- /dev/null
+++ b/Editor/Toolbar/ControlPanelWindow/MainToolbarElementController.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ae80166256b03484a9bfc1ad9c4cc0dc
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/ControlPanelWindow/OrganizationalFoldableContainer.cs b/Editor/Toolbar/ControlPanelWindow/OrganizationalFoldableContainer.cs
new file mode 100644
index 0000000..5178fea
--- /dev/null
+++ b/Editor/Toolbar/ControlPanelWindow/OrganizationalFoldableContainer.cs
@@ -0,0 +1,51 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class OrganizationalFoldableContainer : Box
+ {
+ private static readonly Color ORGANIZATIONAL_FOLDABLE_CONTAINER_BORDER_COLOR = new Color(153f / 255f, 153f / 255f, 153f / 255f);
+ private const string FOLDOUT_STATE_SAVE_KEY_BASE = "organizational-foldable-container:foldout-state:";
+
+ private Foldout _foldout;
+ private string _id;
+
+ public OrganizationalFoldableContainer(string containerId, string foldoutText)
+ {
+ _id = containerId;
+ name = containerId;
+ style.borderTopColor = ORGANIZATIONAL_FOLDABLE_CONTAINER_BORDER_COLOR;
+ style.borderTopWidth = 1;
+
+ _foldout = new Foldout() { text = foldoutText };
+ _foldout.value = GetSavedFoldoutState();
+ _foldout.RegisterCallback>(SaveFoldoutState);
+
+ Add(_foldout);
+ }
+
+ private string GetFullFoldoutStateSaveKey() => FOLDOUT_STATE_SAVE_KEY_BASE + _id;
+
+ private void SaveFoldoutState(ChangeEvent eventArgs)
+ {
+ UserSettingsPrefs.SetBool(GetFullFoldoutStateSaveKey(), eventArgs.newValue);
+ }
+
+ private bool GetSavedFoldoutState()
+ {
+ return UserSettingsPrefs.GetBool(GetFullFoldoutStateSaveKey(), false);
+ }
+
+ public void SetControllers(IEnumerable controllers)
+ {
+ _foldout.Clear();
+
+ foreach (var controller in controllers)
+ {
+ _foldout.Add(controller);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/ControlPanelWindow/OrganizationalFoldableContainer.cs.meta b/Editor/Toolbar/ControlPanelWindow/OrganizationalFoldableContainer.cs.meta
new file mode 100644
index 0000000..82d0a8c
--- /dev/null
+++ b/Editor/Toolbar/ControlPanelWindow/OrganizationalFoldableContainer.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 9ac00cb9059df7e43b1c2ed433ce61cc
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/ControlPanelWindow/OverridableElement.cs b/Editor/Toolbar/ControlPanelWindow/OverridableElement.cs
new file mode 100644
index 0000000..be33db5
--- /dev/null
+++ b/Editor/Toolbar/ControlPanelWindow/OverridableElement.cs
@@ -0,0 +1,18 @@
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal readonly struct OverridableElement
+ {
+ public string Id { get; }
+ public VisualElement VisualElement { get; }
+ public bool IsNative { get; }
+
+ public OverridableElement(string id, VisualElement visualElement, bool isNative)
+ {
+ Id = id;
+ VisualElement = visualElement;
+ IsNative = isNative;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/ControlPanelWindow/OverridableElement.cs.meta b/Editor/Toolbar/ControlPanelWindow/OverridableElement.cs.meta
new file mode 100644
index 0000000..79c9790
--- /dev/null
+++ b/Editor/Toolbar/ControlPanelWindow/OverridableElement.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 542f1fb68120090489ba1613162eb17b
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/Extensions.meta b/Editor/Toolbar/Extensions.meta
new file mode 100644
index 0000000..005d707
--- /dev/null
+++ b/Editor/Toolbar/Extensions.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: f0a074f24b9c98d488341e6258c0c0b0
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/Extensions/EditorWindowExtensions.cs b/Editor/Toolbar/Extensions/EditorWindowExtensions.cs
new file mode 100644
index 0000000..ceb227c
--- /dev/null
+++ b/Editor/Toolbar/Extensions/EditorWindowExtensions.cs
@@ -0,0 +1,17 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ public static class EditorWindowExtensions
+ {
+ public static void ShowAsDropdownForMainToolbar(this EditorWindow window, Rect activatorRect, Vector2 size)
+ {
+ window.ShowAsDropDown(activatorRect, size);
+
+ var rect = GUIUtility.GUIToScreenRect(activatorRect);
+ rect.y += activatorRect.size.y;
+ window.position = new Rect(rect.position, window.position.size);
+ }
+ }
+}
diff --git a/Editor/Toolbar/Extensions/EditorWindowExtensions.cs.meta b/Editor/Toolbar/Extensions/EditorWindowExtensions.cs.meta
new file mode 100644
index 0000000..b8b3fbf
--- /dev/null
+++ b/Editor/Toolbar/Extensions/EditorWindowExtensions.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3333a000c60ebce4aa038ee0945d0072
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/GroupDefinitions.meta b/Editor/Toolbar/GroupDefinitions.meta
new file mode 100644
index 0000000..89f1e7a
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 1a83afb20ef0f5f40b22a93ff124fe1f
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/GroupDefinitions/GroupDefinition.cs b/Editor/Toolbar/GroupDefinitions/GroupDefinition.cs
new file mode 100644
index 0000000..579e6a2
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/GroupDefinition.cs
@@ -0,0 +1,39 @@
+using System.Linq;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal readonly struct GroupDefinition
+ {
+ public string GroupId { get; }
+ public string GroupName { get; }
+ public ToolbarAlign Alignment { get; }
+ public int Order { get; }
+ public string[] ToolbarElementsIds { get; }
+
+ public GroupDefinition(string groupId, string groupName, ToolbarAlign alignment, int order, string[] toolbarElementsIds)
+ {
+ GroupId = groupId;
+ GroupName = string.IsNullOrEmpty(groupName) ? groupId : groupName;
+ Alignment = alignment;
+ Order = order;
+ ToolbarElementsIds = toolbarElementsIds;
+ }
+
+ public bool AreEquals(GroupDefinition other)
+ {
+ return GroupId == other.GroupId &&
+ GroupName == other.GroupName &&
+ Alignment == other.Alignment &&
+ Order == other.Order &&
+ AreEquals(ToolbarElementsIds, other.ToolbarElementsIds);
+ }
+
+ private bool AreEquals(string[] types, string[] types2)
+ {
+ if(types.Length != types2.Length)
+ return false;
+
+ return types.All(typeName => types2.Contains(typeName));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/GroupDefinitions/GroupDefinition.cs.meta b/Editor/Toolbar/GroupDefinitions/GroupDefinition.cs.meta
new file mode 100644
index 0000000..821335d
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/GroupDefinition.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8e3f2e82a96ef3246860b2861fa19b15
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/GroupDefinitions/GroupDropdownWindowPopup.cs b/Editor/Toolbar/GroupDefinitions/GroupDropdownWindowPopup.cs
new file mode 100644
index 0000000..f0c85c0
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/GroupDropdownWindowPopup.cs
@@ -0,0 +1,92 @@
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class GroupDropdownWindowPopup : EditorWindow
+ {
+ private VisualElement[] _groupElements;
+ private ScrollView _scrollView;
+
+ public void Initialize(VisualElement[] groupElements)
+ {
+ _groupElements = groupElements;
+ hideFlags = HideFlags.DontSave;
+ }
+
+ private void OnEnable()
+ {
+ AssemblyReloadEvents.beforeAssemblyReload += Close;
+ }
+
+ private void OnDisable()
+ {
+ AssemblyReloadEvents.beforeAssemblyReload -= Close;
+ }
+
+ private void CreateGUI()
+ {
+ _scrollView = new ScrollView(ScrollViewMode.Vertical);
+ _scrollView.contentContainer.style.alignContent = Align.Center;
+ _scrollView.contentContainer.style.alignItems = Align.Center;
+ _scrollView.horizontalScrollerVisibility = ScrollerVisibility.Hidden;
+
+ foreach (var groupElement in _groupElements)
+ {
+ var container = CreateGroupElementContainer();
+ container.Add(groupElement);
+ groupElement.style.flexWrap = Wrap.Wrap;
+ container.style.display = groupElement.style.display;
+ _scrollView.Add(container);
+ }
+
+ var baseContainer = CreateBaseContainer();
+ baseContainer.Add(_scrollView);
+
+ rootVisualElement.Add(baseContainer);
+ }
+
+ private VisualElement CreateBaseContainer()
+ {
+ return new VisualElement()
+ {
+ style =
+ {
+ flexGrow = 1,
+ borderBottomColor = Color.black,
+ borderTopColor = Color.black,
+ borderLeftColor = Color.black,
+ borderRightColor = Color.black,
+ borderBottomWidth = 2,
+ borderTopWidth = 2,
+ borderLeftWidth = 2,
+ borderRightWidth = 2,
+ }
+ };
+ }
+
+ private VisualElement CreateGroupElementContainer()
+ {
+ return new Box()
+ {
+ style =
+ {
+ alignContent = Align.Center,
+ alignItems = Align.Center,
+ flexDirection = FlexDirection.Row,
+ flexGrow = 1,
+ width = Length.Percent(100),
+ height = Length.Auto(),
+ justifyContent = Justify.Center,
+ borderTopColor = Color.black,
+ borderTopWidth = 1,
+ paddingTop = 3f,
+ paddingBottom = 3f,
+ paddingLeft = 8,
+ paddingRight = 8,
+ }
+ };
+ }
+ }
+}
diff --git a/Editor/Toolbar/GroupDefinitions/GroupDropdownWindowPopup.cs.meta b/Editor/Toolbar/GroupDefinitions/GroupDropdownWindowPopup.cs.meta
new file mode 100644
index 0000000..7b134df
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/GroupDropdownWindowPopup.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8509c9dbf1627b74c9e521402a3de28b
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/GroupDefinitions/GroupDropdownWindowPopupManager.cs b/Editor/Toolbar/GroupDefinitions/GroupDropdownWindowPopupManager.cs
new file mode 100644
index 0000000..bb21d42
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/GroupDropdownWindowPopupManager.cs
@@ -0,0 +1,144 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.UIElements;
+using PopupWindow = UnityEditor.PopupWindow;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal static class GroupDropdownWindowPopupManager
+ {
+ private const string POPUP_WINDOW_CONTENT_FIELD_NAME = "m_WindowContent";
+ private static readonly string[] SPECIAL_EDITOR_WINDOW_TYPE_NAMES =
+ {
+ "UnityEditor.UIElements.Debugger.UIElementsDebugger",
+ "UnityEditor.UIElements.EditorMenuExtensions+ContextMenu",
+ "UnityEditor.ObjectSelector",
+ "UnityEditor.Search.SearchPickerWindow"
+ };
+ private static readonly string[] SPECIAL_POPUP_WINDOW_CONTENT_TYPE_NAMES =
+ {
+ "UnityEditor.UIElements.EditorGenericDropdownMenuWindowContent"
+ };
+
+ private static FieldInfo _popupWindowContentField;
+ private static Type[] _subWindowTypes = new Type[0];
+ private static Type[] _specialWindowTypes = new Type[0];
+ private static List _windows = new List();
+
+ static GroupDropdownWindowPopupManager()
+ {
+ _popupWindowContentField = typeof(PopupWindow)
+ .GetField(POPUP_WINDOW_CONTENT_FIELD_NAME,
+ BindingFlags.NonPublic | BindingFlags.Instance);
+
+ InitializeSpecialWindowTypes();
+ LoadSubWindowTypes();
+ EditorApplication.update += Update;
+ }
+
+ private static void LoadSubWindowTypes()
+ {
+ _subWindowTypes = TypeCache.GetTypesWithAttribute()
+ .Where(type => IsValidSubWindowType(type))
+ .ToArray();
+ }
+
+ private static void InitializeSpecialWindowTypes()
+ {
+ var typeList = new List();
+
+ typeList.AddRange(TypeCache.GetTypesDerivedFrom()
+ .Where(type => SPECIAL_EDITOR_WINDOW_TYPE_NAMES.Contains(type.Name) || SPECIAL_EDITOR_WINDOW_TYPE_NAMES.Contains(type.FullName)));
+
+ typeList.AddRange(TypeCache.GetTypesDerivedFrom()
+ .Where(type => SPECIAL_POPUP_WINDOW_CONTENT_TYPE_NAMES.Contains(type.Name) || SPECIAL_POPUP_WINDOW_CONTENT_TYPE_NAMES.Contains(type.FullName)));
+
+ _specialWindowTypes = typeList.Where(t => t != null).ToArray();
+ }
+
+ private static bool IsValidSubWindowType(Type type)
+ {
+ return typeof(EditorWindow).IsAssignableFrom(type) ||
+ typeof(PopupWindowContent).IsAssignableFrom(type);
+ }
+
+ private static bool ContainsValidPopupWindowContent(EditorWindow window)
+ {
+ if(window is PopupWindow popupWindow)
+ {
+ var popupContent = _popupWindowContentField.GetValue(popupWindow) as PopupWindowContent;
+
+ var popupContentSpecificType = popupContent.GetType();
+
+ return _subWindowTypes.Contains(popupContentSpecificType) || _specialWindowTypes.Contains(popupContentSpecificType);
+ }
+
+ return false;
+ }
+
+ private static void Update()
+ {
+ if (_windows.Count == 0)
+ return;
+
+ if (EditorWindow.focusedWindow == null || !FocusedWindowIsValid())
+ CloseAll();
+ else if(_windows.Contains(EditorWindow.focusedWindow))
+ {
+ var focusedWindow = EditorWindow.focusedWindow;
+
+ var downMostWindow = _windows.Last();
+
+ while(downMostWindow != focusedWindow)
+ {
+ _windows.Remove(downMostWindow);
+ downMostWindow.Close();
+ downMostWindow = _windows.Last();
+ }
+ }
+ }
+
+ private static void CloseAll()
+ {
+ foreach(var window in _windows)
+ {
+ if(window != null)
+ window.Close();
+ }
+
+ _windows.Clear();
+ }
+
+ private static bool FocusedWindowIsValid()
+ {
+ return _windows.Contains(EditorWindow.focusedWindow) ||
+ _subWindowTypes.Contains(EditorWindow.focusedWindow.GetType()) ||
+ _specialWindowTypes.Contains(EditorWindow.focusedWindow.GetType()) ||
+ ContainsValidPopupWindowContent(EditorWindow.focusedWindow);
+ }
+
+ public static void Show(Rect activatorRect, VisualElement[] elements)
+ {
+ var window = ScriptableObject.CreateInstance();
+
+ var rect = GUIUtility.GUIToScreenRect(activatorRect);
+ rect.y += activatorRect.size.y;
+ window.position = new Rect(rect.position, window.position.size);
+
+ _windows.Add(window);
+
+ window.Initialize(elements);
+
+#if UNITY_EDITOR_WIN
+ window.ShowPopup();
+#elif UNITY_EDITOR_OSX
+ window.ShowAsDropdownForMainToolbar(activatorRect, window.position.size);
+#endif
+
+ }
+ }
+}
diff --git a/Editor/Toolbar/GroupDefinitions/GroupDropdownWindowPopupManager.cs.meta b/Editor/Toolbar/GroupDefinitions/GroupDropdownWindowPopupManager.cs.meta
new file mode 100644
index 0000000..4bd2b9b
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/GroupDropdownWindowPopupManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 88333c3cc209cb143bc93891e1664b41
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/GroupDefinitions/GroupElement.cs b/Editor/Toolbar/GroupDefinitions/GroupElement.cs
new file mode 100644
index 0000000..00ee23a
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/GroupElement.cs
@@ -0,0 +1,29 @@
+using System.Linq;
+using UnityEditor.Toolbars;
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class GroupElement : EditorToolbarDropdown
+ {
+ private VisualElement[] _groupedElements;
+ public VisualElement[] GroupedElements => _groupedElements.ToArray();
+
+ public GroupElement(string name)
+ {
+ this.name = name;
+ text = name;
+ clicked += ShowDropdown;
+ }
+
+ public void Initialize(VisualElement[] groupedElements)
+ {
+ _groupedElements = groupedElements;
+ }
+
+ private void ShowDropdown()
+ {
+ GroupDropdownWindowPopupManager.Show(worldBound, _groupedElements);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/GroupDefinitions/GroupElement.cs.meta b/Editor/Toolbar/GroupDefinitions/GroupElement.cs.meta
new file mode 100644
index 0000000..4eee5d1
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/GroupElement.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c782e5c3d1d2bd7499b358c6aa5703cd
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/GroupDefinitions/GroupPopupSubWindowAttribute.cs b/Editor/Toolbar/GroupDefinitions/GroupPopupSubWindowAttribute.cs
new file mode 100644
index 0000000..b074d05
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/GroupPopupSubWindowAttribute.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
+ public class GroupPopupSubWindowAttribute : Attribute
+ {
+
+ }
+}
diff --git a/Editor/Toolbar/GroupDefinitions/GroupPopupSubWindowAttribute.cs.meta b/Editor/Toolbar/GroupDefinitions/GroupPopupSubWindowAttribute.cs.meta
new file mode 100644
index 0000000..0f83646
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/GroupPopupSubWindowAttribute.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f6e542ea23caed94c92fab5ac0d0f1c8
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/GroupDefinitions/IGroupDefinitionRepository.cs b/Editor/Toolbar/GroupDefinitions/IGroupDefinitionRepository.cs
new file mode 100644
index 0000000..84c8e7f
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/IGroupDefinitionRepository.cs
@@ -0,0 +1,7 @@
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal interface IGroupDefinitionRepository
+ {
+ public GroupDefinition[] GetAll();
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/GroupDefinitions/IGroupDefinitionRepository.cs.meta b/Editor/Toolbar/GroupDefinitions/IGroupDefinitionRepository.cs.meta
new file mode 100644
index 0000000..fcd92f1
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/IGroupDefinitionRepository.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 15164a1a1815ea04c9ae72e65e0a9fe9
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/GroupDefinitions/MainToolbarElementDropdownAttribute.cs b/Editor/Toolbar/GroupDefinitions/MainToolbarElementDropdownAttribute.cs
new file mode 100644
index 0000000..abab388
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/MainToolbarElementDropdownAttribute.cs
@@ -0,0 +1,11 @@
+using System;
+using UnityEngine;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
+ internal class MainToolbarElementDropdownAttribute : PropertyAttribute
+ {
+
+ }
+}
diff --git a/Editor/Toolbar/GroupDefinitions/MainToolbarElementDropdownAttribute.cs.meta b/Editor/Toolbar/GroupDefinitions/MainToolbarElementDropdownAttribute.cs.meta
new file mode 100644
index 0000000..4a5d1f8
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/MainToolbarElementDropdownAttribute.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ffb57bb326f1c1247b6e1341c5caecf3
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/GroupDefinitions/MainToolbarElementDropdownDrawer.cs b/Editor/Toolbar/GroupDefinitions/MainToolbarElementDropdownDrawer.cs
new file mode 100644
index 0000000..f070eea
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/MainToolbarElementDropdownDrawer.cs
@@ -0,0 +1,84 @@
+using System.Collections.Generic;
+using System.Linq;
+using UnityEditor;
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ [CustomPropertyDrawer(typeof(MainToolbarElementDropdownAttribute))]
+ internal class MainToolbarElementDropdownDrawer : PropertyDrawer
+ {
+ private string _groupId;
+ private IEnumerable _mainToolbarElementsIds;
+ private IEnumerable _groupIds;
+ private IEnumerable _allIds;
+
+ public override VisualElement CreatePropertyGUI(SerializedProperty property)
+ {
+ _groupId = property.serializedObject.FindProperty("_groupId").stringValue;
+
+ CacheAllIds();
+
+ var availableIds = GetAvailableIds();
+
+ var popupField = new PopupField(
+ choices: availableIds,
+ 0);
+
+ Restore(property, availableIds, popupField);
+
+ popupField.RegisterCallback>(ev =>
+ {
+ property.stringValue = ev.newValue;
+ property.serializedObject.ApplyModifiedProperties();
+ ScriptableGroupDefinitionHelper.Refresh();
+ CacheAllIds();
+ var newAvailableIds = GetAvailableIds();
+ newAvailableIds.Add(property.stringValue);
+ popupField.choices = newAvailableIds.OrderBy(id => id).ToList();
+ });
+
+ return popupField;
+ }
+
+ private void Restore(SerializedProperty property, List availableIds, PopupField popupField)
+ {
+ if (string.IsNullOrEmpty(property.stringValue))
+ {
+ property.stringValue = popupField.value;
+ property.serializedObject.ApplyModifiedProperties();
+ }
+ else
+ {
+ if (_allIds.Contains(property.stringValue))
+ {
+ availableIds.Add(property.stringValue);
+ popupField.choices = availableIds.OrderBy(id => id).ToList();
+ popupField.SetValueWithoutNotify(property.stringValue);
+ }
+ else
+ popupField.SetValueWithoutNotify("");
+ }
+ }
+
+ private void CacheAllIds()
+ {
+ _mainToolbarElementsIds = MainToolbarAutomaticExtender.CustomMainToolbarElements.Select(el => el.Id);
+ _groupIds = ScriptableGroupDefinitionHelper.GetGroupIds();
+
+ _allIds = _mainToolbarElementsIds
+ .Concat(_groupIds);
+ }
+
+ private List GetAvailableIds()
+ {
+ var unusedMainToolbarElementIds = ScriptableGroupDefinitionHelper.GetUnusedMainToolbarElementIds(_mainToolbarElementsIds);
+ var unusedGroupIds = ScriptableGroupDefinitionHelper.GetEligibleGroupChildsFor(_groupId);
+
+ return unusedMainToolbarElementIds
+ .Concat(unusedGroupIds)
+ .OrderBy(id => id)
+ .ToList();
+ }
+ }
+}
diff --git a/Editor/Toolbar/GroupDefinitions/MainToolbarElementDropdownDrawer.cs.meta b/Editor/Toolbar/GroupDefinitions/MainToolbarElementDropdownDrawer.cs.meta
new file mode 100644
index 0000000..072f1fe
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/MainToolbarElementDropdownDrawer.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: cb51db686d5e79d4295bc1a510395e2c
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/GroupDefinitions/ScriptableGroupDefinition.cs b/Editor/Toolbar/GroupDefinitions/ScriptableGroupDefinition.cs
new file mode 100644
index 0000000..332e199
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/ScriptableGroupDefinition.cs
@@ -0,0 +1,52 @@
+using UnityEngine;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ [CreateAssetMenu(menuName = ToolInfo.EDITOR_MENU_BASE + "/Group Definition")]
+ public sealed class ScriptableGroupDefinition : ScriptableObject
+ {
+ [SerializeField]
+ [Tooltip("Id of group. It must be unique")]
+ private string _groupId;
+ [SerializeField]
+ [Tooltip("Text to display in group element dropdown")]
+ private string _groupName;
+ [SerializeField]
+ [Tooltip("Alignment when used as root element. Ignored inside other groups")]
+ private ToolbarAlign _alignment;
+ [Tooltip("Order when used as root element. Ignored inside other groups. Order of elements inside a group is determined by ToolbarElementsIds array elements order.")]
+ [SerializeField] private int _order;
+ [SerializeField]
+ [Tooltip("Elements ids of this group. Order of elements in array determines the order in which the elements will be displayed")]
+ [MainToolbarElementDropdown] private string[] _toolbarElementsIds;
+
+ public string GroupId => _groupId;
+ public string GroupName => _groupName;
+ public ToolbarAlign Alignment => _alignment;
+ public int Order => _order;
+ public string[] ToolbarElementsIds => _toolbarElementsIds == null ? new string[0] : _toolbarElementsIds;
+
+ private void OnValidate()
+ {
+ SetEqualValuesToEmptyInOrder();
+ }
+
+ private void SetEqualValuesToEmptyInOrder()
+ {
+ for (int i = 0; i < _toolbarElementsIds.Length; i++)
+ {
+ var value = _toolbarElementsIds[i];
+ for (int j = 0; j < _toolbarElementsIds.Length; j++)
+ {
+ if (i == j)
+ continue;
+
+ if (_toolbarElementsIds[j] == value)
+ {
+ _toolbarElementsIds[j] = "";
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/GroupDefinitions/ScriptableGroupDefinition.cs.meta b/Editor/Toolbar/GroupDefinitions/ScriptableGroupDefinition.cs.meta
new file mode 100644
index 0000000..062cded
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/ScriptableGroupDefinition.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6df7c06c2de586e41bb0c33bfd80766f
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/GroupDefinitions/ScriptableGroupDefinitionHelper.cs b/Editor/Toolbar/GroupDefinitions/ScriptableGroupDefinitionHelper.cs
new file mode 100644
index 0000000..6f95126
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/ScriptableGroupDefinitionHelper.cs
@@ -0,0 +1,63 @@
+using System.Collections.Generic;
+using System.Linq;
+using UnityEditor;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal static class ScriptableGroupDefinitionHelper
+ {
+ private static ScriptableGroupDefinition[] _projectGroupDefinitions;
+
+ static ScriptableGroupDefinitionHelper()
+ {
+ LoadProjectGroupDefinitions();
+
+ EditorApplication.projectChanged += OnProjectChange;
+ }
+
+ public static void Refresh()
+ {
+ LoadProjectGroupDefinitions();
+ }
+
+ private static void LoadProjectGroupDefinitions()
+ {
+ var paths = AssetDatabase.FindAssets("t:" + nameof(ScriptableGroupDefinition))
+ .Select(guid => AssetDatabase.GUIDToAssetPath(guid));
+
+ _projectGroupDefinitions = paths
+ .Select(path => AssetDatabase.LoadAssetAtPath(path))
+ .ToArray();
+ }
+
+ public static IEnumerable GetUnusedMainToolbarElementIds(IEnumerable allIds)
+ {
+ return allIds.Except(GetUsedMainToolbarElementIds());
+ }
+
+ private static IEnumerable GetUsedMainToolbarElementIds()
+ {
+ return _projectGroupDefinitions
+ .SelectMany(groupDefinition => groupDefinition.ToolbarElementsIds);
+ }
+
+ public static IEnumerable GetGroupIds()
+ {
+ return _projectGroupDefinitions.Select(g => g.GroupId);
+ }
+
+ public static IEnumerable GetEligibleGroupChildsFor(string groupId)
+ {
+ var allUsedIds = _projectGroupDefinitions.SelectMany(g => g.ToolbarElementsIds);
+
+ return _projectGroupDefinitions.Select(g => g.GroupId)
+ .Where(id => !allUsedIds.Contains(id))
+ .Where(id => id != groupId);
+ }
+
+ private static void OnProjectChange()
+ {
+ Refresh();
+ }
+ }
+}
diff --git a/Editor/Toolbar/GroupDefinitions/ScriptableGroupDefinitionHelper.cs.meta b/Editor/Toolbar/GroupDefinitions/ScriptableGroupDefinitionHelper.cs.meta
new file mode 100644
index 0000000..83b04a8
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/ScriptableGroupDefinitionHelper.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 12a0d38180307184e87497e8fbb28985
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/GroupDefinitions/ScriptableObjectGroupDefinitionRepository.cs b/Editor/Toolbar/GroupDefinitions/ScriptableObjectGroupDefinitionRepository.cs
new file mode 100644
index 0000000..f8c5d95
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/ScriptableObjectGroupDefinitionRepository.cs
@@ -0,0 +1,38 @@
+using System.Linq;
+using UnityEditor;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class ScriptableObjectGroupDefinitionRepository : IGroupDefinitionRepository
+ {
+ public GroupDefinition[] GetAll()
+ {
+ var paths = AssetDatabase.FindAssets("t:" + nameof(ScriptableGroupDefinition))
+ .Select(guid => AssetDatabase.GUIDToAssetPath(guid));
+
+ return paths
+ .Select(path => AssetDatabase.LoadAssetAtPath(path))
+ .Where(scriptableGroupDefinition => !string.IsNullOrEmpty(scriptableGroupDefinition.GroupId))
+ .GroupBy(scriptableGroupDefinition => scriptableGroupDefinition.GroupId)
+ .Select(scriptableGroupDefinition => scriptableGroupDefinition.First())
+ .Select(scriptableGroupDefinition => new GroupDefinition(
+ scriptableGroupDefinition.GroupId,
+ scriptableGroupDefinition.GroupName,
+ scriptableGroupDefinition.Alignment,
+ scriptableGroupDefinition.Order,
+ FilterIds(scriptableGroupDefinition)
+ )
+ )
+ .Where(m => m.ToolbarElementsIds.Length > 0)
+ .ToArray();
+ }
+
+ private string[] FilterIds(ScriptableGroupDefinition scriptableGroupDefinition)
+ {
+ return scriptableGroupDefinition.ToolbarElementsIds
+ .Where(id => !string.IsNullOrEmpty(id))
+ .Distinct()
+ .ToArray();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/GroupDefinitions/ScriptableObjectGroupDefinitionRepository.cs.meta b/Editor/Toolbar/GroupDefinitions/ScriptableObjectGroupDefinitionRepository.cs.meta
new file mode 100644
index 0000000..297cac0
--- /dev/null
+++ b/Editor/Toolbar/GroupDefinitions/ScriptableObjectGroupDefinitionRepository.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 225393fc4d1ad744c972f3a876dce3df
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/Helpers.meta b/Editor/Toolbar/Helpers.meta
new file mode 100644
index 0000000..0714222
--- /dev/null
+++ b/Editor/Toolbar/Helpers.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: efeeca875749f6d46905cc399ed76bae
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/Helpers/GlobalActions.cs b/Editor/Toolbar/Helpers/GlobalActions.cs
new file mode 100644
index 0000000..28f11d7
--- /dev/null
+++ b/Editor/Toolbar/Helpers/GlobalActions.cs
@@ -0,0 +1,34 @@
+using System;
+using UnityEditor;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal static class GlobalActions
+ {
+ public static void ResetOverrides()
+ {
+ ServicesAndRepositories.MainToolbarElementOverridesRepository.Clear();
+ MainToolbarAutomaticExtender.Refresh();
+ }
+
+ public static void ResetOverridesIfUserAccepts()
+ {
+ ShowDialog(
+ "Reset Overrides",
+ "You are about to reset all toolbar elements overrides.\nAre you sure you want to continue?",
+ "Reset",
+ "Cancel",
+ ResetOverrides
+ );
+ }
+
+ public static void ShowDialog(string title, string message, string okMessage,
+ string cancelMessage, Action onOk = null, Action onCancel = null)
+ {
+ if (EditorUtility.DisplayDialog(title, message, okMessage, cancelMessage))
+ onOk?.Invoke();
+ else
+ onCancel?.Invoke();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/Helpers/GlobalActions.cs.meta b/Editor/Toolbar/Helpers/GlobalActions.cs.meta
new file mode 100644
index 0000000..3a3c774
--- /dev/null
+++ b/Editor/Toolbar/Helpers/GlobalActions.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: bfe995773a109214db8292f8ce74d342
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/Helpers/Icons.cs b/Editor/Toolbar/Helpers/Icons.cs
new file mode 100644
index 0000000..24d5b8a
--- /dev/null
+++ b/Editor/Toolbar/Helpers/Icons.cs
@@ -0,0 +1,18 @@
+using System;
+using UnityEditor;
+using UnityEngine;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal static class Icons
+ {
+ private static readonly Lazy VISIBILITY_ON_OVERRIDE_ICON_LAZY =
+ new Lazy(() => EditorGUIUtility.IconContent("animationvisibilitytoggleon").image);
+
+ private static readonly Lazy VISIBILITY_OFF_OVERRIDE_ICON_LAZY =
+ new Lazy(() => EditorGUIUtility.IconContent("animationvisibilitytoggleoff").image);
+
+ public static Texture VisibilityOnOverrideIcon => VISIBILITY_ON_OVERRIDE_ICON_LAZY.Value;
+ public static Texture VisibilityOffOverrideIcon => VISIBILITY_OFF_OVERRIDE_ICON_LAZY.Value;
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/Helpers/Icons.cs.meta b/Editor/Toolbar/Helpers/Icons.cs.meta
new file mode 100644
index 0000000..64a811e
--- /dev/null
+++ b/Editor/Toolbar/Helpers/Icons.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 51ede7e0c6a32a74faa6298082ed29cc
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/Helpers/MenuItems.cs b/Editor/Toolbar/Helpers/MenuItems.cs
new file mode 100644
index 0000000..ca1c4f0
--- /dev/null
+++ b/Editor/Toolbar/Helpers/MenuItems.cs
@@ -0,0 +1,19 @@
+using UnityEditor;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal static class MenuItems
+ {
+ [MenuItem(ToolInfo.EDITOR_MENU_BASE + "/Refresh Toolbar Extender", priority = 1)]
+ public static void Refresh()
+ {
+ MainToolbarAutomaticExtender.Refresh();
+ }
+
+ [MenuItem(ToolInfo.EDITOR_MENU_BASE + "/Main Toolbar Control Panel", priority = 12)]
+ public static void OpenControlPanel()
+ {
+ MainToolbarControlPanelWindow.OpenWindow();
+ }
+ }
+}
diff --git a/Editor/Toolbar/Helpers/MenuItems.cs.meta b/Editor/Toolbar/Helpers/MenuItems.cs.meta
new file mode 100644
index 0000000..beaf989
--- /dev/null
+++ b/Editor/Toolbar/Helpers/MenuItems.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a74255adbb601344cb6b565d617de6f1
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/Helpers/RefreshToolbarAutomaticExtenderOnSave.cs b/Editor/Toolbar/Helpers/RefreshToolbarAutomaticExtenderOnSave.cs
new file mode 100644
index 0000000..658a389
--- /dev/null
+++ b/Editor/Toolbar/Helpers/RefreshToolbarAutomaticExtenderOnSave.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Linq;
+using UnityEditor;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class RefreshToolbarAutomaticExtenderOnSave : AssetModificationProcessor
+ {
+ private static string[] OnWillSaveAssets(string[] paths)
+ {
+ var groupDefinitionsAssetsPaths = AssetDatabase.FindAssets("t:" + nameof(ScriptableGroupDefinition))
+ .Select(guid => AssetDatabase.GUIDToAssetPath(guid))
+ .ToArray();
+
+ if (GroupDefinitionAssetIsBeingSaved(paths, groupDefinitionsAssetsPaths))
+ {
+ EditorApplication.update += RefreshOneTime;
+ }
+
+ return paths;
+ }
+
+ private static bool GroupDefinitionAssetIsBeingSaved(string[] savingAssetsPaths, string[] groupDefinitionsAssetsPaths)
+ {
+ return savingAssetsPaths.Any(path => groupDefinitionsAssetsPaths.Contains(path));
+ }
+
+ private static void RefreshOneTime()
+ {
+ EditorApplication.update -= RefreshOneTime;
+ Refresh();
+ }
+
+ private static void Refresh()
+ {
+ MainToolbarAutomaticExtender.Refresh();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/Helpers/RefreshToolbarAutomaticExtenderOnSave.cs.meta b/Editor/Toolbar/Helpers/RefreshToolbarAutomaticExtenderOnSave.cs.meta
new file mode 100644
index 0000000..966e2b3
--- /dev/null
+++ b/Editor/Toolbar/Helpers/RefreshToolbarAutomaticExtenderOnSave.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e74405729947e434fb3760be36ad262e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/Helpers/ServicesAndRepositories.cs b/Editor/Toolbar/Helpers/ServicesAndRepositories.cs
new file mode 100644
index 0000000..4f8e465
--- /dev/null
+++ b/Editor/Toolbar/Helpers/ServicesAndRepositories.cs
@@ -0,0 +1,23 @@
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal static class ServicesAndRepositories
+ {
+ public static IMainToolbarElementOverrideRepository MainToolbarElementOverridesRepository =
+ new UserSettingsFileMainToolbarElementOverrideRepository();
+
+ public static IGroupDefinitionRepository GroupDefinitionRepository =
+ new ScriptableObjectGroupDefinitionRepository();
+
+ public static IMainToolbarElementRepository MainToolbarElementRepository =
+ new ByAttributeMainToolbarElementRepository();
+
+ public static IValueSerializer ValueSerializer =
+ new UnitySerializationValueSerializer();
+
+ public static IMainToolbarElementVariableSerializer MainToolbarElementVariableSerializer =
+ new UnitySerializationMainToolbarElementVariableSerializer(ValueSerializer);
+
+ public static IMainToolbarElementVariableRepository MainToolbarElementVariableRepository =
+ new UserSettingsFileMainToolbarElementVariableRepository(MainToolbarElementVariableSerializer);
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/Helpers/ServicesAndRepositories.cs.meta b/Editor/Toolbar/Helpers/ServicesAndRepositories.cs.meta
new file mode 100644
index 0000000..0fd74ad
--- /dev/null
+++ b/Editor/Toolbar/Helpers/ServicesAndRepositories.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4f95a2c4cbecd4f419ae142074dbb03f
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/Helpers/ToolInfo.cs b/Editor/Toolbar/Helpers/ToolInfo.cs
new file mode 100644
index 0000000..2b14392
--- /dev/null
+++ b/Editor/Toolbar/Helpers/ToolInfo.cs
@@ -0,0 +1,8 @@
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal static class ToolInfo
+ {
+ public const string COMPANY_NAME = "Tools/EditorExtension/Toolbar";
+ public const string EDITOR_MENU_BASE = COMPANY_NAME + "/" ;
+ }
+}
diff --git a/Editor/Toolbar/Helpers/ToolInfo.cs.meta b/Editor/Toolbar/Helpers/ToolInfo.cs.meta
new file mode 100644
index 0000000..04e7a23
--- /dev/null
+++ b/Editor/Toolbar/Helpers/ToolInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c363bf3b832d93c45b14669aa6ae573c
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/Helpers/UnityNativeElementsIds.cs b/Editor/Toolbar/Helpers/UnityNativeElementsIds.cs
new file mode 100644
index 0000000..a6ec37b
--- /dev/null
+++ b/Editor/Toolbar/Helpers/UnityNativeElementsIds.cs
@@ -0,0 +1,120 @@
+using System.Collections.Generic;
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal static class UnityNativeElementsIds
+ {
+ // ------------------- ELEMENTS TYPES ---------------------
+
+ // LEFT
+ private const string ACCOUNT_DROPDOWN_TYPE_NAME = "AccountDropdown";
+ private const string CLOUD_BUTTON_TYPE_NAME = "CloudButton";
+ private const string VERSION_CONTROL_BUTTON_TYPE_NAME = "MainToolbarImguiContainer";
+ private const string STORE_BUTTON_TYPE_NAME = "StoreButton";
+
+ // RIGHT
+ private const string LAYOUT_DROPDOWN_TYPE_NAME = "LayoutDropdown";
+ private const string LAYERS_DROPDOWN_TYPE_NAME = "LayersDropdown";
+ private const string SEARCH_BUTTON_TYPE_NAME = "SearchButton";
+ private const string MODES_DROPDOWN_TYPE_NAME = "ModesDropdown";
+ private const string PREVIEW_PACKAGES_IN_USE_DROPDOWN_TYPE_NAME = "PreviewPackagesInUseDropdown";
+ private const string UNDO_BUTTON_TYPE_NAME = "UndoButton";
+ private const string MULTIPLAYER_ROLE_DROPDOWN_TYPE_NAME = "MultiplayerRoleDropdown";
+
+ // ------------------- ELEMENTS NAMES ---------------------
+
+ // LEFT
+ private const string TOOLBAR_PRODUCT_CAPTION_NAME = "ToolbarProductCaption";
+ private const string ACCOUNT_DROPDOWN_ELEMENT_NAME = "AccountDropdown";
+ private const string CLOUD_BUTTON_ELEMENT_NAME = "Cloud";
+
+ // CENTER
+ private const string PLAY_BUTTON_ELEMENT_NAME = "Play";
+ private const string PAUSE_BUTTON_ELEMENT_NAME = "Pause";
+ private const string FRAME_STEP_BUTTON_ELEMENT_NAME = "Step";
+
+ // RIGHT
+ private const string LAYOUT_DROPDOWN_ELEMENT_NAME = "LayoutDropdown";
+ private const string LAYERS_DROPDOWN_ELEMENT_NAME = "LayersDropdown";
+ private const string MODES_DROPDOWN_ELEMENT_NAME = "ModesDropdown";
+ private const string PREVIEW_PACKAGES_IN_USE_DROPDOWN_ELEMENT_NAME = "PreviewPackagesInUseDropdown";
+ private const string UNDO_BUTTON_ELEMENT_NAME = "History";
+
+ // ------------------- FIXED IDS ---------------------
+
+ // LEFT
+ public const string TOOLBAR_PRODUCT_CAPTION = "ToolbarProductCaption";
+ public const string ACCOUNT_DROPDOWN_ID = "AccountDropdown";
+ public const string CLOUD_BUTTON_ID = "CloudButton";
+ public const string VERSION_CONTROL_ID = "VersionControlButton";
+ public const string STORE_BUTTON_ID = "StoreButton";
+
+ // CENTER
+ public const string PLAY_BUTTON_ID = "PlayButton";
+ public const string PAUSE_BUTTON_ID = "PauseButton";
+ public const string FRAME_STEP_BUTTON_ID = "FrameStepButton";
+
+ // RIGHT
+ public const string LAYOUT_DROPDOWN_ID = "LayoutDropdown";
+ public const string LAYERS_DROPDOWN_ID = "LayersDropdown";
+ public const string SEARCH_BUTTON_ID = "SearchButton";
+ public const string MODES_DROPDOWN_ID = "ModesDropdown";
+ public const string PREVIEW_PACKAGES_IN_USE_DROPDOWN_ID = "PreviewPackagesInUseDropdown";
+ public const string UNDO_BUTTON_ID = "UndoButton";
+ public const string MULTIPLAYER_ROLE_DROPDOWN = "MultiplayerRoleDropdown";
+
+ private static readonly Dictionary IDS_BY_TYPE = new Dictionary()
+ {
+ // LEFT
+ { ACCOUNT_DROPDOWN_TYPE_NAME, ACCOUNT_DROPDOWN_ID },
+ { CLOUD_BUTTON_TYPE_NAME, CLOUD_BUTTON_ID },
+ { VERSION_CONTROL_BUTTON_TYPE_NAME, VERSION_CONTROL_ID },
+ { STORE_BUTTON_TYPE_NAME, STORE_BUTTON_ID },
+
+ // RIGHT
+ { LAYOUT_DROPDOWN_TYPE_NAME, LAYOUT_DROPDOWN_ID },
+ { LAYERS_DROPDOWN_TYPE_NAME, LAYERS_DROPDOWN_ID },
+ { SEARCH_BUTTON_TYPE_NAME, SEARCH_BUTTON_ID },
+ { MODES_DROPDOWN_TYPE_NAME, MODES_DROPDOWN_ID },
+ { PREVIEW_PACKAGES_IN_USE_DROPDOWN_TYPE_NAME, PREVIEW_PACKAGES_IN_USE_DROPDOWN_ID },
+ { UNDO_BUTTON_TYPE_NAME, UNDO_BUTTON_ID },
+ { MULTIPLAYER_ROLE_DROPDOWN_TYPE_NAME, MULTIPLAYER_ROLE_DROPDOWN }
+ };
+
+ private static readonly Dictionary IDS_BY_NAME = new Dictionary()
+ {
+ // LEFT
+ { TOOLBAR_PRODUCT_CAPTION_NAME, TOOLBAR_PRODUCT_CAPTION },
+ { ACCOUNT_DROPDOWN_ELEMENT_NAME, ACCOUNT_DROPDOWN_ID },
+ { CLOUD_BUTTON_ELEMENT_NAME, CLOUD_BUTTON_ID },
+
+ // CENTER
+ { PLAY_BUTTON_ELEMENT_NAME, PLAY_BUTTON_ID },
+ { PAUSE_BUTTON_ELEMENT_NAME, PAUSE_BUTTON_ID },
+ { FRAME_STEP_BUTTON_ELEMENT_NAME, FRAME_STEP_BUTTON_ID },
+
+ // RIGHT
+ { LAYOUT_DROPDOWN_ELEMENT_NAME, LAYOUT_DROPDOWN_ID },
+ { LAYERS_DROPDOWN_ELEMENT_NAME, LAYERS_DROPDOWN_ID },
+ { MODES_DROPDOWN_ELEMENT_NAME, MODES_DROPDOWN_ID },
+ { PREVIEW_PACKAGES_IN_USE_DROPDOWN_ELEMENT_NAME, PREVIEW_PACKAGES_IN_USE_DROPDOWN_ID },
+ { UNDO_BUTTON_ELEMENT_NAME, UNDO_BUTTON_ID },
+ };
+
+ public static string IdOf(VisualElement visualElement)
+ {
+ var typeName = visualElement.GetType().Name;
+
+ if(IDS_BY_TYPE.ContainsKey(typeName))
+ return IDS_BY_TYPE[typeName];
+
+ var elementName = visualElement.name;
+
+ if(IDS_BY_NAME.ContainsKey(elementName))
+ return IDS_BY_NAME[elementName];
+
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/Helpers/UnityNativeElementsIds.cs.meta b/Editor/Toolbar/Helpers/UnityNativeElementsIds.cs.meta
new file mode 100644
index 0000000..61ae332
--- /dev/null
+++ b/Editor/Toolbar/Helpers/UnityNativeElementsIds.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 62370caf7a9d1274ba18d9556d83fd07
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/Helpers/UserSettingsPrefs.cs b/Editor/Toolbar/Helpers/UserSettingsPrefs.cs
new file mode 100644
index 0000000..9b8c024
--- /dev/null
+++ b/Editor/Toolbar/Helpers/UserSettingsPrefs.cs
@@ -0,0 +1,118 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Unity.Serialization.Json;
+using UnityEngine;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ public static class UserSettingsPrefs
+ {
+ private static readonly string DIRECTORY = Path.Combine(Directory.GetParent(Application.dataPath).FullName, "UserSettings/", "unity-toolbar-extender-ui-toolkit", "user-settings-prefs");
+ private static readonly string FILE = Path.Combine(DIRECTORY, "user-settings-prefs.json");
+
+ private static Dictionary _prefs;
+ private static Dictionary Prefs
+ {
+ get
+ {
+ if (_prefs == null)
+ _prefs = Load();
+
+ return _prefs;
+ }
+ }
+
+ public static void SetInt(string key, int value)
+ {
+ Prefs[key] = value;
+ Save();
+ }
+
+ public static void SetFloat(string key, float value)
+ {
+ Prefs[key] = value;
+ Save();
+ }
+
+ public static void SetDouble(string key, double value)
+ {
+ Prefs[key] = value;
+ Save();
+ }
+
+ public static void SetBool(string key, bool value)
+ {
+ Prefs[key] = value;
+ Save();
+ }
+
+ public static void SetString(string key, string value)
+ {
+ Prefs[key] = value;
+ Save();
+ }
+
+ public static string GetString(string key, string defaultValue = null)
+ {
+ if (Prefs.ContainsKey(key))
+ return (string)Prefs[key];
+
+ return defaultValue;
+ }
+
+ public static bool GetBool(string key, bool defaultValue = false)
+ {
+ if (Prefs.ContainsKey(key))
+ return (bool)Prefs[key];
+
+ return defaultValue;
+ }
+
+ public static int GetInt(string key, int defaultValue = 0)
+ {
+ if (Prefs.ContainsKey(key))
+ return Convert.ToInt32(Prefs[key]);
+
+ return defaultValue;
+ }
+
+ public static float GetFloat(string key, float defaultValue = 0.0f)
+ {
+ if (Prefs.ContainsKey(key))
+ return Convert.ToSingle(Prefs[key]);
+
+ return defaultValue;
+ }
+
+ public static double GetDouble(string key, double defaultValue = 0.0)
+ {
+ if (Prefs.ContainsKey(key))
+ return Convert.ToDouble(Prefs[key]);
+
+ return defaultValue;
+ }
+
+ private static Dictionary Load()
+ {
+ if (!Directory.Exists(DIRECTORY))
+ Directory.CreateDirectory(DIRECTORY);
+
+ if (!File.Exists(FILE))
+ return JsonSerialization.FromJson>("{}");
+
+ var json = File.ReadAllText(FILE);
+
+ var serializedDictionary = JsonSerialization.FromJson>(json);
+
+ return serializedDictionary;
+ }
+
+ private static void Save()
+ {
+ var json = JsonSerialization.ToJson(Prefs);
+
+ File.WriteAllText(FILE, json);
+ }
+ }
+}
diff --git a/Editor/Toolbar/Helpers/UserSettingsPrefs.cs.meta b/Editor/Toolbar/Helpers/UserSettingsPrefs.cs.meta
new file mode 100644
index 0000000..0593120
--- /dev/null
+++ b/Editor/Toolbar/Helpers/UserSettingsPrefs.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fad7572312c85da4e80e115c63b2d164
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/IMainToolbarElementRepository.cs b/Editor/Toolbar/IMainToolbarElementRepository.cs
new file mode 100644
index 0000000..df3d199
--- /dev/null
+++ b/Editor/Toolbar/IMainToolbarElementRepository.cs
@@ -0,0 +1,7 @@
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal interface IMainToolbarElementRepository
+ {
+ public MainToolbarElement[] GetAll();
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/IMainToolbarElementRepository.cs.meta b/Editor/Toolbar/IMainToolbarElementRepository.cs.meta
new file mode 100644
index 0000000..b120dfa
--- /dev/null
+++ b/Editor/Toolbar/IMainToolbarElementRepository.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b6fdece3308162d4994b872bcb838c72
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/MainToolbar.cs b/Editor/Toolbar/MainToolbar.cs
new file mode 100644
index 0000000..ff2a5dc
--- /dev/null
+++ b/Editor/Toolbar/MainToolbar.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Reflection;
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ [InitializeOnLoad]
+ public static class MainToolbar
+ {
+ private const string TOOLBAR_ROOT_ELEMENT_FIELD_NAME = "m_Root";
+ private const string TOOLBAR_CENTER_CONTAINER_NAME = "ToolbarZonePlayMode";
+ private const string TOOLBAR_LEFT_CONTAINER_NAME = "ToolbarZoneLeftAlign";
+ private const string TOOLBAR_RIGHT_CONTAINER_NAME = "ToolbarZoneRightAlign";
+ private const string TOOLBAR_PLAY_BUTTON_NAME = "Play";
+
+ private static Type _toolbarType = typeof(Editor).Assembly.GetType("UnityEditor.Toolbar");
+ private static ScriptableObject _innerToolbarObject;
+
+ public static event Action OnInitialized;
+ public static event Action OnRefresh;
+
+ public static VisualElement UnityToolbarRoot { get; private set; }
+
+ public static VisualElement LeftContainer { get; private set; }
+ public static VisualElement CenterContainer { get; private set; }
+ public static VisualElement RightContainer { get; private set; }
+ public static VisualElement PlayModeButtonsContainer { get; private set; }
+
+ public static bool IsAvailable => _innerToolbarObject != null;
+
+ private static bool _initialized;
+
+ static MainToolbar()
+ {
+ EditorApplication.update -= OnUpdate;
+ EditorApplication.update += OnUpdate;
+ }
+
+ private static void WrapNativeToolbar()
+ {
+ FindUnityToolbar();
+ if (_innerToolbarObject == null)
+ return;
+ CacheNativeToolbarContainers();
+
+ if(!_initialized)
+ {
+ _initialized = true;
+ OnInitialized?.Invoke();
+ }
+ else
+ OnRefresh?.Invoke();
+ }
+
+ private static void FindUnityToolbar()
+ {
+ var toolbars = Resources.FindObjectsOfTypeAll(_toolbarType);
+ _innerToolbarObject = toolbars.Length > 0 ? (ScriptableObject)toolbars[0] : null;
+ }
+
+ private static void CacheNativeToolbarContainers()
+ {
+ var unityToolbarRootFieldInfo = _innerToolbarObject.GetType()
+ .GetField(TOOLBAR_ROOT_ELEMENT_FIELD_NAME, BindingFlags.NonPublic | BindingFlags.Instance);
+ UnityToolbarRoot = unityToolbarRootFieldInfo.GetValue(_innerToolbarObject) as VisualElement;
+
+ LeftContainer = UnityToolbarRoot.Q(TOOLBAR_LEFT_CONTAINER_NAME);
+ CenterContainer = UnityToolbarRoot.Q(TOOLBAR_CENTER_CONTAINER_NAME);
+ RightContainer = UnityToolbarRoot.Q(TOOLBAR_RIGHT_CONTAINER_NAME);
+ PlayModeButtonsContainer = CenterContainer.Q(TOOLBAR_PLAY_BUTTON_NAME).parent;
+ }
+
+ private static void OnUpdate()
+ {
+ if (NeedsWrap())
+ {
+ WrapNativeToolbar();
+ }
+ }
+
+ private static bool NeedsWrap()
+ {
+ return _innerToolbarObject == null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/MainToolbar.cs.meta b/Editor/Toolbar/MainToolbar.cs.meta
new file mode 100644
index 0000000..912245e
--- /dev/null
+++ b/Editor/Toolbar/MainToolbar.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ce77a44ce866ce34d9ce10f93b19c256
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/MainToolbarAutomaticExtender.cs b/Editor/Toolbar/MainToolbarAutomaticExtender.cs
new file mode 100644
index 0000000..2decf20
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarAutomaticExtender.cs
@@ -0,0 +1,330 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEditor;
+using UnityEngine.UIElements;
+using System.Reflection;
+using UnityEngine;
+using UnityEditor.SceneManagement;
+using UnityEngine.SceneManagement;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ [InitializeOnLoad]
+ public static class MainToolbarAutomaticExtender
+ {
+ private static MainToolbarElement[] _mainToolbarElements = new MainToolbarElement[0];
+ private static MainToolbarElement[] _groupElements = new MainToolbarElement[0];
+ private static GroupDefinition[] _groupDefinitions = new GroupDefinition[0];
+ private static MainToolbarElement[] _rootElements = new MainToolbarElement[0];
+ private static NativeToolbarElement[] _nativeElements = new NativeToolbarElement[0];
+ private static MainToolbarElement[] _singleElements = new MainToolbarElement[0];
+ private static MainToolbarElementOverrideApplier _overrideApplier = new MainToolbarElementOverrideApplier(ServicesAndRepositories.MainToolbarElementOverridesRepository);
+ private static Dictionary _elementsByGroup = new Dictionary();
+ private static MainToolbarElementVariableWatcher _variableWatcher = new MainToolbarElementVariableWatcher(ServicesAndRepositories.MainToolbarElementVariableRepository, ServicesAndRepositories.ValueSerializer);
+
+ internal static MainToolbarCustomContainer LeftCustomContainer { get; private set; } = new MainToolbarCustomContainer("ToolbarAutomaticExtenderLeftContainer", FlexDirection.RowReverse);
+ internal static MainToolbarCustomContainer RightCustomContainer { get; private set; } = new MainToolbarCustomContainer("ToolbarAutomaticExtenderRightContainer", FlexDirection.Row);
+
+ internal static MainToolbarElement[] CustomMainToolbarElements => _mainToolbarElements.ToArray();
+ internal static MainToolbarElement[] GroupElements => _groupElements.ToArray();
+ internal static NativeToolbarElement[] NativeElements => _nativeElements.ToArray();
+
+ public static event Action OnRefresh;
+ public static event Action OnAddedCustomContainersToToolbar;
+
+ static MainToolbarAutomaticExtender()
+ {
+ MainToolbar.OnInitialized += Initialize;
+ }
+
+ private static void Initialize()
+ {
+ BuildCustomToolbarContainers();
+
+ if (_mainToolbarElements.Length == 0)
+ return;
+
+ EditorApplication.projectChanged += OnProjectChange;
+ MainToolbar.OnRefresh += ApplyFixedChangesToToolbar;
+
+ CacheNativeElements();
+ ApplyFixedChangesToToolbar();
+ }
+
+ private static void CacheNativeElements()
+ {
+ var nativeElements = GetNativeElements();
+ if (nativeElements.Length != 0)
+ {
+ _nativeElements = nativeElements;
+ _overrideApplier.SetNativeElements(_nativeElements);
+ }
+ }
+
+ internal static void Refresh()
+ {
+ if (!MainToolbar.IsAvailable)
+ return;
+
+ ResetCustomContainers();
+ BuildCustomToolbarContainers();
+ _overrideApplier.ApplyOverrides();
+ OnRefresh?.Invoke();
+ }
+
+ internal static MainToolbarElement[] GetElementsOfGroup(string id)
+ {
+ return _elementsByGroup[id].ToArray();
+ }
+
+ private static void ResetCustomContainers()
+ {
+ LeftCustomContainer.ClearContainer();
+ RightCustomContainer.ClearContainer();
+ }
+
+ private static void BuildCustomToolbarContainers()
+ {
+ _mainToolbarElements = ServicesAndRepositories.MainToolbarElementRepository.GetAll();
+
+ if (_mainToolbarElements.Count() == 0)
+ return;
+
+ _groupDefinitions = LoadGroupDefinitions();
+ _groupElements = GetGroups();
+ _elementsByGroup = GetElementsByGroup();
+ InitializeGroups();
+ _singleElements = GetSingles();
+ _rootElements = GetRootElements();
+ _overrideApplier.SetCustomElements(_mainToolbarElements.Concat(_groupElements).ToArray());
+ _variableWatcher.RestoreValues(CustomMainToolbarElements);
+
+ InitializeCustomElements();
+ RegisterElementsForRecommendedStyles();
+
+ AddRootElementsToContainers();
+
+ EditorApplication.update += Update;
+ }
+
+ private static void InitializeCustomElements()
+ {
+ foreach(var customElement in CustomMainToolbarElements)
+ {
+ var typeOfElement = customElement.VisualElement.GetType();
+
+ var initializeMethod = typeOfElement.GetMethod("InitializeElement", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
+ initializeMethod?.Invoke(customElement.VisualElement, null);
+ }
+ }
+
+ private static void Update()
+ {
+ _variableWatcher.Update();
+ }
+
+ private static void InitializeGroups()
+ {
+ foreach (var group in _groupElements)
+ {
+ var groupElement = group.VisualElement as GroupElement;
+ var elementsOfThisGroup = _elementsByGroup[group.Id]
+ .Select(e => e.VisualElement)
+ .ToArray();
+
+ groupElement.Initialize(elementsOfThisGroup);
+ }
+ }
+
+ private static void RegisterElementsForRecommendedStyles()
+ {
+ var eligibleElements = _mainToolbarElements
+ .Concat(_groupElements)
+ .Where(element => element.UseRecommendedStyles)
+ .Select(element => new RecommendedStyleVisualElement(element.VisualElement, IsInGroup(element)))
+ .ToArray();
+
+ RecommendedStyles.SetElements(eligibleElements);
+ }
+
+ private static bool IsInGroup(MainToolbarElement mainToolbarElement)
+ {
+ return !_rootElements.Contains(mainToolbarElement);
+ }
+
+ private static MainToolbarElement[] GetRootElements()
+ {
+ return GetRootGroups()
+ .Concat(_singleElements)
+ .ToArray();
+ }
+
+ private static MainToolbarElement[] GetRootGroups()
+ {
+ var rootGroups = new List();
+
+ var allGroupElements = _groupElements.Select(group => group.VisualElement as GroupElement);
+
+ foreach (var group in _groupElements)
+ {
+ var groupElement = group.VisualElement as GroupElement;
+
+ if (!allGroupElements.Any(g => g.GroupedElements.Contains(groupElement)))
+ rootGroups.Add(group);
+ }
+
+ return rootGroups.ToArray();
+ }
+
+ private static NativeToolbarElement[] GetNativeElements()
+ {
+ return MainToolbar.LeftContainer.Children()
+ .Concat(MainToolbar.RightContainer.Children())
+ .Concat(MainToolbar.PlayModeButtonsContainer.Children())
+ .Where(visualElement => UnityNativeElementsIds.IdOf(visualElement) != null)
+ .Select(visualElement => new NativeToolbarElement(UnityNativeElementsIds.IdOf(visualElement), visualElement))
+ .ToArray();
+ }
+
+ private static void ApplyFixedChangesToToolbar()
+ {
+ ConfigureStyleOfContainers();
+ AddCustomContainers();
+ _overrideApplier.ApplyOverrides();
+ OnAddedCustomContainersToToolbar?.Invoke();
+ }
+
+ private static void AddCustomContainers()
+ {
+ MainToolbar.CenterContainer.Insert(0, LeftCustomContainer);
+ MainToolbar.CenterContainer.Add(RightCustomContainer);
+ }
+
+ private static void AddRootElementsToContainers()
+ {
+ var leftElements = _rootElements.Where(el => el.Alignment == ToolbarAlign.Left)
+ .OrderBy(el => el.Order);
+
+ var rightElements = _rootElements.Where(el => el.Alignment == ToolbarAlign.Right)
+ .OrderBy(el => el.Order);
+
+ foreach (var orderedAlignedElement in leftElements)
+ LeftCustomContainer.AddToContainer(orderedAlignedElement.VisualElement);
+
+ foreach (var orderedAlignedElement in rightElements)
+ RightCustomContainer.AddToContainer(orderedAlignedElement.VisualElement);
+ }
+
+ private static MainToolbarElement[] GetGroups()
+ {
+ var groups = new List();
+
+ foreach (var groupDefinition in _groupDefinitions)
+ {
+ if (groupDefinition.ToolbarElementsIds.Length == 0)
+ continue;
+
+ var groupToolbarElement = new MainToolbarElement(
+ groupDefinition.GroupId,
+ new GroupElement(groupDefinition.GroupName),
+ groupDefinition.Alignment,
+ groupDefinition.Order,
+ true
+ );
+
+ groups.Add(groupToolbarElement);
+ }
+
+ return groups.ToArray();
+ }
+
+ private static MainToolbarElement[] GetSingles()
+ {
+ var elementsInGroups = _elementsByGroup.Values.SelectMany(list => list);
+
+ return _mainToolbarElements
+ .Where(mainToolbarElement => !elementsInGroups.Contains(mainToolbarElement))
+ .ToArray();
+ }
+
+ private static Dictionary GetElementsByGroup()
+ {
+ var elementsByGroup = new Dictionary();
+
+ foreach (var groupDefinition in _groupDefinitions)
+ {
+ var elementsOfThisGroup = groupDefinition.ToolbarElementsIds
+ .Select(id =>
+ {
+ var element = _mainToolbarElements.FirstOrDefault(e => e.Id == id);
+
+ if (element != null)
+ return element;
+
+ element = _groupElements.FirstOrDefault(e => e.Id == id);
+
+ return element;
+ })
+ .Where(mainToolbarElement => mainToolbarElement != null)
+ .ToList();
+
+ elementsByGroup.Add(groupDefinition.GroupId, elementsOfThisGroup.ToArray());
+ }
+
+ return elementsByGroup;
+ }
+
+ private static GroupDefinition[] LoadGroupDefinitions()
+ {
+ return ServicesAndRepositories.GroupDefinitionRepository.GetAll();
+ }
+
+ private static void ConfigureStyleOfContainers()
+ {
+ MainToolbar.LeftContainer.style.flexGrow = 0;
+ MainToolbar.LeftContainer.style.width = Length.Auto();
+
+ MainToolbar.RightContainer.style.flexGrow = 0;
+ MainToolbar.RightContainer.style.width = Length.Auto();
+
+ MainToolbar.CenterContainer.style.flexGrow = 1;
+
+ MainToolbar.CenterContainer.parent.style.paddingTop = 0;
+ MainToolbar.CenterContainer.parent.style.paddingBottom = 0;
+ }
+
+ private static void OnProjectChange()
+ {
+ if(ShouldRefresh())
+ Refresh();
+ }
+
+ private static bool ShouldRefresh()
+ {
+ return GroupsChanged();
+ }
+
+ private static bool GroupsChanged()
+ {
+ var groups = ServicesAndRepositories.GroupDefinitionRepository.GetAll();
+
+ if (_groupDefinitions.Length != groups.Length)
+ return true;
+
+ if (_groupDefinitions.Length == 0 && groups.Length == 0)
+ return false;
+
+ for(int i = 0; i < _groupDefinitions.Length; i++)
+ {
+ var savedGroupDefinition = _groupDefinitions[i];
+ var retrievedGroupDefinition = groups[i];
+
+ if (!savedGroupDefinition.AreEquals(retrievedGroupDefinition))
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/MainToolbarAutomaticExtender.cs.meta b/Editor/Toolbar/MainToolbarAutomaticExtender.cs.meta
new file mode 100644
index 0000000..ec98cfa
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarAutomaticExtender.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6fd1abb4edafb6a4793209e0f154d8a8
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/MainToolbarCustomContainer.cs b/Editor/Toolbar/MainToolbarCustomContainer.cs
new file mode 100644
index 0000000..aa060bb
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarCustomContainer.cs
@@ -0,0 +1,95 @@
+using System.Linq;
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class MainToolbarCustomContainer : VisualElement
+ {
+ private const string LAST_SCROLLER_POSITION_SAVE_KEY_BASE = "main-toolbar-custom-container:last-scroller-position:";
+
+ private const float SCROLL_VIEW_SCROLLER_HEIGHT = 1;
+ private const float SCROLLER_HEIGHT = 5;
+ private const float SCROLL_VIEW_HORIZONTAL_PADDING = 5;
+ private const float SCROLL_VIEW_SCROLLER_BORDER_TOP_WIDTH = 0;
+
+ private string _id;
+ private ScrollView _scrollView;
+ private Scroller _scroller;
+ private VisualElement _container;
+
+ public MainToolbarCustomContainer(string id, FlexDirection flexDirection)
+ {
+ _id = id;
+ name = id;
+
+ style.flexDirection = flexDirection;
+ style.flexGrow = 1;
+ style.width = 0;
+
+ _container = CreateAndAddContainer(flexDirection);
+ }
+
+ private VisualElement CreateAndAddContainer(FlexDirection flexDirection)
+ {
+ _scrollView = new ScrollView(ScrollViewMode.Horizontal);
+
+ _scrollView.style.paddingLeft = SCROLL_VIEW_HORIZONTAL_PADDING;
+ _scrollView.style.paddingRight = SCROLL_VIEW_HORIZONTAL_PADDING;
+
+ _scrollView.verticalScrollerVisibility = ScrollerVisibility.Hidden;
+ _scrollView.contentContainer.style.flexDirection = flexDirection;
+
+ _scroller = _scrollView.horizontalScroller;
+
+ var leftButton = _scroller.lowButton;
+ var rightButton = _scroller.highButton;
+ var slider = _scroller.slider;
+
+ _scroller.style.height = SCROLL_VIEW_SCROLLER_HEIGHT;
+ _scroller.style.borderTopWidth = SCROLL_VIEW_SCROLLER_BORDER_TOP_WIDTH;
+ leftButton.style.height = SCROLLER_HEIGHT;
+ rightButton.style.height = SCROLLER_HEIGHT;
+ slider.style.height = SCROLLER_HEIGHT;
+
+ Add(_scrollView);
+ _scrollView.RegisterCallback(LoadLastScrollerPosition);
+
+ return _scrollView;
+ }
+
+ private void LoadLastScrollerPosition(GeometryChangedEvent eventArgs)
+ {
+ _scroller.value = (float)LastScrollerPosition();
+ _scroller.valueChanged += SaveScrollerPosition;
+
+ _scrollView.UnregisterCallback(LoadLastScrollerPosition);
+ }
+
+ private double LastScrollerPosition()
+ {
+ return UserSettingsPrefs.GetDouble(GetFullKey(), 0d);
+ }
+
+ private void SaveScrollerPosition(float newPosition)
+ {
+ UserSettingsPrefs.SetDouble(GetFullKey(), newPosition);
+ }
+
+ private string GetFullKey() => LAST_SCROLLER_POSITION_SAVE_KEY_BASE + _id;
+
+ public void AddToContainer(VisualElement child)
+ {
+ _container.Add(child);
+ }
+
+ public void ClearContainer()
+ {
+ _container.Clear();
+ }
+
+ public VisualElement[] GetContainerChilds()
+ {
+ return _container.Children().ToArray();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/MainToolbarCustomContainer.cs.meta b/Editor/Toolbar/MainToolbarCustomContainer.cs.meta
new file mode 100644
index 0000000..94de1cc
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarCustomContainer.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3a0122c91e132b8478c5d18c85d0df6f
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/MainToolbarElement.cs b/Editor/Toolbar/MainToolbarElement.cs
new file mode 100644
index 0000000..fb8d76b
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElement.cs
@@ -0,0 +1,23 @@
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class MainToolbarElement
+ {
+ public string Id { get; }
+ public VisualElement VisualElement { get; }
+ public ToolbarAlign Alignment { get; }
+ public int Order { get; }
+ public bool UseRecommendedStyles { get; }
+
+ public MainToolbarElement(string id, VisualElement visualElement,
+ ToolbarAlign alignment, int order, bool useRecommendedStyles)
+ {
+ Id = id;
+ VisualElement = visualElement;
+ Alignment = alignment;
+ Order = order;
+ UseRecommendedStyles = useRecommendedStyles;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/MainToolbarElement.cs.meta b/Editor/Toolbar/MainToolbarElement.cs.meta
new file mode 100644
index 0000000..7da1baa
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElement.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f67ca04efaf7f044fa5a17a7627aca0b
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/MainToolbarElementAttribute.cs b/Editor/Toolbar/MainToolbarElementAttribute.cs
new file mode 100644
index 0000000..35271bf
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElementAttribute.cs
@@ -0,0 +1,31 @@
+using System;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
+ public class MainToolbarElementAttribute : Attribute
+ {
+ public string Id { get; }
+ public ToolbarAlign Alignment { get; }
+ public int Order { get; }
+ public bool UseRecommendedStyles { get; }
+
+ ///
+ /// Mark a class derived from VisualElement to be found by toolbar extender
+ ///
+ /// Id of element. Must be unique. In case of collision, first found is used
+ /// Left or right to play buttons. Ignored if inside a group
+ /// Order in which this element will be displayed in toolbar. Ignored if inside a group
+ /// True if this element should use recommended styles. Set it to false if you want to style the visual element yourself.
+ ///
+ public MainToolbarElementAttribute(string id, ToolbarAlign alignment = ToolbarAlign.Left,
+ int order = 0,
+ bool useRecommendedStyles = true)
+ {
+ Id = id;
+ Alignment = alignment;
+ Order = order;
+ UseRecommendedStyles = useRecommendedStyles;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/MainToolbarElementAttribute.cs.meta b/Editor/Toolbar/MainToolbarElementAttribute.cs.meta
new file mode 100644
index 0000000..952db19
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElementAttribute.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d4059a4ac36791549810df04f72dcc75
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/MainToolbarElementOverrideApplier.cs b/Editor/Toolbar/MainToolbarElementOverrideApplier.cs
new file mode 100644
index 0000000..cb13938
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElementOverrideApplier.cs
@@ -0,0 +1,179 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class MainToolbarElementOverrideApplier
+ {
+ private class HiddenRemovedElement
+ {
+ public VisualElement RemovedVisualElement;
+ public VisualElement Parent;
+ public int Index;
+ }
+
+ private static readonly string[] EXCEPTIONAL_ELEMENTS_FOR_VISIBILITY =
+ {
+ UnityNativeElementsIds.ACCOUNT_DROPDOWN_ID,
+ UnityNativeElementsIds.CLOUD_BUTTON_ID
+ };
+ private readonly IMainToolbarElementOverrideRepository _mainToolbarElementOverrideRepository;
+ private MainToolbarElement[] _mainToolbarElements = new MainToolbarElement[0];
+ private NativeToolbarElement[] _nativeElements = new NativeToolbarElement[0];
+ private readonly Dictionary _nativeElementsInitialState = new Dictionary();
+ private readonly Dictionary _hiddenElementsByRemotion = new Dictionary();
+
+ public MainToolbarElementOverrideApplier(IMainToolbarElementOverrideRepository mainToolbarElementOverrideRepository)
+ {
+ _mainToolbarElementOverrideRepository = mainToolbarElementOverrideRepository;
+ }
+
+ public void SetNativeElements(NativeToolbarElement[] nativeElements)
+ {
+ _nativeElements = nativeElements.ToArray();
+
+ SaveNativeElementsInitialState();
+ SetNativeElementsDefaultState(); // necesito hacer esto?
+ }
+
+ public void SetCustomElements(MainToolbarElement[] mainToolbarElements)
+ {
+ _mainToolbarElements = mainToolbarElements.ToArray();
+ }
+
+ public void ApplyOverrides()
+ {
+ SetNativeElementsDefaultState();
+
+ ApplyOverridesOnCustomElements();
+ ApplyOverridesOnNativeElements();
+ }
+
+ private void ApplyOverridesOnCustomElements()
+ {
+ foreach (var mainToolbarElement in _mainToolbarElements)
+ {
+ ApplyOverride(mainToolbarElement.Id, mainToolbarElement.VisualElement);
+ }
+ }
+
+ private void ApplyOverridesOnNativeElements()
+ {
+ foreach (var nativeElement in _nativeElements)
+ {
+ ApplyOverride(nativeElement.Id, nativeElement.VisualElement);
+ }
+ }
+
+ private void SaveNativeElementsInitialState()
+ {
+ if (_nativeElementsInitialState.Count > 0)
+ return;
+
+ foreach (var nativeElement in _nativeElements)
+ {
+ _nativeElementsInitialState[nativeElement.Id] =
+ new MainToolbarElementOverride(
+ nativeElement.Id,
+ nativeElement.VisualElement.resolvedStyle.display == DisplayStyle.Flex
+ );
+ }
+ }
+
+ private void SetNativeElementsDefaultState()
+ {
+ foreach (var nativeElement in _nativeElements)
+ {
+ var defaultStateOverride = _nativeElementsInitialState[nativeElement.Id];
+
+ ApplyOverride(nativeElement, defaultStateOverride);
+ }
+ }
+
+ private void ApplyOverride(NativeToolbarElement nativeElement, MainToolbarElementOverride overrideData)
+ {
+ ApplyVisibilityOverride(nativeElement.Id, nativeElement.VisualElement, overrideData.Visible);
+ }
+
+ private void ApplyOverride(string id, VisualElement visualElement)
+ {
+ var userOverride = _mainToolbarElementOverrideRepository
+ .Get(id);
+
+ if (userOverride == null)
+ return;
+
+ ApplyVisibilityOverride(id, visualElement, userOverride.Value.Visible);
+ }
+
+ private void ApplyVisibilityOverride(string elementId, VisualElement visualElement, bool visible)
+ {
+ if (IsExceptionElementForVisibility(elementId))
+ HandleVisibilityApplicationOnExceptions(elementId, visualElement, visible);
+ else
+ visualElement.style.display = visible ? DisplayStyle.Flex : DisplayStyle.None;
+ }
+
+ private bool IsExceptionElementForVisibility(string elementId)
+ {
+ return EXCEPTIONAL_ELEMENTS_FOR_VISIBILITY.Contains(elementId);
+ }
+
+ private void HandleVisibilityApplicationOnExceptions(string elementId, VisualElement visualElement, bool visible)
+ {
+ if (visible)
+ HandleExceptionalElementVisibleCase(elementId, visualElement);
+ else
+ HandleExceptionalElementInvisibleCase(elementId, visualElement);
+ }
+
+ private void HandleExceptionalElementInvisibleCase(string elementId, VisualElement visualElement)
+ {
+ var parent = visualElement.parent;
+ var index = parent.IndexOf(visualElement);
+
+ if (parent.Contains(visualElement))
+ parent.Remove(visualElement);
+
+ if (!_hiddenElementsByRemotion.ContainsKey(elementId))
+ _hiddenElementsByRemotion.Add(elementId, new HiddenRemovedElement()
+ {
+ RemovedVisualElement = visualElement,
+ Parent = parent,
+ Index = index
+ });
+ }
+
+ private void HandleExceptionalElementVisibleCase(string elementId, VisualElement visualElement)
+ {
+ if (_hiddenElementsByRemotion.ContainsKey(elementId))
+ {
+ var removedElement = _hiddenElementsByRemotion[elementId];
+
+ var parent = removedElement.Parent;
+
+ if (!parent.Contains(visualElement))
+ {
+ var bestIndex = GetIndexEqualOrLessThan(removedElement.Index, parent);
+
+ parent.Insert(bestIndex, visualElement);
+ }
+
+ _hiddenElementsByRemotion.Remove(elementId);
+ }
+ }
+
+ private int GetIndexEqualOrLessThan(int removedElementIndex, VisualElement parent)
+ {
+ for (int i = parent.childCount - 1; i >= 0; i--)
+ {
+ if (removedElementIndex <= i)
+ return i;
+ }
+
+ return 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/MainToolbarElementOverrideApplier.cs.meta b/Editor/Toolbar/MainToolbarElementOverrideApplier.cs.meta
new file mode 100644
index 0000000..ffd8952
--- /dev/null
+++ b/Editor/Toolbar/MainToolbarElementOverrideApplier.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 24d310911f14d4d45a02bd5586c371bb
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/NativeToolbarElement.cs b/Editor/Toolbar/NativeToolbarElement.cs
new file mode 100644
index 0000000..b95a5d1
--- /dev/null
+++ b/Editor/Toolbar/NativeToolbarElement.cs
@@ -0,0 +1,16 @@
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class NativeToolbarElement
+ {
+ public string Id { get; }
+ public VisualElement VisualElement { get; }
+
+ public NativeToolbarElement(string id, VisualElement visualElement)
+ {
+ Id = id;
+ VisualElement = visualElement;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/NativeToolbarElement.cs.meta b/Editor/Toolbar/NativeToolbarElement.cs.meta
new file mode 100644
index 0000000..65bf7ba
--- /dev/null
+++ b/Editor/Toolbar/NativeToolbarElement.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4b9dec15dbb8eea42b0c2254ce4b7177
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/Override.meta b/Editor/Toolbar/Override.meta
new file mode 100644
index 0000000..0c09781
--- /dev/null
+++ b/Editor/Toolbar/Override.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 6f722a3e209ed5649a219e2282177125
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/Override/IMainToolbarElementOverrideRepository.cs b/Editor/Toolbar/Override/IMainToolbarElementOverrideRepository.cs
new file mode 100644
index 0000000..b5e5377
--- /dev/null
+++ b/Editor/Toolbar/Override/IMainToolbarElementOverrideRepository.cs
@@ -0,0 +1,10 @@
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal interface IMainToolbarElementOverrideRepository
+ {
+ public MainToolbarElementOverride? Get(string elementId);
+ public MainToolbarElementOverride[] GetAll();
+ public void Save(MainToolbarElementOverride elementOverride);
+ public void Clear();
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/Override/IMainToolbarElementOverrideRepository.cs.meta b/Editor/Toolbar/Override/IMainToolbarElementOverrideRepository.cs.meta
new file mode 100644
index 0000000..66c1634
--- /dev/null
+++ b/Editor/Toolbar/Override/IMainToolbarElementOverrideRepository.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 280c883dcd1944448a1b93cecc8877f7
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/Override/MainToolbarElementOverride.cs b/Editor/Toolbar/Override/MainToolbarElementOverride.cs
new file mode 100644
index 0000000..4d16d6c
--- /dev/null
+++ b/Editor/Toolbar/Override/MainToolbarElementOverride.cs
@@ -0,0 +1,14 @@
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal readonly struct MainToolbarElementOverride
+ {
+ public string ElementId { get; }
+ public bool Visible { get; }
+
+ public MainToolbarElementOverride(string elementId, bool visible)
+ {
+ ElementId = elementId;
+ Visible = visible;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/Override/MainToolbarElementOverride.cs.meta b/Editor/Toolbar/Override/MainToolbarElementOverride.cs.meta
new file mode 100644
index 0000000..d6beecb
--- /dev/null
+++ b/Editor/Toolbar/Override/MainToolbarElementOverride.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e51009f5c83b62f419eee2089fd6e63f
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/Override/UserSettingsFileMainToolbarElementOverrideRepository.cs b/Editor/Toolbar/Override/UserSettingsFileMainToolbarElementOverrideRepository.cs
new file mode 100644
index 0000000..3429a9d
--- /dev/null
+++ b/Editor/Toolbar/Override/UserSettingsFileMainToolbarElementOverrideRepository.cs
@@ -0,0 +1,99 @@
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Unity.Serialization.Json;
+using UnityEngine;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class UserSettingsFileMainToolbarElementOverrideRepository : IMainToolbarElementOverrideRepository
+ {
+ private static readonly string DIRECTORY = Path.Combine(Directory.GetParent(Application.dataPath).FullName, "UserSettings/", "unity-toolbar-extender-ui-toolkit", "overrides");
+ private static readonly string FILE = Path.Combine(DIRECTORY, "overrides.json");
+
+ private struct SerializableOverride
+ {
+ public string ElementId;
+ public bool Visible;
+ }
+
+ private Dictionary _overrides = new Dictionary();
+
+ public UserSettingsFileMainToolbarElementOverrideRepository()
+ {
+ _overrides = LoadOverrides();
+ }
+
+ public void Clear()
+ {
+ _overrides.Clear();
+ DeleteSave();
+ }
+
+ public MainToolbarElementOverride? Get(string elementId)
+ {
+ if(_overrides.ContainsKey(elementId))
+ return _overrides[elementId];
+
+ return null;
+ }
+
+ public MainToolbarElementOverride[] GetAll()
+ {
+ return _overrides.Values.ToArray();
+ }
+
+ public void Save(MainToolbarElementOverride elementOverride)
+ {
+ _overrides[elementOverride.ElementId] = elementOverride;
+ SaveOverrides();
+ }
+
+ private MainToolbarElementOverride FromSerialized(SerializableOverride serializableOverride)
+ {
+ return new MainToolbarElementOverride(serializableOverride.ElementId, serializableOverride.Visible);
+ }
+
+ private SerializableOverride ToSerialized(MainToolbarElementOverride mainToolbarElementOverride)
+ {
+ return new SerializableOverride() {
+ ElementId = mainToolbarElementOverride.ElementId,
+ Visible = mainToolbarElementOverride.Visible
+ };
+ }
+
+ private void DeleteSave()
+ {
+ File.Delete(FILE);
+ }
+
+ private Dictionary LoadOverrides()
+ {
+ if (!Directory.Exists(DIRECTORY))
+ Directory.CreateDirectory(DIRECTORY);
+
+ if (!File.Exists(FILE))
+ return JsonSerialization.FromJson>("{}");
+
+ var json = File.ReadAllText(FILE);
+
+ var serializedDictionary = JsonSerialization.FromJson>(json);
+
+ return serializedDictionary.Values
+ .ToDictionary(serializedOverride => serializedOverride.ElementId,
+ serializedOverride => FromSerialized(serializedOverride));
+ }
+
+ private void SaveOverrides()
+ {
+ var serializableDictionary = _overrides.Values.ToDictionary(
+ mainToolbarElementOverride => mainToolbarElementOverride.ElementId,
+ mainToolbarElementOverride => ToSerialized(mainToolbarElementOverride)
+ );
+
+ var json = JsonSerialization.ToJson(serializableDictionary);
+
+ File.WriteAllText(FILE, json);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/Override/UserSettingsFileMainToolbarElementOverrideRepository.cs.meta b/Editor/Toolbar/Override/UserSettingsFileMainToolbarElementOverrideRepository.cs.meta
new file mode 100644
index 0000000..bb15f60
--- /dev/null
+++ b/Editor/Toolbar/Override/UserSettingsFileMainToolbarElementOverrideRepository.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 267c04a3d47600c488137859ea7af2a9
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/Paps.UnityToolbarExtenderUIToolkit.asmdef b/Editor/Toolbar/Paps.UnityToolbarExtenderUIToolkit.asmdef
new file mode 100644
index 0000000..0217154
--- /dev/null
+++ b/Editor/Toolbar/Paps.UnityToolbarExtenderUIToolkit.asmdef
@@ -0,0 +1,18 @@
+{
+ "name": "Paps.UnityToolbarExtenderUIToolkit",
+ "rootNamespace": "Paps.UnityToolbarExtenderUIToolkit",
+ "references": [
+ "Unity.Serialization"
+ ],
+ "includePlatforms": [
+ "Editor"
+ ],
+ "excludePlatforms": [],
+ "allowUnsafeCode": false,
+ "overrideReferences": false,
+ "precompiledReferences": [],
+ "autoReferenced": false,
+ "defineConstraints": [],
+ "versionDefines": [],
+ "noEngineReferences": false
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/Paps.UnityToolbarExtenderUIToolkit.asmdef.meta b/Editor/Toolbar/Paps.UnityToolbarExtenderUIToolkit.asmdef.meta
new file mode 100644
index 0000000..e244337
--- /dev/null
+++ b/Editor/Toolbar/Paps.UnityToolbarExtenderUIToolkit.asmdef.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 8d62da4aabd2a19419c7378d23ea5849
+AssemblyDefinitionImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles.meta b/Editor/Toolbar/RecommendedStyles.meta
new file mode 100644
index 0000000..07aa3a2
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 21a21acb2ce38fb46bd178a11e0cc483
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles/ButtonRecommendedStyle.cs b/Editor/Toolbar/RecommendedStyles/ButtonRecommendedStyle.cs
new file mode 100644
index 0000000..d4b905d
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/ButtonRecommendedStyle.cs
@@ -0,0 +1,19 @@
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class ButtonRecommendedStyle : RecommendedStyle
+ {
+ private Button _button;
+
+ public ButtonRecommendedStyle(Button button)
+ {
+ _button = button;
+ }
+
+ protected override void ApplyRootElementStyle()
+ {
+ _button.style.overflow = Overflow.Visible;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/RecommendedStyles/ButtonRecommendedStyle.cs.meta b/Editor/Toolbar/RecommendedStyles/ButtonRecommendedStyle.cs.meta
new file mode 100644
index 0000000..b9f4863
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/ButtonRecommendedStyle.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: dcaec52f220ee13458fa862e8f9f31b6
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles/ColorFieldRecommendedStyle.cs b/Editor/Toolbar/RecommendedStyles/ColorFieldRecommendedStyle.cs
new file mode 100644
index 0000000..8732a9c
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/ColorFieldRecommendedStyle.cs
@@ -0,0 +1,20 @@
+using UnityEditor.UIElements;
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class ColorFieldRecommendedStyle : RecommendedStyle
+ {
+ private readonly ColorField _colorField;
+
+ public ColorFieldRecommendedStyle(ColorField colorField)
+ {
+ _colorField = colorField;
+ }
+
+ protected override void ApplyRootElementStyle()
+ {
+ _colorField.labelElement.style.minWidth = Length.Auto();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/RecommendedStyles/ColorFieldRecommendedStyle.cs.meta b/Editor/Toolbar/RecommendedStyles/ColorFieldRecommendedStyle.cs.meta
new file mode 100644
index 0000000..4243822
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/ColorFieldRecommendedStyle.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ee22b5ac49a830e4a8e35f5e98b656d1
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles/DropdownFieldRecommendedStyle.cs b/Editor/Toolbar/RecommendedStyles/DropdownFieldRecommendedStyle.cs
new file mode 100644
index 0000000..824d6ec
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/DropdownFieldRecommendedStyle.cs
@@ -0,0 +1,27 @@
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class DropdownFieldRecommendedStyle : RecommendedStyle
+ {
+ private DropdownField _dropdownField;
+
+ public DropdownFieldRecommendedStyle(DropdownField dropdownField)
+ {
+ _dropdownField = dropdownField;
+ }
+
+ protected override void ApplyRootElementStyle()
+ {
+ _dropdownField.labelElement.style.minWidth = Length.Auto();
+
+ var inputFieldIndex = 1;
+
+ if (string.IsNullOrEmpty(_dropdownField.label))
+ inputFieldIndex = 0;
+
+ var inputElement = _dropdownField[inputFieldIndex];
+ inputElement.style.overflow = Overflow.Visible;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/RecommendedStyles/DropdownFieldRecommendedStyle.cs.meta b/Editor/Toolbar/RecommendedStyles/DropdownFieldRecommendedStyle.cs.meta
new file mode 100644
index 0000000..4194266
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/DropdownFieldRecommendedStyle.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 494f883ee1470b044a6a7dbdc7218c66
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles/EditorToolbarDropdownRecommendedStyle.cs b/Editor/Toolbar/RecommendedStyles/EditorToolbarDropdownRecommendedStyle.cs
new file mode 100644
index 0000000..7ab7d0a
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/EditorToolbarDropdownRecommendedStyle.cs
@@ -0,0 +1,49 @@
+using UnityEditor.Toolbars;
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class EditorToolbarDropdownRecommendedStyle : RecommendedStyle
+ {
+ private EditorToolbarDropdown _dropdown;
+
+ public EditorToolbarDropdownRecommendedStyle(EditorToolbarDropdown dropdown)
+ {
+ _dropdown = dropdown;
+ }
+
+ protected override void ApplyInsideGroupStyle()
+ {
+ var arrowIndex = 2;
+
+ if (string.IsNullOrEmpty(_dropdown.text))
+ arrowIndex = 1;
+
+ var arrow = _dropdown[arrowIndex];
+
+ _dropdown.style.flexDirection = FlexDirection.Row;
+ _dropdown.style.flexWrap = Wrap.NoWrap;
+ _dropdown.style.overflow = Overflow.Visible;
+ _dropdown.RemoveFromClassList("unity-toolbar-button");
+ _dropdown.AddToClassList("unity-button");
+ arrow.AddToClassList("unity-base-popup-field__arrow");
+ }
+
+ protected override void ApplyRootElementStyle()
+ {
+ var arrowIndex = 2;
+
+ if (string.IsNullOrEmpty(_dropdown.text))
+ arrowIndex = 1;
+
+ var arrow = _dropdown[arrowIndex];
+
+ _dropdown.style.flexDirection = FlexDirection.Row;
+ _dropdown.style.flexWrap = Wrap.NoWrap;
+ _dropdown.style.overflow = StyleKeyword.Null;
+ _dropdown.RemoveFromClassList("unity-button");
+ _dropdown.AddToClassList("unity-toolbar-button");
+ arrow.RemoveFromClassList("unity-base-popup-field__arrow");
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/RecommendedStyles/EditorToolbarDropdownRecommendedStyle.cs.meta b/Editor/Toolbar/RecommendedStyles/EditorToolbarDropdownRecommendedStyle.cs.meta
new file mode 100644
index 0000000..c1e2aaa
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/EditorToolbarDropdownRecommendedStyle.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ceacb8187593d1345ac7101feedd059c
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles/EditorToolbarToggleRecommendedStyle.cs b/Editor/Toolbar/RecommendedStyles/EditorToolbarToggleRecommendedStyle.cs
new file mode 100644
index 0000000..f2361e8
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/EditorToolbarToggleRecommendedStyle.cs
@@ -0,0 +1,35 @@
+using UnityEditor.Toolbars;
+using UnityEngine.UIElements;
+using System.Reflection;
+using UnityEngine;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class EditorToolbarToggleRecommendedStyle : RecommendedStyle
+ {
+ private readonly EditorToolbarToggle _toolbarToggle;
+ private Image _iconImageElement;
+ private VisualElement _checkmark;
+
+ public EditorToolbarToggleRecommendedStyle(EditorToolbarToggle toolbarToggle)
+ {
+ _toolbarToggle = toolbarToggle;
+ _iconImageElement = _toolbarToggle.Q();
+ _checkmark = _toolbarToggle.Query(className: "unity-toggle__checkmark");
+ }
+
+ protected override void ApplyRootElementStyle()
+ {
+ _iconImageElement.style.width = Length.Auto();
+ _toolbarToggle.style.paddingLeft = 3;
+ }
+
+ protected override void ApplyInsideGroupStyle()
+ {
+ _toolbarToggle.AddToClassList("unity-button");
+ _toolbarToggle.RemoveFromClassList("unity-toolbar-toggle");
+ _toolbarToggle.RemoveFromClassList("unity-editor-toolbar-toggle");
+ _checkmark.style.display = DisplayStyle.None;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/RecommendedStyles/EditorToolbarToggleRecommendedStyle.cs.meta b/Editor/Toolbar/RecommendedStyles/EditorToolbarToggleRecommendedStyle.cs.meta
new file mode 100644
index 0000000..2f64b7f
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/EditorToolbarToggleRecommendedStyle.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1397116b676f4994c8458c8ca852d7dc
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles/EnumFieldRecommendedStyle.cs b/Editor/Toolbar/RecommendedStyles/EnumFieldRecommendedStyle.cs
new file mode 100644
index 0000000..9fd80c2
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/EnumFieldRecommendedStyle.cs
@@ -0,0 +1,27 @@
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class EnumFieldRecommendedStyle : RecommendedStyle
+ {
+ private EnumField _enumField;
+
+ public EnumFieldRecommendedStyle(EnumField enumField)
+ {
+ _enumField = enumField;
+ }
+
+ protected override void ApplyRootElementStyle()
+ {
+ _enumField.labelElement.style.minWidth = Length.Auto();
+
+ var inputFieldIndex = 1;
+
+ if (string.IsNullOrEmpty(_enumField.label))
+ inputFieldIndex = 0;
+
+ var inputElement = _enumField[inputFieldIndex];
+ inputElement.style.overflow = Overflow.Visible;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/RecommendedStyles/EnumFieldRecommendedStyle.cs.meta b/Editor/Toolbar/RecommendedStyles/EnumFieldRecommendedStyle.cs.meta
new file mode 100644
index 0000000..8a3069f
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/EnumFieldRecommendedStyle.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d96e8ee8678283341916b37ef64659a9
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles/EnumFlagsFieldRecommendedStyle.cs b/Editor/Toolbar/RecommendedStyles/EnumFlagsFieldRecommendedStyle.cs
new file mode 100644
index 0000000..20c7663
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/EnumFlagsFieldRecommendedStyle.cs
@@ -0,0 +1,34 @@
+using UnityEditor.UIElements;
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class EnumFlagsFieldRecommendedStyle : RecommendedStyle
+ {
+ private EnumFlagsField _enumField;
+
+ public EnumFlagsFieldRecommendedStyle(EnumFlagsField enumField)
+ {
+ _enumField = enumField;
+ }
+
+ protected override void ApplyRootElementStyle()
+ {
+ _enumField.labelElement.style.minWidth = Length.Auto();
+
+ var inputFieldIndex = 1;
+
+ if (string.IsNullOrEmpty(_enumField.label))
+ inputFieldIndex = 0;
+
+ var inputElement = _enumField[inputFieldIndex];
+ inputElement.style.overflow = Overflow.Visible;
+ inputElement.style.minWidth = 120;
+ }
+
+ protected override void ApplyInsideGroupStyle()
+ {
+ _enumField.style.flexGrow = 1;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/RecommendedStyles/EnumFlagsFieldRecommendedStyle.cs.meta b/Editor/Toolbar/RecommendedStyles/EnumFlagsFieldRecommendedStyle.cs.meta
new file mode 100644
index 0000000..0a98d2a
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/EnumFlagsFieldRecommendedStyle.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: bb3b70fed4d19e84394fb93b4e4417aa
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles/FloatFieldRecommendedStyle.cs b/Editor/Toolbar/RecommendedStyles/FloatFieldRecommendedStyle.cs
new file mode 100644
index 0000000..37fe638
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/FloatFieldRecommendedStyle.cs
@@ -0,0 +1,30 @@
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class FloatFieldRecommendedStyle : RecommendedStyle
+ {
+ private const int MIN_WIDTH = 80;
+
+ private FloatField _floatField;
+
+ public FloatFieldRecommendedStyle(FloatField floatField)
+ {
+ _floatField = floatField;
+ }
+
+ protected override void ApplyRootElementStyle()
+ {
+ var inputFieldIndex = 1;
+
+ if (string.IsNullOrEmpty(_floatField.label))
+ inputFieldIndex = 0;
+
+ var inputElement = _floatField[inputFieldIndex];
+
+ _floatField.labelElement.style.minWidth = Length.Auto();
+ inputElement.style.minWidth = MIN_WIDTH;
+ inputElement.style.overflow = Overflow.Visible;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/RecommendedStyles/FloatFieldRecommendedStyle.cs.meta b/Editor/Toolbar/RecommendedStyles/FloatFieldRecommendedStyle.cs.meta
new file mode 100644
index 0000000..7915d36
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/FloatFieldRecommendedStyle.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1886e6235603764499ce2f621b0104e1
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles/IntegerFieldRecommendedStyle.cs b/Editor/Toolbar/RecommendedStyles/IntegerFieldRecommendedStyle.cs
new file mode 100644
index 0000000..b497596
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/IntegerFieldRecommendedStyle.cs
@@ -0,0 +1,31 @@
+using UnityEngine;
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class IntegerFieldRecommendedStyle : RecommendedStyle
+ {
+ private const int MIN_WIDTH = 80;
+
+ private IntegerField _integerField;
+
+ public IntegerFieldRecommendedStyle(IntegerField integerField)
+ {
+ _integerField = integerField;
+ }
+
+ protected override void ApplyRootElementStyle()
+ {
+ var inputFieldIndex = 1;
+
+ if(string.IsNullOrEmpty(_integerField.label))
+ inputFieldIndex = 0;
+
+ var inputElement = _integerField[inputFieldIndex];
+
+ _integerField.labelElement.style.minWidth = Length.Auto();
+ inputElement.style.minWidth = MIN_WIDTH;
+ inputElement.style.overflow = Overflow.Visible;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/RecommendedStyles/IntegerFieldRecommendedStyle.cs.meta b/Editor/Toolbar/RecommendedStyles/IntegerFieldRecommendedStyle.cs.meta
new file mode 100644
index 0000000..42a928b
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/IntegerFieldRecommendedStyle.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e985a178fb9e7144997ea894be45f69c
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles/LayerFieldRecommendedStyle.cs b/Editor/Toolbar/RecommendedStyles/LayerFieldRecommendedStyle.cs
new file mode 100644
index 0000000..1ef3532
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/LayerFieldRecommendedStyle.cs
@@ -0,0 +1,28 @@
+using UnityEditor.UIElements;
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class LayerFieldRecommendedStyle : RecommendedStyle
+ {
+ private readonly LayerField _layerField;
+
+ public LayerFieldRecommendedStyle(LayerField layerField)
+ {
+ _layerField = layerField;
+ }
+
+ protected override void ApplyRootElementStyle()
+ {
+ _layerField.labelElement.style.minWidth = Length.Auto();
+
+ var inputFieldIndex = 1;
+
+ if (string.IsNullOrEmpty(_layerField.label))
+ inputFieldIndex = 0;
+
+ var inputElement = _layerField[inputFieldIndex];
+ inputElement.style.overflow = Overflow.Visible;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/RecommendedStyles/LayerFieldRecommendedStyle.cs.meta b/Editor/Toolbar/RecommendedStyles/LayerFieldRecommendedStyle.cs.meta
new file mode 100644
index 0000000..d04d1bf
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/LayerFieldRecommendedStyle.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2d1af6dea50217644b547fb52bf5c06d
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles/ObjectFieldRecommendedStyle.cs b/Editor/Toolbar/RecommendedStyles/ObjectFieldRecommendedStyle.cs
new file mode 100644
index 0000000..92420ae
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/ObjectFieldRecommendedStyle.cs
@@ -0,0 +1,28 @@
+using UnityEditor.UIElements;
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class ObjectFieldRecommendedStyle : RecommendedStyle
+ {
+ private ObjectField _objectField;
+
+ public ObjectFieldRecommendedStyle(ObjectField objectField)
+ {
+ _objectField = objectField;
+ }
+
+ protected override void ApplyRootElementStyle()
+ {
+ _objectField.labelElement.style.minWidth = Length.Auto();
+
+ var inputFieldIndex = 1;
+
+ if (string.IsNullOrEmpty(_objectField.label))
+ inputFieldIndex = 0;
+
+ var inputElement = _objectField[inputFieldIndex];
+ inputElement.style.overflow = Overflow.Visible;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/RecommendedStyles/ObjectFieldRecommendedStyle.cs.meta b/Editor/Toolbar/RecommendedStyles/ObjectFieldRecommendedStyle.cs.meta
new file mode 100644
index 0000000..6a35420
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/ObjectFieldRecommendedStyle.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4867ef570d5dc0d4aa440c808aa8b8cb
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles/RecommendedStyle.cs b/Editor/Toolbar/RecommendedStyles/RecommendedStyle.cs
new file mode 100644
index 0000000..1a5fe01
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/RecommendedStyle.cs
@@ -0,0 +1,16 @@
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal abstract class RecommendedStyle
+ {
+ public void Apply(bool isInsideGroup)
+ {
+ if (isInsideGroup)
+ ApplyInsideGroupStyle();
+ else
+ ApplyRootElementStyle();
+ }
+
+ protected virtual void ApplyRootElementStyle() { }
+ protected virtual void ApplyInsideGroupStyle() { }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/RecommendedStyles/RecommendedStyle.cs.meta b/Editor/Toolbar/RecommendedStyles/RecommendedStyle.cs.meta
new file mode 100644
index 0000000..305daf7
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/RecommendedStyle.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5f26f22147430fd489504b39ee8b4701
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles/RecommendedStyleVisualElement.cs b/Editor/Toolbar/RecommendedStyles/RecommendedStyleVisualElement.cs
new file mode 100644
index 0000000..0cc16fa
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/RecommendedStyleVisualElement.cs
@@ -0,0 +1,16 @@
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class RecommendedStyleVisualElement
+ {
+ public VisualElement VisualElement { get; }
+ public bool IsInsideGroup { get; }
+
+ public RecommendedStyleVisualElement(VisualElement visualElement, bool isInsideGroup)
+ {
+ VisualElement = visualElement;
+ IsInsideGroup = isInsideGroup;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/RecommendedStyles/RecommendedStyleVisualElement.cs.meta b/Editor/Toolbar/RecommendedStyles/RecommendedStyleVisualElement.cs.meta
new file mode 100644
index 0000000..88b25e3
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/RecommendedStyleVisualElement.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c7fa52a9eb868af459e137032102136d
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles/RecommendedStyles.cs b/Editor/Toolbar/RecommendedStyles/RecommendedStyles.cs
new file mode 100644
index 0000000..bdbef7c
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/RecommendedStyles.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEditor.Toolbars;
+using UnityEditor.UIElements;
+using UnityEngine;
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal static class RecommendedStyles
+ {
+ private static Dictionary _recommendedStyles = new Dictionary();
+
+ public static void SetElements(RecommendedStyleVisualElement[] elements)
+ {
+ _recommendedStyles.Clear();
+
+ foreach(var element in elements)
+ {
+ var recommendedStyle = GetRecommendedStyleFor(element.VisualElement);
+
+ if (recommendedStyle == null)
+ continue;
+
+ element.VisualElement.RegisterCallback(ApplyRecommendedStyle);
+ _recommendedStyles.Add(element, recommendedStyle);
+ }
+ }
+
+ private static void ApplyRecommendedStyle(AttachToPanelEvent eventArgs)
+ {
+ var visualElement = eventArgs.target as VisualElement;
+
+ var key = _recommendedStyles.Keys.FirstOrDefault(key => key.VisualElement == visualElement);
+
+ ApplySafely(key);
+ }
+
+ private static void ApplySafely(RecommendedStyleVisualElement key)
+ {
+ try
+ {
+ _recommendedStyles[key].Apply(key.IsInsideGroup);
+ }
+ catch(Exception e)
+ {
+ Debug.LogWarning("An exception ocurred when trying to apply recommended styles");
+ Debug.LogException(e);
+ }
+ }
+
+ private static RecommendedStyle GetRecommendedStyleFor(VisualElement visualElement)
+ {
+ if (visualElement is not EditorToolbarToggle && visualElement is Toggle toggle)
+ return new ToggleRecommendedStyle(toggle);
+ else if (visualElement is not EditorToolbarButton && visualElement is Button button)
+ return new ButtonRecommendedStyle(button);
+ else if (visualElement is Slider slider)
+ return new SliderRecommendedStyle(slider);
+ else if (visualElement is DropdownField dropdownField)
+ return new DropdownFieldRecommendedStyle(dropdownField);
+ else if (visualElement is EditorToolbarDropdown dropdown)
+ return new EditorToolbarDropdownRecommendedStyle(dropdown);
+ else if (visualElement is IntegerField integerField)
+ return new IntegerFieldRecommendedStyle(integerField);
+ else if (visualElement is FloatField floatField)
+ return new FloatFieldRecommendedStyle(floatField);
+ else if (visualElement is TextField textField)
+ return new TextFieldRecommendedStyle(textField);
+ else if (visualElement is EditorToolbarToggle toolbarToggle)
+ return new EditorToolbarToggleRecommendedStyle(toolbarToggle);
+ else if (visualElement is Vector3Field vector3Field)
+ return new Vector3FieldRecommendedStyle(vector3Field);
+ else if (visualElement is Vector2Field vector2Field)
+ return new Vector2FieldRecommendedStyle(vector2Field);
+ else if (visualElement is ColorField colorField)
+ return new ColorFieldRecommendedStyle(colorField);
+ else if (visualElement is LayerField layerField)
+ return new LayerFieldRecommendedStyle(layerField);
+ else if (visualElement is EnumField enumField)
+ return new EnumFieldRecommendedStyle(enumField);
+ else if (visualElement is TagField tagField)
+ return new TagFieldRecommendedStyle(tagField);
+ else if (visualElement is ObjectField objectField)
+ return new ObjectFieldRecommendedStyle(objectField);
+ else if (visualElement is EnumFlagsField enumFlagsField)
+ return new EnumFlagsFieldRecommendedStyle(enumFlagsField);
+
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/RecommendedStyles/RecommendedStyles.cs.meta b/Editor/Toolbar/RecommendedStyles/RecommendedStyles.cs.meta
new file mode 100644
index 0000000..35ec40c
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/RecommendedStyles.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 716c417d45185ed49880601a82aa7ce3
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles/SliderRecommendedStyle.cs b/Editor/Toolbar/RecommendedStyles/SliderRecommendedStyle.cs
new file mode 100644
index 0000000..ac8eddc
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/SliderRecommendedStyle.cs
@@ -0,0 +1,29 @@
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class SliderRecommendedStyle : RecommendedStyle
+ {
+ private const float MIN_WIDTH = 200;
+
+ private readonly Slider _slider;
+
+ public SliderRecommendedStyle(Slider slider)
+ {
+ _slider = slider;
+ }
+
+ protected override void ApplyInsideGroupStyle()
+ {
+ _slider.style.flexWrap = Wrap.NoWrap;
+ _slider.style.flexShrink = 1;
+ }
+
+ protected override void ApplyRootElementStyle()
+ {
+ _slider.labelElement.style.minWidth = 0;
+ _slider.style.minWidth = MIN_WIDTH;
+ _slider.style.flexShrink = 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/RecommendedStyles/SliderRecommendedStyle.cs.meta b/Editor/Toolbar/RecommendedStyles/SliderRecommendedStyle.cs.meta
new file mode 100644
index 0000000..bb1da62
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/SliderRecommendedStyle.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5d17fd66cf40a264298b8233ece34e5d
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles/TagFieldRecommendedStyle.cs b/Editor/Toolbar/RecommendedStyles/TagFieldRecommendedStyle.cs
new file mode 100644
index 0000000..0574cc6
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/TagFieldRecommendedStyle.cs
@@ -0,0 +1,28 @@
+using UnityEditor.UIElements;
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class TagFieldRecommendedStyle : RecommendedStyle
+ {
+ private TagField _tagField;
+
+ public TagFieldRecommendedStyle(TagField tagField)
+ {
+ _tagField = tagField;
+ }
+
+ protected override void ApplyRootElementStyle()
+ {
+ _tagField.labelElement.style.minWidth = Length.Auto();
+
+ var inputFieldIndex = 1;
+
+ if (string.IsNullOrEmpty(_tagField.label))
+ inputFieldIndex = 0;
+
+ var inputElement = _tagField[inputFieldIndex];
+ inputElement.style.overflow = Overflow.Visible;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/RecommendedStyles/TagFieldRecommendedStyle.cs.meta b/Editor/Toolbar/RecommendedStyles/TagFieldRecommendedStyle.cs.meta
new file mode 100644
index 0000000..9dd6bd8
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/TagFieldRecommendedStyle.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0bb992cea63cc3b4a8bb869531fa8d11
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles/TextFieldRecommendedStyle.cs b/Editor/Toolbar/RecommendedStyles/TextFieldRecommendedStyle.cs
new file mode 100644
index 0000000..bef7b24
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/TextFieldRecommendedStyle.cs
@@ -0,0 +1,30 @@
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class TextFieldRecommendedStyle : RecommendedStyle
+ {
+ private const int MIN_WIDTH = 120;
+
+ private TextField _textField;
+
+ public TextFieldRecommendedStyle(TextField textField)
+ {
+ _textField = textField;
+ }
+
+ protected override void ApplyRootElementStyle()
+ {
+ var inputFieldIndex = 1;
+
+ if (string.IsNullOrEmpty(_textField.label))
+ inputFieldIndex = 0;
+
+ var inputElement = _textField[inputFieldIndex];
+
+ _textField.labelElement.style.minWidth = Length.Auto();
+ inputElement.style.minWidth = MIN_WIDTH;
+ inputElement.style.overflow = Overflow.Visible;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/RecommendedStyles/TextFieldRecommendedStyle.cs.meta b/Editor/Toolbar/RecommendedStyles/TextFieldRecommendedStyle.cs.meta
new file mode 100644
index 0000000..0c63798
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/TextFieldRecommendedStyle.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 34fd75b876b07474eb077487a678ff0e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles/ToggleRecommendedStyle.cs b/Editor/Toolbar/RecommendedStyles/ToggleRecommendedStyle.cs
new file mode 100644
index 0000000..86caeb6
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/ToggleRecommendedStyle.cs
@@ -0,0 +1,19 @@
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class ToggleRecommendedStyle : RecommendedStyle
+ {
+ private Toggle _toggle;
+
+ public ToggleRecommendedStyle(Toggle toggle)
+ {
+ _toggle = toggle;
+ }
+
+ protected override void ApplyRootElementStyle()
+ {
+ _toggle.labelElement.style.minWidth = 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/RecommendedStyles/ToggleRecommendedStyle.cs.meta b/Editor/Toolbar/RecommendedStyles/ToggleRecommendedStyle.cs.meta
new file mode 100644
index 0000000..b003c10
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/ToggleRecommendedStyle.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d7af66ce1efeb9645835121aad8c63d4
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles/Vector2FieldRecommendedStyle.cs b/Editor/Toolbar/RecommendedStyles/Vector2FieldRecommendedStyle.cs
new file mode 100644
index 0000000..2bd3442
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/Vector2FieldRecommendedStyle.cs
@@ -0,0 +1,59 @@
+using System.Linq;
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class Vector2FieldRecommendedStyle : RecommendedStyle
+ {
+ private const int SINGLE_FIELD_MIN_WIDTH = 80;
+
+ private readonly Vector2Field _vector2Field;
+
+ public Vector2FieldRecommendedStyle(Vector2Field vector2Field)
+ {
+ _vector2Field = vector2Field;
+ }
+
+ protected override void ApplyRootElementStyle()
+ {
+ _vector2Field.labelElement.style.minWidth = Length.Auto();
+
+ var inputFieldsParentElement = GetInputFieldsParentElement();
+
+ foreach (var child in inputFieldsParentElement.Children().Where(childElement => childElement is FloatField))
+ {
+ var inputFieldElementIndex = 1;
+
+ var inputFieldElement = child[inputFieldElementIndex];
+
+ inputFieldElement.style.overflow = Overflow.Visible;
+ inputFieldElement.style.minWidth = SINGLE_FIELD_MIN_WIDTH;
+ }
+
+ var spacerElement = inputFieldsParentElement.Children().Last();
+
+ spacerElement.style.flexGrow = 0;
+ }
+
+ protected override void ApplyInsideGroupStyle()
+ {
+ var inputFieldsParentElement = GetInputFieldsParentElement();
+
+ inputFieldsParentElement.style.flexWrap = Wrap.Wrap;
+
+ var spacerElement = inputFieldsParentElement.Children().Last();
+
+ spacerElement.style.flexGrow = 0;
+ }
+
+ private VisualElement GetInputFieldsParentElement()
+ {
+ var inputFieldsParentIndex = 1;
+
+ if (string.IsNullOrEmpty(_vector2Field.label))
+ inputFieldsParentIndex = 0;
+
+ return _vector2Field[inputFieldsParentIndex];
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/RecommendedStyles/Vector2FieldRecommendedStyle.cs.meta b/Editor/Toolbar/RecommendedStyles/Vector2FieldRecommendedStyle.cs.meta
new file mode 100644
index 0000000..f662b73
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/Vector2FieldRecommendedStyle.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d74598c0b3338b540a340e16719351b2
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/RecommendedStyles/Vector3FieldRecommendedStyle.cs b/Editor/Toolbar/RecommendedStyles/Vector3FieldRecommendedStyle.cs
new file mode 100644
index 0000000..613a4c3
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/Vector3FieldRecommendedStyle.cs
@@ -0,0 +1,50 @@
+using UnityEngine.UIElements;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class Vector3FieldRecommendedStyle : RecommendedStyle
+ {
+ private const int SINGLE_FIELD_MIN_WIDTH = 80;
+
+ private readonly Vector3Field _vector3Field;
+
+ public Vector3FieldRecommendedStyle(Vector3Field vector3Field)
+ {
+ _vector3Field = vector3Field;
+ }
+
+ protected override void ApplyRootElementStyle()
+ {
+ _vector3Field.labelElement.style.minWidth = Length.Auto();
+
+ var inputFieldsParentElement = GetInputFieldsParentElement();
+
+ foreach(var floatField in inputFieldsParentElement.Children())
+ {
+ var inputFieldElementIndex = 1;
+
+ var inputFieldElement = floatField[inputFieldElementIndex];
+
+ inputFieldElement.style.overflow = Overflow.Visible;
+ inputFieldElement.style.minWidth = SINGLE_FIELD_MIN_WIDTH;
+ }
+ }
+
+ protected override void ApplyInsideGroupStyle()
+ {
+ var inputFieldsParentElement = GetInputFieldsParentElement();
+
+ inputFieldsParentElement.style.flexWrap = Wrap.Wrap;
+ }
+
+ private VisualElement GetInputFieldsParentElement()
+ {
+ var inputFieldsParentIndex = 1;
+
+ if (string.IsNullOrEmpty(_vector3Field.label))
+ inputFieldsParentIndex = 0;
+
+ return _vector3Field[inputFieldsParentIndex];
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/RecommendedStyles/Vector3FieldRecommendedStyle.cs.meta b/Editor/Toolbar/RecommendedStyles/Vector3FieldRecommendedStyle.cs.meta
new file mode 100644
index 0000000..b96db90
--- /dev/null
+++ b/Editor/Toolbar/RecommendedStyles/Vector3FieldRecommendedStyle.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ca6000716cd684f44ac44154a65f9653
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/SerializableValues.meta b/Editor/Toolbar/SerializableValues.meta
new file mode 100644
index 0000000..eae14c6
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: da7391b8db06da04394d88ad292f12d1
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/SerializableValues/ElementVariables.cs b/Editor/Toolbar/SerializableValues/ElementVariables.cs
new file mode 100644
index 0000000..6d5d166
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/ElementVariables.cs
@@ -0,0 +1,33 @@
+using UnityEngine;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class ElementVariables
+ {
+ public MainToolbarElement MainToolbarElement;
+ public FieldVariable[] Fields;
+ public PropertyVariable[] Properties;
+
+ public bool DidChange()
+ {
+ foreach (var field in Fields)
+ if (field.DidChange())
+ return true;
+
+ foreach (var property in Properties)
+ if (property.DidChange())
+ return true;
+
+ return false;
+ }
+
+ public void UpdateValues()
+ {
+ foreach (var field in Fields)
+ field.UpdateValue();
+
+ foreach (var property in Properties)
+ property.UpdateValue();
+ }
+ }
+}
diff --git a/Editor/Toolbar/SerializableValues/ElementVariables.cs.meta b/Editor/Toolbar/SerializableValues/ElementVariables.cs.meta
new file mode 100644
index 0000000..2f4c421
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/ElementVariables.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1fd7c94aebc6703448efe6f6e8e899aa
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/SerializableValues/FieldVariable.cs b/Editor/Toolbar/SerializableValues/FieldVariable.cs
new file mode 100644
index 0000000..fadfd14
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/FieldVariable.cs
@@ -0,0 +1,25 @@
+using System.Reflection;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class FieldVariable : Variable
+ {
+ public readonly FieldInfo Field;
+
+ public FieldVariable(MainToolbarElement element, FieldInfo field, IValueSerializer valueSerializer, SerializeAttribute attribute)
+ : base(element, field.FieldType, field.GetValue(element.VisualElement), valueSerializer, attribute)
+ {
+ Field = field;
+ }
+
+ public override object Get()
+ {
+ return Field.GetValue(Element.VisualElement);
+ }
+
+ public override void Set(object value)
+ {
+ Field.SetValue(Element.VisualElement, value);
+ }
+ }
+}
diff --git a/Editor/Toolbar/SerializableValues/FieldVariable.cs.meta b/Editor/Toolbar/SerializableValues/FieldVariable.cs.meta
new file mode 100644
index 0000000..685b510
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/FieldVariable.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 52b93a1d12abcdd43ad8862697bad9ef
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/SerializableValues/IMainToolbarElementVariableRepository.cs b/Editor/Toolbar/SerializableValues/IMainToolbarElementVariableRepository.cs
new file mode 100644
index 0000000..43b739b
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/IMainToolbarElementVariableRepository.cs
@@ -0,0 +1,10 @@
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal interface IMainToolbarElementVariableRepository
+ {
+ public void Set(SerializableElement serializableElement);
+ public void SetAll(SerializableElement[] serializableElements);
+ public SerializableElement[] GetAll();
+ public void Save();
+ }
+}
diff --git a/Editor/Toolbar/SerializableValues/IMainToolbarElementVariableRepository.cs.meta b/Editor/Toolbar/SerializableValues/IMainToolbarElementVariableRepository.cs.meta
new file mode 100644
index 0000000..d83d5a1
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/IMainToolbarElementVariableRepository.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: cc3941d2eca2d2f4ea42787117a4bd40
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/SerializableValues/IMainToolbarElementVariableSerializer.cs b/Editor/Toolbar/SerializableValues/IMainToolbarElementVariableSerializer.cs
new file mode 100644
index 0000000..b18de2e
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/IMainToolbarElementVariableSerializer.cs
@@ -0,0 +1,8 @@
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal interface IMainToolbarElementVariableSerializer
+ {
+ public string Serialize(SerializableElementGroup serializableElementGroup);
+ public SerializableElementGroup Deserialize(string serializedElementGroup);
+ }
+}
diff --git a/Editor/Toolbar/SerializableValues/IMainToolbarElementVariableSerializer.cs.meta b/Editor/Toolbar/SerializableValues/IMainToolbarElementVariableSerializer.cs.meta
new file mode 100644
index 0000000..150bed4
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/IMainToolbarElementVariableSerializer.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d142e847e3be4574e9d1689324b5720c
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/SerializableValues/IValueSerializer.cs b/Editor/Toolbar/SerializableValues/IValueSerializer.cs
new file mode 100644
index 0000000..a581761
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/IValueSerializer.cs
@@ -0,0 +1,8 @@
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal interface IValueSerializer
+ {
+ string Serialize(T value);
+ T Deserialize(string serializedValue);
+ }
+}
diff --git a/Editor/Toolbar/SerializableValues/IValueSerializer.cs.meta b/Editor/Toolbar/SerializableValues/IValueSerializer.cs.meta
new file mode 100644
index 0000000..580311f
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/IValueSerializer.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d5c4ccea207b25d4098b94a25cd4eb5e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/SerializableValues/MainToolbarElementVariableWatcher.cs b/Editor/Toolbar/SerializableValues/MainToolbarElementVariableWatcher.cs
new file mode 100644
index 0000000..33b3e37
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/MainToolbarElementVariableWatcher.cs
@@ -0,0 +1,160 @@
+using System.Linq;
+using System.Reflection;
+using UnityEditor;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class MainToolbarElementVariableWatcher
+ {
+ private const BindingFlags BINDING_FLAGS = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
+
+ private const double SERIALIZE_EVERY_SECONDS = 0.5f;
+ private static double _nextSerializeTime = SERIALIZE_EVERY_SECONDS;
+
+ private ElementVariables[] _elementsWithVariables;
+ private readonly IMainToolbarElementVariableRepository _repository;
+ private readonly IValueSerializer _valueSerializer;
+
+ public MainToolbarElementVariableWatcher(IMainToolbarElementVariableRepository repository, IValueSerializer valueSerializer)
+ {
+ _repository = repository;
+ _valueSerializer = valueSerializer;
+ }
+
+ public void RestoreValues(MainToolbarElement[] elements)
+ {
+ _elementsWithVariables = GetElementsWithVariables(elements);
+
+ var serializedElements = _repository.GetAll();
+
+ foreach(var element in _elementsWithVariables)
+ {
+ var matchingSerialized = serializedElements.FirstOrDefault(serialized => serialized.ElementFullTypeName ==
+ element.MainToolbarElement.VisualElement.GetType().FullName);
+
+ if(matchingSerialized != null)
+ {
+ RestoreFields(element, matchingSerialized);
+ RestoreProperties(element, matchingSerialized);
+ }
+ }
+
+ SaveCurrentState();
+ }
+
+ private void RestoreFields(ElementVariables element, SerializableElement matchingSerialized)
+ {
+ foreach (var field in element.Fields)
+ {
+ var matchingField = matchingSerialized.Variables.FirstOrDefault(v =>
+ (v.Key == field.Attribute.SerializationKey || v.Key == field.Field.Name) &&
+ v.Type == ValueHolderType.Field &&
+ v.ValueType == field.Field.FieldType);
+
+ if (matchingField.Key != null)
+ {
+ field.Set(matchingField.Value);
+ }
+ }
+ }
+
+ private void RestoreProperties(ElementVariables element, SerializableElement matchingSerialized)
+ {
+ foreach (var property in element.Properties)
+ {
+ var matchingField = matchingSerialized.Variables.FirstOrDefault(v =>
+ (v.Key == property.Attribute.SerializationKey || v.Key == property.Property.Name) &&
+ v.Type == ValueHolderType.Property &&
+ v.ValueType == property.Property.PropertyType);
+
+ if (matchingField.Key != null)
+ {
+ property.Set(matchingField.Value);
+ }
+ }
+ }
+
+ public void Update()
+ {
+ if (EditorApplication.timeSinceStartup > _nextSerializeTime)
+ {
+ _nextSerializeTime = EditorApplication.timeSinceStartup + SERIALIZE_EVERY_SECONDS;
+ WatchChanges();
+ }
+ }
+
+ private void WatchChanges()
+ {
+ var anyChange = false;
+
+ foreach(var element in _elementsWithVariables)
+ {
+ if (element.DidChange())
+ {
+ anyChange = true;
+ element.UpdateValues();
+ _repository.Set(ToSerializable(element));
+ }
+ }
+
+ if(anyChange)
+ _repository.Save();
+ }
+
+ private void SaveCurrentState()
+ {
+ _repository.SetAll(_elementsWithVariables.Select(e => ToSerializable(e)).ToArray());
+
+ _repository.Save();
+ }
+
+ private ElementVariables[] GetElementsWithVariables(MainToolbarElement[] elements)
+ {
+ return elements.Select(element => new ElementVariables
+ {
+ MainToolbarElement = element,
+ Fields = GetSerializableFields(element),
+ Properties = GetSerializableProperties(element)
+ })
+ .Where(serializableElement => serializableElement.Fields.Any() || serializableElement.Properties.Any())
+ .ToArray();
+ }
+
+ private FieldVariable[] GetSerializableFields(MainToolbarElement element)
+ {
+ return element.VisualElement.GetType().GetFields(BINDING_FLAGS)
+ .Where(field => field.GetCustomAttribute() != null)
+ .Select(field => new FieldVariable(element, field, _valueSerializer, field.GetCustomAttribute()))
+ .ToArray();
+ }
+
+ private PropertyVariable[] GetSerializableProperties(MainToolbarElement element)
+ {
+ return element.VisualElement.GetType().GetProperties(BINDING_FLAGS)
+ .Where(property => property.GetCustomAttribute() != null)
+ .Select(property => new PropertyVariable(element, property, _valueSerializer, property.GetCustomAttribute()))
+ .ToArray();
+ }
+
+ private SerializableElement ToSerializable(ElementVariables elementWithVariables)
+ {
+ return new SerializableElement()
+ {
+ ElementFullTypeName = elementWithVariables.MainToolbarElement.VisualElement.GetType().FullName,
+ Variables = elementWithVariables.Fields.Select(f => new SerializableVariable()
+ {
+ Type = ValueHolderType.Field,
+ Key = string.IsNullOrEmpty(f.Attribute.SerializationKey) ? f.Field.Name : f.Attribute.SerializationKey,
+ ValueType = f.Field.FieldType,
+ Value = f.Get()
+ }).Concat(elementWithVariables.Properties.Select(p => new SerializableVariable()
+ {
+ Type = ValueHolderType.Property,
+ Key = string.IsNullOrEmpty(p.Attribute.SerializationKey) ? p.Property.Name : p.Attribute.SerializationKey,
+ ValueType = p.Property.PropertyType,
+ Value = p.Get()
+ })).ToArray()
+ };
+ }
+ }
+}
diff --git a/Editor/Toolbar/SerializableValues/MainToolbarElementVariableWatcher.cs.meta b/Editor/Toolbar/SerializableValues/MainToolbarElementVariableWatcher.cs.meta
new file mode 100644
index 0000000..79554e0
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/MainToolbarElementVariableWatcher.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 62abfdfdd04775b409e83c230d7ddc4c
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/SerializableValues/PropertyVariable.cs b/Editor/Toolbar/SerializableValues/PropertyVariable.cs
new file mode 100644
index 0000000..58dc6f6
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/PropertyVariable.cs
@@ -0,0 +1,26 @@
+using System.Collections;
+using System.Reflection;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class PropertyVariable : Variable
+ {
+ public readonly PropertyInfo Property;
+
+ public PropertyVariable(MainToolbarElement element, PropertyInfo property, IValueSerializer valueSerializer, SerializeAttribute attribute)
+ : base(element, property.PropertyType, property.GetValue(element.VisualElement), valueSerializer, attribute)
+ {
+ Property = property;
+ }
+
+ public override object Get()
+ {
+ return Property.GetValue(Element.VisualElement);
+ }
+
+ public override void Set(object value)
+ {
+ Property.SetValue(Element.VisualElement, value);
+ }
+ }
+}
diff --git a/Editor/Toolbar/SerializableValues/PropertyVariable.cs.meta b/Editor/Toolbar/SerializableValues/PropertyVariable.cs.meta
new file mode 100644
index 0000000..b77e154
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/PropertyVariable.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e18acef36457df44da9432e05a0c38a1
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/SerializableValues/SerializableElement.cs b/Editor/Toolbar/SerializableValues/SerializableElement.cs
new file mode 100644
index 0000000..e1c9def
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/SerializableElement.cs
@@ -0,0 +1,8 @@
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class SerializableElement
+ {
+ public string ElementFullTypeName;
+ public SerializableVariable[] Variables = new SerializableVariable[0];
+ }
+}
diff --git a/Editor/Toolbar/SerializableValues/SerializableElement.cs.meta b/Editor/Toolbar/SerializableValues/SerializableElement.cs.meta
new file mode 100644
index 0000000..a87418c
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/SerializableElement.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 7edf7215b75471c4f83e4affd1852a6f
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/SerializableValues/SerializableElementGroup.cs b/Editor/Toolbar/SerializableValues/SerializableElementGroup.cs
new file mode 100644
index 0000000..313b389
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/SerializableElementGroup.cs
@@ -0,0 +1,9 @@
+using System.Collections.Generic;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class SerializableElementGroup
+ {
+ public Dictionary SerializableElements = new Dictionary();
+ }
+}
diff --git a/Editor/Toolbar/SerializableValues/SerializableElementGroup.cs.meta b/Editor/Toolbar/SerializableValues/SerializableElementGroup.cs.meta
new file mode 100644
index 0000000..22d7157
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/SerializableElementGroup.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 657001aa20153804f8d8e39515494221
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/SerializableValues/SerializableVariable.cs b/Editor/Toolbar/SerializableValues/SerializableVariable.cs
new file mode 100644
index 0000000..d77a5f8
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/SerializableVariable.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal struct SerializableVariable
+ {
+ public ValueHolderType Type;
+ public string Key;
+ public Type ValueType;
+ public object Value;
+ }
+}
diff --git a/Editor/Toolbar/SerializableValues/SerializableVariable.cs.meta b/Editor/Toolbar/SerializableValues/SerializableVariable.cs.meta
new file mode 100644
index 0000000..98178ad
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/SerializableVariable.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fbe233d1da6590648bd836f9184b28c7
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/SerializableValues/SerializeAttribute.cs b/Editor/Toolbar/SerializableValues/SerializeAttribute.cs
new file mode 100644
index 0000000..f516366
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/SerializeAttribute.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ public class SerializeAttribute : Attribute
+ {
+ public string SerializationKey { get; }
+
+ public SerializeAttribute(string serializationKey = null)
+ {
+ SerializationKey = serializationKey;
+ }
+ }
+}
diff --git a/Editor/Toolbar/SerializableValues/SerializeAttribute.cs.meta b/Editor/Toolbar/SerializableValues/SerializeAttribute.cs.meta
new file mode 100644
index 0000000..00cd790
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/SerializeAttribute.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 13ca109f93dfdcd49bb7e38c834a6679
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/SerializableValues/UnitySerializationMainToolbarElementVariableSerializer.cs b/Editor/Toolbar/SerializableValues/UnitySerializationMainToolbarElementVariableSerializer.cs
new file mode 100644
index 0000000..9149683
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/UnitySerializationMainToolbarElementVariableSerializer.cs
@@ -0,0 +1,133 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using Unity.Serialization.Json;
+using UnityEditor;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class UnitySerializationMainToolbarElementVariableSerializer : IMainToolbarElementVariableSerializer
+ {
+ private struct SerializableElementGroupDTO
+ {
+ public Dictionary SerializableElements;
+ }
+
+ private struct SerializableElementDTO
+ {
+ public string ElementFullTypeName;
+ public SerializableVariableDTO[] Variables;
+ }
+
+ private struct SerializableVariableDTO
+ {
+ public ValueHolderType Type;
+ public string Key;
+ public string SerializedValue;
+ public string SerializedValueTypeFullyQualifiedName;
+ }
+
+ private IValueSerializer _valuesSerializer;
+ private MethodInfo _serializeValueMethod, _deserializeValueMethod;
+
+ public UnitySerializationMainToolbarElementVariableSerializer(IValueSerializer valuesSerializer)
+ {
+ _valuesSerializer = valuesSerializer;
+
+ _serializeValueMethod = _valuesSerializer.GetType().GetMethod("Serialize", BindingFlags.Instance | BindingFlags.Public);
+ _deserializeValueMethod = _valuesSerializer.GetType().GetMethod("Deserialize", BindingFlags.Instance | BindingFlags.Public);
+ }
+
+ public string Serialize(SerializableElementGroup serializableElementGroup)
+ {
+ var dto = ToDTO(serializableElementGroup);
+
+ return JsonSerialization.ToJson(dto, new JsonSerializationParameters() { Minified = true });
+ }
+
+ public SerializableElementGroup Deserialize(string serializedElementGroup)
+ {
+ var dto = JsonSerialization.FromJson(serializedElementGroup);
+
+ return FromDTO(dto);
+ }
+
+ private SerializableElementGroupDTO ToDTO(SerializableElementGroup group)
+ {
+ return new SerializableElementGroupDTO()
+ {
+ SerializableElements = group.SerializableElements.ToDictionary(e => e.Key, e => ToDTO(e.Value))
+ };
+ }
+
+
+ private SerializableElementGroup FromDTO(SerializableElementGroupDTO dto)
+ {
+ return new SerializableElementGroup()
+ {
+ SerializableElements = dto.SerializableElements == null ?
+ new Dictionary() :
+ dto.SerializableElements.ToDictionary(e => e.Key, e => FromDTO(e.Value))
+ };
+ }
+
+ private SerializableElementDTO ToDTO(SerializableElement serializableElement)
+ {
+ return new SerializableElementDTO()
+ {
+ ElementFullTypeName = serializableElement.ElementFullTypeName,
+ Variables = serializableElement.Variables.Select(v => new SerializableVariableDTO()
+ {
+ Key = v.Key,
+ Type = v.Type,
+ SerializedValue = SerializeValue(v.ValueType, v.Value),
+ SerializedValueTypeFullyQualifiedName = v.ValueType.AssemblyQualifiedName
+ }).ToArray()
+ };
+ }
+
+ private SerializableElement FromDTO(SerializableElementDTO dto)
+ {
+ return new SerializableElement()
+ {
+ ElementFullTypeName = dto.ElementFullTypeName,
+ Variables = dto.Variables.Select(v =>
+ {
+ try
+ {
+ var valueType = Type.GetType(v.SerializedValueTypeFullyQualifiedName);
+
+ return new SerializableVariable()
+ {
+ Key = v.Key,
+ Type = v.Type,
+ ValueType = valueType,
+ Value = DeserializeValue(valueType, v.SerializedValue)
+ };
+ }
+ catch
+ {
+ return default;
+ }
+ })
+ .Where(v => !string.IsNullOrEmpty(v.Key))
+ .ToArray()
+ };
+ }
+
+ private string SerializeValue(Type type, object value)
+ {
+ var genericMethod = _serializeValueMethod.MakeGenericMethod(type);
+
+ return (string)genericMethod.Invoke(_valuesSerializer, new object[] { value });
+ }
+
+ private object DeserializeValue(Type type, string serializedValue)
+ {
+ var genericMethod = _deserializeValueMethod.MakeGenericMethod(type);
+
+ return genericMethod.Invoke(_valuesSerializer, new object[] { serializedValue });
+ }
+ }
+}
diff --git a/Editor/Toolbar/SerializableValues/UnitySerializationMainToolbarElementVariableSerializer.cs.meta b/Editor/Toolbar/SerializableValues/UnitySerializationMainToolbarElementVariableSerializer.cs.meta
new file mode 100644
index 0000000..e7b0b77
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/UnitySerializationMainToolbarElementVariableSerializer.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: eb8fdee7bd4d00a489619573c341c510
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/SerializableValues/UnitySerializationValueSerializer.cs b/Editor/Toolbar/SerializableValues/UnitySerializationValueSerializer.cs
new file mode 100644
index 0000000..3bafa22
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/UnitySerializationValueSerializer.cs
@@ -0,0 +1,17 @@
+using Unity.Serialization.Json;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class UnitySerializationValueSerializer : IValueSerializer
+ {
+ public T Deserialize(string serializedValue)
+ {
+ return JsonSerialization.FromJson(serializedValue);
+ }
+
+ public string Serialize(T value)
+ {
+ return JsonSerialization.ToJson(value, new JsonSerializationParameters() { Minified = true } );
+ }
+ }
+}
diff --git a/Editor/Toolbar/SerializableValues/UnitySerializationValueSerializer.cs.meta b/Editor/Toolbar/SerializableValues/UnitySerializationValueSerializer.cs.meta
new file mode 100644
index 0000000..4db3f29
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/UnitySerializationValueSerializer.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 71e02839f1a8c5240af3b944fc2daa38
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/SerializableValues/UserSettingsFileMainToolbarElementVariableRepository.cs b/Editor/Toolbar/SerializableValues/UserSettingsFileMainToolbarElementVariableRepository.cs
new file mode 100644
index 0000000..9b841d7
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/UserSettingsFileMainToolbarElementVariableRepository.cs
@@ -0,0 +1,63 @@
+using System.IO;
+using System.Linq;
+using UnityEditor;
+using UnityEngine;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal class UserSettingsFileMainToolbarElementVariableRepository : IMainToolbarElementVariableRepository
+ {
+ private static readonly string DIRECTORY = Path.Combine(Directory.GetParent(Application.dataPath).FullName, "UserSettings/", "unity-toolbar-extender-ui-toolkit", "serialized-user-values");
+ private static readonly string FILE = Path.Combine(DIRECTORY, "serialized_values.json");
+ private readonly IMainToolbarElementVariableSerializer _serializer;
+ private SerializableElementGroup _elementGroup;
+ private SerializableElementGroup ElementGroup
+ {
+ get
+ {
+ if (_elementGroup == null)
+ _elementGroup = Load();
+
+ return _elementGroup;
+ }
+ set => _elementGroup = value;
+ }
+
+ public UserSettingsFileMainToolbarElementVariableRepository(IMainToolbarElementVariableSerializer serializer)
+ {
+ _serializer = serializer;
+ }
+
+ public SerializableElement[] GetAll()
+ {
+ return ElementGroup.SerializableElements.Values.ToArray();
+ }
+
+ public void Set(SerializableElement serializableElement)
+ {
+ ElementGroup.SerializableElements[serializableElement.ElementFullTypeName] = serializableElement;
+ }
+
+ public void SetAll(SerializableElement[] serializableElements)
+ {
+ ElementGroup.SerializableElements = serializableElements.ToDictionary(s => s.ElementFullTypeName, s => s);
+ }
+
+ private SerializableElementGroup Load()
+ {
+ if(!Directory.Exists(DIRECTORY))
+ Directory.CreateDirectory(DIRECTORY);
+
+ if (!File.Exists(FILE))
+ return _serializer.Deserialize("{}");
+ else
+ return _serializer.Deserialize(File.ReadAllText(FILE));
+ }
+
+ public void Save()
+ {
+ var serializedString = _serializer.Serialize(ElementGroup);
+ File.WriteAllText(FILE, serializedString);
+ }
+ }
+}
diff --git a/Editor/Toolbar/SerializableValues/UserSettingsFileMainToolbarElementVariableRepository.cs.meta b/Editor/Toolbar/SerializableValues/UserSettingsFileMainToolbarElementVariableRepository.cs.meta
new file mode 100644
index 0000000..7e2e197
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/UserSettingsFileMainToolbarElementVariableRepository.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8063852f8dc46d74a9fa8cd1d5401716
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/SerializableValues/ValueHolderType.cs b/Editor/Toolbar/SerializableValues/ValueHolderType.cs
new file mode 100644
index 0000000..f2bd9ec
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/ValueHolderType.cs
@@ -0,0 +1,8 @@
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal enum ValueHolderType
+ {
+ Field,
+ Property
+ }
+}
diff --git a/Editor/Toolbar/SerializableValues/ValueHolderType.cs.meta b/Editor/Toolbar/SerializableValues/ValueHolderType.cs.meta
new file mode 100644
index 0000000..01a509d
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/ValueHolderType.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1dd09907e73e4a84ab82d32c04378911
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/SerializableValues/Variable.cs b/Editor/Toolbar/SerializableValues/Variable.cs
new file mode 100644
index 0000000..664d483
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/Variable.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Reflection;
+
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ internal abstract class Variable
+ {
+ private string _lastValueSerialized;
+ private string LastValueSerialized
+ {
+ get
+ {
+ if (_lastValueSerialized == null)
+ _lastValueSerialized = Serialize(Get());
+
+ return _lastValueSerialized;
+ }
+
+ set => _lastValueSerialized = value;
+ }
+ private IValueSerializer _valueSerializer;
+ private MethodInfo _serializeValueMethod, _deserializeValueMethod;
+
+ public MainToolbarElement Element { get; }
+ public Type ValueType { get; }
+ public SerializeAttribute Attribute { get; }
+
+ public Variable(MainToolbarElement element, Type valueType, object initialValue, IValueSerializer valueSerializer, SerializeAttribute attribute)
+ {
+ Element = element;
+ ValueType = valueType;
+ _valueSerializer = valueSerializer;
+ Attribute = attribute;
+ _serializeValueMethod = _valueSerializer.GetType().GetMethod("Serialize", BindingFlags.Instance | BindingFlags.Public);
+ _deserializeValueMethod = _valueSerializer.GetType().GetMethod("Deserialize", BindingFlags.Instance | BindingFlags.Public);
+ }
+
+ public abstract object Get();
+
+ public abstract void Set(object value);
+
+ public bool DidChange()
+ {
+ var currentValue = Get();
+
+ var currentValueSerialized = Serialize(currentValue);
+
+ return currentValueSerialized != LastValueSerialized;
+ }
+
+ private string Serialize(object value)
+ {
+ var genericMethod = _serializeValueMethod.MakeGenericMethod(ValueType);
+ return (string)genericMethod.Invoke(_valueSerializer, new object[] { Get() });
+ }
+
+ private object Deserialize(string serialized)
+ {
+ var genericMethod = _deserializeValueMethod.MakeGenericMethod(ValueType);
+ return genericMethod.Invoke(_valueSerializer, new object[] { serialized });
+ }
+
+ public void UpdateValue()
+ {
+ LastValueSerialized = Serialize(Get());
+ }
+ }
+}
diff --git a/Editor/Toolbar/SerializableValues/Variable.cs.meta b/Editor/Toolbar/SerializableValues/Variable.cs.meta
new file mode 100644
index 0000000..b8586a3
--- /dev/null
+++ b/Editor/Toolbar/SerializableValues/Variable.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 219c1bb61dbca8e4d966b029961aed81
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/Toolbar/ToolbarAlign.cs b/Editor/Toolbar/ToolbarAlign.cs
new file mode 100644
index 0000000..aa8632f
--- /dev/null
+++ b/Editor/Toolbar/ToolbarAlign.cs
@@ -0,0 +1,8 @@
+namespace Paps.UnityToolbarExtenderUIToolkit
+{
+ public enum ToolbarAlign
+ {
+ Left,
+ Right
+ }
+}
\ No newline at end of file
diff --git a/Editor/Toolbar/ToolbarAlign.cs.meta b/Editor/Toolbar/ToolbarAlign.cs.meta
new file mode 100644
index 0000000..041e815
--- /dev/null
+++ b/Editor/Toolbar/ToolbarAlign.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3ea30c0e2b125014f8d433ee5360acb4
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: