diff --git a/NumberRecognizer/NumberRecognizer.App/App.xaml b/NumberRecognizer/NumberRecognizer.App/App.xaml new file mode 100644 index 0000000..06378af --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/App.xaml @@ -0,0 +1,17 @@ + + + + + + + + + Number Recognizer + + + diff --git a/NumberRecognizer/NumberRecognizer.App/App.xaml.cs b/NumberRecognizer/NumberRecognizer.App/App.xaml.cs new file mode 100644 index 0000000..f99e129 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/App.xaml.cs @@ -0,0 +1,126 @@ +//----------------------------------------------------------------------- +// +// Copyright Markus Zytek. All rights reserved. +// +// Markus Zytek +// App. +//----------------------------------------------------------------------- +namespace NumberRecognizer.App +{ + using System; + using NumberRecognizer.App.Common; + using NumberRecognizer.App.View; + using Windows.ApplicationModel; + using Windows.ApplicationModel.Activation; + using Windows.UI.Xaml; + using Windows.UI.Xaml.Controls; + using Windows.UI.Xaml.Navigation; + + /// + /// Provides application-specific behavior to supplement the default Application class. + /// + public sealed partial class App : Application + { + /// + /// Initializes a new instance of the class. + /// + public App() + { + this.InitializeComponent(); + this.Suspending += this.OnSuspending; + } + + /// + /// Gets the root frame. + /// + /// + /// The root frame. + /// + public static Frame RootFrame { get; private set; } + + /// + /// Invoked when Navigation to a certain page fails. + /// + /// The Frame which failed navigation. + /// Details about the navigation failure. + public void OnNavigationFailed(object sender, NavigationFailedEventArgs e) + { + throw new Exception("Failed to load Page " + e.SourcePageType.FullName); + } + + /// + /// Invoked when the application is launched normally by the end user. Other entry points + /// will be used such as when the application is launched to open a specific storageFile. + /// + /// Details about the launch request and process. + protected override async void OnLaunched(LaunchActivatedEventArgs e) + { +#if DEBUG + // Show graphics profiling information while debugging. + if (System.Diagnostics.Debugger.IsAttached) + { + // Display the current frame rate counters + this.DebugSettings.EnableFrameRateCounter = true; + } +#endif + + RootFrame = Window.Current.Content as Frame; + + //// Do not repeat app initialization when the Window already has content, + //// just ensure that the window is active + + if (RootFrame == null) + { + //// Create a Frame to act as the navigation context and navigate to the first page + RootFrame = new Frame(); + ////Associate the frame with a SuspensionManager key + SuspensionManager.RegisterFrame(RootFrame, "AppFrame"); + //// Set the default language + RootFrame.Language = Windows.Globalization.ApplicationLanguages.Languages[0]; + + RootFrame.NavigationFailed += this.OnNavigationFailed; + + if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) + { + //// Restore the saved session state only when appropriate + try + { + await SuspensionManager.RestoreAsync(); + } + catch (SuspensionManagerException) + { + ////Something went wrong restoring state. + ////Assume there is no state and continue + } + } + + // Place the frame in the current Window + Window.Current.Content = RootFrame; + } + + if (RootFrame.Content == null) + { + // When the navigation stack isn't restored navigate to the first page, + // configuring the new page by passing required information as a navigation + // parameter + RootFrame.Navigate(typeof(GroupedNetworksPage), e.Arguments); + } + //// Ensure the current window is active + Window.Current.Activate(); + } + + /// + /// Invoked when application execution is being suspended. Application state is saved + /// without knowing whether the application will be terminated or resumed with the contents + /// of memory still intact. + /// + /// The source of the suspend request. + /// Details about the suspend request. + private async void OnSuspending(object sender, SuspendingEventArgs e) + { + var deferral = e.SuspendingOperation.GetDeferral(); + await SuspensionManager.SaveAsync(); + deferral.Complete(); + } + } +} diff --git a/NumberRecognizer/NumberRecognizer.App/Assets/Logo.scale-100.png b/NumberRecognizer/NumberRecognizer.App/Assets/Logo.scale-100.png new file mode 100644 index 0000000..ad9a6a6 Binary files /dev/null and b/NumberRecognizer/NumberRecognizer.App/Assets/Logo.scale-100.png differ diff --git a/NumberRecognizer/NumberRecognizer.App/Assets/SmallLogo.scale-100.png b/NumberRecognizer/NumberRecognizer.App/Assets/SmallLogo.scale-100.png new file mode 100644 index 0000000..dfec380 Binary files /dev/null and b/NumberRecognizer/NumberRecognizer.App/Assets/SmallLogo.scale-100.png differ diff --git a/NumberRecognizer/NumberRecognizer.App/Assets/SplashScreen.scale-100.png b/NumberRecognizer/NumberRecognizer.App/Assets/SplashScreen.scale-100.png new file mode 100644 index 0000000..ff6de24 Binary files /dev/null and b/NumberRecognizer/NumberRecognizer.App/Assets/SplashScreen.scale-100.png differ diff --git a/NumberRecognizer/NumberRecognizer.App/Assets/StoreLogo.scale-100.png b/NumberRecognizer/NumberRecognizer.App/Assets/StoreLogo.scale-100.png new file mode 100644 index 0000000..193299c Binary files /dev/null and b/NumberRecognizer/NumberRecognizer.App/Assets/StoreLogo.scale-100.png differ diff --git a/NumberRecognizer/NumberRecognizer.App/Common/LoadStateEventArgs.cs b/NumberRecognizer/NumberRecognizer.App/Common/LoadStateEventArgs.cs new file mode 100644 index 0000000..f1f4960 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Common/LoadStateEventArgs.cs @@ -0,0 +1,46 @@ +//----------------------------------------------------------------------- +// +// Copyright Markus Zytek. All rights reserved. +// +// Markus Zytek +// Load State Event Args. +//----------------------------------------------------------------------- +namespace NumberRecognizer.App.Common +{ + using System; + using System.Collections.Generic; + + /// + /// Class used to hold the event data required when a page attempts to load state. + /// + public class LoadStateEventArgs : EventArgs + { + /// + /// Initializes a new instance of the class. + /// + /// The navigation parameter. + /// State of the page. + public LoadStateEventArgs(object navigationParameter, Dictionary pageState) + : base() + { + this.NavigationParameter = navigationParameter; + this.PageState = pageState; + } + + /// + /// Gets the navigation parameter. + /// + /// + /// The navigation parameter. + /// + public object NavigationParameter { get; private set; } + + /// + /// Gets the state of the page. + /// + /// + /// The state of the page. + /// + public Dictionary PageState { get; private set; } + } +} diff --git a/NumberRecognizer/NumberRecognizer.App/Common/NavigationHelper.cs b/NumberRecognizer/NumberRecognizer.App/Common/NavigationHelper.cs new file mode 100644 index 0000000..cb12532 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Common/NavigationHelper.cs @@ -0,0 +1,425 @@ +//----------------------------------------------------------------------- +// +// Copyright Markus Zytek. All rights reserved. +// +// Markus Zytek +// Navigation Helper. +//----------------------------------------------------------------------- +namespace NumberRecognizer.App.Common +{ + using System.Collections.Generic; + using Windows.System; + using Windows.UI.Core; + using Windows.UI.Xaml; + using Windows.UI.Xaml.Controls; + using Windows.UI.Xaml.Navigation; + + /// + /// Represents the method that will handle the event. + /// + /// The sender. + /// The instance containing the event data. + public delegate void LoadStateEventHandler(object sender, LoadStateEventArgs e); + + /// + /// Represents the method that will handle the event. + /// + /// The sender. + /// The instance containing the event data. + public delegate void SaveStateEventHandler(object sender, SaveStateEventArgs e); + + /// + /// NavigationHelper aids in navigation between pages. It provides commands used to + /// navigate back and forward as well as registers for standard mouse and keyboard + /// shortcuts used to go back and forward in Windows and the hardware back button in + /// Windows Phone. In addition it integrates SuspensionManger to handle process lifetime + /// management and state management when navigating between pages. + /// + /// + /// To make use of NavigationHelper, follow these two steps or + /// start with a BasicPage or any other Page item template other than BlankPage. + /// 1) Create an instance of the NavigationHelper somewhere such as in the + /// constructor for the page and register a callback for the LoadState and + /// SaveState events. + /// + /// public MyPage() + /// { + /// this.InitializeComponent(); + /// var navigationHelper = new NavigationHelper(this); + /// this.navigationHelper.LoadState += NavigationHelper_LoadState; + /// this.navigationHelper.SaveState += NavigationHelper_SaveState; + /// } + /// + /// private async void NavigationHelper_LoadState(object sender, LoadStateEventArgs e) + /// { } + /// private async void NavigationHelper_SaveState(object sender, LoadStateEventArgs e) + /// { } + /// + /// 2) Register the page to call into the NavigationHelper whenever the page participates + /// in navigation by overriding the + /// and events. + /// + /// protected override void OnNavigatedTo(NavigationEventArgs e) + /// { + /// navigationHelper.OnNavigatedTo(e); + /// } + /// + /// protected override void OnNavigatedFrom(NavigationEventArgs e) + /// { + /// navigationHelper.OnNavigatedFrom(e); + /// } + /// + /// + [Windows.Foundation.Metadata.WebHostHidden] + public class NavigationHelper : DependencyObject + { + /// + /// The go back command. + /// + private RelayCommand goBackCommand; + + /// + /// The go forward command. + /// + private RelayCommand goForwardCommand; + + /// + /// The _page key. + /// + private string pageKey; + + /// + /// Initializes a new instance of the class. + /// + /// A reference to the current page used for navigation. + /// This reference allows for frame manipulation and to ensure that keyboard + /// navigation requests only occur when the page is occupying the entire window. + public NavigationHelper(Page page) + { + this.Page = page; + + // When this page is part of the visual tree make two changes: + // 1) Map application view state to visual state for the page + // 2) Handle hardware navigation requests + this.Page.Loaded += (sender, e) => + { +#if WINDOWS_PHONE_APP + Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed; +#else + // Keyboard and mouse navigation only apply when occupying the entire window + if (this.Page.ActualHeight == Window.Current.Bounds.Height && + this.Page.ActualWidth == Window.Current.Bounds.Width) + { + // Listen to the window directly so focus isn't required + Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated += + CoreDispatcher_AcceleratorKeyActivated; + Window.Current.CoreWindow.PointerPressed += + this.CoreWindow_PointerPressed; + } +#endif + }; + + // Undo the same changes when the page is no longer visible + this.Page.Unloaded += (sender, e) => + { +#if WINDOWS_PHONE_APP + Windows.Phone.UI.Input.HardwareButtons.BackPressed -= HardwareButtons_BackPressed; +#else + Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated -= + CoreDispatcher_AcceleratorKeyActivated; + Window.Current.CoreWindow.PointerPressed -= + this.CoreWindow_PointerPressed; +#endif + }; + } + + /// + /// Register this event on the current page to populate the page + /// with content passed during navigation as well as any saved + /// state provided when recreating a page from a prior session. + /// + public event LoadStateEventHandler LoadState; + + /// + /// Register this event on the current page to preserve + /// state associated with the current page in case the + /// application is suspended or the page is discarded from + /// the navigation cache. + /// + public event SaveStateEventHandler SaveState; + + /// + /// Gets or sets the go back command. + /// + /// + /// The go back command. + /// + public RelayCommand GoBackCommand + { + get + { + if (this.goBackCommand == null) + { + this.goBackCommand = new RelayCommand( + () => this.GoBack(), + () => this.CanGoBack()); + } + + return this.goBackCommand; + } + + set + { + this.goBackCommand = value; + } + } + + /// + /// Gets the go forward command. + /// + /// + /// The go forward command. + /// + public RelayCommand GoForwardCommand + { + get + { + if (this.goForwardCommand == null) + { + this.goForwardCommand = new RelayCommand( + () => this.GoForward(), + () => this.CanGoForward()); + } + + return this.goForwardCommand; + } + } + + /// + /// Gets or sets the page. + /// + /// + /// The page field. + /// + private Page Page { get; set; } + + /// + /// Gets the frame. + /// + /// + /// The frame. + /// + private Frame Frame + { + get + { + return this.Page.Frame; + } + } + + /// + /// Virtual method used by the property + /// to determine if the can go back. + /// + /// + /// True if the has at least one entry + /// in the back navigation history. + /// + public virtual bool CanGoBack() + { + return this.Frame != null && this.Frame.CanGoBack; + } + + /// + /// Virtual method used by the property + /// to determine if the can go forward. + /// + /// + /// True if the has at least one entry + /// in the forward navigation history. + /// + public virtual bool CanGoForward() + { + return this.Frame != null && this.Frame.CanGoForward; + } + + /// + /// Virtual method used by the property + /// to invoke the method. + /// + public virtual void GoBack() + { + if (this.Frame != null && this.Frame.CanGoBack) + { + this.Frame.GoBack(); + } + } + + /// + /// Virtual method used by the property + /// to invoke the method. + /// + public virtual void GoForward() + { + if (this.Frame != null && this.Frame.CanGoForward) + { + this.Frame.GoForward(); + } + } + + /// + /// Invoked when this page is about to be displayed in a Frame. + /// This method calls , where all page specific + /// navigation and process lifetime management logic should be placed. + /// + /// Event data that describes how this page was reached. The Parameter + /// property provides the group to be displayed. + public void OnNavigatedTo(NavigationEventArgs e) + { + var frameState = SuspensionManager.SessionStateForFrame(this.Frame); + this.pageKey = "Page-" + this.Frame.BackStackDepth; + + if (e.NavigationMode == NavigationMode.New) + { + // Clear existing state for forward navigation when adding a new page to the + // navigation stack + var nextPageKey = this.pageKey; + int nextPageIndex = this.Frame.BackStackDepth; + while (frameState.Remove(nextPageKey)) + { + nextPageIndex++; + nextPageKey = "Page-" + nextPageIndex; + } + + // Pass the navigation parameter to the new page + if (this.LoadState != null) + { + this.LoadState(this, new LoadStateEventArgs(e.Parameter, null)); + } + } + else + { + // Pass the navigation parameter and preserved page state to the page, using + // the same strategy for loading suspended state and recreating pages discarded + // from cache + if (this.LoadState != null) + { + this.LoadState(this, new LoadStateEventArgs(e.Parameter, (Dictionary)frameState[this.pageKey])); + } + } + } + + /// + /// Invoked when this page will no longer be displayed in a Frame. + /// This method calls , where all page specific + /// navigation and process lifetime management logic should be placed. + /// + /// Event data that describes how this page was reached. The Parameter + /// property provides the group to be displayed. + public void OnNavigatedFrom(NavigationEventArgs e) + { + var frameState = SuspensionManager.SessionStateForFrame(this.Frame); + var pageState = new Dictionary(); + if (this.SaveState != null) + { + this.SaveState(this, new SaveStateEventArgs(pageState)); + } + + frameState[this.pageKey] = pageState; + } + +#if WINDOWS_PHONE_APP + /// + /// Invoked when the hardware back button is pressed. For Windows Phone only. + /// + /// Instance that triggered the event. + /// Event data describing the conditions that led to the event. + private void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e) + { + if (this.GoBackCommand.CanExecute(null)) + { + e.Handled = true; + this.GoBackCommand.Execute(null); + } + } +#else + /// + /// Invoked on every keystroke, including system keys such as Alt key combinations, when + /// this page is active and occupies the entire window. Used to detect keyboard navigation + /// between pages even when the page itself doesn't have focus. + /// + /// Instance that triggered the event. + /// Event data describing the conditions that led to the event. + private void CoreDispatcher_AcceleratorKeyActivated(CoreDispatcher sender, AcceleratorKeyEventArgs e) + { + var virtualKey = e.VirtualKey; + + // Only investigate further when Left, Right, or the dedicated Previous or Next keys + // are pressed + if ((e.EventType == CoreAcceleratorKeyEventType.SystemKeyDown || + e.EventType == CoreAcceleratorKeyEventType.KeyDown) && + (virtualKey == VirtualKey.Left || virtualKey == VirtualKey.Right || + (int)virtualKey == 166 || (int)virtualKey == 167)) + { + var coreWindow = Window.Current.CoreWindow; + var downState = CoreVirtualKeyStates.Down; + bool menuKey = (coreWindow.GetKeyState(VirtualKey.Menu) & downState) == downState; + bool controlKey = (coreWindow.GetKeyState(VirtualKey.Control) & downState) == downState; + bool shiftKey = (coreWindow.GetKeyState(VirtualKey.Shift) & downState) == downState; + bool noModifiers = !menuKey && !controlKey && !shiftKey; + bool onlyAlt = menuKey && !controlKey && !shiftKey; + + if (((int)virtualKey == 166 && noModifiers) || + (virtualKey == VirtualKey.Left && onlyAlt)) + { + // When the previous key or Alt+Left are pressed navigate back + e.Handled = true; + this.GoBackCommand.Execute(null); + } + else if (((int)virtualKey == 167 && noModifiers) || + (virtualKey == VirtualKey.Right && onlyAlt)) + { + // When the next key or Alt+Right are pressed navigate forward + e.Handled = true; + this.GoForwardCommand.Execute(null); + } + } + } + + /// + /// Invoked on every mouse click, touch screen tap, or equivalent interaction when this + /// page is active and occupies the entire window. Used to detect browser-style next and + /// previous mouse button clicks to navigate between pages. + /// + /// Instance that triggered the event. + /// Event data describing the conditions that led to the event. + private void CoreWindow_PointerPressed(CoreWindow sender, PointerEventArgs e) + { + var properties = e.CurrentPoint.Properties; + + // Ignore button chords with the left, right, and middle buttons + if (properties.IsLeftButtonPressed || properties.IsRightButtonPressed || properties.IsMiddleButtonPressed) + { + return; + } + + // If back or foward are pressed (but not both) navigate appropriately + bool backPressed = properties.IsXButton1Pressed; + bool forwardPressed = properties.IsXButton2Pressed; + if (backPressed ^ forwardPressed) + { + e.Handled = true; + if (backPressed) + { + this.GoBackCommand.Execute(null); + } + + if (forwardPressed) + { + this.GoForwardCommand.Execute(null); + } + } + } +#endif + } +} diff --git a/NumberRecognizer/NumberRecognizer.App/Common/ObservableDictionary.cs b/NumberRecognizer/NumberRecognizer.App/Common/ObservableDictionary.cs new file mode 100644 index 0000000..1753bf8 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Common/ObservableDictionary.cs @@ -0,0 +1,299 @@ +//----------------------------------------------------------------------- +// +// Copyright Markus Zytek. All rights reserved. +// +// Markus Zytek +// Observable Dictionary. +//----------------------------------------------------------------------- +namespace NumberRecognizer.App.Common +{ + using System; + using System.Collections.Generic; + using System.Linq; + using Windows.Foundation.Collections; + + /// + /// Implementation of IObservableMap that supports reentrancy for use as a default view + /// model. + /// + public class ObservableDictionary : IObservableMap + { + /// + /// The dictionary. + /// + private Dictionary dictionary = new Dictionary(); + + /// + /// Occurs when [map changed]. + /// + public event MapChangedEventHandler MapChanged; + + /// + /// Gets an containing the keys of the . + /// + /// + /// The keys property. + /// + public ICollection Keys + { + get { return this.dictionary.Keys; } + } + + /// + /// Gets an containing the values in the . + /// + /// + /// The values property. + /// + public ICollection Values + { + get + { + return this.dictionary.Values; + } + } + + /// + /// Gets the number of elements contained in the . + /// + /// + /// The count property. + /// + public int Count + { + get + { + return this.dictionary.Count; + } + } + + /// + /// Gets a value indicating whether the is read-only. + /// + /// + /// The IsReadOnly property. + /// + public bool IsReadOnly + { + get + { + return false; + } + } + + /// + /// Gets or sets the element with the specified key. + /// + /// The key property. + /// The object. + public object this[string key] + { + get + { + return this.dictionary[key]; + } + + set + { + this.dictionary[key] = value; + this.InvokeMapChanged(CollectionChange.ItemChanged, key); + } + } + + /// + /// Adds an element with the provided key and value to the . + /// + /// The object to use as the key of the element to add. + /// The object to use as the value of the element to add. + public void Add(string key, object value) + { + this.dictionary.Add(key, value); + this.InvokeMapChanged(CollectionChange.ItemInserted, key); + } + + /// + /// Adds an item to the . + /// + /// The object to add to the . + public void Add(KeyValuePair item) + { + this.Add(item.Key, item.Value); + } + + /// + /// Removes the element with the specified key from the . + /// + /// The key of the element to remove. + /// + /// True if the element is successfully removed; otherwise, false. This method also returns false if was not found in the original . + /// + public bool Remove(string key) + { + if (this.dictionary.Remove(key)) + { + this.InvokeMapChanged(CollectionChange.ItemRemoved, key); + return true; + } + + return false; + } + + /// + /// Removes the first occurrence of a specific object from the . + /// + /// The object to remove from the . + /// + /// True if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original . + /// + public bool Remove(KeyValuePair item) + { + object currentValue; + if (this.dictionary.TryGetValue(item.Key, out currentValue) && + object.Equals(item.Value, currentValue) && this.dictionary.Remove(item.Key)) + { + this.InvokeMapChanged(CollectionChange.ItemRemoved, item.Key); + return true; + } + + return false; + } + + /// + /// Removes all items from the . + /// + public void Clear() + { + var priorKeys = this.dictionary.Keys.ToArray(); + this.dictionary.Clear(); + foreach (var key in priorKeys) + { + this.InvokeMapChanged(CollectionChange.ItemRemoved, key); + } + } + + /// + /// Determines whether the contains an element with the specified key. + /// + /// The key to locate in the . + /// + /// True if the contains an element with the key; otherwise, false. + /// + public bool ContainsKey(string key) + { + return this.dictionary.ContainsKey(key); + } + + /// + /// Gets the value associated with the specified key. + /// + /// The key whose value to get. + /// When this method returns, the value associated with the specified key, if the key is found; otherwise, the default value for the type of the parameter. This parameter is passed uninitialized. + /// + /// True if the object that implements contains an element with the specified key; otherwise, false. + /// + public bool TryGetValue(string key, out object value) + { + return this.dictionary.TryGetValue(key, out value); + } + + /// + /// Determines whether the contains a specific value. + /// + /// The object to locate in the . + /// + /// True if is found in the ; otherwise, false. + /// + public bool Contains(KeyValuePair item) + { + return this.dictionary.Contains(item); + } + + /// + /// Returns an enumerator that iterates through the collection. + /// + /// + /// A that can be used to iterate through the collection. + /// + public IEnumerator> GetEnumerator() + { + return this.dictionary.GetEnumerator(); + } + + /// + /// Returns an enumerator that iterates through a collection. + /// + /// + /// An object that can be used to iterate through the collection. + /// + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return this.dictionary.GetEnumerator(); + } + + /// + /// Copies to. + /// + /// The array. + /// Index of the array. + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + int arraySize = array.Length; + foreach (var pair in this.dictionary) + { + if (arrayIndex >= arraySize) + { + break; + } + + array[arrayIndex++] = pair; + } + } + + /// + /// Invokes the map changed. + /// + /// The change parameter. + /// The key parameter. + private void InvokeMapChanged(CollectionChange change, string key) + { + var eventHandler = this.MapChanged; + if (eventHandler != null) + { + eventHandler(this, new ObservableDictionaryChangedEventArgs(change, key)); + } + } + + /// + /// Observable Dictionary Changed Event Args. + /// + private class ObservableDictionaryChangedEventArgs : IMapChangedEventArgs + { + /// + /// Initializes a new instance of the class. + /// + /// The change parameter. + /// The key parameter. + public ObservableDictionaryChangedEventArgs(CollectionChange change, string key) + { + this.CollectionChange = change; + this.Key = key; + } + + /// + /// Gets collection change. + /// + /// + /// The collection change. + /// + public CollectionChange CollectionChange { get; private set; } + + /// + /// Gets the key. + /// + /// + /// The key property. + /// + public string Key { get; private set; } + } + } +} diff --git a/NumberRecognizer/NumberRecognizer.App/Common/RelayCommand.cs b/NumberRecognizer/NumberRecognizer.App/Common/RelayCommand.cs new file mode 100644 index 0000000..b766bfe --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Common/RelayCommand.cs @@ -0,0 +1,97 @@ +//----------------------------------------------------------------------- +// +// Copyright Markus Zytek. All rights reserved. +// +// Markus Zytek +// The Relay Command. +//----------------------------------------------------------------------- +namespace NumberRecognizer.App.Common +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + using System.Windows.Input; + + /// + /// Relay Command. + /// + public class RelayCommand : ICommand + { + /// + /// The execute. + /// + private readonly Action execute; + + /// + /// The can execute. + /// + private readonly Func canExecute; + + /// + /// Initializes a new instance of the class. + /// + /// The execution logic. + public RelayCommand(Action execute) + : this(execute, null) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The execution logic. + /// The execution status logic. + public RelayCommand(Action execute, Func canExecute) + { + if (execute == null) + { + throw new ArgumentNullException("execute"); + } + + this.execute = execute; + this.canExecute = canExecute; + } + + /// + /// Raised when RaiseCanExecuteChanged is called. + /// + public event EventHandler CanExecuteChanged; + + /// + /// Determines whether this can execute in its current state. + /// + /// + /// Data used by the command. If the command does not require data to be passed, this object can be set to null. + /// + /// true if this command can be executed; otherwise, false. + public bool CanExecute(object parameter) + { + return this.canExecute == null ? true : this.canExecute(); + } + + /// + /// Executes the on the current command target. + /// + /// + /// Data used by the command. If the command does not require data to be passed, this object can be set to null. + /// + public void Execute(object parameter) + { + this.execute(); + } + + /// + /// Raises the can execute changed. + /// + public void RaiseCanExecuteChanged() + { + var handler = this.CanExecuteChanged; + if (handler != null) + { + handler(this, EventArgs.Empty); + } + } + } +} \ No newline at end of file diff --git a/NumberRecognizer/NumberRecognizer.App/Common/SaveStateEventArgs.cs b/NumberRecognizer/NumberRecognizer.App/Common/SaveStateEventArgs.cs new file mode 100644 index 0000000..a3a9373 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Common/SaveStateEventArgs.cs @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------- +// +// Copyright Markus Zytek. All rights reserved. +// +// Markus Zytek +// Save State Event Args. +//----------------------------------------------------------------------- +namespace NumberRecognizer.App.Common +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + /// + /// Class used to hold the event data required when a page attempts to save state. + /// + public class SaveStateEventArgs : EventArgs + { + /// + /// Initializes a new instance of the class. + /// + /// An empty dictionary to be populated with serializable state. + public SaveStateEventArgs(Dictionary pageState) + : base() + { + this.PageState = pageState; + } + + /// + /// Gets the state of the page. + /// + /// + /// The state of the page. + /// + public Dictionary PageState { get; private set; } + } +} diff --git a/NumberRecognizer/NumberRecognizer.App/Common/SuspensionManager.cs b/NumberRecognizer/NumberRecognizer.App/Common/SuspensionManager.cs new file mode 100644 index 0000000..7db3617 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Common/SuspensionManager.cs @@ -0,0 +1,298 @@ +//----------------------------------------------------------------------- +// +// Copyright Markus Zytek. All rights reserved. +// +// Markus Zytek +// The Supension Manager. +//----------------------------------------------------------------------- +namespace NumberRecognizer.App.Common +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Runtime.Serialization; + using System.Threading.Tasks; + using Windows.Storage; + using Windows.Storage.Streams; + using Windows.UI.Xaml; + using Windows.UI.Xaml.Controls; + + /// + /// SuspensionManager captures global session state to simplify process lifetime management + /// for an application. Note that session state will be automatically cleared under a variety + /// of conditions and should only be used to store information that would be convenient to + /// carry across sessions, but that should be discarded when an application crashes or is + /// upgraded. + /// + internal sealed class SuspensionManager + { + /// + /// The session state filename. + /// + private const string SessionStateFilename = "_sessionState.xml"; + + /// + /// The session state. + /// + private static Dictionary sessionState = new Dictionary(); + + /// + /// The known types. + /// + private static List knownTypes = new List(); + + /// + /// The frame session state key property. + /// + private static DependencyProperty frameSessionStateKeyProperty = + DependencyProperty.RegisterAttached("_FrameSessionStateKey", typeof(string), typeof(SuspensionManager), null); + + /// + /// The frame session base key property. + /// + private static DependencyProperty frameSessionBaseKeyProperty = + DependencyProperty.RegisterAttached("_FrameSessionBaseKeyParams", typeof(string), typeof(SuspensionManager), null); + + /// + /// The frame session state property. + /// + private static DependencyProperty frameSessionStateProperty = + DependencyProperty.RegisterAttached("_FrameSessionState", typeof(Dictionary), typeof(SuspensionManager), null); + + /// + /// The _registered frames. + /// + private static List> registeredFrames = new List>(); + + /// + /// Gets Provides access to global session state for the current session. This state is + /// serialized by and restored by + /// , so values must be serializable by + /// and should be as compact as possible. Strings + /// and other self-contained data types are strongly recommended. + /// + public static Dictionary SessionState + { + get { return sessionState; } + } + + /// + /// Gets List of custom types provided to the when + /// reading and writing session state. Initially empty, additional types may be + /// added to customize the serialization process. + /// + public static List KnownTypes + { + get { return knownTypes; } + } + + /// + /// Save the current . Any instances + /// registered with will also preserve their current + /// navigation stack, which in turn gives their active an opportunity + /// to save its state. + /// + /// An asynchronous task that reflects when session state has been saved. + public static async Task SaveAsync() + { + try + { + // Save the navigation state for all registered frames + foreach (var weakFrameReference in registeredFrames) + { + Frame frame; + if (weakFrameReference.TryGetTarget(out frame)) + { + SaveFrameNavigationState(frame); + } + } + + // Serialize the session state synchronously to avoid asynchronous access to shared + // state + MemoryStream sessionData = new MemoryStream(); + DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary), knownTypes); + serializer.WriteObject(sessionData, sessionState); + + // Get an output randomAccessStream for the SessionState storageFile and write the state asynchronously + StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(SessionStateFilename, CreationCollisionOption.ReplaceExisting); + using (Stream fileStream = await file.OpenStreamForWriteAsync()) + { + sessionData.Seek(0, SeekOrigin.Begin); + await sessionData.CopyToAsync(fileStream); + } + } + catch (Exception e) + { + throw new SuspensionManagerException(e); + } + } + + /// + /// Restores previously saved . Any instances + /// registered with will also restore their prior navigation + /// state, which in turn gives their active an opportunity restore its + /// state. + /// + /// An optional key that identifies the type of session. + /// This can be used to distinguish between multiple application launch scenarios. + /// An asynchronous task that reflects when session state has been read. The + /// content of should not be relied upon until this task + /// completes. + public static async Task RestoreAsync(string sessionBaseKey = null) + { + sessionState = new Dictionary(); + + try + { + // Get the input randomAccessStream for the SessionState storageFile + StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(SessionStateFilename); + using (IInputStream inStream = await file.OpenSequentialReadAsync()) + { + // Deserialize the Session State + DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary), knownTypes); + sessionState = (Dictionary)serializer.ReadObject(inStream.AsStreamForRead()); + } + + // Restore any registered frames to their saved state + foreach (var weakFrameReference in registeredFrames) + { + Frame frame; + if (weakFrameReference.TryGetTarget(out frame) && (string)frame.GetValue(frameSessionBaseKeyProperty) == sessionBaseKey) + { + frame.ClearValue(frameSessionStateProperty); + RestoreFrameNavigationState(frame); + } + } + } + catch (Exception e) + { + throw new SuspensionManagerException(e); + } + } + + /// + /// Registers a instance to allow its navigation history to be saved to + /// and restored from . Frames should be registered once + /// immediately after creation if they will participate in session state management. Upon + /// registration if state has already been restored for the specified key + /// the navigation history will immediately be restored. Subsequent invocations of + /// will also restore navigation history. + /// + /// An instance whose navigation history should be managed by + /// + /// A unique key into used to + /// store navigation-related information. + /// An optional key that identifies the type of session. + /// This can be used to distinguish between multiple application launch scenarios. + public static void RegisterFrame(Frame frame, string sessionStateKey, string sessionBaseKey = null) + { + if (frame.GetValue(frameSessionStateKeyProperty) != null) + { + throw new InvalidOperationException("Frames can only be registered to one session state key"); + } + + if (frame.GetValue(frameSessionStateProperty) != null) + { + throw new InvalidOperationException("Frames must be either be registered before accessing frame session state, or not registered at all"); + } + + if (!string.IsNullOrEmpty(sessionBaseKey)) + { + frame.SetValue(frameSessionBaseKeyProperty, sessionBaseKey); + sessionStateKey = sessionBaseKey + "_" + sessionStateKey; + } + + // Use a dependency property to associate the session key with a frame, and keep a list of frames whose + // navigation state should be managed + frame.SetValue(frameSessionStateKeyProperty, sessionStateKey); + registeredFrames.Add(new WeakReference(frame)); + + // Check to see if navigation state can be restored + RestoreFrameNavigationState(frame); + } + + /// + /// Disassociates a previously registered by + /// from . Any navigation state previously captured will be + /// removed. + /// + /// An instance whose navigation history should no longer be + /// managed. + public static void UnregisterFrame(Frame frame) + { + // Remove session state and remove the frame from the list of frames whose navigation + // state will be saved (along with any weak references that are no longer reachable) + SessionState.Remove((string)frame.GetValue(frameSessionStateKeyProperty)); + registeredFrames.RemoveAll((weakFrameReference) => + { + Frame testFrame; + return !weakFrameReference.TryGetTarget(out testFrame) || testFrame == frame; + }); + } + + /// + /// Provides storage for session state associated with the specified . + /// Frames that have been previously registered with have + /// their session state saved and restored automatically as a part of the global + /// . Frames that are not registered have transient state + /// that can still be useful when restoring pages that have been discarded from the + /// navigation cache. + /// + /// Apps may choose to rely on to manage + /// page-specific state instead of working with frame session state directly. + /// The instance for which session state is desired. + /// A collection of state subject to the same serialization mechanism as + /// . + public static Dictionary SessionStateForFrame(Frame frame) + { + var frameState = (Dictionary)frame.GetValue(frameSessionStateProperty); + + if (frameState == null) + { + var frameSessionKey = (string)frame.GetValue(frameSessionStateKeyProperty); + if (frameSessionKey != null) + { + // Registered frames reflect the corresponding session state + if (!sessionState.ContainsKey(frameSessionKey)) + { + sessionState[frameSessionKey] = new Dictionary(); + } + + frameState = (Dictionary)sessionState[frameSessionKey]; + } + else + { + // Frames that aren't registered have transient state + frameState = new Dictionary(); + } + + frame.SetValue(frameSessionStateProperty, frameState); + } + + return frameState; + } + + /// + /// Restores the state of the frame navigation. + /// + /// The frame. + private static void RestoreFrameNavigationState(Frame frame) + { + var frameState = SessionStateForFrame(frame); + if (frameState.ContainsKey("Navigation")) + { + frame.SetNavigationState((string)frameState["Navigation"]); + } + } + + /// + /// Saves the state of the frame navigation. + /// + /// The frame. + private static void SaveFrameNavigationState(Frame frame) + { + var frameState = SessionStateForFrame(frame); + frameState["Navigation"] = frame.GetNavigationState(); + } + } +} diff --git a/NumberRecognizer/NumberRecognizer.App/Common/SuspensionManagerException.cs b/NumberRecognizer/NumberRecognizer.App/Common/SuspensionManagerException.cs new file mode 100644 index 0000000..8980383 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Common/SuspensionManagerException.cs @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------- +// +// Copyright Markus Zytek. All rights reserved. +// +// Markus Zytek +// Suspension Manager Exception. +//----------------------------------------------------------------------- +namespace NumberRecognizer.App.Common +{ + using System; + + /// + /// Suspension Manager Exception. + /// + public class SuspensionManagerException : Exception + { + /// + /// Initializes a new instance of the class. + /// + public SuspensionManagerException() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The Exception. + public SuspensionManagerException(Exception e) + : base("SuspensionManager failed", e) + { + } + } +} diff --git a/NumberRecognizer/NumberRecognizer.App/Control/InkCanvasRT.cs b/NumberRecognizer/NumberRecognizer.App/Control/InkCanvasRT.cs new file mode 100644 index 0000000..6d0d7aa --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Control/InkCanvasRT.cs @@ -0,0 +1,259 @@ +//----------------------------------------------------------------------- +// +// Copyright Markus Zytek. All rights reserved. +// +// Markus Zytek +// Control like InkCanvas for RT. +//----------------------------------------------------------------------- +namespace NumberRecognizer.App.Control +{ + using System; + using System.Collections.Generic; + using System.Linq; + using NumberRecognition.Labeling; + using Windows.Devices.Input; + using Windows.Foundation; + using Windows.UI; + using Windows.UI.Input; + using Windows.UI.Input.Inking; + using Windows.UI.Xaml; + using Windows.UI.Xaml.Controls; + using Windows.UI.Xaml.Input; + using Windows.UI.Xaml.Media; + using Windows.UI.Xaml.Shapes; + + /// + /// InkCanvas for RT. + /// + public class InkCanvasRT : Canvas + { + /// + /// The ink manager. + /// + private InkManager inkManager; + + /// + /// The pen identifier. + /// + private uint penID; + + /// + /// The previous contact point. + /// + private Point previousContactPoint; + + /// + /// The current contact point. + /// + private Point currentContactPoint; + + /// + /// The connected component labeling. + /// + private ConnectedComponentLabeling labeling = new ConnectedComponentLabeling(); + + /// + /// Initializes a new instance of the class. + /// + public InkCanvasRT() + { + this.inkManager = new InkManager(); + this.ForegroundColor = Colors.Black; + this.BackgroundColor = Colors.White; + this.Background = new SolidColorBrush(this.BackgroundColor); + this.StrokeThickness = 4.0; + this.Margin = new Thickness(1); + this.PointerPressed += this.InkCanvasRT_PointerPressed; + this.PointerReleased += this.InkCanvasRT_PointerReleased; + this.PointerExited += this.InkCanvasRT_PointerReleased; + this.PointerMoved += this.InkCanvasRT_PointerMoved; + this.IsRightTapEnabled = true; + this.RightTapped += this.InkCanvasRT_RightTapped; + this.Labeling = new ConnectedComponentLabeling(); + } + + /// + /// Gets or sets the color of the foreground. + /// + /// + /// The color of the foreground. + /// + public Color ForegroundColor { get; set; } + + /// + /// Gets or sets the color of the background. + /// + /// + /// The color of the background. + /// + public Color BackgroundColor { get; set; } + + /// + /// Gets or sets the connected component labeling. + /// + /// + /// The connected component labeling. + /// + public ConnectedComponentLabeling Labeling { get; set; } + + /// + /// Gets or sets the stroke thickness. + /// + /// + /// The stroke thickness. + /// + public double StrokeThickness + { + get; + set; + } + + /// + /// Refreshes the canvas. + /// + public void RefreshCanvas() + { + this.Children.Clear(); + this.RenderStrokes(); + } + + /// + /// Distance to the specified previous point. + /// + /// The previous point. + /// The current point. + /// The Distance to the specified previous point. + private static double Distance(Point previousPoint, Point currentPoint) + { + return Math.Sqrt(Math.Pow(currentPoint.X - previousPoint.X, 2) + Math.Pow(currentPoint.Y - previousPoint.Y, 2)); + } + + /// + /// Handles the RightTapped event of the inkCanvasRT control. + /// + /// The source of the event. + /// The instance containing the event data. + private void InkCanvasRT_RightTapped(object sender, RightTappedRoutedEventArgs e) + { + this.Children.Clear(); + this.inkManager = new InkManager(); + } + + /// + /// Handles the PointerPressed event of the inkCanvasRT control. + /// + /// The source of the event. + /// The instance containing the event data. + private void InkCanvasRT_PointerPressed(object sender, PointerRoutedEventArgs e) + { + PointerPoint pointerPoint = e.GetCurrentPoint(this); + this.previousContactPoint = pointerPoint.Position; + PointerDeviceType pointerDevType = e.Pointer.PointerDeviceType; + if (pointerDevType == PointerDeviceType.Pen || + (pointerDevType == PointerDeviceType.Mouse && + pointerPoint.Properties.IsLeftButtonPressed)) + { + this.inkManager.ProcessPointerDown(pointerPoint); + this.penID = pointerPoint.PointerId; + e.Handled = true; + } + } + + /// + /// Handles the PointerMoved event of the inkCanvasRT control. + /// + /// The source of the event. + /// The instance containing the event data. + private void InkCanvasRT_PointerMoved(object sender, PointerRoutedEventArgs e) + { + if (e.Pointer.PointerId == this.penID) + { + PointerPoint pointerPoint = e.GetCurrentPoint(this); + this.currentContactPoint = pointerPoint.Position; + + if (Distance(this.previousContactPoint, this.currentContactPoint) > 1.0) + { + Line line = new Line() + { + X1 = this.previousContactPoint.X, + Y1 = this.previousContactPoint.Y, + X2 = this.currentContactPoint.X, + Y2 = this.currentContactPoint.Y, + StrokeThickness = this.StrokeThickness, + Stroke = new SolidColorBrush(this.ForegroundColor) + }; + + this.previousContactPoint = this.currentContactPoint; + this.Children.Add(line); + } + + this.inkManager.ProcessPointerUpdate(pointerPoint); + } + } + + /// + /// Handles the PointerReleased event of the inkCanvasRT control. + /// + /// The source of the event. + /// The instance containing the event data. + private void InkCanvasRT_PointerReleased(object sender, PointerRoutedEventArgs e) + { + if (e.Pointer.PointerId == this.penID) + { + PointerPoint pointerPoint = e.GetCurrentPoint(this); + this.inkManager.ProcessPointerUp(pointerPoint); + } + + this.penID = 0; + + this.RenderStrokes(); + e.Handled = true; + } + + /// + /// Renders the stroke. + /// + /// The stroke. + private void RenderStroke(InkStroke inkStroke) + { + PathSegmentCollection pathSegments = new PathSegmentCollection(); + IReadOnlyList inkStrokeRenderingSegments = inkStroke.GetRenderingSegments(); + PathFigure pathFigure = new PathFigure(); + pathFigure.StartPoint = inkStrokeRenderingSegments.First().BezierControlPoint1; + foreach (InkStrokeRenderingSegment inkStrokeRenderingSegment in inkStrokeRenderingSegments) + { + BezierSegment bezierSegment = new BezierSegment(); + bezierSegment.Point1 = inkStrokeRenderingSegment.BezierControlPoint1; + bezierSegment.Point2 = inkStrokeRenderingSegment.BezierControlPoint2; + bezierSegment.Point3 = inkStrokeRenderingSegment.Position; + pathSegments.Add(bezierSegment); + } + + pathFigure.Segments = pathSegments; + + PathFigureCollection pathFigures = new PathFigureCollection(); + pathFigures.Add(pathFigure); + + PathGeometry pathGeometry = new PathGeometry(); + pathGeometry.Figures = pathFigures; + + Path path = new Path(); + path.Stroke = new SolidColorBrush(this.ForegroundColor); + path.StrokeThickness = this.StrokeThickness; + path.Data = pathGeometry; + + this.Children.Add(path); + } + + /// + /// Renders the strokes. + /// + private void RenderStrokes() + { + foreach (var stroke in this.inkManager.GetStrokes()) + { + this.RenderStroke(stroke); + } + } + } +} \ No newline at end of file diff --git a/NumberRecognizer/NumberRecognizer.App/Converter/BooleanToVisibilityConverter.cs b/NumberRecognizer/NumberRecognizer.App/Converter/BooleanToVisibilityConverter.cs new file mode 100644 index 0000000..052886d --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Converter/BooleanToVisibilityConverter.cs @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------- +// +// Copyright Markus Zytek. All rights reserved. +// +// Markus Zytek +// DateTime To String Converterer. +//----------------------------------------------------------------------- +namespace NumberRecognizer.App.Converter +{ + using System; + using Windows.UI.Xaml; + using Windows.UI.Xaml.Data; + + /// + /// Boolean To Visibility Converter. + /// + public class BooleanToVisibilityConverter : IValueConverter + { + /// + /// Modifies the source data before passing it to the target for display in the UI. + /// + /// The source data being passed to the target. + /// The type of the target property. This uses a different type depending on whether you're programming with Microsoft .NET or Visual C++ component extensions (C++/CX). See Remarks. + /// An optional parameter to be used in the converter logic. + /// The language of the conversion. + /// + /// The value to be passed to the target dependency property. + /// + public object Convert(object value, Type targetType, object parameter, string language) + { + bool isVisible = (bool)value; + if (isVisible) + { + return Visibility.Visible; + } + else + { + return Visibility.Collapsed; + } + } + + /// + /// Modifies the target data before passing it to the source object. This method is called only in TwoWay bindings. + /// + /// The target data being passed to the source. + /// The type of the target property, specified by a helper structure that wraps the type name. + /// An optional parameter to be used in the converter logic. + /// The language of the conversion. + /// + /// The value to be passed to the source object. + /// + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + throw new NotImplementedException(); + } + } +} diff --git a/NumberRecognizer/NumberRecognizer.App/Converter/DateTimeToStringConverter.cs b/NumberRecognizer/NumberRecognizer.App/Converter/DateTimeToStringConverter.cs new file mode 100644 index 0000000..b2d743f --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Converter/DateTimeToStringConverter.cs @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------- +// +// Copyright Markus Zytek. All rights reserved. +// +// Markus Zytek +// DateTime To String Converterer. +//----------------------------------------------------------------------- +namespace NumberRecognizer.App.Converter +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + using Windows.UI.Xaml.Data; + + /// + /// DateTime To String Converter. + /// + public class DateTimeToStringConverter : IValueConverter + { + /// + /// Modifies the source data before passing it to the target for display in the UI. + /// + /// The source data being passed to the target. + /// The type of the target property. This uses a different type depending on whether you're programming with Microsoft .NET or Visual C++ component extensions (C++/CX). See Remarks. + /// An optional parameter to be used in the converter logic. + /// The language of the conversion. + /// + /// The value to be passed to the target dependency property. + /// + public object Convert(object value, Type targetType, object parameter, string language) + { + if (value != null) + { + DateTime dateTime = (DateTime)value; + return dateTime.ToString("dd.MM.yyyy HH:mm:ss"); + } + + return string.Empty; + } + + /// + /// Modifies the target data before passing it to the source object. This method is called only in TwoWay bindings. + /// + /// The target data being passed to the source. + /// The type of the target property, specified by a helper structure that wraps the type name. + /// An optional parameter to be used in the converter logic. + /// The language of the conversion. + /// + /// The value to be passed to the source object. + /// + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + throw new NotImplementedException(); + } + } +} diff --git a/NumberRecognizer/NumberRecognizer.App/DataModel/NetworkInfoGroup.cs b/NumberRecognizer/NumberRecognizer.App/DataModel/NetworkInfoGroup.cs new file mode 100644 index 0000000..8f49826 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/DataModel/NetworkInfoGroup.cs @@ -0,0 +1,99 @@ +//----------------------------------------------------------------------- +// +// Copyright Markus Zytek. All rights reserved. +// +// Markus Zytek +// Network Info Group. +//----------------------------------------------------------------------- +namespace NumberRecognizer.App.DataModel +{ + using System.Collections.ObjectModel; + using System.Windows.Input; + using NumberRecognizer.App.Common; + using NumberRecognizer.App.View; + using PropertyChanged; + + /// + /// Network Info Group. + /// + [ImplementPropertyChanged] + public class NetworkInfoGroup + { + /// + /// Initializes a new instance of the class. + /// + public NetworkInfoGroup() + { + this.InitializeProperties(); + this.InitializeCommands(); + } + + /// + /// Initializes a new instance of the class. + /// + /// The unique identifier. + /// The title. + public NetworkInfoGroup(string uniqueId, string title) + : this() + { + this.UniqueId = uniqueId; + this.Title = title; + } + + /// + /// Gets the unique identifier. + /// + /// + /// The unique identifier. + /// + public string UniqueId { get; private set; } + + /// + /// Gets or sets the title. + /// + /// + /// The title. + /// + public string Title { get; set; } + + /// + /// Gets or sets the networks. + /// + /// + /// The networks. + /// + public ObservableCollection Networks { get; set; } + + /// + /// Gets the click title command. + /// + /// + /// The click title command. + /// + public ICommand ClickTitleCommand { get; private set; } + + /// + /// Initializes the commands. + /// + private void InitializeCommands() + { + this.ClickTitleCommand = new RelayCommand(this.TitleClicked); + } + + /// + /// Initializes the properties. + /// + private void InitializeProperties() + { + this.Networks = new ObservableCollection(); + } + + /// + /// Titles the clicked. + /// + private void TitleClicked() + { + App.RootFrame.Navigate(typeof(GroupDetailPage), this); + } + } +} diff --git a/NumberRecognizer/NumberRecognizer.App/DataModel/NetworkInfoRT.cs b/NumberRecognizer/NumberRecognizer.App/DataModel/NetworkInfoRT.cs new file mode 100644 index 0000000..176ef58 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/DataModel/NetworkInfoRT.cs @@ -0,0 +1,64 @@ +//----------------------------------------------------------------------- +// +// Copyright Markus Zytek. All rights reserved. +// +// Markus Zytek +// Network Info RT. +//----------------------------------------------------------------------- +namespace NumberRecognizer.App.DataModel +{ + using System.Windows.Input; + using NumberRecognizer.App.Common; + using NumberRecognizer.App.NumberRecognizerService; + using NumberRecognizer.App.View; + using PropertyChanged; + + /// + /// Network Info RT. + /// + [ImplementPropertyChanged] + public class NetworkInfoRT + { + /// + /// Initializes a new instance of the class. + /// + public NetworkInfoRT() + { + this.ClickNetworkInfoRTCommand = new RelayCommand(this.NetworkInfoRTClicked); + } + + /// + /// Initializes a new instance of the class. + /// + /// The network. + public NetworkInfoRT(NetworkInfo network) + : this() + { + this.Network = network; + } + + /// + /// Gets or sets the network. + /// + /// + /// The network. + /// + public NetworkInfo Network { get; set; } + + /// + /// Gets the click network information command. + /// + /// + /// The click network information command. + /// + public ICommand ClickNetworkInfoRTCommand { get; private set; } + + /// + /// Networks the information clicked. + /// + private void NetworkInfoRTClicked() + { + App.RootFrame.Navigate(typeof(NetworkDetailPage), this.Network); + } + } +} diff --git a/NumberRecognizer/NumberRecognizer.App/DataModel/TrainingImageGroup.cs b/NumberRecognizer/NumberRecognizer.App/DataModel/TrainingImageGroup.cs new file mode 100644 index 0000000..d2008bc --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/DataModel/TrainingImageGroup.cs @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------- +// +// Copyright Markus Zytek. All rights reserved. +// +// Markus Zytek +// Training Image Group. +//----------------------------------------------------------------------- +namespace NumberRecognizer.App.DataModel +{ + using System.Collections.ObjectModel; + using GalaSoft.MvvmLight; + using PropertyChanged; + + /// + /// Training Image Group. + /// + [ImplementPropertyChanged] + public class TrainingImageGroup : ViewModelBase + { + /// + /// Initializes a new instance of the class. + /// + public TrainingImageGroup() + { + this.Images = new ObservableCollection(); + } + + /// + /// Initializes a new instance of the class. + /// + /// The unique identifier. + /// The title. + public TrainingImageGroup(string uniqueId, string title) : this() + { + this.UniqueId = uniqueId; + this.Title = title; + } + + /// + /// Gets or sets the unique identifier. + /// + /// + /// The unique identifier. + /// + public string UniqueId { get; set; } + + /// + /// Gets or sets the title. + /// + /// + /// The title. + /// + public string Title { get; set; } + + /// + /// Gets or sets the images. + /// + /// + /// The images. + /// + public ObservableCollection Images { get; set; } + } +} diff --git a/NumberRecognizer/NumberRecognizer.App/DataModel/TrainingImageRT.cs b/NumberRecognizer/NumberRecognizer.App/DataModel/TrainingImageRT.cs new file mode 100644 index 0000000..a996608 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/DataModel/TrainingImageRT.cs @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------- +// +// Copyright Markus Zytek. All rights reserved. +// +// Markus Zytek +// Training Image RT. +//----------------------------------------------------------------------- +namespace NumberRecognizer.App.DataModel +{ + using NumberRecognizer.App.NumberRecognizerService; + using Windows.UI.Xaml.Media.Imaging; + + /// + /// Training Image RT. + /// + public class TrainingImageRT + { + /// + /// Initializes a new instance of the class. + /// + public TrainingImageRT() + { + this.Image = new TrainingImage(); + } + + /// + /// Initializes a new instance of the class. + /// + /// The image. + public TrainingImageRT(TrainingImage image) + : this() + { + this.Image = image; + } + + /// + /// Gets or sets the image. + /// + /// + /// The image. + /// + public TrainingImage Image { get; set; } + + /// + /// Gets or sets the bitmap. + /// + /// + /// The bitmap. + /// + public WriteableBitmap Bitmap { get; set; } + } +} diff --git a/NumberRecognizer/NumberRecognizer.App/FodyWeavers.xml b/NumberRecognizer/NumberRecognizer.App/FodyWeavers.xml new file mode 100644 index 0000000..a20b504 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/FodyWeavers.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/NumberRecognizer/NumberRecognizer.App/Help/ImageHelperRT.cs b/NumberRecognizer/NumberRecognizer.App/Help/ImageHelperRT.cs new file mode 100644 index 0000000..8246894 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Help/ImageHelperRT.cs @@ -0,0 +1,245 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Markus Zytek. All rights reserved. +// +// Markus Zytek +// ImageHelper for RT. +//----------------------------------------------------------------------- +namespace NumberRecognizer.App.Help +{ + using System; + using System.Collections.ObjectModel; + using System.Runtime.InteropServices.WindowsRuntime; + using System.Threading.Tasks; + using Windows.Graphics.Imaging; + using Windows.Storage; + using Windows.Storage.Streams; + using Windows.UI; + using Windows.UI.Xaml.Media.Imaging; + + /// + /// Image Helper. + /// + public static class ImageHelperRT + { + /// + /// The image height. + /// + public const double ImageHeight = 20; + + /// + /// The image width. + /// + public const double ImageWidth = 20; + + /// + /// The RGBA constant. + /// + private const int RGBA = 4; + + /// + /// Gets the byte array from red, green, blue, alpha byte array. + /// + /// The red, green, blue, alpha byte array. + /// The foreground. + /// The background. + /// The byte array from red, green, blue, alpha byte array. + public static byte[] GetByteArrayFromRGBAByteArray(byte[] rgbaByteArray, Color foreground, Color background) + { + byte[] byteArray = new byte[rgbaByteArray.Length / RGBA]; + + for (int i = 0; i < rgbaByteArray.Length; i++) + { + Color color = new Color(); + color.R = rgbaByteArray[i]; + color.G = rgbaByteArray[++i]; + color.B = rgbaByteArray[++i]; + color.A = rgbaByteArray[++i]; + + if (color.R == foreground.R && color.R == foreground.G && color.R == foreground.B && color.A != 0) + { + byteArray[i / RGBA] = foreground.A; + } + } + + return byteArray; + } + + /// + /// Gets the red, green, blue, alpha byte array from byte array. + /// + /// The byte array. + /// The foreground. + /// + /// The red, green, blue, alpha byte array from byte array. + /// + public static byte[] GetRGBAByteArrayFromByteArrayAsync(byte[] byteArray, Color foreground) + { + byte[] rgbaByteArray = new byte[byteArray.Length * RGBA]; + + for (int i = 0; i < byteArray.Length; i++) + { + if (byteArray[i] > 0) + { + int r = i * RGBA; + rgbaByteArray[r] = foreground.R; + rgbaByteArray[++r] = foreground.G; + rgbaByteArray[++r] = foreground.B; + rgbaByteArray[++r] = foreground.A; + } + } + + return rgbaByteArray; + } + + /// + /// Gets the pixels from byte array. + /// + /// The byte array. + /// The width. + /// The height. + /// The pixels from byte array. + public static double[,] Get2DPixelArrayFromByteArray(byte[] byteArray, double width, double height) + { + double[,] pixelArray2D = new double[(int)height, (int)width]; + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int z = (int)(width * y) + x; + if (byteArray[z] != 0) + { + pixelArray2D[y, x] = byteArray[z] / 255; + } + } + } + + return pixelArray2D; + } + + /// + /// Gets the byte array from pixel 2d array. + /// + /// The pixel 2d array. + /// The byte array from pixel 2d array. + public static byte[] GetByteArrayFrom2DPixelArrayAsync(double[,] pixelArray2D) + { + int length = pixelArray2D.Length; + int height = pixelArray2D.GetLength(0); + int width = pixelArray2D.GetLength(1); + byte[] byteArray = new byte[length]; + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int z = (width * y) + x; + if (pixelArray2D[y, x] != 0) + { + byteArray[z] = (byte)(pixelArray2D[y, x] * 255); + } + } + } + + return byteArray; + } + + /// + /// Gets the observable collection from 2D pixel array. + /// + /// The pixel array. + /// The observable collection from 2D pixel array. + public static ObservableCollection GetObservableCollectionFrom2DPixelArray(double[,] pixelArray) + { + ObservableCollection observableCollection = new ObservableCollection(); + + for (int y = 0; y < pixelArray.GetLength(1); y++) + { + for (int x = 0; x < pixelArray.GetLength(0); x++) + { + observableCollection.Add(pixelArray[y, x]); + } + } + + return observableCollection; + } + + /// + /// Saves the red, green, blue, alpha byte array as bitmap image asynchronous. + /// + /// The red, green, blue, alpha byte array. + /// The width parameter. + /// The height parameter. + /// The name parameter. + /// + /// The red, green, blue, alpha byte array as bitmap image asynchronous. + /// + public static async Task SaveRGBAByteArrayAsBitmapImageAsync(byte[] rgbaByteArray, double width, double height, string name) + { + var storageFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(name + ".png", CreationCollisionOption.ReplaceExisting); + + using (var randomAccessStream = await storageFile.OpenAsync(FileAccessMode.ReadWrite)) + { + var bitmapEncoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, randomAccessStream); + bitmapEncoder.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Straight, (uint)width, (uint)height, 96d, 96d, rgbaByteArray); + bitmapEncoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.NearestNeighbor; + await bitmapEncoder.FlushAsync(); + } + } + + /// + /// Saves the red, green, blue, alpha byte array as memory stream. + /// + /// The red, green, blue, alpha byte array. + /// The width. + /// The height. + /// + /// The red, green, blue, alpha byte array as memory stream. + /// + public static async Task SaveRGBAByteArrayAsMemoryStream(byte[] rgbaByteArray, double width, double height) + { + var inMemoryRandomAccessStream = new InMemoryRandomAccessStream(); + + var bitmapEncoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, inMemoryRandomAccessStream); + + bitmapEncoder.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Straight, (uint)width, (uint)height, 96d, 96d, rgbaByteArray); + bitmapEncoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.NearestNeighbor; + + await bitmapEncoder.FlushAsync(); + + return inMemoryRandomAccessStream; + } + + /// + /// Scales the red, green, blue, alpha byte array asynchronous. + /// + /// The red, green, blue, alpha byte array. + /// The width. + /// The height. + /// Width of the scaled. + /// Height of the scaled. + /// The scaled red, green, blue, alpha byte array asynchronous. + public static async Task ScaleRGBAByteArrayAsync(byte[] rgbaByteArray, double width, double height, double scaledWidth, double scaledHeight) + { + var inMemoryRandomAccessStream = new InMemoryRandomAccessStream(); + + var bitmapEncoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, inMemoryRandomAccessStream); + + bitmapEncoder.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Straight, (uint)width, (uint)height, 96d, 96d, rgbaByteArray); + bitmapEncoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.NearestNeighbor; + + if (height != scaledHeight || width != scaledWidth) + { + bitmapEncoder.BitmapTransform.ScaledWidth = (uint)scaledWidth; + bitmapEncoder.BitmapTransform.ScaledHeight = (uint)scaledHeight; + } + + await bitmapEncoder.FlushAsync(); + + var bitmap = new WriteableBitmap((int)scaledWidth, (int)scaledHeight); + await bitmap.SetSourceAsync(inMemoryRandomAccessStream); + return bitmap.PixelBuffer.ToArray(); + } + } +} \ No newline at end of file diff --git a/NumberRecognizer/NumberRecognizer.App/Help/LabelingHelperRT.cs b/NumberRecognizer/NumberRecognizer.App/Help/LabelingHelperRT.cs new file mode 100644 index 0000000..8582960 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Help/LabelingHelperRT.cs @@ -0,0 +1,100 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Markus Zytek. All rights reserved. +// +// Markus Zytek +// Labeling Helper for RT. +//----------------------------------------------------------------------- +namespace NumberRecognizer.App.Help +{ + using System; + using System.Collections.ObjectModel; + using System.Runtime.InteropServices.WindowsRuntime; + using System.Threading.Tasks; + using NumberRecognition.Labeling; + using NumberRecognizer.App.Control; + using NumberRecognizer.App.NumberRecognizerService; + using Windows.UI; + using Windows.UI.Xaml; + using Windows.UI.Xaml.Media; + using Windows.UI.Xaml.Media.Imaging; + using Windows.UI.Xaml.Shapes; + + /// + /// Labeling Helper for RT. + /// + public class LabelingHelperRT + { + /// + /// Connected component labeling for canvas. + /// + /// The ink canvas. + /// Connected Component Task for Ink Canvas. + public static async Task ConnectedComponentLabelingForInkCanvasRT(InkCanvasRT inkCanvas) + { + inkCanvas.RefreshCanvas(); + var renderTargetBitmap = new RenderTargetBitmap(); + await renderTargetBitmap.RenderAsync(inkCanvas); + + byte[] canvasRGBABytes = (await renderTargetBitmap.GetPixelsAsync()).ToArray(); + byte[] canvasBytes = ImageHelperRT.GetByteArrayFromRGBAByteArray(canvasRGBABytes, inkCanvas.ForegroundColor, inkCanvas.BackgroundColor); + + double canvasWidth = inkCanvas.ActualWidth; + double canvasHeight = inkCanvas.ActualHeight; + double[,] canvasPixels = ImageHelperRT.Get2DPixelArrayFromByteArray(canvasBytes, canvasWidth, canvasHeight); + + inkCanvas.Labeling = new ConnectedComponentLabeling(); + inkCanvas.Labeling.TwoPassLabeling(canvasPixels, 0.0); + + foreach (ConnectedComponent connectedComponent in inkCanvas.Labeling.ConnectedComponents) + { + MinimumBoundingRectangle mbr = connectedComponent.MinBoundingRect; + Rectangle rectangle = new Rectangle() + { + Stroke = new SolidColorBrush(Colors.OrangeRed), + StrokeThickness = 2.0, + Width = mbr.Width, + Height = mbr.Height, + Margin = new Thickness() { Top = mbr.Top, Left = mbr.Left } + }; + inkCanvas.Children.Add(rectangle); + + byte[] orgBytes = new byte[(int)(mbr.Width * mbr.Height)]; + byte[] scaBytes = new byte[(int)Math.Pow(mbr.Size, 2)]; + for (int y = 0; y < mbr.Height; y++) + { + for (int x = 0; x < mbr.Width; x++) + { + if (connectedComponent.ComponentPoints.Exists(p => p.X == mbr.Left + x && p.Y == mbr.Top + y)) + { + double row = (mbr.Top + y) * canvasWidth; + double col = mbr.Left + x; + byte val = canvasBytes[(int)(row + col)]; + + int orgIdx = (int)(y * mbr.Width) + x; + orgBytes[orgIdx] = val; + + int scaIdx = (int)(((y + mbr.PadTop) * mbr.Size) + (x + mbr.PadLeft)); + scaBytes[scaIdx] = val; + } + } + } + + connectedComponent.Pixels = ImageHelperRT.Get2DPixelArrayFromByteArray(orgBytes, mbr.Width, mbr.Height); + connectedComponent.Bytes = orgBytes; + + try + { + byte[] scaRGBABytes = ImageHelperRT.GetRGBAByteArrayFromByteArrayAsync(scaBytes, inkCanvas.ForegroundColor); + scaRGBABytes = await ImageHelperRT.ScaleRGBAByteArrayAsync(scaRGBABytes, mbr.Size, mbr.Size, ImageHelperRT.ImageWidth, ImageHelperRT.ImageHeight); + scaBytes = ImageHelperRT.GetByteArrayFromRGBAByteArray(scaRGBABytes, inkCanvas.ForegroundColor, inkCanvas.BackgroundColor); + connectedComponent.ScaledPixels = ImageHelperRT.Get2DPixelArrayFromByteArray(scaBytes, ImageHelperRT.ImageWidth, ImageHelperRT.ImageHeight); + connectedComponent.ScaledBytes = scaBytes; + } + catch (Exception ex) + { + } + } + } + } +} diff --git a/NumberRecognizer/NumberRecognizer.App/Lib/De.TorstenMandelkow.MetroChart.dll b/NumberRecognizer/NumberRecognizer.App/Lib/De.TorstenMandelkow.MetroChart.dll new file mode 100644 index 0000000..38ff6b9 Binary files /dev/null and b/NumberRecognizer/NumberRecognizer.App/Lib/De.TorstenMandelkow.MetroChart.dll differ diff --git a/NumberRecognizer/NumberRecognizer.App/NumberRecognizer.App.csproj b/NumberRecognizer/NumberRecognizer.App/NumberRecognizer.App.csproj new file mode 100644 index 0000000..bdb9929 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/NumberRecognizer.App.csproj @@ -0,0 +1,293 @@ + + + + + Debug + AnyCPU + {D7A7A48F-2A13-4CA4-A11D-B06EB30B4439} + AppContainerExe + Properties + NumberRecognizer.App + NumberRecognizer.App + en-US + 8.1 + 12 + 512 + {BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + NumberRecognizer.App_TemporaryKey.pfx + 5125bef2 + SAK + SAK + SAK + SAK + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_APP + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE;NETFX_CORE;WINDOWS_APP + prompt + 4 + + + true + bin\ARM\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_APP + ;2008 + full + ARM + false + prompt + true + + + bin\ARM\Release\ + TRACE;NETFX_CORE;WINDOWS_APP + true + ;2008 + pdbonly + ARM + false + prompt + true + + + true + bin\x64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_APP + ;2008 + full + x64 + false + prompt + true + + + bin\x64\Release\ + TRACE;NETFX_CORE;WINDOWS_APP + true + ;2008 + pdbonly + x64 + false + prompt + true + + + true + bin\x86\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_APP + ;2008 + full + x86 + false + prompt + true + + + bin\x86\Release\ + TRACE;NETFX_CORE;WINDOWS_APP + true + ;2008 + pdbonly + x86 + false + prompt + true + + + + App.xaml + + + + + + False + + + + + + + + + + True + True + Reference.svcmap + + + + + + + + CreateNetworkPage.xaml + False + + + GroupedImagesPage.xaml + + + GroupedNetworksPage.xaml + + + GroupDetailPage.xaml + False + + + False + + + NetworkDetailPage.xaml + + + + False + + + + + + + + Designer + + + + + + + Reference.svcmap + + + Reference.svcmap + + + + Designer + + + Designer + + + Designer + + + Designer + + + WCF Proxy Generator + Reference.cs + + + + + + + + + + + + + + + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + PreserveNewest + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + + + + + {73dab28e-ec91-469b-904e-9ec8123d155f} + NumberRecognition.Labeling + + + + + False + Lib\De.TorstenMandelkow.MetroChart.dll + + + ..\packages\Portable.MvvmLightLibs.5.0.2.0\lib\netcore451\GalaSoft.MvvmLight.dll + + + ..\packages\Portable.MvvmLightLibs.5.0.2.0\lib\netcore451\GalaSoft.MvvmLight.Extras.dll + + + ..\packages\Portable.MvvmLightLibs.5.0.2.0\lib\netcore451\GalaSoft.MvvmLight.Platform.dll + + + ..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll + + + ..\packages\Mutzl.Mvvm.DependentRelayCommand.0.9.5.0\lib\Mutzl.MvvmLight.dll + + + ..\packages\PropertyChanged.Fody.1.48.7\Lib\portable-net4+sl4+wp8+win8+wpa81+MonoAndroid16+MonoTouch40\PropertyChanged.dll + False + + + + + + + + 12.0 + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/NumberRecognizer/NumberRecognizer.App/NumberRecognizer.App.csproj.vspscc b/NumberRecognizer/NumberRecognizer.App/NumberRecognizer.App.csproj.vspscc new file mode 100644 index 0000000..feffdec --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/NumberRecognizer.App.csproj.vspscc @@ -0,0 +1,10 @@ +"" +{ +"FILE_VERSION" = "9237" +"ENLISTMENT_CHOICE" = "NEVER" +"PROJECT_FILE_RELATIVE_PATH" = "" +"NUMBER_OF_EXCLUDED_FILES" = "0" +"ORIGINAL_PROJECT_FILE_PATH" = "" +"NUMBER_OF_NESTED_PROJECTS" = "0" +"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" +} diff --git a/NumberRecognizer/NumberRecognizer.App/NumberRecognizer.App_TemporaryKey.pfx b/NumberRecognizer/NumberRecognizer.App/NumberRecognizer.App_TemporaryKey.pfx new file mode 100644 index 0000000..688b2c5 Binary files /dev/null and b/NumberRecognizer/NumberRecognizer.App/NumberRecognizer.App_TemporaryKey.pfx differ diff --git a/NumberRecognizer/NumberRecognizer.App/Package.appxmanifest b/NumberRecognizer/NumberRecognizer.App/Package.appxmanifest new file mode 100644 index 0000000..b5f1cbd --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Package.appxmanifest @@ -0,0 +1,37 @@ + + + + + Number Recognizer App + Markus Zytek + Assets\StoreLogo.png + + + 6.3.0 + 6.3.0 + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/NumberRecognizer/NumberRecognizer.App/Properties/AssemblyInfo.cs b/NumberRecognizer/NumberRecognizer.App/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..d146abb --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Properties/AssemblyInfo.cs @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------- +// +// Copyright Markus Zytek. All rights reserved. +// +// Markus Zytek +// Assembly Info. +//----------------------------------------------------------------------- + +using System.Reflection; +using System.Resources; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("NumberRecognizer.App")] +[assembly: AssemblyDescription("NumberRecognizer.App")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("FH Wr. Neustadt")] +[assembly: AssemblyProduct("NumberRecognizer.App")] +[assembly: AssemblyCopyright("Copyright © 2014")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: ComVisible(false)] +[assembly: NeutralResourcesLanguageAttribute("en")] diff --git a/NumberRecognizer/NumberRecognizer.App/Properties/ServiceReferences.Designer.ClientConfig b/NumberRecognizer/NumberRecognizer.App/Properties/ServiceReferences.Designer.ClientConfig new file mode 100644 index 0000000..140ea06 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Properties/ServiceReferences.Designer.ClientConfig @@ -0,0 +1,4 @@ + + + + diff --git a/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizer.App.NumberRecognizerService.NetworkInfo.datasource b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizer.App.NumberRecognizerService.NetworkInfo.datasource new file mode 100644 index 0000000..7790b14 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizer.App.NumberRecognizerService.NetworkInfo.datasource @@ -0,0 +1,10 @@ + + + + NumberRecognizer.App.NumberRecognizerService.NetworkInfo, Service References.NumberRecognizerService.Reference.cs, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + \ No newline at end of file diff --git a/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizer.App.NumberRecognizerService.NumberRecognitionResult.datasource b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizer.App.NumberRecognizerService.NumberRecognitionResult.datasource new file mode 100644 index 0000000..ea97664 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizer.App.NumberRecognizerService.NumberRecognitionResult.datasource @@ -0,0 +1,10 @@ + + + + NumberRecognizer.App.NumberRecognizerService.NumberRecognitionResult, Service References.NumberRecognizerService.Reference.cs, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + \ No newline at end of file diff --git a/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService1.disco b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService1.disco new file mode 100644 index 0000000..261b461 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService1.disco @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService1.wsdl b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService1.wsdl new file mode 100644 index 0000000..20b2a0b --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService1.wsdl @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService4.xsd b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService4.xsd new file mode 100644 index 0000000..ff47a11 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService4.xsd @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 2 + + + + + + + 4 + + + + + + + 8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService41.xsd b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService41.xsd new file mode 100644 index 0000000..c6fa852 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService41.xsd @@ -0,0 +1,83 @@ + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService42.xsd b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService42.xsd new file mode 100644 index 0000000..cb603d0 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService42.xsd @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService43.xsd b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService43.xsd new file mode 100644 index 0000000..32e1c19 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService43.xsd @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/Reference.cs b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/Reference.cs new file mode 100644 index 0000000..868d191 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/Reference.cs @@ -0,0 +1,556 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34014 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +// +// This code was auto-generated by Microsoft.VisualStudio.ServiceReference.Platforms, version 12.0.21005.1 +// +namespace NumberRecognizer.App.NumberRecognizerService { + using System.Runtime.Serialization; + + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] + [System.Runtime.Serialization.DataContractAttribute(Name="NetworkInfo", Namespace="http://schemas.datacontract.org/2004/07/NumberRecognizer.Cloud.Contract.Data")] + public partial class NetworkInfo : object, System.ComponentModel.INotifyPropertyChanged { + + private bool CalculatedField; + + private System.Nullable CalculationEndField; + + private System.Nullable CalculationStartField; + + private NumberRecognizer.App.NumberRecognizerService.FitnessLog FinalPoolFitnessLogField; + + private bool MultipleGenPoolField; + + private System.Collections.Generic.Dictionary MultiplePoolFitnessLogField; + + private double NetworkFitnessField; + + private int NetworkIdField; + + private string NetworkNameField; + + private NumberRecognizer.App.NumberRecognizerService.NetworkStatusType StatusField; + + [System.Runtime.Serialization.DataMemberAttribute()] + public bool Calculated { + get { + return this.CalculatedField; + } + set { + if ((this.CalculatedField.Equals(value) != true)) { + this.CalculatedField = value; + this.RaisePropertyChanged("Calculated"); + } + } + } + + [System.Runtime.Serialization.DataMemberAttribute()] + public System.Nullable CalculationEnd { + get { + return this.CalculationEndField; + } + set { + if ((this.CalculationEndField.Equals(value) != true)) { + this.CalculationEndField = value; + this.RaisePropertyChanged("CalculationEnd"); + } + } + } + + [System.Runtime.Serialization.DataMemberAttribute()] + public System.Nullable CalculationStart { + get { + return this.CalculationStartField; + } + set { + if ((this.CalculationStartField.Equals(value) != true)) { + this.CalculationStartField = value; + this.RaisePropertyChanged("CalculationStart"); + } + } + } + + [System.Runtime.Serialization.DataMemberAttribute()] + public NumberRecognizer.App.NumberRecognizerService.FitnessLog FinalPoolFitnessLog { + get { + return this.FinalPoolFitnessLogField; + } + set { + if ((object.ReferenceEquals(this.FinalPoolFitnessLogField, value) != true)) { + this.FinalPoolFitnessLogField = value; + this.RaisePropertyChanged("FinalPoolFitnessLog"); + } + } + } + + [System.Runtime.Serialization.DataMemberAttribute()] + public bool MultipleGenPool { + get { + return this.MultipleGenPoolField; + } + set { + if ((this.MultipleGenPoolField.Equals(value) != true)) { + this.MultipleGenPoolField = value; + this.RaisePropertyChanged("MultipleGenPool"); + } + } + } + + [System.Runtime.Serialization.DataMemberAttribute()] + public System.Collections.Generic.Dictionary MultiplePoolFitnessLog { + get { + return this.MultiplePoolFitnessLogField; + } + set { + if ((object.ReferenceEquals(this.MultiplePoolFitnessLogField, value) != true)) { + this.MultiplePoolFitnessLogField = value; + this.RaisePropertyChanged("MultiplePoolFitnessLog"); + } + } + } + + [System.Runtime.Serialization.DataMemberAttribute()] + public double NetworkFitness { + get { + return this.NetworkFitnessField; + } + set { + if ((this.NetworkFitnessField.Equals(value) != true)) { + this.NetworkFitnessField = value; + this.RaisePropertyChanged("NetworkFitness"); + } + } + } + + [System.Runtime.Serialization.DataMemberAttribute()] + public int NetworkId { + get { + return this.NetworkIdField; + } + set { + if ((this.NetworkIdField.Equals(value) != true)) { + this.NetworkIdField = value; + this.RaisePropertyChanged("NetworkId"); + } + } + } + + [System.Runtime.Serialization.DataMemberAttribute()] + public string NetworkName { + get { + return this.NetworkNameField; + } + set { + if ((object.ReferenceEquals(this.NetworkNameField, value) != true)) { + this.NetworkNameField = value; + this.RaisePropertyChanged("NetworkName"); + } + } + } + + [System.Runtime.Serialization.DataMemberAttribute()] + public NumberRecognizer.App.NumberRecognizerService.NetworkStatusType Status { + get { + return this.StatusField; + } + set { + if ((this.StatusField.Equals(value) != true)) { + this.StatusField = value; + this.RaisePropertyChanged("Status"); + } + } + } + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected void RaisePropertyChanged(string propertyName) { + System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged; + if ((propertyChanged != null)) { + propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] + [System.Runtime.Serialization.DataContractAttribute(Name="FitnessLog", Namespace="http://schemas.datacontract.org/2004/07/NumberRecognizer.Cloud.Contract.Data")] + public partial class FitnessLog : object, System.ComponentModel.INotifyPropertyChanged { + + private System.Collections.Generic.Dictionary FinalPatternFittnessField; + + private System.Collections.ObjectModel.ObservableCollection FitnessTrendField; + + private System.Collections.Generic.Dictionary> PatternTrendsField; + + [System.Runtime.Serialization.DataMemberAttribute()] + public System.Collections.Generic.Dictionary FinalPatternFittness { + get { + return this.FinalPatternFittnessField; + } + set { + if ((object.ReferenceEquals(this.FinalPatternFittnessField, value) != true)) { + this.FinalPatternFittnessField = value; + this.RaisePropertyChanged("FinalPatternFittness"); + } + } + } + + [System.Runtime.Serialization.DataMemberAttribute()] + public System.Collections.ObjectModel.ObservableCollection FitnessTrend { + get { + return this.FitnessTrendField; + } + set { + if ((object.ReferenceEquals(this.FitnessTrendField, value) != true)) { + this.FitnessTrendField = value; + this.RaisePropertyChanged("FitnessTrend"); + } + } + } + + [System.Runtime.Serialization.DataMemberAttribute()] + public System.Collections.Generic.Dictionary> PatternTrends { + get { + return this.PatternTrendsField; + } + set { + if ((object.ReferenceEquals(this.PatternTrendsField, value) != true)) { + this.PatternTrendsField = value; + this.RaisePropertyChanged("PatternTrends"); + } + } + } + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected void RaisePropertyChanged(string propertyName) { + System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged; + if ((propertyChanged != null)) { + propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + } + + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] + [System.Runtime.Serialization.DataContractAttribute(Name="NetworkStatusType", Namespace="http://schemas.datacontract.org/2004/07/NumberRecognizer.Cloud.Contract.Data")] + public enum NetworkStatusType : int { + + [System.Runtime.Serialization.EnumMemberAttribute()] + NotStarted = 1, + + [System.Runtime.Serialization.EnumMemberAttribute()] + Running = 2, + + [System.Runtime.Serialization.EnumMemberAttribute()] + Ready = 4, + + [System.Runtime.Serialization.EnumMemberAttribute()] + Error = 8, + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] + [System.Runtime.Serialization.DataContractAttribute(Name="TrainingImage", Namespace="http://schemas.datacontract.org/2004/07/NumberRecognizer.Cloud.Contract.Data")] + public partial class TrainingImage : NumberRecognizer.App.NumberRecognizerService.RecognitionImage { + + private string PatternField; + + [System.Runtime.Serialization.DataMemberAttribute()] + public string Pattern { + get { + return this.PatternField; + } + set { + if ((object.ReferenceEquals(this.PatternField, value) != true)) { + this.PatternField = value; + this.RaisePropertyChanged("Pattern"); + } + } + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] + [System.Runtime.Serialization.DataContractAttribute(Name="RecognitionImage", Namespace="http://schemas.datacontract.org/2004/07/NumberRecognizer.Cloud.Contract.Data")] + [System.Runtime.Serialization.KnownTypeAttribute(typeof(NumberRecognizer.App.NumberRecognizerService.TrainingImage))] + public partial class RecognitionImage : object, System.ComponentModel.INotifyPropertyChanged { + + private int HeightField; + + private System.Collections.ObjectModel.ObservableCollection ImageDataField; + + private int WidthField; + + [System.Runtime.Serialization.DataMemberAttribute()] + public int Height { + get { + return this.HeightField; + } + set { + if ((this.HeightField.Equals(value) != true)) { + this.HeightField = value; + this.RaisePropertyChanged("Height"); + } + } + } + + [System.Runtime.Serialization.DataMemberAttribute()] + public System.Collections.ObjectModel.ObservableCollection ImageData { + get { + return this.ImageDataField; + } + set { + if ((object.ReferenceEquals(this.ImageDataField, value) != true)) { + this.ImageDataField = value; + this.RaisePropertyChanged("ImageData"); + } + } + } + + [System.Runtime.Serialization.DataMemberAttribute()] + public int Width { + get { + return this.WidthField; + } + set { + if ((this.WidthField.Equals(value) != true)) { + this.WidthField = value; + this.RaisePropertyChanged("Width"); + } + } + } + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected void RaisePropertyChanged(string propertyName) { + System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged; + if ((propertyChanged != null)) { + propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] + [System.Runtime.Serialization.DataContractAttribute(Name="NumberRecognitionResult", Namespace="http://schemas.datacontract.org/2004/07/NumberRecognizer.Cloud.Contract.Data")] + public partial class NumberRecognitionResult : object, System.ComponentModel.INotifyPropertyChanged { + + private System.Collections.ObjectModel.ObservableCollection ItemsField; + + private string NumberField; + + [System.Runtime.Serialization.DataMemberAttribute()] + public System.Collections.ObjectModel.ObservableCollection Items { + get { + return this.ItemsField; + } + set { + if ((object.ReferenceEquals(this.ItemsField, value) != true)) { + this.ItemsField = value; + this.RaisePropertyChanged("Items"); + } + } + } + + [System.Runtime.Serialization.DataMemberAttribute()] + public string Number { + get { + return this.NumberField; + } + set { + if ((object.ReferenceEquals(this.NumberField, value) != true)) { + this.NumberField = value; + this.RaisePropertyChanged("Number"); + } + } + } + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected void RaisePropertyChanged(string propertyName) { + System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged; + if ((propertyChanged != null)) { + propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] + [System.Runtime.Serialization.DataContractAttribute(Name="NumberRecognitionResultItem", Namespace="http://schemas.datacontract.org/2004/07/NumberRecognizer.Cloud.Contract.Data")] + public partial class NumberRecognitionResultItem : object, System.ComponentModel.INotifyPropertyChanged { + + private int NumericCharacterField; + + private System.Collections.Generic.Dictionary ProbabilitiesField; + + [System.Runtime.Serialization.DataMemberAttribute()] + public int NumericCharacter { + get { + return this.NumericCharacterField; + } + set { + if ((this.NumericCharacterField.Equals(value) != true)) { + this.NumericCharacterField = value; + this.RaisePropertyChanged("NumericCharacter"); + } + } + } + + [System.Runtime.Serialization.DataMemberAttribute()] + public System.Collections.Generic.Dictionary Probabilities { + get { + return this.ProbabilitiesField; + } + set { + if ((object.ReferenceEquals(this.ProbabilitiesField, value) != true)) { + this.ProbabilitiesField = value; + this.RaisePropertyChanged("Probabilities"); + } + } + } + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected void RaisePropertyChanged(string propertyName) { + System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged; + if ((propertyChanged != null)) { + propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + } + + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + [System.ServiceModel.ServiceContractAttribute(ConfigurationName="NumberRecognizerService.INumberRecognizerService")] + public interface INumberRecognizerService { + + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/INumberRecognizerService/GetNetworks", ReplyAction="http://tempuri.org/INumberRecognizerService/GetNetworksResponse")] + System.Threading.Tasks.Task> GetNetworksAsync(); + + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/INumberRecognizerService/CreateNetwork", ReplyAction="http://tempuri.org/INumberRecognizerService/CreateNetworkResponse")] + System.Threading.Tasks.Task CreateNetworkAsync(string networkName, System.Collections.ObjectModel.ObservableCollection individualTrainingsData); + + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/INumberRecognizerService/CreateNetworkWithTrainingDataCopy", ReplyAction="http://tempuri.org/INumberRecognizerService/CreateNetworkWithTrainingDataCopyResp" + + "onse")] + System.Threading.Tasks.Task CreateNetworkWithTrainingDataCopyAsync(string networkName, System.Collections.ObjectModel.ObservableCollection individualTrainingsData, int copyTraindataFromNetworkId); + + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/INumberRecognizerService/DeleteNetwork", ReplyAction="http://tempuri.org/INumberRecognizerService/DeleteNetworkResponse")] + System.Threading.Tasks.Task DeleteNetworkAsync(int networkId); + + [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/INumberRecognizerService/RecognizePhoneNumber", ReplyAction="http://tempuri.org/INumberRecognizerService/RecognizePhoneNumberResponse")] + System.Threading.Tasks.Task RecognizePhoneNumberAsync(int networkId, System.Collections.ObjectModel.ObservableCollection imageData); + } + + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + public interface INumberRecognizerServiceChannel : NumberRecognizer.App.NumberRecognizerService.INumberRecognizerService, System.ServiceModel.IClientChannel { + } + + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] + public partial class NumberRecognizerServiceClient : System.ServiceModel.ClientBase, NumberRecognizer.App.NumberRecognizerService.INumberRecognizerService { + + /// + /// Implement this partial method to configure the service endpoint. + /// + /// The endpoint to configure + /// The client credentials + static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials); + + public NumberRecognizerServiceClient() : + base(NumberRecognizerServiceClient.GetDefaultBinding(), NumberRecognizerServiceClient.GetDefaultEndpointAddress()) { + this.Endpoint.Name = EndpointConfiguration.BasicHttpBinding_INumberRecognizerService.ToString(); + ConfigureEndpoint(this.Endpoint, this.ClientCredentials); + } + + public NumberRecognizerServiceClient(EndpointConfiguration endpointConfiguration) : + base(NumberRecognizerServiceClient.GetBindingForEndpoint(endpointConfiguration), NumberRecognizerServiceClient.GetEndpointAddress(endpointConfiguration)) { + this.Endpoint.Name = endpointConfiguration.ToString(); + ConfigureEndpoint(this.Endpoint, this.ClientCredentials); + } + + public NumberRecognizerServiceClient(EndpointConfiguration endpointConfiguration, string remoteAddress) : + base(NumberRecognizerServiceClient.GetBindingForEndpoint(endpointConfiguration), new System.ServiceModel.EndpointAddress(remoteAddress)) { + this.Endpoint.Name = endpointConfiguration.ToString(); + ConfigureEndpoint(this.Endpoint, this.ClientCredentials); + } + + public NumberRecognizerServiceClient(EndpointConfiguration endpointConfiguration, System.ServiceModel.EndpointAddress remoteAddress) : + base(NumberRecognizerServiceClient.GetBindingForEndpoint(endpointConfiguration), remoteAddress) { + this.Endpoint.Name = endpointConfiguration.ToString(); + ConfigureEndpoint(this.Endpoint, this.ClientCredentials); + } + + public NumberRecognizerServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : + base(binding, remoteAddress) { + } + + public System.Threading.Tasks.Task> GetNetworksAsync() { + return base.Channel.GetNetworksAsync(); + } + + public System.Threading.Tasks.Task CreateNetworkAsync(string networkName, System.Collections.ObjectModel.ObservableCollection individualTrainingsData) { + return base.Channel.CreateNetworkAsync(networkName, individualTrainingsData); + } + + public System.Threading.Tasks.Task CreateNetworkWithTrainingDataCopyAsync(string networkName, System.Collections.ObjectModel.ObservableCollection individualTrainingsData, int copyTraindataFromNetworkId) { + return base.Channel.CreateNetworkWithTrainingDataCopyAsync(networkName, individualTrainingsData, copyTraindataFromNetworkId); + } + + public System.Threading.Tasks.Task DeleteNetworkAsync(int networkId) { + return base.Channel.DeleteNetworkAsync(networkId); + } + + public System.Threading.Tasks.Task RecognizePhoneNumberAsync(int networkId, System.Collections.ObjectModel.ObservableCollection imageData) { + return base.Channel.RecognizePhoneNumberAsync(networkId, imageData); + } + + public virtual System.Threading.Tasks.Task OpenAsync() { + return System.Threading.Tasks.Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginOpen(null, null), new System.Action(((System.ServiceModel.ICommunicationObject)(this)).EndOpen)); + } + + public virtual System.Threading.Tasks.Task CloseAsync() { + return System.Threading.Tasks.Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginClose(null, null), new System.Action(((System.ServiceModel.ICommunicationObject)(this)).EndClose)); + } + + private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration) { + if ((endpointConfiguration == EndpointConfiguration.BasicHttpBinding_INumberRecognizerService)) { + System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding(); + result.MaxBufferSize = int.MaxValue; + result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max; + result.MaxReceivedMessageSize = int.MaxValue; + result.AllowCookies = true; + return result; + } + throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration)); + } + + private static System.ServiceModel.EndpointAddress GetEndpointAddress(EndpointConfiguration endpointConfiguration) { + if ((endpointConfiguration == EndpointConfiguration.BasicHttpBinding_INumberRecognizerService)) { + return new System.ServiceModel.EndpointAddress("http://0d832919582344d9b6d490f5aca905d8.cloudapp.net/NumberRecognizerService.svc"); + } + throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration)); + } + + private static System.ServiceModel.Channels.Binding GetDefaultBinding() { + return NumberRecognizerServiceClient.GetBindingForEndpoint(EndpointConfiguration.BasicHttpBinding_INumberRecognizerService); + } + + private static System.ServiceModel.EndpointAddress GetDefaultEndpointAddress() { + return NumberRecognizerServiceClient.GetEndpointAddress(EndpointConfiguration.BasicHttpBinding_INumberRecognizerService); + } + + public enum EndpointConfiguration { + + BasicHttpBinding_INumberRecognizerService, + } + } +} diff --git a/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/Reference.svcmap b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/Reference.svcmap new file mode 100644 index 0000000..647a23e --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/Reference.svcmap @@ -0,0 +1,38 @@ + + + + false + true + true + + false + false + false + + + + + false + Auto + true + true + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/configuration.svcinfo b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/configuration.svcinfo new file mode 100644 index 0000000..ed19569 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/configuration.svcinfo @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/configuration91.svcinfo b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/configuration91.svcinfo new file mode 100644 index 0000000..fa2f8e5 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/configuration91.svcinfo @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/NumberRecognizer/NumberRecognizer.App/Style/AppStyle.xaml b/NumberRecognizer/NumberRecognizer.App/Style/AppStyle.xaml new file mode 100644 index 0000000..9bfcd64 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/Style/AppStyle.xaml @@ -0,0 +1,54 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/NumberRecognizer/NumberRecognizer.App/View/CreateNetworkPage.xaml b/NumberRecognizer/NumberRecognizer.App/View/CreateNetworkPage.xaml new file mode 100644 index 0000000..f98c6cf --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/View/CreateNetworkPage.xaml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NumberRecognizer/NumberRecognizer.App/View/CreateNetworkPage.xaml.cs b/NumberRecognizer/NumberRecognizer.App/View/CreateNetworkPage.xaml.cs new file mode 100644 index 0000000..c539b76 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/View/CreateNetworkPage.xaml.cs @@ -0,0 +1,180 @@ +//----------------------------------------------------------------------- +// +// Copyright Markus Zytek. All rights reserved. +// +// Markus Zytek +// Create Network Page. +//----------------------------------------------------------------------- +namespace NumberRecognizer.App.View +{ + using System; + using System.Collections.ObjectModel; + using NumberRecognizer.App.Common; + using NumberRecognizer.App.Control; + using NumberRecognizer.App.ViewModel; + using Windows.UI; + using Windows.UI.Xaml; + using Windows.UI.Xaml.Controls; + using Windows.UI.Xaml.Media; + using Windows.UI.Xaml.Navigation; + + /// + /// A basic page that provides characteristics common to most applications. + /// + public sealed partial class CreateNetworkPage : Page + { + /// + /// The navigation helper. + /// + private NavigationHelper navigationHelper; + + /// + /// The default view model. + /// + private ObservableDictionary defaultViewModel = new ObservableDictionary(); + + /// + /// The text block collection. + /// + private ObservableCollection textBlockCollection = new ObservableCollection(); + + /// + /// The view model. + /// + private CreateNetworkPageViewModel viewModel; + + /// + /// Initializes a new instance of the class. + /// + public CreateNetworkPage() + { + this.InitializeComponent(); + this.navigationHelper = new NavigationHelper(this); + this.navigationHelper.LoadState += this.NavigationHelper_LoadState; + this.navigationHelper.SaveState += this.NavigationHelper_SaveState; + this.viewModel = (CreateNetworkPageViewModel)this.DataContext; + this.InitializePage(); + this.inkCanvasRTStackPanel.SizeChanged += this.InkCanvasRTStackPanel_SizeChanged; + } + + /// + /// Gets the default view model. + /// + /// + /// The default view model. + /// + public ObservableDictionary DefaultViewModel + { + get { return this.defaultViewModel; } + } + + /// + /// Gets the navigation helper. + /// + /// + /// The navigation helper. + /// + public NavigationHelper NavigationHelper + { + get { return this.navigationHelper; } + } + + /// + /// Invoked when the Page is loaded and becomes the current source of a parent Frame. + /// + /// Event data that can be examined by overriding code. The event data is representative of the pending navigation that will load the current Page. Usually the most relevant property to examine is Parameter. + /// The methods provided in this section are simply used to allow + /// NavigationHelper to respond to the page's navigation methods. + /// Page specific logic should be placed in event handlers for the + /// + /// and . + /// The navigation parameter is available in the LoadState method + /// in addition to page state preserved during an earlier session. + protected override void OnNavigatedTo(NavigationEventArgs e) + { + this.navigationHelper.OnNavigatedTo(e); + } + + /// + /// Invoked immediately after the Page is unloaded and is no longer the current source of a parent Frame. + /// + /// Event data that can be examined by overriding code. The event data is representative of the navigation that has unloaded the current Page. + protected override void OnNavigatedFrom(NavigationEventArgs e) + { + this.navigationHelper.OnNavigatedFrom(e); + } + + /// + /// Initializes the page. + /// + private void InitializePage() + { + foreach (InkCanvasRT inkCanvasRT in this.viewModel.InkCanvasRTCollection) + { + this.inkCanvasRTStackPanel.Children.Add(inkCanvasRT); + TextBlock textBlock = new TextBlock() + { + Text = string.Format("{0} *", inkCanvasRT.Name), + FontSize = 28, + Foreground = new SolidColorBrush(Colors.OrangeRed), + VerticalAlignment = VerticalAlignment.Bottom, + Margin = inkCanvasRT.Margin + }; + this.textBlockCollection.Add(textBlock); + this.textBlockStackPanel.Children.Add(textBlock); + } + } + + /// + /// Handles the SizeChanged event of the InkCanvasRTStackPanel control. + /// + /// The source of the event. + /// The instance containing the event data. + private void InkCanvasRTStackPanel_SizeChanged(object sender, SizeChangedEventArgs e) + { + StackPanel stackPanel = (StackPanel)sender; + int count = this.viewModel.InkCanvasRTCollection.Count; + + foreach (InkCanvasRT inkCanvasRT in this.viewModel.InkCanvasRTCollection) + { + inkCanvasRT.Height = stackPanel.ActualHeight / count; + inkCanvasRT.Width = stackPanel.ActualWidth; + } + + foreach (TextBlock textBlock in this.textBlockCollection) + { + textBlock.Height = stackPanel.ActualHeight / count; + textBlock.Width = stackPanel.ActualWidth; + } + + this.inkCanvasRTStackPanel.SizeChanged -= this.InkCanvasRTStackPanel_SizeChanged; + } + + /// + /// Populates the page with content passed during navigation. Any saved state is also + /// provided when recreating a page from a prior session. + /// + /// + /// The source of the event; typically + /// + /// Event data that provides both the navigation parameter passed to + /// when this page was initially requested and + /// a dictionary of state preserved by this page during an earlier + /// session. The state will be null the first time a page is visited. + private void NavigationHelper_LoadState(object sender, LoadStateEventArgs e) + { + } + + /// + /// Preserves state associated with this page in case the application is suspended or the + /// page is discarded from the navigation cache. Values must conform to the serialization + /// requirements of . + /// + /// The source of the event; typically + /// Event data that provides an empty dictionary to be populated with + /// serializable state. + private void NavigationHelper_SaveState(object sender, SaveStateEventArgs e) + { + } + } +} diff --git a/NumberRecognizer/NumberRecognizer.App/View/GroupDetailPage.xaml b/NumberRecognizer/NumberRecognizer.App/View/GroupDetailPage.xaml new file mode 100644 index 0000000..cfd280e --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/View/GroupDetailPage.xaml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NumberRecognizer/NumberRecognizer.App/View/GroupedImagesPage.xaml.cs b/NumberRecognizer/NumberRecognizer.App/View/GroupedImagesPage.xaml.cs new file mode 100644 index 0000000..1864932 --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/View/GroupedImagesPage.xaml.cs @@ -0,0 +1,119 @@ +//----------------------------------------------------------------------- +// +// Copyright Markus Zytek. All rights reserved. +// +// Markus Zytek +// Grouped Images Page. +//----------------------------------------------------------------------- +namespace NumberRecognizer.App.View +{ + using System; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using NumberRecognizer.App.Common; + using NumberRecognizer.App.DataModel; + using NumberRecognizer.App.ViewModel; + using Windows.UI.Xaml.Controls; + using Windows.UI.Xaml.Navigation; + + /// + /// A page that displays a grouped collection of items. + /// + public sealed partial class GroupedImagesPage : Page + { + /// + /// The navigation helper. + /// + private NavigationHelper navigationHelper; + + /// + /// The default view model. + /// + private ObservableDictionary defaultViewModel = new ObservableDictionary(); + + /// + /// The view model. + /// + private GroupedImagesPageViewModel viewModel; + + /// + /// Initializes a new instance of the class. + /// + public GroupedImagesPage() + { + this.InitializeComponent(); + this.navigationHelper = new NavigationHelper(this); + this.navigationHelper.LoadState += this.NavigationHelper_LoadState; + } + + /// + /// Gets the default view model. + /// + /// + /// The default view model. + /// + public ObservableDictionary DefaultViewModel + { + get { return this.defaultViewModel; } + } + + /// + /// Gets the navigation helper. + /// + /// + /// The navigation helper. + /// + public NavigationHelper NavigationHelper + { + get + { + return this.navigationHelper; + } + } + + /// + /// Invoked when the Page is loaded and becomes the current source of a parent Frame. + /// + /// Event data that can be examined by overriding code. The event data is representative of the pending navigation that will load the current Page. Usually the most relevant property to examine is Parameter. + /// The methods provided in this section are simply used to allow + /// NavigationHelper to respond to the page's navigation methods. + /// Page specific logic should be placed in event handlers for the + /// + /// and . + /// The navigation parameter is available in the LoadState method + /// in addition to page state preserved during an earlier session. + protected override void OnNavigatedTo(NavigationEventArgs e) + { + this.navigationHelper.OnNavigatedTo(e); + } + + /// + /// Invoked immediately after the Page is unloaded and is no longer the current source of a parent Frame. + /// + /// Event data that can be examined by overriding code. The event data is representative of the navigation that has unloaded the current Page. + protected override void OnNavigatedFrom(NavigationEventArgs e) + { + this.navigationHelper.OnNavigatedFrom(e); + } + + /// + /// Populates the page with content passed during navigation. Any saved state is also + /// provided when recreating a page from a prior session. + /// + /// + /// The source of the event; typically + /// + /// Event data that provides both the navigation parameter passed to + /// when this page was initially requested and + /// a dictionary of state preserved by this page during an earlier + /// session. The state will be null the first time a page is visited. + private void NavigationHelper_LoadState(object sender, LoadStateEventArgs e) + { + // TODO: Assign a collection of bindable groups to this.DefaultViewModel["Groups"] + this.viewModel = (GroupedImagesPageViewModel)this.DataContext; + KeyValuePair> keyValuePair = (KeyValuePair>)e.NavigationParameter; + this.viewModel.NetworkName = keyValuePair.Key; + this.viewModel.Images = keyValuePair.Value; + } + } +} diff --git a/NumberRecognizer/NumberRecognizer.App/View/GroupedNetworksPage.xaml b/NumberRecognizer/NumberRecognizer.App/View/GroupedNetworksPage.xaml new file mode 100644 index 0000000..dc8188d --- /dev/null +++ b/NumberRecognizer/NumberRecognizer.App/View/GroupedNetworksPage.xaml @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +