Develop #10

Merged
SemvdH merged 229 commits from develop into master 2020-10-29 22:50:49 +00:00
35 changed files with 1269 additions and 113 deletions
Showing only changes of commit e3c580c8c2 - Show all commits

View File

@@ -6,13 +6,25 @@
xmlns:views="clr-namespace:ClientApp.Views"
StartupUri="Views/MainWindow.xaml">
<Application.Resources>
<DataTemplate DataType="{x:Type viewModels:MainViewModel}">
<views:MainView />
<!-- This is a UserControl -->
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:LoginViewModel}">
<views:LoginView />
<!-- This is a UserControl -->
</DataTemplate>
<ResourceDictionary>
<DataTemplate DataType="{x:Type viewModels:MainViewModel}">
<views:MainView />
<!-- This is a Page -->
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:LoginViewModel}">
<views:LoginView />
<!-- This is a Page -->
</DataTemplate>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles/Fonts.xaml"/>
<ResourceDictionary Source="Styles/Colors.xaml"/>
<ResourceDictionary Source="Styles/Buttons.xaml"/>
<ResourceDictionary Source="Styles/Texts.xaml"/>
<ResourceDictionary Source="Styles/Windows.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

View File

@@ -7,6 +7,36 @@
<ApplicationIcon>Images\Logo\icon1.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<None Remove="Images\CoolBackground.jpg" />
<None Remove="Images\Icons\CheckMark.png" />
<None Remove="Images\Icons\CrossMark.png" />
<None Remove="Images\Logo\icon1.ico" />
<None Remove="Images\re15.jpg" />
<None Remove="Images\stone.png" />
</ItemGroup>
<ItemGroup>
<Content Include="Images\CoolBackground.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Images\Icons\CheckMark.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Images\Icons\CrossMark.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Images\Logo\icon1.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Images\re15.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Images\stone.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="AsyncAwaitBestPractices.MVVM" Version="4.3.0" />
<PackageReference Include="MvvmLightLibsStd10" Version="5.4.1.1" />
@@ -19,6 +49,10 @@
<ProjectReference Include="..\RH-Engine\RH-Engine.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<Import Project="..\Hashing\Hashing.projitems" Label="Shared" />
</Project>

