From 6076abe9d1422f4c8aa0e1239d8ecada5f866ecf Mon Sep 17 00:00:00 2001 From: Colin McMillen Date: Thu, 3 Aug 2023 18:38:21 -0400 Subject: [PATCH] return ToolState and start switching tools --- Program.cs | 69 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 19 deletions(-) diff --git a/Program.cs b/Program.cs index b933325..d46ae9b 100644 --- a/Program.cs +++ b/Program.cs @@ -52,9 +52,15 @@ public class CameraInfo { public static readonly CameraInfo IPHONE_12_MINI = new(new Vector2i(4032, 3024)); } +public enum ToolState { + Active, + Done, + Canceled +} + public interface ITool { void SetActivePhoto(Photo photo); - void HandleInput(UiGeometry geometry, KeyboardState input, MouseState mouse, Game game); + ToolState HandleInput(UiGeometry geometry, KeyboardState input, MouseState mouse, Game game); string Status(); void Draw(UiGeometry geometry, Game game); } @@ -66,29 +72,32 @@ public class ViewTool : ITool { activePhoto = photo; } - public void HandleInput(UiGeometry geometry, KeyboardState input, MouseState mouse, Game game) { + public ToolState HandleInput(UiGeometry geometry, KeyboardState input, MouseState mouse, Game game) { + return ToolState.Active; } public string Status() { - return ""; + return "view"; } public void Draw(UiGeometry geometry, Game game) { } } + // FIXME: remove unneeded dependencies on "Game" or at least refactor them a bit. public class CropTool : ITool { Photo? activePhoto; Vector2i mouseDragStart; Vector2i mouseDragEnd; + string status = ""; public void SetActivePhoto(Photo photo) { activePhoto = photo; } - public void HandleInput(UiGeometry geometry, KeyboardState input, MouseState mouse, Game game) { + public ToolState HandleInput(UiGeometry geometry, KeyboardState input, MouseState mouse, Game game) { Vector2i mousePosition = (Vector2i) mouse.Position; if (mouse.IsButtonPressed(MouseButton.Button1)) { @@ -104,15 +113,23 @@ public class CropTool : ITool { } } - if (input.IsKeyPressed(Keys.Escape)) { - mouseDragStart = new(-1, -1); - mouseDragEnd = new(-1, -1); - } + Vector2i start = game.ScreenToImage(mouseDragStart); + // FIXME: this needs to be the actual width of the computed box. + Vector2i size = game.ScreenToImage(mouseDragEnd) - start; + + status = $"({start.X}, {start.Y}) {size.X}x{size.Y}"; - // FIXME: crop should be a modal tool that starts with C and ends with Enter or Escape. if (input.IsKeyPressed(Keys.Enter)) { ApplyCrop(game); + return ToolState.Done; + } + + if (input.IsKeyPressed(Keys.Escape)) { + activePhoto.CropRectangle = Rectangle.Empty; + return ToolState.Canceled; } + + return ToolState.Active; } // left, right, top, bottom @@ -171,7 +188,7 @@ public class CropTool : ITool { } public string Status() { - return "crop"; + return "[crop] " + status; } } @@ -754,7 +771,9 @@ public static class Util { } public class Game : GameWindow { - public Game(GameWindowSettings gwSettings, NativeWindowSettings nwSettings) : base(gwSettings, nwSettings) {} + public Game(GameWindowSettings gwSettings, NativeWindowSettings nwSettings) : base(gwSettings, nwSettings) { + activeTool = viewTool; + } private static string outputRoot = @"c:\users\colin\desktop\totte-output"; // private static string outputRoot = @"c:\users\colin\pictures\photos"; @@ -785,7 +804,8 @@ public class Game : GameWindow { HashSet loadedImages = new(); HashSet loadingImages = new(); readonly object loadedImagesLock = new(); - ITool activeTool = new CropTool(); + readonly ViewTool viewTool = new ViewTool(); + ITool activeTool; int photoIndex = 0; int ribbonIndex = 0; Vector2i mousePosition; @@ -951,8 +971,21 @@ public class Game : GameWindow { zoomLevel = 16f; } + // Handle tool switching. + if (activeTool == viewTool) { + if (input.IsKeyPressed(Keys.C)) { + activeTool = new CropTool(); + } + } + + // Delegate input to the active tool. activeTool.SetActivePhoto(photos[photoIndex]); - activeTool.HandleInput(geometry, KeyboardState, MouseState, this); + ToolState state = activeTool.HandleInput(geometry, KeyboardState, MouseState, this); + + // Change back to the default tool if the active tool is done. + if (state != ToolState.Active) { + activeTool = viewTool; + } } void FilterByRating(int rating) { @@ -1186,15 +1219,13 @@ public class Game : GameWindow { if (activePhoto.Loaded) { DrawText($"{(scale * 100):F1}%", geometry.StatusBox.Min.X, y); } - DrawText($"({mousePosition.X}, {mousePosition.Y})", geometry.StatusBox.Min.X + 72, y); - Vector2i imagePosition = ScreenToImage(mousePosition); - DrawText($"({imagePosition.X}, {imagePosition.Y})", geometry.StatusBox.Min.X + 320, y); + DrawText(activeTool.Status(), geometry.StatusBox.Min.X + 72, y); } public Vector2i ScreenToImage(int x, int y) { - return new( - (int) ((x - activeOffset.X) / activeScale), - (int) ((y - activeOffset.Y) / activeScale)); + int rx = (int) ((x - activeOffset.X) / activeScale); + int ry = (int) ((y - activeOffset.Y) / activeScale); + return new(rx, ry); } public Vector2i ScreenToImage(Vector2i position) {