Browse Source

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.
master
TheoryOfNekomata 3 years ago
parent
commit
4e9b47ee40
7 changed files with 653 additions and 72 deletions
  1. +10
    -1
      GameOfLife/GameOfLife.csproj
  2. +0
    -1
      GameOfLife/MainForm.Designer.cs
  3. +156
    -64
      GameOfLife/MainForm.cs
  4. +11
    -6
      GameOfLife/Program.cs
  5. +344
    -0
      GameOfLife/SettingsForm.Designer.cs
  6. +72
    -0
      GameOfLife/SettingsForm.cs
  7. +60
    -0
      GameOfLife/SettingsForm.resx

+ 10
- 1
GameOfLife/GameOfLife.csproj View File

@@ -2,8 +2,17 @@
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net5.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<StartupObject>GameOfLife.Program</StartupObject>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="unvell.D2DLib-x64" Version="1.3.1" />
</ItemGroup>
</Project>

+ 0
- 1
GameOfLife/MainForm.Designer.cs View File

@@ -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);


+ 156
- 64
GameOfLife/MainForm.cs View File

@@ -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<Rectangle> liveCells = new List<Rectangle>();
List<Rectangle> deadCells = new List<Rectangle>();
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);
}
}
}

+ 11
- 6
GameOfLife/Program.cs View File

@@ -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());
}
}


+ 344
- 0
GameOfLife/SettingsForm.Designer.cs View File

@@ -0,0 +1,344 @@

namespace GameOfLife
{
partial class SettingsForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
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;
}
}

+ 72
- 0
GameOfLife/SettingsForm.cs View File

@@ -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();
}
}
}

+ 60
- 0
GameOfLife/SettingsForm.resx View File

@@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

Loading…
Cancel
Save