View File

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -0,0 +1,212 @@
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
namespace ClientApp.MagicCode
{
/// <summary>
/// Fixes the issue with Windows of Style <see cref="WindowStyle.None"/> covering the taskbar
/// </summary>
public class WindowResizer
{
#region Private Members
/// <summary>
/// The window to handle the resizing for
/// </summary>
private Window mWindow;
#endregion
#region Dll Imports
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetCursorPos(out POINT lpPoint);
[DllImport("user32.dll")]
static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr MonitorFromPoint(POINT pt, MonitorOptions dwFlags);
#endregion
#region Constructor
/// <summary>
/// Default constructor
/// </summary>
/// <param name="window">The window to monitor and correctly maximize</param>
/// <param name="adjustSize">The callback for the host to adjust the maximum available size if needed</param>
public WindowResizer(Window window)
{
mWindow = window;
// Listen out for source initialized to setup
mWindow.SourceInitialized += Window_SourceInitialized;
}
#endregion
#region Initialize
/// <summary>
/// Initialize and hook into the windows message pump
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Window_SourceInitialized(object sender, System.EventArgs e)
{
// Get the handle of this window
var handle = (new WindowInteropHelper(mWindow)).Handle;
var handleSource = HwndSource.FromHwnd(handle);
// If not found, end
if (handleSource == null)
return;
// Hook into it's Windows messages
handleSource.AddHook(WindowProc);
}
#endregion
#region Windows Proc
/// <summary>
/// Listens out for all windows messages for this window
/// </summary>
/// <param name="hwnd"></param>
/// <param name="msg"></param>
/// <param name="wParam"></param>
/// <param name="lParam"></param>
/// <param name="handled"></param>
/// <returns></returns>
private IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
{
// Handle the GetMinMaxInfo of the Window
case 0x0024:/* WM_GETMINMAXINFO */
WmGetMinMaxInfo(hwnd, lParam);
handled = true;
break;
}
return (IntPtr)0;
}
#endregion
/// <summary>
/// Get the min/max window size for this window
/// Correctly accounting for the taskbar size and position
/// </summary>
/// <param name="hwnd"></param>
/// <param name="lParam"></param>
private void WmGetMinMaxInfo(System.IntPtr hwnd, System.IntPtr lParam)
{
POINT lMousePosition;
GetCursorPos(out lMousePosition);
IntPtr lPrimaryScreen = MonitorFromPoint(new POINT(0, 0), MonitorOptions.MONITOR_DEFAULTTOPRIMARY);
MONITORINFO lPrimaryScreenInfo = new MONITORINFO();
if (GetMonitorInfo(lPrimaryScreen, lPrimaryScreenInfo) == false)
{
return;
}
IntPtr lCurrentScreen = MonitorFromPoint(lMousePosition, MonitorOptions.MONITOR_DEFAULTTONEAREST);
MINMAXINFO lMmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
if (lPrimaryScreen.Equals(lCurrentScreen) == true)
{
lMmi.ptMaxPosition.X = lPrimaryScreenInfo.rcWork.Left;
lMmi.ptMaxPosition.Y = lPrimaryScreenInfo.rcWork.Top;
lMmi.ptMaxSize.X = lPrimaryScreenInfo.rcWork.Right - lPrimaryScreenInfo.rcWork.Left;
lMmi.ptMaxSize.Y = lPrimaryScreenInfo.rcWork.Bottom - lPrimaryScreenInfo.rcWork.Top;
}
else
{
lMmi.ptMaxPosition.X = lPrimaryScreenInfo.rcMonitor.Left;
lMmi.ptMaxPosition.Y = lPrimaryScreenInfo.rcMonitor.Top;
lMmi.ptMaxSize.X = lPrimaryScreenInfo.rcMonitor.Right - lPrimaryScreenInfo.rcMonitor.Left;
lMmi.ptMaxSize.Y = lPrimaryScreenInfo.rcMonitor.Bottom - lPrimaryScreenInfo.rcMonitor.Top;
}
// Now we have the max size, allow the host to tweak as needed
Marshal.StructureToPtr(lMmi, lParam, true);
}
}
#region Dll Helper Structures
enum MonitorOptions : uint
{
MONITOR_DEFAULTTONULL = 0x00000000,
MONITOR_DEFAULTTOPRIMARY = 0x00000001,
MONITOR_DEFAULTTONEAREST = 0x00000002
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class MONITORINFO
{
public int cbSize = Marshal.SizeOf(typeof(MONITORINFO));
public Rectangle rcMonitor = new Rectangle();
public Rectangle rcWork = new Rectangle();
public int dwFlags = 0;
}
[StructLayout(LayoutKind.Sequential)]
public struct Rectangle
{
public int Left, Top, Right, Bottom;
public Rectangle(int left, int top, int right, int bottom)
{
this.Left = left;
this.Top = top;
this.Right = right;
this.Bottom = bottom;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct MINMAXINFO
{
public POINT ptReserved;
public POINT ptMaxSize;
public POINT ptMaxPosition;
public POINT ptMinTrackSize;
public POINT ptMaxTrackSize;
};
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
/// <summary>
/// x coordinate of point.
/// </summary>
public int X;
/// <summary>
/// y coordinate of point.
/// </summary>
public int Y;
/// <summary>
/// Construct a point of coordinates (x,y).
/// </summary>
public POINT(int x, int y)
{
this.X = x;
this.Y = y;
}
}
#endregion
}

View File

@@ -10,7 +10,7 @@ using Util;
namespace ClientApp.Utils
{
public delegate void EngineCallback();
public class Client : IDataReceiver
public class Client : IDataReceiver, IDisposable
{
public EngineCallback engineConnectFailed;
public EngineCallback engineConnectSuccess;
@@ -46,6 +46,7 @@ namespace ClientApp.Utils
engineConnection = EngineConnection.INSTANCE;
engineConnection.OnNoTunnelId = RetryEngineConnection;
engineConnection.OnSuccessFullConnection = engineConnected;
engineConnection.OnEngineDisconnect = RetryEngineConnection;
if (!engineConnection.Connected) engineConnection.Connect();
}
@@ -87,6 +88,10 @@ namespace ClientApp.Utils
/// <param name="ar">the result of the async read</param>
private void OnRead(IAsyncResult ar)
{
if (ar == null || (!ar.IsCompleted) || (!this.stream.CanRead))
return;
int receivedBytes = this.stream.EndRead(ar);
if (totalBufferReceived + receivedBytes > 1024)
@@ -122,7 +127,7 @@ namespace ClientApp.Utils
this.LoginViewModel.setLoginStatus(true);
this.connected = true;
initEngine();
}
else
{
@@ -224,7 +229,7 @@ namespace ClientApp.Utils
/// <param name="bytes">the message</param>
public void Bike(byte[] bytes)
{
if (!sessionRunning)
{
return;
@@ -266,7 +271,7 @@ namespace ClientApp.Utils
/// </summary>
public void tryLogin(string username, string password)
{
string hashPassword = Util.Hasher.HashString(password);
byte[] message = DataParser.getJsonMessage(DataParser.GetLoginJson(username, hashPassword));
@@ -288,5 +293,13 @@ namespace ClientApp.Utils
{
this.LoginViewModel = loginViewModel;
}
public void Dispose()
{
Debug.WriteLine("client dispose called");
this.stream.Dispose();
this.client.Dispose();
this.handler.stop();
}
}
}

View File

@@ -10,16 +10,17 @@ using LibNoise.Primitive;
namespace ClientApp.Utils
{
public delegate void HandleSerial(string message);
public delegate void HandleNoTunnelId();
public delegate void OnSuccessfullConnection();
public delegate void EngineDelegate();
public sealed class EngineConnection
{
private static EngineConnection instance = null;
private static readonly object padlock = new object();
private static System.Timers.Timer updateTimer;
public HandleNoTunnelId OnNoTunnelId;
public OnSuccessfullConnection OnSuccessFullConnection;
private static System.Timers.Timer noVRResponseTimer;
public EngineDelegate OnNoTunnelId;
public EngineDelegate OnSuccessFullConnection;
public EngineDelegate OnEngineDisconnect;
private static PC[] PCs = {
@@ -42,6 +43,7 @@ namespace ClientApp.Utils
private static string headId = string.Empty;
private static string groundPlaneId = string.Empty;
private static string terrainId = string.Empty;
private static string lastMessage = "No message received yet";
public float BikeSpeed { get; set; }
public float BikePower { get; set; }
@@ -67,6 +69,12 @@ namespace ClientApp.Utils
updateTimer.Elapsed += UpdateTimer_Elapsed;
updateTimer.AutoReset = true;
updateTimer.Enabled = false;
noVRResponseTimer = new System.Timers.Timer(15000);
noVRResponseTimer.Elapsed += noVRResponseTimeout;
noVRResponseTimer.AutoReset = false;
noVRResponseTimer.Enabled = false;
}
private void UpdateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
@@ -74,6 +82,21 @@ namespace ClientApp.Utils
UpdateInfoPanel();
}
private void noVRResponseTimeout(object sender, System.Timers.ElapsedEventArgs e)
{
Write("VR RESPONSE TIMEOUT");
noVRResponseTimer.Stop();
sessionId = string.Empty;
tunnelId = string.Empty;
cameraId = string.Empty;
routeId = string.Empty;
panelId = string.Empty;
bikeId = string.Empty;
groundPlaneId = string.Empty;
terrainId = string.Empty;
OnEngineDisconnect?.Invoke();
}
/// <summary>
/// Singleton constructor
/// </summary>
@@ -165,6 +188,7 @@ namespace ClientApp.Utils
{
Write("got tunnel id! " + tunnelId);
Connected = true;
noVRResponseTimer.Enabled = true;
OnSuccessFullConnection?.Invoke();
}
}
@@ -176,6 +200,9 @@ namespace ClientApp.Utils
//Console.WriteLine("Got serial " + serial);
if (serialResponses.ContainsKey(serial)) serialResponses[serial].Invoke(message);
}
noVRResponseTimer.Stop();
noVRResponseTimer.Start();
}
public void initScene()
@@ -297,6 +324,11 @@ namespace ClientApp.Utils
{
// TODO check if is drawn
});
SendMessageAndOnResponse(mainCommand.showMessage(panelId, "message", lastMessage), "message",
(message) =>
{
// TODO check if is drawn
});
// Check if every text is drawn!

View File

@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Data;
using System.Windows.Media.Imaging;
namespace ClientApp.ValueConverters
{
//[ValueConversion(typeof(bool), typeof(BitmapImage))]
class BoolToMarkConverter : IValueConverter
{
public BitmapImage TrueImage { get; set; } = new BitmapImage(new Uri("pack://application:,,,/Images/Icons/CheckMark.png"));
public BitmapImage FalseImage { get; set; } = new BitmapImage(new Uri("pack://application:,,,/Images/Icons/CrossMark.png"));
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (!(value is bool))
{
return null;
}
bool b = (bool)value;
if (b)
{
return this.TrueImage;
}
else
{
return this.FalseImage;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@@ -20,14 +20,14 @@ namespace ClientApp.ViewModels
public bool InvertedLoginStatus { get; set; }
private MainWindowViewModel mainWindowViewModel;
private MainWindowViewModel MainWindowViewModel;
public LoginViewModel(MainWindowViewModel mainWindowViewModel)
{
this.mainWindowViewModel = mainWindowViewModel;
this.MainWindowViewModel = mainWindowViewModel;
LoginCommand = new RelayCommand<object>((parameter) =>
{
//TODO send username and password to server
this.mainWindowViewModel.client.tryLogin(Username, ((PasswordBox)parameter).Password);
this.MainWindowViewModel.client.tryLogin(Username, ((PasswordBox)parameter).Password);
});
}
@@ -35,11 +35,11 @@ namespace ClientApp.ViewModels
internal void setLoginStatus(bool status)
{
this.mainWindowViewModel.InfoModel.ConnectedToServer = status;
this.MainWindowViewModel.InfoModel.ConnectedToServer = status;
this.InvertedLoginStatus = !status;
if (status)
{
this.mainWindowViewModel.SelectedViewModel = new MainViewModel(mainWindowViewModel);
this.MainWindowViewModel.SelectedViewModel = new MainViewModel(MainWindowViewModel);
}
}
}

View File

@@ -1,37 +1,137 @@
using ClientApp.Models;
using ClientApp.MagicCode;
using ClientApp.Models;
using ClientApp.Utils;
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Text;
using Util;
using System.Windows;
using System.Windows.Input;
namespace ClientApp.ViewModels
{
class MainWindowViewModel : ObservableObject
{
#region private members
private Window mWindow;
private int mOuterMarginSize = 10;
private int mWindowRadius = 10;
#endregion
#region commands
public ICommand MinimizeCommand { get; set; }
public ICommand MaximizeCommand { get; set; }
public ICommand CloseCommand { get; set; }
public ICommand MenuCommand { get; set; }
#endregion
#region public properties
public Info InfoModel { get; set; }
public ObservableObject SelectedViewModel { get; set; }
public Client client { get; }
LoginViewModel loginViewModel;
/// <summary>
/// size of the resize border around the window
/// </summary>
public MainWindowViewModel(Client client)
public double MinimumWidth { get; set; } = 250;
public double MinimumHeight { get; set; } = 250;
public int ResizeBorder { get; set; } = 6;
public Thickness ResizeBorderThickness { get { return new Thickness(ResizeBorder + OuterMarginSize); } }
public Thickness InnerContentPadding { get { return new Thickness(ResizeBorder); } }
public Thickness OuterMarginThickness { get { return new Thickness(OuterMarginSize); } }
public CornerRadius WindowCornerRadius { get { return new CornerRadius(WindowRadius); } }
public int OuterMarginSize
{
get
{
return mWindow.WindowState == WindowState.Maximized ? 0 : mOuterMarginSize;
}
set
{
mOuterMarginSize = value;
}
}
public int WindowRadius
{
get
{
return mWindow.WindowState == WindowState.Maximized ? 0 : mWindowRadius;
}
set
{
mWindowRadius = value;
}
}
public int TitleHeight { get; set; } = 42;
public GridLength TitleHeightGridLength { get { return new GridLength(TitleHeight + ResizeBorder); } }
#endregion
public MainWindowViewModel(Window window, Client client)
{
this.mWindow = window;
this.mWindow.StateChanged += (sender, e) =>
{
OnPropertyChanged(nameof(ResizeBorderThickness));
OnPropertyChanged(nameof(OuterMarginThickness));
OnPropertyChanged(nameof(WindowCornerRadius));
OnPropertyChanged(nameof(OuterMarginSize));
OnPropertyChanged(nameof(WindowRadius));
};
this.InfoModel = new Info();
this.client = client;
loginViewModel = new LoginViewModel(this);
SelectedViewModel = loginViewModel;
this.client.SetLoginViewModel(loginViewModel);
App.Current.MainWindow.Closing += new CancelEventHandler(MainWindow_Closing);
this.MinimizeCommand = new RelayCommand(() => this.mWindow.WindowState = WindowState.Minimized);
this.MaximizeCommand = new RelayCommand(() => this.mWindow.WindowState ^= WindowState.Maximized);
this.CloseCommand = new RelayCommand(() => this.mWindow.Close());
this.MenuCommand = new RelayCommand(() => SystemCommands.ShowSystemMenu(this.mWindow, GetMousePosition()));
var resizer = new WindowResizer(this.mWindow);
this.mWindow.Closed += (sender, e) => this.client.Dispose();
}
void MainWindow_Closing(object sender, CancelEventArgs e)
#region helper
private Point GetMousePosition()
{
this.client.sendMessage(DataParser.getDisconnectJson(loginViewModel.Username));
Debug.WriteLine("getmousePosition called");
var p = Mouse.GetPosition(this.mWindow);
return new Point(p.X + this.mWindow.Left, p.Y + this.mWindow.Top);
}
#endregion
}
}

View File

@@ -6,11 +6,12 @@
xmlns:local="clr-namespace:ClientApp.Views"
xmlns:viewModels="clr-namespace:ClientApp.ViewModels"
mc:Ignorable="d"
ShowsNavigationUI="False"
d:DesignHeight="450" d:DesignWidth="800">
<DockPanel Background="Lime">
<!--<DockPanel.Background>
<ImageBrush TileMode="Tile" ViewportUnits="Absolute" Viewport="0 0 256 256" ImageSource="\images\stone.png"/>
</DockPanel.Background>-->
<DockPanel>
<DockPanel.Background>
<ImageBrush TileMode="Tile" ViewportUnits="Absolute" Viewport="0 0 64 64" ImageSource="\images\stone.png"/>
</DockPanel.Background>
<StackPanel VerticalAlignment="Center" Width="auto">
<Label Content="Username" HorizontalContentAlignment="Center" />
<TextBox x:Name="Username" Text="{Binding Username}" TextWrapping="Wrap" Width="120"/>

View File

@@ -4,8 +4,13 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ClientApp.Views"
xmlns:converter="clr-namespace:ClientApp.ValueConverters"
ShowsNavigationUI="False"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Page.Resources>
<converter:BoolToMarkConverter x:Key="BoolToMarkConverter"/>
</Page.Resources>
<DockPanel>
<Grid>
<Grid.ColumnDefinitions>
@@ -14,32 +19,21 @@
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Grid.Column="0" Grid.Row="0" Orientation="Horizontal" Margin="10">
<Label Content="Connected to server:"/>
<Label Content="true"/>
<StackPanel Grid.Column="0" Grid.Row="0" Orientation="Horizontal" Margin="20" HorizontalAlignment="Center">
<Label Content="Connected to server:" VerticalAlignment="Center"/>
<Image Source="{Binding Converter={StaticResource BoolToMarkConverter},Path=MainWindowViewModel.InfoModel.ConnectedToServer}" Stretch="Uniform" Width="20" Height="20"/>
</StackPanel>
<StackPanel Grid.Column="1" Grid.Row="0" Orientation="Horizontal" Margin="10">
<Label Content="Connected to VR-Engine:"/>
<Label Content="{Binding Path=MainWindowViewModel.InfoModel.ConnectedToVREngine}"/>
<StackPanel Grid.Column="1" Grid.Row="0" Orientation="Horizontal" Margin="20" HorizontalAlignment="Center">
<Label Content="Connected to VR-Engine:" VerticalAlignment="Center"/>
<Image Source="{Binding Converter={StaticResource BoolToMarkConverter},Path=MainWindowViewModel.InfoModel.ConnectedToVREngine}" Stretch="Uniform" Width="20" Height="20"/>
</StackPanel>
<StackPanel Grid.Column="2" Grid.Row="0" Orientation="Horizontal" Margin="10">
<Label Content="Doctor connected:"/>
<Label Content="{Binding Path=MainWindowViewModel.InfoModel.DoctorConnected}"/>
<StackPanel Grid.Column="2" Grid.Row="0" Orientation="Horizontal" Margin="20" HorizontalAlignment="Center">
<Label Content="Doctor connected:" VerticalAlignment="Center"/>
<Image Source="{Binding Converter={StaticResource BoolToMarkConverter},Path=MainWindowViewModel.InfoModel.DoctorConnected}" Stretch="Uniform" Width="20" Height="20"/>
</StackPanel>
<Button Grid.Column="0" Grid.Row="1" Command="{Binding RetryServerCommand}" Width="50" Height="20">
<Button.Content>
<TextBlock TextWrapping="Wrap" Text="retry"/>
</Button.Content>
</Button>
</Grid>
</DockPanel>

View File

@@ -5,12 +5,124 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ClientApp"
xmlns:views="clr-namespace:ClientApp.Views"
xmlns:images="clrnamespace.Images"
mc:Ignorable="d"
Title="Whaazzzzuuuuuuuup" Height="450" Width="800">
WindowStyle="None"
AllowsTransparency="True"
x:Name="applicatonWindow"
WindowStartupLocation="CenterScreen"
MinHeight="{Binding MinimumHeight}"
MinWidth="{Binding MinimumWidth}"
Title="Whaazzzzuuuuuuuup">
<!--Icon="/Images/Logo/icon1_small.ico"-->
<!--Icon="pack://application:,,,/Images/Log/icon1_small.ico"-->
<Window.Resources>
<Style TargetType="{x:Type local:MainWindow}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Border Padding="{Binding OuterMarginThickness, FallbackValue=10}" >
<Grid>
<!-- opacity mask -->
<Border x:Name="Container"
Background="{StaticResource BackgroundLightBrush}"
CornerRadius="{Binding WindowCornerRadius, FallbackValue=10}"/>
<Border CornerRadius="{Binding WindowCornerRadius, FallbackValue=10}"
Background="{StaticResource BackgroundVeryLightBrush}">
<Border.Effect>
<DropShadowEffect ShadowDepth="0" Opacity="0.2"/>
</Border.Effect>
</Border>
<Grid>
<Grid.OpacityMask>
<VisualBrush Visual="{Binding ElementName=Container}"/>
</Grid.OpacityMask>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding TitleHeightGridLength, FallbackValue=42}"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Title bar -->
<Grid Grid.Column="0" Grid.Row="0" Panel.ZIndex="1" Background="{StaticResource BackgroundLightBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- icon -->
<Button Grid.Column="0" Style="{StaticResource SystemIconButton}" Command="{Binding MenuCommand}">
<Image Source="/Images/Logo/icon1.ico"/>
<!--<TextBlock Text="icon"/>-->
</Button>
<!-- Title -->
<Viewbox Grid.Column="1" Margin="0">
<TextBlock Style="{StaticResource HeaderText}" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Title, FallbackValue=failed}"/>
</Viewbox>
<!-- Window buttons -->
<StackPanel Grid.Column="2" Orientation="Horizontal">
<Button Style="{StaticResource WindowControlButton}" Content="_" Command="{Binding MinimizeCommand}"/>
<Button Style="{StaticResource WindowControlButton}" Content="[]" Command="{Binding MaximizeCommand}"/>
<Button Style="{StaticResource WindowCloseButton}" Content="X" Command="{Binding CloseCommand}"/>
</StackPanel>
</Grid>
<!-- Page content -->
<Border Grid.Row="1" Grid.Column="0">
<ContentPresenter Content="{TemplateBinding Content}"/>
</Border>
<!-- shadow? -->
<Border Grid.Row="1" Height="6" BorderThickness="0 0.2 0 0" VerticalAlignment="Top">
<!--<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Color="{StaticResource BackgroundSemiLight}" Offset="0.0"/>
<GradientStop Color="{StaticResource BackgroundVeryLight}" Offset="1.0"/>
</LinearGradientBrush>
</Border.BorderBrush>-->
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="Transparent" Offset="1.0"/>
<GradientStop Color="#7000" Offset="0.0"/>
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<WindowChrome.WindowChrome>
<WindowChrome
ResizeBorderThickness="{Binding ResizeBorderThickness}"
CaptionHeight="{Binding TitleHeight}"
CornerRadius="0"
GlassFrameThickness="0"/>
</WindowChrome.WindowChrome>
<Grid>
<Frame Content="{Binding SelectedViewModel}" Focusable="False"/>
<Frame Content="{Binding SelectedViewModel}" Focusable="False" NavigationUIVisibility="Hidden"/>
<Label Content="gemaakt door: mensen" DockPanel.Dock="Bottom" HorizontalAlignment="Right" VerticalAlignment="Bottom" FontStyle="Italic" Foreground="Gray"/>
</Grid>
</Window>

View File

@@ -31,7 +31,7 @@ namespace ClientApp
Client client = new Client();
InitializeComponent();
DataContext = new MainWindowViewModel(client);
DataContext = new MainWindowViewModel(this, client);
//BLEHandler bLEHandler = new BLEHandler(client);

View File

@@ -6,17 +6,27 @@
xmlns:views="clr-namespace:DoctorApp.Views"
StartupUri="Views/MainWindow.xaml">
<Application.Resources>
<DataTemplate DataType="{x:Type viewModels:MainViewModel}">
<views:MainView />
<!-- This is a UserControl -->
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:LoginViewModel}">
<views:LoginView />
<!-- This is a UserControl -->
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:ClientInfoViewModel}">
<views:ClientInfoView/>
</DataTemplate>
<ResourceDictionary>
<DataTemplate DataType="{x:Type viewModels:MainViewModel}">
<views:MainView />
<!-- This is a UserControl -->
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:LoginViewModel}">
<views:LoginView />
<!-- This is a UserControl -->
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:ClientInfoViewModel}">
<views:ClientInfoView/>
</DataTemplate>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles/Fonts.xaml"/>
<ResourceDictionary Source="Styles/Colors.xaml"/>
<ResourceDictionary Source="Styles/Buttons.xaml"/>
<ResourceDictionary Source="Styles/Texts.xaml"/>
<ResourceDictionary Source="Styles/Windows.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

