diff --git a/OpenNest/Forms/BestFitViewerForm.Designer.cs b/OpenNest/Forms/BestFitViewerForm.Designer.cs index a53a48a..e977148 100644 --- a/OpenNest/Forms/BestFitViewerForm.Designer.cs +++ b/OpenNest/Forms/BestFitViewerForm.Designer.cs @@ -14,11 +14,15 @@ namespace OpenNest.Forms private void InitializeComponent() { this.gridPanel = new System.Windows.Forms.TableLayoutPanel(); + this.navPanel = new System.Windows.Forms.Panel(); + this.btnPrev = new System.Windows.Forms.Button(); + this.btnNext = new System.Windows.Forms.Button(); + this.lblPage = new System.Windows.Forms.Label(); + this.navPanel.SuspendLayout(); this.SuspendLayout(); // // gridPanel // - this.gridPanel.AutoScroll = true; this.gridPanel.ColumnCount = 5; this.gridPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 20F)); this.gridPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 20F)); @@ -28,24 +32,72 @@ namespace OpenNest.Forms this.gridPanel.Dock = System.Windows.Forms.DockStyle.Fill; this.gridPanel.Location = new System.Drawing.Point(0, 0); this.gridPanel.Name = "gridPanel"; - this.gridPanel.RowCount = 1; - this.gridPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.gridPanel.Size = new System.Drawing.Size(1200, 800); + this.gridPanel.RowCount = 2; + 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, 50F)); + this.gridPanel.Size = new System.Drawing.Size(1200, 764); this.gridPanel.TabIndex = 0; // + // navPanel + // + this.navPanel.Controls.Add(this.btnPrev); + this.navPanel.Controls.Add(this.lblPage); + this.navPanel.Controls.Add(this.btnNext); + this.navPanel.Dock = System.Windows.Forms.DockStyle.Bottom; + this.navPanel.Location = new System.Drawing.Point(0, 764); + this.navPanel.Name = "navPanel"; + this.navPanel.Size = new System.Drawing.Size(1200, 36); + this.navPanel.TabIndex = 1; + // + // btnPrev + // + this.btnPrev.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnPrev.Location = new System.Drawing.Point(4, 4); + this.btnPrev.Name = "btnPrev"; + this.btnPrev.Size = new System.Drawing.Size(80, 28); + this.btnPrev.TabIndex = 0; + this.btnPrev.Text = "< Prev"; + this.btnPrev.Click += new System.EventHandler(this.btnPrev_Click); + // + // lblPage + // + this.lblPage.Dock = System.Windows.Forms.DockStyle.Fill; + this.lblPage.Name = "lblPage"; + this.lblPage.Size = new System.Drawing.Size(1200, 36); + this.lblPage.TabIndex = 1; + this.lblPage.Text = "Page 1 / 1"; + this.lblPage.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // btnNext + // + this.btnNext.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right; + this.btnNext.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnNext.Location = new System.Drawing.Point(1116, 4); + this.btnNext.Name = "btnNext"; + this.btnNext.Size = new System.Drawing.Size(80, 28); + this.btnNext.TabIndex = 2; + this.btnNext.Text = "Next >"; + this.btnNext.Click += new System.EventHandler(this.btnNext_Click); + // // BestFitViewerForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(1200, 800); this.Controls.Add(this.gridPanel); + this.Controls.Add(this.navPanel); this.KeyPreview = true; this.Name = "BestFitViewerForm"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Best-Fit Viewer"; + this.navPanel.ResumeLayout(false); this.ResumeLayout(false); } private System.Windows.Forms.TableLayoutPanel gridPanel; + private System.Windows.Forms.Panel navPanel; + private System.Windows.Forms.Button btnPrev; + private System.Windows.Forms.Button btnNext; + private System.Windows.Forms.Label lblPage; } } diff --git a/OpenNest/Forms/BestFitViewerForm.cs b/OpenNest/Forms/BestFitViewerForm.cs index 2b52a4d..5d590a7 100644 --- a/OpenNest/Forms/BestFitViewerForm.cs +++ b/OpenNest/Forms/BestFitViewerForm.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Windows.Forms; @@ -9,7 +10,8 @@ namespace OpenNest.Forms public partial class BestFitViewerForm : Form { private const int Columns = 5; - private const int RowHeight = 300; + private const int Rows = 2; + private const int ItemsPerPage = Columns * Rows; private const int MaxResults = 50; private static readonly Color KeptColor = Color.FromArgb(0, 0, 100); @@ -18,6 +20,14 @@ namespace OpenNest.Forms private readonly Drawing drawing; private readonly Plate plate; + private List results; + private int totalResults; + private int keptCount; + private double computeSeconds; + private double totalSeconds; + private int currentPage; + private int pageCount; + public BestFitResult SelectedResult { get; private set; } public BestFitViewerForm(Drawing drawing, Plate plate) @@ -33,7 +43,8 @@ namespace OpenNest.Forms Cursor = Cursors.WaitCursor; try { - PopulateGrid(drawing, plate); + ComputeResults(); + ShowPage(0); } finally { @@ -48,51 +59,84 @@ namespace OpenNest.Forms Close(); return true; } + if (keyData == Keys.Left || keyData == Keys.PageUp) + { + NavigatePage(-1); + return true; + } + if (keyData == Keys.Right || keyData == Keys.PageDown) + { + NavigatePage(1); + return true; + } return base.ProcessCmdKey(ref msg, keyData); } - private void PopulateGrid(Drawing drawing, Plate plate) + private void ComputeResults() { var sw = Stopwatch.StartNew(); - var results = BestFitCache.GetOrCompute( + var all = BestFitCache.GetOrCompute( drawing, plate.Size.Width, plate.Size.Length, plate.PartSpacing); - var findMs = sw.ElapsedMilliseconds; - var total = results.Count; - var kept = 0; + computeSeconds = sw.ElapsedMilliseconds / 1000.0; + totalResults = all.Count; + keptCount = 0; - foreach (var r in results) + foreach (var r in all) { - if (r.Keep) kept++; + if (r.Keep) keptCount++; } - var count = System.Math.Min(total, MaxResults); - var rows = (int)System.Math.Ceiling(count / (double)Columns); - gridPanel.RowCount = rows; - gridPanel.RowStyles.Clear(); - - for (var i = 0; i < rows; i++) - gridPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, RowHeight)); - - gridPanel.SuspendLayout(); - try - { - for (var i = 0; i < count; i++) - { - var result = results[i]; - var cell = CreateCell(result, drawing, i + 1); - gridPanel.Controls.Add(cell, i % Columns, i / Columns); - } - } - finally - { - gridPanel.ResumeLayout(true); - } + var count = System.Math.Min(totalResults, MaxResults); + results = all.GetRange(0, count); + pageCount = System.Math.Max(1, (int)System.Math.Ceiling(count / (double)ItemsPerPage)); sw.Stop(); - Text = string.Format("Best-Fit Viewer — {0} candidates ({1} kept) | Compute: {2:F1}s | Total: {3:F1}s | Showing {4}", - total, kept, findMs / 1000.0, sw.Elapsed.TotalSeconds, count); + totalSeconds = sw.Elapsed.TotalSeconds; + } + + private void ShowPage(int page) + { + currentPage = page; + var start = page * ItemsPerPage; + var count = System.Math.Min(ItemsPerPage, results.Count - start); + + gridPanel.SuspendLayout(); + gridPanel.Controls.Clear(); + + gridPanel.RowCount = Rows; + gridPanel.RowStyles.Clear(); + for (var i = 0; i < Rows; i++) + gridPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f / Rows)); + + for (var i = 0; i < count; i++) + { + var result = results[start + i]; + var cell = CreateCell(result, drawing, start + i + 1); + gridPanel.Controls.Add(cell, i % Columns, i / Columns); + } + + gridPanel.ResumeLayout(true); + + btnPrev.Enabled = currentPage > 0; + btnNext.Enabled = currentPage < pageCount - 1; + lblPage.Text = string.Format("Page {0} / {1}", currentPage + 1, pageCount); + + 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, + start + 1, start + count, results.Count); + } + + private void btnPrev_Click(object sender, System.EventArgs e) => NavigatePage(-1); + + private void btnNext_Click(object sender, System.EventArgs e) => NavigatePage(1); + + private void NavigatePage(int delta) + { + var newPage = currentPage + delta; + if (newPage >= 0 && newPage < pageCount) + ShowPage(newPage); } private BestFitCell CreateCell(BestFitResult result, Drawing drawing, int rank)