# Editor Tooling

This page covers how to extend the Spark Editor with custom tabs, views, and property drawers for your plugin.

## The Spark Editor Window

The Spark Editor Window (`SparkEditorWindow`) is the central hub for managing game data. It uses a tabbed interface where each plugin adds its own tabs.

The window architecture:

1. **Sidebar**: Lists all plugin categories and their tabs.
2. **Content Area**: Displays the currently selected tab's content.
3. **Inspector Panel**: Shows the selected entry's fields for editing.

Tabs are loaded dynamically from plugin manifests.

## Creating Custom Editor Tabs

When you create a plugin manifest, you define tabs that appear in the Spark Editor. There are two tab types:

### Database Tabs

These show a list of database entries with CRUD (create, read, update, delete) operations. Most plugins use database tabs.

In your plugin manifest, configure a tab with:

* **Tab Type**: Database
* **Asset Type**: Your entry class (e.g., `FactionEntry`)
* **Path**: The Resources path where entries are stored

The Spark Editor automatically generates the list view, search, filtering, and inspector for database entries. Your entry's fields (with Spark attributes) render automatically.

### Plugin Settings Tabs

These show a single settings asset for plugin configuration. Used for plugins that need global settings rather than a list of entries.

In your plugin manifest, configure a tab with:

* **Tab Type**: PluginSettings
* **Asset Type**: Your settings class (inheriting `PluginSettingsBase`)

## Custom Editor Views

For more control over how your plugin appears in the Spark Editor, implement `ISparkPluginViewProvider`:

```csharp
public class FactionEditorView : SparkPluginViewProviderBase
{
    public override VisualElement CreateEditorView(PluginManifest manifest)
    {
        var root = new VisualElement();

        // Build custom UI using UI Toolkit
        var header = new Label("Faction Manager");
        header.AddToClassList("spark-header");
        root.Add(header);

        // Add custom controls, graphs, visualizations, etc.

        return root;
    }
}
```

`SparkPluginViewProviderBase` provides the scaffolding. Override `CreateEditorView()` to build your custom UI using Unity's UI Toolkit (VisualElements, UXML, USS).

## Plugin View Loader

The `SparkPluginViewLoader` handles dynamic loading of editor views. It finds the correct view provider for each tab based on assembly and type scanning.

## Custom Property Drawers

Spark includes several custom property drawers for its attributes. If you need custom rendering for a specific field type in your plugin, create a property drawer:

```csharp
[CustomPropertyDrawer(typeof(MyCustomAttribute))]
public class MyCustomDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        // Custom rendering logic
    }
}
```

### Built-in Drawers

Spark provides drawers for all its custom attributes:

* `ConditionalFieldDrawer`: Shows/hides fields based on conditions.
* `DatabaseEntryDropdownDrawer`: Renders entry selection dropdowns.
* `ReadOnlyDrawer`: Makes fields non-editable.
* `SectionDrawer`: Renders collapsible section headers.
* `SwitchDrawer`: Switches field layouts based on another field.

## Entry Selector Windows

The `SparkDatabaseEntrySelectorWindow` is a popup window for selecting database entries. It provides:

* Search by name
* Filtering by type
* Preview of entry details
* Quick creation of new entries

You can open this window from your custom editor code:

```csharp
SparkDatabaseEntrySelectorWindow.Show<FactionEntry>(
    selectedId: currentValue,
    onSelected: (entry) => { /* Handle selection */ });
```

## Editor Field Creation

The `EditorFields.CreateField()` utility creates appropriate editor fields based on the property type. It handles:

* Primitive types (int, float, string, bool)
* Unity types (Vector3, Color, Sprite, GameObject)
* Enum dropdowns
* Object references
* Collections (lists, arrays)
* Custom types with Spark attributes

Use this when building custom editor views to get consistent field rendering.

## UI Toolkit Patterns

Spark's editor UI uses Unity's UI Toolkit. Key patterns:

* **UXML templates**: Define layout structure.
* **USS stylesheets**: Define visual styling.
* **Element querying**: `root.Q<Label>("my-label")` to find elements.
* **Value change callbacks**: Bind to field changes for auto-saving.

```csharp
var nameField = new TextField("Faction Name");
nameField.RegisterValueChangedCallback(evt =>
{
    entry.name = evt.newValue;
    EditorUtility.SetDirty(entry);
});
root.Add(nameField);
```

## Extension Data Cleanup

The `ExtensionDataCleanupUtility` handles orphaned extension data. When a database entry is deleted, its extension data should be cleaned up. This utility scans for extension data whose target entries no longer exist.

## Best Practices

* Use database tabs for entry management. They come with free CRUD, search, and inspector.
* Only create custom views when you need non-standard UI (graphs, visualizations, drag-and-drop editors).
* Follow Spark's USS class naming for consistent styling.
* Use `EditorFields.CreateField()` for field rendering instead of building fields manually.
* Always mark assets dirty (`EditorUtility.SetDirty()`) when modifying them through custom editor code.
* Test your editor extensions with domain reload enabled to catch static state issues.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.sparkframework.dev/documentation/developer-guide/core-systems/editor-tooling.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