View File

@@ -57,6 +57,9 @@ namespace DoctorApp.Utils
/// <param name="ar">the result of the async read</param>
private void OnRead(IAsyncResult ar)
{
if (ar == null || (!ar.IsCompleted) || (!this.stream.CanRead))
return;
int receivedBytes = this.stream.EndRead(ar);
if (totalBufferReceived + receivedBytes > 1024)
@@ -91,7 +94,7 @@ namespace DoctorApp.Utils
Debug.WriteLine("Username and password correct!");
this.LoginViewModel.setLoginStatus(true);
this.connected = true;
}
else
{
@@ -192,7 +195,7 @@ namespace DoctorApp.Utils
/// <param name="bytes">the message</param>
public void Bike(byte[] bytes)
{
if (!sessionRunning)
{
return;
@@ -202,18 +205,18 @@ namespace DoctorApp.Utils
throw new ArgumentNullException("no bytes");
}
byte[] message = DataParser.GetRawDataMessage(bytes);
/* switch (bytes[0])
{
case 0x10:
/* switch (bytes[0])
{
if (canSendToEngine) engineConnection.BikeSpeed = (bytes[4] | (bytes[5] << 8)) * 0.01f;
break;
case 0x19:
if (canSendToEngine) engineConnection.BikePower = (bytes[5]) | (bytes[6] & 0b00001111) << 8;
break;
}*/
case 0x10:
if (canSendToEngine) engineConnection.BikeSpeed = (bytes[4] | (bytes[5] << 8)) * 0.01f;
break;
case 0x19:
if (canSendToEngine) engineConnection.BikePower = (bytes[5]) | (bytes[6] & 0b00001111) << 8;
break;
}*/
this.stream.BeginWrite(message, 0, message.Length, new AsyncCallback(OnWrite), null);
@@ -234,8 +237,8 @@ namespace DoctorApp.Utils
/// </summary>
public void tryLogin(string username, string password)
{
string hashUser = Hasher.HashString(username);
string hashPassword = Hasher.HashString(password);
string hashPassword = Util.Hasher.HashString(password);
byte[] message = DataParser.getJsonMessage(DataParser.GetLoginJson(hashUser, hashPassword));
@@ -266,5 +269,13 @@ namespace DoctorApp.Utils
{
this.ClientInfoViewModel = clientInfoViewModel;
}
public void Dispose()
{
Debug.WriteLine("client dispose called");
this.stream.Dispose();
this.client.Dispose();
this.handler?.stop();
}
}
}

