diff --git a/Program.cs b/Program.cs index ff8726a..fe2413e 100644 --- a/Program.cs +++ b/Program.cs @@ -639,7 +639,6 @@ public class Game : GameWindow { int ribbonIndex = 0; Vector2i mouseDragStart; Vector2i mouseDragEnd; - bool mouseDragging; Shader shader = new(); Matrix4 projection; float zoomLevel = 0f; @@ -655,44 +654,48 @@ public class Game : GameWindow { // FIXME: add a confirm dialog before closing. (Also for the window-close button.) // FIXME: don't quit if there's pending file-write operations. - // Close when Escape is pressed. - if (input.IsKeyPressed(Keys.Escape)) { + // Close when Ctrl-Q is pressed. + if (input.IsKeyPressed(Keys.Q) && ctrlIsDown) { Close(); } + int lastPhotoIndex = photoIndex; + + Vector2i mousePosition = (Vector2i) MouseState.Position; + // Look for mouse clicks on thumbnails or stars. // // Note that we don't bounds-check photoIndex until after all the possible // inputs that might affect it. That simplifies this logic significantly. if (MouseState.IsButtonPressed(MouseButton.Button1)) { - Vector2i click = (Vector2i) MouseState.Position; for (int i = 0; i < geometry.StarBoxes.Count; i++) { - if (geometry.StarBoxes[i].ContainsInclusive(click)) { + if (geometry.StarBoxes[i].ContainsInclusive(mousePosition)) { photos[photoIndex].Rating = i + 1; } } for (int i = 0; i < geometry.ThumbnailBoxes.Count; i++) { - if (geometry.ThumbnailBoxes[i].ContainsInclusive(click)) { + if (geometry.ThumbnailBoxes[i].ContainsInclusive(mousePosition)) { photoIndex = ribbonIndex + i; } } - if (geometry.PhotoBox.ContainsInclusive(click)) { - mouseDragging = true; - mouseDragStart = click; + if (geometry.PhotoBox.ContainsInclusive(mousePosition)) { + mouseDragStart = mousePosition; } } - if (MouseState.IsButtonDown(MouseButton.Button1)) { - // FIXME: really this should be clipped to the active photo's drawable area, not the whole photobox. - mouseDragEnd = new Vector2i( - Math.Clamp((int) MouseState.Position.X, geometry.PhotoBox.Min.X, geometry.PhotoBox.Max.X), - Math.Clamp((int) MouseState.Position.Y, geometry.PhotoBox.Min.Y, geometry.PhotoBox.Max.Y)); - } else { - mouseDragging = false; + if (geometry.PhotoBox.ContainsInclusive(mousePosition)) { + // FIXME: really this should be clipped to the active photo's drawable area, not the whole photobox. + mouseDragEnd = mousePosition; + } + } + + if (input.IsKeyPressed(Keys.Escape)) { + mouseDragStart = new(-1, -1); + mouseDragEnd = new(-1, -1); } if (MouseState.IsButtonPressed(MouseButton.Button4)) { @@ -745,6 +748,11 @@ public class Game : GameWindow { photoIndex = Math.Clamp(photoIndex, 0, photos.Count - 1); } + if (photoIndex != lastPhotoIndex) { + mouseDragStart = new(-1, -1); + mouseDragEnd = new(-1, -1); + } + // Handle presses of the "rating" keys -- 0-5 and `. // A normal press just sets the rating of the current photo. // If the user is holding "shift", we instead filter to only show photos of that rating or higher. @@ -980,19 +988,30 @@ public class Game : GameWindow { DrawText("No photos found.", 10, 10); } - if (mouseDragging) { - DrawCropBox(); - } + DrawCropBox(); SwapBuffers(); } void DrawCropBox() { - int left = Math.Min(mouseDragStart.X, mouseDragEnd.X); - int right = Math.Max(mouseDragStart.X, mouseDragEnd.X); - int top = Math.Min(mouseDragStart.Y, mouseDragEnd.Y); - int bottom = Math.Max(mouseDragStart.Y, mouseDragEnd.Y); - + Vector2i start = mouseDragStart; + Vector2i end = mouseDragEnd; + end.Y = Math.Min(end.Y, start.Y + (end.X - start.X) * 4 / 6); + end.X = start.X + (end.Y - start.Y) * 6 / 4; + int left = Math.Min(start.X, end.X); + int right = Math.Max(start.X, end.X); + int top = Math.Min(start.Y, end.Y); + int bottom = Math.Max(start.Y, end.Y); + int area = (right - left) * (bottom - top); + + if (area < 100) { + return; + } + Color4 shadeColor = new Color4(0, 0, 0, 0.75f); + DrawFilledBox(new Box2i(0, 0, left, geometry.PhotoBox.Max.Y), shadeColor); + DrawFilledBox(new Box2i(left, 0, geometry.PhotoBox.Max.X, top), shadeColor); + DrawFilledBox(new Box2i(left, bottom, geometry.PhotoBox.Max.X, geometry.PhotoBox.Max.Y), shadeColor); + DrawFilledBox(new Box2i(right, top, geometry.PhotoBox.Max.X, bottom), shadeColor); DrawBox(new Box2i(left, top, right, bottom), 1, Color4.White); DrawBox(new Box2i(left - 1, top - 1 , right + 1, bottom + 1), 1, Color4.Black); DrawBox(new Box2i(left - 2, top - 2 , right + 2, bottom + 2), 1, Color4.White);