From 933fcdf0828f77b42c8dd3720d8fdb1ebd674193 Mon Sep 17 00:00:00 2001 From: That_One_Nerd Date: Tue, 16 Apr 2024 09:43:16 -0400 Subject: [PATCH] This took way too long. Zoom-box system works. --- Base/Base.csproj.user | 3 + Base/Forms/GraphForm.cs | 133 +++++++++++++++++++++++++---- Base/Forms/SetZoomForm.Designer.cs | 60 +++++++++++++ Base/Forms/SetZoomForm.cs | 38 +++++++++ Base/Forms/SetZoomForm.resx | 120 ++++++++++++++++++++++++++ 5 files changed, 338 insertions(+), 16 deletions(-) create mode 100644 Base/Forms/SetZoomForm.Designer.cs create mode 100644 Base/Forms/SetZoomForm.cs create mode 100644 Base/Forms/SetZoomForm.resx diff --git a/Base/Base.csproj.user b/Base/Base.csproj.user index a1412bd..b8c9d44 100644 --- a/Base/Base.csproj.user +++ b/Base/Base.csproj.user @@ -13,6 +13,9 @@ Form + + Form + Form diff --git a/Base/Forms/GraphForm.cs b/Base/Forms/GraphForm.cs index b8e0d2e..e4d22f5 100644 --- a/Base/Forms/GraphForm.cs +++ b/Base/Forms/GraphForm.cs @@ -21,6 +21,7 @@ public partial class GraphForm : Form public static readonly Color SemiAxisColor = Color.FromArgb(unchecked((int)0xFF_999999)); public static readonly Color QuarterAxisColor = Color.FromArgb(unchecked((int)0xFF_E0E0E0)); public static readonly Color UnitsTextColor = Color.Black; + public static readonly Color ZoomBoxColor = Color.Black; public Float2 ScreenCenter { get; private set; } public Float2 Dpi { get; private set; } @@ -223,9 +224,8 @@ public partial class GraphForm : Form // Equation selection detection. // This system lets you select multiple graphs, and that's cool by me. - if (ableDrag) + if (selectState == SelectionState.GraphSelect) { - Font textFont = new(Font.Name, 8, FontStyle.Bold); for (int i = 0; i < ables.Count; i++) { if (ables[i].ShouldSelectGraphable(this, graphMousePos, 2.5)) @@ -235,6 +235,20 @@ public partial class GraphForm : Form } } } + else if (selectState == SelectionState.ZoomBox) + { + // Draw the current box selection. + Int2 boxPosA = GraphSpaceToScreenSpace(boxSelectA), + boxPosB = GraphSpaceToScreenSpace(boxSelectB); + + if (boxPosA.x > boxPosB.x) (boxPosA.x, boxPosB.x) = (boxPosB.x, boxPosA.x); + if (boxPosA.y > boxPosB.y) (boxPosA.y, boxPosB.y) = (boxPosB.y, boxPosA.y); + + Pen boxPen = new(ZoomBoxColor, 2 * DpiFloat / 192); + g.DrawRectangle(boxPen, new(boxPosA.x, boxPosA.y, + boxPosB.x - boxPosA.x, + boxPosB.y - boxPosA.y)); + } base.OnPaint(e); } @@ -264,35 +278,52 @@ public partial class GraphForm : Form pixelPos.y >= 0 && pixelPos.y < ClientRectangle.Height; } - private bool mouseDrag = false; + private SelectionState selectState = SelectionState.None; + internal bool canBoxSelect; + private SetZoomForm? setZoomForm; + private Int2 initialMouseLocation; private Float2 initialScreenCenter; - private bool ableDrag = false; + private Float2 boxSelectA, boxSelectB; + protected override void OnMouseDown(MouseEventArgs e) { - if (!mouseDrag) + if (selectState == SelectionState.None && canBoxSelect) + { + Point clientMousePos = PointToClient(Cursor.Position); + Float2 graphMousePos = ScreenSpaceToGraphSpace(new(clientMousePos.X, + clientMousePos.Y)); + + boxSelectA = graphMousePos; + boxSelectB = graphMousePos; + + selectState = SelectionState.ZoomBox; + } + + if (selectState == SelectionState.None) { Point clientMousePos = PointToClient(Cursor.Position); Float2 graphMousePos = ScreenSpaceToGraphSpace(new(clientMousePos.X, clientMousePos.Y)); foreach (Graphable able in Graphables) { - if (able.ShouldSelectGraphable(this, graphMousePos, 1)) ableDrag = true; + if (able.ShouldSelectGraphable(this, graphMousePos, 1)) + selectState = SelectionState.GraphSelect; } - if (ableDrag) Invalidate(false); + if (selectState == SelectionState.GraphSelect) Invalidate(false); } - if (!ableDrag) + if (selectState == SelectionState.None) { - mouseDrag = true; + selectState = SelectionState.ViewportDrag; initialMouseLocation = new Int2(Cursor.Position.X, Cursor.Position.Y); initialScreenCenter = ScreenCenter; } } protected override void OnMouseUp(MouseEventArgs e) { - if (mouseDrag) + if (selectState == SelectionState.ViewportDrag) { Int2 pixelDiff = new(initialMouseLocation.x - Cursor.Position.X, initialMouseLocation.y - Cursor.Position.Y); @@ -300,22 +331,52 @@ public partial class GraphForm : Form ScreenCenter = new(initialScreenCenter.x + graphDiff.x, initialScreenCenter.y + graphDiff.y); } - mouseDrag = false; - ableDrag = false; + else if (selectState == SelectionState.ZoomBox) + { + Point clientMousePos = PointToClient(Cursor.Position); + Float2 graphMousePos = ScreenSpaceToGraphSpace(new(clientMousePos.X, + clientMousePos.Y)); + boxSelectB = graphMousePos; + + // Set center. + ScreenCenter = new((boxSelectA.x + boxSelectB.x) * 0.5, + -(boxSelectA.y + boxSelectB.y) * 0.5); + + // Set zoom. Kind of weird but it works. + Float2 minGraph = MinVisibleGraph, maxGraph = MaxVisibleGraph; + Float2 oldDist = new(maxGraph.x - minGraph.x, + maxGraph.y - minGraph.y); + Float2 newDist = new(Math.Abs(boxSelectB.x - boxSelectA.x), + Math.Abs(boxSelectB.y - boxSelectA.y)); + ZoomLevel = new(ZoomLevel.x * newDist.x / oldDist.x, + ZoomLevel.y * newDist.y / oldDist.y); + + setZoomForm!.CompleteBoxSelection(); + + boxSelectA = new(0, 0); + boxSelectB = new(0, 0); + } + selectState = SelectionState.None; Invalidate(false); } protected override void OnMouseMove(MouseEventArgs e) { - if (mouseDrag) + if (selectState == SelectionState.ViewportDrag) { Int2 pixelDiff = new(initialMouseLocation.x - Cursor.Position.X, initialMouseLocation.y - Cursor.Position.Y); Float2 graphDiff = new(pixelDiff.x * ZoomLevel.x / Dpi.x, pixelDiff.y * ZoomLevel.y / Dpi.y); ScreenCenter = new(initialScreenCenter.x + graphDiff.x, initialScreenCenter.y + graphDiff.y); - Invalidate(false); } - else if (ableDrag) Invalidate(false); + else if (selectState == SelectionState.ZoomBox) + { + Point clientMousePos = PointToClient(Cursor.Position); + Float2 graphMousePos = ScreenSpaceToGraphSpace(new(clientMousePos.X, + clientMousePos.Y)); + boxSelectB = graphMousePos; + } + Invalidate(false); } protected override void OnMouseWheel(MouseEventArgs e) { @@ -445,7 +506,31 @@ public partial class GraphForm : Form private void ButtonViewportSetZoom_Click(object? sender, EventArgs e) { - MessageBox.Show("TODO", "Set Viewport Zoom", MessageBoxButtons.OK, MessageBoxIcon.Error); + if (setZoomForm is not null) + { + setZoomForm.Focus(); + return; + } + + SetZoomForm zoomForm = new(this) + { + StartPosition = FormStartPosition.Manual, + }; + zoomForm.Location = new Point(Location.X + ClientRectangle.Width + 10, + Location.Y + (ClientRectangle.Height - zoomForm.ClientRectangle.Height) / 2); + + if (zoomForm.Location.X + zoomForm.Width > Screen.FromControl(this).WorkingArea.Width) + { + zoomForm.StartPosition = FormStartPosition.WindowsDefaultLocation; + } + + setZoomForm = zoomForm; + zoomForm.Show(); + zoomForm.FormClosing += (o, e) => + { + zoomForm.CompleteBoxSelection(); + setZoomForm = null; + }; } private void ButtonViewportSetCenter_Click(object? sender, EventArgs e) { @@ -464,12 +549,20 @@ public partial class GraphForm : Form WindowState = FormWindowState.Normal; } + private ViewCacheForm? cacheForm; private void MenuMiscCaches_Click(object? sender, EventArgs e) { + if (this.cacheForm is not null) + { + this.cacheForm.Focus(); + return; + } + ViewCacheForm cacheForm = new(this) { StartPosition = FormStartPosition.Manual }; + this.cacheForm = cacheForm; cacheForm.Location = new Point(Location.X + ClientRectangle.Width + 10, Location.Y + (ClientRectangle.Height - cacheForm.ClientRectangle.Height) / 2); @@ -594,4 +687,12 @@ public partial class GraphForm : Form Console.WriteLine($"Failed to check for updates:\n{ex}"); } } + + private enum SelectionState + { + None = 0, + ViewportDrag, + GraphSelect, + ZoomBox, + } } diff --git a/Base/Forms/SetZoomForm.Designer.cs b/Base/Forms/SetZoomForm.Designer.cs new file mode 100644 index 0000000..d3324cd --- /dev/null +++ b/Base/Forms/SetZoomForm.Designer.cs @@ -0,0 +1,60 @@ +namespace Graphing.Forms +{ + partial class SetZoomForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + EnableBoxSelect = new System.Windows.Forms.Button(); + SuspendLayout(); + // + // EnableBoxSelect + // + EnableBoxSelect.Location = new System.Drawing.Point(12, 12); + EnableBoxSelect.Name = "EnableBoxSelect"; + EnableBoxSelect.Size = new System.Drawing.Size(150, 46); + EnableBoxSelect.TabIndex = 0; + EnableBoxSelect.Text = "Box Select"; + EnableBoxSelect.UseVisualStyleBackColor = true; + EnableBoxSelect.Click += EnableBoxSelect_Click; + // + // SetZoomForm + // + AutoScaleDimensions = new System.Drawing.SizeF(13F, 32F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(800, 450); + Controls.Add(EnableBoxSelect); + FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; + Name = "SetZoomForm"; + Text = "Set Viewport Zoom"; + ResumeLayout(false); + } + + #endregion + + private System.Windows.Forms.Button EnableBoxSelect; + } +} \ No newline at end of file diff --git a/Base/Forms/SetZoomForm.cs b/Base/Forms/SetZoomForm.cs new file mode 100644 index 0000000..3a8c499 --- /dev/null +++ b/Base/Forms/SetZoomForm.cs @@ -0,0 +1,38 @@ +using System; +using System.Windows.Forms; + +namespace Graphing.Forms; + +public partial class SetZoomForm : Form +{ + private readonly GraphForm refForm; + + private bool boxSelectEnabled; + + public SetZoomForm(GraphForm refForm) + { + InitializeComponent(); + this.refForm = refForm; + } + + private void EnableBoxSelect_Click(object? sender, EventArgs e) + { + boxSelectEnabled = !boxSelectEnabled; + refForm.canBoxSelect = boxSelectEnabled; + + if (boxSelectEnabled) + { + EnableBoxSelect.Text = $"Cancel ..."; + refForm.Focus(); + } + else + { + EnableBoxSelect.Text = "Box Select"; + } + } + + internal void CompleteBoxSelection() + { + if (boxSelectEnabled) EnableBoxSelect_Click(null, new()); + } +} diff --git a/Base/Forms/SetZoomForm.resx b/Base/Forms/SetZoomForm.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/Base/Forms/SetZoomForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file