add openhack files

This commit is contained in:
Ryan Peters
2022-11-03 16:41:13 -04:00
commit b2c9f7e29f
920 changed files with 118861 additions and 0 deletions

View File

@ -0,0 +1,64 @@
<Page
x:Class="MyDriving.UWP.Views.CurrentTripView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:maps="using:Windows.UI.Xaml.Controls.Maps"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid Canvas.ZIndex="2" Background="{StaticResource GridBackgroundColor}" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Name="TextFuel" Text="{x:Bind ViewModel.FuelConsumption}" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Center" Foreground="{StaticResource CalculationTextColor}" Visibility="Visible" FontSize="16" VerticalAlignment="Center" Margin="0,4,0,2"/>
<TextBlock Name="TextFuelunits" Text="{x:Bind ViewModel.FuelConsumptionUnits}" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Center" Foreground="{StaticResource CalculationTextColor}" FontSize="13" VerticalAlignment="Center" Margin="0,2,0,4"/>
<TextBlock Name="TextDistance" Text="{x:Bind ViewModel.Distance}" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Center" Foreground="{StaticResource CalculationTextColor}" Visibility="Visible" FontSize="16" VerticalAlignment="Center" Margin="0,4,0,2"/>
<TextBlock Name="TextDistanceunits" Text="{x:Bind ViewModel.DistanceUnits}" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" Foreground="{StaticResource CalculationTextColor}" FontSize="13" VerticalAlignment="Center" Margin="0,2,0,4"/>
<TextBlock Name="TextTime" Text="{x:Bind ViewModel.ElapsedTime}" Grid.Row="0" Grid.Column="2" HorizontalAlignment="Center" Foreground="{StaticResource CalculationTextColor}" Visibility="Visible" FontSize="16" VerticalAlignment="Center" Margin="0,4,0,2"/>
<TextBlock Text="Duration" Grid.Row="1" HorizontalAlignment="Center" Grid.Column="2" Foreground="{StaticResource CalculationTextColor}" FontSize="13" VerticalAlignment="Center" Margin="0,2,0,4"/>
<TextBlock Name="TextEngineload" Text="{x:Bind ViewModel.EngineLoad}" Grid.Row="0" Grid.Column="3" HorizontalAlignment="Center" Foreground="{StaticResource CalculationTextColor}" Visibility="Visible" FontSize="16" VerticalAlignment="Center" Margin="0,4,0,2"/>
<TextBlock Text="Engine Load" Grid.Row="1" Grid.Column="3" HorizontalAlignment="Center" Foreground="{StaticResource CalculationTextColor}" FontSize="13" VerticalAlignment="Center" Margin="0,2,0,4"/>
</Grid>
<Grid >
<maps:MapControl
x:Name="MyMap"
ZoomInteractionMode="GestureAndControl"
Canvas.ZIndex="0"
LandmarksVisible="True"
IsRightTapEnabled="true"
/>
<Rectangle HorizontalAlignment="Stretch" Height="90" VerticalAlignment="Bottom" Fill="{StaticResource MapFillColor}" Opacity="0.4" />
<Button x:Name="StartRecordBtn" Width="50" Height="50" HorizontalAlignment="Center" VerticalAlignment="Bottom" Canvas.ZIndex="4" Margin="0,16">
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse Name="Elipse1" Stroke="White" Canvas.ZIndex="5" StrokeThickness="3" >
<Ellipse.Fill>
<ImageBrush ImageSource="{Binding RecordButtonImage, Mode=OneWay}" />
</Ellipse.Fill>
</Ellipse>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
</Grid>
</Page>

View File

