PrefabPalette.cs 81 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835
  1. /*
  2. Copyright (c) 2020 Omar Duarte
  3. Unauthorized copying of this file, via any medium is strictly prohibited.
  4. Writen by Omar Duarte, 2020.
  5. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  6. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  7. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  8. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  9. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  10. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  11. THE SOFTWARE.
  12. */
  13. using System.Linq;
  14. using UnityEngine;
  15. namespace PluginMaster
  16. {
  17. public class PrefabPalette : UnityEditor.EditorWindow, ISerializationCallbackReceiver
  18. {
  19. #region COMMON
  20. private GUISkin _skin = null;
  21. [SerializeField] private PaletteManager _paletteManager = null;
  22. private static PrefabPalette _instance = null;
  23. public static PrefabPalette instance => _instance;
  24. [UnityEditor.MenuItem("Tools/Plugin Master/Prefab World Builder/Palette...", false, 1110)]
  25. public static void ShowWindow() => _instance = GetWindow<PrefabPalette>("Palette");
  26. private static bool _repaint = false;
  27. public static void RepainWindow()
  28. {
  29. if (_instance != null) _instance.Repaint();
  30. _repaint = true;
  31. }
  32. public static void OnChangeRepaint()
  33. {
  34. if (_instance != null)
  35. {
  36. _instance.OnPaletteChange();
  37. RepainWindow();
  38. }
  39. }
  40. public static void CloseWindow()
  41. {
  42. if (_instance != null) _instance.Close();
  43. }
  44. private void OnEnable()
  45. {
  46. _instance = this;
  47. _paletteManager = PaletteManager.instance;
  48. _skin = Resources.Load<GUISkin>("PWBSkin");
  49. if (_skin == null) return;
  50. _toggleStyle = _skin.GetStyle("PaletteToggle");
  51. _loadingIcon = Resources.Load<Texture2D>("Sprites/Loading");
  52. _toggleStyle.margin = new RectOffset(4, 4, 4, 4);
  53. _dropdownIcon = new GUIContent(Resources.Load<Texture2D>("Sprites/DropdownArrow"));
  54. _labelIcon = new GUIContent(Resources.Load<Texture2D>("Sprites/Label"), "Filter by label");
  55. _selectionFilterIcon = new GUIContent(Resources.Load<Texture2D>("Sprites/SelectionFilter"),
  56. "Filter by selection");
  57. _folderFilterIcon = new GUIContent(Resources.Load<Texture2D>("Sprites/FolderFilter"), "Filter by folder");
  58. _newBrushIcon = new GUIContent(Resources.Load<Texture2D>("Sprites/New"), "New Brush");
  59. _deleteBrushIcon = new GUIContent(Resources.Load<Texture2D>("Sprites/Delete"), "Delete Brush");
  60. _pickerIcon = new GUIContent(Resources.Load<Texture2D>("Sprites/Picker"), "Brush Picker");
  61. _clearFilterIcon = new GUIContent(Resources.Load<Texture2D>("Sprites/Clear"));
  62. _settingsIcon = new GUIContent(Resources.Load<Texture2D>("Sprites/Settings"));
  63. _cursorStyle = _skin.GetStyle("Cursor");
  64. _visibleTabCount = PaletteManager.paletteNames.Length;
  65. autoRepaintOnSceneChange = true;
  66. UpdateLabelFilter();
  67. UpdateFilteredList(false);
  68. PaletteManager.ClearSelection(false);
  69. UnityEditor.Undo.undoRedoPerformed += OnPaletteChange;
  70. PWBCore.SetSavePending();
  71. var paletteFiles = System.IO.Directory.GetFiles(PWBData.palettesDirectory, "*.txt",
  72. System.IO.SearchOption.AllDirectories);
  73. if (paletteFiles.Length == 0) PaletteManager.instance.LoadPaletteFiles(true);
  74. }
  75. private void OnDisable() => UnityEditor.Undo.undoRedoPerformed -= OnPaletteChange;
  76. private void OnDestroy() => ToolManager.OnPaletteClosed();
  77. public static void ClearUndo()
  78. {
  79. if (_instance == null) return;
  80. UnityEditor.Undo.ClearUndo(_instance);
  81. }
  82. private void OnGUI()
  83. {
  84. if (_skin == null)
  85. {
  86. Close();
  87. return;
  88. }
  89. if (PaletteManager.loadPaletteFilesPending)
  90. {
  91. PaletteManager.instance.LoadPaletteFiles(true);
  92. Reload(false);
  93. UpdateTabBar();
  94. }
  95. if (PWBCore.refreshDatabase) PWBCore.AssetDatabaseRefresh();
  96. if (_contextBrushAdded)
  97. {
  98. RegisterUndo("Add Brush");
  99. PaletteManager.selectedPalette.AddBrush(_newContextBrush);
  100. _newContextBrush = null;
  101. PaletteManager.selectedBrushIdx = PaletteManager.selectedPalette.brushes.Length - 1;
  102. _contextBrushAdded = false;
  103. OnPaletteChange();
  104. return;
  105. }
  106. try
  107. {
  108. TabBar();
  109. if (PaletteManager.paletteData.Length == 0) return;
  110. SearchBar();
  111. Palette();
  112. }
  113. catch
  114. {
  115. RepainWindow();
  116. }
  117. var eventType = Event.current.rawType;
  118. if (eventType == EventType.MouseMove || eventType == EventType.MouseUp)
  119. {
  120. _moveBrush.to = -1;
  121. draggingBrush = false;
  122. _showCursor = false;
  123. }
  124. else if (PWBSettings.shortcuts.paletteDeleteBrush.Check()) OnDelete();
  125. if (PWBSettings.shortcuts.paletteReplaceSceneSelection.Check()) PWBIO.ReplaceSelected();
  126. }
  127. private void Update()
  128. {
  129. if (mouseOverWindow != this)
  130. {
  131. _moveBrush.to = -1;
  132. _showCursor = false;
  133. }
  134. else if (draggingBrush) _showCursor = true;
  135. if (_repaint)
  136. {
  137. _repaint = false;
  138. Repaint();
  139. }
  140. if (_frameSelectedBrush && _newSelectedPositionSet) DoFrameSelectedBrush();
  141. if (PaletteManager.savePending) PaletteManager.SaveIfPending();
  142. }
  143. private void RegisterUndo(string name)
  144. {
  145. if (PWBCore.staticData.undoPalette) UnityEditor.Undo.RegisterCompleteObjectUndo(this, name);
  146. }
  147. public void OnBeforeSerialize() { }
  148. public void OnAfterDeserialize()
  149. {
  150. _repaint = true;
  151. PaletteManager.ClearSelection(false);
  152. }
  153. public void UpdateAllThumbnails() => PaletteManager.UpdateAllThumbnails();
  154. #endregion
  155. #region PALETTE
  156. private Vector2 _scrollPosition;
  157. private Rect _scrollViewRect;
  158. private Vector2 _prevSize;
  159. private int _columnCount = 1;
  160. private GUIStyle _toggleStyle = null;
  161. private const int MIN_ICON_SIZE = 24;
  162. private const int MAX_ICON_SIZE = 256;
  163. public const int DEFAULT_ICON_SIZE = 64;
  164. private int _prevIconSize = DEFAULT_ICON_SIZE;
  165. private GUIContent _dropdownIcon = null;
  166. private bool _draggingBrush = false;
  167. private bool _showCursor = false;
  168. private Rect _cursorRect;
  169. private GUIStyle _cursorStyle = null;
  170. private (int from, int to, bool perform) _moveBrush = (0, 0, false);
  171. private bool draggingBrush
  172. {
  173. get => _draggingBrush;
  174. set
  175. {
  176. _draggingBrush = value;
  177. wantsMouseMove = value;
  178. wantsMouseEnterLeaveWindow = value;
  179. }
  180. }
  181. private void Palette()
  182. {
  183. UpdateColumnCount();
  184. _prevIconSize = PaletteManager.iconSize;
  185. if (_moveBrush.perform)
  186. {
  187. RegisterUndo("Change Brush Order");
  188. var selection = PaletteManager.idxSelection;
  189. PaletteManager.selectedPalette.Swap(_moveBrush.from, _moveBrush.to, ref selection);
  190. PaletteManager.idxSelection = selection;
  191. if (selection.Length == 1) PaletteManager.selectedBrushIdx = selection[0];
  192. _moveBrush.perform = false;
  193. UpdateFilteredList(false);
  194. }
  195. BrushInputData toggleData = null;
  196. using (var scrollView = new UnityEditor.EditorGUILayout.ScrollViewScope(_scrollPosition, false, false,
  197. GUI.skin.horizontalScrollbar, GUI.skin.verticalScrollbar, _skin.box))
  198. {
  199. _scrollPosition = scrollView.scrollPosition;
  200. Brushes(ref toggleData);
  201. if (_showCursor) GUI.Box(_cursorRect, string.Empty, _cursorStyle);
  202. }
  203. _scrollViewRect = GUILayoutUtility.GetLastRect();
  204. if (PaletteManager.selectedPalette.brushCount == 0) DropBox();
  205. Bottom();
  206. BrushMouseEventHandler(toggleData);
  207. PaletteContext();
  208. DropPrefab();
  209. }
  210. private void UpdateColumnCount()
  211. {
  212. if (PaletteManager.paletteCount == 0) return;
  213. var paletteData = PaletteManager.selectedPalette;
  214. var brushes = paletteData.brushes;
  215. if (_scrollViewRect.width > MIN_ICON_SIZE)
  216. {
  217. if (_prevSize != position.size || _prevIconSize != PaletteManager.iconSize || _repaint)
  218. {
  219. var iconW = (float)((PaletteManager.iconSize + 4) * brushes.Length + 6) / brushes.Length;
  220. _columnCount = Mathf.Max((int)(_scrollViewRect.width / iconW), 1);
  221. var rowCount = Mathf.CeilToInt((float)brushes.Length / _columnCount);
  222. var h = rowCount * (PaletteManager.iconSize + 4) + 42;
  223. if (h > _scrollViewRect.height)
  224. {
  225. iconW = (float)((PaletteManager.iconSize + 4) * brushes.Length + 17) / brushes.Length;
  226. _columnCount = Mathf.Max((int)(_scrollViewRect.width / iconW), 1);
  227. }
  228. }
  229. _prevSize = position.size;
  230. }
  231. }
  232. public void OnPaletteChange()
  233. {
  234. UpdateLabelFilter();
  235. UpdateFilteredList(false);
  236. _repaint = true;
  237. UpdateColumnCount();
  238. Repaint();
  239. }
  240. #endregion
  241. #region BOTTOM
  242. private GUIContent _newBrushIcon = null;
  243. private GUIContent _deleteBrushIcon = null;
  244. private GUIContent _pickerIcon = null;
  245. private GUIContent _settingsIcon = null;
  246. private void Bottom()
  247. {
  248. using (new GUILayout.HorizontalScope(UnityEditor.EditorStyles.toolbar, GUILayout.Height(18)))
  249. {
  250. if (PaletteManager.selectedPalette.brushCount > 0)
  251. {
  252. var sliderStyle = new GUIStyle(GUI.skin.horizontalSlider);
  253. sliderStyle.margin.top = 0;
  254. PaletteManager.iconSize = (int)GUILayout.HorizontalSlider(
  255. (float)PaletteManager.iconSize,
  256. (float)MIN_ICON_SIZE,
  257. (float)MAX_ICON_SIZE,
  258. sliderStyle,
  259. GUI.skin.horizontalSliderThumb,
  260. GUILayout.MaxWidth(128));
  261. }
  262. GUILayout.FlexibleSpace();
  263. if (GUILayout.Button(_newBrushIcon, UnityEditor.EditorStyles.toolbarButton)) PaletteContextMenu();
  264. using (new UnityEditor.EditorGUI.DisabledGroupScope(PaletteManager.selectionCount == 0))
  265. {
  266. if (GUILayout.Button(_deleteBrushIcon, UnityEditor.EditorStyles.toolbarButton)) OnDelete();
  267. }
  268. PaletteManager.pickingBrushes = GUILayout.Toggle(PaletteManager.pickingBrushes,
  269. _pickerIcon, UnityEditor.EditorStyles.toolbarButton);
  270. if (GUILayout.Button(_settingsIcon, UnityEditor.EditorStyles.toolbarButton)) SettingsContextMenu();
  271. }
  272. var rect = GUILayoutUtility.GetLastRect();
  273. if (rect.Contains(Event.current.mousePosition))
  274. {
  275. if (Event.current.type == EventType.MouseDown || Event.current.type == EventType.DragUpdated
  276. || Event.current.type == EventType.MouseDrag || Event.current.type == EventType.DragPerform)
  277. Event.current.Use();
  278. }
  279. }
  280. private void OnDelete()
  281. {
  282. RegisterUndo("Delete Brush");
  283. DeleteBrushSelection();
  284. PaletteManager.ClearSelection();
  285. OnPaletteChange();
  286. }
  287. public void Reload(bool clearSelection)
  288. {
  289. if (PaletteManager.selectedPaletteIdx >= PaletteManager.paletteCount) PaletteManager.selectedPaletteIdx = 0;
  290. if (clearSelection)
  291. {
  292. PaletteManager.ClearSelection(true);
  293. _lastVisibleIdx = PaletteManager.paletteCount - 1;
  294. }
  295. _updateTabBar = true;
  296. OnPaletteChange();
  297. }
  298. private void SettingsContextMenu()
  299. {
  300. var menu = new UnityEditor.GenericMenu();
  301. menu.AddItem(new GUIContent(PaletteManager.viewList ? "Grid View" : "List View"), false,
  302. () => PaletteManager.viewList = !PaletteManager.viewList);
  303. if (!PaletteManager.viewList)
  304. menu.AddItem(new GUIContent("Show Brush Name"), PaletteManager.showBrushName,
  305. () => PaletteManager.showBrushName = !PaletteManager.showBrushName);
  306. if (PaletteManager.selectedPalette.brushCount > 1)
  307. {
  308. menu.AddItem(new GUIContent("Ascending Sort"), false,
  309. () => { PaletteManager.selectedPalette.AscendingSort(); });
  310. menu.AddItem(new GUIContent("Descending Sort"), false,
  311. () => { PaletteManager.selectedPalette.DescendingSort(); });
  312. }
  313. menu.AddSeparator(string.Empty);
  314. menu.AddItem(new GUIContent("Rename palette..."), false, ShowRenamePaletteWindow,
  315. new RenameData(PaletteManager.selectedPaletteIdx, PaletteManager.selectedPalette.name,
  316. position.position + Event.current.mousePosition));
  317. menu.AddItem(new GUIContent("Delete palette"), false, ShowDeleteConfirmation,
  318. PaletteManager.selectedPaletteIdx);
  319. menu.AddItem(new GUIContent("Cleanup palette"), false, () =>
  320. {
  321. PaletteManager.Cleanup();
  322. OnPaletteChange();
  323. UpdateTabBar();
  324. Repaint();
  325. });
  326. menu.AddItem(new GUIContent("Load palette files"), false, () =>
  327. {
  328. PaletteManager.instance.LoadPaletteFiles(true);
  329. Reload(!ThumbnailUtils.savingImage);
  330. });
  331. menu.AddSeparator(string.Empty);
  332. menu.AddItem(new GUIContent("Update all thumbnails"), false, UpdateAllThumbnails);
  333. menu.AddSeparator(string.Empty);
  334. menu.AddItem(new GUIContent("Brush creation settings..."), false,
  335. BrushCreationSettingsWindow.ShowWindow);
  336. menu.ShowAsContext();
  337. }
  338. #endregion
  339. #region BRUSHES
  340. private Vector3 _selectedBrushPosition = Vector3.zero;
  341. private bool _frameSelectedBrush = false;
  342. private bool _newSelectedPositionSet = false;
  343. private Texture2D _loadingIcon = null;
  344. public void FrameSelectedBrush()
  345. {
  346. _frameSelectedBrush = true;
  347. _newSelectedPositionSet = false;
  348. }
  349. private void DoFrameSelectedBrush()
  350. {
  351. _frameSelectedBrush = false;
  352. if (_scrollPosition.y > _selectedBrushPosition.y
  353. || _scrollPosition.y + _scrollViewRect.height < _selectedBrushPosition.y)
  354. _scrollPosition.y = _selectedBrushPosition.y - 4;
  355. RepainWindow();
  356. }
  357. private static bool _edittingThumbnail = false;
  358. private static int _edittingThumbnailIdx = -1;
  359. private void Brushes(ref BrushInputData toggleData)
  360. {
  361. if (Event.current.control && Event.current.keyCode == KeyCode.A && _filteredBrushList.Count > 0)
  362. {
  363. PaletteManager.ClearSelection();
  364. foreach (var brush in _filteredBrushList) PaletteManager.AddToSelection(brush.index);
  365. PaletteManager.selectedBrushIdx = _filteredBrushList[0].index;
  366. Repaint();
  367. }
  368. if (PaletteManager.selectedPalette.brushCount == 0) return;
  369. if (filteredBrushListCount == 0) return;
  370. var filteredBrushes = filteredBrushList.ToArray();
  371. int filterBrushIdx = 0;
  372. var nameStyle = GUIStyle.none;
  373. nameStyle.margin = new RectOffset(2, 2, 0, 1);
  374. nameStyle.clipping = TextClipping.Clip;
  375. nameStyle.fontSize = 8;
  376. nameStyle.normal.textColor = Color.white;
  377. MultibrushSettings brushSettings = null;
  378. int brushIdx = -1;
  379. Texture2D icon = null;
  380. void GetBrushSettings(ref GUIStyle style)
  381. {
  382. brushSettings = filteredBrushes[filterBrushIdx].brush;
  383. brushIdx = filteredBrushes[filterBrushIdx].index;
  384. if (PaletteManager.SelectionContains(brushIdx))
  385. style.normal = _toggleStyle.onNormal;
  386. icon = brushSettings.thumbnail;
  387. if (icon == null) icon = _loadingIcon;
  388. }
  389. void GetInputData(ref BrushInputData inputData)
  390. {
  391. var rect = GUILayoutUtility.GetLastRect();
  392. void GetPaletteInputData(ref BrushInputData data)
  393. {
  394. data = new BrushInputData(brushIdx, rect, Event.current.type,
  395. Event.current.control, Event.current.shift, Event.current.mousePosition.x);
  396. }
  397. if (rect.Contains(Event.current.mousePosition))
  398. {
  399. if (Event.current.type == EventType.MouseDrag && Event.current.button == 1
  400. && Event.current.delta != Vector2.zero)
  401. {
  402. if (!_edittingThumbnail) _edittingThumbnailIdx = brushIdx;
  403. if (!Event.current.control && !Event.current.shift)
  404. {
  405. var brush = PaletteManager.selectedPalette.GetBrush(_edittingThumbnailIdx);
  406. if (brush.thumbnailSettings.useCustomImage)
  407. {
  408. GetPaletteInputData(ref inputData);
  409. return;
  410. }
  411. var rot = Quaternion.Euler(brush.thumbnailSettings.targetEuler);
  412. brush.thumbnailSettings.targetEuler = (Quaternion.AngleAxis(Event.current.delta.y, Vector3.left)
  413. * Quaternion.AngleAxis(Event.current.delta.x, Vector3.down) * rot).eulerAngles;
  414. brush.UpdateThumbnail(true, false);
  415. Event.current.Use();
  416. _edittingThumbnail = true;
  417. }
  418. else if (Event.current.control && !Event.current.shift)
  419. {
  420. var brush = PaletteManager.selectedPalette.GetBrush(_edittingThumbnailIdx);
  421. if (brush.thumbnailSettings.useCustomImage)
  422. {
  423. GetPaletteInputData(ref inputData);
  424. return;
  425. }
  426. var delta = Event.current.delta / PaletteManager.iconSize;
  427. delta.y = -delta.y;
  428. brush.thumbnailSettings.targetOffset = Vector2.Min(Vector2.one,
  429. Vector2.Max(brush.thumbnailSettings.targetOffset + delta, -Vector2.one));
  430. brush.UpdateThumbnail(true, false);
  431. Event.current.Use();
  432. _edittingThumbnail = true;
  433. }
  434. }
  435. else if (Event.current.type == EventType.ContextClick && _edittingThumbnail)
  436. {
  437. var brush = PaletteManager.selectedPalette.GetBrush(brushIdx);
  438. if (brush.thumbnailSettings.useCustomImage)
  439. {
  440. GetPaletteInputData(ref inputData);
  441. return;
  442. }
  443. brush.UpdateThumbnail(true, true);
  444. Event.current.Use();
  445. _edittingThumbnail = false;
  446. }
  447. else if (Event.current.isScrollWheel && Event.current.control && !Event.current.shift)
  448. {
  449. var brush = PaletteManager.selectedPalette.GetBrush(brushIdx);
  450. if (brush.thumbnailSettings.useCustomImage)
  451. {
  452. GetPaletteInputData(ref inputData);
  453. return;
  454. }
  455. var scrollSign = Mathf.Sign(Event.current.delta.y);
  456. brush.thumbnailSettings.zoom += scrollSign * 0.1f;
  457. brush.UpdateThumbnail(true, false);
  458. Event.current.Use();
  459. }
  460. else GetPaletteInputData(ref inputData);
  461. }
  462. if (Event.current.type != EventType.Layout && PaletteManager.selectedBrushIdx == brushIdx)
  463. {
  464. _selectedBrushPosition = rect.position;
  465. _newSelectedPositionSet = true;
  466. }
  467. }
  468. void GridViewRow(ref BrushInputData inputData)
  469. {
  470. using (new GUILayout.HorizontalScope())
  471. {
  472. for (int col = 0; col < _columnCount && filterBrushIdx < filteredBrushes.Length; ++col)
  473. {
  474. var style = new GUIStyle(_toggleStyle);
  475. GetBrushSettings(ref style);
  476. using (new GUILayout.VerticalScope(style))
  477. {
  478. if (PaletteManager.showBrushName)
  479. GUILayout.Box(new GUIContent(brushSettings.name, brushSettings.name),
  480. nameStyle, GUILayout.Width(PaletteManager.iconSize));
  481. GUILayout.Box(new GUIContent(icon, brushSettings.name), GUIStyle.none,
  482. GUILayout.Width(PaletteManager.iconSize),
  483. GUILayout.Height(PaletteManager.iconSize));
  484. }
  485. GetInputData(ref inputData);
  486. ++filterBrushIdx;
  487. }
  488. GUILayout.FlexibleSpace();
  489. }
  490. }
  491. void ListView(ref BrushInputData inputData)
  492. {
  493. var style = new GUIStyle(_toggleStyle);
  494. style.padding = new RectOffset(0, 0, 0, 0);
  495. GetBrushSettings(ref style);
  496. using (new GUILayout.HorizontalScope(style))
  497. {
  498. GUILayout.Box(new GUIContent(icon, brushSettings.name), GUIStyle.none,
  499. GUILayout.Width(PaletteManager.iconSize),
  500. GUILayout.Height(PaletteManager.iconSize));
  501. GUILayout.Space(4);
  502. using (new GUILayout.VerticalScope())
  503. {
  504. var span = (PaletteManager.iconSize - 16) / 2;
  505. GUILayout.Space(span);
  506. GUILayout.Box(new GUIContent(brushSettings.name, brushSettings.name), nameStyle);
  507. GUILayout.Space(span);
  508. }
  509. }
  510. GetInputData(ref inputData);
  511. ++filterBrushIdx;
  512. }
  513. nameStyle.fontSize = PaletteManager.viewList ? 12 : 8;
  514. nameStyle.fontSize = Mathf.Max(Mathf.RoundToInt(nameStyle.fontSize
  515. * ((float)PaletteManager.iconSize / (float)PrefabPalette.DEFAULT_ICON_SIZE)), nameStyle.fontSize);
  516. while (filterBrushIdx < filteredBrushes.Length)
  517. {
  518. if (PaletteManager.viewList) ListView(ref toggleData);
  519. else GridViewRow(ref toggleData);
  520. }
  521. }
  522. public void DeselectAllButThis(int index)
  523. {
  524. if (PaletteManager.selectedBrushIdx == index && PaletteManager.selectionCount == 1) return;
  525. PaletteManager.ClearSelection();
  526. if (index < 0) return;
  527. PaletteManager.AddToSelection(index);
  528. PaletteManager.selectedBrushIdx = index;
  529. }
  530. private void DeleteBrushSelection()
  531. {
  532. var descendingSelection = PaletteManager.idxSelection;
  533. System.Array.Sort<int>(descendingSelection, new System.Comparison<int>((i1, i2) => i2.CompareTo(i1)));
  534. foreach (var i in descendingSelection) PaletteManager.selectedPalette.RemoveBrushAt(i);
  535. }
  536. private void DeleteBrush(object idx)
  537. {
  538. RegisterUndo("Delete Brush");
  539. if (PaletteManager.SelectionContains((int)idx)) DeleteBrushSelection();
  540. else PaletteManager.selectedPalette.RemoveBrushAt((int)idx);
  541. PaletteManager.ClearSelection();
  542. OnPaletteChange();
  543. }
  544. private void CopyBrushSettings(object idx)
  545. => PaletteManager.clipboardSetting = PaletteManager.selectedPalette.brushes[(int)idx].CloneMainSettings();
  546. private void PasteBrushSettings(object idx)
  547. {
  548. RegisterUndo("Paste Brush Settings");
  549. PaletteManager.selectedPalette.brushes[(int)idx].Copy(PaletteManager.clipboardSetting);
  550. if (BrushProperties.instance != null) BrushProperties.instance.Repaint();
  551. PaletteManager.selectedPalette.Save();
  552. }
  553. private void DuplicateBrush(object idx)
  554. {
  555. RegisterUndo("Duplicate Brush");
  556. if (PaletteManager.SelectionContains((int)idx))
  557. {
  558. var descendingSelection = PaletteManager.idxSelection;
  559. System.Array.Sort<int>(descendingSelection, new System.Comparison<int>((i1, i2) => i2.CompareTo(i1)));
  560. for (int i = 0; i < descendingSelection.Length; ++i)
  561. {
  562. PaletteManager.selectedPalette.DuplicateBrush(descendingSelection[i]);
  563. descendingSelection[i] += descendingSelection.Length - 1 - i;
  564. }
  565. PaletteManager.idxSelection = descendingSelection;
  566. }
  567. else PaletteManager.selectedPalette.DuplicateBrush((int)idx);
  568. OnPaletteChange();
  569. }
  570. private void MergeBrushes()
  571. {
  572. RegisterUndo("Merge Brushes");
  573. var selection = new System.Collections.Generic.List<int>(PaletteManager.idxSelection);
  574. selection.Sort();
  575. var resultIdx = selection[0];
  576. var lastIdx = selection.Last() + 1;
  577. PaletteManager.selectedPalette.DuplicateBrushAt(resultIdx, selection.Last() + 1);
  578. resultIdx = lastIdx;
  579. var result = PaletteManager.selectedPalette.GetBrush(resultIdx);
  580. var firstItem = result.GetItemAt(0);
  581. if (!firstItem.overwriteSettings) firstItem.Copy(result);
  582. firstItem.overwriteSettings = true;
  583. result.name += "_merged";
  584. selection.RemoveAt(0);
  585. for (int i = 0; i < selection.Count; ++i)
  586. {
  587. var idx = selection[i];
  588. var other = PaletteManager.selectedPalette.GetBrush(idx);
  589. var otherItems = other.items;
  590. foreach (var item in otherItems)
  591. {
  592. var clone = new MultibrushItemSettings(item.prefab, result);
  593. if (item.overwriteSettings) clone.Copy(item);
  594. else clone.Copy(other);
  595. clone.overwriteSettings = true;
  596. result.AddItem(clone);
  597. }
  598. }
  599. result.Reset();
  600. PaletteManager.ClearSelection();
  601. PaletteManager.AddToSelection(resultIdx);
  602. PaletteManager.selectedBrushIdx = resultIdx;
  603. OnPaletteChange();
  604. }
  605. private void OnMergeBrushesContext()
  606. {
  607. RegisterUndo("Merge Brushes");
  608. var selection = new System.Collections.Generic.List<int>(PaletteManager.idxSelection);
  609. selection.Sort();
  610. var resultIdx = selection[0];
  611. selection.RemoveAt(0);
  612. selection.Reverse();
  613. var result = PaletteManager.selectedPalette.GetBrush(resultIdx);
  614. for (int i = 0; i < selection.Count; ++i)
  615. {
  616. var idx = selection[i];
  617. var other = PaletteManager.selectedPalette.GetBrush(idx);
  618. var otherItems = other.items;
  619. foreach (var item in otherItems)
  620. {
  621. var clone = item.Clone() as MultibrushItemSettings;
  622. clone.parentSettings = result;
  623. result.AddItem(clone);
  624. }
  625. PaletteManager.selectedPalette.RemoveBrushAt(idx);
  626. }
  627. PaletteManager.ClearSelection();
  628. PaletteManager.AddToSelection(resultIdx);
  629. PaletteManager.selectedBrushIdx = resultIdx;
  630. OnPaletteChange();
  631. }
  632. private void SelectPrefabs(object idx)
  633. {
  634. var prefabs = new System.Collections.Generic.List<GameObject>();
  635. if (PaletteManager.SelectionContains((int)idx))
  636. {
  637. foreach (int selectedIdx in PaletteManager.idxSelection)
  638. {
  639. var brush = PaletteManager.selectedPalette.GetBrush(selectedIdx);
  640. foreach (var item in brush.items)
  641. {
  642. if (item.prefab != null) prefabs.Add(item.prefab);
  643. }
  644. }
  645. }
  646. else
  647. {
  648. var brush = PaletteManager.selectedPalette.GetBrush((int)idx);
  649. foreach (var item in brush.items)
  650. {
  651. if (item.prefab != null) prefabs.Add(item.prefab);
  652. }
  653. }
  654. UnityEditor.Selection.objects = prefabs.ToArray();
  655. }
  656. private void OpenPrefab(object idx)
  657. => UnityEditor.AssetDatabase.OpenAsset(PaletteManager.selectedPalette.GetBrush((int)idx).items[0].prefab);
  658. private void SelectReferences(object idx)
  659. {
  660. var items = PaletteManager.selectedPalette.GetBrush((int)idx).items;
  661. var itemsprefabIds = new System.Collections.Generic.List<int>();
  662. foreach (var item in items)
  663. {
  664. if (item.prefab != null) itemsprefabIds.Add(item.prefab.GetInstanceID());
  665. }
  666. var selection = new System.Collections.Generic.List<GameObject>();
  667. #if UNITY_2022_2_OR_NEWER
  668. var objects = GameObject.FindObjectsByType<Transform>(FindObjectsSortMode.None);
  669. #else
  670. var objects = GameObject.FindObjectsOfType<Transform>();
  671. #endif
  672. foreach (var obj in objects)
  673. {
  674. var source = UnityEditor.PrefabUtility.GetCorrespondingObjectFromSource(obj);
  675. if (source == null) continue;
  676. var sourceIdx = source.gameObject.GetInstanceID();
  677. if (itemsprefabIds.Contains(sourceIdx)) selection.Add(obj.gameObject);
  678. }
  679. UnityEditor.Selection.objects = selection.ToArray();
  680. }
  681. private void UpdateThumbnail(object idx) => PaletteManager.UpdateSelectedThumbnails();
  682. private void EditThumbnail(object idx)
  683. {
  684. var brushIdx = (int)idx;
  685. var brush = PaletteManager.selectedPalette.GetBrush(brushIdx);
  686. ThumbnailEditorWindow.ShowWindow(brush, brushIdx);
  687. }
  688. private void CopyThumbnailSettings(object idx)
  689. {
  690. var brush = PaletteManager.selectedPalette.brushes[(int)idx];
  691. PaletteManager.clipboardThumbnailSettings = brush.thumbnailSettings.Clone();
  692. PaletteManager.clipboardOverwriteThumbnailSettings = PaletteManager.Trit.SAME;
  693. }
  694. private void PasteThumbnailSettings(object idx)
  695. {
  696. if (PaletteManager.clipboardThumbnailSettings == null) return;
  697. RegisterUndo("Paste Thumbnail Settings");
  698. void Paste(MultibrushSettings brush)
  699. {
  700. brush.thumbnailSettings.Copy(PaletteManager.clipboardThumbnailSettings);
  701. ThumbnailUtils.UpdateThumbnail(brushSettings: brush, updateItemThumbnails: true, savePng: true);
  702. }
  703. if (PaletteManager.SelectionContains((int)idx))
  704. {
  705. foreach (var i in PaletteManager.idxSelection) Paste(PaletteManager.selectedPalette.brushes[i]);
  706. }
  707. else Paste(PaletteManager.selectedPalette.brushes[(int)idx]);
  708. PaletteManager.selectedPalette.Save();
  709. }
  710. private void BrushContext(int idx)
  711. {
  712. void ShowBrushProperties(object idx)
  713. {
  714. PaletteManager.ClearSelection();
  715. PaletteManager.AddToSelection((int)idx);
  716. PaletteManager.selectedBrushIdx = (int)idx;
  717. BrushProperties.ShowWindow();
  718. }
  719. var menu = new UnityEditor.GenericMenu();
  720. menu.AddItem(new GUIContent("Brush Properties..."), false, ShowBrushProperties, idx);
  721. menu.AddSeparator(string.Empty);
  722. var brush = PaletteManager.selectedPalette.GetBrush(idx);
  723. menu.AddItem(new GUIContent("Select Prefab" + (PaletteManager.selectionCount > 1
  724. || brush.itemCount > 1 ? "s" : "")), false, SelectPrefabs, idx);
  725. if (brush.itemCount == 1) menu.AddItem(new GUIContent("Open Prefab"), false, OpenPrefab, idx);
  726. menu.AddItem(new GUIContent("Select References In Scene"), false, SelectReferences, idx);
  727. menu.AddSeparator(string.Empty);
  728. menu.AddItem(new GUIContent("Update Thumbnail"), false, UpdateThumbnail, idx);
  729. menu.AddItem(new GUIContent("Edit Thumbnail..."), false, EditThumbnail, idx);
  730. menu.AddItem(new GUIContent("Copy Thumbnail Settings"), false, CopyThumbnailSettings, idx);
  731. if (PaletteManager.clipboardThumbnailSettings != null)
  732. menu.AddItem(new GUIContent("Paste Thumbnail Settings"), false, PasteThumbnailSettings, idx);
  733. menu.AddSeparator(string.Empty);
  734. menu.AddItem(new GUIContent("Delete"), false, DeleteBrush, idx);
  735. menu.AddItem(new GUIContent("Duplicate"), false, DuplicateBrush, idx);
  736. if (PaletteManager.selectionCount > 1) menu.AddItem(new GUIContent("Merge"), false, OnMergeBrushesContext);
  737. if (PaletteManager.selectionCount == 1)
  738. menu.AddItem(new GUIContent("Copy Brush Settings"), false, CopyBrushSettings, idx);
  739. if (PaletteManager.clipboardSetting != null)
  740. menu.AddItem(new GUIContent("Paste Brush Settings"), false, PasteBrushSettings, idx);
  741. menu.AddSeparator(string.Empty);
  742. PaletteContextAddMenuItems(menu);
  743. menu.ShowAsContext();
  744. }
  745. private void BrushMouseEventHandler(BrushInputData data)
  746. {
  747. void DeselectAllButCurrent()
  748. {
  749. PaletteManager.ClearSelection();
  750. PaletteManager.selectedBrushIdx = data.index;
  751. PaletteManager.AddToSelection(data.index);
  752. }
  753. if (data == null) return;
  754. if (data.eventType == EventType.MouseMove) Event.current.Use();
  755. if (data.eventType == EventType.MouseDown && Event.current.button == 0)
  756. {
  757. void DeselectAll() => PaletteManager.ClearSelection();
  758. void ToggleCurrent()
  759. {
  760. if (PaletteManager.SelectionContains(data.index)) PaletteManager.RemoveFromSelection(data.index);
  761. else PaletteManager.AddToSelection(data.index);
  762. PaletteManager.selectedBrushIdx = PaletteManager.selectionCount == 1
  763. ? PaletteManager.idxSelection[0] : -1;
  764. }
  765. if (data.shift)
  766. {
  767. var selectedIdx = PaletteManager.selectedBrushIdx;
  768. var sign = (int)Mathf.Sign(data.index - selectedIdx);
  769. if (sign != 0)
  770. {
  771. PaletteManager.ClearSelection();
  772. for (int i = selectedIdx; i != data.index; i += sign)
  773. {
  774. if (FilteredListContains(i)) PaletteManager.AddToSelection(i);
  775. }
  776. PaletteManager.AddToSelection(data.index);
  777. PaletteManager.selectedBrushIdx = selectedIdx;
  778. }
  779. else DeselectAllButCurrent();
  780. }
  781. else
  782. {
  783. if (data.control && PaletteManager.selectionCount < 2)
  784. {
  785. if (PaletteManager.selectedBrushIdx == data.index) DeselectAll();
  786. else ToggleCurrent();
  787. }
  788. else if (data.control && PaletteManager.selectionCount > 1) ToggleCurrent();
  789. else if (!data.control && PaletteManager.selectionCount < 2)
  790. {
  791. if (PaletteManager.selectedBrushIdx == data.index) DeselectAll();
  792. else DeselectAllButCurrent();
  793. }
  794. else if (!data.control && PaletteManager.selectionCount > 1) DeselectAllButCurrent();
  795. }
  796. Event.current.Use();
  797. Repaint();
  798. }
  799. else if (data.eventType == EventType.ContextClick)
  800. {
  801. BrushContext(data.index);
  802. Event.current.Use();
  803. }
  804. else if (Event.current.type == EventType.MouseDrag && Event.current.button == 0
  805. && Event.current.delta != Vector2.zero)
  806. {
  807. if (!PaletteManager.SelectionContains(data.index)) DeselectAllButCurrent();
  808. UnityEditor.DragAndDrop.PrepareStartDrag();
  809. if (Event.current.control)
  810. {
  811. UnityEditor.DragAndDrop.StartDrag("Dragging brush");
  812. UnityEditor.DragAndDrop.objectReferences = new Object[]
  813. { PaletteManager.selectedBrush.GetItemAt(0).prefab };
  814. UnityEditor.DragAndDrop.visualMode = UnityEditor.DragAndDropVisualMode.Move;
  815. }
  816. else
  817. {
  818. PWBIO.sceneDragReceiver.brushId = data.index;
  819. SceneDragAndDrop.StartDrag(PWBIO.sceneDragReceiver, "Dragging brush");
  820. UnityEditor.DragAndDrop.visualMode = UnityEditor.DragAndDropVisualMode.Copy;
  821. }
  822. draggingBrush = true;
  823. _moveBrush.from = data.index;
  824. _moveBrush.perform = false;
  825. _moveBrush.to = -1;
  826. }
  827. else if (data.eventType == EventType.DragUpdated && Event.current.button == 0)
  828. {
  829. if (Event.current.control) UnityEditor.DragAndDrop.visualMode = UnityEditor.DragAndDropVisualMode.Move;
  830. else
  831. {
  832. UnityEditor.DragAndDrop.visualMode = UnityEditor.DragAndDropVisualMode.Copy;
  833. var size = new Vector2(4, PaletteManager.iconSize);
  834. var min = data.rect.min;
  835. bool toTheRight = data.mouseX - data.rect.center.x > 0;
  836. min.x = toTheRight ? data.rect.max.x : min.x - size.x;
  837. _cursorRect = new Rect(min, size);
  838. _showCursor = true;
  839. _moveBrush.to = data.index;
  840. if (toTheRight) ++_moveBrush.to;
  841. }
  842. }
  843. else if (data.eventType == EventType.DragPerform && Event.current.button == 0 && !Event.current.control)
  844. {
  845. _moveBrush.to = data.index;
  846. bool toTheRight = data.mouseX - data.rect.center.x > 0;
  847. if (toTheRight) ++_moveBrush.to;
  848. if (draggingBrush)
  849. {
  850. _moveBrush.perform = _moveBrush.from != _moveBrush.to;
  851. draggingBrush = false;
  852. }
  853. _showCursor = false;
  854. }
  855. else if (data.eventType == EventType.DragExited && Event.current.button == 0 && !Event.current.control)
  856. {
  857. _showCursor = false;
  858. draggingBrush = false;
  859. _moveBrush.to = -1;
  860. }
  861. }
  862. #endregion
  863. #region PALETTE CONTEXT
  864. private int _currentPickerId = -1;
  865. private bool _contextBrushAdded = false;
  866. private MultibrushSettings _newContextBrush = null;
  867. private void PaletteContext()
  868. {
  869. if (_scrollViewRect.Contains(Event.current.mousePosition))
  870. {
  871. if (Event.current.type == EventType.ContextClick)
  872. {
  873. PaletteContextMenu();
  874. Event.current.Use();
  875. }
  876. else if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
  877. {
  878. PaletteManager.ClearSelection();
  879. Repaint();
  880. }
  881. }
  882. if (Event.current.commandName == "ObjectSelectorClosed"
  883. && UnityEditor.EditorGUIUtility.GetObjectPickerControlID() == _currentPickerId)
  884. {
  885. var obj = UnityEditor.EditorGUIUtility.GetObjectPickerObject();
  886. if (obj != null)
  887. {
  888. var prefabType = UnityEditor.PrefabUtility.GetPrefabAssetType(obj);
  889. if (prefabType == UnityEditor.PrefabAssetType.Regular
  890. || prefabType == UnityEditor.PrefabAssetType.Variant)
  891. {
  892. _contextBrushAdded = true;
  893. var gameObj = obj as GameObject;
  894. AddLabels(gameObj);
  895. _newContextBrush = new MultibrushSettings(gameObj, PaletteManager.selectedPalette);
  896. }
  897. }
  898. _currentPickerId = -1;
  899. }
  900. }
  901. private void PaletteContextAddMenuItems(UnityEditor.GenericMenu menu)
  902. {
  903. menu.AddItem(new GUIContent("New Brush From Prefab..."), false, CreateBrushFromPrefab);
  904. menu.AddItem(new GUIContent("New MultiBrush From Folder..."), false, CreateBrushFromFolder);
  905. menu.AddItem(new GUIContent("New Brush From Each Prefab In Folder..."), false,
  906. CreateBrushFromEachPrefabInFolder);
  907. menu.AddSeparator(string.Empty);
  908. menu.AddItem(new GUIContent("New MultiBrush From Selection"), false, CreateBrushFromSelection);
  909. menu.AddItem(new GUIContent("New Brush From Each Prefab Selected"), false,
  910. CreateBushFromEachPrefabSelected);
  911. menu.AddSeparator(string.Empty);
  912. menu.AddItem(new GUIContent("Update all thumbnails"), false, UpdateAllThumbnails);
  913. menu.AddSeparator(string.Empty);
  914. menu.AddItem(new GUIContent("Brush Creation And Drop Settings..."), false,
  915. BrushCreationSettingsWindow.ShowWindow);
  916. if (PaletteManager.selectedBrushIdx > 0 || PaletteManager.movingBrushes)
  917. {
  918. menu.AddSeparator(string.Empty);
  919. if (PaletteManager.selectedBrushIdx > 0)
  920. menu.AddItem(new GUIContent("Copy Selected brushes"), false, PaletteManager.SelectBrushesToMove);
  921. if (PaletteManager.movingBrushes)
  922. {
  923. menu.AddItem(new GUIContent("Paste brushes and keep originals"),
  924. false, PasteBrushesToSelectedPalette);
  925. menu.AddItem(new GUIContent("Paste brushes and delete originals"),
  926. false, MoveBrushesToSelectedPalette);
  927. }
  928. }
  929. }
  930. private void PasteBrushesToSelectedPalette()
  931. {
  932. PaletteManager.PasteBrushesToSelectedPalette();
  933. OnPaletteChange();
  934. }
  935. private void MoveBrushesToSelectedPalette()
  936. {
  937. PaletteManager.MoveBrushesToSelectedPalette();
  938. OnPaletteChange();
  939. }
  940. private void PaletteContextMenu()
  941. {
  942. var menu = new UnityEditor.GenericMenu();
  943. PaletteContextAddMenuItems(menu);
  944. menu.ShowAsContext();
  945. }
  946. private void CreateBrushFromPrefab()
  947. {
  948. _currentPickerId = GUIUtility.GetControlID(FocusType.Passive) + 100;
  949. UnityEditor.EditorGUIUtility.ShowObjectPicker<GameObject>(null, false, "t:Prefab", _currentPickerId);
  950. }
  951. private void CreateBrushFromFolder()
  952. {
  953. var items = PluginMaster.DropUtils.GetFolderItems();
  954. if (items == null) return;
  955. RegisterUndo("Add Brush");
  956. var brush = new MultibrushSettings(items[0].obj, PaletteManager.selectedPalette);
  957. AddLabels(items[0].obj);
  958. PaletteManager.selectedPalette.AddBrush(brush);
  959. DeselectAllButThis(PaletteManager.selectedPalette.brushes.Length - 1);
  960. for (int i = 1; i < items.Length; ++i)
  961. {
  962. var item = new MultibrushItemSettings(items[i].obj, brush);
  963. AddLabels(items[i].obj);
  964. brush.AddItem(item);
  965. }
  966. OnPaletteChange();
  967. }
  968. private void CreateBrushFromEachPrefabInFolder()
  969. {
  970. var items = PluginMaster.DropUtils.GetFolderItems();
  971. if (items == null) return;
  972. foreach (var item in items)
  973. {
  974. if (item.obj == null) continue;
  975. RegisterUndo("Add Brush");
  976. AddLabels(item.obj);
  977. var brush = new MultibrushSettings(item.obj, PaletteManager.selectedPalette);
  978. PaletteManager.selectedPalette.AddBrush(brush);
  979. }
  980. DeselectAllButThis(PaletteManager.selectedPalette.brushes.Length - 1);
  981. OnPaletteChange();
  982. }
  983. private string GetPrefabFolder(GameObject obj)
  984. {
  985. var path = UnityEditor.AssetDatabase.GetAssetPath(obj);
  986. var folders = path.Split(new char[] { '\\', '/' });
  987. var subFolder = folders[folders.Length - 2];
  988. return subFolder;
  989. }
  990. public void CreateBrushFromSelection()
  991. {
  992. if (PaletteManager.selectionCount > 1)
  993. {
  994. MergeBrushes();
  995. return;
  996. }
  997. var selectionPrefabs = SelectionManager.GetSelectionPrefabs();
  998. CreateBrushFromSelection(selectionPrefabs);
  999. }
  1000. public void CreateBrushFromSelection(GameObject[] selectionPrefabs)
  1001. {
  1002. if (selectionPrefabs.Length == 0) return;
  1003. RegisterUndo("Add Brush");
  1004. AddLabels(selectionPrefabs[0]);
  1005. var brush = new MultibrushSettings(selectionPrefabs[0], PaletteManager.selectedPalette);
  1006. PaletteManager.selectedPalette.AddBrush(brush);
  1007. DeselectAllButThis(PaletteManager.selectedPalette.brushes.Length - 1);
  1008. for (int i = 1; i < selectionPrefabs.Length; ++i)
  1009. {
  1010. AddLabels(selectionPrefabs[i]);
  1011. brush.AddItem(new MultibrushItemSettings(selectionPrefabs[i], brush));
  1012. }
  1013. OnPaletteChange();
  1014. }
  1015. public void CreateBrushFromSelection(GameObject selectedPrefab)
  1016. => CreateBrushFromSelection(new GameObject[] { selectedPrefab });
  1017. public void CreateBushFromEachPrefabSelected()
  1018. {
  1019. var selectionPrefabs = SelectionManager.GetSelectionPrefabs();
  1020. if (selectionPrefabs.Length == 0) return;
  1021. foreach (var obj in selectionPrefabs)
  1022. {
  1023. if (obj == null) continue;
  1024. RegisterUndo("Add Brush");
  1025. var brush = new MultibrushSettings(obj, PaletteManager.selectedPalette);
  1026. AddLabels(obj);
  1027. PaletteManager.selectedPalette.AddBrush(brush);
  1028. }
  1029. DeselectAllButThis(PaletteManager.selectedPalette.brushes.Length - 1);
  1030. OnPaletteChange();
  1031. }
  1032. #endregion
  1033. #region DROPBOX
  1034. private void DropBox()
  1035. {
  1036. GUIStyle dragAndDropBoxStyle = new GUIStyle();
  1037. dragAndDropBoxStyle.alignment = TextAnchor.MiddleCenter;
  1038. dragAndDropBoxStyle.fontStyle = FontStyle.Italic;
  1039. dragAndDropBoxStyle.fontSize = 12;
  1040. dragAndDropBoxStyle.normal.textColor = Color.white;
  1041. dragAndDropBoxStyle.wordWrap = true;
  1042. GUI.Box(_scrollViewRect, "Drag and Drop Prefabs Or Folders Here", dragAndDropBoxStyle);
  1043. }
  1044. private void AddLabels(GameObject obj)
  1045. {
  1046. if (!PaletteManager.selectedPalette.brushCreationSettings.addLabelsToDroppedPrefabs) return;
  1047. var labels = new System.Collections.Generic.HashSet<string>(UnityEditor.AssetDatabase.GetLabels(obj));
  1048. int labelCount = labels.Count;
  1049. if (PaletteManager.selectedPalette.brushCreationSettings.addLabelsToDroppedPrefabs)
  1050. labels.UnionWith(PaletteManager.selectedPalette.brushCreationSettings.labels);
  1051. if (labelCount != labels.Count) UnityEditor.AssetDatabase.SetLabels(obj, labels.ToArray());
  1052. }
  1053. private void DropPrefab()
  1054. {
  1055. if (_scrollViewRect.Contains(Event.current.mousePosition))
  1056. {
  1057. if (Event.current.type == EventType.DragUpdated)
  1058. {
  1059. UnityEditor.DragAndDrop.visualMode = UnityEditor.DragAndDropVisualMode.Copy;
  1060. Event.current.Use();
  1061. }
  1062. else if (Event.current.type == EventType.DragPerform)
  1063. {
  1064. bool paletteChanged = false;
  1065. var items = DropUtils.GetDroppedPrefabs();
  1066. if (items.Length > 0) PaletteManager.ClearSelection();
  1067. var i = 0;
  1068. foreach (var item in items)
  1069. {
  1070. AddLabels(item.obj);
  1071. var brush = new MultibrushSettings(item.obj, PaletteManager.selectedPalette);
  1072. RegisterUndo("Add Brush");
  1073. if (_moveBrush.to < 0)
  1074. {
  1075. PaletteManager.selectedPalette.AddBrush(brush);
  1076. PaletteManager.selectedBrushIdx = PaletteManager.selectedPalette.brushes.Length - 1;
  1077. }
  1078. else
  1079. {
  1080. var idx = _moveBrush.to + i++;
  1081. PaletteManager.selectedPalette.InsertBrushAt(brush, idx);
  1082. PaletteManager.selectedBrushIdx = _moveBrush.to;
  1083. }
  1084. paletteChanged = true;
  1085. }
  1086. if (paletteChanged) OnPaletteChange();
  1087. if (draggingBrush && _moveBrush.to >= 0)
  1088. {
  1089. _moveBrush.perform = _moveBrush.from != _moveBrush.to;
  1090. draggingBrush = false;
  1091. }
  1092. _showCursor = false;
  1093. Event.current.Use();
  1094. }
  1095. else if (Event.current.type == EventType.DragExited) _showCursor = false;
  1096. }
  1097. }
  1098. #endregion
  1099. #region TAB BAR
  1100. #region RENAME
  1101. private class RenamePaletteWindow : UnityEditor.EditorWindow
  1102. {
  1103. private string _name = string.Empty;
  1104. private int _paletteIdx = -1;
  1105. private System.Action<string, int> _onDone;
  1106. private bool _focusSet = false;
  1107. public static void ShowWindow(RenameData data, System.Action<string, int> onDone)
  1108. {
  1109. var window = GetWindow<RenamePaletteWindow>(true, "Rename Palette");
  1110. window._name = data.currentName;
  1111. window._paletteIdx = data.paletteIdx;
  1112. window._onDone = onDone;
  1113. window.position = new Rect(data.mousePosition.x + 50, data.mousePosition.y + 50, 0, 0);
  1114. window.minSize = window.maxSize = new Vector2(160, 45);
  1115. window._focusSet = false;
  1116. }
  1117. private void OnGUI()
  1118. {
  1119. UnityEditor.EditorGUIUtility.labelWidth = 50;
  1120. UnityEditor.EditorGUIUtility.fieldWidth = 70;
  1121. GUI.SetNextControlName("NameField");
  1122. _name = UnityEditor.EditorGUILayout.TextField(string.Empty, _name);
  1123. if (!_focusSet)
  1124. {
  1125. UnityEditor.EditorGUI.FocusTextInControl("NameField");
  1126. _focusSet = true;
  1127. }
  1128. using (new UnityEditor.EditorGUI.DisabledGroupScope(string.IsNullOrWhiteSpace(_name)))
  1129. {
  1130. if (GUILayout.Button("Apply"))
  1131. {
  1132. _onDone(_name, _paletteIdx);
  1133. Close();
  1134. }
  1135. }
  1136. }
  1137. }
  1138. private struct RenameData
  1139. {
  1140. public readonly int paletteIdx;
  1141. public readonly string currentName;
  1142. public readonly Vector2 mousePosition;
  1143. public RenameData(int paletteIdx, string currentName, Vector2 mousePosition)
  1144. => (this.paletteIdx, this.currentName, this.mousePosition) = (paletteIdx, currentName, mousePosition);
  1145. }
  1146. private void ShowRenamePaletteWindow(object obj)
  1147. {
  1148. if (!(obj is RenameData)) return;
  1149. var data = (RenameData)obj;
  1150. RenamePaletteWindow.ShowWindow(data, RenamePalette);
  1151. }
  1152. private void RenamePalette(string paletteName, int paletteIdx)
  1153. {
  1154. RegisterUndo("Rename Palette");
  1155. PaletteManager.paletteData[paletteIdx].name = paletteName;
  1156. _updateTabBarWidth = true;
  1157. Repaint();
  1158. }
  1159. #endregion
  1160. private void ShowDeleteConfirmation(object obj)
  1161. {
  1162. int paletteIdx = (int)obj;
  1163. var palette = PaletteManager.paletteData[paletteIdx];
  1164. if (UnityEditor.EditorUtility.DisplayDialog("Delete Palette: " + palette.name,
  1165. "Are you sure you want to delete this palette?\n" + palette.name, "Delete", "Cancel"))
  1166. {
  1167. RegisterUndo("Remove Palette");
  1168. PaletteManager.RemovePaletteAt(paletteIdx);
  1169. if (PaletteManager.paletteCount == 0) CreatePalette();
  1170. else if (PaletteManager.selectedPaletteIdx >= PaletteManager.paletteCount) SelectPalette(0);
  1171. --_visibleTabCount;
  1172. if (lastVisibleIdx >= _visibleTabCount) lastVisibleIdx = _visibleTabCount - 1;
  1173. PaletteManager.selectedBrushIdx = -1;
  1174. _updateTabBarWidth = true;
  1175. _updateTabBar = true;
  1176. UpdateFilteredList(false);
  1177. Repaint();
  1178. }
  1179. }
  1180. #region TAB BUTTONS
  1181. private float _prevWidth = 0f;
  1182. private bool _updateTabBarWidth = true;
  1183. private bool _updateTabBar = false;
  1184. private int _lastVisibleIdx = 0;
  1185. private int _visibleTabCount = 0;
  1186. private Rect _dropdownRect;
  1187. public static void UpdateTabBar()
  1188. {
  1189. if (instance == null) return;
  1190. instance._updateTabBar = true;
  1191. instance._updateTabBarWidth = true;
  1192. }
  1193. private int lastVisibleIdx
  1194. {
  1195. get
  1196. {
  1197. if (_lastVisibleIdx >= PaletteManager.paletteCount) _lastVisibleIdx = 0;
  1198. return _lastVisibleIdx;
  1199. }
  1200. set => _lastVisibleIdx = value;
  1201. }
  1202. public void SelectPalette(int idx)
  1203. {
  1204. if (PaletteManager.selectedPaletteIdx == idx) return;
  1205. PaletteManager.selectedPaletteIdx = idx;
  1206. PaletteManager.selectedBrushIdx = -1;
  1207. PaletteManager.ClearSelection();
  1208. _updateTabBar = true;
  1209. OnPaletteChange();
  1210. }
  1211. private void SelectPalette(object obj) => SelectPalette((int)obj);
  1212. private void CreatePalette()
  1213. {
  1214. _lastVisibleIdx = PaletteManager.paletteCount;
  1215. PaletteManager.AddPalette(new PaletteData("Palette" + (PaletteManager.paletteCount + 1),
  1216. System.DateTime.Now.ToBinary()), save: true);
  1217. SelectPalette(lastVisibleIdx);
  1218. UpdateTabBar();
  1219. }
  1220. private void DuplicatePalette(object obj)
  1221. {
  1222. int paletteIdx = (int)obj;
  1223. PaletteManager.DuplicatePalette(paletteIdx);
  1224. UpdateTabBar();
  1225. RepainWindow();
  1226. }
  1227. private void ToggleMultipleRows()
  1228. => PaletteManager.showTabsInMultipleRows = !PaletteManager.showTabsInMultipleRows;
  1229. private System.Collections.Generic.List<Rect> _tabRects = new System.Collections.Generic.List<Rect>();
  1230. private System.Collections.Generic.Dictionary<long, float> _tabSize
  1231. = new System.Collections.Generic.Dictionary<long, float>();
  1232. private void TabBar()
  1233. {
  1234. float visibleW = 0;
  1235. int lastVisibleIdx = 0;
  1236. if (Event.current.type == EventType.MouseDown && Event.current.button == 1)
  1237. {
  1238. for (int i = 0; i < _tabRects.Count; ++i)
  1239. {
  1240. if (_tabRects[i].Contains(Event.current.mousePosition))
  1241. {
  1242. var name = PaletteManager.paletteNames[i];
  1243. var menu = new UnityEditor.GenericMenu();
  1244. menu.AddItem(new GUIContent("Rename"), false, ShowRenamePaletteWindow,
  1245. new RenameData(i, name, position.position + Event.current.mousePosition));
  1246. menu.AddItem(new GUIContent("Delete"), false, ShowDeleteConfirmation, i);
  1247. menu.AddItem(new GUIContent("Duplicate"), false, DuplicatePalette, i);
  1248. menu.ShowAsContext();
  1249. }
  1250. }
  1251. }
  1252. var names = PaletteManager.paletteNames;
  1253. var paletteIds = PaletteManager.paletteIds;
  1254. int Tabs(int from, int to)
  1255. {
  1256. var lastVisible = to;
  1257. for (int i = from; i <= to; ++i)
  1258. {
  1259. var isSelected = PaletteManager.selectedPaletteIdx == i;
  1260. var name = names[i];
  1261. if (GUILayout.Toggle(isSelected, name, UnityEditor.EditorStyles.toolbarButton)
  1262. && Event.current.button == 0)
  1263. {
  1264. if (!isSelected) SelectPalette(i);
  1265. isSelected = true;
  1266. }
  1267. var toggleRect = GUILayoutUtility.GetLastRect();
  1268. var id = paletteIds[i];
  1269. if (Event.current.type == EventType.Repaint)
  1270. {
  1271. if (_tabSize.ContainsKey(id)) _tabSize[id] = toggleRect.width;
  1272. else _tabSize.Add(id, toggleRect.width);
  1273. }
  1274. if (Event.current.type == EventType.Repaint) _tabRects.Add(toggleRect);
  1275. if (Event.current.type == EventType.Repaint && toggleRect.xMax < position.width)
  1276. {
  1277. lastVisible = i;
  1278. visibleW = toggleRect.xMax;
  1279. }
  1280. }
  1281. GUILayout.FlexibleSpace();
  1282. return lastVisible;
  1283. }
  1284. using (new GUILayout.HorizontalScope(UnityEditor.EditorStyles.toolbar))
  1285. {
  1286. if (GUILayout.Button(_dropdownIcon, UnityEditor.EditorStyles.toolbarButton))
  1287. {
  1288. var menu = new UnityEditor.GenericMenu();
  1289. menu.AddItem(new GUIContent("New palette"), false, CreatePalette);
  1290. menu.AddSeparator(string.Empty);
  1291. menu.AddItem(new GUIContent("Show tabs in multiple rows"),
  1292. PaletteManager.showTabsInMultipleRows, ToggleMultipleRows);
  1293. menu.AddSeparator(string.Empty);
  1294. var namesDic = PaletteManager.paletteNames.Select((name, index) => new { name, index })
  1295. .ToDictionary(item => item.index, item => item.name);
  1296. var sortedDic = (from item in namesDic orderby item.Value ascending select item)
  1297. .ToDictionary(pair => pair.Key, pair => pair.Value);
  1298. var repeatedNameCount = new System.Collections.Generic.Dictionary<string, int>();
  1299. foreach (var item in sortedDic)
  1300. {
  1301. var name = item.Value;
  1302. if (repeatedNameCount.ContainsKey(item.Value)) name += "(" + repeatedNameCount[item.Value] + ")";
  1303. menu.AddItem(new GUIContent(name), PaletteManager.selectedPaletteIdx == item.Key,
  1304. SelectPalette, item.Key);
  1305. if (repeatedNameCount.ContainsKey(item.Value)) repeatedNameCount[item.Value] += 1;
  1306. else repeatedNameCount.Add(item.Value, 1);
  1307. }
  1308. menu.ShowAsContext();
  1309. }
  1310. if (Event.current.type == EventType.Repaint) _tabRects.Clear();
  1311. if (PaletteManager.paletteCount == 0) return;
  1312. lastVisibleIdx = Tabs(0, this.lastVisibleIdx);
  1313. if (Event.current.type == EventType.Repaint)
  1314. {
  1315. if (_updateTabBarWidth && _visibleTabCount == PaletteManager.paletteCount)
  1316. {
  1317. _updateTabBarWidth = false;
  1318. _lastVisibleIdx = lastVisibleIdx;
  1319. _updateTabBar = true;
  1320. }
  1321. else if (_updateTabBarWidth && _visibleTabCount != PaletteManager.paletteCount)
  1322. {
  1323. _lastVisibleIdx = PaletteManager.paletteCount - 1;
  1324. _updateTabBar = true;
  1325. }
  1326. if (_prevWidth != position.width)
  1327. {
  1328. if (_prevWidth < position.width) _updateTabBarWidth = true;
  1329. _lastVisibleIdx = lastVisibleIdx;
  1330. _prevWidth = position.width;
  1331. _updateTabBar = true;
  1332. }
  1333. }
  1334. }
  1335. if (PaletteManager.showTabsInMultipleRows)
  1336. {
  1337. var rowItemCount = new System.Collections.Generic.List<int>();
  1338. float tabsWidth = 0;
  1339. var tabItemCount = 0;
  1340. for (int i = _visibleTabCount; i < PaletteManager.paletteCount; ++i)
  1341. {
  1342. var id = paletteIds[i];
  1343. if (!_tabSize.ContainsKey(id))
  1344. {
  1345. _updateTabBarWidth = true;
  1346. _updateTabBar = true;
  1347. continue;
  1348. }
  1349. var w = _tabSize[id];
  1350. tabsWidth += w;
  1351. if (tabsWidth > position.width)
  1352. {
  1353. rowItemCount.Add(Mathf.Max(tabItemCount, 1));
  1354. tabsWidth = tabItemCount > 0 ? w : 0;
  1355. if (tabItemCount == 0) continue;
  1356. tabItemCount = 0;
  1357. }
  1358. ++tabItemCount;
  1359. }
  1360. if (tabItemCount > 0) rowItemCount.Add(tabItemCount);
  1361. if (rowItemCount.Count > 0)
  1362. {
  1363. if (_visibleTabCount == PaletteManager.paletteCount)
  1364. _updateTabBar = true;
  1365. int fromIdx = _visibleTabCount;
  1366. int toIdx = _visibleTabCount;
  1367. foreach (var itemCount in rowItemCount)
  1368. {
  1369. toIdx = fromIdx + itemCount - 1;
  1370. using (new GUILayout.HorizontalScope(UnityEditor.EditorStyles.toolbar))
  1371. {
  1372. Tabs(fromIdx, toIdx);
  1373. }
  1374. fromIdx = toIdx + 1;
  1375. if (fromIdx >= PaletteManager.paletteCount) break;
  1376. }
  1377. }
  1378. }
  1379. if (_updateTabBar && PaletteManager.paletteCount > 1)
  1380. {
  1381. if (!PaletteManager.showTabsInMultipleRows && PaletteManager.selectedPaletteIdx > this.lastVisibleIdx)
  1382. {
  1383. PaletteManager.SwapPalette(PaletteManager.selectedPaletteIdx, this.lastVisibleIdx);
  1384. PaletteManager.selectedPaletteIdx = this.lastVisibleIdx;
  1385. }
  1386. _visibleTabCount = this.lastVisibleIdx + 1;
  1387. _updateTabBar = false;
  1388. Repaint();
  1389. }
  1390. }
  1391. #endregion
  1392. #endregion
  1393. #region SEARCH BAR
  1394. private string _filterText = string.Empty;
  1395. private GUIContent _labelIcon = null;
  1396. private GUIContent _selectionFilterIcon = null;
  1397. private GUIContent _folderFilterIcon = null;
  1398. private GUIContent _clearFilterIcon = null;
  1399. private struct FilteredBrush
  1400. {
  1401. public readonly MultibrushSettings brush;
  1402. public readonly int index;
  1403. public FilteredBrush(MultibrushSettings brush, int index) => (this.brush, this.index) = (brush, index);
  1404. }
  1405. private System.Collections.Generic.List<FilteredBrush> _filteredBrushList
  1406. = new System.Collections.Generic.List<FilteredBrush>();
  1407. private System.Collections.Generic.List<FilteredBrush> filteredBrushList
  1408. {
  1409. get
  1410. {
  1411. if (_filteredBrushList == null) _filteredBrushList = new System.Collections.Generic.List<FilteredBrush>();
  1412. return _filteredBrushList;
  1413. }
  1414. }
  1415. public bool FilteredBrushListContains(int index) => _filteredBrushList.Exists(brush => brush.index == index);
  1416. private System.Collections.Generic.Dictionary<string, bool> _labelFilter
  1417. = new System.Collections.Generic.Dictionary<string, bool>();
  1418. public System.Collections.Generic.Dictionary<string, bool> labelFilter
  1419. {
  1420. get
  1421. {
  1422. if (_labelFilter == null) _labelFilter = new System.Collections.Generic.Dictionary<string, bool>();
  1423. return _labelFilter;
  1424. }
  1425. set => _labelFilter = value;
  1426. }
  1427. private bool _updateLabelFilter = true;
  1428. public int filteredBrushListCount => filteredBrushList.Count;
  1429. public string filterText
  1430. {
  1431. get
  1432. {
  1433. if (_filterText == null) _filterText = string.Empty;
  1434. return _filterText;
  1435. }
  1436. set => _filterText = value;
  1437. }
  1438. private System.Collections.Generic.Dictionary<int, string[]> _hiddenFolders
  1439. = new System.Collections.Generic.Dictionary<int, string[]>();
  1440. private string[] hiddenFolders
  1441. {
  1442. get
  1443. {
  1444. if (_hiddenFolders.Count == 0 || !_hiddenFolders.ContainsKey(PaletteManager.selectedPaletteIdx))
  1445. return new string[] { };
  1446. return _hiddenFolders[PaletteManager.selectedPaletteIdx];
  1447. }
  1448. }
  1449. public static string[] GetHiddenFolders()
  1450. {
  1451. if (instance == null) return new string[] { };
  1452. return instance.hiddenFolders;
  1453. }
  1454. public static void SetHiddenFolders(string[] value)
  1455. {
  1456. if (instance == null) return;
  1457. if (instance._hiddenFolders.ContainsKey(PaletteManager.selectedPaletteIdx))
  1458. instance._hiddenFolders[PaletteManager.selectedPaletteIdx] = value;
  1459. else instance._hiddenFolders.Add(PaletteManager.selectedPaletteIdx, value);
  1460. instance.UpdateFilteredList(false);
  1461. RepainWindow();
  1462. }
  1463. private void ClearLabelFilter()
  1464. {
  1465. foreach (var key in labelFilter.Keys.ToArray()) labelFilter[key] = false;
  1466. }
  1467. private void SearchBar()
  1468. {
  1469. using (new GUILayout.HorizontalScope(UnityEditor.EditorStyles.toolbar))
  1470. {
  1471. GUILayout.FlexibleSpace();
  1472. using (var check = new UnityEditor.EditorGUI.ChangeCheckScope())
  1473. {
  1474. #if UNITY_2019_1_OR_NEWER
  1475. var searchFieldStyle = UnityEditor.EditorStyles.toolbarSearchField;
  1476. #else
  1477. var searchFieldStyle = EditorStyles.toolbarTextField;
  1478. #endif
  1479. GUILayout.Space(2);
  1480. filterText = UnityEditor.EditorGUILayout.TextField(filterText, searchFieldStyle).Trim();
  1481. if (check.changed) UpdateFilteredList(true);
  1482. }
  1483. if (filterText != string.Empty)
  1484. {
  1485. if (GUILayout.Button(_clearFilterIcon, UnityEditor.EditorStyles.toolbarButton))
  1486. {
  1487. filterText = string.Empty;
  1488. ClearLabelFilter();
  1489. UpdateFilteredList(true);
  1490. GUI.FocusControl(null);
  1491. }
  1492. }
  1493. if (GUILayout.Button(_labelIcon, UnityEditor.EditorStyles.toolbarButton))
  1494. {
  1495. GUI.FocusControl(null);
  1496. UpdateLabelFilter();
  1497. var menu = new UnityEditor.GenericMenu();
  1498. if (labelFilter.Count == 0)
  1499. menu.AddItem(new GUIContent("No labels Found"), false, null);
  1500. else
  1501. foreach (var labelItem in labelFilter.OrderBy(item => item.Key))
  1502. menu.AddItem(new GUIContent(labelItem.Key), labelItem.Value,
  1503. SelectLabelFilter, labelItem.Key);
  1504. menu.ShowAsContext();
  1505. }
  1506. if (GUILayout.Button(_selectionFilterIcon, UnityEditor.EditorStyles.toolbarButton))
  1507. {
  1508. GUI.FocusControl(null);
  1509. FilterBySelection();
  1510. }
  1511. if (GUILayout.Button(_folderFilterIcon, UnityEditor.EditorStyles.toolbarButton))
  1512. {
  1513. FilterByFolderWindow.ShowWindow();
  1514. }
  1515. }
  1516. if (_updateLabelFilter)
  1517. {
  1518. _updateLabelFilter = false;
  1519. UpdateLabelFilter();
  1520. }
  1521. if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
  1522. {
  1523. GUI.FocusControl(null);
  1524. Repaint();
  1525. }
  1526. }
  1527. private bool FilteredListContains(int index)
  1528. {
  1529. foreach (var filtered in filteredBrushList)
  1530. {
  1531. if (filtered.index == index) return true;
  1532. }
  1533. return false;
  1534. }
  1535. private void UpdateFilteredList(bool textCanged)
  1536. {
  1537. filteredBrushList.Clear();
  1538. void RemoveFromSelection(int index)
  1539. {
  1540. PaletteManager.RemoveFromSelection(index);
  1541. if (PaletteManager.selectedBrushIdx == index) PaletteManager.selectedBrushIdx = -1;
  1542. if (PaletteManager.selectionCount == 1)
  1543. PaletteManager.selectedBrushIdx = PaletteManager.idxSelection[0];
  1544. }
  1545. //filter by label
  1546. var filterTextArray = filterText.Split(',');
  1547. var filterTextSet = new System.Collections.Generic.List<string>();
  1548. ClearLabelFilter();
  1549. bool filterByLabel = false;
  1550. for (int i = 0; i < filterTextArray.Length; ++i)
  1551. {
  1552. var filterText = filterTextArray[i].Trim();
  1553. if (filterText.Length >= 2 && filterText.Substring(0, 2) == "l:")
  1554. {
  1555. filterText = filterText.Substring(2);
  1556. if (labelFilter.ContainsKey(filterText))
  1557. {
  1558. labelFilter[filterText] = true;
  1559. filterByLabel = true;
  1560. }
  1561. else return;
  1562. continue;
  1563. }
  1564. filterTextSet.Add(filterText);
  1565. }
  1566. var tempFilteredBrushList = new System.Collections.Generic.HashSet<FilteredBrush>();
  1567. var brushes = PaletteManager.selectedPalette.brushes;
  1568. if (!filterByLabel)
  1569. for (int i = 0; i < brushes.Length; ++i)
  1570. {
  1571. if (brushes[i].containMissingPrefabs) continue;
  1572. tempFilteredBrushList.Add(new FilteredBrush(brushes[i], i));
  1573. }
  1574. else
  1575. {
  1576. for (int i = 0; i < brushes.Length; ++i)
  1577. {
  1578. var brush = brushes[i];
  1579. if (brush.containMissingPrefabs) continue;
  1580. bool itemContainsFilter = false;
  1581. foreach (var item in brush.items)
  1582. {
  1583. if (item.prefab == null) continue;
  1584. var labels = UnityEditor.AssetDatabase.GetLabels(item.prefab);
  1585. foreach (var label in labels)
  1586. {
  1587. if (labelFilter[label])
  1588. {
  1589. itemContainsFilter = true;
  1590. break;
  1591. }
  1592. }
  1593. if (itemContainsFilter) break;
  1594. }
  1595. if (itemContainsFilter) tempFilteredBrushList.Add(new FilteredBrush(brush, i));
  1596. else RemoveFromSelection(i);
  1597. }
  1598. }
  1599. if (tempFilteredBrushList.Count == 0) return;
  1600. //filter by name
  1601. var listIsEmpty = filterTextSet.Count == 0;
  1602. if (!listIsEmpty)
  1603. {
  1604. listIsEmpty = true;
  1605. foreach (var filter in filterTextSet)
  1606. {
  1607. if (filter != string.Empty)
  1608. {
  1609. listIsEmpty = false;
  1610. break;
  1611. }
  1612. }
  1613. }
  1614. if (!listIsEmpty)
  1615. {
  1616. foreach (var filteredItem in tempFilteredBrushList.ToArray())
  1617. {
  1618. for (int i = 0; i < filterTextSet.Count; ++i)
  1619. {
  1620. var filterText = filterTextSet[i].Trim();
  1621. bool wholeWordOnly = false;
  1622. if (filterText == string.Empty) continue;
  1623. if (filterText.Length >= 2 && filterText.Substring(0, 2) == "w:")
  1624. {
  1625. wholeWordOnly = true;
  1626. filterText = filterText.Substring(2);
  1627. }
  1628. if (filterText == string.Empty) continue;
  1629. filterText = filterText.ToLower();
  1630. var brush = filteredItem.brush;
  1631. if ((!wholeWordOnly && brush.name.ToLower().Contains(filterText))
  1632. || (wholeWordOnly && brush.name.ToLower() == filterText))
  1633. tempFilteredBrushList.Add(filteredItem);
  1634. else
  1635. {
  1636. if(tempFilteredBrushList.Contains(filteredItem)) tempFilteredBrushList.Remove(filteredItem);
  1637. RemoveFromSelection(filteredItem.index);
  1638. }
  1639. }
  1640. }
  1641. }
  1642. if (tempFilteredBrushList.Count == 0) return;
  1643. // Filter by folder
  1644. foreach (var filteredItem in tempFilteredBrushList.ToArray())
  1645. {
  1646. var brushItems = filteredItem.brush.items;
  1647. foreach (var brushItem in brushItems)
  1648. {
  1649. if (filteredBrushList.Contains(filteredItem)) continue;
  1650. if (hiddenFolders.Any(filter => brushItem.prefabPath.StartsWith(filter)))
  1651. RemoveFromSelection(filteredItem.index);
  1652. else filteredBrushList.Add(filteredItem);
  1653. }
  1654. }
  1655. }
  1656. private void UpdateLabelFilter()
  1657. {
  1658. foreach (var brush in PaletteManager.selectedPalette.brushes)
  1659. {
  1660. foreach (var item in brush.items)
  1661. {
  1662. if (item.prefab == null) continue;
  1663. var labels = UnityEditor.AssetDatabase.GetLabels(item.prefab);
  1664. foreach (var label in labels)
  1665. {
  1666. if (labelFilter.ContainsKey(label)) continue;
  1667. labelFilter.Add(label, false);
  1668. }
  1669. }
  1670. }
  1671. }
  1672. private void SelectLabelFilter(object key)
  1673. {
  1674. labelFilter[(string)key] = !labelFilter[(string)key];
  1675. foreach (var pair in labelFilter)
  1676. {
  1677. if (!pair.Value) continue;
  1678. var labelFilter = "l:" + pair.Key;
  1679. if (filterText.Contains(labelFilter)) continue;
  1680. if (filterText.Length > 0) filterText += ", ";
  1681. filterText += labelFilter;
  1682. }
  1683. var filterTextArray = filterText.Split(',');
  1684. filterText = string.Empty;
  1685. for (int i = 0; i < filterTextArray.Length; ++i)
  1686. {
  1687. var filter = filterTextArray[i].Trim();
  1688. if (filter.Length >= 2 && filter.Substring(0, 2) == "l:")
  1689. {
  1690. var label = filter.Substring(2);
  1691. if (!labelFilter.ContainsKey(label)) continue;
  1692. if (!labelFilter[label]) continue;
  1693. if (filterText.Contains(filter)) continue;
  1694. }
  1695. if (filter == string.Empty) continue;
  1696. filterText += filter + ", ";
  1697. }
  1698. if (filterText != string.Empty) filterText = filterText.Substring(0, filterText.Length - 2);
  1699. UpdateFilteredList(false);
  1700. Repaint();
  1701. }
  1702. public int FilterBySelection()
  1703. {
  1704. var selection = SelectionManager.GetSelectionPrefabs();
  1705. filterText = string.Empty;
  1706. for (int i = 0; i < selection.Length; ++i)
  1707. {
  1708. filterText += "w:" + selection[i].name;
  1709. if (i < selection.Length - 1) filterText += ", ";
  1710. }
  1711. UpdateFilteredList(false);
  1712. return filteredBrushListCount;
  1713. }
  1714. public void SelectFirstBrush()
  1715. {
  1716. if (filteredBrushListCount == 0) return;
  1717. DeselectAllButThis(filteredBrushList[0].index);
  1718. }
  1719. #endregion
  1720. }
  1721. }