mirror of
https://github.com/haven1433/HexManiacAdvance.git
synced 2026-10-02 05:06:35 -05:00
block editing
This commit is contained in:
@@ -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<byte[][]> BlocksChanged;
|
||||
public event EventHandler<byte[][]> 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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
<Grid Width="{Binding Blocks.ScaledWidth}" MinHeight="100" DockPanel.Dock="Top">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" MinHeight="112"/>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="75"/>
|
||||
</Grid.RowDefinitions>
|
||||
<CheckBox HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="10,10,10,35"
|
||||
<CheckBox HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="5,10,10,35"
|
||||
Content="Automatic Movement Permission" IsChecked="{Binding AutoUpdateCollision}" Grid.Row="1">
|
||||
<CheckBox.ToolTip>
|
||||
<TextBlock>
|
||||
@@ -49,13 +49,17 @@
|
||||
</TextBlock>
|
||||
</CheckBox.ToolTip>
|
||||
</CheckBox>
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="5,10" Grid.Row="1">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Left" Margin="0,10" Grid.Row="1">
|
||||
<local:AngleBorder Direction="Left" VerticalAlignment="Stretch">
|
||||
<TextBlock Text="Movement Permissions:" Margin="2,0" Height="30"/>
|
||||
</local:AngleBorder>
|
||||
<local:AngleComboBox Direction="Out" Width="50" Height="20"
|
||||
ItemsSource="{Binding CollisionOptions}" SelectedIndex="{Binding CollisionIndex}" />
|
||||
</StackPanel>
|
||||
<Decorator Grid.Row="1" Height="20" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="0,0,35,55" Visibility="{Binding BlockEditorVisible, Converter={StaticResource BoolToVisibility}}">
|
||||
<local:AngleButton DataContext="{Binding PrimaryMap.BlockEditor}" Content="Edit Tiles"
|
||||
Direction="Right" Padding="2,0" IsChecked="{Binding ShowTiles}" />
|
||||
</Decorator>
|
||||
<Decorator Visibility="{Binding DrawMultipleTiles, Converter={StaticResource BoolToVisibility}}" HorizontalAlignment="Center" VerticalAlignment="Top">
|
||||
<local:PixelImage DataContext="{Binding MultiTileDrawRender}" />
|
||||
</Decorator>
|
||||
@@ -539,8 +543,8 @@
|
||||
<!-- Tile Panel -->
|
||||
<Border DataContext="{Binding PrimaryMap.BlockEditor}" Grid.Column="1" Grid.RowSpan="2" Panel.ZIndex="3" HorizontalAlignment="Left"
|
||||
BorderBrush="{DynamicResource Backlight}" BorderThickness="1"
|
||||
Background="{DynamicResource Background}" Visibility="{Binding ShowTiles, Converter={StaticResource BoolToVisibility}}">
|
||||
<DockPanel Name="TilePanel" Width="400">
|
||||
Background="{DynamicResource Background}">
|
||||
<DockPanel Name="TilePanel" Width="400" HorizontalAlignment="Right">
|
||||
<Button Command="{res:MethodCommand HideTiles}" Width="20" Height="20" DockPanel.Dock="Top" HorizontalAlignment="Right" Margin="1">
|
||||
<Path Data="{res:Icon Exit}" Fill="{DynamicResource Secondary}" Stretch="Fill" />
|
||||
</Button>
|
||||
@@ -548,15 +552,67 @@
|
||||
<ScrollViewer Name="TileViewer" VerticalAlignment="Top">
|
||||
<Grid HorizontalAlignment="Left">
|
||||
<local:PixelImage x:Name="TileImage" DataContext="{Binding TileRender}" MouseDown="TilesDown" TransparentBrush="{DynamicResource Background}" />
|
||||
<Rectangle Name="TileSelectionRect" StrokeThickness="1" Opacity=".5" Width="24" Height="24" HorizontalAlignment="Left" VerticalAlignment="Top"
|
||||
Stroke="{DynamicResource Background}" Fill="{DynamicResource Primary}" IsHitTestVisible="False">
|
||||
<Rectangle.RenderTransform>
|
||||
<TranslateTransform X="{Binding TileSelectionX}" Y="{Binding TileSelectionY}" />
|
||||
</Rectangle.RenderTransform>
|
||||
</Rectangle>
|
||||
<ContentControl HorizontalAlignment="Left" VerticalAlignment="Top" IsHitTestVisible="False">
|
||||
<ContentControl.Template>
|
||||
<ControlTemplate>
|
||||
<Rectangle StrokeThickness="1" Opacity=".5" Width="24" Height="24" RenderTransformOrigin=".5,.5"
|
||||
Stroke="{DynamicResource Background}" Fill="{DynamicResource Primary}">
|
||||
<Rectangle.RenderTransform>
|
||||
<TransformGroup>
|
||||
<ScaleTransform x:Name="SelectionScale" />
|
||||
<TranslateTransform X="{Binding TileSelectionX}" Y="{Binding TileSelectionY}" />
|
||||
</TransformGroup>
|
||||
</Rectangle.RenderTransform>
|
||||
</Rectangle>
|
||||
<ControlTemplate.Triggers>
|
||||
<DataTrigger Binding="{Binding TileSelectionToggle}" Value="True">
|
||||
<DataTrigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="SelectionScale" Storyboard.TargetProperty="ScaleX" From="3" To="1" Duration="0:0:.5" DecelerationRatio="1" />
|
||||
<DoubleAnimation Storyboard.TargetName="SelectionScale" Storyboard.TargetProperty="ScaleY" From="3" To="1" Duration="0:0:.5" DecelerationRatio="1" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.EnterActions>
|
||||
<DataTrigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="SelectionScale" Storyboard.TargetProperty="ScaleX" From="3" To="1" Duration="0:0:.5" DecelerationRatio="1" />
|
||||
<DoubleAnimation Storyboard.TargetName="SelectionScale" Storyboard.TargetProperty="ScaleY" From="3" To="1" Duration="0:0:.5" DecelerationRatio="1" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.ExitActions>
|
||||
</DataTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</ContentControl.Template>
|
||||
</ContentControl>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</DockPanel>
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Width" Value="0" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding ShowTiles}" Value="True">
|
||||
<DataTrigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation DecelerationRatio="1" Duration="0:0:0.3" Storyboard.TargetProperty="Width" To="402" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.EnterActions>
|
||||
<DataTrigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation DecelerationRatio="1" Duration="0:0:0.3" Storyboard.TargetProperty="Width" To="0" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.ExitActions>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
</Border>
|
||||
|
||||
<!-- Toolbar -->
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user