return ToolState and start switching tools

This commit is contained in:
Colin McMillen 2023-08-03 18:38:21 -04:00
parent 7db0ec7e62
commit 6076abe9d1

View File

@ -52,9 +52,15 @@ public class CameraInfo {
public static readonly CameraInfo IPHONE_12_MINI = new(new Vector2i(4032, 3024)); public static readonly CameraInfo IPHONE_12_MINI = new(new Vector2i(4032, 3024));
} }
public enum ToolState {
Active,
Done,
Canceled
}
public interface ITool { public interface ITool {
void SetActivePhoto(Photo photo); 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(); string Status();
void Draw(UiGeometry geometry, Game game); void Draw(UiGeometry geometry, Game game);
} }
@ -66,29 +72,32 @@ public class ViewTool : ITool {
activePhoto = 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) {
return ToolState.Active;
} }
public string Status() { public string Status() {
return ""; return "view";
} }
public void Draw(UiGeometry geometry, Game game) { public void Draw(UiGeometry geometry, Game game) {
} }
} }
// FIXME: remove unneeded dependencies on "Game" or at least refactor them a bit. // FIXME: remove unneeded dependencies on "Game" or at least refactor them a bit.
public class CropTool : ITool { public class CropTool : ITool {
Photo? activePhoto; Photo? activePhoto;
Vector2i mouseDragStart; Vector2i mouseDragStart;
Vector2i mouseDragEnd; Vector2i mouseDragEnd;
string status = "";
public void SetActivePhoto(Photo photo) { public void SetActivePhoto(Photo photo) {
activePhoto = 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; Vector2i mousePosition = (Vector2i) mouse.Position;
if (mouse.IsButtonPressed(MouseButton.Button1)) { if (mouse.IsButtonPressed(MouseButton.Button1)) {
@ -104,15 +113,23 @@ public class CropTool : ITool {
} }
} }
if (input.IsKeyPressed(Keys.Escape)) { Vector2i start = game.ScreenToImage(mouseDragStart);
mouseDragStart = new(-1, -1); // FIXME: this needs to be the actual width of the computed box.
mouseDragEnd = new(-1, -1); 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)) { if (input.IsKeyPressed(Keys.Enter)) {
ApplyCrop(game); ApplyCrop(game);
return ToolState.Done;
} }
if (input.IsKeyPressed(Keys.Escape)) {
activePhoto.CropRectangle = Rectangle.Empty;
return ToolState.Canceled;
}
return ToolState.Active;
} }
// left, right, top, bottom // left, right, top, bottom
@ -171,7 +188,7 @@ public class CropTool : ITool {
} }
public string Status() { public string Status() {
return "crop"; return "[crop] " + status;
} }
} }
@ -754,7 +771,9 @@ public static class Util {
} }
public class Game : GameWindow { 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\desktop\totte-output";
// private static string outputRoot = @"c:\users\colin\pictures\photos"; // private static string outputRoot = @"c:\users\colin\pictures\photos";
@ -785,7 +804,8 @@ public class Game : GameWindow {
HashSet<Photo> loadedImages = new(); HashSet<Photo> loadedImages = new();
HashSet<Photo> loadingImages = new(); HashSet<Photo> loadingImages = new();
readonly object loadedImagesLock = new(); readonly object loadedImagesLock = new();
ITool activeTool = new CropTool(); readonly ViewTool viewTool = new ViewTool();
ITool activeTool;
int photoIndex = 0; int photoIndex = 0;
int ribbonIndex = 0; int ribbonIndex = 0;
Vector2i mousePosition; Vector2i mousePosition;
@ -951,8 +971,21 @@ public class Game : GameWindow {
zoomLevel = 16f; 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.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) { void FilterByRating(int rating) {
@ -1186,15 +1219,13 @@ public class Game : GameWindow {
if (activePhoto.Loaded) { if (activePhoto.Loaded) {
DrawText($"{(scale * 100):F1}%", geometry.StatusBox.Min.X, y); DrawText($"{(scale * 100):F1}%", geometry.StatusBox.Min.X, y);
} }
DrawText($"({mousePosition.X}, {mousePosition.Y})", geometry.StatusBox.Min.X + 72, y); DrawText(activeTool.Status(), geometry.StatusBox.Min.X + 72, y);
Vector2i imagePosition = ScreenToImage(mousePosition);
DrawText($"({imagePosition.X}, {imagePosition.Y})", geometry.StatusBox.Min.X + 320, y);
} }
public Vector2i ScreenToImage(int x, int y) { public Vector2i ScreenToImage(int x, int y) {
return new( int rx = (int) ((x - activeOffset.X) / activeScale);
(int) ((x - activeOffset.X) / activeScale), int ry = (int) ((y - activeOffset.Y) / activeScale);
(int) ((y - activeOffset.Y) / activeScale)); return new(rx, ry);
} }
public Vector2i ScreenToImage(Vector2i position) { public Vector2i ScreenToImage(Vector2i position) {