From 5123140377d09d6a2499c7c4ffe7c8dc01b5a5c4 Mon Sep 17 00:00:00 2001 From: BinaryConstruct Date: Tue, 9 Jul 2024 23:48:28 -0500 Subject: [PATCH] initial editing in TEditAvalonia --- src/TEdit.Desktop/App.axaml.cs | 2 +- .../Controls/SkiaWorldRenderBox.cs | 8 +- .../WorldRenderEngine/IRasterTileCache.cs | 2 + .../Layers/WorldPixelsCustomDrawOp.cs | 7 ++ .../WorldRenderEngine/RasterTileCache.cs | 6 ++ src/TEdit.Desktop/Editor/IMouseTool.cs | 85 ++++++++++++++++++- src/TEdit.Editor/ToolDefaultData.cs | 42 ++++----- src/TEdit.Editor/WorldEditor.cs | 12 +++ 8 files changed, 138 insertions(+), 26 deletions(-) diff --git a/src/TEdit.Desktop/App.axaml.cs b/src/TEdit.Desktop/App.axaml.cs index 5275adcf..e2099275 100644 --- a/src/TEdit.Desktop/App.axaml.cs +++ b/src/TEdit.Desktop/App.axaml.cs @@ -32,7 +32,7 @@ public override void Initialize() services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); + //services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/src/TEdit.Desktop/Controls/SkiaWorldRenderBox.cs b/src/TEdit.Desktop/Controls/SkiaWorldRenderBox.cs index 0e86a70d..8e74976b 100644 --- a/src/TEdit.Desktop/Controls/SkiaWorldRenderBox.cs +++ b/src/TEdit.Desktop/Controls/SkiaWorldRenderBox.cs @@ -1270,7 +1270,7 @@ private void ViewPortOnPointerPressed(object? sender, PointerPressedEventArgs e) if (ActiveTool != null) { ActiveTool?.Press(WorldEditor, pointer, WorldCoordinate); - + _pixelTileCache.SetPixelDirty((int)WorldCoordinate.X, (int)WorldCoordinate.Y); } if (SelectionMode != SelectionModes.None) @@ -1314,7 +1314,11 @@ private void ViewPortOnPointerMoved(object? sender, PointerEventArgs e) (double wcX, double wcY) = PointToImage(_pointerPosition, true); WorldCoordinate = new Point((int)wcX, (int)wcY); // cast to int - ActiveTool?.Move(WorldEditor, pointer, WorldCoordinate); + if (ActiveTool != null) + { + ActiveTool?.Move(WorldEditor, pointer, WorldCoordinate); + _pixelTileCache.SetPixelDirty((int)WorldCoordinate.X, (int)WorldCoordinate.Y); + } if (!_isPanning && !_isSelecting) { diff --git a/src/TEdit.Desktop/Controls/WorldRenderEngine/IRasterTileCache.cs b/src/TEdit.Desktop/Controls/WorldRenderEngine/IRasterTileCache.cs index 129761ca..3fa6f417 100644 --- a/src/TEdit.Desktop/Controls/WorldRenderEngine/IRasterTileCache.cs +++ b/src/TEdit.Desktop/Controls/WorldRenderEngine/IRasterTileCache.cs @@ -10,6 +10,8 @@ public interface IRasterTileCache : IDisposable RasterTile? GetTile(int x, int y); void Clear(); + void SetPixelDirty(int x, int y); + int TileSize { get; } int TilesX { get; } diff --git a/src/TEdit.Desktop/Controls/WorldRenderEngine/Layers/WorldPixelsCustomDrawOp.cs b/src/TEdit.Desktop/Controls/WorldRenderEngine/Layers/WorldPixelsCustomDrawOp.cs index d8a3cb98..9aeb22c9 100644 --- a/src/TEdit.Desktop/Controls/WorldRenderEngine/Layers/WorldPixelsCustomDrawOp.cs +++ b/src/TEdit.Desktop/Controls/WorldRenderEngine/Layers/WorldPixelsCustomDrawOp.cs @@ -29,6 +29,13 @@ private static TEditColor GetBackgroundColor(World _world, int y) return WorldConfiguration.GlobalColors["Sky"]; } + public static SKColor GetBlockColor(World _world, int currentBlockX, int currentBlockY) + { + var block = _world.Tiles[currentBlockX, currentBlockY]; + var bgColor = GetBackgroundColor(_world, currentBlockY); + return PixelMap.GetTileColor(block, bgColor).ToSKColor().WithAlpha(255); + } + public static SKBitmap CreateBitmapTile(World _world, int xTile, int yTile, int tileSize) { ArgumentNullException.ThrowIfNull(_world); diff --git a/src/TEdit.Desktop/Controls/WorldRenderEngine/RasterTileCache.cs b/src/TEdit.Desktop/Controls/WorldRenderEngine/RasterTileCache.cs index c2b048fb..0874a46b 100644 --- a/src/TEdit.Desktop/Controls/WorldRenderEngine/RasterTileCache.cs +++ b/src/TEdit.Desktop/Controls/WorldRenderEngine/RasterTileCache.cs @@ -67,6 +67,12 @@ public int PixelToTileIndex(int worldPixelX, int worldPixelY) return tileIndex; } + public void SetPixelDirty(int x, int y) + { + (int tileIndex, int tilePixelX, int tilePixelY) = PixelToTilePixelIndex(x, y); + _tiles[tileIndex].IsDirty = true; + } + private (int tileIndex, int tilePixelX, int tilePixelY) PixelToTilePixelIndex(int worldPixelX, int worldPixelY) { int curTileX = worldPixelX / TileSize; diff --git a/src/TEdit.Desktop/Editor/IMouseTool.cs b/src/TEdit.Desktop/Editor/IMouseTool.cs index 5b2221dc..c165e061 100644 --- a/src/TEdit.Desktop/Editor/IMouseTool.cs +++ b/src/TEdit.Desktop/Editor/IMouseTool.cs @@ -4,11 +4,13 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; using TEdit.Desktop.Services; using TEdit.Desktop.ViewModels; using TEdit.Editor; +using TEdit.Geometry; using static TEdit.Desktop.Controls.SkiaWorldRenderBox; namespace TEdit.Desktop.Editor; @@ -69,11 +71,90 @@ public PencilTool(IDocumentService documentService) [Reactive] public bool IsActive { get; set; } public string IconName { get; } = "mdi-pencil"; + private bool _isLeftDown; + private bool _isRightDown; + private Vector2Int32 _startPoint; + private Vector2Int32 _endPoint; + private WorldEditor _editor; + + private void CheckDirectionandDraw(Vector2Int32 tile) + { + Vector2Int32 p = tile; + Vector2Int32 p2 = tile; + if (_isRightDown) + { + if (_isLeftDown) + p.X = _startPoint.X; + else + p.Y = _startPoint.Y; + + DrawLine(p); + _startPoint = p; + System.Diagnostics.Debug.WriteLine($"Update _startpoint {_startPoint} CheckDirectionandDraw _isRightDown"); + } + else if (_isLeftDown) + { + DrawLine(p); + _startPoint = p; + System.Diagnostics.Debug.WriteLine($"Update _startpoint {_startPoint} CheckDirectionandDraw _isLeftDown"); + _endPoint = p; + } + } + + private void DrawLine(Vector2Int32 to) + { + foreach (Vector2Int32 pixel in Shape.DrawLineTool(_startPoint, to)) + { + _editor.SetPixel(pixel.X, pixel.Y); + //BlendRules.ResetUVCache(_wvm, pixel.X, pixel.Y, 1, 1); + } + } + + private void DrawLineP2P(Vector2Int32 endPoint) + { + foreach (Vector2Int32 pixel in Shape.DrawLineTool(_startPoint, _endPoint)) + { + _editor.SetPixel(pixel.X, pixel.Y); + } + } + public void Press(WorldEditor editor, PointerPoint buttons, Point worldCoordinate) { - if (IsActive) + _editor = editor; + _editor.BeginOperationAsync().Wait(); + + if (!_isRightDown && !_isLeftDown) { - editor.SetPixel((int)worldCoordinate.X, (int)worldCoordinate.Y); + _startPoint = new Vector2Int32((int)worldCoordinate.X, (int)worldCoordinate.Y); } + + _isLeftDown = buttons.Properties.IsLeftButtonPressed; + _isRightDown = buttons.Properties.IsRightButtonPressed; + + CheckDirectionandDraw(new Vector2Int32((int)worldCoordinate.X, (int)worldCoordinate.Y)); + } + + public void Move(WorldEditor editor, PointerPoint buttons, Point worldCoordinate) + { + _isLeftDown = buttons.Properties.IsLeftButtonPressed; + _isRightDown = buttons.Properties.IsRightButtonPressed; + + CheckDirectionandDraw(new Vector2Int32((int)worldCoordinate.X, (int)worldCoordinate.Y)); + } + public void Release(WorldEditor editor, PointerPoint buttons, Point worldCoordinate) + { + CheckDirectionandDraw(new Vector2Int32((int)worldCoordinate.X, (int)worldCoordinate.Y)); + + _isLeftDown = buttons.Properties.IsLeftButtonPressed; + _isRightDown = buttons.Properties.IsRightButtonPressed; + + if (!_isLeftDown && !_isRightDown) + { + _editor.EndOperationAsync().Wait(); + } + } + + public void LeaveWindow(WorldEditor editor, PointerPoint buttons, Point worldCoordinate) + { } } diff --git a/src/TEdit.Editor/ToolDefaultData.cs b/src/TEdit.Editor/ToolDefaultData.cs index f858ea10..844811c2 100644 --- a/src/TEdit.Editor/ToolDefaultData.cs +++ b/src/TEdit.Editor/ToolDefaultData.cs @@ -6,27 +6,27 @@ namespace TEdit.Editor; public partial class ToolDefaultData { - private static PaintMode _paintMode; - - private static int _brushWidth; - private static int _brushHeight; - private static int _brushOutline; - private static BrushShape _brushShape; - - private static int _paintTile; - private static int _paintTileMask; - private static bool _paintTileActive; - private static MaskMode _paintTileMaskMode; - - private static int _paintWall; - private static int _paintWallMask; - private static bool _paintWallActive; - private static MaskMode _paintWallMaskMode; - - private static bool _redWire; - private static bool _greenWire; - private static bool _blueWire; - private static bool _yellowWire; + private static PaintMode _paintMode = PaintMode.TileAndWall; + + private static int _brushWidth = 20; + private static int _brushHeight = 20; + private static int _brushOutline = 1; + private static BrushShape _brushShape = BrushShape.Square; + + private static int _paintTile = 0; + private static int _paintTileMask = 0; + private static bool _paintTileActive = true; + private static MaskMode _paintTileMaskMode = MaskMode.Off; + + private static int _paintWall = 0; + private static int _paintWallMask = 0; + private static bool _paintWallActive = true; + private static MaskMode _paintWallMaskMode = MaskMode.Off; + + private static bool _redWire = false; + private static bool _greenWire = false; + private static bool _blueWire = false; + private static bool _yellowWire = false; // Invoked from World.Settings public static void LoadSettings(IEnumerable xmlToolSettings) diff --git a/src/TEdit.Editor/WorldEditor.cs b/src/TEdit.Editor/WorldEditor.cs index 8441c571..45adc0a9 100644 --- a/src/TEdit.Editor/WorldEditor.cs +++ b/src/TEdit.Editor/WorldEditor.cs @@ -57,7 +57,10 @@ public async Task BeginOperationAsync() public async Task EndOperationAsync() { + if (_undo == null) return; + await _undo.SaveUndoAsync(); + } public BrushSettings Brush { get; set; } = new BrushSettings(); @@ -67,6 +70,10 @@ public void SetPixel(int x, int y, PaintMode? mode = null, bool? erase = null) if (_world == null) return; if (TilePicker == null) return; + int index = GetTileIndex(x, y); + if (_checkTiles[index]) { return; } + else { _checkTiles[index] = true; } + Tile curTile = _world.Tiles[x, y]; if (curTile == null) return; @@ -187,6 +194,11 @@ public void SetPixel(int x, int y, PaintMode? mode = null, bool? erase = null) } } + private int GetTileIndex(int x, int y) + { + return x + y * _world.TilesWide; + } + private void SetWall(Tile curTile, bool erase) { if (TilePicker.WallMaskMode == MaskMode.Off ||