@ -0,0 +1,491 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using Windows.ApplicationModel.ExtendedExecution;
using Windows.Devices.Geolocation;
using Windows.Foundation;
using Windows.Storage.Streams;
using Windows.UI;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls.Maps;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
using MyDriving.ViewModel;
using MyDriving.Utils;
using Windows.Devices.Enumeration;
using Windows.Devices.Bluetooth.Rfcomm;
namespace MyDriving.UWP.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class CurrentTripView : INotifyPropertyChanged
{
private bool recordButtonIsBusy = false;
private ImageSource recordButtonImage;
private ExtendedExecutionSession session;
public CurrentTripViewModel ViewModel;
public CurrentTripView()
{
InitializeComponent();
ViewModel = new CurrentTripViewModel();
Locations = new List<BasicGeoposition>();
if (Logger.BingMapsAPIKey != "Ar6iuHZYgX1BrfJs6SRJaXWbpU_HKdoe7G-OO9b2kl3rWvcawYx235GGx5FPM76O")
{
MyMap.MapServiceToken = Logger.BingMapsAPIKey;
}
MyMap.Loaded += MyMap_Loaded;
DataContext = this;
recordButtonImage = new BitmapImage(new Uri("ms-appx:///Assets/StartRecord.png", UriKind.Absolute));
OnPropertyChanged(nameof(RecordButtonImage));
StartRecordBtn.Click += StartRecordBtn_Click;
}
public IList<BasicGeoposition> Locations { get; set; }
public ImageSource RecordButtonImage => recordButtonImage;
public event PropertyChangedEventHandler PropertyChanged;
//private Geolocator geolocator = null;
public void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
private void MyMap_Loaded(object sender, RoutedEventArgs e)
{
MyMap.ZoomLevel = 16;
MyMap.MapElements.Clear();
}
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
App.SetTitle("CURRENT TRIP");
ViewModel.PropertyChanged += OnPropertyChanged;
await StartTrackingAsync();
UpdateStats();
SystemNavigationManager systemNavigationManager = SystemNavigationManager.GetForCurrentView();
systemNavigationManager.BackRequested += SystemNavigationManager_BackRequested;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
//Ideally, we should stop tracking only if we aren't recording
ViewModel.StopTrackingTripCommand.Execute(null);
Locations?.Clear();
Locations = null;
MyMap.MapElements.Clear();
MyMap.Loaded -= MyMap_Loaded;
StartRecordBtn.Click -= StartRecordBtn_Click;
ViewModel.PropertyChanged -= OnPropertyChanged;
SystemNavigationManager systemNavigationManager = SystemNavigationManager.GetForCurrentView();
systemNavigationManager.BackRequested -= SystemNavigationManager_BackRequested;
ClearExtendedExecution();
}
private void SystemNavigationManager_BackRequested(object sender, BackRequestedEventArgs e)
{
if (!e.Handled)
{
e.Handled = TryGoBack();
}
}
private bool TryGoBack()
{
bool navigated = false;
if (Frame.CanGoBack && !ViewModel.IsRecording)
{
Frame.GoBack();
navigated = true;
}
return navigated;
}
void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case nameof(ViewModel.CurrentPosition):
var basicGeoposition = new BasicGeoposition()
{
Latitude = ViewModel.CurrentPosition.Latitude,
Longitude = ViewModel.CurrentPosition.Longitude
};
UpdateMap_PositionChanged(basicGeoposition);
UpdateStats();
break;
case nameof(ViewModel.CurrentTrip):
ResetTrip();
break;
// Todo VJ. Fix Databinding issue to directly update the UI. Currently updating manually.
case nameof(ViewModel.Distance):
case nameof(ViewModel.EngineLoad):
case nameof(ViewModel.FuelConsumption):
case nameof(ViewModel.ElapsedTime):
case nameof(ViewModel.DistanceUnits):
case nameof(ViewModel.FuelConsumptionUnits):
UpdateStats();
break;
}
}
private async Task StartTrackingAsync()
{
// Request permission to access bluetooth
try
{
DeviceInformationCollection deviceInfoCollection =
await DeviceInformation.FindAllAsync(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.SerialPort));
if (deviceInfoCollection.Count() > 0)
{
DeviceInformation device = deviceInfoCollection[0];
await RfcommDeviceService.FromIdAsync(device.Id);
}
}
catch (Exception) { }
// Request permission to access location
var accessStatus = await Geolocator.RequestAccessAsync();
switch (accessStatus)
{
case GeolocationAccessStatus.Allowed:
StartRecordBtn.IsEnabled = true;
await BeginExtendedExecution();
break;
case GeolocationAccessStatus.Denied:
Acr.UserDialogs.UserDialogs.Instance.Alert(
"Please ensure that geolocation is enabled and permissions are allowed for MyDriving to start a recording.",
"Geolocation Disabled", "OK");
StartRecordBtn.IsEnabled = false;
break;
case GeolocationAccessStatus.Unspecified:
Acr.UserDialogs.UserDialogs.Instance.Alert("Unspecified Error...", "Geolocation Disabled", "OK");
StartRecordBtn.IsEnabled = false;
break;
}
}
private async Task BeginExtendedExecution()
{
if (ViewModel == null)
return;
ClearExtendedExecution();
try
{
var newSession = new ExtendedExecutionSession
{
Reason = ExtendedExecutionReason.LocationTracking,
Description = "Tracking your location"
};
newSession.Revoked += SessionRevoked;
ExtendedExecutionResult result = await newSession.RequestExtensionAsync();
switch (result)
{
case ExtendedExecutionResult.Allowed:
session = newSession;
ViewModel.Geolocator.AllowsBackgroundUpdates = true;
ViewModel.StartTrackingTripCommand.Execute(null);
break;
default:
Acr.UserDialogs.UserDialogs.Instance.Alert("Unable to execute app in the background.",
"Background execution denied.", "OK");
newSession.Dispose();
break;
}
}
catch (Exception ex)
{
// Sometimes while creating ExtendedExecution session you get Resource not ready exception.
Logger.Instance.Report(ex);
Acr.UserDialogs.UserDialogs.Instance.Alert("Will not be able to execute app in the background.",
"Background execution session failed.", "OK");
}
}
private void ClearExtendedExecution()
{
if (session != null)
{
session.Revoked -= SessionRevoked;
session.Dispose();
session = null;
}
}
private async void SessionRevoked(object sender, ExtendedExecutionRevokedEventArgs args)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
switch (args.Reason)
{
case ExtendedExecutionRevokedReason.Resumed:
break;
case ExtendedExecutionRevokedReason.SystemPolicy:
Acr.UserDialogs.UserDialogs.Instance.Alert("Extended execution revoked due to system policy.",
"Background Execution revoked.", "OK");
break;
}
ClearExtendedExecution();
await BeginExtendedExecution();
});
}
private async void StartRecordBtn_Click(object sender, RoutedEventArgs e)
{
if (ViewModel?.CurrentPosition == null || ViewModel.IsBusy || recordButtonIsBusy)
return;
recordButtonIsBusy = true;
var basicGeoposition = new BasicGeoposition()
{
Latitude = ViewModel.CurrentPosition.Latitude,
Longitude = ViewModel.CurrentPosition.Longitude
};
if (ViewModel.IsRecording)
{
// Need to update Map UI before we start saving. So that the entire trip is visible.
UpdateMap_PositionChanged(basicGeoposition);
// Changing the record button icon and andding end marker earlier to notify user about the stop process.
recordButtonImage = new BitmapImage(new Uri("ms-appx:///Assets/StartRecord.png", UriKind.Absolute));
OnPropertyChanged(nameof(RecordButtonImage));
AddEndMarker(basicGeoposition);
if (!await ViewModel.StopRecordingTrip())
{
recordButtonIsBusy = false;
return;
}
await ViewModel.SaveRecordingTripAsync();
var recordedTripSummary = ViewModel.TripSummary;
// Launch Trip Summary Page.
Frame.Navigate(typeof(TripSummaryView), recordedTripSummary);
}
else
{
if (!await ViewModel.StartRecordingTrip())
{
recordButtonIsBusy = false;
return;
}
if (ViewModel.CurrentTrip.HasSimulatedOBDData)
App.SetTitle("CURRENT TRIP (SIMULATED OBD)");
// Update UI to start recording.
recordButtonImage = new BitmapImage(new Uri("ms-appx:///Assets/StopRecord.png", UriKind.Absolute));
OnPropertyChanged(nameof(RecordButtonImage));
// Update the Map with StartMarker, Path
AddStartMarker(basicGeoposition);
UpdateMap_PositionChanged(basicGeoposition);
UpdateStats();
}
recordButtonIsBusy = false;
}
private async void UpdateMap_PositionChanged(BasicGeoposition basicGeoposition)
{
if (ViewModel.IsBusy)
return;
// To update the carIcon first find it if it exists in MapElements already.
// If it exists just update the existing one with new location and image
await Dispatcher.RunAsync(CoreDispatcherPriority.Low, () =>
{
MapIcon _carIcon = null;
// Find if there is a MapIcon with title Car
if (MyMap.MapElements != null)
{
var mapIcons = MyMap.MapElements.OfType<MapIcon>().ToList();
foreach (var item in mapIcons)
{
if (item.Title == "Car")
_carIcon = item;
}
}
if (_carIcon == null)
{
// Car Icon is currently not present. So add it.
_carIcon = new MapIcon
{
NormalizedAnchorPoint = new Point(0.5, 0.5),
ZIndex = 4,
CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible,
Title = "Car"
};
MyMap.MapElements.Add(_carIcon);
}
// Update the icon of the car based on the recording status
if (ViewModel.IsRecording)
_carIcon.Image =
RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/RedCar.png"));
else
_carIcon.Image =
RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/BlueCar.png"));
// Update the location
_carIcon.Location = new Geopoint(basicGeoposition);
MyMap.Center = _carIcon.Location;
// Add Path if we are recording
DrawPath(basicGeoposition);
});
}
private async void AddStartMarker(BasicGeoposition basicGeoposition)
{
if (!ViewModel.IsRecording || ViewModel.CurrentTrip.Points.Count == 0)
return;
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
// First point of the trip will be Start Position.
MapIcon mapStartIcon = new MapIcon
{
Location = new Geopoint(basicGeoposition),
NormalizedAnchorPoint = new Point(0.5, 0.5),
Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/A100.png")),
ZIndex = 3,
CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible
};
MyMap.MapElements.Add(mapStartIcon);
});
}
private async void DrawPath(BasicGeoposition basicGeoposition)
{
if (!ViewModel.IsRecording || ViewModel.CurrentTrip?.Points?.Count == 0)
return;
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
if (MyMap == null)
return;
if (Locations.Count == 0)
{
Locations =
new List<BasicGeoposition>(
ViewModel.CurrentTrip?.Points?.Select(
s => new BasicGeoposition() { Latitude = s.Latitude, Longitude = s.Longitude }));
// If the viewmodel still has not added this point, then add it locally to the Locations collection.
if (Locations.Count == 0)
Locations.Add(basicGeoposition);
}
else
Locations.Add(basicGeoposition);
// Check if _mapPolyline is already in MapElements
var _mapPolyline = MyMap.MapElements.OfType<MapPolyline>().FirstOrDefault();
if (_mapPolyline == null)
{
// Polyline does not exist. Create a new path and add it.
_mapPolyline = new MapPolyline
{
StrokeColor = Colors.Red,
StrokeThickness = 3,
Visible = true,
Path = new Geopath(Locations)
};
MyMap.MapElements.Add(_mapPolyline);
}
else
{
// Set the path of the already added polyline to new locations
_mapPolyline.Path = new Geopath(Locations);
}
});
}
private async void UpdateMapView(BasicGeoposition basicGeoposition)
{
var geoPoint = new Geopoint(basicGeoposition);
if (!ViewModel.IsBusy)
{
await MyMap.TrySetViewAsync(geoPoint);
}
}
private async void UpdateStats()
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
TextFuel.Text = ViewModel.FuelConsumption;
TextFuelunits.Text = ViewModel.FuelConsumptionUnits;
TextDistance.Text = ViewModel.Distance;
TextDistanceunits.Text = ViewModel.DistanceUnits;
TextTime.Text = ViewModel.ElapsedTime;
TextEngineload.Text = ViewModel.EngineLoad;
});
}
private void ResetTrip()
{
MyMap.MapElements.Clear();
Locations?.Clear();
Locations = null;
UpdateStats();
}
private async void AddEndMarker(BasicGeoposition basicGeoposition)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
MapIcon mapEndIcon = new MapIcon
{
Location = new Geopoint(basicGeoposition),
NormalizedAnchorPoint = new Point(0.5, 0.5),
Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/B100.png")),
ZIndex = 3,
CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible
};
MyMap.MapElements.Add(mapEndIcon);
});
}
}
}

