From 4e9b47ee4018e253ff7069cdb60ab24a9a0bde38 Mon Sep 17 00:00:00 2001 From: TheoryOfNekomata Date: Wed, 28 Apr 2021 10:21:10 +0800 Subject: [PATCH] Add configuration, use Direct2D, target .NET 5.0 The configuration window has been added. The screensaver now uses D2DForm as replacement for standard WinForms. The screensaver has been targeted to older .NET for compatibility. --- GameOfLife/GameOfLife.csproj | 11 +- GameOfLife/MainForm.Designer.cs | 1 - GameOfLife/MainForm.cs | 220 ++++++++++++------ GameOfLife/Program.cs | 17 +- GameOfLife/SettingsForm.Designer.cs | 344 ++++++++++++++++++++++++++++ GameOfLife/SettingsForm.cs | 72 ++++++ GameOfLife/SettingsForm.resx | 60 +++++ 7 files changed, 653 insertions(+), 72 deletions(-) create mode 100644 GameOfLife/SettingsForm.Designer.cs create mode 100644 GameOfLife/SettingsForm.cs create mode 100644 GameOfLife/SettingsForm.resx diff --git a/GameOfLife/GameOfLife.csproj b/GameOfLife/GameOfLife.csproj index 7b05c62..c1f01fb 100644 --- a/GameOfLife/GameOfLife.csproj +++ b/GameOfLife/GameOfLife.csproj @@ -2,8 +2,17 @@ WinExe - netcoreapp3.1 + net5.0-windows true + GameOfLife.Program + + x64 + + + + + + \ No newline at end of file diff --git a/GameOfLife/MainForm.Designer.cs b/GameOfLife/MainForm.Designer.cs index 0aab3aa..c8b5237 100644 --- a/GameOfLife/MainForm.Designer.cs +++ b/GameOfLife/MainForm.Designer.cs @@ -44,7 +44,6 @@ namespace GameOfLife this.Name = "MainForm"; this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; this.Load += new System.EventHandler(this.MainForm_Load); - this.Paint += new System.Windows.Forms.PaintEventHandler(this.MainForm_Paint); this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.MainForm_KeyPress); this.MouseClick += new System.Windows.Forms.MouseEventHandler(this.MainForm_MouseClick); this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.MainForm_MouseMove); diff --git a/GameOfLife/MainForm.cs b/GameOfLife/MainForm.cs index 97528bd..82d2a11 100644 --- a/GameOfLife/MainForm.cs +++ b/GameOfLife/MainForm.cs @@ -1,16 +1,18 @@ -using System; -using System.Collections.Generic; +using Microsoft.Win32; +using System; using System.Drawing; +using System.Runtime.InteropServices; using System.Windows.Forms; +using unvell.D2DLib; +using unvell.D2DLib.WinForm; namespace GameOfLife { - public partial class MainForm : Form + public partial class MainForm : D2DForm { private Point mouseLocation; private bool[,] newCells; - private bool[,] toggleCells; private bool[,] oldCells; private Random random; @@ -19,28 +21,125 @@ namespace GameOfLife private int magicCells = 0; - private double density = 0.35; + private double density = 0.5; - private int interval = 500; + private int interval = 100; + + // TODO color + //private int color; - public MainForm(Rectangle bounds) + private D2DRect boundsRect; + + private D2DRect cellRect; + + private int maxX; + + private int maxY; + + private int firstX; + private int lastX; + private int firstY; + private int lastY; + + private bool previewMode; + + [DllImport("user32.dll")] + static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); + + [DllImport("user32.dll")] + static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong); + + [DllImport("user32.dll", SetLastError = true)] + static extern int GetWindowLong(IntPtr hWnd, int nIndex); + + [DllImport("user32.dll")] + static extern bool GetClientRect(IntPtr hWnd, out Rectangle lpRect); + + + private void LoadSettings() { - InitializeComponent(); - random = new Random(); + RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\TheoryOfNekomata\\WindowsScreensavers\\GameOfLife"); + var retrievedGridSize = 3; + var retrievedSpores = 0; + int retrievedDensity = 50; + var retrievedInterval = 250; + var gridSizes = new int[] { 1, 2, 4, 8 }; + + if (key != null) + { + retrievedGridSize = (int)key.GetValue("GridSizeIndex", 3); + retrievedSpores = (int)key.GetValue("Spores", 0); + retrievedDensity = (int)key.GetValue("DensityPercentage", 50); + retrievedInterval = (int)key.GetValue("IntervalMs", 250); + } + + gridSize = gridSizes[retrievedGridSize]; + magicCells = retrievedSpores; + density = ((double)retrievedDensity) / 100.0; + interval = retrievedInterval; + } + + private void SetBounds(Rectangle bounds) { Bounds = bounds; - newCells = new bool[bounds.Width / gridSize, bounds.Height / gridSize]; - toggleCells = new bool[bounds.Width / gridSize, bounds.Height / gridSize]; - oldCells = new bool[bounds.Width / gridSize, bounds.Height / gridSize]; + boundsRect = new D2DRect(Bounds.Left, Bounds.Top, Bounds.Width, Bounds.Height); + } + + private void RandomizeCells() { + random = new Random(); + + maxX = Bounds.Width / gridSize; + maxY = Bounds.Height / gridSize; + + newCells = new bool[maxX, maxY]; + oldCells = new bool[maxX, maxY]; + + firstX = oldCells.GetLowerBound(0); + lastX = oldCells.GetUpperBound(0); + firstY = oldCells.GetLowerBound(1); + lastY = oldCells.GetUpperBound(1); - for (var x = 0; x < newCells.GetLength(0); x++) { - for (var y = 0; y < newCells.GetLength(1); y++) { + for (var x = 0; x < maxX; x++) + { + for (var y = 0; y < maxY; y++) + { newCells[x, y] = random.NextDouble() <= density; oldCells[x, y] = false; - toggleCells[x, y] = true; } } } + public MainForm(Rectangle bounds) + { + LoadSettings(); + InitializeComponent(); + SetBounds(bounds); + RandomizeCells(); + } + + public MainForm(IntPtr PreviewWndHandle) + { + LoadSettings(); + gridSize = 1; + magicCells = 0; + density = 0.5; + InitializeComponent(); + // Set the preview window as the parent of this window + SetParent(this.Handle, PreviewWndHandle); + + // Make this a child window so it will close when the parent dialog closes + // GWL_STYLE = -16, WS_CHILD = 0x40000000 + SetWindowLong(this.Handle, -16, new IntPtr(GetWindowLong(this.Handle, -16) | 0x40000000)); + + // Place our window inside the parent + Rectangle ParentRect; + GetClientRect(PreviewWndHandle, out ParentRect); + Size = ParentRect.Size; + Location = new Point(0, 0); + RandomizeCells(); + previewMode = true; + } + + private void MainForm_Load(object sender, EventArgs e) { Cursor.Hide(); @@ -53,64 +152,74 @@ namespace GameOfLife private void MainForm_MouseMove(object sender, MouseEventArgs e) { - if (!mouseLocation.IsEmpty) + if (!previewMode) { - // Terminate if mouse is moved a significant distance - if (Math.Abs(mouseLocation.X - e.X) > 5 || - Math.Abs(mouseLocation.Y - e.Y) > 5) - Application.Exit(); - } - - // Update current mouse location - mouseLocation = e.Location; + if (!mouseLocation.IsEmpty) + { + // Terminate if mouse is moved a significant distance + if (Math.Abs(mouseLocation.X - e.X) > 5 || + Math.Abs(mouseLocation.Y - e.Y) > 5) + Application.Exit(); + } + // Update current mouse location + mouseLocation = e.Location; + } } private void MainForm_MouseClick(object sender, MouseEventArgs e) { - Application.Exit(); + + if (!previewMode) + { + Application.Exit(); + } } private void MainForm_KeyPress(object sender, KeyPressEventArgs e) { - Application.Exit(); + + if (!previewMode) + { + Application.Exit(); + } } - private int GetAliveNeighbors(bool[,] cells, int x, int y) { - int prevX = x == cells.GetLowerBound(0) ? cells.GetUpperBound(0) : x - 1; - int nextX = x == cells.GetUpperBound(0) ? cells.GetLowerBound(0) : x + 1; - int prevY = y == cells.GetLowerBound(1) ? cells.GetUpperBound(1) : y - 1; - int nextY = y == cells.GetUpperBound(1) ? cells.GetLowerBound(1) : y + 1; + private int GetAliveNeighbors(int x, int y) { + int prevX = x == firstX ? lastX : x - 1; + int nextX = x == lastX ? firstX : x + 1; + int prevY = y == firstY ? lastY : y - 1; + int nextY = y == lastY ? firstY : y + 1; int aliveNeighbors = 0; - if (cells[prevX, prevY]) { + if (oldCells[prevX, prevY]) { aliveNeighbors += 1; } - if (cells[x, prevY]) + if (oldCells[x, prevY]) { aliveNeighbors += 1; } - if (cells[nextX, prevY]) + if (oldCells[nextX, prevY]) { aliveNeighbors += 1; } - if (cells[prevX, y]) + if (oldCells[prevX, y]) { aliveNeighbors += 1; } - if (cells[nextX, y]) + if (oldCells[nextX, y]) { aliveNeighbors += 1; } - if (cells[prevX, nextY]) + if (oldCells[prevX, nextY]) { aliveNeighbors += 1; } - if (cells[x, nextY]) + if (oldCells[x, nextY]) { aliveNeighbors += 1; } - if (cells[nextX, nextY]) + if (oldCells[nextX, nextY]) { aliveNeighbors += 1; } @@ -130,7 +239,7 @@ namespace GameOfLife { for (var y = 0; y < newCells.GetLength(1); y++) { - int neighbors = GetAliveNeighbors(oldCells, x, y); + int neighbors = GetAliveNeighbors(x, y); bool shouldLive = false; if (oldCells[x, y] && neighbors == 2) { @@ -140,7 +249,6 @@ namespace GameOfLife } newCells[x, y] = shouldLive; - toggleCells[x, y] = oldCells[x, y] == newCells[x, y]; } } @@ -149,41 +257,25 @@ namespace GameOfLife int magicY = random.Next(0, newCells.GetUpperBound(1)); newCells[magicX, magicY] = true; - toggleCells[magicX, magicY] = oldCells[magicX, magicY] == newCells[magicX, magicY]; } - - Redraw(CreateGraphics()); + Refresh(); } - private void Redraw(Graphics graphics) { - List liveCells = new List(); - List deadCells = new List(); + protected override void OnRender(D2DGraphics graphics) + { + graphics.FillRectangle(boundsRect, D2DColor.White); for (var x = 0; x < newCells.GetLength(0); x++) { for (var y = 0; y < newCells.GetLength(1); y++) { - if (newCells[x, y]) + if (!newCells[x, y]) { - liveCells.Add(new Rectangle(x * gridSize, y * gridSize, gridSize, gridSize)); + cellRect = new D2DRect(x * gridSize, y * gridSize, gridSize, gridSize); + graphics.FillRectangle(cellRect, D2DColor.Black); } - else { - deadCells.Add(new Rectangle(x * gridSize, y * gridSize, gridSize, gridSize)); - } - //else if (!newCells[x, y]) { - // graphics.FillRectangle(Brushes.Black, x * gridSize, y * gridSize, gridSize, gridSize); - //} } } - - graphics.FillRectangle(Brushes.Black, Bounds); - //graphics.FillRectangles(Brushes.Black, deadCells.ToArray()); - graphics.FillRectangles(Brushes.White, liveCells.ToArray()); - } - - private void MainForm_Paint(object sender, PaintEventArgs e) - { - Redraw(e.Graphics); } } } diff --git a/GameOfLife/Program.cs b/GameOfLife/Program.cs index ed16915..5512d95 100644 --- a/GameOfLife/Program.cs +++ b/GameOfLife/Program.cs @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using System.Windows.Forms; namespace GameOfLife @@ -35,11 +32,19 @@ namespace GameOfLife if (firstArgument == "/c") // Configuration mode { - // TODO + Application.Run(new SettingsForm()); } else if (firstArgument == "/p") // Preview mode { - // TODO + if (secondArgument == null) + { + MessageBox.Show("Sorry, but the expected window handle was not provided.", + "ScreenSaver", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + return; + } + + IntPtr previewWndHandle = new IntPtr(long.Parse(secondArgument)); + Application.Run(new MainForm(previewWndHandle)); } else if (firstArgument == "/s") // Full-screen mode { @@ -55,7 +60,7 @@ namespace GameOfLife } else // No arguments - treat like /c { - // TODO + Application.Run(new SettingsForm()); } } diff --git a/GameOfLife/SettingsForm.Designer.cs b/GameOfLife/SettingsForm.Designer.cs new file mode 100644 index 0000000..160e714 --- /dev/null +++ b/GameOfLife/SettingsForm.Designer.cs @@ -0,0 +1,344 @@ + +namespace GameOfLife +{ + partial class SettingsForm + { + /// + /// 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() + { + this.ctrlGridSize = new System.Windows.Forms.ComboBox(); + this.ctrlSpores = new System.Windows.Forms.NumericUpDown(); + this.ctrlInterval = new System.Windows.Forms.TrackBar(); + this.ctrlDensity = new System.Windows.Forms.TrackBar(); + this.lblSpores = new System.Windows.Forms.Label(); + this.lblGridSize = new System.Windows.Forms.Label(); + this.grpGridSize = new System.Windows.Forms.GroupBox(); + this.grpSpores = new System.Windows.Forms.GroupBox(); + this.grpDensity = new System.Windows.Forms.GroupBox(); + this.lblDensityValue = new System.Windows.Forms.Label(); + this.lblDensity = new System.Windows.Forms.Label(); + this.grpInterval = new System.Windows.Forms.GroupBox(); + this.lblIntervalValue = new System.Windows.Forms.Label(); + this.lblInterval = new System.Windows.Forms.Label(); + this.panelMain = new System.Windows.Forms.TableLayoutPanel(); + this.panelActions = new System.Windows.Forms.FlowLayoutPanel(); + this.btnOK = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)(this.ctrlSpores)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.ctrlInterval)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.ctrlDensity)).BeginInit(); + this.grpGridSize.SuspendLayout(); + this.grpSpores.SuspendLayout(); + this.grpDensity.SuspendLayout(); + this.grpInterval.SuspendLayout(); + this.panelMain.SuspendLayout(); + this.panelActions.SuspendLayout(); + this.SuspendLayout(); + // + // ctrlGridSize + // + this.ctrlGridSize.Dock = System.Windows.Forms.DockStyle.Top; + this.ctrlGridSize.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.ctrlGridSize.FormattingEnabled = true; + this.ctrlGridSize.Items.AddRange(new object[] { + "1", + "2", + "4", + "8"}); + this.ctrlGridSize.Location = new System.Drawing.Point(8, 70); + this.ctrlGridSize.Name = "ctrlGridSize"; + this.ctrlGridSize.Size = new System.Drawing.Size(177, 23); + this.ctrlGridSize.TabIndex = 1; + // + // ctrlSpores + // + this.ctrlSpores.Dock = System.Windows.Forms.DockStyle.Top; + this.ctrlSpores.Location = new System.Drawing.Point(8, 70); + this.ctrlSpores.Name = "ctrlSpores"; + this.ctrlSpores.Size = new System.Drawing.Size(178, 23); + this.ctrlSpores.TabIndex = 2; + // + // ctrlInterval + // + this.ctrlInterval.Dock = System.Windows.Forms.DockStyle.Top; + this.ctrlInterval.Location = new System.Drawing.Point(8, 70); + this.ctrlInterval.Maximum = 3000; + this.ctrlInterval.Minimum = 50; + this.ctrlInterval.Name = "ctrlInterval"; + this.ctrlInterval.Size = new System.Drawing.Size(177, 45); + this.ctrlInterval.TabIndex = 3; + this.ctrlInterval.TickFrequency = 250; + this.ctrlInterval.Value = 250; + this.ctrlInterval.Scroll += new System.EventHandler(this.ctrlInterval_Scroll); + // + // ctrlDensity + // + this.ctrlDensity.Dock = System.Windows.Forms.DockStyle.Top; + this.ctrlDensity.Location = new System.Drawing.Point(8, 70); + this.ctrlDensity.Maximum = 100; + this.ctrlDensity.Name = "ctrlDensity"; + this.ctrlDensity.Size = new System.Drawing.Size(178, 45); + this.ctrlDensity.TabIndex = 4; + this.ctrlDensity.TickFrequency = 10; + this.ctrlDensity.Value = 50; + this.ctrlDensity.Scroll += new System.EventHandler(this.ctrlDensity_Scroll); + // + // lblSpores + // + this.lblSpores.Dock = System.Windows.Forms.DockStyle.Top; + this.lblSpores.Location = new System.Drawing.Point(8, 24); + this.lblSpores.Name = "lblSpores"; + this.lblSpores.Padding = new System.Windows.Forms.Padding(0, 8, 0, 8); + this.lblSpores.Size = new System.Drawing.Size(178, 46); + this.lblSpores.TabIndex = 5; + this.lblSpores.Text = "This sets the count of live cells randomly spawning in the grid."; + // + // lblGridSize + // + this.lblGridSize.Dock = System.Windows.Forms.DockStyle.Top; + this.lblGridSize.Location = new System.Drawing.Point(8, 24); + this.lblGridSize.Name = "lblGridSize"; + this.lblGridSize.Padding = new System.Windows.Forms.Padding(0, 8, 0, 8); + this.lblGridSize.Size = new System.Drawing.Size(177, 46); + this.lblGridSize.TabIndex = 6; + this.lblGridSize.Text = "This is the size of each cell in pixels."; + // + // grpGridSize + // + this.grpGridSize.AutoSize = true; + this.grpGridSize.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.grpGridSize.Controls.Add(this.ctrlGridSize); + this.grpGridSize.Controls.Add(this.lblGridSize); + this.grpGridSize.Dock = System.Windows.Forms.DockStyle.Fill; + this.grpGridSize.Location = new System.Drawing.Point(8, 8); + this.grpGridSize.Margin = new System.Windows.Forms.Padding(8); + this.grpGridSize.Name = "grpGridSize"; + this.grpGridSize.Padding = new System.Windows.Forms.Padding(8); + this.grpGridSize.Size = new System.Drawing.Size(193, 146); + this.grpGridSize.TabIndex = 7; + this.grpGridSize.TabStop = false; + this.grpGridSize.Text = "Grid Size"; + // + // grpSpores + // + this.grpSpores.AutoSize = true; + this.grpSpores.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.grpSpores.Controls.Add(this.ctrlSpores); + this.grpSpores.Controls.Add(this.lblSpores); + this.grpSpores.Dock = System.Windows.Forms.DockStyle.Fill; + this.grpSpores.Location = new System.Drawing.Point(217, 170); + this.grpSpores.Margin = new System.Windows.Forms.Padding(8); + this.grpSpores.Name = "grpSpores"; + this.grpSpores.Padding = new System.Windows.Forms.Padding(8); + this.grpSpores.Size = new System.Drawing.Size(194, 147); + this.grpSpores.TabIndex = 8; + this.grpSpores.TabStop = false; + this.grpSpores.Text = "Spores"; + // + // grpDensity + // + this.grpDensity.AutoSize = true; + this.grpDensity.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.grpDensity.Controls.Add(this.lblDensityValue); + this.grpDensity.Controls.Add(this.ctrlDensity); + this.grpDensity.Controls.Add(this.lblDensity); + this.grpDensity.Dock = System.Windows.Forms.DockStyle.Fill; + this.grpDensity.Location = new System.Drawing.Point(217, 8); + this.grpDensity.Margin = new System.Windows.Forms.Padding(8); + this.grpDensity.Name = "grpDensity"; + this.grpDensity.Padding = new System.Windows.Forms.Padding(8); + this.grpDensity.Size = new System.Drawing.Size(194, 146); + this.grpDensity.TabIndex = 9; + this.grpDensity.TabStop = false; + this.grpDensity.Text = "Density"; + // + // lblDensityValue + // + this.lblDensityValue.Dock = System.Windows.Forms.DockStyle.Top; + this.lblDensityValue.Location = new System.Drawing.Point(8, 115); + this.lblDensityValue.Name = "lblDensityValue"; + this.lblDensityValue.Size = new System.Drawing.Size(178, 30); + this.lblDensityValue.TabIndex = 6; + this.lblDensityValue.Text = "Current Value: 50%"; + this.lblDensityValue.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // + // lblDensity + // + this.lblDensity.Dock = System.Windows.Forms.DockStyle.Top; + this.lblDensity.Location = new System.Drawing.Point(8, 24); + this.lblDensity.Name = "lblDensity"; + this.lblDensity.Padding = new System.Windows.Forms.Padding(0, 8, 0, 8); + this.lblDensity.Size = new System.Drawing.Size(178, 46); + this.lblDensity.TabIndex = 5; + this.lblDensity.Text = "This controls the starting density of live cells throughout the grid."; + // + // grpInterval + // + this.grpInterval.AutoSize = true; + this.grpInterval.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.grpInterval.Controls.Add(this.lblIntervalValue); + this.grpInterval.Controls.Add(this.ctrlInterval); + this.grpInterval.Controls.Add(this.lblInterval); + this.grpInterval.Dock = System.Windows.Forms.DockStyle.Fill; + this.grpInterval.Location = new System.Drawing.Point(8, 170); + this.grpInterval.Margin = new System.Windows.Forms.Padding(8); + this.grpInterval.Name = "grpInterval"; + this.grpInterval.Padding = new System.Windows.Forms.Padding(8); + this.grpInterval.Size = new System.Drawing.Size(193, 147); + this.grpInterval.TabIndex = 10; + this.grpInterval.TabStop = false; + this.grpInterval.Text = "Interval"; + // + // lblIntervalValue + // + this.lblIntervalValue.Dock = System.Windows.Forms.DockStyle.Top; + this.lblIntervalValue.Location = new System.Drawing.Point(8, 115); + this.lblIntervalValue.Name = "lblIntervalValue"; + this.lblIntervalValue.Size = new System.Drawing.Size(177, 30); + this.lblIntervalValue.TabIndex = 5; + this.lblIntervalValue.Text = "Current Value: 250ms"; + this.lblIntervalValue.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // + // lblInterval + // + this.lblInterval.Dock = System.Windows.Forms.DockStyle.Top; + this.lblInterval.Location = new System.Drawing.Point(8, 24); + this.lblInterval.Name = "lblInterval"; + this.lblInterval.Padding = new System.Windows.Forms.Padding(0, 8, 0, 8); + this.lblInterval.Size = new System.Drawing.Size(177, 46); + this.lblInterval.TabIndex = 4; + this.lblInterval.Text = "This specifies how often the screen updates."; + // + // panelMain + // + this.panelMain.AutoSize = true; + this.panelMain.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.panelMain.ColumnCount = 2; + this.panelMain.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.panelMain.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.panelMain.Controls.Add(this.grpDensity, 1, 0); + this.panelMain.Controls.Add(this.grpSpores, 1, 1); + this.panelMain.Controls.Add(this.grpInterval, 0, 1); + this.panelMain.Controls.Add(this.grpGridSize, 0, 0); + this.panelMain.Dock = System.Windows.Forms.DockStyle.Fill; + this.panelMain.Location = new System.Drawing.Point(0, 0); + this.panelMain.Name = "panelMain"; + this.panelMain.RowCount = 2; + this.panelMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.panelMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.panelMain.Size = new System.Drawing.Size(419, 325); + this.panelMain.TabIndex = 11; + // + // panelActions + // + this.panelActions.AutoSize = true; + this.panelActions.BackColor = System.Drawing.SystemColors.Window; + this.panelActions.Controls.Add(this.btnOK); + this.panelActions.Controls.Add(this.btnCancel); + this.panelActions.Dock = System.Windows.Forms.DockStyle.Bottom; + this.panelActions.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft; + this.panelActions.Location = new System.Drawing.Point(0, 325); + this.panelActions.Margin = new System.Windows.Forms.Padding(0); + this.panelActions.Name = "panelActions"; + this.panelActions.Size = new System.Drawing.Size(419, 39); + this.panelActions.TabIndex = 12; + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point(340, 8); + this.btnOK.Margin = new System.Windows.Forms.Padding(4, 8, 4, 8); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(75, 23); + this.btnOK.TabIndex = 0; + this.btnOK.Text = "O&K"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // btnCancel + // + this.btnCancel.Location = new System.Drawing.Point(257, 8); + this.btnCancel.Margin = new System.Windows.Forms.Padding(4, 8, 4, 8); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(75, 23); + this.btnCancel.TabIndex = 1; + this.btnCancel.Text = "C&ancel"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); + // + // SettingsForm + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size(419, 364); + this.Controls.Add(this.panelMain); + this.Controls.Add(this.panelActions); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "SettingsForm"; + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Game of Life Settings"; + ((System.ComponentModel.ISupportInitialize)(this.ctrlSpores)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.ctrlInterval)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.ctrlDensity)).EndInit(); + this.grpGridSize.ResumeLayout(false); + this.grpSpores.ResumeLayout(false); + this.grpDensity.ResumeLayout(false); + this.grpDensity.PerformLayout(); + this.grpInterval.ResumeLayout(false); + this.grpInterval.PerformLayout(); + this.panelMain.ResumeLayout(false); + this.panelMain.PerformLayout(); + this.panelActions.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + private System.Windows.Forms.ComboBox ctrlGridSize; + private System.Windows.Forms.NumericUpDown ctrlSpores; + private System.Windows.Forms.TrackBar ctrlInterval; + private System.Windows.Forms.TrackBar ctrlDensity; + private System.Windows.Forms.Label lblSpores; + private System.Windows.Forms.Label lblGridSize; + private System.Windows.Forms.GroupBox grpGridSize; + private System.Windows.Forms.GroupBox grpSpores; + private System.Windows.Forms.GroupBox grpDensity; + private System.Windows.Forms.Label lblDensity; + private System.Windows.Forms.GroupBox grpInterval; + private System.Windows.Forms.Label lblInterval; + private System.Windows.Forms.TableLayoutPanel panelMain; + private System.Windows.Forms.Label lblDensityValue; + private System.Windows.Forms.Label lblIntervalValue; + private System.Windows.Forms.FlowLayoutPanel panelActions; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + } +} \ No newline at end of file diff --git a/GameOfLife/SettingsForm.cs b/GameOfLife/SettingsForm.cs new file mode 100644 index 0000000..80ebb2d --- /dev/null +++ b/GameOfLife/SettingsForm.cs @@ -0,0 +1,72 @@ +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace GameOfLife +{ + public partial class SettingsForm : Form + { + private void LoadSettings() { + RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\TheoryOfNekomata\\WindowsScreensavers\\GameOfLife"); + object retrievedGridSize = 3; + object retrievedSpores = 0; + object retrievedDensity = 50; + object retrievedInterval = 250; + + if (key != null) + { + retrievedGridSize = key.GetValue("GridSizeIndex", 3); + retrievedSpores = key.GetValue("Spores", 0); + retrievedDensity = key.GetValue("DensityPercentage", 50); + retrievedInterval = key.GetValue("IntervalMs", 250); + } + + ctrlGridSize.SelectedIndex = (int) retrievedGridSize; + ctrlSpores.Value = decimal.Parse(retrievedSpores.ToString()); + ctrlDensity.Value = (int)retrievedDensity; + lblDensityValue.Text = string.Format("Current Value: {0}%", ctrlDensity.Value); + ctrlInterval.Value = (int)retrievedInterval; + lblIntervalValue.Text = string.Format("Current Value: {0}ms", ctrlInterval.Value); + } + + private void SaveSettings() { + RegistryKey key = Registry.CurrentUser.CreateSubKey("SOFTWARE\\TheoryOfNekomata\\WindowsScreensavers\\GameOfLife"); + key.SetValue("GridSizeIndex", ctrlGridSize.SelectedIndex); + key.SetValue("Spores", int.Parse(ctrlSpores.Value.ToString())); + key.SetValue("DensityPercentage", ctrlDensity.Value); + key.SetValue("IntervalMs", ctrlInterval.Value); + } + + public SettingsForm() + { + InitializeComponent(); + LoadSettings(); + } + + private void ctrlDensity_Scroll(object sender, EventArgs e) + { + lblDensityValue.Text = string.Format("Current Value: {0}%", (sender as TrackBar).Value); + } + + private void ctrlInterval_Scroll(object sender, EventArgs e) + { + lblIntervalValue.Text = string.Format("Current Value: {0}ms", (sender as TrackBar).Value); + } + + private void btnOK_Click(object sender, EventArgs e) + { + SaveSettings(); + Close(); + } + + private void btnCancel_Click(object sender, EventArgs e) + { + Close(); + } + } +} diff --git a/GameOfLife/SettingsForm.resx b/GameOfLife/SettingsForm.resx new file mode 100644 index 0000000..b5ae26c --- /dev/null +++ b/GameOfLife/SettingsForm.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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