View File

@@ -1,26 +1,134 @@
using DoctorApp.Models;
using DoctorApp.Utils;
using System;
using System.Collections.Generic;
using System.Text;
using GalaSoft.MvvmLight.Command;
using System.Diagnostics;
using Util;
using System.Windows;
using System.Windows.Input;
using DoctorApp.Models;
using DoctorApp.Utils;
using Util.MagicCode;
namespace DoctorApp.ViewModels
{
class MainWindowViewModel : ObservableObject
{
#region private members
private Window mWindow;
private int mOuterMarginSize = 10;
private int mWindowRadius = 10;
#endregion
#region commands
public ICommand MinimizeCommand { get; set; }
public ICommand MaximizeCommand { get; set; }
public ICommand CloseCommand { get; set; }
public ICommand MenuCommand { get; set; }
#endregion
#region public properties
public Info InfoModel { get; set; }
public ObservableObject SelectedViewModel { get; set; }
public Client client { get; }
public MainWindowViewModel(Client client)
/// <summary>
/// size of the resize border around the window
/// </summary>
public double MinimumWidth { get; set; } = 250;
public double MinimumHeight { get; set; } = 250;
public int ResizeBorder { get; set; } = 6;
public Thickness ResizeBorderThickness { get { return new Thickness(ResizeBorder + OuterMarginSize); } }
public Thickness InnerContentPadding { get { return new Thickness(ResizeBorder); } }
public Thickness OuterMarginThickness { get { return new Thickness(OuterMarginSize); } }
public CornerRadius WindowCornerRadius { get { return new CornerRadius(WindowRadius); } }
public int OuterMarginSize
{
get
{
return mWindow.WindowState == WindowState.Maximized ? 0 : mOuterMarginSize;
}
set
{
mOuterMarginSize = value;
}
}
public int WindowRadius
{
get
{
return mWindow.WindowState == WindowState.Maximized ? 0 : mWindowRadius;
}
set
{
mWindowRadius = value;
}
}
public int TitleHeight { get; set; } = 42;
public GridLength TitleHeightGridLength { get { return new GridLength(TitleHeight + ResizeBorder); } }
#endregion
public MainWindowViewModel(Window window, Client client)
{
this.mWindow = window;
this.mWindow.StateChanged += (sender, e) =>
{
OnPropertyChanged(nameof(ResizeBorderThickness));
OnPropertyChanged(nameof(OuterMarginThickness));
OnPropertyChanged(nameof(WindowCornerRadius));
OnPropertyChanged(nameof(OuterMarginSize));
OnPropertyChanged(nameof(WindowRadius));
};
this.InfoModel = new Info();
this.client = client;
LoginViewModel loginViewModel = new LoginViewModel(this);
SelectedViewModel = loginViewModel;
this.client.SetLoginViewModel(loginViewModel);
this.MinimizeCommand = new RelayCommand(() => this.mWindow.WindowState = WindowState.Minimized);
this.MaximizeCommand = new RelayCommand(() => this.mWindow.WindowState ^= WindowState.Maximized);
this.CloseCommand = new RelayCommand(() => this.mWindow.Close());
this.MenuCommand = new RelayCommand(() => SystemCommands.ShowSystemMenu(this.mWindow, GetMousePosition()));
var resizer = new WindowResizer(this.mWindow);
this.mWindow.Closed += (sender, e) => this.client.Dispose();
}
#region helper
private Point GetMousePosition()
{
Debug.WriteLine("getmousePosition called");
var p = Mouse.GetPosition(this.mWindow);
return new Point(p.X + this.mWindow.Left, p.Y + this.mWindow.Top);
}
#endregion
}
}

