Starting progress on graph selection and preloading. More to come.

This commit is contained in:
That_One_Nerd 2024-03-17 00:45:11 -04:00
parent f87ef52a7d
commit 255a7d3774
7 changed files with 106 additions and 6 deletions

View File

@ -41,6 +41,7 @@
MenuEquationsIntegral = new ToolStripMenuItem();
MenuMisc = new ToolStripMenuItem();
MenuMiscCaches = new ToolStripMenuItem();
MiscMenuPreload = new ToolStripMenuItem();
GraphMenu.SuspendLayout();
SuspendLayout();
//
@ -129,7 +130,7 @@
//
// MenuMisc
//
MenuMisc.DropDownItems.AddRange(new ToolStripItem[] { MenuMiscCaches });
MenuMisc.DropDownItems.AddRange(new ToolStripItem[] { MenuMiscCaches, MiscMenuPreload });
MenuMisc.Name = "MenuMisc";
MenuMisc.Size = new Size(83, 38);
MenuMisc.Text = "Misc";
@ -141,6 +142,13 @@
MenuMiscCaches.Text = "View Caches";
MenuMiscCaches.Click += MenuMiscCaches_Click;
//
// MiscMenuPreload
//
MiscMenuPreload.Name = "MiscMenuPreload";
MiscMenuPreload.Size = new Size(359, 44);
MiscMenuPreload.Text = "Preload Cache";
MiscMenuPreload.Click += MiscMenuPreload_Click;
//
// GraphForm
//
AutoScaleDimensions = new SizeF(13F, 32F);
@ -172,5 +180,6 @@
private ToolStripMenuItem MenuEquationsIntegral;
private ToolStripMenuItem MenuMisc;
private ToolStripMenuItem MenuMiscCaches;
private ToolStripMenuItem MiscMenuPreload;
}
}

View File

@ -1,4 +1,5 @@
using Graphing.Graphables;
using Graphing.Parts;
using System.Drawing.Drawing2D;
namespace Graphing.Forms;
@ -200,6 +201,10 @@ public partial class GraphForm : Form
PaintGrid(g);
PaintUnits(g);
Point clientMousePos = PointToClient(Cursor.Position);
Float2 graphMousePos = ScreenSpaceToGraphSpace(new(clientMousePos.X,
clientMousePos.Y));
// Draw the actual graphs.
for (int i = 0; i < ables.Count; i++)
{
@ -207,6 +212,18 @@ public partial class GraphForm : Form
Brush graphBrush = new SolidBrush(ables[i].Color);
Pen graphPen = new(graphBrush, DpiFloat * 3 / 192);
foreach (IGraphPart gp in lines) gp.Render(this, g, graphPen);
// Equation selection detection.
// This system lets you select multiple graphs, and that's cool by me.
if (ableDrag)
{
if (ables[i].ShouldSelectGraphable(this, graphMousePos, 2.5))
{
Float2 selectedPoint = ables[i].GetSelectedPoint(this, graphMousePos);
GraphUiCircle select = new(selectedPoint, 8);
select.Render(this, g, graphPen);
}
}
}
base.OnPaint(e);
@ -227,11 +244,28 @@ public partial class GraphForm : Form
private bool mouseDrag = false;
private Int2 initialMouseLocation;
private Float2 initialScreenCenter;
private bool ableDrag = false;
protected override void OnMouseDown(MouseEventArgs e)
{
mouseDrag = true;
initialMouseLocation = new Int2(Cursor.Position.X, Cursor.Position.Y);
initialScreenCenter = ScreenCenter;
if (!mouseDrag)
{
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 (ableDrag) Invalidate(false);
}
if (!ableDrag)
{
mouseDrag = true;
initialMouseLocation = new Int2(Cursor.Position.X, Cursor.Position.Y);
initialScreenCenter = ScreenCenter;
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
@ -242,9 +276,10 @@ public partial class GraphForm : Form
Float2 graphDiff = new(pixelDiff.x * ZoomLevel / Dpi.x, pixelDiff.y * ZoomLevel / Dpi.y);
ScreenCenter = new(initialScreenCenter.x + graphDiff.x,
initialScreenCenter.y + graphDiff.y);
Invalidate(false);
}
mouseDrag = false;
ableDrag = false;
Invalidate(false);
}
protected override void OnMouseMove(MouseEventArgs e)
{
@ -257,6 +292,7 @@ public partial class GraphForm : Form
initialScreenCenter.y + graphDiff.y);
Invalidate(false);
}
else if (ableDrag) Invalidate(false);
}
protected override void OnMouseWheel(MouseEventArgs e)
{
@ -425,4 +461,17 @@ public partial class GraphForm : Form
cacheForm.TopMost = true;
cacheForm.Show();
}
private void MiscMenuPreload_Click(object sender, EventArgs e)
{
Float2 min = MinVisibleGraph, max = MaxVisibleGraph;
Float2 add = new(max.x - min.x, max.y - min.y);
add.x *= 0.75; // Expansion
add.y *= 0.75; //
Float2 xRange = new(min.x - add.x, max.x + add.x),
yRange = new(min.y - add.y, max.y + add.y);
foreach (Graphable able in Graphables) able.Preload(xRange, yRange);
Invalidate(false);
}
}

