add openhack files
This commit is contained in:
@ -0,0 +1,442 @@
|
||||
// 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.Globalization;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using CoreAnimation;
|
||||
using CoreLocation;
|
||||
using Foundation;
|
||||
using MapKit;
|
||||
using UIKit;
|
||||
using MyDriving.DataObjects;
|
||||
using MyDriving.ViewModel;
|
||||
using Plugin.Permissions;
|
||||
using Plugin.Permissions.Abstractions;
|
||||
using MyDriving.Utils;
|
||||
using Microsoft.WindowsAzure.MobileServices;
|
||||
using MyDriving.iOS.Helpers;
|
||||
using MyDriving.AzureClient;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
partial class CurrentTripViewController : UIViewController
|
||||
{
|
||||
CarAnnotation currentLocationAnnotation;
|
||||
TripMapViewDelegate mapDelegate;
|
||||
List<CLLocationCoordinate2D> route;
|
||||
|
||||
public CurrentTripViewController(IntPtr handle) : base(handle)
|
||||
{
|
||||
}
|
||||
|
||||
public CurrentTripViewModel CurrentTripViewModel { get; set; }
|
||||
public PastTripsDetailViewModel PastTripsDetailViewModel { get; set; }
|
||||
|
||||
public override async void ViewDidLoad()
|
||||
{
|
||||
base.ViewDidLoad();
|
||||
|
||||
NavigationItem.RightBarButtonItem = null;
|
||||
|
||||
if (PastTripsDetailViewModel == null)
|
||||
await ConfigureCurrentTripUserInterface();
|
||||
else
|
||||
await ConfigurePastTripUserInterface();
|
||||
}
|
||||
|
||||
public override async void ViewDidAppear(bool animated)
|
||||
{
|
||||
base.ViewDidAppear(animated);
|
||||
PopRecordButtonAnimation();
|
||||
|
||||
if (CurrentTripViewModel != null)
|
||||
{
|
||||
await CurrentTripViewModel.ExecuteStartTrackingTripCommandAsync().ContinueWith(async (task) =>
|
||||
{
|
||||
// If we don't have permission from the user, prompt a dialog requesting permission.
|
||||
await PromptPermissionsChangeDialog();
|
||||
});
|
||||
|
||||
if (!CurrentTripViewModel.Geolocator.IsGeolocationEnabled)
|
||||
{
|
||||
tripMapView.Camera.CenterCoordinate = new CLLocationCoordinate2D(47.6204, -122.3491);
|
||||
tripMapView.Camera.Altitude = 5000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Current Trip User Interface Logic
|
||||
|
||||
async Task ConfigureCurrentTripUserInterface()
|
||||
{
|
||||
// Configure map
|
||||
mapDelegate = new TripMapViewDelegate(true);
|
||||
tripMapView.Delegate = mapDelegate;
|
||||
tripMapView.ShowsUserLocation = false;
|
||||
tripMapView.Camera.Altitude = 5000;
|
||||
|
||||
// Setup record button
|
||||
recordButton.Hidden = false;
|
||||
recordButton.Layer.CornerRadius = recordButton.Frame.Width/2;
|
||||
recordButton.Layer.MasksToBounds = true;
|
||||
recordButton.Layer.BorderColor = UIColor.White.CGColor;
|
||||
recordButton.Layer.BorderWidth = 0;
|
||||
recordButton.TouchUpInside += RecordButton_TouchUpInside;
|
||||
|
||||
// Hide slider
|
||||
tripSlider.Hidden = true;
|
||||
wayPointA.Hidden = true;
|
||||
wayPointB.Hidden = true;
|
||||
|
||||
UpdateRecordButton(false);
|
||||
tripInfoView.Alpha = 0;
|
||||
ResetTripInfoView();
|
||||
|
||||
CurrentTripViewModel = new CurrentTripViewModel();
|
||||
CurrentTripViewModel.Geolocator.PositionChanged += Geolocator_PositionChanged;
|
||||
|
||||
}
|
||||
|
||||
void AnimateTripInfoView()
|
||||
{
|
||||
tripInfoView.FadeIn(0.3, 0);
|
||||
}
|
||||
|
||||
void ResetMapViewState()
|
||||
{
|
||||
InvokeOnMainThread(() =>
|
||||
{
|
||||
route = null;
|
||||
tripMapView.RemoveAnnotations(tripMapView.Annotations);
|
||||
|
||||
if (tripMapView.Overlays != null && tripMapView.Overlays.Length > 0)
|
||||
{
|
||||
tripMapView.RemoveOverlays(tripMapView.Overlays[0]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ResetTripInfoView()
|
||||
{
|
||||
labelOneValue.Text = "N/A";
|
||||
labelTwoValue.Text = "0";
|
||||
labelThreeValue.Text = "0:00";
|
||||
labelFourValue.Text = "N/A";
|
||||
}
|
||||
|
||||
void UpdateRecordButton(bool isRecording)
|
||||
{
|
||||
//Corner Radius
|
||||
var radiusAnimation = CABasicAnimation.FromKeyPath("cornerRadius");
|
||||
radiusAnimation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseIn);
|
||||
radiusAnimation.From = NSNumber.FromNFloat(recordButton.Layer.CornerRadius);
|
||||
|
||||
//Border Thickness
|
||||
var borderAnimation = CABasicAnimation.FromKeyPath("borderWidth");
|
||||
borderAnimation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseIn);
|
||||
radiusAnimation.From = NSNumber.FromNFloat(recordButton.Layer.BorderWidth);
|
||||
|
||||
//Animation Group
|
||||
var animationGroup = CAAnimationGroup.CreateAnimation();
|
||||
animationGroup.Animations = new CAAnimation[] {radiusAnimation, borderAnimation};
|
||||
animationGroup.Duration = 0.6;
|
||||
animationGroup.FillMode = CAFillMode.Forwards;
|
||||
|
||||
recordButton.Layer.CornerRadius = isRecording ? 4 : recordButton.Frame.Width/2;
|
||||
recordButton.Layer.BorderWidth = isRecording ? 2 : 3;
|
||||
|
||||
recordButton.Layer.AddAnimation(animationGroup, "borderChanges");
|
||||
}
|
||||
|
||||
async Task PromptPermissionsChangeDialog()
|
||||
{
|
||||
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
|
||||
if (status == PermissionStatus.Denied)
|
||||
{
|
||||
InvokeOnMainThread(() =>
|
||||
{
|
||||
var alertController = UIAlertController.Create("Location Permission Denied",
|
||||
"Tracking your location is required to record trips. Visit the Settings app to change the permission status.",
|
||||
UIAlertControllerStyle.Alert);
|
||||
alertController.AddAction(UIAlertAction.Create("Change Permission", UIAlertActionStyle.Default,
|
||||
obj =>
|
||||
{
|
||||
var url = NSUrl.FromString(UIApplication.OpenSettingsUrlString);
|
||||
UIApplication.SharedApplication.OpenUrl(url);
|
||||
}));
|
||||
|
||||
alertController.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Cancel, null));
|
||||
|
||||
PresentViewController(alertController, true, null);
|
||||
|
||||
tripMapView.Camera.CenterCoordinate = new CLLocationCoordinate2D(47.6204, -122.3491);
|
||||
tripMapView.Camera.Altitude = 5000;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async void RecordButton_TouchUpInside(object sender, EventArgs e)
|
||||
{
|
||||
if (!CurrentTripViewModel.Geolocator.IsGeolocationEnabled)
|
||||
{
|
||||
Acr.UserDialogs.UserDialogs.Instance.Alert(
|
||||
"Please ensure that geolocation is enabled and permissions are allowed for MyDriving to start a recording.",
|
||||
"Geolocation Disabled", "OK");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CurrentTripViewModel.IsRecording)
|
||||
{
|
||||
if (!await CurrentTripViewModel.StartRecordingTrip())
|
||||
return;
|
||||
|
||||
UpdateRecordButton(true);
|
||||
ResetTripInfoView();
|
||||
AnimateTripInfoView();
|
||||
|
||||
if (CurrentTripViewModel.CurrentTrip.HasSimulatedOBDData)
|
||||
NavigationItem.Title = "Current Trip (Sim OBD)";
|
||||
|
||||
var endpoint = "A";
|
||||
var annotation = new WaypointAnnotation(CurrentTripViewModel.CurrentPosition.ToCoordinate(), endpoint);
|
||||
tripMapView.AddAnnotation(annotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (await CurrentTripViewModel.StopRecordingTrip())
|
||||
{
|
||||
ResetMapViewState();
|
||||
InvokeOnMainThread(delegate
|
||||
{
|
||||
mapDelegate = new TripMapViewDelegate(true);
|
||||
tripMapView.Delegate = mapDelegate;
|
||||
});
|
||||
|
||||
UpdateRecordButton(false);
|
||||
tripInfoView.Alpha = 0;
|
||||
NavigationItem.Title = "Current Trip";
|
||||
|
||||
await CurrentTripViewModel.SaveRecordingTripAsync();
|
||||
|
||||
var vc =
|
||||
Storyboard.InstantiateViewController("tripSummaryViewController") as TripSummaryViewController;
|
||||
vc.ViewModel = CurrentTripViewModel;
|
||||
PresentModalViewController(vc, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Geolocator_PositionChanged(object sender, Plugin.Geolocator.Abstractions.PositionEventArgs e)
|
||||
{
|
||||
var coordinate = e.Position.ToCoordinate();
|
||||
UpdateCarAnnotationPosition(coordinate);
|
||||
|
||||
if (CurrentTripViewModel.IsRecording)
|
||||
{
|
||||
// Update trip information
|
||||
labelOneValue.Text = CurrentTripViewModel.FuelConsumption;
|
||||
labelOneTitle.Text = CurrentTripViewModel.FuelConsumptionUnits;
|
||||
labelThreeValue.Text = CurrentTripViewModel.ElapsedTime;
|
||||
labelTwoValue.Text = CurrentTripViewModel.CurrentTrip.Distance.ToString("F");
|
||||
labelTwoTitle.Text =
|
||||
CultureInfo.CurrentCulture.TextInfo.ToTitleCase(CurrentTripViewModel.CurrentTrip.Units.ToLower());
|
||||
labelFourValue.Text = CurrentTripViewModel.EngineLoad;
|
||||
|
||||
// If we already haven't starting tracking route yet, start that.
|
||||
if (route == null)
|
||||
StartTrackingRoute(coordinate);
|
||||
// Draw from last known coordinate to new coordinate.
|
||||
else
|
||||
DrawNewRouteWaypoint(coordinate);
|
||||
}
|
||||
}
|
||||
|
||||
void StartTrackingRoute(CLLocationCoordinate2D coordinate)
|
||||
{
|
||||
route = new List<CLLocationCoordinate2D>();
|
||||
|
||||
var count = CurrentTripViewModel.CurrentTrip.Points.Count;
|
||||
if (count == 0)
|
||||
{
|
||||
route.Add(coordinate);
|
||||
}
|
||||
else
|
||||
{
|
||||
var firstPoint = CurrentTripViewModel.CurrentTrip.Points?[0];
|
||||
var firstCoordinate = new CLLocationCoordinate2D(firstPoint.Latitude, firstPoint.Longitude);
|
||||
route.Add(firstCoordinate);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Past Trip User Interface Logic
|
||||
|
||||
async Task ConfigurePastTripUserInterface()
|
||||
{
|
||||
NavigationItem.Title = PastTripsDetailViewModel.Title;
|
||||
sliderView.Hidden = false;
|
||||
tripSlider.Hidden = false;
|
||||
|
||||
wayPointA.Layer.CornerRadius = wayPointA.Frame.Width / 2;
|
||||
wayPointA.Layer.BorderWidth = 2;
|
||||
wayPointA.Layer.BorderColor = UIColor.White.CGColor;
|
||||
|
||||
wayPointB.Layer.CornerRadius = wayPointB.Frame.Width / 2;
|
||||
wayPointB.Layer.BorderWidth = 2;
|
||||
wayPointB.Layer.BorderColor = UIColor.White.CGColor;
|
||||
|
||||
var success = await PastTripsDetailViewModel.ExecuteLoadTripCommandAsync(PastTripsDetailViewModel.Trip.Id);
|
||||
|
||||
if(!success)
|
||||
{
|
||||
NavigationController.PopViewController(true);
|
||||
return;
|
||||
}
|
||||
// Setup map
|
||||
mapDelegate = new TripMapViewDelegate(false);
|
||||
tripMapView.Delegate = mapDelegate;
|
||||
tripMapView.ShowsUserLocation = false;
|
||||
|
||||
if (PastTripsDetailViewModel.Trip == null || PastTripsDetailViewModel.Trip.Points == null || PastTripsDetailViewModel.Trip.Points.Count == 0)
|
||||
return;
|
||||
|
||||
var coordinateCount = PastTripsDetailViewModel.Trip.Points.Count;
|
||||
// Draw endpoints
|
||||
var startEndpoint = new WaypointAnnotation(PastTripsDetailViewModel.Trip.Points[0].ToCoordinate(), "A");
|
||||
tripMapView.AddAnnotation(startEndpoint);
|
||||
|
||||
var endEndpoint =
|
||||
new WaypointAnnotation(PastTripsDetailViewModel.Trip.Points[coordinateCount - 1].ToCoordinate(), "B");
|
||||
tripMapView.AddAnnotation(endEndpoint);
|
||||
|
||||
// Draw route
|
||||
tripMapView.DrawRoute(PastTripsDetailViewModel.Trip.Points.ToCoordinateArray());
|
||||
|
||||
// Draw car
|
||||
var carCoordinate = PastTripsDetailViewModel.Trip.Points[0];
|
||||
currentLocationAnnotation = new CarAnnotation(carCoordinate.ToCoordinate(), UIColor.Blue);
|
||||
tripMapView.AddAnnotation(currentLocationAnnotation);
|
||||
|
||||
// Configure slider area
|
||||
ConfigureSlider();
|
||||
ConfigureWayPointButtons();
|
||||
ConfigurePoiAnnotations();
|
||||
recordButton.Hidden = true;
|
||||
|
||||
tripMapView.SetVisibleMapRect(
|
||||
MKPolyline.FromCoordinates(PastTripsDetailViewModel.Trip.Points.ToCoordinateArray()).BoundingMapRect,
|
||||
new UIEdgeInsets(25, 25, 25, 25), false);
|
||||
|
||||
tripMapView.CenterCoordinate = carCoordinate.ToCoordinate();
|
||||
UpdateTripStatistics(carCoordinate);
|
||||
NSNotificationCenter.DefaultCenter.AddObserver(new NSString("RefreshTripUnits"), HandleTripUnitsChanged);
|
||||
}
|
||||
|
||||
void HandleTripUnitsChanged(NSNotification obj)
|
||||
{
|
||||
UpdateTripStatistics(PastTripsDetailViewModel.CurrentPosition);
|
||||
}
|
||||
|
||||
void UpdateTripStatistics(TripPoint point)
|
||||
{
|
||||
PastTripsDetailViewModel.CurrentPosition = point;
|
||||
labelOneTitle.Text = PastTripsDetailViewModel.FuelConsumptionUnits;
|
||||
labelOneValue.Text = PastTripsDetailViewModel.FuelConsumption;
|
||||
|
||||
labelTwoTitle.Text = PastTripsDetailViewModel.DistanceUnits;
|
||||
labelTwoValue.Text = PastTripsDetailViewModel.Distance;
|
||||
|
||||
labelThreeTitle.Text = "Elapsed Time";
|
||||
labelThreeValue.Text = PastTripsDetailViewModel.ElapsedTime;
|
||||
|
||||
labelFourTitle.Text = PastTripsDetailViewModel.SpeedUnits;
|
||||
labelFourValue.Text = PastTripsDetailViewModel.Speed;
|
||||
}
|
||||
|
||||
void ConfigureSlider()
|
||||
{
|
||||
tripSlider.MinValue = 0;
|
||||
tripSlider.MaxValue = PastTripsDetailViewModel.Trip.Points.Count - 1;
|
||||
tripSlider.Value = 0;
|
||||
|
||||
tripSlider.ValueChanged += TripSlider_ValueChanged;
|
||||
}
|
||||
|
||||
void ConfigureWayPointButtons()
|
||||
{
|
||||
startTimeLabel.Hidden = false;
|
||||
endTimeLabel.Hidden = false;
|
||||
|
||||
startTimeLabel.Text = PastTripsDetailViewModel.Trip.StartTimeDisplay;
|
||||
endTimeLabel.Text = PastTripsDetailViewModel.Trip.EndTimeDisplay;
|
||||
|
||||
wayPointA.TouchUpInside += delegate
|
||||
{
|
||||
tripSlider.Value = 0;
|
||||
TripSlider_ValueChanged(this, null);
|
||||
};
|
||||
|
||||
wayPointB.TouchUpInside += delegate
|
||||
{
|
||||
tripSlider.Value = tripSlider.MaxValue;
|
||||
TripSlider_ValueChanged(this, null);
|
||||
};
|
||||
}
|
||||
|
||||
void ConfigurePoiAnnotations()
|
||||
{
|
||||
foreach (var poi in PastTripsDetailViewModel.POIs)
|
||||
{
|
||||
var poiAnnotation = new PoiAnnotation(poi, poi.ToCoordinate());
|
||||
tripMapView.AddAnnotation(poiAnnotation);
|
||||
}
|
||||
}
|
||||
|
||||
void TripSlider_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
var value = (int) tripSlider.Value;
|
||||
var tripPoint = PastTripsDetailViewModel.Trip.Points[value];
|
||||
UpdateCarAnnotationPosition(tripPoint.ToCoordinate());
|
||||
|
||||
UpdateTripStatistics(tripPoint);
|
||||
}
|
||||
|
||||
void PopRecordButtonAnimation()
|
||||
{
|
||||
if (recordButton.Hidden && PastTripsDetailViewModel == null)
|
||||
recordButton.Pop(0.5, 0, 1);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Shared User Interface Logic
|
||||
|
||||
void UpdateCarAnnotationPosition(CLLocationCoordinate2D coordinate)
|
||||
{
|
||||
if (currentLocationAnnotation != null)
|
||||
tripMapView.RemoveAnnotation(currentLocationAnnotation);
|
||||
|
||||
var color = CurrentTripViewModel != null && CurrentTripViewModel.IsRecording ? UIColor.Red : UIColor.Blue;
|
||||
currentLocationAnnotation = new CarAnnotation(coordinate, color);
|
||||
|
||||
tripMapView.AddAnnotation(currentLocationAnnotation);
|
||||
tripMapView.Camera.CenterCoordinate = coordinate;
|
||||
}
|
||||
|
||||
void DrawNewRouteWaypoint(CLLocationCoordinate2D coordinate)
|
||||
{
|
||||
route.Add(coordinate);
|
||||
|
||||
if (tripMapView.Overlays != null)
|
||||
tripMapView.RemoveOverlays(tripMapView.Overlays);
|
||||
|
||||
tripMapView.DrawRoute(route.ToArray());
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
173
MobileApps/MyDriving/MyDriving.iOS/Screens/Trips/CurrentTripViewController.designer.cs
generated
Normal file
173
MobileApps/MyDriving/MyDriving.iOS/Screens/Trips/CurrentTripViewController.designer.cs
generated
Normal file
@ -0,0 +1,173 @@
|
||||
// WARNING
|
||||
//
|
||||
// This file has been generated automatically by Visual Studio from the outlets and
|
||||
// actions declared in your storyboard file.
|
||||
// Manual changes to this file will not be maintained.
|
||||
//
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using UIKit;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
[Register ("CurrentTripViewController")]
|
||||
partial class CurrentTripViewController
|
||||
{
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel endTimeLabel { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel labelFourTitle { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel labelFourValue { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel labelOneTitle { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel labelOneValue { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel labelThreeTitle { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel labelThreeValue { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel labelTwoTitle { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel labelTwoValue { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIButton recordButton { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIView sliderView { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel startTimeLabel { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIView tripInfoView { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
MyDriving.iOS.TripMapView tripMapView { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UISlider tripSlider { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIButton wayPointA { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIButton wayPointB { get; set; }
|
||||
|
||||
void ReleaseDesignerOutlets ()
|
||||
{
|
||||
if (endTimeLabel != null) {
|
||||
endTimeLabel.Dispose ();
|
||||
endTimeLabel = null;
|
||||
}
|
||||
|
||||
if (labelFourTitle != null) {
|
||||
labelFourTitle.Dispose ();
|
||||
labelFourTitle = null;
|
||||
}
|
||||
|
||||
if (labelFourValue != null) {
|
||||
labelFourValue.Dispose ();
|
||||
labelFourValue = null;
|
||||
}
|
||||
|
||||
if (labelOneTitle != null) {
|
||||
labelOneTitle.Dispose ();
|
||||
labelOneTitle = null;
|
||||
}
|
||||
|
||||
if (labelOneValue != null) {
|
||||
labelOneValue.Dispose ();
|
||||
labelOneValue = null;
|
||||
}
|
||||
|
||||
if (labelThreeTitle != null) {
|
||||
labelThreeTitle.Dispose ();
|
||||
labelThreeTitle = null;
|
||||
}
|
||||
|
||||
if (labelThreeValue != null) {
|
||||
labelThreeValue.Dispose ();
|
||||
labelThreeValue = null;
|
||||
}
|
||||
|
||||
if (labelTwoTitle != null) {
|
||||
labelTwoTitle.Dispose ();
|
||||
labelTwoTitle = null;
|
||||
}
|
||||
|
||||
if (labelTwoValue != null) {
|
||||
labelTwoValue.Dispose ();
|
||||
labelTwoValue = null;
|
||||
}
|
||||
|
||||
if (recordButton != null) {
|
||||
recordButton.Dispose ();
|
||||
recordButton = null;
|
||||
}
|
||||
|
||||
if (sliderView != null) {
|
||||
sliderView.Dispose ();
|
||||
sliderView = null;
|
||||
}
|
||||
|
||||
if (startTimeLabel != null) {
|
||||
startTimeLabel.Dispose ();
|
||||
startTimeLabel = null;
|
||||
}
|
||||
|
||||
if (tripInfoView != null) {
|
||||
tripInfoView.Dispose ();
|
||||
tripInfoView = null;
|
||||
}
|
||||
|
||||
if (tripMapView != null) {
|
||||
tripMapView.Dispose ();
|
||||
tripMapView = null;
|
||||
}
|
||||
|
||||
if (tripSlider != null) {
|
||||
tripSlider.Dispose ();
|
||||
tripSlider = null;
|
||||
}
|
||||
|
||||
if (wayPointA != null) {
|
||||
wayPointA.Dispose ();
|
||||
wayPointA = null;
|
||||
}
|
||||
|
||||
if (wayPointB != null) {
|
||||
wayPointB.Dispose ();
|
||||
wayPointB = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for details.
|
||||
|
||||
using System;
|
||||
using UIKit;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
public partial class TripSummaryViewController : UIViewController
|
||||
{
|
||||
public TripSummaryViewController(IntPtr handle) : base(handle)
|
||||
{
|
||||
}
|
||||
|
||||
public ViewModel.CurrentTripViewModel ViewModel { get; set; }
|
||||
|
||||
public override void ViewDidLoad()
|
||||
{
|
||||
lblDateTime.Text = $"{DateTime.Now.ToString("M")} {DateTime.Now.ToString("t")}";
|
||||
lblDistance.Text = ViewModel.TripSummary.TotalDistanceDisplay;
|
||||
lblDuration.Text = ViewModel.TripSummary.TotalTimeDisplay;
|
||||
lblFuelConsumed.Text = ViewModel.TripSummary.FuelDisplay;
|
||||
lblTopSpeed.Text = ViewModel.TripSummary.MaxSpeedDisplay;
|
||||
|
||||
lblDistance.Alpha = 0;
|
||||
lblDuration.Alpha = 0;
|
||||
lblTopSpeed.Alpha = 0;
|
||||
lblFuelConsumed.Alpha = 0;
|
||||
lblTopSpeed.Alpha = 0;
|
||||
}
|
||||
|
||||
public override void ViewDidAppear(bool animated)
|
||||
{
|
||||
base.ViewDidAppear(animated);
|
||||
|
||||
lblDistance.FadeIn(0.4, 0.1f);
|
||||
lblDuration.FadeIn(0.4, 0.2f);
|
||||
lblTopSpeed.FadeIn(0.4, 0.3f);
|
||||
lblFuelConsumed.FadeIn(0.4, 0.4f);
|
||||
lblTopSpeed.FadeIn(0.4, 0.5f);
|
||||
}
|
||||
|
||||
async partial void BtnClose_TouchUpInside(UIButton sender)
|
||||
{
|
||||
await DismissViewControllerAsync(true);
|
||||
}
|
||||
}
|
||||
}
|
78
MobileApps/MyDriving/MyDriving.iOS/Screens/Trips/TripSummaryViewController.designer.cs
generated
Normal file
78
MobileApps/MyDriving/MyDriving.iOS/Screens/Trips/TripSummaryViewController.designer.cs
generated
Normal file
@ -0,0 +1,78 @@
|
||||
// WARNING
|
||||
//
|
||||
// This file has been generated automatically by Visual Studio from the outlets and
|
||||
// actions declared in your storyboard file.
|
||||
// Manual changes to this file will not be maintained.
|
||||
//
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using UIKit;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
[Register ("TripSummaryViewController")]
|
||||
partial class TripSummaryViewController
|
||||
{
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UIButton btnClose { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel lblDateTime { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel lblDistance { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel lblDuration { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel lblFuelConsumed { get; set; }
|
||||
|
||||
[Outlet]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
UIKit.UILabel lblTopSpeed { get; set; }
|
||||
|
||||
[Action ("BtnClose_TouchUpInside:")]
|
||||
[GeneratedCode ("iOS Designer", "1.0")]
|
||||
partial void BtnClose_TouchUpInside (UIKit.UIButton sender);
|
||||
|
||||
void ReleaseDesignerOutlets ()
|
||||
{
|
||||
if (btnClose != null) {
|
||||
btnClose.Dispose ();
|
||||
btnClose = null;
|
||||
}
|
||||
|
||||
if (lblDateTime != null) {
|
||||
lblDateTime.Dispose ();
|
||||
lblDateTime = null;
|
||||
}
|
||||
|
||||
if (lblDistance != null) {
|
||||
lblDistance.Dispose ();
|
||||
lblDistance = null;
|
||||
}
|
||||
|
||||
if (lblDuration != null) {
|
||||
lblDuration.Dispose ();
|
||||
lblDuration = null;
|
||||
}
|
||||
|
||||
if (lblFuelConsumed != null) {
|
||||
lblFuelConsumed.Dispose ();
|
||||
lblFuelConsumed = null;
|
||||
}
|
||||
|
||||
if (lblTopSpeed != null) {
|
||||
lblTopSpeed.Dispose ();
|
||||
lblTopSpeed = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,152 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for details.
|
||||
|
||||
using System;
|
||||
using CoreGraphics;
|
||||
using Foundation;
|
||||
using ObjCRuntime;
|
||||
using UIKit;
|
||||
using MyDriving.ViewModel;
|
||||
using SDWebImage;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
public partial class TripsTableViewController : UITableViewController
|
||||
{
|
||||
const string TripCellWithImageIdentifier = "TRIP_CELL_WITHIMAGE_IDENTIFIER";
|
||||
const string TripCellIdentifier = "TRIP_CELL_IDENTIFIER";
|
||||
const string PastTripSegueIdentifier = "pastTripSegue";
|
||||
|
||||
public TripsTableViewController(IntPtr handle) : base(handle)
|
||||
{
|
||||
}
|
||||
|
||||
public PastTripsViewModel ViewModel { get; set; }
|
||||
|
||||
public override async void ViewDidLoad()
|
||||
{
|
||||
base.ViewDidLoad();
|
||||
|
||||
ViewModel = new PastTripsViewModel();
|
||||
await ViewModel.ExecuteLoadPastTripsCommandAsync();
|
||||
|
||||
TableView.ReloadData();
|
||||
TableView.TableFooterView = new UIView(new CGRect(0, 0, 0, 0));
|
||||
|
||||
RefreshControl.AddTarget(this, new Selector("RefreshSource"), UIControlEvent.ValueChanged);
|
||||
NSNotificationCenter.DefaultCenter.AddObserver(new NSString("RefreshPastTripsTable"),
|
||||
HandleReloadTableNotification);
|
||||
}
|
||||
|
||||
public override void PrepareForSegue(UIStoryboardSegue segue, NSObject sender)
|
||||
{
|
||||
if (segue.Identifier == PastTripSegueIdentifier)
|
||||
{
|
||||
var controller = segue.DestinationViewController as CurrentTripViewController;
|
||||
var indexPath = TableView.IndexPathForCell(sender as UITableViewCell);
|
||||
var trip = ViewModel.Trips[indexPath.Row];
|
||||
|
||||
controller.PastTripsDetailViewModel = new PastTripsDetailViewModel(trip);
|
||||
}
|
||||
}
|
||||
|
||||
[Export("RefreshSource")]
|
||||
async void RefreshControl_ValueChanged()
|
||||
{
|
||||
await ViewModel.ExecuteLoadPastTripsCommandAsync();
|
||||
|
||||
InvokeOnMainThread(delegate
|
||||
{
|
||||
TableView.ReloadData();
|
||||
RefreshControl.EndRefreshing();
|
||||
});
|
||||
}
|
||||
|
||||
async void HandleReloadTableNotification(NSNotification obj)
|
||||
{
|
||||
await ViewModel.ExecuteLoadPastTripsCommandAsync();
|
||||
|
||||
InvokeOnMainThread(delegate { TableView.ReloadData(); });
|
||||
}
|
||||
|
||||
#region UITableViewSource
|
||||
|
||||
public override nint RowsInSection(UITableView tableView, nint section)
|
||||
{
|
||||
return ViewModel.Trips.Count;
|
||||
}
|
||||
|
||||
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
|
||||
{
|
||||
if (ViewModel.CanLoadMore && !ViewModel.IsBusy && ViewModel.Trips.Count > 0 && indexPath.Row == ViewModel.Trips.Count - 1)
|
||||
{
|
||||
ViewModel.ExecuteLoadMorePastTripsCommandAsync().ContinueWith((t) =>
|
||||
{
|
||||
InvokeOnMainThread(delegate { TableView.ReloadData(); });
|
||||
}, scheduler: System.Threading.Tasks.TaskScheduler.Current);
|
||||
}
|
||||
|
||||
var trip = ViewModel.Trips[indexPath.Row];
|
||||
if (string.IsNullOrEmpty(trip.MainPhotoUrl))
|
||||
{
|
||||
var cell = tableView.DequeueReusableCell(TripCellIdentifier) as TripTableViewCell;
|
||||
|
||||
if (cell == null)
|
||||
{
|
||||
cell = new TripTableViewCell(new NSString(TripCellIdentifier));
|
||||
}
|
||||
|
||||
cell.LocationName = trip.Name;
|
||||
cell.TimeAgo = trip.TimeAgo;
|
||||
cell.Distance = trip.TotalDistance;
|
||||
|
||||
return cell;
|
||||
}
|
||||
else
|
||||
{
|
||||
var cell = tableView.DequeueReusableCell(TripCellWithImageIdentifier) as TripTableViewCellWithImage;
|
||||
|
||||
if (cell == null)
|
||||
{
|
||||
cell = new TripTableViewCellWithImage(new NSString(TripCellWithImageIdentifier));
|
||||
}
|
||||
|
||||
cell.DisplayImage.SetImage(new NSUrl(trip.MainPhotoUrl));
|
||||
cell.LocationName = trip.Name;
|
||||
cell.TimeAgo = trip.TimeAgo;
|
||||
cell.Distance = trip.TotalDistance;
|
||||
|
||||
return cell;
|
||||
}
|
||||
}
|
||||
|
||||
public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
|
||||
{
|
||||
var trip = ViewModel.Trips[indexPath.Row];
|
||||
if (string.IsNullOrEmpty(trip.MainPhotoUrl))
|
||||
return 70;
|
||||
else
|
||||
return 221;
|
||||
}
|
||||
|
||||
public override bool CanEditRow(UITableView tableView, NSIndexPath indexPath)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override async void CommitEditingStyle(UITableView tableView, UITableViewCellEditingStyle editingStyle,
|
||||
NSIndexPath indexPath)
|
||||
{
|
||||
switch (editingStyle)
|
||||
{
|
||||
case UITableViewCellEditingStyle.Delete:
|
||||
var trip = ViewModel.Trips[indexPath.Row];
|
||||
if(await ViewModel.ExecuteDeleteTripCommand(trip))
|
||||
tableView.DeleteRows(new[] {indexPath}, UITableViewRowAnimation.Automatic);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
21
MobileApps/MyDriving/MyDriving.iOS/Screens/Trips/TripsTableViewController.designer.cs
generated
Normal file
21
MobileApps/MyDriving/MyDriving.iOS/Screens/Trips/TripsTableViewController.designer.cs
generated
Normal file
@ -0,0 +1,21 @@
|
||||
// WARNING
|
||||
//
|
||||
// This file has been generated automatically by Visual Studio from the outlets and
|
||||
// actions declared in your storyboard file.
|
||||
// Manual changes to this file will not be maintained.
|
||||
//
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using UIKit;
|
||||
|
||||
namespace MyDriving.iOS
|
||||
{
|
||||
[Register ("TripsTableViewController")]
|
||||
partial class TripsTableViewController
|
||||
{
|
||||
void ReleaseDesignerOutlets ()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user