/// <summary> /// Attempts to find a resource tile element with the specified path. /// </summary> /// <param name="path">Project library path to the element.</param> /// <param name="entry">Found element, or null if none found.</param> /// <returns>True if an element was found, false otherwise.</returns> public bool TryGetEntry(string path, out LibraryGUIEntry entry) { return(entryLookup.TryGetValue(path, out entry)); }
/// <summary> /// Attempts to find a resource tile element with the specified path. /// </summary> /// <param name="path">Project library path to the element.</param> /// <param name="entry">Found element, or null if none found.</param> /// <returns>True if an element was found, false otherwise.</returns> public bool TryGetEntry(string path, out LibraryGUIEntry entry) { return entryLookup.TryGetValue(path, out entry); }
/// <summary> /// Refreshes the contents of the content area. Must be called at least once after construction. /// </summary> /// <param name="viewType">Determines how to display the resource tiles.</param> /// <param name="entriesToDisplay">Project library entries to display.</param> /// <param name="bounds">Bounds within which to lay out the content entries.</param> public void Refresh(ProjectViewType viewType, LibraryEntry[] entriesToDisplay, Rect2I bounds) { if (mainPanel != null) { mainPanel.Destroy(); } entries.Clear(); entryLookup.Clear(); mainPanel = parent.Layout.AddPanel(); GUIPanel contentPanel = mainPanel.AddPanel(1); overlay = mainPanel.AddPanel(0); underlay = mainPanel.AddPanel(2); deepUnderlay = mainPanel.AddPanel(3); renameOverlay = mainPanel.AddPanel(-1); main = contentPanel.AddLayoutY(); List <ResourceToDisplay> resourcesToDisplay = new List <ResourceToDisplay>(); foreach (var entry in entriesToDisplay) { if (entry.Type == LibraryEntryType.Directory) { resourcesToDisplay.Add(new ResourceToDisplay(entry.Path, LibraryGUIEntryType.Single)); } else { FileEntry fileEntry = (FileEntry)entry; ResourceMeta[] metas = fileEntry.ResourceMetas; if (metas.Length > 0) { if (metas.Length == 1) { resourcesToDisplay.Add(new ResourceToDisplay(entry.Path, LibraryGUIEntryType.Single)); } else { resourcesToDisplay.Add(new ResourceToDisplay(entry.Path, LibraryGUIEntryType.MultiFirst)); for (int i = 1; i < metas.Length - 1; i++) { string path = Path.Combine(entry.Path, metas[i].SubresourceName); resourcesToDisplay.Add(new ResourceToDisplay(path, LibraryGUIEntryType.MultiElement)); } string lastPath = Path.Combine(entry.Path, metas[metas.Length - 1].SubresourceName); resourcesToDisplay.Add(new ResourceToDisplay(lastPath, LibraryGUIEntryType.MultiLast)); } } } } if (viewType == ProjectViewType.List16) { tileSize = 16; gridLayout = false; elementsPerRow = 1; horzElementSpacing = 0; int elemWidth = bounds.width; int elemHeight = tileSize; main.AddSpace(TOP_MARGIN); for (int i = 0; i < resourcesToDisplay.Count; i++) { ResourceToDisplay entry = resourcesToDisplay[i]; LibraryGUIEntry guiEntry = new LibraryGUIEntry(this, main, entry.path, i, elemWidth, elemHeight, entry.type); entries.Add(guiEntry); entryLookup[guiEntry.path] = guiEntry; if (i != resourcesToDisplay.Count - 1) { main.AddSpace(LIST_ENTRY_SPACING); } } main.AddFlexibleSpace(); } else { int elemWidth = 0; int elemHeight = 0; int vertElemSpacing = 0; switch (viewType) { case ProjectViewType.Grid64: tileSize = 64; elemWidth = tileSize; elemHeight = tileSize + 36; horzElementSpacing = 10; vertElemSpacing = 12; break; case ProjectViewType.Grid48: tileSize = 48; elemWidth = tileSize; elemHeight = tileSize + 36; horzElementSpacing = 8; vertElemSpacing = 10; break; case ProjectViewType.Grid32: tileSize = 32; elemWidth = tileSize + 16; elemHeight = tileSize + 48; horzElementSpacing = 6; vertElemSpacing = 10; break; } gridLayout = true; int availableWidth = bounds.width; elementsPerRow = MathEx.FloorToInt((availableWidth - horzElementSpacing) / (float)(elemWidth + horzElementSpacing)); elementsPerRow = Math.Max(elementsPerRow, 1); int numRows = MathEx.CeilToInt(resourcesToDisplay.Count / (float)elementsPerRow); int neededHeight = numRows * elemHeight + TOP_MARGIN; if (numRows > 0) { neededHeight += (numRows - 1) * vertElemSpacing; } bool requiresScrollbar = neededHeight > bounds.height; if (requiresScrollbar) { availableWidth -= parent.ScrollBarWidth; elementsPerRow = MathEx.FloorToInt((availableWidth - horzElementSpacing) / (float)(elemWidth + horzElementSpacing)); elementsPerRow = Math.Max(elementsPerRow, 1); } int extraRowSpace = availableWidth - (elementsPerRow * (elemWidth + horzElementSpacing) + horzElementSpacing); main.AddSpace(TOP_MARGIN); GUILayoutX rowLayout = main.AddLayoutX(); rowLayout.AddSpace(horzElementSpacing); int elemsInRow = 0; for (int i = 0; i < resourcesToDisplay.Count; i++) { if (elemsInRow == elementsPerRow && elemsInRow > 0) { main.AddSpace(vertElemSpacing); rowLayout.AddSpace(extraRowSpace); rowLayout = main.AddLayoutX(); rowLayout.AddSpace(horzElementSpacing); elemsInRow = 0; } ResourceToDisplay entry = resourcesToDisplay[i]; LibraryGUIEntry guiEntry = new LibraryGUIEntry(this, rowLayout, entry.path, i, elemWidth, elemHeight, entry.type); entries.Add(guiEntry); entryLookup[guiEntry.path] = guiEntry; rowLayout.AddSpace(horzElementSpacing); elemsInRow++; } int extraElements = elementsPerRow - elemsInRow; rowLayout.AddSpace((elemWidth + horzElementSpacing) * extraElements + extraRowSpace); main.AddFlexibleSpace(); } for (int i = 0; i < entries.Count; i++) { LibraryGUIEntry guiEntry = entries[i]; guiEntry.Initialize(); } }
/// <summary> /// Refreshes the contents of the content area. Must be called at least once after construction. /// </summary> /// <param name="viewType">Determines how to display the resource tiles.</param> /// <param name="entriesToDisplay">Project library entries to display.</param> /// <param name="bounds">Bounds within which to lay out the content entries.</param> public void Refresh(ProjectViewType viewType, LibraryEntry[] entriesToDisplay, Rect2I bounds) { if (mainPanel != null) mainPanel.Destroy(); entries.Clear(); entryLookup.Clear(); mainPanel = parent.Layout.AddPanel(); GUIPanel contentPanel = mainPanel.AddPanel(1); overlay = mainPanel.AddPanel(0); underlay = mainPanel.AddPanel(2); deepUnderlay = mainPanel.AddPanel(3); renameOverlay = mainPanel.AddPanel(-1); main = contentPanel.AddLayoutY(); List<ResourceToDisplay> resourcesToDisplay = new List<ResourceToDisplay>(); foreach (var entry in entriesToDisplay) { if (entry.Type == LibraryEntryType.Directory) resourcesToDisplay.Add(new ResourceToDisplay(entry.Path, LibraryGUIEntryType.Single)); else { FileEntry fileEntry = (FileEntry)entry; ResourceMeta[] metas = fileEntry.ResourceMetas; if (metas.Length > 0) { if (metas.Length == 1) resourcesToDisplay.Add(new ResourceToDisplay(entry.Path, LibraryGUIEntryType.Single)); else { resourcesToDisplay.Add(new ResourceToDisplay(entry.Path, LibraryGUIEntryType.MultiFirst)); for (int i = 1; i < metas.Length - 1; i++) { string path = Path.Combine(entry.Path, metas[i].SubresourceName); resourcesToDisplay.Add(new ResourceToDisplay(path, LibraryGUIEntryType.MultiElement)); } string lastPath = Path.Combine(entry.Path, metas[metas.Length - 1].SubresourceName); resourcesToDisplay.Add(new ResourceToDisplay(lastPath, LibraryGUIEntryType.MultiLast)); } } } } if (viewType == ProjectViewType.List16) { tileSize = 16; gridLayout = false; elementsPerRow = 1; horzElementSpacing = 0; int elemWidth = bounds.width; int elemHeight = tileSize; main.AddSpace(TOP_MARGIN); for (int i = 0; i < resourcesToDisplay.Count; i++) { ResourceToDisplay entry = resourcesToDisplay[i]; LibraryGUIEntry guiEntry = new LibraryGUIEntry(this, main, entry.path, i, elemWidth, elemHeight, entry.type); entries.Add(guiEntry); entryLookup[guiEntry.path] = guiEntry; if (i != resourcesToDisplay.Count - 1) main.AddSpace(LIST_ENTRY_SPACING); } main.AddFlexibleSpace(); } else { int elemWidth = 0; int elemHeight = 0; int vertElemSpacing = 0; switch (viewType) { case ProjectViewType.Grid64: tileSize = 64; elemWidth = tileSize; elemHeight = tileSize + 36; horzElementSpacing = 10; vertElemSpacing = 12; break; case ProjectViewType.Grid48: tileSize = 48; elemWidth = tileSize; elemHeight = tileSize + 36; horzElementSpacing = 8; vertElemSpacing = 10; break; case ProjectViewType.Grid32: tileSize = 32; elemWidth = tileSize + 16; elemHeight = tileSize + 48; horzElementSpacing = 6; vertElemSpacing = 10; break; } gridLayout = true; int availableWidth = bounds.width; elementsPerRow = MathEx.FloorToInt((availableWidth - horzElementSpacing) / (float)(elemWidth + horzElementSpacing)); elementsPerRow = Math.Max(elementsPerRow, 1); int numRows = MathEx.CeilToInt(resourcesToDisplay.Count / (float)elementsPerRow); int neededHeight = numRows * elemHeight + TOP_MARGIN; if (numRows > 0) neededHeight += (numRows - 1)* vertElemSpacing; bool requiresScrollbar = neededHeight > bounds.height; if (requiresScrollbar) { availableWidth -= parent.ScrollBarWidth; elementsPerRow = MathEx.FloorToInt((availableWidth - horzElementSpacing) / (float)(elemWidth + horzElementSpacing)); elementsPerRow = Math.Max(elementsPerRow, 1); } int extraRowSpace = availableWidth - (elementsPerRow * (elemWidth + horzElementSpacing) + horzElementSpacing); main.AddSpace(TOP_MARGIN); GUILayoutX rowLayout = main.AddLayoutX(); rowLayout.AddSpace(horzElementSpacing); int elemsInRow = 0; for (int i = 0; i < resourcesToDisplay.Count; i++) { if (elemsInRow == elementsPerRow && elemsInRow > 0) { main.AddSpace(vertElemSpacing); rowLayout.AddSpace(extraRowSpace); rowLayout = main.AddLayoutX(); rowLayout.AddSpace(horzElementSpacing); elemsInRow = 0; } ResourceToDisplay entry = resourcesToDisplay[i]; LibraryGUIEntry guiEntry = new LibraryGUIEntry(this, rowLayout, entry.path, i, elemWidth, elemHeight, entry.type); entries.Add(guiEntry); entryLookup[guiEntry.path] = guiEntry; rowLayout.AddSpace(horzElementSpacing); elemsInRow++; } int extraElements = elementsPerRow - elemsInRow; rowLayout.AddSpace((elemWidth + horzElementSpacing) * extraElements + extraRowSpace); main.AddFlexibleSpace(); } for (int i = 0; i < entries.Count; i++) { LibraryGUIEntry guiEntry = entries[i]; guiEntry.Initialize(); } }
/// <summary> /// Stops the rename operation, if one is in progress on any element. /// </summary> internal void StopRename() { if (inProgressRenameElement != null) { inProgressRenameElement.StopRename(); inProgressRenameElement = null; } }
/// <summary> /// Starts a rename operation on the currently selected elements. If more than one elements are selected only the /// first one will be affected. /// </summary> internal void RenameSelection() { string[] filePaths = GetFiles(selectionPaths); if (filePaths.Length == 0) return; if (filePaths.Length > 1) { DeselectAll(); Select(filePaths[0]); } LibraryGUIEntry entry; if (content.TryGetEntry(filePaths[0], out entry)) { entry.StartRename(); inProgressRenameElement = entry; } }
/// <summary> /// Rebuilds the library window GUI. Should be called any time the active folder or contents change. /// </summary> private void Refresh() { requiresRefresh = false; LibraryEntry[] entriesToDisplay = new LibraryEntry[0]; if (IsSearchActive) { entriesToDisplay = ProjectLibrary.Search("*" + searchQuery + "*"); } else { DirectoryEntry entry = ProjectLibrary.GetEntry(CurrentFolder) as DirectoryEntry; if (entry == null) { CurrentFolder = ProjectLibrary.Root.Path; entry = ProjectLibrary.GetEntry(CurrentFolder) as DirectoryEntry; } if(entry != null) entriesToDisplay = entry.Children; } inProgressRenameElement = null; RefreshDirectoryBar(); SortEntries(entriesToDisplay); Rect2I visibleContentBounds = GetScrollAreaBounds(); content.Refresh(viewType, entriesToDisplay, visibleContentBounds); foreach (var path in cutPaths) content.MarkAsCut(path, true); foreach (var path in selectionPaths) content.MarkAsSelected(path, true); content.MarkAsPinged(pingPath, true); Rect2I contentBounds = content.Bounds; contentBounds.height = Math.Max(contentBounds.height, visibleContentBounds.height); GUIButton catchAll = new GUIButton("", EditorStyles.Blank); catchAll.Bounds = contentBounds; catchAll.OnClick += OnCatchAllClicked; catchAll.SetContextMenu(entryContextMenu); content.Underlay.AddElement(catchAll); Rect2I focusBounds = contentBounds; // Contents + Folder bar Rect2I scrollBounds = contentScrollArea.Bounds; focusBounds.x += scrollBounds.x; focusBounds.y += scrollBounds.y; Rect2I folderBarBounds = folderListLayout.Bounds; focusBounds.y -= folderBarBounds.height; focusBounds.height += folderBarBounds.height; GUIButton focusCatcher = new GUIButton("", EditorStyles.Blank); focusCatcher.Blocking = false; focusCatcher.OnFocusGained += () => hasContentFocus = true; focusCatcher.OnFocusLost += () => hasContentFocus = false; focusCatcher.Bounds = focusBounds; GUIPanel focusPanel = GUI.AddPanel(-3); focusPanel.AddElement(focusCatcher); UpdateDragSelection(dragSelectionEnd); }
/// <summary> /// Refreshes the contents of the content area. Must be called at least once after construction. /// </summary> /// <param name="viewType">Determines how to display the resource tiles.</param> /// <param name="entriesToDisplay">Project library entries to display.</param> public void Refresh(ProjectViewType viewType, LibraryEntry[] entriesToDisplay) { if (mainPanel != null) { mainPanel.Destroy(); } entries = new LibraryGUIEntry[entriesToDisplay.Length]; entryLookup.Clear(); mainPanel = parent.Layout.AddPanel(); GUIPanel contentPanel = mainPanel.AddPanel(1); overlay = mainPanel.AddPanel(0); underlay = mainPanel.AddPanel(2); renameOverlay = mainPanel.AddPanel(-1); main = contentPanel.AddLayoutY(); if (viewType == ProjectViewType.List16) { tileSize = 16; gridLayout = false; elementsPerRow = 1; } else { switch (viewType) { case ProjectViewType.Grid64: tileSize = 64; break; case ProjectViewType.Grid48: tileSize = 48; break; case ProjectViewType.Grid32: tileSize = 32; break; } gridLayout = true; Rect2I scrollBounds = parent.Bounds; int availableWidth = scrollBounds.width; int elemSize = tileSize + GRID_ENTRY_SPACING; elementsPerRow = (availableWidth - GRID_ENTRY_SPACING * 2) / elemSize; elementsPerRow = Math.Max(elementsPerRow, 1); int numRows = MathEx.CeilToInt(entriesToDisplay.Length / (float)elementsPerRow); int neededHeight = numRows * (elemSize); bool requiresScrollbar = neededHeight > scrollBounds.height; if (requiresScrollbar) { availableWidth -= parent.ScrollBarWidth; elementsPerRow = (availableWidth - GRID_ENTRY_SPACING * 2) / elemSize; } if (elementsPerRow > 0) { labelWidth = (availableWidth - (elementsPerRow + 1) * MIN_HORZ_SPACING) / elementsPerRow; } else { labelWidth = 0; } } if (viewType == ProjectViewType.List16) { for (int i = 0; i < entriesToDisplay.Length; i++) { LibraryGUIEntry guiEntry = new LibraryGUIEntry(this, main, entriesToDisplay[i], i, labelWidth); entries[i] = guiEntry; entryLookup[guiEntry.path] = guiEntry; if (i != entriesToDisplay.Length - 1) { main.AddSpace(LIST_ENTRY_SPACING); } } main.AddFlexibleSpace(); } else { main.AddSpace(GRID_ENTRY_SPACING / 2); GUILayoutX rowLayout = main.AddLayoutX(); main.AddSpace(GRID_ENTRY_SPACING); rowLayout.AddFlexibleSpace(); int elemsInRow = 0; for (int i = 0; i < entriesToDisplay.Length; i++) { if (elemsInRow == elementsPerRow && elemsInRow > 0) { rowLayout = main.AddLayoutX(); main.AddSpace(GRID_ENTRY_SPACING); rowLayout.AddFlexibleSpace(); elemsInRow = 0; } LibraryGUIEntry guiEntry = new LibraryGUIEntry(this, rowLayout, entriesToDisplay[i], i, labelWidth); entries[i] = guiEntry; entryLookup[guiEntry.path] = guiEntry; rowLayout.AddFlexibleSpace(); elemsInRow++; } int extraElements = elementsPerRow - elemsInRow; for (int i = 0; i < extraElements; i++) { rowLayout.AddSpace(labelWidth); rowLayout.AddFlexibleSpace(); } main.AddFlexibleSpace(); } for (int i = 0; i < entries.Length; i++) { LibraryGUIEntry guiEntry = entries[i]; guiEntry.Initialize(); } }