View File

@ -1,5 +1,4 @@
using Graphing.Forms;
using Graphing.Parts;
namespace Graphing;
@ -33,4 +32,8 @@ public abstract class Graphable
public abstract void EraseCache();
public abstract long GetCacheBytes();
public abstract void Preload(Float2 xRange, Float2 yRange);
public abstract bool ShouldSelectGraphable(in GraphForm graph, Float2 graphMousePos, double factor);
public abstract Float2 GetSelectedPoint(in GraphForm graph, Float2 graphMousePos);
}

View File

@ -48,4 +48,9 @@ public class ColumnTable : Graphable
return items;
}
public override bool ShouldSelectGraphable(in GraphForm graph, Float2 graphMousePos, double factor) => false;
public override Float2 GetSelectedPoint(in GraphForm graph, Float2 graphMousePos) => default;
public override void Preload(Float2 xRange, Float2 yRange) { }
}

View File

@ -96,6 +96,30 @@ public class Equation : Graphable
public override Graphable DeepCopy() => new Equation(equ);
public override long GetCacheBytes() => cache.Count * 16;
public override bool ShouldSelectGraphable(in GraphForm graph, Float2 graphMousePos, double factor)
{
Int2 screenMousePos = graph.GraphSpaceToScreenSpace(graphMousePos);
(_, _, int index) = NearestCachedPoint(graphMousePos.x);
Int2 screenCachePos = graph.GraphSpaceToScreenSpace(cache[index]);
double allowedDist = factor * graph.DpiFloat * 80 / 192;
Int2 dist = new(screenCachePos.x - screenMousePos.x,
screenCachePos.y - screenMousePos.y);
double totalDist = Math.Sqrt(dist.x * dist.x + dist.y * dist.y);
return totalDist <= allowedDist;
}
public override Float2 GetSelectedPoint(in GraphForm graph, Float2 graphMousePos)
{
return new(graphMousePos.x, GetFromCache(graphMousePos.x, 0.001));
}
public override void Preload(Float2 xRange, Float2 yRange)
{
for (double x = xRange.x; x <= xRange.y; x += 1e-3) GetFromCache(x, 1e-4);
}
}
public delegate double EquationDelegate(double x);

View File

@ -74,6 +74,11 @@ public class SlopeField : Graphable
public override void EraseCache() => cache.Clear();
public override long GetCacheBytes() => cache.Count * 48;
public override bool ShouldSelectGraphable(in GraphForm graph, Float2 graphMousePos, double factor) => false;
public override Float2 GetSelectedPoint(in GraphForm graph, Float2 graphMousePos) => default;
public override void Preload(Float2 xRange, Float2 yRange) { }
}
public delegate double SlopeFieldsDelegate(double x, double y);

View File

@ -48,4 +48,9 @@ public class TangentLine : Graphable
public override void EraseCache() { }
public override long GetCacheBytes() => 0;
public override bool ShouldSelectGraphable(in GraphForm graph, Float2 graphMousePos, double factor) => false;
public override Float2 GetSelectedPoint(in GraphForm graph, Float2 graphMousePos) => default;
public override void Preload(Float2 xRange, Float2 yRange) { }
}