gum-tool-delete-logic

$npx mdskill add vchelaru/Gum/gum-tool-delete-logic

Guide delete logic for Gum's two distinct object patterns.

  • Handles blocking conditions for states and categories before dialogs.
  • Integrates IEditCommands, IDeleteLogic, and plugin hooks.
  • Validates behavior dependencies and default-state checks first.
  • Executes undo locks and displays Yes/No or selection dialogs.

SKILL.md

.github/skills/gum-tool-delete-logicView on GitHub ↗
---
name: gum-tool-delete-logic
description: Reference guide for Gum's delete architecture. Load this when working on delete commands, IEditCommands delete methods, IDeleteLogic, DeleteLogic, DeleteOptionsWindow, HandleDeleteCommand, AskToDeleteState, AskToDeleteStateCategory, or DeleteSelection.
---

# Gum Delete Logic Reference

## Two Delete Patterns

There are two distinct delete flows depending on the object type being deleted.

### Pattern 1 — AskTo* (states and categories)

Used for states and state categories. These types have blocking conditions that must be checked before any dialog is shown, so they have their own typed methods on `IEditCommands`.

**Flow**: `IEditCommands.AskTo*` → validate (behavior deps, plugin hooks, default-state check) → simple Yes/No dialog → undo lock → `IDeleteLogic.Remove*`

**Entry points**:
- `IEditCommands.AskToDeleteState(stateSave, stateContainer)`
- `IEditCommands.AskToDeleteStateCategory(category, container)`

**Why not DeleteOptionsWindow**: States and categories are in-memory only — no XML files, no child hierarchy — so plugins have nothing to contribute to the delete dialog.

### Pattern 2 — DeleteSelection (elements, behaviors, instances)

Used for screens, components, behaviors, and instances. All go through one shared entry point that dispatches based on what is currently selected.

**Flow**: `IEditCommands.DeleteSelection` → undo lock → `IDeleteLogic.HandleDeleteCommand` → `DoDeletingLogic` → `ShowDeleteDialog` (creates `DeleteOptionsWindow`) → `IDeleteLogic.Remove*`

**Entry point**: `IEditCommands.DeleteSelection()`

**Why DeleteOptionsWindow**: Plugins contribute runtime UI to this dialog (e.g. `DeleteObjectPlugin` adds "Delete XML file?" and "Delete children?" options via the `DeleteOptionsWindowShow` plugin event).

## Responsibility Split

| Class | Responsibility |
|-------|---------------|
| `IEditCommands` / `EditCommands` | All user-triggered deletes. Shows dialogs, acquires undo locks, then delegates to `IDeleteLogic`. Only entry point callers should use. |
| `IDeleteLogic` / `DeleteLogic` | Pure data mutation after confirmation. `Remove*` methods do not show dialogs. `HandleDeleteCommand` is the exception — it orchestrates the DeleteOptionsWindow flow and is only called from `EditCommands.DeleteSelection`. |

## Callers

All delete actions funnel through `IEditCommands`:
- **Delete key** → `HotkeyManager` → `IEditCommands.DeleteSelection`
- **Element tree right-click Delete** → `ElementTreeViewManager` → `IEditCommands.DeleteSelection`
- **State tree right-click Delete state** → `StateTreeViewRightClickService` → `IEditCommands.AskToDeleteState`
- **State tree right-click Delete category** → `StateTreeViewRightClickService` → `IEditCommands.AskToDeleteStateCategory`
- **Menu strip Remove > Element** → `MenuStripManager` → `IEditCommands.DeleteSelection`
- **Menu strip Remove > State/Category** → `MenuStripManager` → `IEditCommands.AskToDeleteState` / `AskToDeleteStateCategory`

Do not call `IDeleteLogic` methods directly from UI code — always go through `IEditCommands`.

## Testability

`ShowDeleteDialog` creates a WPF `DeleteOptionsWindow` and calls `ShowDialog()` — it cannot be unit-tested directly. The `internal BuildDeleteDialogMessage(Array, List<InstanceSave>?)` method on `DeleteLogic` is the testable seam for asserting dialog message content (`InternalsVisibleTo("GumToolUnitTests")` is already configured).