View File

@@ -5,10 +5,113 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DoctorApp"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"
WindowState="Maximized">
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<Style TargetType="{x:Type local:MainWindow}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Border Padding="{Binding OuterMarginThickness, FallbackValue=10}" >
<Grid>
<!-- opacity mask -->
<Border x:Name="Container"
Background="{StaticResource BackgroundLightBrush}"
CornerRadius="{Binding WindowCornerRadius, FallbackValue=10}"/>
<Border CornerRadius="{Binding WindowCornerRadius, FallbackValue=10}"
Background="{StaticResource BackgroundVeryLightBrush}">
<Border.Effect>
<DropShadowEffect ShadowDepth="0" Opacity="0.2"/>
</Border.Effect>
</Border>
<Grid>
<Grid.OpacityMask>
<VisualBrush Visual="{Binding ElementName=Container}"/>
</Grid.OpacityMask>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding TitleHeightGridLength, FallbackValue=42}"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Title bar -->
<Grid Grid.Column="0" Grid.Row="0" Panel.ZIndex="1" Background="{StaticResource BackgroundLightBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- icon -->
<Button Grid.Column="0" Style="{StaticResource SystemIconButton}" Command="{Binding MenuCommand}">
<Image Source="/Images/Logo/icon1.ico"/>
<!--<TextBlock Text="icon"/>-->
</Button>
<!-- Title -->
<Viewbox Grid.Column="1" Margin="0">
<TextBlock Style="{StaticResource HeaderText}" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Title, FallbackValue=failed}"/>
</Viewbox>
<!-- Window buttons -->
<StackPanel Grid.Column="2" Orientation="Horizontal">
<Button Style="{StaticResource WindowControlButton}" Content="_" Command="{Binding MinimizeCommand}"/>
<Button Style="{StaticResource WindowControlButton}" Content="[]" Command="{Binding MaximizeCommand}"/>
<Button Style="{StaticResource WindowCloseButton}" Content="X" Command="{Binding CloseCommand}"/>
</StackPanel>
</Grid>
<!-- Page content -->
<Border Grid.Row="1" Grid.Column="0">
<ContentPresenter Content="{TemplateBinding Content}"/>
</Border>
<!-- shadow? -->
<Border Grid.Row="1" Height="6" BorderThickness="0 0.2 0 0" VerticalAlignment="Top">
<!--<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Color="{StaticResource BackgroundSemiLight}" Offset="0.0"/>
<GradientStop Color="{StaticResource BackgroundVeryLight}" Offset="1.0"/>
</LinearGradientBrush>
</Border.BorderBrush>-->
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="Transparent" Offset="1.0"/>
<GradientStop Color="#7000" Offset="0.0"/>
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<WindowChrome.WindowChrome>
<WindowChrome
ResizeBorderThickness="{Binding ResizeBorderThickness}"
CaptionHeight="{Binding TitleHeight}"
CornerRadius="0"
GlassFrameThickness="0"/>
</WindowChrome.WindowChrome>
<Grid>
<ContentControl Content="{Binding SelectedViewModel}" Focusable="False" />
<Frame Content="{Binding SelectedViewModel}" Focusable="False" NavigationUIVisibility="Hidden"/>
<Label Content="gemaakt door: mensen" DockPanel.Dock="Bottom" HorizontalAlignment="Right" VerticalAlignment="Bottom" FontStyle="Italic" Foreground="Gray"/>
</Grid>
</Window>