View File

@ -0,0 +1,18 @@
<Page
x:Class="MyDriving.UWP.Views.GetStarted1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:MyDriving.UWP.Controls"
mc:Ignorable="d">
<Grid >
<Grid.Background>
<ImageBrush Stretch="Fill" ImageSource="{StaticResource Background}" />
</Grid.Background>
<Image x:Name="Getstarted1" Source="{StaticResource GetStarted1}" />
<Grid Height="60" VerticalAlignment="Bottom">
<controls:DotsControl x:Name="Dots" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</Grid>
</Page>

View File

@ -0,0 +1,43 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using Windows.UI.Xaml.Input;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace MyDriving.UWP.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class GetStarted1
{
private double endX;
private double startX;
public GetStarted1()
{
InitializeComponent();
Dots.SelectCircle(1);
ManipulationMode = ManipulationModes.TranslateX;
ManipulationStarted += Manipulation_Started;
ManipulationCompleted += Manipulation_Completed;
}
void Manipulation_Started(object sender, ManipulationStartedRoutedEventArgs e)
{
startX = e.Position.X;
e.Handled = true;
}
void Manipulation_Completed(object sender, ManipulationCompletedRoutedEventArgs e)
{
endX = e.Position.X;
if (endX < startX)
Frame.Navigate(typeof (GetStarted2));
e.Handled = true;
}
}
}

View File

@ -0,0 +1,19 @@
<Page
x:Class="MyDriving.UWP.Views.GetStarted2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:MyDriving.UWP.Controls"
mc:Ignorable="d">
<Grid>
<Grid.Background>
<ImageBrush Stretch="Fill" ImageSource="{StaticResource Background}" />
</Grid.Background>
<Image x:Name="Getstarted2" Source="{StaticResource GetStarted2}" />
<Grid Height="60" VerticalAlignment="Bottom">
<controls:DotsControl x:Name="Dots" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</Grid>
</Page>

View File

@ -0,0 +1,45 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using Windows.UI.Xaml.Input;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace MyDriving.UWP.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class GetStarted2
{
private double endX;
private double startX;
public GetStarted2()
{
InitializeComponent();
Dots.SelectCircle(2);
ManipulationMode = ManipulationModes.TranslateX;
ManipulationStarted += Manipulation_Started;
ManipulationCompleted += Manipulation_Completed;
}
void Manipulation_Started(object sender, ManipulationStartedRoutedEventArgs e)
{
startX = e.Position.X;
e.Handled = true;
}
void Manipulation_Completed(object sender, ManipulationCompletedRoutedEventArgs e)
{
endX = e.Position.X;
if (endX < startX) //forward
Frame.Navigate(typeof (GetStarted3));
else if (endX > startX) //back
Frame.Navigate(typeof (GetStarted1));
e.Handled = true;
}
}
}

View File

@ -0,0 +1,19 @@
<Page
x:Class="MyDriving.UWP.Views.GetStarted3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:MyDriving.UWP.Controls"
mc:Ignorable="d">
<Grid>
<Grid.Background>
<ImageBrush Stretch="Fill" ImageSource="{StaticResource Background}" />
</Grid.Background>
<Image x:Name="Getstarted3" Source="{StaticResource GetStarted3}" Grid.Row="0"/>
<Grid Height="60" VerticalAlignment="Bottom">
<controls:DotsControl x:Name="Dots" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</Grid>
</Page>

View File

@ -0,0 +1,45 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using Windows.UI.Xaml.Input;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace MyDriving.UWP.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class GetStarted3
{
private double endX;
private double startX;
public GetStarted3()
{
InitializeComponent();
Dots.SelectCircle(3);
ManipulationMode = ManipulationModes.TranslateX;
ManipulationStarted += Manipulation_Started;
ManipulationCompleted += Manipulation_Completed;
}
void Manipulation_Started(object sender, ManipulationStartedRoutedEventArgs e)
{
startX = e.Position.X;
e.Handled = true;
}
void Manipulation_Completed(object sender, ManipulationCompletedRoutedEventArgs e)
{
endX = e.Position.X;
if (endX < startX) //forward
Frame.Navigate(typeof (GetStarted4));
else if (endX > startX) //back
Frame.Navigate(typeof (GetStarted2));
e.Handled = true;
}
}
}

View File

@ -0,0 +1,19 @@
<Page
x:Class="MyDriving.UWP.Views.GetStarted4"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:MyDriving.UWP.Controls"
mc:Ignorable="d">
<Grid>
<Grid.Background>
<ImageBrush Stretch="Fill" ImageSource="{StaticResource Background}" />
</Grid.Background>
<Image x:Name="Getstarted4" Source="{StaticResource GetStarted4}" Grid.Row="0"/>
<Grid Height="60" VerticalAlignment="Bottom">
<controls:DotsControl x:Name="Dots" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</Grid>
</Page>

View File

@ -0,0 +1,45 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using Windows.UI.Xaml.Input;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace MyDriving.UWP.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class GetStarted4
{
private double endX;
private double startX;
public GetStarted4()
{
InitializeComponent();
Dots.SelectCircle(4);
ManipulationMode = ManipulationModes.TranslateX;
ManipulationStarted += Manipulation_Started;
ManipulationCompleted += Manipulation_Completed;
}
void Manipulation_Started(object sender, ManipulationStartedRoutedEventArgs e)
{
startX = e.Position.X;
e.Handled = true;
}
void Manipulation_Completed(object sender, ManipulationCompletedRoutedEventArgs e)
{
endX = e.Position.X;
if (endX < startX) //forward
Frame.Navigate(typeof (GetStarted5));
else if (endX > startX) //back
Frame.Navigate(typeof (GetStarted3));
e.Handled = true;
}
}
}

View File

@ -0,0 +1,29 @@
<Page
x:Class="MyDriving.UWP.Views.GetStarted5"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:MyDriving.UWP.Controls"
mc:Ignorable="d">
<Grid>
<Grid.Background>
<ImageBrush Stretch="Fill" ImageSource="{StaticResource Background}" />
</Grid.Background>
<Image x:Name="Getstarted5" Source="{StaticResource GetStarted5}" Grid.Row="0"/>
<Grid VerticalAlignment="Bottom" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<controls:DotsControl x:Name="Dots" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Button x:Name="DoneButton" Click="GoNext" Content="Let's Go!" HorizontalAlignment="Stretch" Height="40" Background="{StaticResource BrandColor}" Grid.Row="1"/>
</Grid>
</Grid>
</Page>

View File

@ -0,0 +1,51 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using Windows.UI.Xaml;
using Windows.UI.Xaml.Input;
using MyDriving.Utils;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace MyDriving.UWP.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class GetStarted5
{
private double endX;
private double startX;
public GetStarted5()
{
InitializeComponent();
Dots.SelectCircle(5);
ManipulationMode = ManipulationModes.TranslateX;
ManipulationStarted += Manipulation_Started;
ManipulationCompleted += Manipulation_Completed;
}
void Manipulation_Started(object sender, ManipulationStartedRoutedEventArgs e)
{
startX = e.Position.X;
e.Handled = true;
}
void Manipulation_Completed(object sender, ManipulationCompletedRoutedEventArgs e)
{
endX = e.Position.X;
if (endX > startX) //back
Frame.Navigate(typeof (GetStarted4));
e.Handled = true;
}
private void GoNext(object sender, RoutedEventArgs e)
{
Settings.Current.FirstRun = false;
Frame.Navigate(typeof (LoginView));
}
}
}

View File