## Key Files

| File | Purpose |
|------|---------|
| `Gum/Commands/IEditCommands.cs` | Interface with architecture overview comment |
| `Gum/Commands/EditCommands.cs` | Implementation; AskTo* dialog logic lives here |
| `Gum/Managers/IDeleteLogic.cs` | Interface for pure data-mutation operations |
| `Gum/Managers/DeleteLogic.cs` | Data mutation + DeleteOptionsWindow orchestration |
| `Gum/Logic/RenameLogic.cs` | `ElementReferences` class; `GetDeleteImpactDetails()` and `ExcludeContainersBeingDeleted()` used to build impact warnings in the delete dialog |
| `Gum/Plugins/InternalPlugins/Delete/DeleteObjectPlugin.cs` | Contributes "Delete XML?" and "Delete children?" to DeleteOptionsWindow |
| `Gum/Plugins/InternalPlugins/StatePlugin/StateTreeViewRightClickService.cs` | State/category right-click menu; calls AskTo* methods |
| `Gum/Plugins/InternalPlugins/TreeView/ElementTreeViewManager.RightClick.cs` | Element tree right-click; calls DeleteSelection |
| `Gum/Managers/HotkeyManager.cs` | Delete key handler; calls DeleteSelection |

More from vchelaru/Gum

SkillDescription
bump-nuget-versionBump the NuGet package versions for all 12 Gum projects (11 libraries + GumCli). Queries NuGet to check if a version exists for today, then sets the new version to YYYY.M.D.V where V increments from the latest published version today (or starts at 1). Creates a release branch named ReleaseCode_YYYY_M_D_V, commits the changes, and pushes. Run this before triggering the nuget release workflow.
gum-cliReference guide for GumCli — the headless command-line tool for Gum projects. Load this when working on gumcli commands (new, check, codegen, codegen-init), Gum.ProjectServices, HeadlessErrorChecker, ProjectLoader, HeadlessCodeGenerationService, CodeGenerationAutoSetupService, or the FormsTemplateCreator.
gum-docs-writingReference guide for writing Gum documentation in GitBook markdown. Load when writing or editing docs/ files, adding pages to SUMMARY.md, using GitBook hints/figures, linking between pages, or adding images.
gum-forms-behaviorsCovers Gum's behaviors system and the design-time → runtime Forms wrapping lifecycle. Load this when working on BehaviorSave, ElementBehaviorReference, StandardFormsBehaviorNames, FormsUtilities.RegisterFromFileFormRuntimeDefaults, DefaultFromFileXxxRuntime classes, or when investigating why Forms properties cannot be set at design time in the Gum tool.
gum-forms-controlsReference guide for Forms controls — classes inheriting from FrameworkElement. Load this when working on Button, CheckBox, ListBox, ComboBox, TextBox, ScrollViewer, or any class in Gum.Forms.Controls (or FlatRedBall.Forms.Controls). Also load when working on FrameworkElement itself, the Visual/InteractiveGue relationship, state machines, DefaultVisuals, or ReactToVisualChanged.
gum-forms-default-visualsReference guide for Forms DefaultVisuals — the code-only visual classes that back Forms controls. Load when working on ButtonVisual, any *Visual class in DefaultVisuals/, Styling, DefaultFormsTemplates registration, or building custom code-only Forms visuals.
gum-forms-itemscontrolReference guide for ItemsControl and ListBox — the Items/ListBoxItems relationship, templates, InnerPanel sync, and gotchas. Load this when working on ItemsControl, ListBox, ListBoxItem, VisualTemplate, FrameworkElementTemplate, Items collection behavior, ListBoxItems desync, or adding/removing items from a list box.
gum-layout>
gum-layout-engine>
gum-localizationReference guide for Gum's runtime localization system — ILocalizationService, CSV/RESX loading, Text vs TextNoTranslate paths, Forms control localization patterns, and gotchas.