View File

@@ -26,7 +26,7 @@ namespace DoctorApp
{
Client client = new Client();
InitializeComponent();
DataContext = new MainWindowViewModel(client);
DataContext = new MainWindowViewModel(this, client);
}
}
}

View File

@@ -40,6 +40,19 @@ namespace Util
return Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(json));
}
public static byte[] GetMessageToSend(string messageToSend)
{
dynamic json = new
{
identifier = MESSAGE,
data = new
{
message = messageToSend
}
};
return Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(json));
}
public static byte[] LoginAsDoctor(string mUsername, string mPassword)
{
dynamic json = new

View File

@@ -11,6 +11,29 @@
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)DataParser.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Hasher.cs" />
<Compile Include="$(MSBuildThisFileDirectory)MagicCode\WindowResizer.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ObservableObject.cs" />
</ItemGroup>
<ItemGroup>
<Page Include="$(MSBuildThisFileDirectory)Styles\Buttons.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Styles\Colors.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Styles\Fonts.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Styles\Texts.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Styles\Windows.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,212 @@
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
namespace Util.MagicCode
{
/// <summary>
/// Fixes the issue with Windows of Style <see cref="WindowStyle.None"/> covering the taskbar
/// </summary>
public class WindowResizer
{
#region Private Members
/// <summary>
/// The window to handle the resizing for
/// </summary>
private Window mWindow;
#endregion
#region Dll Imports
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetCursorPos(out POINT lpPoint);
[DllImport("user32.dll")]
static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr MonitorFromPoint(POINT pt, MonitorOptions dwFlags);
#endregion
#region Constructor
/// <summary>
/// Default constructor
/// </summary>
/// <param name="window">The window to monitor and correctly maximize</param>
/// <param name="adjustSize">The callback for the host to adjust the maximum available size if needed</param>
public WindowResizer(Window window)
{
mWindow = window;
// Listen out for source initialized to setup
mWindow.SourceInitialized += Window_SourceInitialized;
}
#endregion
#region Initialize
/// <summary>
/// Initialize and hook into the windows message pump
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Window_SourceInitialized(object sender, System.EventArgs e)
{
// Get the handle of this window
var handle = (new WindowInteropHelper(mWindow)).Handle;
var handleSource = HwndSource.FromHwnd(handle);
// If not found, end
if (handleSource == null)
return;
// Hook into it's Windows messages
handleSource.AddHook(WindowProc);
}
#endregion
#region Windows Proc
/// <summary>
/// Listens out for all windows messages for this window
/// </summary>
/// <param name="hwnd"></param>
/// <param name="msg"></param>
/// <param name="wParam"></param>
/// <param name="lParam"></param>
/// <param name="handled"></param>
/// <returns></returns>
private IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
{
// Handle the GetMinMaxInfo of the Window
case 0x0024:/* WM_GETMINMAXINFO */
WmGetMinMaxInfo(hwnd, lParam);
handled = true;
break;
}
return (IntPtr)0;
}
#endregion
/// <summary>
/// Get the min/max window size for this window
/// Correctly accounting for the taskbar size and position
/// </summary>
/// <param name="hwnd"></param>
/// <param name="lParam"></param>
private void WmGetMinMaxInfo(System.IntPtr hwnd, System.IntPtr lParam)
{
POINT lMousePosition;
GetCursorPos(out lMousePosition);
IntPtr lPrimaryScreen = MonitorFromPoint(new POINT(0, 0), MonitorOptions.MONITOR_DEFAULTTOPRIMARY);
MONITORINFO lPrimaryScreenInfo = new MONITORINFO();
if (GetMonitorInfo(lPrimaryScreen, lPrimaryScreenInfo) == false)
{
return;
}
IntPtr lCurrentScreen = MonitorFromPoint(lMousePosition, MonitorOptions.MONITOR_DEFAULTTONEAREST);
MINMAXINFO lMmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
if (lPrimaryScreen.Equals(lCurrentScreen) == true)
{
lMmi.ptMaxPosition.X = lPrimaryScreenInfo.rcWork.Left;
lMmi.ptMaxPosition.Y = lPrimaryScreenInfo.rcWork.Top;
lMmi.ptMaxSize.X = lPrimaryScreenInfo.rcWork.Right - lPrimaryScreenInfo.rcWork.Left;
lMmi.ptMaxSize.Y = lPrimaryScreenInfo.rcWork.Bottom - lPrimaryScreenInfo.rcWork.Top;
}
else
{
lMmi.ptMaxPosition.X = lPrimaryScreenInfo.rcMonitor.Left;
lMmi.ptMaxPosition.Y = lPrimaryScreenInfo.rcMonitor.Top;
lMmi.ptMaxSize.X = lPrimaryScreenInfo.rcMonitor.Right - lPrimaryScreenInfo.rcMonitor.Left;
lMmi.ptMaxSize.Y = lPrimaryScreenInfo.rcMonitor.Bottom - lPrimaryScreenInfo.rcMonitor.Top;
}
// Now we have the max size, allow the host to tweak as needed
Marshal.StructureToPtr(lMmi, lParam, true);
}
}
#region Dll Helper Structures
enum MonitorOptions : uint
{
MONITOR_DEFAULTTONULL = 0x00000000,
MONITOR_DEFAULTTOPRIMARY = 0x00000001,
MONITOR_DEFAULTTONEAREST = 0x00000002
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class MONITORINFO
{
public int cbSize = Marshal.SizeOf(typeof(MONITORINFO));
public Rectangle rcMonitor = new Rectangle();
public Rectangle rcWork = new Rectangle();
public int dwFlags = 0;
}
[StructLayout(LayoutKind.Sequential)]
public struct Rectangle
{
public int Left, Top, Right, Bottom;
public Rectangle(int left, int top, int right, int bottom)
{
this.Left = left;
this.Top = top;
this.Right = right;
this.Bottom = bottom;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct MINMAXINFO
{
public POINT ptReserved;
public POINT ptMaxSize;
public POINT ptMaxPosition;
public POINT ptMinTrackSize;
public POINT ptMaxTrackSize;
};
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
/// <summary>
/// x coordinate of point.
/// </summary>
public int X;
/// <summary>
/// y coordinate of point.
/// </summary>
public int Y;
/// <summary>
/// Construct a point of coordinates (x,y).
/// </summary>
public POINT(int x, int y)
{
this.X = x;
this.Y = y;
}
}
#endregion
}

View File

@@ -7,6 +7,11 @@ namespace Util
{
public abstract class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public event PropertyChangedEventHandler PropertyChanged = (sender, e) => { };
public void OnPropertyChanged(string name)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}

View File

@@ -0,0 +1,65 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ClientApp">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Colors.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type Button}" x:Key="Hoverless">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type Button}" x:Key="SystemIconButton" BasedOn="{StaticResource Hoverless}" >
<Setter Property="WindowChrome.IsHitTestVisibleInChrome" Value="True"/>
<Setter Property="Padding" Value="4"/>
</Style>
<Style TargetType="{x:Type Button}" x:Key="WindowControlButton">
<Setter Property="WindowChrome.IsHitTestVisibleInChrome" Value="True"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="Foreground" Value="{StaticResource ForegroundMainBrush}"/>
<Setter Property="Padding" Value="6"/>
<Setter Property="LayoutTransform">
<Setter.Value>
<ScaleTransform ScaleX="2"/>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource BackgroundSemiLightBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type Button}" x:Key="WindowCloseButton" BasedOn="{StaticResource WindowControlButton}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,25 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ClientApp">
<Color x:Key="BackgroundLight">#efefef</Color>
<SolidColorBrush x:Key="BackgroundLightBrush" Color="{StaticResource BackgroundLight}"/>
<Color x:Key="BackgroundVeryLight">#fafafa</Color>
<SolidColorBrush x:Key="BackgroundVeryLightBrush" Color="{StaticResource BackgroundVeryLight}"/>
<Color x:Key="BackgroundSemiLight">#d7d7d7</Color>
<SolidColorBrush x:Key="BackgroundSemiLightBrush" Color="{StaticResource BackgroundSemiLight}"/>
<Color x:Key="ForegroundMain">#686868</Color>
<SolidColorBrush x:Key="ForegroundMainBrush" Color="{StaticResource ForegroundMain}"/>
<Color x:Key="ForegroundVeryDark">#000</Color>
<SolidColorBrush x:Key="ForegroundVeryDarkBrush" Color="{StaticResource ForegroundVeryDark}"/>
<Color x:Key="ForegroundWhite">#fff</Color>
<SolidColorBrush x:Key="ForegroundWhiteBrush" Color="{StaticResource ForegroundWhite}"/>
</ResourceDictionary>