@ -0,0 +1,62 @@
<Page
x:Class="MyDriving.UWP.Views.LoginView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Name="LoginGrid" >
<Grid.Background>
<ImageBrush Stretch="Fill" ImageSource="{StaticResource Background}" />
</Grid.Background>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image x:Name="ProfileImage" HorizontalAlignment="Center" VerticalAlignment="Bottom" Width="70" Height="70" Grid.Row ="0" Visibility="Collapsed"/>
<TextBlock x:Name="WelcomeText" HorizontalAlignment="Center" VerticalAlignment="Top" Visibility="Collapsed" Grid.Row="1" Margin="0,10,0,10" />
<Image x:Name="AppLogo" HorizontalAlignment="Center" VerticalAlignment="Bottom" Source="{StaticResource ApplicationLogo}" Stretch="Uniform" Margin="80,0,80,0" MaxWidth="300"/>
<!-- textblock is overlapped on the image -->
<TextBlock x:Name="LogoText" HorizontalAlignment="Center" VerticalAlignment="Bottom" Text="MyDriving" Foreground="White" FontFamily="Assets/Fonts/CorbertRegular/Corbert-regular.otf#Corbert" FontSize="24" />
<StackPanel x:Name="LoginButtons" VerticalAlignment="Center" Grid.Row="1" Visibility="Visible" Margin="50,0,50,0">
<Button x:Name="FaceBookButtonLogin" Command="{x:Bind viewModel.LoginFacebookCommand, Mode=OneWay}" Style="{StaticResource LoginButtonStyle}"
Background="{StaticResource FacebookLoginButtonColor}" Height="40" MaxWidth="300">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="20,0,0,0">
<Image Source="{StaticResource FacebookLogo}" HorizontalAlignment="Left" Height="24" Width="24"/>
<TextBlock Text="Login with Facebook" Style="{StaticResource LoginButtonTextStyle}" />
</StackPanel>
</Button>
<Button x:Name="TwitterButtonLogin" Style="{StaticResource LoginButtonStyle}" Command="{x:Bind viewModel.LoginTwitterCommand, Mode=OneWay}"
Background="{StaticResource TwitterLoginButtonColor}" >
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="20,0,0,0">
<Image Source="{StaticResource TwitterLogo}" HorizontalAlignment="Left" Height="24" Width="24"/>
<TextBlock Text="Login with Twitter" Style="{StaticResource LoginButtonTextStyle}" />
</StackPanel>
</Button>
<Button x:Name="MSAButtonLogin" Style="{StaticResource LoginButtonStyle}" Command="{x:Bind viewModel.LoginMicrosoftCommand, Mode=OneWay}"
Background="{StaticResource MSALoginButtonColor}" >
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="20,0,0,0">
<Image Name="MSAImage" Source="{StaticResource MicrosoftLogo}" HorizontalAlignment="Left" Height="24" Width="24"/>
<TextBlock Text="Login with Microsoft" Style="{StaticResource LoginButtonTextStyle}" />
</StackPanel>
</Button>
</StackPanel>
<Button x:Name="ContinueButton" HorizontalAlignment="Center" Margin="0,10,0,0" Content="Continue" Click="Continue_Click" Grid.Row="2" VerticalAlignment="Top" Visibility="Collapsed" />
</Grid>
</Page>

View File

@ -0,0 +1,85 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using System;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
using MyDriving.Utils;
using MyDriving.ViewModel;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace MyDriving.UWP.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class LoginView
{
readonly LoginViewModel viewModel;
public LoginView()
{
InitializeComponent();
DataContext = viewModel = new LoginViewModel();
}
private void ViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case nameof(viewModel.IsLoggedIn):
//When the first screen of the app is launched after user has logged in, initialize the processor that manages connection to OBD Device and to the IOT Hub
Services.OBDDataProcessor.GetProcessor().Initialize(ViewModel.ViewModelBase.StoreManager);
SplitViewShell shell = new SplitViewShell(this.Frame);
Window.Current.Content = shell;
shell.SetTitle("CURRENT TRIP");
Frame.Navigate(typeof (CurrentTripView));
break;
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
viewModel.PropertyChanged += ViewModel_PropertyChanged;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
viewModel.PropertyChanged -= ViewModel_PropertyChanged;
}
private void OnBackRequested(object sender, BackRequestedEventArgs e)
{
//For now, don't let user go back to the log in page; need to finalize what this experience should be like when user keeps pushing back
if (Frame.CurrentSourcePageType != typeof (PastTripsMenuView))
{
if (Frame != null && Frame.CanGoBack)
{
e.Handled = true;
Frame.GoBack();
}
}
}
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
private void Continue_Click(object sender, RoutedEventArgs e)
{
Frame.Navigate(typeof (CurrentTripView));
}
private void SetImageSource()
{
ProfileImage.Source = new BitmapImage(new Uri(Settings.Current.UserProfileUrl));
}
}
}

View File

@ -0,0 +1,68 @@
<Page
x:Class="MyDriving.UWP.Views.PastTripMapView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:maps="using:Windows.UI.Xaml.Controls.Maps"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid Canvas.ZIndex="2" Background="{StaticResource GridBackgroundColor}" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Name="TextFuel" Text="{x:Bind viewModel.FuelConsumption}" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Center" Foreground="{StaticResource CalculationTextColor}" Visibility="Visible" FontSize="16" VerticalAlignment="Center" Margin="0,4,0,2"/>
<TextBlock Name="TextFuelunits" Text="{x:Bind viewModel.FuelConsumptionUnits}" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Center" Foreground="{StaticResource CalculationTextColor}" FontSize="13" VerticalAlignment="Center" Margin="0,2,0,4"/>
<TextBlock Name="TextDistance" Text="{x:Bind viewModel.Distance}" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Center" Foreground="{StaticResource CalculationTextColor}" Visibility="Visible" FontSize="16" VerticalAlignment="Center" Margin="0,4,0,2"/>
<TextBlock Name="TextDistanceunits" Text="{x:Bind viewModel.DistanceUnits}" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" Foreground="{StaticResource CalculationTextColor}" FontSize="13" VerticalAlignment="Center" Margin="0,2,0,4"/>
<TextBlock Name="TextTime" Text="{x:Bind viewModel.ElapsedTime}" Grid.Row="0" Grid.Column="2" HorizontalAlignment="Center" Foreground="{StaticResource CalculationTextColor}" Visibility="Visible" FontSize="16" VerticalAlignment="Center" Margin="0,4,0,2"/>
<TextBlock Text="Elapsed Time" Grid.Row="1" HorizontalAlignment="Center" Grid.Column="2" Foreground="{StaticResource CalculationTextColor}" FontSize="13" VerticalAlignment="Center" Margin="0,2,0,4"/>
<TextBlock Name="TextSpeed" Text="{x:Bind viewModel.Speed}" Grid.Row="0" Grid.Column="3" HorizontalAlignment="Center" Foreground="{StaticResource CalculationTextColor}" Visibility="Visible" FontSize="16" VerticalAlignment="Center" Margin="0,4,0,2"/>
<TextBlock Name="TextSpeedunits" Text="{x:Bind viewModel.SpeedUnits}" Grid.Row="1" Grid.Column="3" HorizontalAlignment="Center" Foreground="{StaticResource CalculationTextColor}" FontSize="13" VerticalAlignment="Center" Margin="0,2,0,4"/>
</Grid>
<Grid >
<maps:MapControl
x:Name="MyMap"
ZoomInteractionMode="GestureAndControl"
Canvas.ZIndex="0"
LandmarksVisible="True"
IsRightTapEnabled="true"
/>
<Rectangle HorizontalAlignment="Stretch" Height="90" VerticalAlignment="Bottom" Fill="{StaticResource MapFillColor}" Opacity="0.4" />
<StackPanel x:Name="FooterPanel" Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Center">
<Image Source="ms-appx:///Assets/A.png" AutomationProperties.Name="Start Point" Stretch="None" VerticalAlignment="Center"
HorizontalAlignment="Left" Margin="20,0,10,16" Canvas.ZIndex="3"/>
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="0,0,0,16" >
<Slider Name="PositionSlider" HorizontalAlignment="Stretch" VerticalAlignment="Center" ValueChanged="positionSlider_ValueChanged" Canvas.ZIndex="2" Width="200" RequestedTheme="Light" Foreground="{StaticResource SliderColor}" Height="30" />
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" VerticalAlignment="Center" >
<TextBlock x:Name="TextStarttime" HorizontalAlignment="Left" Foreground="Black" Margin="0,0,50,0" FontSize="13"/>
<TextBlock x:Name="TextEndtime" HorizontalAlignment="Right" Foreground="Black" Margin="50,0,0,0" FontSize="13"/>
</StackPanel>
</StackPanel>
<Image Source="ms-appx:///Assets/B.png" Canvas.ZIndex="3" AutomationProperties.Name="End Point" Stretch="None" Margin="10,0,20,16" VerticalAlignment="Center" HorizontalAlignment="Right"/>
</StackPanel>
</Grid>
</Grid>
</Page>

