From 37f167356d7b8a53b6e1d8fba151ca403d8f200e Mon Sep 17 00:00:00 2001 From: haven1433 Date: Sat, 8 Oct 2022 23:49:48 -0500 Subject: [PATCH] block editing --- .../ViewModels/Map/BlockEditor.cs | 15 +++- .../ViewModels/Map/BlockMapViewModel.cs | 7 ++ .../ViewModels/Map/MapEditorViewModel.cs | 10 +++ src/HexManiac.WPF/Controls/MapTab.xaml | 78 ++++++++++++++++--- src/HexManiac.WPF/Controls/MapTab.xaml.cs | 9 +++ .../Controls/SelectedBlockEditor.xaml.cs | 5 +- 6 files changed, 108 insertions(+), 16 deletions(-) diff --git a/src/HexManiac.Core/ViewModels/Map/BlockEditor.cs b/src/HexManiac.Core/ViewModels/Map/BlockEditor.cs index f1b2b241..72789c0d 100644 --- a/src/HexManiac.Core/ViewModels/Map/BlockEditor.cs +++ b/src/HexManiac.Core/ViewModels/Map/BlockEditor.cs @@ -10,6 +10,7 @@ using System.Collections.ObjectModel; using System.Configuration; using System.Diagnostics; using System.Linq; +using System.Windows; /* #define MB_NORMAL 0x00 @@ -374,6 +375,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map { }; } + public event EventHandler AutoscrollTiles; public event EventHandler BlocksChanged; public event EventHandler BlockAttributesChanged; @@ -445,10 +447,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map { } public void DrawOnTile(IPixelViewModel tile) { - if (!showTiles) { - ShowTiles = true; - return; - } + if (!showTiles) return; var index = indexForTileImage[tile]; LzTilemapRun.WriteTileData(blocks[blockIndex], index, drawPalette, drawFlipH, drawFlipV, drawTile); var newImage = BlocksetModel.Read(blocks[blockIndex], index, tiles, palettes); @@ -465,6 +464,8 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map { drawFlipH = hFlip; drawPalette = pal; NotifyPropertiesChanged(nameof(TileSelectionX), nameof(TileSelectionY), nameof(PaletteSelection)); + AutoscrollTiles.Raise(this); + AnimateTileSelection(); } public void ExitTiles() { @@ -550,6 +551,12 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map { public void HideTiles() => ShowTiles = false; + // hack: a DataTrigger can watch this property and start an animation whenever this property changes. + // the value doesn't matter, just the change + private bool tileSelectionToggle; + public bool TileSelectionToggle { get => tileSelectionToggle; set => Set(ref tileSelectionToggle, value); } + private void AnimateTileSelection() => TileSelectionToggle = !TileSelectionToggle; + private int drawTile, drawPalette; private bool drawFlipV, drawFlipH; public int TileSelectionX { diff --git a/src/HexManiac.Core/ViewModels/Map/BlockMapViewModel.cs b/src/HexManiac.Core/ViewModels/Map/BlockMapViewModel.cs index 320a8057..dd77ce6b 100644 --- a/src/HexManiac.Core/ViewModels/Map/BlockMapViewModel.cs +++ b/src/HexManiac.Core/ViewModels/Map/BlockMapViewModel.cs @@ -313,6 +313,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map { #endregion public event EventHandler NeighborsChanged; + public event EventHandler AutoscrollTiles; private BlockEditor blockEditor; public BlockEditor BlockEditor { @@ -328,6 +329,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map { blockEditor = new BlockEditor(model, palettes, tiles, blocks, blockAttributes); blockEditor.BlocksChanged += HandleBlocksChanged; blockEditor.BlockAttributesChanged += HandleBlockAttributesChanged; + BlockEditor.AutoscrollTiles += HandleAutoscrollTiles; } return blockEditor; } @@ -387,6 +389,9 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map { RefreshMapSize(); if (blockEditor != null) { var selection = blockEditor.BlockIndex; + blockEditor.BlocksChanged -= HandleBlocksChanged; + blockEditor.BlockAttributesChanged -= HandleBlockAttributesChanged; + BlockEditor.AutoscrollTiles -= HandleAutoscrollTiles; blockEditor = null; NotifyPropertyChanged(nameof(BlockEditor)); BlockEditor.BlockIndex = selection; @@ -1401,6 +1406,8 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map { BlockmapRun.WriteBlockAttributes(tokenFactory(), blockModel1, blockModel2, attributes); } + private void HandleAutoscrollTiles(object sender, EventArgs e) => AutoscrollTiles.Raise(this); + public static string MapIDToText(IDataModel model, int id) { var group = id / 1000; var map = id % 1000; diff --git a/src/HexManiac.Core/ViewModels/Map/MapEditorViewModel.cs b/src/HexManiac.Core/ViewModels/Map/MapEditorViewModel.cs index e5c20826..1ac2861a 100644 --- a/src/HexManiac.Core/ViewModels/Map/MapEditorViewModel.cs +++ b/src/HexManiac.Core/ViewModels/Map/MapEditorViewModel.cs @@ -209,6 +209,10 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map { #endregion + public event EventHandler AutoscrollTiles; + + #region Constructor + public static bool TryCreateMapEditor(IFileSystem fileSystem, IEditableViewPort viewPort, Singletons singletons, out MapEditorViewModel editor) { editor = null; var maps = viewPort.Model.GetTable(HardcodeTablesModel.MapBankTable); @@ -231,6 +235,8 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map { for (int i = 0; i < 0x40; i++) CollisionOptions.Add(i.ToString("X2")); } + #endregion + public void SwitchToViewPortOnNextBackNavigation() { backStack.Add(-1); if (backStack.Count == 1) backCommand.RaiseCanExecuteChanged(); @@ -258,6 +264,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map { primaryMap.NeighborsChanged -= PrimaryMapNeighborsChanged; primaryMap.PropertyChanged -= PrimaryMapPropertyChanged; primaryMap.CollisionHighlight = -1; + primaryMap.AutoscrollTiles -= HandleAutoscrollTiles; } primaryMap = map; primaryMap.BlockEditor.BlockIndex = drawBlockIndex; @@ -266,6 +273,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map { primaryMap.NeighborsChanged += PrimaryMapNeighborsChanged; primaryMap.PropertyChanged += PrimaryMapPropertyChanged; primaryMap.CollisionHighlight = collisionIndex; + primaryMap.AutoscrollTiles += HandleAutoscrollTiles; } NotifyPropertyChanged(nameof(Blocks)); NotifyPropertyChanged(nameof(Name)); @@ -848,6 +856,8 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map { return combined; } + private void HandleAutoscrollTiles(object sender, EventArgs e) => AutoscrollTiles.Raise(this); + private int GetPreferredCollision(int tile) { if (preferredCollisionsPrimary == null) CountCollisionForBlocks(); int[] preference; diff --git a/src/HexManiac.WPF/Controls/MapTab.xaml b/src/HexManiac.WPF/Controls/MapTab.xaml index 510f791c..abe08914 100644 --- a/src/HexManiac.WPF/Controls/MapTab.xaml +++ b/src/HexManiac.WPF/Controls/MapTab.xaml @@ -37,9 +37,9 @@ - + - @@ -49,13 +49,17 @@ - + + + + @@ -539,8 +543,8 @@ - + Background="{DynamicResource Background}"> + @@ -548,15 +552,67 @@ - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/HexManiac.WPF/Controls/MapTab.xaml.cs b/src/HexManiac.WPF/Controls/MapTab.xaml.cs index 4473e400..21d41e73 100644 --- a/src/HexManiac.WPF/Controls/MapTab.xaml.cs +++ b/src/HexManiac.WPF/Controls/MapTab.xaml.cs @@ -25,11 +25,13 @@ namespace HavenSoft.HexManiac.WPF.Controls { if (oldContext != null) { oldContext.PropertyChanged -= HandleContextPropertyChanged; oldContext.AutoscrollBlocks -= AutoscrollBlocks; + oldContext.AutoscrollTiles -= AutoscrollTiles; } var newContext = e.NewValue as MapEditorViewModel; if (newContext != null) { newContext.PropertyChanged += HandleContextPropertyChanged; newContext.AutoscrollBlocks += AutoscrollBlocks; + newContext.AutoscrollTiles += AutoscrollTiles; } } @@ -44,6 +46,13 @@ namespace HavenSoft.HexManiac.WPF.Controls { BlockViewer.ScrollToVerticalOffset(scrollRange * scrollPercent); } + private void AutoscrollTiles(object sender, EventArgs e) { + var scrollRange = TileViewer.ExtentHeight - TileViewer.ViewportHeight; + var tileHeight = ViewModel.PrimaryMap.BlockEditor.TileRender.PixelHeight * 3 - 24; + var scrollPercent = (ViewModel.PrimaryMap.BlockEditor.TileSelectionY / (double)tileHeight).LimitToRange(0, 1); + TileViewer.ScrollToVerticalOffset(scrollRange * scrollPercent); + } + protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) { base.OnRenderSizeChanged(sizeInfo); var partial = ActualWidth / 2 - (int)(ActualWidth / 2); diff --git a/src/HexManiac.WPF/Controls/SelectedBlockEditor.xaml.cs b/src/HexManiac.WPF/Controls/SelectedBlockEditor.xaml.cs index 1213df72..37fc26d7 100644 --- a/src/HexManiac.WPF/Controls/SelectedBlockEditor.xaml.cs +++ b/src/HexManiac.WPF/Controls/SelectedBlockEditor.xaml.cs @@ -1,12 +1,15 @@ using HavenSoft.HexManiac.Core.ViewModels.Images; using HavenSoft.HexManiac.Core.ViewModels.Map; +using System; using System.Windows; using System.Windows.Input; namespace HavenSoft.HexManiac.WPF.Controls { public partial class SelectedBlockEditor { private BlockEditor ViewModel => (BlockEditor)DataContext; - public SelectedBlockEditor() => InitializeComponent(); + public SelectedBlockEditor() { + InitializeComponent(); + } private void WheelOverImage(object sender, MouseWheelEventArgs e) { ViewModel.LayerMode = (ViewModel.LayerMode + 1) % 3;