Skip to content

Commit

Permalink
Port to Silverlight 3 on Visual Studio 2008.
Browse files Browse the repository at this point in the history
  • Loading branch information
PKRoma committed Oct 11, 2012
1 parent 4076a86 commit 7d3ae84
Show file tree
Hide file tree
Showing 19 changed files with 190 additions and 80 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.user
*.suo
ClientBin/
obj/
8 changes: 8 additions & 0 deletions App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SilverlightSudokuHelper.App"
>
<Application.Resources>

</Application.Resources>
</Application>
57 changes: 57 additions & 0 deletions App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System;
using System.Windows;

namespace SilverlightSudokuHelper
{
public partial class App : Application
{

public App()
{
this.Startup += this.Application_Startup;
this.Exit += this.Application_Exit;
this.UnhandledException += this.Application_UnhandledException;

InitializeComponent();
}

private void Application_Startup(object sender, StartupEventArgs e)
{
this.RootVisual = new Page();
}

private void Application_Exit(object sender, EventArgs e)
{

}
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
// If the app is running outside of the debugger then report the exception using
// the browser's exception mechanism. On IE this will display it a yellow alert
// icon in the status bar and Firefox will display a script error.
if (!System.Diagnostics.Debugger.IsAttached)
{

// NOTE: This will allow the application to continue running after an exception has been thrown
// but not handled.
// For production applications this error handling should be replaced with something that will
// report the error to the website and stop the application.
e.Handled = true;
Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); });
}
}
private void ReportErrorToDOM(ApplicationUnhandledExceptionEventArgs e)
{
try
{
string errorMsg = e.ExceptionObject.Message + e.ExceptionObject.StackTrace;
errorMsg = errorMsg.Replace('"', '\'').Replace("\r\n", @"\n");

System.Windows.Browser.HtmlPage.Window.Eval("throw new Error(\"Unhandled Error in Silverlight Application " + errorMsg + "\");");
}
catch (Exception)
{
}
}
}
}
20 changes: 15 additions & 5 deletions BoardDisplay.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
using System;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightSudokuHelper
{
internal class BoardDisplay : Control
internal class BoardDisplay : UserControl
{
private const int MarkerMargin = 2;
private const string FontFamily = "Arial";
private FontFamily FontFamily = new FontFamily("Arial");

private bool _candidatesVisible = true;
private Canvas _root;
Expand All @@ -30,7 +31,7 @@ internal class BoardDisplay : Control
public BoardDisplay()
{
// Initialize from XAML and get references to child elements
_root = InitializeFromXaml(Utility.GetXamlResource("SilverlightSudokuHelper.BoardDisplay.xaml")) as Canvas;
_root = XamlReader.Load(Utility.GetXamlResource("SilverlightSudokuHelper.BoardDisplay.xaml")) as Canvas;
_fadeStoryboard = _root.FindName("FadeStoryboard") as Storyboard;
_fadeAnimation = _root.FindName("FadeAnimation") as DoubleAnimation;

Expand Down Expand Up @@ -92,7 +93,10 @@ public BoardDisplay()
}

// Handle the Loaded event to do layout
Loaded += new EventHandler(HandleLoaded);
Loaded += new RoutedEventHandler(HandleLoaded);

// Attach the constructed object to make it visible
Content = _root;
}

private void HandleLoaded(object sender, EventArgs e)
Expand All @@ -103,6 +107,12 @@ private void HandleLoaded(object sender, EventArgs e)

public void Layout()
{
// Do nothing if Width is NaN
if (Double.IsNaN(Width))
{
return;
}

// Resize the frame and lines to fill the control
_frame.Width = Width;
_frame.Height = Height;
Expand Down
2 changes: 1 addition & 1 deletion BoardDisplay.xaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Canvas xmlns="http://schemas.microsoft.com/client/2007"
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="canvas">
<Canvas.Resources>
Expand Down
2 changes: 1 addition & 1 deletion Default.html.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
function createSilverlight()
{
Silverlight.createObjectEx({
source: "Page.xaml",
source: "ClientBin/SilverlightSudokuHelper.xap",
parentElement: document.getElementById("SilverlightControlHost"),
id: "SilverlightControl",
properties: {
Expand Down
8 changes: 5 additions & 3 deletions Marker.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using System.Windows.Controls;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightSudokuHelper
{
internal class Marker : Control
internal class Marker : UserControl
{
private Canvas _root;
private Rectangle _background;
Expand All @@ -14,10 +15,11 @@ internal class Marker : Control
public Marker(string resourceName)
{
// Initialize from XAML and get references to child elements
_root = InitializeFromXaml(Utility.GetXamlResource(resourceName)) as Canvas;
_root = XamlReader.Load(Utility.GetXamlResource(resourceName)) as Canvas;
_background = _root.FindName("Background") as Rectangle;
_border = _root.FindName("Border") as Rectangle;
_pulse = _root.FindName("Pulse") as Storyboard; // May fail
Content = _root;
}

public void Layout()
Expand Down
2 changes: 1 addition & 1 deletion MarkerConflict.xaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Canvas xmlns="http://schemas.microsoft.com/client/2007"
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="canvas">
<Rectangle x:Name="Background"
Expand Down
2 changes: 1 addition & 1 deletion MarkerSelection.xaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Canvas xmlns="http://schemas.microsoft.com/client/2007"
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Rectangle x:Name="Background"
Opacity="0.8"
Expand Down
4 changes: 2 additions & 2 deletions Page.xaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Canvas xmlns="http://schemas.microsoft.com/client/2007"
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SilverlightSudokuHelper.Page;assembly=ClientBin/SilverlightSudokuHelper.dll"
x:Class="SilverlightSudokuHelper.Page"
Loaded="Page_Loaded">
<MediaElement x:Name="mediaElement" />
</Canvas>
78 changes: 42 additions & 36 deletions Page.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Controls;
Expand Down Expand Up @@ -59,12 +59,18 @@ private enum SoundEffect { New, Move, Conflict, Complete };
// _fadingBoardDisplay renders the previous board and fades away when changes are made
private BoardDisplay _fadingBoardDisplay;
private double _defaultVolume;
private Content BrowserHost;

public Page()
{
InitializeComponent();
}

public void Page_Loaded(object o, EventArgs e)
{
// Initialize variables
InitializeComponent();
_defaultVolume = mediaElement.Volume;
BrowserHost = App.Current.Host.Content;

// Initialize UI
_primaryBoardDisplay = new BoardDisplay();
Expand All @@ -73,40 +79,40 @@ public void Page_Loaded(object o, EventArgs e)
Children.Add(_fadingBoardDisplay);

// Initialize handlers
KeyUp += new KeyboardEventHandler(HandleKeyUp);
MouseLeftButtonDown += new MouseEventHandler(HandleMouseLeftButtonDown);
BrowserHost.Resize += new EventHandler(HandleResize);
KeyUp += new KeyEventHandler(HandleKeyUp);
MouseLeftButtonDown += new MouseButtonEventHandler(HandleMouseLeftButtonDown);
BrowserHost.Resized += new EventHandler(HandleResize);

// Create the starting board, play the "new" sound, and fade it in
_primaryBoardDisplay.Board = Board.FromString(BoardWikipediaSample);
PlaySoundEffect(SoundEffect.New);
_fadingBoardDisplay.Fade(FadeSecondsLoading);
}

private void HandleKeyUp(object sender, KeyboardEventArgs e)
private void HandleKeyUp(object sender, KeyEventArgs e)
{
switch (e.Key)
{
case 8: // Escape
case Key.Escape: // Escape
_primaryBoardDisplay.Solve();
break;
case 14: // Left arrow
case 15: // Up arrow
case 16: // Right arrow
case 17: // Down arrow
case Key.Left: // Left arrow
case Key.Up: // Up arrow
case Key.Right: // Right arrow
case Key.Down: // Down arrow
// Move the marker
var markerPosition = _primaryBoardDisplay.MarkerPosition;
switch (e.Key)
{
case 14: markerPosition.X--; break;
case 15: markerPosition.Y--; break;
case 16: markerPosition.X++; break;
case 17: markerPosition.Y++; break;
case Key.Left: markerPosition.X--; break;
case Key.Up: markerPosition.Y--; break;
case Key.Right: markerPosition.X++; break;
case Key.Down: markerPosition.Y++; break;
}
_primaryBoardDisplay.MarkerPosition = markerPosition;
_fadingBoardDisplay.MarkerPosition = markerPosition;
break;
case 19: // Delete
case Key.Delete: // Delete
// Clear the cell's value
PrepareFade();
if (_primaryBoardDisplay.ChangeSelectedValue(Digit.Unknown, Digit.Kind.Normal))
Expand All @@ -116,18 +122,18 @@ private void HandleKeyUp(object sender, KeyboardEventArgs e)
_fadingBoardDisplay.Fade(FadeSecondsNormal);
}
break;
case 21: // 1
case 22: // 2
case 23: // 3
case 24: // 4
case 25: // 5
case 26: // 6
case 27: // 7
case 28: // 8
case 29: // 9
case Key.D1: // 1
case Key.D2: // 2
case Key.D3: // 3
case Key.D4: // 4
case Key.D5: // 5
case Key.D6: // 6
case Key.D7: // 7
case Key.D8: // 8
case Key.D9: // 9
// Set the cell's value
PrepareFade();
if (_primaryBoardDisplay.ChangeSelectedValue(e.Key - 20, (e.Shift ? Digit.Kind.Given : (e.Ctrl ? Digit.Kind.Guess : Digit.Kind.Normal))))
if (_primaryBoardDisplay.ChangeSelectedValue(e.Key - Key.D0, ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift ? Digit.Kind.Given : ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control ? Digit.Kind.Guess : Digit.Kind.Normal))))
{
// Normal move; play the appropriate sound and fade it
PlaySoundEffect(_primaryBoardDisplay.Board.Complete ? SoundEffect.Complete : SoundEffect.Move);
Expand All @@ -139,25 +145,25 @@ private void HandleKeyUp(object sender, KeyboardEventArgs e)
PlaySoundEffect(SoundEffect.Conflict);
}
break;
case 31: // B
case 35: // F
case 48: // S
case 52: // W
case Key.B: // B
case Key.F: // F
case Key.S: // S
case Key.W: // W
// Switch to the specified board
PrepareFade();
var boardString = "";
switch (e.Key)
{
case 31: boardString = BoardBlank; break;
case 35: boardString = BoardAlmostFinished; break;
case 48: boardString = BoardSudopediaSample; break;
case 52: boardString = BoardWikipediaSample; break;
case Key.B: boardString = BoardBlank; break;
case Key.F: boardString = BoardAlmostFinished; break;
case Key.S: boardString = BoardSudopediaSample; break;
case Key.W: boardString = BoardWikipediaSample; break;
}
_primaryBoardDisplay.Board = Board.FromString(boardString);
PlaySoundEffect(SoundEffect.New);
_fadingBoardDisplay.Fade(FadeSecondsNormal);
break;
case 32: // C
case Key.C: // C
// Toggle the candidate display
PrepareFade();
_primaryBoardDisplay.CandidatesVisible = !_primaryBoardDisplay.CandidatesVisible;
Expand Down Expand Up @@ -205,7 +211,7 @@ private void PlaySoundEffect(SoundEffect soundEffect)
break;
}
// Set the source and play the sound
mediaElement.Source = new Uri(HtmlPage.DocumentUri, soundFile);
mediaElement.Source = new Uri(HtmlPage.Document.DocumentUri, soundFile);
mediaElement.Play();
}

Expand Down
7 changes: 7 additions & 0 deletions Properties/AppManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Deployment.Parts>
</Deployment.Parts>

</Deployment>
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Silverlight Sudoku with LINQ

A port to Silverlight 3 of the original code published in 2007 by Richard
Birkby, which itself is a merge of his Sudoku solver using LINQ, based on
Peter Norvig's work, with David Anson's Silverlight Sudoku Helper program.
The respective articles can be found here:

* Richard Birkby: [C# Nuggets : Silverlight Sudoku with LINQ](http://aspadvice.com/blogs/rbirkby/archive/2007/08/23/Silverlight-Sudoku-with-LINQ.aspx)
* David Anson: [Time for a little fun and games (Silverlight helps play Sudoku!) - Delay's Blog - Site Home - MSDN Blogs](http://blogs.msdn.com/b/delay/archive/2007/08/21/time-for-a-little-fun-and-games-silverlight-helps-play-sudoku.aspx)
* Peter Norvig: [Solving Every Sudoku Puzzle](http://www.norvig.com/sudoku.html)

0 comments on commit 7d3ae84

Please sign in to comment.