View File

@ -0,0 +1,269 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using System;
using System.Collections.Generic;
using System.Linq;
using Windows.Devices.Geolocation;
using Windows.Foundation;
using Windows.Storage.Streams;
using Windows.UI;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls.Maps;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Navigation;
using MyDriving.DataObjects;
using MyDriving.ViewModel;
using MyDriving.Utils;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace MyDriving.UWP.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class PastTripMapView
{
readonly PastTripsDetailViewModel viewModel;
public Trip SelectedTrip;
public PastTripMapView()
{
InitializeComponent();
viewModel = new PastTripsDetailViewModel();
Locations = new List<BasicGeoposition>();
DataContext = this;
if (Logger.BingMapsAPIKey != "Ar6iuHZYgX1BrfJs6SRJaXWbpU_HKdoe7G-OO9b2kl3rWvcawYx235GGx5FPM76O")
{
MyMap.MapServiceToken = Logger.BingMapsAPIKey;
}
}
public IList<BasicGeoposition> Locations { get; set; }
public List<TripPoint> TripPoints { get; set; }
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
var trip = e.Parameter as Trip;
base.OnNavigatedTo(e);
viewModel.Trip = trip;
App.SetTitle("PAST TRIPS");
MyMap.Loaded += MyMap_Loaded;
MyMap.MapElements.Clear();
var success = await viewModel.ExecuteLoadTripCommandAsync(trip.Id);
if(!success)
{
Frame.GoBack();
return;
}
DrawPath();
foreach (var poi in viewModel.POIs)
DrawPoiOnMap(poi);
// Currently Points are all jumbled. We need to investigate why this is happening.
// As a workaround I am sorting the points based on timestamp.
TripPoints = viewModel.Trip.Points.OrderBy(p => p.RecordedTimeStamp).ToList();
if (TripPoints.Any())
{
viewModel.CurrentPosition = TripPoints[0];
UpdateStats();
}
if (mapLoaded)
InitialSetup();
// Enable the back button navigation
SystemNavigationManager systemNavigationManager = SystemNavigationManager.GetForCurrentView();
systemNavigationManager.BackRequested += SystemNavigationManager_BackRequested;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
SystemNavigationManager systemNavigationManager = SystemNavigationManager.GetForCurrentView();
systemNavigationManager.BackRequested -= SystemNavigationManager_BackRequested;
}
private void SystemNavigationManager_BackRequested(object sender, BackRequestedEventArgs e)
{
if (!e.Handled)
{
e.Handled = TryGoBack();
}
}
private bool TryGoBack()
{
bool navigated = false;
if (Frame.CanGoBack)
{
Frame.GoBack();
navigated = true;
}
return navigated;
}
bool initialized;
void InitialSetup()
{
if (initialized)
return;
initialized = true;
MyMap.ZoomLevel = 16;
if (viewModel.Trip.Points.Count > 0)
PositionSlider.Maximum = TripPoints.Count - 1;
else
PositionSlider.Maximum = 0;
PositionSlider.Minimum = 0;
PositionSlider.IsThumbToolTipEnabled = false;
TextStarttime.Text = viewModel.Trip.StartTimeDisplay;
TextEndtime.Text = viewModel.Trip.EndTimeDisplay;
}
bool mapLoaded;
private void MyMap_Loaded(object sender, RoutedEventArgs e)
{
mapLoaded = true;
if (!initialized && TripPoints != null)
InitialSetup();
}
private async void DrawPath()
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
MapPolyline mapPolyLine = new MapPolyline();
Locations =
TripPoints.Select(s => new BasicGeoposition() {Latitude = s.Latitude, Longitude = s.Longitude})
.ToList();
mapPolyLine.Path = new Geopath(Locations);
mapPolyLine.ZIndex = 1;
mapPolyLine.Visible = true;
mapPolyLine.StrokeColor = new Color { A = 255, R = 0, G = 94, B = 147 };
mapPolyLine.StrokeThickness = 4;
// Starting off with the first point as center
if (Locations.Count > 0)
MyMap.Center = new Geopoint(Locations.First());
MyMap.MapElements.Add(mapPolyLine);
// Draw Start Icon
MapIcon mapStartIcon = new MapIcon
{
Location = new Geopoint(Locations.First()),
NormalizedAnchorPoint = new Point(0.5, 0.5),
Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/A100.png")),
ZIndex = 1,
CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible
};
MyMap.MapElements.Add(mapStartIcon);
//Draw End Icon
MapIcon mapEndIcon = new MapIcon
{
Location = new Geopoint(Locations.Last()),
NormalizedAnchorPoint = new Point(0.5, 0.5),
Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/B100.png")),
ZIndex = 1,
CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible
};
MyMap.MapElements.Add(mapEndIcon);
// Draw the Car
DrawCarOnMap(Locations.First());
});
}
private void DrawPoiOnMap(POI poi)
{
// Foreach POI point. Put it on Maps.
var poiIcon = new MapIcon
{
Location = new Geopoint(new BasicGeoposition { Latitude = poi.Latitude, Longitude = poi.Longitude }),
NormalizedAnchorPoint = new Point(0.5, 0.5),
Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/POI.png")),
ZIndex = 2,
CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible
};
MyMap.MapElements.Add(poiIcon);
}
private void DrawCarOnMap(BasicGeoposition basicGeoposition)
{
MapIcon carIcon = null;
// Find if there is a MapIcon with title Car
if (MyMap.MapElements != null)
{
var mapIcons = MyMap.MapElements.OfType<MapIcon>().ToList();
foreach (var item in mapIcons)
{
if (item.Title == "Car")
carIcon = item;
}
}
if (carIcon == null)
{
// Car Icon not found creating it at the position and adding to maps
carIcon = new MapIcon
{
Location = new Geopoint(basicGeoposition),
NormalizedAnchorPoint = new Point(0.5, 0.5),
Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/BlueCar.png")),
ZIndex = 2,
CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible,
Title = "Car"
};
MyMap.MapElements.Add(carIcon);
}
else
{
carIcon.Location = new Geopoint(basicGeoposition);
}
MyMap.Center = carIcon.Location;
}
private async void positionSlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
{
viewModel.CurrentPosition = TripPoints[(int) e.NewValue];
var basicGeoposition = Locations[(int) e.NewValue];
DrawCarOnMap(basicGeoposition);
await MyMap.TrySetViewAsync(new Geopoint(basicGeoposition));
UpdateStats();
}
private async void UpdateStats()
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
// TODO: Need to fix data binding and remove this code.
TextTime.Text = viewModel.ElapsedTime;
TextDistance.Text = viewModel.Distance;
TextFuel.Text = viewModel.FuelConsumption;
TextFuelunits.Text = viewModel.FuelConsumptionUnits;
TextSpeed.Text = viewModel.Speed;
TextSpeedunits.Text = viewModel.SpeedUnits;
TextDistanceunits.Text = viewModel.DistanceUnits;
});
}
}
}

View File

