Compare commits

..

No commits in common. "1c586a619705b8513a2e704c13b32fde96ecb0cb" and "304097177ce41b188ca80816b0d045a944d1f8f3" have entirely different histories.

View File

@ -50,7 +50,7 @@ public class CameraInfo {
} }
public enum ToolStatus { public enum ToolState {
Active, Active,
Done, Done,
Canceled Canceled
@ -58,15 +58,15 @@ public enum ToolStatus {
public interface ITool { public interface ITool {
ToolStatus HandleInput(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);
} }
public class ViewTool : ITool { public class ViewTool : ITool {
public ToolStatus HandleInput(KeyboardState input, MouseState mouse, Game game) { public ToolState HandleInput(UiGeometry geometry, KeyboardState input, MouseState mouse, Game game) {
return ToolStatus.Active; return ToolState.Active;
} }
public string Status() { public string Status() {
@ -81,82 +81,59 @@ public class ViewTool : ITool {
// 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 photo; Photo activePhoto;
Vector2i mouseDragStart; Vector2i mouseDragStart;
Vector2i mouseDragEnd; Vector2i mouseDragEnd;
bool dragging;
string status = ""; string status = "";
public CropTool(Photo photo) { public CropTool(Photo photo) {
this.photo = photo; activePhoto = photo;
mouseDragStart = new(photo.CropRectangle.Left, photo.CropRectangle.Top);
mouseDragEnd = new(photo.CropRectangle.Right, photo.CropRectangle.Bottom);
} }
public ToolStatus HandleInput(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;
Vector2i imagePosition = game.ScreenToImage(mousePosition); Vector2i imagePosition = game.ScreenToImage(mousePosition);
if (mouse.IsButtonPressed(MouseButton.Button1)) { if (mouse.IsButtonPressed(MouseButton.Button1)) {
dragging = photo.CropRectangle.Contains(imagePosition.X, imagePosition.Y); if (geometry.PhotoBox.ContainsInclusive(mousePosition)) {
}
if (!dragging) {
if (mouse.IsButtonPressed(MouseButton.Button1)) {
mouseDragStart = imagePosition; mouseDragStart = imagePosition;
} }
if (mouse.IsButtonDown(MouseButton.Button1)) { }
mouseDragEnd = imagePosition;
}
var (left, right, top, bottom) = GetCrop(); if (mouse.IsButtonDown(MouseButton.Button1)) {
if (left != right && top != bottom) { if (geometry.PhotoBox.ContainsInclusive(mousePosition)) {
photo.CropRectangle = Rectangle.FromLTRB(left, top, right, bottom); mouseDragEnd = imagePosition;
} else {
photo.CropRectangle = Rectangle.Empty;
}
} else {
if (mouse.IsButtonDown(MouseButton.Button1)) {
Vector2 delta = mouse.Delta;
Vector2i imageDelta = game.ScreenToImageDelta((int) delta.X, (int) delta.Y);
photo.CropRectangle.Offset(imageDelta.X, imageDelta.Y);
if (photo.CropRectangle.Left < 0) {
photo.CropRectangle.Offset(-photo.CropRectangle.Left, 0);
}
if (photo.CropRectangle.Right > photo.Size.X) {
int overshoot = photo.CropRectangle.Right - photo.Size.X;
photo.CropRectangle.Offset(-overshoot, 0);
}
if (photo.CropRectangle.Top < 0) {
photo.CropRectangle.Offset(0, -photo.CropRectangle.Top);
}
if (photo.CropRectangle.Bottom > photo.Size.Y) {
int overshoot = photo.CropRectangle.Bottom - photo.Size.Y;
photo.CropRectangle.Offset(0, -overshoot);
}
} }
} }
Rectangle r = photo.CropRectangle; var (left, right, top, bottom) = GetCrop();
status = $"({r.Left}, {r.Top}, {r.Right}, {r.Bottom}) {r.Width}x{r.Height}"; Vector2i size = new(right - left, bottom - top);
status = $"({left}, {top}) {size.X}x{size.Y}";
Rectangle crop = Rectangle.Empty;
if (size.X > 0 && size.Y > 0) {
crop = Rectangle.FromLTRB(left, top, right, bottom);
}
activePhoto.CropRectangle = crop;
if (input.IsKeyPressed(Keys.Enter)) { if (input.IsKeyPressed(Keys.Enter)) {
return ToolStatus.Done; return ToolState.Done;
} }
if (input.IsKeyPressed(Keys.Escape)) { if (input.IsKeyPressed(Keys.Escape)) {
photo.CropRectangle = Rectangle.Empty; activePhoto.CropRectangle = Rectangle.Empty;
return ToolStatus.Canceled; return ToolState.Canceled;
} }
return ToolStatus.Active; return ToolState.Active;
} }
// left, right, top, bottom // left, right, top, bottom
(int, int, int, int) GetCrop() { (int, int, int, int) GetCrop() {
// FIXME: this expects the start point in the top left and the end point // FIXME: this expects the start point in the top left and the end point
// in the bottom right; some sign flipping needs to occur to make anchors // in the bottom right; some sign flipping needs to occur to make anchors
// in other directions work well. // in other direction work well.
Vector2i start = mouseDragStart; Vector2i start = mouseDragStart;
Vector2i end = mouseDragEnd; Vector2i end = mouseDragEnd;
// FIXME: choose the aspect ratio based on the original image aspect ratio. // FIXME: choose the aspect ratio based on the original image aspect ratio.
@ -574,10 +551,10 @@ public class Game : GameWindow {
} }
// Delegate input to the active tool. // Delegate input to the active tool.
ToolStatus status = activeTool.HandleInput(KeyboardState, MouseState, this); ToolState state = activeTool.HandleInput(geometry, KeyboardState, MouseState, this);
// Change back to the default tool if the active tool is done. // Change back to the default tool if the active tool is done.
if (status != ToolStatus.Active) { if (state != ToolState.Active) {
activeTool = viewTool; activeTool = viewTool;
} }
} }
@ -846,14 +823,10 @@ public class Game : GameWindow {
} }
} }
public Vector2i ScreenToImageDelta(int x, int y) {
return new((int) (x / activeScale), (int) (y / activeScale));
}
public Vector2i ScreenToImage(int x, int y) { public Vector2i ScreenToImage(int x, int y) {
int rx = (int) ((x - activeOffset.X) / activeScale); int rx = (int) ((x - activeOffset.X) / activeScale);
int ry = (int) ((y - activeOffset.Y) / activeScale);
rx = Math.Clamp(rx, 0, photos[photoIndex].Size.X); rx = Math.Clamp(rx, 0, photos[photoIndex].Size.X);
int ry = (int) ((y - activeOffset.Y) / activeScale);
ry = Math.Clamp(ry, 0, photos[photoIndex].Size.Y); ry = Math.Clamp(ry, 0, photos[photoIndex].Size.Y);
return new(rx, ry); return new(rx, ry);
} }