complete layered WPF migration and retire legacy runtime#4
complete layered WPF migration and retire legacy runtime#4PhantornRU wants to merge 45 commits intomainfrom
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 512ae90322
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 46a9af9cb5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ebe4e14d07
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Да, заюзали чтобы быстрее всё это переработать из-за нехватки времени. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a0ffd3f0b2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| session.LoadAsset(loadResult.Value); | ||
| workspaceService.Load(loadResult.Value); |
There was a problem hiding this comment.
Reject incompatible DMI when a config is already active
After loading a DMI, this path always updates the session asset without checking compatibility against session.CurrentConfig. If a user loads a config first and then opens a DMI with different resolution/direction depth, the workspace keeps an incompatible config in memory; subsequent preview/batch operations fail with compatibility errors and the editor surface can stay based on the stale config contract instead of the newly opened asset. LoadDmiFileUseCase should validate (or clear) the active config when the loaded asset changes.
Useful? React with 👍 / 👎.
| LastLandmarkState: null, | ||
| LastOverlayState: null, | ||
| LastSelectedDirection: null, | ||
| LastOverwritePolicy: OverwritePolicy.OverwriteExisting); |
There was a problem hiding this comment.
Default empty workspace settings to a non-destructive policy
WorkspaceSettings.Empty initializes LastOverwritePolicy to OverwriteExisting, and LoadWorkspaceSettingsUseCase returns this value when no settings file exists. On first launch, batch mode is therefore preconfigured to overwrite outputs, which can silently replace prior exports if the user runs a batch without changing policy. This is inconsistent with other defaults in the migration (SkipExisting) and creates avoidable data-loss risk.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ac2e500ef8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (!string.IsNullOrWhiteSpace(ConfigPath) && File.Exists(ConfigPath)) | ||
| { | ||
| var configResult = await _loadConfigUseCase.ExecuteAsync(ConfigPath, CancellationToken.None); | ||
| if (configResult.IsFailure) |
There was a problem hiding this comment.
Restore legacy CSV config when rebuilding startup workspace
RestoreWorkspaceAsync only reloads ConfigPath and never falls back to LegacyCsvPath, even though ApplyWorkspaceSettings and BuildWorkspaceSettings persist LastImportedLegacyCsvPath. In the common case where a user imported a legacy CSV and did not save a JSON, restarting the app drops the active config instead of restoring it, so the workspace opens without the mappings the user last used.
Useful? React with 👍 / 👎.
Сделал Stage 1 presentation-only проход поверх текущего mixed worktree. В [MainWindow.xaml](/d:/GitHub/AdaptiveSpritesDMItool/src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml#L432) редактор переведён в matrix-first layout: direct toolbar вместо selector-heavy полосы, убран global direction selector из normal matrix flow, включён horizontal scroll для матрицы, preview уехал в collapsible inspector, нижний workspace стал visible-by-default и разложен на одновременные `States / Config / Mappings` панели вместо tab-first drawer. В том же файле я ещё уплотнил direction tiles и сделал focused mode явно experimental с быстрым `Return to Matrix`. В [WorkspaceShellSections.cs](/d:/GitHub/AdaptiveSpritesDmiTool/src/AdaptiveSpritesDmiTool.Presentation.Wpf/WorkspaceShellSections.cs#L215) добавил только presentation glue для direct toolbar: computed selected-state flags, команды выбора tool/scope, более полезные status/lower-workspace summaries. В [MainWindowViewModel.Commands2.cs](/d:/GitHub/AdaptiveSpritesDmiTool/src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Commands2.cs#L337) появились минимальные команды выбора tool/scope без изменения semantics. В [MainWindowViewModel.Rendering.cs](/d:/GitHub/AdaptiveSpritesDmiTool/src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Rendering.cs#L38) lower workspace теперь раскрыт по умолчанию и workspace note приведён к parity-oriented формулировке. В [MainWindowViewModelSmokeTests.cs](/d:/GitHub/AdaptiveSpritesDmiTool/tests/AdaptiveSpritesDmiTool.Tests.Unit/Presentation/MainWindowViewModelSmokeTests.cs#L12) добавил точечные проверки на expanded lower workspace и direct toolbar selection glue. Проверка: `git diff --check` прошёл, кроме CRLF warning-ов. Полная пересборка через `dotnet build` / `dotnet msbuild` в этом окружении по-прежнему падает на project-reference resolution без вывода реальных compile/XAML errors, поэтому compile verification неполная. `dotnet test ... --no-build` отработал на существующих binaries и дал `39 passed`, но это не заменяет свежую rebuild-проверку. Остаточный риск: в worktree всё ещё лежат не мои mixed-scope изменения из Stage 2 / contract / settings path в [MainWindowViewModel.Commands.cs](/d:/GitHub/AdaptiveSpritesDmiTool/src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Commands.cs), [Contracts.cs](/d:/GitHub/AdaptiveSpritesDmiTool/src/AdaptiveSpritesDmiTool.Application/Contracts.cs), [UseCases.cs](/d:/GitHub/AdaptiveSpritesDmiTool/src/AdaptiveSpritesDmiTool.Application/UseCases.cs), [JsonWorkspaceSettingsRepository.cs](/d:/GitHub/AdaptiveSpritesDmiTool/src/AdaptiveSpritesDmiTool.Infrastructure/Settings/JsonWorkspaceSettingsRepository.cs). Их я не расширял, но перед Stage 2 branch всё ещё нужно чистить/сплитить по hunk map.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dc7235a8e2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| LegacyCsvPath = path; | ||
| DraftConfigName = result.Value.Name; |
There was a problem hiding this comment.
Clear stale save path when importing legacy CSV
After a successful legacy import, this path only updates LegacyCsvPath and leaves any existing JSON SaveConfigPath/ConfigPath intact. In the common flow where a JSON config was loaded first, SaveConfigAsync will reuse that stale save path (it only prompts when SaveConfigPath is empty), so saving the imported legacy config can silently overwrite an unrelated JSON file; resume logic also prioritizes ConfigPath over LegacyCsvPath, restoring the wrong config source.
Useful? React with 👍 / 👎.
| if (SelectedBatchSourceItem is not null && | ||
| BatchSourceTreeItems.All(item => !string.Equals(item.FullPath, SelectedBatchSourceItem.FullPath, StringComparison.OrdinalIgnoreCase))) | ||
| { |
There was a problem hiding this comment.
Keep nested batch selection when rebuilding source tree
This selection guard checks only the root-level BatchSourceTreeItems, but the batch picker builds nested children recursively. If a user selected a file inside a subfolder, any subsequent refresh will clear SelectedBatchSourceItem even though that file still exists, and RunBatchAsync then falls back to processing all files instead of the selected one, expanding batch scope unexpectedly.
Useful? React with 👍 / 👎.
Выполнен STAGE 1 presentation/layout revision без выхода в Stage 2 scope. Изменения: - В [`src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml) пересобран `Editor` layout в matrix-first схему: центральная матрица теперь доминирует, левый rail сужен, preview переведен в secondary panel, нижняя workspace area сделана always-visible вместо expander-first, toolbar уплотнен, тайлы и cell spacing уменьшены, визуальное разделение Source/Editable усилено, status bar упрощен, focused mode визуально демотирован внутри основного editor flow. - В [`src/AdaptiveSpritesDmiTool.Presentation.Wpf/WorkspaceShellSections.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/WorkspaceShellSections.cs) упрощены summary/status-facing строки, убран shell-first/staged tone, снижен шум в lower-workspace и status-facing presentation glue. - В [`src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs) закреплены parity-safe defaults: matrix mode как default path, нижняя workspace area visible-by-default, preview inspector недоминантен по default, стартовые workflow messages стали прямее и ближе к old editor flow. - В [`src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Commands2.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Commands2.cs) выполнен минимальный presentation-only cleanup статусов для viewport switching и убрана лишняя привязка к expand/collapse поведениям, без изменения tool semantics. - В [`src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Rendering.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Rendering.cs) синхронизированы reset/default/status/preview summaries под matrix-first workflow и менее staged presentation. - В [`tests/AdaptiveSpritesDmiTool.Tests.Unit/Presentation/MainWindowViewModelSmokeTests.cs`](tests/AdaptiveSpritesDmiTool.Tests.Unit/Presentation/MainWindowViewModelSmokeTests.cs) обновлено smoke-ожидание для нового default status message. Проверки: - `dotnet build AdaptiveSpritesDMItool.sln` — успешно. - `dotnet test tests/AdaptiveSpritesDmiTool.Tests.Unit/AdaptiveSpritesDmiTool.Tests.Unit.csproj --filter MainWindowViewModelSmokeTests` — 10/10 passed. Результат ревизии направлен именно на rollback toward old matrix-first UX: 4-direction workflow больше не подан как shell-first/scroll-first, нижняя рабочая зона возвращена в основной flow, preview перестал быть dominant rail, focused mode отведен на вторичный путь, toolbar и matrix стали плотнее и прямее.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 933b7a00ae
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (string.IsNullOrWhiteSpace(SaveConfigPath) && !string.IsNullOrWhiteSpace(DmiPath)) | ||
| { | ||
| SaveConfigPath = Path.ChangeExtension(DmiPath, ".json") ?? string.Empty; |
There was a problem hiding this comment.
Clear stale save path when creating a fresh config
CreateConfig keeps the previous SaveConfigPath unless it is blank, so a user who loaded old.json, then clicks “Create Config” and saves immediately will write the new blank config back to old.json without any prompt. This is a data-loss path because CreateConfigUseCase resets the active config to a new draft, but the persisted save target still points at the prior file.
Useful? React with 👍 / 👎.
|
|
||
| private static IEnumerable<BatchSourceTreeItemViewModel> BuildBatchSourceTreeItems(string rootDirectory) | ||
| { | ||
| foreach (var directory in Directory.EnumerateDirectories(rootDirectory).OrderBy(static path => path, StringComparer.OrdinalIgnoreCase)) |
There was a problem hiding this comment.
Catch access errors when enumerating batch source folders
BuildBatchSourceTreeItems recursively enumerates every child directory/file without handling UnauthorizedAccessException/IOException, so selecting or restoring an input folder that contains unreadable subfolders can throw during BatchInputDirectory updates on the UI thread and break the workspace flow. The tree builder should skip unreadable branches instead of letting enumeration exceptions escape.
Useful? React with 👍 / 👎.
Выполнен дополнительный Stage 1 correction pass. Что исправлено: - В [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml) центральной матрице отдано больше реальной площади: уменьшены боковые колонки, сокращена высота нижнего workspace блока, убран эффект «маленькой матрицы в большом контейнере». - В [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml) левый rail дополнительно сужен и возвращен к роли компактного state picker без лишнего summary-блока. - В [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml) убрано дублирование states между левым rail и нижней зоной: states оставлены слева, нижняя зона сфокусирована на config + mappings. - В [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml) preview дополнительно демотирован: панель уже, текстового шума меньше, визуальный приоритет снижен. - В [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml) `Focused` убран из primary toolbar flow и переведен во вторичный affordance рядом со status/hint line. - В [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml) matrix block больше не завязан на `Viewbox`-центрирование для normal matrix mode, поэтому он заполняет доступную editor area заметно агрессивнее. Что осталось в scope и не менялось: - Без правок [`MainWindow.xaml.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml.cs), [`MainWindowViewModel.Commands.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Commands.cs), [`MainWindowViewModel.Surface.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Surface.cs). - Без изменений application contracts, use-cases, preview builder и interaction semantics. - Без изменений Settings tab. Проверки: - `dotnet build AdaptiveSpritesDMItool.sln` — успешно. - `dotnet test tests/AdaptiveSpritesDmiTool.Tests.Unit/AdaptiveSpritesDmiTool.Tests.Unit.csproj --filter MainWindowViewModelSmokeTests` — успешно, 10/10 passed. Измененные файлы в этом correction pass: - [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml) - ранее подготовленные presentation-support изменения в [`WorkspaceShellSections.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/WorkspaceShellSections.cs), [`MainWindowViewModel.State.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs), [`MainWindowViewModel.Commands2.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Commands2.cs), [`MainWindowViewModel.Rendering.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Rendering.cs), [`MainWindowViewModelSmokeTests.cs`](tests/AdaptiveSpritesDmiTool.Tests.Unit/Presentation/MainWindowViewModelSmokeTests.cs). Итог: layout сдвинут еще ближе к old matrix-first UX — матрица крупнее, боковые и нижние зоны слабее давят на editor, preview и focused mode стали более вторичными, а экран распределяет место в пользу основной 4-direction рабочей области.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
1. Что изменено по layout - В [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml) editor workspace перестроен из статического `states | source | editable | directions` в адаптивную композицию: optional single-state strip, optional horizontal directions strip, adaptive central workspace и скрытый по умолчанию bottom dock. - Editable viewport теперь всегда является главным визуальным хостом: в default-сценарии отдельная source-колонка не занимает ширину, а compare/overlay режимы включаются явно. - Для compare режима добавлен resizable split между reference/source и editable в [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml). - Для 4-dir сценария directions перенесены в компактную горизонтальную полосу, для 8-dir+ сохранен правый vertical rail в [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml). 2. Какие новые VM flags / enum / commands добавлены - Добавлен enum [`EditorViewMode`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:9) с режимами [`EditableOnly`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:11), [`CompareSplit`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:12) и [`OverlayCompare`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:13). - Добавлены presentation flags [`IsEditableOnlyMode`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:266), [`IsCompareSplitMode`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:268), [`IsOverlayCompareMode`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:270), [`IsReferencePaneVisible`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:272), [`ShowOverlayCompareLayer`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:274), [`ShowStatesRail`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:282), [`ShowSingleStateStrip`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:284), [`UseHorizontalDirectionsStrip`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:286), [`UseVerticalDirectionsRail`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:288), [`HasDirectionSelector`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:290), [`CanFitViewport`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:298) и состояние [`isFocusMode`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:210). - Добавлены команды [`SetEditableOnlyMode()`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Commands2.cs:392), [`SetCompareSplitMode()`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Commands2.cs:395), [`SetOverlayCompareMode()`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Commands2.cs:398), [`ToggleFocusMode()`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Commands2.cs:401) и [`FitViewport()`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Commands2.cs:415). 3. Какие файлы затронуты - [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml) - [`MainWindowViewModel.State.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs) - [`MainWindowViewModel.Rendering.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Rendering.cs) - [`MainWindowViewModel.Commands.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Commands.cs) - [`MainWindowViewModel.Commands2.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Commands2.cs) - [`MainWindowViewModel.Surface.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Surface.cs) - [`WorkspaceShellSections.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/WorkspaceShellSections.cs) 4. Как теперь работает default editor mode - Default editor mode теперь идет через [`EditorViewMode`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:154) со стартовым значением [`EditableOnly`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:11). - После открытия DMI/конфига adaptive layout не показывает source pane постоянно; editable viewport сразу получает основную рабочую ширину. - Bottom dock остается скрытым по умолчанию, как и после первого этапа reset. 5. Как работает compare/overlay/focus - Compare mode включает отдельный source pane через [`IsReferencePaneVisible`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:272) и `GridSplitter` в [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml); editable остается шире source и split не 50/50. - Overlay mode не создает отдельную source-колонку, а рендерит presentation-only source overlay поверх editable host в [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml), не ломая существующий surface pipeline. - Focus mode переключается через [`ToggleFocusMode()`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Commands2.cs:401): скрывает states rail, directions selector, reference pane и принудительно оставляет bottom dock закрытым. 6. Как работает adaptive directions layout - Для 4 направлений включается [`UseHorizontalDirectionsStrip`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:286), и directions отображаются горизонтальной selector-strip над viewport в [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml). - Для наборов больше 4 включается [`UseVerticalDirectionsRail`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:288), и справа показывается vertical rail. - Для 0/1 направления selector вообще не расходует место через [`HasDirectionSelector`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:290). 7. Как работает single-state compaction - Полноценный left states rail теперь зависит от [`ShowStatesRail`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:282), то есть показывается только при multi-state workflow. - При single-state сценарии включается [`ShowSingleStateStrip`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:284), и вместо целой колонки рендерится компактная strip-row с текущим state и действиями Base/Landmark/Overlay/Clear в [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml). 8. Как реализован adaptive zoom / fit - Fit command идет через [`FitViewport()`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Commands2.cs:415), а доступность определяется флагом [`CanFitViewport`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:298). - Adaptive zoom bootstrap встроен в [`MainWindowViewModel.Rendering.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Rendering.cs) и вызывается после инициализации workspace, открытия DMI, загрузки JSON-конфига и импорта legacy CSV через [`MainWindowViewModel.Commands.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Commands.cs). - Эвристика основана на resolution: small sprites получают повышенный стартовый zoom, поэтому 32x32 больше не выглядит потерянным как на условных 100%. - Существующая zoom-модель не сломана: колесо мыши и [`ResetEditorZoom()`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Commands2.cs:422) продолжают работать поверх новой bootstrap-логики. 9. Результат сборки - Сборка [`AdaptiveSpritesDMItool.sln`](AdaptiveSpritesDMItool.sln) прошла успешно: `0 Warning(s), 0 Error(s)`. 10. Какие осознанные компромиссы остались - Overlay compare реализован как presentation-only visual overlay в [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml), а не как глубокий merge в render pipeline; это сохраняет behavior compatibility и не трогает domain/application/infrastructure. - Adaptive fit пока использует resolution-driven heuristic из [`MainWindowViewModel.Rendering.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.Rendering.cs), а не live viewport measurement по фактическому размеру host-контейнера. - Focus mode не сворачивает глобальный shell/navigation rail, чтобы не влезать глубже в navigation architecture; он ограничен editor-level compaction, чего достаточно для acceptance criteria второго этапа.
1. Audit summary - Убраны широкие верхние блоки из [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml): отдельная status-row, отдельная `State` row и full-width directions strip больше не являются default presentation path. - Из top area в left rail перенесены: - вертикальный список states, - selector `Base / Landmark / Overlay / Clear`, - medium `Source` pane, - selector directions. - Вниз, в secondary/status bar, перенесены: - active direction, - hover/selection summary, - sprite/config metadata, - `Composite`, - `Refresh`, - `Auto`, - zoom label, - reset zoom, - bottom dock toggle. - Новый layout ближе к legacy workflow, потому что теперь editor читается как: - сверху действия, - слева контекст редактирования, - по центру рабочее полотно, - снизу служебная строка. Это возвращает editable canvas в роль главного элемента окна. 2. Список измененных файлов с пояснением - [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml) — полностью пересобрана композиция `Editor` tab, новые sidebar/status templates и toolbar styles. - [`MainWindowViewModel.State.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs) — добавлены/уточнены layout flags для нового контракта editor shell. - [`WorkspaceShellSections.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/WorkspaceShellSections.cs) — проброшены новые presentation properties в editor-facing VM, добавлены compact labels для directions и state count. 3. Реализация - Верх editor-а ужат до одной primary toolbar row в [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml). - Введены новые стили: - [`EditorPrimaryToolbarButtonStyle`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml), - [`EditorPrimaryToolbarToggleStyle`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml), - [`EditorPrimaryToolbarCheckBoxStyle`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml), - [`SidebarSectionBorderStyle`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml), - [`StateListItemStyle`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml), - [`SidebarDirectionListBoxItemStyle`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml). - Добавлены templates: - [`StateSidebarItemTemplate`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml), - [`SidebarDirectionItemTemplate`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml). - Добавлены explicit layout flags в [`MainWindowViewModel.State.cs`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs): - [`ShowEditorLeftRail`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:283), - [`ShowStateLayersPanel`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:285), - [`ShowSourcePalettePane`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:287), - [`ShowDirectionsInSidebar`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:289), - [`ShowBottomStatusBar`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:291), - [`ShowCompactCanvasHeader`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindowViewModel.State.cs:293). - Эти flags проброшены в [`EditorWorkspaceViewModel`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/WorkspaceShellSections.cs:437). 4. Как теперь устроен left rail - Left rail теперь единый вертикальный sidebar фиксированной ширины в [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml). - Внутри него идут секции: - `States`, - `Target layer`, - `Source`, - `Directions`. - `States` показываются как вертикальный scrollable layers-like list, а не как горизонтальная полоса. - В заголовке states показывается summary через [`StateCountLabel`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/WorkspaceShellSections.cs:530). 5. Где теперь живет source/original pane - `Source/Original` теперь постоянно живет в left rail в виде medium preview-pane в [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml). - Это read-only/working reference для обычного `Edit` режима. - В `CompareSplit` дополнительно появляется отдельный compare-source surface в центральной области, то есть compare расширяет информацию, а не подменяет архитектуру sidebar. 6. Где теперь живет target layer selector - `Base / Landmark / Overlay / Clear` теперь находятся в секции `Target layer` внутри left rail в [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml). - Они больше не занимают отдельную широкую row над canvas. 7. Где теперь живут directions - Directions переехали в секцию `Directions` внутри left rail в [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml). - Используется компактный grid-паттерн через [`SidebarDirectionItemTemplate`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml) и [`SidebarDirectionListBoxItemStyle`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml). - Для short labels добавлено свойство [`ShortLabel`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/WorkspaceShellSections.cs:437) в item VM. - Full-width horizontal strip над canvas больше не является основным presentation path. 8. Что осталось в top toolbar - Вверху остались только primary editing controls: - tools, - scope, - view mode, - `Undo`, - `Redo`, - `Clear`, - `Fit`, - `Focus`. - Controls стали текстовыми/labeled, а не набором неочевидных анонимных glyph-кнопок. - Это реализовано в верхнем toolbar block в [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml). 9. Что уехало в bottom status bar - В нижнюю secondary/status bar editor-а переехали: - active direction, - hover/status summary, - sprite metadata, - config metadata, - preview mode combo, - `Refresh`, - `Auto`, - `Grid`, - `Overlay`, - zoom label, - `100%`, - `Bottom dock`. - Это собрано в bottom editor status bar внутри [`MainWindow.xaml`](src/AdaptiveSpritesDmiTool.Presentation.Wpf/MainWindow.xaml). 10. Manual verification checklist - single-state - states больше не раздуваются в wide horizontal strip - left rail остается компактным и читаемым - multi-state - states отображаются как вертикальный список - selection видна явно - 4-dir - directions живут в sidebar, не во full-width strip - 8-dir - directions продолжают работать через sidebar grid - Edit - left rail visible - medium source pane visible - editable canvas доминирует - Compare - left rail сохраняется - compare добавляет central reference pane - `GridSplitter` работает - Overlay - left rail сохраняется - source overlay остается поверх editable - Focus - left rail скрывается - bottom secondary bar скрывается - остается компактный toolbar + canvas - state selection - list selection остается рабочим через существующий binding - target layer selection - `Base/Landmark/Overlay/Clear` работают из sidebar - source/original visibility - source pane всегда виден в обычном `Edit` - status readability - статус/мета собраны внизу в одну строку - top toolbar compactness - больше нет 3–4 stacked rows над canvas - canvas vertical space increase - центральная рабочая область получила больше высоты, чем в предыдущем состоянии 11. Результат сборки - [`dotnet build AdaptiveSpritesDMItool.sln`](AdaptiveSpritesDMItool.sln) проходит успешно: `0 Warning(s), 0 Error(s)`.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fba8f00d34
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (_host is not null) | ||
| { | ||
| var viewModel = _host.Services.GetService<MainWindowViewModel>(); | ||
| viewModel?.PersistWorkspaceSettingsAsync().GetAwaiter().GetResult(); |
There was a problem hiding this comment.
Replace blocking shutdown settings flush
OnExit blocks the dispatcher with PersistWorkspaceSettingsAsync().GetAwaiter().GetResult(), but settings persistence is also triggered in fire-and-forget calls and waits on _workspaceSettingsPersistenceGate before saving. Because that wait captures the UI context, a pending persistence continuation can require the dispatcher to run in order to release the semaphore; blocking the dispatcher here can deadlock app shutdown and leave the window hanging during exit.
Useful? React with 👍 / 👎.
| OverlayStateName = settings.LastOverlayState ?? string.Empty; | ||
| SelectedDirection = settings.LastSelectedDirection ?? SelectedDirection; | ||
| SelectedOverwritePolicy = settings.LastOverwritePolicy; | ||
| SelectedEditorViewportMode = EditorViewportMode.Matrix; |
There was a problem hiding this comment.
Restore saved viewport mode from workspace settings
BuildWorkspaceSettings persists SelectedEditorViewportMode, but startup restore hard-codes SelectedEditorViewportMode = EditorViewportMode.Matrix instead of reading settings.LastEditorViewportMode. This means users always lose their last chosen viewport mode (e.g., Focused) after restart even though it is written to disk.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f559c773cd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (!Enum.TryParse<OverwritePolicy>(value, true, out var policy)) | ||
| { | ||
| throw new JsonException($"Unsupported overwrite policy '{value}'."); | ||
| } |
There was a problem hiding this comment.
Reject undefined overwrite policy values from settings
ParseOverwritePolicy accepts numeric strings because Enum.TryParse is used without checking Enum.IsDefined. A malformed settings file value like "99" is therefore treated as a valid enum and loaded into SelectedOverwritePolicy; later batch processing falls through the switch default path and behaves like overwrite mode, which can replace existing outputs unexpectedly. Validate that parsed enum values are defined members before accepting them.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5aec5350ad
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ConfigPath = string.Empty; | ||
| SaveConfigPath = string.Empty; | ||
| DraftConfigName = "Unsaved Draft"; | ||
| StatusMessage = "Removed the active config."; | ||
| RefreshWorkspaceState(); |
There was a problem hiding this comment.
Reset session config when removing final queue item
When the active queue item is removed and no DMI is loaded, this branch only clears ConfigPath/SaveConfigPath UI fields but leaves _editorSession.CurrentConfig intact. RefreshWorkspaceState() then calls RefreshConfigQueueItems(), and UpsertCurrentSessionIntoConfigQueue() re-creates a queue item from the still-active session config, so the removal effectively does not stick in config-only workflows. Clear the session config (or reset the session) before refreshing state.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 18d555d3e2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
|
|
||
| [RelayCommand] | ||
| private void SetEditableOnlyMode() => SetEditorViewMode(EditorViewMode.CompareSplit, "Dual workspace active."); |
There was a problem hiding this comment.
Switch editable-only command to EditableOnly mode
SetEditableOnlyMode currently passes EditorViewMode.CompareSplit, so triggering the "Editable only" action can never activate EditorViewMode.EditableOnly. In practice the UI stays in dual-pane mode and IsEditableOnlyMode-dependent bindings never become true, which breaks the mode switch behavior users expect.
Useful? React with 👍 / 👎.
|
|
||
| SelectedDirectionScope = scope; | ||
| } | ||
|
|
There was a problem hiding this comment.
Clear origin mappings when moving editable selections
The move workflow only applies mappings to translated coordinates and does not remove mappings from the original coordinates, so dragging a mapped pixel/area effectively copies it instead of moving it. This leaves stale mappings behind in the source area whenever the destination differs from the origin, contradicting the "Move" tool semantics.
Useful? React with 👍 / 👎.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
What changed
This PR completes the migration of AdaptiveSpritesDMItool from the legacy static-controller runtime to a production-grade layered WPF application.
The branch delivers:
Domain,Application,Infrastructure, andPresentation.WpfF5debug configurationWhy this changed
The legacy application mixed:
.dmiassetsThat architecture made the app hard to test, hard to extend, and unsafe to evolve. This PR moves the runtime to explicit contracts and layered ownership so that 4-dir and 8-dir workflows, preview generation, config persistence, and batch processing are deterministic and testable.
Changelog
Foundation
src/andtests/Domain + Application
Infrastructure
IDmiWritersupport viaDmiSharpConfigWriterJsonWorkspaceSettingsRepositoryWPF shell
Legacy removal + docs
README.md,README-ru.md,docs/CONFIG_FORMAT.md,docs/MIGRATION_GUIDE.md, anddocs/TEST_PLAN.mdFinal polish
.vscode/launch.jsonand.vscode/tasks.jsonfor one-stepF5debugging of the WPF shell in VS CodeUser impact
The app now starts with an empty workspace, lets users open a DMI manually, author/load/save JSON configs, import legacy CSV configs, preview base/landmark/overlay/composite states, and run deterministic batch processing without relying on legacy bundled assets or static controller state. Contributors also get a cleaner CI baseline and ready-to-use VS Code debug tasks.
Validation
Executed locally after the final polish commits:
dotnet build AdaptiveSpritesDMItool.sln -m:1 -v minimaldotnet test AdaptiveSpritesDMItool.sln -m:1 -v minimalResults:
0 warnings,0 errors)Commit breakdown
28bd3a6bootstrap layered solution foundation66d948cextract domain and application workflowsb47642badd infrastructure adapters and integration tests6c52281build empty-workspace WPF shellfa4b754add DMI writer and workspace settings pipeline30ff6e5complete MVVM shell batch and editor workflowded383dremove legacy runtime and refresh release docs1fef115clean test analyzer warnings512ae90add VS Code debug configurationResidual follow-up