@ -0,0 +1,59 @@
<Page
x:Class="MyDriving.UWP.Views.PastTripsMenuView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyDriving.DataObjects"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.BottomAppBar>
<CommandBar>
<CommandBar.PrimaryCommands>
<AppBarButton Icon="Refresh" Label="Refresh" x:Name="RefreshButton" Click="RefreshButton_Click"/>
</CommandBar.PrimaryCommands>
</CommandBar>
</Page.BottomAppBar>
<Grid Background="{StaticResource MainBackgroundColor}">
<ListView x:Name="ListView" ItemsSource="{x:Bind ViewModel.Trips, Mode=OneWay}" SelectionChanged="listView_SelectionChanged" >
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Margin" Value="0,4,0,0" />
<Setter Property="Background" Value="{StaticResource MainBackgroundColor2}" />
<Setter Property="BorderBrush" Value="{StaticResource PastTripsBorderColor}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Padding" Value="0,0,0,0" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Trip">
<Grid Holding="ListViewItem_Holding" HorizontalAlignment="Stretch">
<FlyoutBase.AttachedFlyout>
<MenuFlyout>
<MenuFlyoutItem Text="Delete"
Click="DeleteButton_Click" />
</MenuFlyout>
</FlyoutBase.AttachedFlyout>
<Grid HorizontalAlignment="Stretch" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image x:Name="Image" Source="{x:Bind MainPhotoUrl, Converter={StaticResource ImageSourceConverter}, Mode=OneWay}" HorizontalAlignment="Stretch" Stretch="UniformToFill" />
<TextBlock Text="{x:Bind Name}" Margin="12,5,0,0" HorizontalAlignment="Left" Grid.Row="1"/>
<TextBlock Text="{x:Bind TimeAgo}" HorizontalAlignment="Left" Foreground="{StaticResource CalculationTextColor}" Margin="12,0,0,5" FontSize="13.333" Grid.Row="2"/>
<TextBlock Text="{x:Bind TotalDistance}" HorizontalAlignment="Right" Foreground="{StaticResource CalculationTextColor}" Margin="0,0,12,5" FontSize="13.333" Grid.Row="2"/>
</Grid>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Page>

View File

@ -0,0 +1,98 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using Windows.UI.Core;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using MyDriving.DataObjects;
using MyDriving.ViewModel;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Input;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace MyDriving.UWP.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class PastTripsMenuView
{
public PastTripsMenuView()
{
InitializeComponent();
ViewModel = new PastTripsViewModel();
}
public PastTripsViewModel ViewModel { get; set; }
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
App.SetTitle("PAST TRIPS");
// Enable back button behavior
SystemNavigationManager systemNavigationManager = SystemNavigationManager.GetForCurrentView();
systemNavigationManager.BackRequested += SystemNavigationManager_BackRequested;
await ViewModel.ExecuteLoadPastTripsCommandAsync();
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
SystemNavigationManager systemNavigationManager = SystemNavigationManager.GetForCurrentView();
systemNavigationManager.BackRequested -= SystemNavigationManager_BackRequested;
}
private void SystemNavigationManager_BackRequested(object sender, BackRequestedEventArgs e)
{
if (!e.Handled)
{
e.Handled = TryGoBack();
}
}
private bool TryGoBack()
{
bool navigated = false;
if (Frame.CanGoBack)
{
Frame.GoBack();
navigated = true;
}
return navigated;
}
private void listView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var trip = (Trip) e.AddedItems[0];
Frame.Navigate(typeof (PastTripMapView), trip); // PastTripMapView does not exist
}
private void ListViewItem_Holding(object sender, HoldingRoutedEventArgs e)
{
var senderElement = sender as FrameworkElement;
var flyoutBase = FlyoutBase.GetAttachedFlyout(senderElement);
flyoutBase.ShowAt(senderElement);
}
private async void DeleteButton_Click(object sender, RoutedEventArgs e)
{
var trip = (e.OriginalSource as FrameworkElement).DataContext as Trip;
if (trip == null)
return;
await ViewModel.ExecuteDeleteTripCommand(trip);
}
private async void RefreshButton_Click(object sender, RoutedEventArgs e)
{
await ViewModel.ExecuteLoadPastTripsCommandAsync();
}
}
}

View File

@ -0,0 +1,59 @@
<Page
x:Class="MyDriving.UWP.Views.ProfileView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:MyDriving.UWP.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{StaticResource MainBackgroundColor2}">
<ScrollViewer VerticalScrollBarVisibility="Hidden">
<StackPanel Margin="24,24,24,24">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<controls:CirclePercentage x:Name="CirclePercentage" Grid.RowSpan="2" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center" DataContext="{x:Bind profileViewModel.DrivingSkills, Mode=OneWay}"/>
<Ellipse Grid.RowSpan="2" Width="100" Height="100">
<Ellipse.Fill>
<ImageBrush x:Name="ProfileImage" ImageSource="{x:Bind profileViewModel.Settings.UserProfileUrl, Mode=OneWay, Converter={StaticResource ImageSourceConverter}}"/>
</Ellipse.Fill>
</Ellipse>
<TextBlock Name="DrivingSkills" Text="{x:Bind profileViewModel.DrivingSkills, Mode=OneWay, Converter={StaticResource StringFormatConverter}, ConverterParameter=' {0}% '}"
Grid.Column="1" FontFamily="SegoeUI" FontSize="32" Foreground="{StaticResource BrandColor}" TextWrapping="Wrap"/>
<StackPanel Grid.Column="1" Grid.Row="1">
<TextBlock Name="DrivingSkillsMessage2" Text="{x:Bind profileViewModel.DrivingSkillsPlacementBucket.Description, Converter={StaticResource StringFormatConverter}, ConverterParameter='Driving skills: {0}', Mode=OneWay}"
FontFamily="SegoeUI-Light" FontSize="16" Foreground="White" TextWrapping="Wrap" />
</StackPanel>
</Grid>
<Border Margin="0,6,0,0" />
<controls:ProfileViewTabControl x:Name="TotalDistanceTab" DataContext="{x:Bind profileViewModel.TotalDistanceDisplay, Mode=OneWay}" />
<controls:ProfileViewTabControl x:Name="TotalTimeTab" DataContext="{x:Bind profileViewModel.TotalTimeDisplay, Mode=OneWay}" />
<controls:ProfileViewTabControl x:Name="MaxSpeedTab" DataContext="{x:Bind profileViewModel.MaxSpeedDisplay, Mode=OneWay}" />
<controls:ProfileViewTabControl x:Name="FuelConsumptionTab" DataContext="{x:Bind profileViewModel.FuelDisplay, Mode=OneWay}" />
<controls:ProfileViewTabControl x:Name="HardBreaksTab" DataContext="{x:Bind profileViewModel.HardStops, Mode=OneWay, Converter={StaticResource StringFormatConverter}, ConverterParameter=' {0} times'}" />
<controls:ProfileViewTabControl x:Name="HardAccelTab" DataContext="{x:Bind profileViewModel.HardAccelerations, Mode=OneWay, Converter={StaticResource StringFormatConverter}, ConverterParameter=' {0} times'}" />
<controls:ProfileViewTabControl x:Name="TotalTripsTab" DataContext="{x:Bind profileViewModel.TotalTrips, Mode=OneWay}" />
</StackPanel>
</ScrollViewer>
</Grid>
</Page>

View File

@ -0,0 +1,94 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using Windows.UI.Core;
using Windows.UI.Xaml.Navigation;
using MyDriving.ViewModel;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace MyDriving.UWP.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class ProfileView
{
readonly ProfileViewModel profileViewModel;
public ProfileView()
{
profileViewModel = new ProfileViewModel();
DataContext = profileViewModel;
InitializeComponent();
TotalDistanceTab.Title1 = "Total";
TotalDistanceTab.Title2 = "DISTANCE";
TotalTimeTab.Title1 = "Total";
TotalTimeTab.Title2 = "TIME";
MaxSpeedTab.Title1 = "Max";
MaxSpeedTab.Title2 = "SPEED";
FuelConsumptionTab.Title1 = "Total";
FuelConsumptionTab.Title2 = "FUEL USED";
HardBreaksTab.Title1 = "Hard";
HardBreaksTab.Title2 = "STOPS";
HardAccelTab.Title1 = "Hard";
HardAccelTab.Title2 = "ACCELERATIONS";
TotalTripsTab.Title1 = "Total";
TotalTripsTab.Title2 = "TRIPS";
}
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
App.SetTitle("PROFILE");
// Enable back button behavior
SystemNavigationManager systemNavigationManager = SystemNavigationManager.GetForCurrentView();
systemNavigationManager.BackRequested += SystemNavigationManager_BackRequested;
profileViewModel.PropertyChanged += ViewModel_PropertyChanged;
await profileViewModel.UpdateProfileAsync();
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
SystemNavigationManager systemNavigationManager = SystemNavigationManager.GetForCurrentView();
systemNavigationManager.BackRequested -= SystemNavigationManager_BackRequested;
}
private void SystemNavigationManager_BackRequested(object sender, BackRequestedEventArgs e)
{
profileViewModel.PropertyChanged += ViewModel_PropertyChanged;
if (!e.Handled)
{
e.Handled = TryGoBack();
}
}
private bool TryGoBack()
{
bool navigated = false;
if (Frame.CanGoBack)
{
Frame.GoBack();
navigated = true;
}
return navigated;
}
private void ViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (string.CompareOrdinal(e.PropertyName, nameof(profileViewModel.DrivingSkills)) == 0)
{
CirclePercentage.Percentage = (double)profileViewModel.DrivingSkills;
CirclePercentage.Update();
}
}
}
}

