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 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<Photo> loadedImages = new();
HashSet<Photo> 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) {