feat(ui): improve BestFitViewerForm navigation and reduce flicker
Add third row (5x3 grid, 15 items/page), remove 50-result cap so all candidates are pageable, start maximized, replace page label with editable textbox for direct page entry, center nav controls, and eliminate flicker on page change via DoubleBuffered + WM_SETREDRAW. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+36
-17
@@ -17,7 +17,8 @@ namespace OpenNest.Forms
|
|||||||
this.navPanel = new System.Windows.Forms.Panel();
|
this.navPanel = new System.Windows.Forms.Panel();
|
||||||
this.btnPrev = new System.Windows.Forms.Button();
|
this.btnPrev = new System.Windows.Forms.Button();
|
||||||
this.btnNext = new System.Windows.Forms.Button();
|
this.btnNext = new System.Windows.Forms.Button();
|
||||||
this.lblPage = new System.Windows.Forms.Label();
|
this.txtPage = new System.Windows.Forms.TextBox();
|
||||||
|
this.lblPageCount = new System.Windows.Forms.Label();
|
||||||
this.navPanel.SuspendLayout();
|
this.navPanel.SuspendLayout();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
@@ -32,16 +33,18 @@ namespace OpenNest.Forms
|
|||||||
this.gridPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
this.gridPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
this.gridPanel.Location = new System.Drawing.Point(0, 0);
|
this.gridPanel.Location = new System.Drawing.Point(0, 0);
|
||||||
this.gridPanel.Name = "gridPanel";
|
this.gridPanel.Name = "gridPanel";
|
||||||
this.gridPanel.RowCount = 2;
|
this.gridPanel.RowCount = 3;
|
||||||
this.gridPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
this.gridPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33F));
|
||||||
this.gridPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
this.gridPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.34F));
|
||||||
|
this.gridPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33F));
|
||||||
this.gridPanel.Size = new System.Drawing.Size(1200, 764);
|
this.gridPanel.Size = new System.Drawing.Size(1200, 764);
|
||||||
this.gridPanel.TabIndex = 0;
|
this.gridPanel.TabIndex = 0;
|
||||||
//
|
//
|
||||||
// navPanel
|
// navPanel
|
||||||
//
|
//
|
||||||
this.navPanel.Controls.Add(this.btnPrev);
|
this.navPanel.Controls.Add(this.btnPrev);
|
||||||
this.navPanel.Controls.Add(this.lblPage);
|
this.navPanel.Controls.Add(this.txtPage);
|
||||||
|
this.navPanel.Controls.Add(this.lblPageCount);
|
||||||
this.navPanel.Controls.Add(this.btnNext);
|
this.navPanel.Controls.Add(this.btnNext);
|
||||||
this.navPanel.Dock = System.Windows.Forms.DockStyle.Bottom;
|
this.navPanel.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||||
this.navPanel.Location = new System.Drawing.Point(0, 764);
|
this.navPanel.Location = new System.Drawing.Point(0, 764);
|
||||||
@@ -51,31 +54,44 @@ namespace OpenNest.Forms
|
|||||||
//
|
//
|
||||||
// btnPrev
|
// btnPrev
|
||||||
//
|
//
|
||||||
|
this.btnPrev.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||||
this.btnPrev.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
this.btnPrev.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
this.btnPrev.Location = new System.Drawing.Point(4, 4);
|
this.btnPrev.Location = new System.Drawing.Point(480, 4);
|
||||||
this.btnPrev.Name = "btnPrev";
|
this.btnPrev.Name = "btnPrev";
|
||||||
this.btnPrev.Size = new System.Drawing.Size(80, 28);
|
this.btnPrev.Size = new System.Drawing.Size(80, 28);
|
||||||
this.btnPrev.TabIndex = 0;
|
this.btnPrev.TabIndex = 0;
|
||||||
this.btnPrev.Text = "< Prev";
|
this.btnPrev.Text = "< Prev";
|
||||||
this.btnPrev.Click += new System.EventHandler(this.btnPrev_Click);
|
this.btnPrev.Click += new System.EventHandler(this.btnPrev_Click);
|
||||||
//
|
//
|
||||||
// lblPage
|
// txtPage
|
||||||
//
|
//
|
||||||
this.lblPage.Dock = System.Windows.Forms.DockStyle.Fill;
|
this.txtPage.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||||
this.lblPage.Name = "lblPage";
|
this.txtPage.Location = new System.Drawing.Point(564, 7);
|
||||||
this.lblPage.Size = new System.Drawing.Size(1200, 36);
|
this.txtPage.Name = "txtPage";
|
||||||
this.lblPage.TabIndex = 1;
|
this.txtPage.Size = new System.Drawing.Size(40, 20);
|
||||||
this.lblPage.Text = "Page 1 / 1";
|
this.txtPage.TabIndex = 1;
|
||||||
this.lblPage.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
this.txtPage.Text = "1";
|
||||||
|
this.txtPage.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||||
|
this.txtPage.KeyDown += new System.Windows.Forms.KeyEventHandler(this.txtPage_KeyDown);
|
||||||
|
//
|
||||||
|
// lblPageCount
|
||||||
|
//
|
||||||
|
this.lblPageCount.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||||
|
this.lblPageCount.Location = new System.Drawing.Point(606, 4);
|
||||||
|
this.lblPageCount.Name = "lblPageCount";
|
||||||
|
this.lblPageCount.Size = new System.Drawing.Size(50, 28);
|
||||||
|
this.lblPageCount.TabIndex = 2;
|
||||||
|
this.lblPageCount.Text = "/ 1";
|
||||||
|
this.lblPageCount.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||||
//
|
//
|
||||||
// btnNext
|
// btnNext
|
||||||
//
|
//
|
||||||
this.btnNext.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
|
this.btnNext.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||||
this.btnNext.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
this.btnNext.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
this.btnNext.Location = new System.Drawing.Point(1116, 4);
|
this.btnNext.Location = new System.Drawing.Point(660, 4);
|
||||||
this.btnNext.Name = "btnNext";
|
this.btnNext.Name = "btnNext";
|
||||||
this.btnNext.Size = new System.Drawing.Size(80, 28);
|
this.btnNext.Size = new System.Drawing.Size(80, 28);
|
||||||
this.btnNext.TabIndex = 2;
|
this.btnNext.TabIndex = 3;
|
||||||
this.btnNext.Text = "Next >";
|
this.btnNext.Text = "Next >";
|
||||||
this.btnNext.Click += new System.EventHandler(this.btnNext_Click);
|
this.btnNext.Click += new System.EventHandler(this.btnNext_Click);
|
||||||
//
|
//
|
||||||
@@ -90,7 +106,9 @@ namespace OpenNest.Forms
|
|||||||
this.Name = "BestFitViewerForm";
|
this.Name = "BestFitViewerForm";
|
||||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||||
this.Text = "Best-Fit Viewer";
|
this.Text = "Best-Fit Viewer";
|
||||||
|
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
|
||||||
this.navPanel.ResumeLayout(false);
|
this.navPanel.ResumeLayout(false);
|
||||||
|
this.navPanel.PerformLayout();
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,6 +116,7 @@ namespace OpenNest.Forms
|
|||||||
private System.Windows.Forms.Panel navPanel;
|
private System.Windows.Forms.Panel navPanel;
|
||||||
private System.Windows.Forms.Button btnPrev;
|
private System.Windows.Forms.Button btnPrev;
|
||||||
private System.Windows.Forms.Button btnNext;
|
private System.Windows.Forms.Button btnNext;
|
||||||
private System.Windows.Forms.Label lblPage;
|
private System.Windows.Forms.TextBox txtPage;
|
||||||
|
private System.Windows.Forms.Label lblPageCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,24 @@
|
|||||||
using OpenNest.Controls;
|
using OpenNest.Controls;
|
||||||
using OpenNest.Engine.BestFit;
|
using OpenNest.Engine.BestFit;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace OpenNest.Forms
|
namespace OpenNest.Forms
|
||||||
{
|
{
|
||||||
public partial class BestFitViewerForm : Form
|
public partial class BestFitViewerForm : Form
|
||||||
{
|
{
|
||||||
|
private const int WM_SETREDRAW = 0x000B;
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
|
||||||
|
|
||||||
private const int Columns = 5;
|
private const int Columns = 5;
|
||||||
private const int Rows = 2;
|
private const int Rows = 3;
|
||||||
private const int ItemsPerPage = Columns * Rows;
|
private const int ItemsPerPage = Columns * Rows;
|
||||||
private const int MaxResults = 50;
|
|
||||||
|
|
||||||
private static readonly Color KeptColor = Color.FromArgb(0, 0, 100);
|
private static readonly Color KeptColor = Color.FromArgb(0, 0, 100);
|
||||||
private static readonly Color DroppedColor = Color.FromArgb(100, 0, 0);
|
private static readonly Color DroppedColor = Color.FromArgb(100, 0, 0);
|
||||||
@@ -34,6 +40,7 @@ namespace OpenNest.Forms
|
|||||||
{
|
{
|
||||||
this.drawing = drawing;
|
this.drawing = drawing;
|
||||||
this.plate = plate;
|
this.plate = plate;
|
||||||
|
DoubleBuffered = true;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Shown += BestFitViewerForm_Shown;
|
Shown += BestFitViewerForm_Shown;
|
||||||
}
|
}
|
||||||
@@ -88,9 +95,8 @@ namespace OpenNest.Forms
|
|||||||
if (r.Keep) keptCount++;
|
if (r.Keep) keptCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var count = System.Math.Min(totalResults, MaxResults);
|
results = all;
|
||||||
results = all.GetRange(0, count);
|
pageCount = System.Math.Max(1, (int)System.Math.Ceiling(results.Count / (double)ItemsPerPage));
|
||||||
pageCount = System.Math.Max(1, (int)System.Math.Ceiling(count / (double)ItemsPerPage));
|
|
||||||
|
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
totalSeconds = sw.Elapsed.TotalSeconds;
|
totalSeconds = sw.Elapsed.TotalSeconds;
|
||||||
@@ -102,6 +108,9 @@ namespace OpenNest.Forms
|
|||||||
var start = page * ItemsPerPage;
|
var start = page * ItemsPerPage;
|
||||||
var count = System.Math.Min(ItemsPerPage, results.Count - start);
|
var count = System.Math.Min(ItemsPerPage, results.Count - start);
|
||||||
|
|
||||||
|
SendMessage(gridPanel.Handle, WM_SETREDRAW, IntPtr.Zero, IntPtr.Zero);
|
||||||
|
try
|
||||||
|
{
|
||||||
gridPanel.SuspendLayout();
|
gridPanel.SuspendLayout();
|
||||||
gridPanel.Controls.Clear();
|
gridPanel.Controls.Clear();
|
||||||
|
|
||||||
@@ -118,10 +127,17 @@ namespace OpenNest.Forms
|
|||||||
}
|
}
|
||||||
|
|
||||||
gridPanel.ResumeLayout(true);
|
gridPanel.ResumeLayout(true);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
SendMessage(gridPanel.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero);
|
||||||
|
gridPanel.Invalidate(true);
|
||||||
|
}
|
||||||
|
|
||||||
btnPrev.Enabled = currentPage > 0;
|
btnPrev.Enabled = currentPage > 0;
|
||||||
btnNext.Enabled = currentPage < pageCount - 1;
|
btnNext.Enabled = currentPage < pageCount - 1;
|
||||||
lblPage.Text = string.Format("Page {0} / {1}", currentPage + 1, pageCount);
|
txtPage.Text = (currentPage + 1).ToString();
|
||||||
|
lblPageCount.Text = string.Format("/ {0}", pageCount);
|
||||||
|
|
||||||
Text = string.Format("Best-Fit Viewer — {0} candidates ({1} kept) | Compute: {2:F1}s | Total: {3:F1}s | Showing {4}-{5} of {6}",
|
Text = string.Format("Best-Fit Viewer — {0} candidates ({1} kept) | Compute: {2:F1}s | Total: {3:F1}s | Showing {4}-{5} of {6}",
|
||||||
totalResults, keptCount, computeSeconds, totalSeconds,
|
totalResults, keptCount, computeSeconds, totalSeconds,
|
||||||
@@ -139,6 +155,18 @@ namespace OpenNest.Forms
|
|||||||
ShowPage(newPage);
|
ShowPage(newPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void txtPage_KeyDown(object sender, KeyEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.KeyCode == Keys.Enter)
|
||||||
|
{
|
||||||
|
e.SuppressKeyPress = true;
|
||||||
|
if (int.TryParse(txtPage.Text, out var page) && page >= 1 && page <= pageCount)
|
||||||
|
ShowPage(page - 1);
|
||||||
|
else
|
||||||
|
txtPage.Text = (currentPage + 1).ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private BestFitCell CreateCell(BestFitResult result, Drawing drawing, int rank)
|
private BestFitCell CreateCell(BestFitResult result, Drawing drawing, int rank)
|
||||||
{
|
{
|
||||||
var bgColor = result.Keep ? KeptColor : DroppedColor;
|
var bgColor = result.Keep ? KeptColor : DroppedColor;
|
||||||
|
|||||||
Reference in New Issue
Block a user