View File

@ -0,0 +1,54 @@
<Page
x:Class="MyDriving.UWP.Views.SettingsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{StaticResource MainBackgroundColor}">
<ScrollViewer VerticalScrollBarVisibility="Hidden" Margin="15,0,15,0">
<StackPanel Margin="0,16,0,0">
<TextBlock Text="Unit Preferences" Style="{StaticResource SettingsLabelStyle}"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<RadioButton Name="Kilometers" IsChecked="{Binding MetricDistance, Mode=TwoWay}" Margin="10,5,0,0" GroupName="A" BorderBrush="Gray" >
Kilometers
</RadioButton>
<RadioButton Name="Miles" Margin="10,5,0,0" IsChecked="{Binding MetricDistance, Mode=TwoWay, Converter={StaticResource NotConverter}}" GroupName="A" Grid.Row="1">
Miles
</RadioButton>
<RadioButton Name="Liters" IsChecked="{Binding MetricUnits, Mode=TwoWay}" Margin="10,5,0,0" GroupName="B" Grid.Column="1">
Liters
</RadioButton>
<RadioButton Name="Gallons" Margin="10,5,0,0" IsChecked="{Binding MetricUnits, Mode=TwoWay, Converter={StaticResource NotConverter}}" GroupName="B" Grid.Column="1" Grid.Row="1">
Gallons
</RadioButton>
</Grid>
<Border Style="{StaticResource SettingsSeparatorLine}" />
<TextBlock Text="About" Style="{StaticResource SettingsLabelStyle}"/>
<Button Content="Copyright 2016 Microsoft" Style="{StaticResource SettingsAboutButtonStyle}" />
<Button Name="TermsOfUseButton" Content="Terms of use" Click="TermsOfUseButton_Click" Style="{StaticResource SettingsAboutButtonStyle}" />
<Button Name="PrivacyPolicyButton" Content="Privacy policy" Click="PrivacyPolicyButton_Click" Style="{StaticResource SettingsAboutButtonStyle}" />
<Button Name="OpenSourceNoticeButton" Content="Open Source Notice" Click="OpenSourceNoticeButton_Click" Style="{StaticResource SettingsAboutButtonStyle}" />
<Button Name="OpenSourceGitHubButton" Content="Open Source on GitHub" Click="OpenSourceGitHubButton_Click" Style="{StaticResource SettingsAboutButtonStyle}" />
</StackPanel>
</ScrollViewer>
</Grid>
</Page>

View File

@ -0,0 +1,84 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Navigation;
using MyDriving.Utils;
using MyDriving.ViewModel;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace MyDriving.UWP.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class SettingsView
{
readonly SettingsViewModel settingsViewModel;
public SettingsView()
{
InitializeComponent();
DataContext = Settings.Current;
settingsViewModel = new SettingsViewModel();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
App.SetTitle("SETTINGS");
// Enable back button behavior
SystemNavigationManager systemNavigationManager = SystemNavigationManager.GetForCurrentView();
systemNavigationManager.BackRequested += SystemNavigationManager_BackRequested;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
SystemNavigationManager systemNavigationManager = SystemNavigationManager.GetForCurrentView();
systemNavigationManager.BackRequested -= SystemNavigationManager_BackRequested;
}
private void SystemNavigationManager_BackRequested(object sender, BackRequestedEventArgs e)
{
if (!e.Handled)
{
e.Handled = TryGoBack();
}
}
private bool TryGoBack()
{
bool navigated = false;
if (Frame.CanGoBack)
{
Frame.GoBack();
navigated = true;
}
return navigated;
}
public void PrivacyPolicyButton_Click(object sender, RoutedEventArgs e)
{
settingsViewModel.OpenBrowserCommand.Execute(settingsViewModel.PrivacyPolicyUrl);
}
private void TermsOfUseButton_Click(object sender, RoutedEventArgs e)
{
settingsViewModel.OpenBrowserCommand.Execute(settingsViewModel.TermsOfUseUrl);
}
public void OpenSourceNoticeButton_Click(object sender, RoutedEventArgs e)
{
settingsViewModel.OpenBrowserCommand.Execute(settingsViewModel.OpenSourceNoticeUrl);
}
public void OpenSourceGitHubButton_Click(object sender, RoutedEventArgs e)
{
settingsViewModel.OpenBrowserCommand.Execute(settingsViewModel.SourceOnGitHubUrl);
}
}
}

View File

@ -0,0 +1,53 @@
<Page
x:Class="MyDriving.UWP.Views.SplitViewShell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:MyDriving.UWP.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid x:Name="MainGrid" >
<Grid.Background>
<ImageBrush Stretch="Fill" ImageSource="{StaticResource Background}" />
</Grid.Background>
<Grid.RowDefinitions>
<RowDefinition Height="48"/>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Background="{StaticResource SplitViewColor}" x:Name="HamburgerGrid">
<Button x:Name="HamburgerButton" Height="48" Width="48" FontFamily="Segoe MDL2 Assets" Content="&#xE700;" Background="Transparent" Click="HamburgerButton_Click" VerticalAlignment="Center"
Foreground="White" FontSize="20" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"/>
</Grid>
<Grid Grid.Column="1" Background="{StaticResource SplitViewColor}" x:Name="TitleGrid">
<TextBlock x:Name="PageTitle" Margin="10,0,0,0" Foreground="White"
VerticalAlignment="Center"
HorizontalAlignment="Left"/>
</Grid>
<SplitView x:Name="MyDrivingSplitView" DisplayMode="Overlay" IsPaneOpen="False" CompactPaneLength="48" OpenPaneLength="200" Grid.Row="1" Grid.ColumnSpan="2" BorderThickness="0" >
<SplitView.Pane>
<StackPanel Background="Black" x:Name="SplitViewPanel">
<Button x:Name="NewTripButton" Click="NewTripButton_Click" Style="{StaticResource SplitViewButtonStyle}">
<controls:SplitViewButtonContent x:Name="Current" />
</Button>
<Button x:Name="TripsButton" Click="TripsButton_Click" Style="{StaticResource SplitViewButtonStyle}">
<controls:SplitViewButtonContent x:Name="PastTrips" />
</Button>
<Button x:Name="ProfileButton" Click="ProfileButton_Click" Style="{StaticResource SplitViewButtonStyle}">
<controls:SplitViewButtonContent x:Name="Profile" />
</Button>
<Button x:Name="SettingsButton" Click="SettingsButton_Click" Style="{StaticResource SplitViewButtonStyle}">
<controls:SplitViewButtonContent x:Name="Settings" />
</Button>
</StackPanel>
</SplitView.Pane>
</SplitView>
</Grid>
</Page>

View File