View File

@@ -0,0 +1,5 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ClientApp">
</ResourceDictionary>

11
Hashing/Styles/Texts.xaml Normal file
View File

@@ -0,0 +1,11 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ClientApp">
<Style TargetType="{x:Type TextBlock}" x:Key="HeaderText">
<Setter Property="Foreground" Value="{StaticResource ForegroundMainBrush}"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="Margin" Value="0 4"/>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,5 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ClientApp">
</ResourceDictionary>

View File

@@ -2,6 +2,7 @@
using ProftaakRH;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
@@ -92,8 +93,17 @@ namespace Hardware.Simulators
//Generate an ANT message for page 0x10
private byte[] GenerateBike0x10()
{
byte[] bikeByte = { 0x10, Convert.ToByte(equipmentType), Convert.ToByte(elapsedTime * 4 % 64), Convert.ToByte(distanceTraveled), speedArray[0], speedArray[1], Convert.ToByte(BPM), 0xFF };
return bikeByte;
//SOMEONE FIX THIS!!!!!!!!!
try
{
byte[] bikeByte = { 0x10, Convert.ToByte(equipmentType), Convert.ToByte(elapsedTime * 4 % 64), Convert.ToByte(distanceTraveled), speedArray[0], speedArray[1], Convert.ToByte(BPM), 0xFF };
return bikeByte;
}
catch (OverflowException e)
{
Debug.WriteLine(e);
return GenerateBike0x10();
}
}
//Generate an ANT message for BPM

