Game.UI.Editor.DirectoryBrowserPanel
Assembly: Assembly-CSharp (Game assembly for Cities: Skylines 2 mods)
Namespace: Game.UI.Editor
Type: class
Base: DirectoryPanelBase
Summary:
DirectoryBrowserPanel is a UI panel used by the in-game editor for browsing and selecting directories on disk. It builds a hierarchical view of drives and folders, supports searching (via base search adapter), can limit navigation depth to a provided root path, and calls back when the user selects or cancels. The panel handles inaccessible directories gracefully by using EnumerationOptions.IgnoreInaccessible and logs exceptions via DirectoryPanelBase.log.
Fields
-
public delegate void SelectCallback(string directory)
Used to define the callback signature invoked when a directory is selected. The argument is the selected directory path (with trailing '/'). -
private readonly SelectCallback m_SelectCallback
Callback provided in the constructor that will be invoked when the user confirms a directory selection. -
private readonly Action m_OnCloseDirectoryBrowser
Cancel callback provided in the constructor; executed when the user cancels/ closes the browser. -
private string m_SelectedDirectory
Current selected directory path (normalized with forward slashes and trailing '/'). Updated when navigating or selecting folders. -
private string m_RootDirectory
Optional root directory path used when limiting navigation depth. The constructor appends a trailing '/' to the provided root. -
private bool m_LimitDepthToRoot
When true, navigation is restricted down to m_RootDirectory; back navigation from the root is disabled. -
private const
/other inherited fields (not declared in this class)
Note: The panel uses members from DirectoryPanelBase (m_Items, m_Directories, m_Stack, m_Pages, m_PageView, etc.) to construct and manage the UI; those are not re-declared here.
Properties
- None declared on DirectoryBrowserPanel itself. (UI/state is exposed via fields and the base class API.)
Constructors
public DirectoryBrowserPanel(string directory, string root, SelectCallback onSelect, Action onCancel)
Creates a directory browser panel.- directory: initial directory to open (may be null). The constructor will walk up parent directories until it finds an existing directory if the passed value does not exist.
- root: optional root path to limit navigation to; if non-empty, the panel will set m_LimitDepthToRoot = true and append a trailing '/' to the root path.
- onSelect: callback invoked with the selected directory path when the user confirms.
- onCancel: callback invoked when the user cancels/closes the panel.
- Behavior: the constructor lists available drives (ListDrives) and attempts to traverse to the provided initial directory (TraverseToDirectory). Any ArgumentException encountered while traversing is logged.
Methods
-
private bool ImportNotReady()
Stub placeholder that currently always returns true. Intended to indicate whether import operations are ready/allowed. Not used elsewhere in this class. -
private void ImportAssets()
Empty stub. Placeholder for importing assets from a selected directory. -
private void TraverseToDirectory(string directory)
Walks up from the provided directory to the filesystem root, collects each segment, and calls ShowSubDir progressively for each cumulative path (so UI pages are built from root toward the target directory). Uses DirectoryInfo and appends folder names with '/' while calling ShowSubDir. -
private void ListDrives()
Enumerates system drives via DriveInfo.GetDrives(). For each drive: - Creates a DirectoryInfo based on drive.VolumeLabel (note: uses the VolumeLabel as a parentDir identifier).
- Uses GetDirectories with EnumerationOptions { IgnoreInaccessible = true } to avoid exceptions for protected folders.
- Constructs Item objects describing each top-level directory found and calls ListItems("Editor.DRIVES", list).
- Calls ShowSubDir(null) after listing drives to initialize the view.
-
Catches and ignores IOExceptions thrown by DriveInfo/Directory enumerations.
-
private void ListItems(string directory, List<Item> items)
Populates the panel with a mixed set of Items and synthesized directory entries: - If items is empty, returns early.
- Clears m_Directories and sets m_Items to the provided list.
- Builds and registers intermediate parent directory entries (m_Directories) from each item's parentDir by splitting on '/' and creating entries for each cumulative path segment. LocalizedString.Value is used to set display names for those synthetic directory entries.
- Adds synthesized directories to m_Items, sorts items, sets panel title to "Editor.OPEN_DIRECTORY", and constructs the children widgets:
- SearchField (adapter = this)
- PageView for pages
- "Editor.SELECT_DIRECTORY" Button wired to OnSelectDirectory, disabled by DirectoryNotSelectedOrRootSelected
- "Common.CANCEL" Button wired to m_OnCloseDirectoryBrowser
-
The resulting children replace the panel's UI layout and controls.
-
private bool DirectoryNotSelectedOrRootSelected()
Used by the Select button to determine enabled state: - Returns true (disabled) if no directory is selected.
-
If a directory is selected, returns true (disabled) when the selected directory equals the root directory and navigation is limited (i.e., selection of the root is prevented in that case); otherwise returns false.
-
private void OnSelectDirectory()
Invokes m_SelectCallback with m_SelectedDirectory. Called when the user confirms selection via the select button. -
public override void OnSelect(Item item)
Called when the user selects an item in the UI list: -
If item is non-null, calls ShowSubDir(...) to navigate into the selected folder. Uses item.fullName (if present) with trailing '/' otherwise uses item.name + '/'.
-
protected override void OnBack()
Handles page back-navigation: - If more than one page on the stack, pops the last stack entry and page, clears the selectedItem of the new last page, updates m_SelectedDirectory from the new last stack entry.
- If navigation is limited to root and new selected directory equals m_RootDirectory, disables the back action on the top PageLayout.
-
Updates m_PageView.children and currentPage accordingly.
-
protected override void ShowSubDir(string dir)
Primary method for populating page contents for a directory: - If dir is null or empty, calls base.ShowSubDir(dir) and returns.
- Sets m_SelectedDirectory to dir, clears m_Items, enumerates immediate subdirectories using new DirectoryInfo(dir).GetDirectories("*", new EnumerationOptions { IgnoreInaccessible = true }).
- For each subdirectory, creates an Item describing it, sets parentDir, fullName (normalized with forward slashes), tooltip = full path, and adds it to the list.
- Determines whether each listed directory has children by enumerating its own GetDirectories(...) and sets item.directory accordingly. Also adds the child directories as Item entries (with parentDir set to directoryInfo.Name) so the page shows both leaf and nested entries for easier navigation.
- If the collected list is empty, returns early. Otherwise calls ListItems(dir, list).
- Catches and logs exceptions via DirectoryPanelBase.log.Error with the directory context.
- After calling base.ShowSubDir(dir), if navigation is limited and the selected directory equals the root directory, disables the backAction on the current PageLayout.
Notes and implementation details: - Paths are normalized to use forward slashes and trailing '/' is used consistently for stored directory paths. - EnumerationOptions.IgnoreInaccessible is used to avoid throwing exceptions on protected/system folders; nevertheless, exceptions are caught and logged. - The class relies on DirectoryPanelBase for much of the UI machinery (m_PageView, m_Stack, m_Pages, base.title, base.children, etc.).
Usage Example
// Example: open a directory browser starting at "C:/Users/Example/Documents",
// limit navigation to "C:/Users/Example", and handle selection/cancel.
void OpenDirectoryBrowser()
{
string startDir = @"C:/Users/Example/Documents";
string rootLimit = @"C:/Users/Example"; // pass null or empty to allow full navigation
DirectoryBrowserPanel.SelectCallback onSelect = selectedDir =>
{
Debug.Log("User selected directory: " + selectedDir);
// selectedDir ends with a '/' and uses forward slashes.
};
Action onCancel = () =>
{
Debug.Log("Directory selection canceled.");
};
var panel = new DirectoryBrowserPanel(startDir, rootLimit, onSelect, onCancel);
// Add panel to the UI container or open it according to the editor UI flow.
}
If you want, I can also produce a shorter quick-reference summary listing only public behaviors and important caveats (like path normalization and root-limiting behavior).