@ -0,0 +1,140 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
using MyDriving.UWP.Controls;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace MyDriving.UWP.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class SplitViewShell
{
SplitViewButtonContent selectedControl;
public SplitViewShell(Frame frame)
{
InitializeComponent();
MyDrivingSplitView.Content = frame;
frame.Navigated += Frame_Navigated;
Current.LabelText = "Current Trip";
Current.DefaultImageSource =
new BitmapImage(new Uri("ms-appx:///Assets/SplitView/current.png", UriKind.Absolute));
Current.SelectedImageSource =
new BitmapImage(new Uri("ms-appx:///Assets/SplitView/selected_current.png", UriKind.Absolute));
PastTrips.LabelText = "Past Trips";
PastTrips.DefaultImageSource =
new BitmapImage(new Uri("ms-appx:///Assets/SplitView/pastTrips.png", UriKind.Absolute));
PastTrips.SelectedImageSource =
new BitmapImage(new Uri("ms-appx:///Assets/SplitView/selected_pastTrips.png", UriKind.Absolute));
Profile.LabelText = "Profile";
Profile.DefaultImageSource =
new BitmapImage(new Uri("ms-appx:///Assets/SplitView/profile.png", UriKind.Absolute));
Profile.SelectedImageSource =
new BitmapImage(new Uri("ms-appx:///Assets/SplitView/selected_profile.png", UriKind.Absolute));
Settings.LabelText = "Settings";
Settings.DefaultImageSource =
new BitmapImage(new Uri("ms-appx:///Assets/SplitView/settings.png", UriKind.Absolute));
Settings.SelectedImageSource =
new BitmapImage(new Uri("ms-appx:///Assets/SplitView/selected_settings.png", UriKind.Absolute));
}
private void HamburgerButton_Click(object sender, RoutedEventArgs e)
{
MyDrivingSplitView.IsPaneOpen = !MyDrivingSplitView.IsPaneOpen;
if (MyDrivingSplitView.IsPaneOpen)
{
double openPaneLength = MainGrid.ActualWidth * .6;
if (openPaneLength > MyDrivingSplitView.OpenPaneLength && openPaneLength < 300)
{
MyDrivingSplitView.OpenPaneLength = openPaneLength;
NewTripButton.Width = openPaneLength;
TripsButton.Width = openPaneLength;
ProfileButton.Width = openPaneLength;
SettingsButton.Width = openPaneLength;
}
}
}
private void TripsButton_Click(object sender, RoutedEventArgs e)
{
SelectControl(PastTrips);
MyDrivingSplitView.IsPaneOpen = false;
PageTitle.Text = "PAST TRIPS";
((Frame)MyDrivingSplitView.Content).Navigate(typeof(PastTripsMenuView));
}
private void ProfileButton_Click(object sender, RoutedEventArgs e)
{
SelectControl(Profile);
MyDrivingSplitView.IsPaneOpen = false;
PageTitle.Text = "PROFILE";
((Frame)MyDrivingSplitView.Content).Navigate(typeof(ProfileView));
}
private void SettingsButton_Click(object sender, RoutedEventArgs e)
{
SelectControl(Settings);
MyDrivingSplitView.IsPaneOpen = false;
PageTitle.Text = "SETTINGS";
((Frame)MyDrivingSplitView.Content).Navigate(typeof(SettingsView));
}
private void NewTripButton_Click(object sender, RoutedEventArgs e)
{
SelectControl(Current);
MyDrivingSplitView.IsPaneOpen = false;
PageTitle.Text = "CURRENT TRIP";
((Frame)MyDrivingSplitView.Content).Navigate(typeof(CurrentTripView));
}
private void Frame_Navigated(object sender, NavigationEventArgs e)
{
MyDrivingSplitView.IsPaneOpen = false;
}
public void SelectControl(SplitViewButtonContent control)
{
selectedControl?.SetSelected(false);
control.SetSelected(true);
selectedControl = control;
}
public void SetTitle(string title)
{
PageTitle.Text = title;
}
public void SetSelectedPage(string page)
{
switch (page)
{
case "PAST TRIPS":
SelectControl(PastTrips);
break;
case "PROFILE":
SelectControl(Profile);
break;
case "SETTINGS":
SelectControl(Settings);
break;
default:
SelectControl(Current);
break;
}
}
}
}

View File

@ -0,0 +1,46 @@
<Page
x:Class="MyDriving.UWP.Views.TripSummaryView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:MyDriving.UWP.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Name="SUMMARY">
<Grid Background="{StaticResource MainBackgroundColor2}">
<ScrollViewer VerticalScrollBarVisibility="Hidden">
<StackPanel>
<Button x:Name="Close" VerticalAlignment="Top" HorizontalAlignment="Right" Height="40" Width="40" Click="ButtonClick_CloseView" Background="Transparent">
<Image Source="{StaticResource Close}" Height="32" Width="32" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Button>
<StackPanel Margin="24,4,24,4">
<StackPanel>
<TextBlock Text="You completed your trip!" HorizontalAlignment="Center" Margin="0,0,0,5" FontFamily="SegoeUI-Light" FontSize="21" Foreground="{StaticResource SummaryTextColor}" />
<TextBlock Text="Trip Summary" HorizontalAlignment="Center" Margin="0,5,0,15" FontFamily="SegoeUI-Semibold" FontSize="16" Foreground="White" FontWeight="Bold" />
</StackPanel>
<controls:ProfileViewTabControl x:Name="TotalDistanceTab" DataContext="{x:Bind ViewModel.TotalDistance, Mode=OneWay, Converter={StaticResource DistanceConverter} }" />
<controls:ProfileViewTabControl x:Name="TotalTimeTab" DataContext="{x:Bind ViewModel.TotalTime, Mode=OneWay, Converter={StaticResource TimeConverter}, ConverterParameter=' {0} seconds'}" />
<controls:ProfileViewTabControl x:Name="MaxSpeedTab" DataContext="{x:Bind ViewModel.MaxSpeedDisplay, Mode=OneWay}" />
<controls:ProfileViewTabControl x:Name="FuelConsumptionTab" DataContext="{x:Bind ViewModel.FuelDisplay, Mode=OneWay}" />
<controls:ProfileViewTabControl x:Name="HardBreaksTab" DataContext="{x:Bind ViewModel.HardStops, Mode=OneWay, Converter={StaticResource StringFormatConverter}, ConverterParameter=' {0} times'}" />
<controls:ProfileViewTabControl x:Name="HardAccelerationsTab" DataContext="{x:Bind ViewModel.HardAccelerations, Mode=OneWay, Converter={StaticResource StringFormatConverter}, ConverterParameter=' {0} times'}" />
</StackPanel>
</StackPanel>
</ScrollViewer>
</Grid>
</Page>

View File

@ -0,0 +1,99 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using System;
using Windows.UI.Core;
using Windows.UI.Xaml.Navigation;
using MyDriving.ViewModel;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace MyDriving.UWP.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class TripSummaryView
{
public TripSummaryView()
{
InitializeComponent();
ViewModel = new TripSummaryViewModel();
TotalDistanceTab.Title1 = "Total";
TotalDistanceTab.Title2 = "DISTANCE";
TotalTimeTab.Title1 = "Total";
TotalTimeTab.Title2 = "TIME";
MaxSpeedTab.Title1 = "Max";
MaxSpeedTab.Title2 = "SPEED";
FuelConsumptionTab.Title1 = "Total";
FuelConsumptionTab.Title2 = "FUEL USED";
HardBreaksTab.Title1 = "Hard";
HardBreaksTab.Title2 = "STOPS";
HardAccelerationsTab.Title1 = "Hard";
HardAccelerationsTab.Title2 = "ACCELERATIONS";
}
public TripSummaryViewModel ViewModel { get; set; }
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
ViewModel = e.Parameter as TripSummaryViewModel;
DataContext = this;
UpdateSummary();
// Enable back button behavior
SystemNavigationManager systemNavigationManager = SystemNavigationManager.GetForCurrentView();
systemNavigationManager.BackRequested += SystemNavigationManager_BackRequested;
// DrawPath();
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
SystemNavigationManager systemNavigationManager = SystemNavigationManager.GetForCurrentView();
systemNavigationManager.BackRequested -= SystemNavigationManager_BackRequested;
}
private void SystemNavigationManager_BackRequested(object sender, BackRequestedEventArgs e)
{
if (!e.Handled)
{
e.Handled = TryGoBack();
}
}
private bool TryGoBack()
{
bool navigated = false;
if (Frame.CanGoBack)
{
Frame.GoBack();
navigated = true;
}
return navigated;
}
private async void UpdateSummary()
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
//TotalDistanceTab.SetValue( ViewModel.TotalDistance);
});
}
private void ButtonClick_CloseView(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
App.SetTitle("CURRENT TRIP");
Frame.Navigate(typeof (CurrentTripView));
}
}
}