View File

@@ -74,6 +74,7 @@ namespace RH_Engine
public static string GetID(string json)
{
//TODO fix null
dynamic d = JsonConvert.DeserializeObject(json);
return d.id;
}

View File

@@ -34,14 +34,16 @@ namespace Server
private void OnRead(IAsyncResult ar)
{
if (ar == null || (!ar.IsCompleted) || (!this.stream.CanRead))
return;
int receivedBytes = this.stream.EndRead(ar);
if (totalBufferReceived + receivedBytes > 1024)
if (totalBufferReceived + receivedBytes > 1024)
{
throw new OutOfMemoryException("buffer too small");
}
if (totalBufferReceived + receivedBytes > 1024)
{
throw new OutOfMemoryException("buffer too small");
}
Array.Copy(buffer, 0, totalBuffer, totalBufferReceived, receivedBytes);
totalBufferReceived += receivedBytes;
@@ -98,9 +100,14 @@ namespace Server
handleLogin(payloadbytes);
break;
case DataParser.LOGIN_DOCTOR:
handleLogin(payloadbytes);
communication.doctor = this;
Console.WriteLine("Set doctor to " + communication.doctor + " , this is " + this);
if (communication.doctor != null)
return;
if (handleLogin(payloadbytes))
{
communication.doctor = this;
Console.WriteLine("Set doctor to " + communication.doctor + " , this is " + this);
}
break;
case DataParser.START_SESSION:
this.saveData = new SaveData(Directory.GetCurrentDirectory() + "/" + this.username + "/" + sessionStart.ToString("yyyy-MM-dd HH-mm-ss"));
@@ -148,7 +155,7 @@ namespace Server
}
private void handleLogin(byte[] payloadbytes)
private bool handleLogin(byte[] payloadbytes)
{
string username;
string password;
@@ -162,6 +169,7 @@ namespace Server
sendMessage(DataParser.getLoginResponse("OK"));
//sendMessage(DataParser.getStartSessionJson());
communication.NewLogin(this);
return true;
}
else
{
@@ -172,6 +180,7 @@ namespace Server
{
sendMessage(DataParser.getLoginResponse("invalid json"));
}
return false;
}
public void sendMessage(byte[] message)
@@ -212,7 +221,7 @@ namespace Server
}
}

View File

@@ -35,15 +35,6 @@ namespace Server
var tcpClient = listener.EndAcceptTcpClient(ar);
Console.WriteLine($"Client connected from {tcpClient.Client.RemoteEndPoint}");
clients.Add(new Client(this, tcpClient));
/*if (doctor == null)
{
doctor = clients.ElementAt(0);
}
else
{
doctor.sendMessage(DataParser.getNewConnectionJson("jan"));
}*/
listener.BeginAcceptTcpClient(new AsyncCallback(OnConnect), null);
}