Add squat service to exercising view.
authorPiotr Czaja/Advanced Frameworks (PLT) /SRPOL/Engineer/Samsung Electronics <p.czaja@samsung.com>
Mon, 19 Jul 2021 11:59:45 +0000 (13:59 +0200)
committerPiotr Czaja <p.czaja@samsung.com>
Tue, 14 Sep 2021 11:01:34 +0000 (13:01 +0200)
Fitness/ViewModels/ExercisingViewModel.cs
Fitness/Views/ExercisingView.xaml.cs
Fitness/res/layout/ExercisingView.xaml
Fitness/res/layout/PlayingView.xaml

index 9b73e4a5ef401032d4d579302c37c01c0e6a4564..f3a74d52cce83e66c0495c4c8d18f9d12f33e797 100644 (file)
@@ -1,6 +1,7 @@
 using System;
 using System.Windows.Input;
 using Fitness.Models;
+using Fitness.Services;
 using Tizen.NUI.Binding;
 
 namespace Fitness.ViewModels
@@ -8,6 +9,7 @@ namespace Fitness.ViewModels
     public class ExercisingViewModel : ChangeWorkoutViewModel
     {
         private WorkoutState state;
+        private SquatService squatService;
 
         public ExercisingViewModel(WorkoutViewModel workoutViewModel)
         {
@@ -16,6 +18,10 @@ namespace Fitness.ViewModels
             EndWorkout = new Command(ExecuteEndWorkout);
             State = WorkoutState.Playing;
             CurrentWorkout = workoutViewModel;
+            squatService = new SquatService()
+            {
+                HoldTimeThreshold = 1200,
+            };
         }
 
         /// <summary>
@@ -96,6 +102,22 @@ namespace Fitness.ViewModels
 
         public string PauseResumeLabel { get; private set; } = "Pause";
 
+        /// <summary>
+        /// Gets or sets the <see cref="SquatService"/> property.
+        /// </summary>
+        public SquatService SquatService
+        {
+            get => squatService;
+            set
+            {
+                if (value != squatService)
+                {
+                    squatService = value;
+                    RaisePropertyChanged();
+                }
+            }
+        }
+
         protected override void GoPrevious()
         {
             if (State == WorkoutState.Playing)
index 26e0296019dc7032505843b16328c0ff3bb99fe9..077c5f0b3e9193ad5c86362b5bc74102de940138 100644 (file)
@@ -3,6 +3,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using Fitness.Models;
 using Fitness.ViewModels;
+using Tizen.Multimedia;
 using Tizen.NUI;
 using Tizen.NUI.BaseComponents;
 using Tizen.NUI.Binding;
@@ -27,12 +28,12 @@ namespace Fitness.Views
             Preview: new Coordinates() // fixed for now
             {
                 Position = new Position(0, 0),
-                Size = new Size(1920, 1080),
+                Size = new Tizen.NUI.Size(1920, 1080),
             },
             Camera: new Coordinates() // fixed for now
             {
                 Position = new Position(1356, 144),
-                Size = new Size(500, 292),
+                Size = new Tizen.NUI.Size(500, 292),
             });
 
         /// <summary>
@@ -50,6 +51,7 @@ namespace Fitness.Views
         {
             if (cameraView.PreviewState == Tizen.Multimedia.CameraState.Preview)
             {
+                cameraView.Preview -= DetectPreview;
                 cameraView.StopPreview();
             }
         }
@@ -62,6 +64,7 @@ namespace Fitness.Views
             if (cameraView.PreviewState == Tizen.Multimedia.CameraState.Created || cameraView.PreviewState == Tizen.Multimedia.CameraState.Captured)
             {
                 cameraView.StartPreview();
+                cameraView.Preview += DetectPreview;
             }
         }
 
@@ -115,6 +118,7 @@ namespace Fitness.Views
             InitializeComponent();
 
             PlayingView.PreviewStub.Relayout += OnPlayingViewRelayout;
+            cameraView.Preview += DetectPreview;
         }
 
         private async Task TriggerStates(bool isPlaying)
@@ -128,7 +132,7 @@ namespace Fitness.Views
                 if (isPlaying)
                 {
                     (Task scalePreview, Task movePreview) = Animate(Preview, pause.Preview, playing.Preview, source.Token);
-                    (Task scaleCamera, Task moveCamera) = Animate(cameraView, pause.Camera, playing.Camera, source.Token);
+                    (Task scaleCamera, Task moveCamera) = Animate(cameraOverlayView, pause.Camera, playing.Camera, source.Token);
                     await Task.WhenAll(scalePreview, movePreview, scaleCamera, moveCamera);
 
                     PauseView.Hide();
@@ -142,7 +146,7 @@ namespace Fitness.Views
                     PauseView.Show();
 
                     (Task scalePreview, Task movePreview) = Animate(Preview, playing.Preview, pause.Preview, source.Token);
-                    (Task scaleCamera, Task moveCamera) = Animate(cameraView, playing.Camera, pause.Camera, source.Token);
+                    (Task scaleCamera, Task moveCamera) = Animate(cameraOverlayView, playing.Camera, pause.Camera, source.Token);
                     await Task.WhenAll(scalePreview, movePreview, scaleCamera, moveCamera);
                 }
 
@@ -189,14 +193,14 @@ namespace Fitness.Views
 
         private void SetPositionAndSize(bool isPlaying)
         {
-            cameraView.Size = playing.Camera.Size;
+            cameraOverlayView.Size = playing.Camera.Size;
             Preview.Size = playing.Preview.Size;
 
             if (isPlaying)
             {
-                cameraView.Position = playing.Camera.Position;
-                cameraView.ScaleX = 1;
-                cameraView.ScaleY = 1;
+                cameraOverlayView.Position = playing.Camera.Position;
+                cameraOverlayView.ScaleX = 1;
+                cameraOverlayView.ScaleY = 1;
                 Preview.Position = playing.Preview.Position;
                 Preview.ScaleX = 1;
                 Preview.ScaleY = 1;
@@ -207,10 +211,10 @@ namespace Fitness.Views
             else
             {
                 var cameraScale = pause.Camera.Size.Width / playing.Camera.Size.Width;
-                cameraView.Position = pause.Camera.Position;
-                cameraView.PivotPoint = new Position(0, 0);
-                cameraView.ScaleX = cameraScale;
-                cameraView.ScaleY = cameraScale;
+                cameraOverlayView.Position = pause.Camera.Position;
+                cameraOverlayView.PivotPoint = new Position(0, 0);
+                cameraOverlayView.ScaleX = cameraScale;
+                cameraOverlayView.ScaleY = cameraScale;
 
                 var previewScale = pause.Preview.Size.Width / playing.Preview.Size.Width;
                 Preview.Position = pause.Preview.Position;
@@ -223,10 +227,18 @@ namespace Fitness.Views
             }
         }
 
+        private void DetectPreview(object sender, PreviewEventArgs e)
+        {
+            if (BindingContext is ViewModels.ExercisingViewModel viewModel)
+            {
+                _ = viewModel.SquatService.DetectSquat(e.Preview);
+            }
+        }
+
         private struct Coordinates
         {
             public Position Position;
-            public Size Size;
+            public Tizen.NUI.Size Size;
             public float Scale;
         }
     }
index 7f7178a9fa0885e0d5914d8ae60177285c3a01ad..dcfd000478f650e50997cf0a2710ce99b5644317 100644 (file)
                        BindingContext="{Binding Source={x:Reference Root}, Path=BindingContext}"/>
     
     <!--Layer-->
-    
-    <ctrl:Camera x:Name="cameraView"
-                 PreviewFps="Fps30"
-                 PositionX="796"
-                 PositionY="152"
-                 SizeWidth="640"
-                 SizeHeight="480"/>
-    
+
+    <View x:Name="cameraOverlayView" PositionX="796" PositionY="152" SizeWidth="640" SizeHeight="480">
+        <ctrl:Camera x:Name="cameraView"
+                 WidthResizePolicy="FillToParent"
+                 HeightResizePolicy="FillToParent"
+                 PreviewFps="Fps30"/>
+        <ctrl:Overlay
+                 WidthResizePolicy="FillToParent"
+                 HeightResizePolicy="FillToParent"
+                 BindingContext="{Binding Source={x:Reference Root}, Path=BindingContext}"
+                 PoseLandmarks="{Binding SquatService.PoseLandmarks}">
+            <x:Arguments>
+                <Size2D>1124, 632</Size2D>
+            </x:Arguments>
+    </ctrl:Overlay>
+
+    </View>
+
     <!--Layer-->
     
     <VideoView x:Name="Preview"
index 2ed1b0a4b95ad9d862ca15d7db653b974ecc6b90..18c7789408676ce8c71459e5a4222da5b94e0614 100644 (file)
                 </View.Layout>
                 
                 <TextLabel BindingContext="{Binding Source={x:Reference Root}, Path=BindingContext}"
-                           Text="{Binding Hold, StringFormat='{0:ss}'}"
+                           Text="{Binding SquatService.Hold}"
                            TextColor="#000C2B"
                            PixelSize="40"
                            HorizontalAlignment="Center"
                            Size="{views:SizeInUnits Width=36, Height=16}"/>
                 
                 <TextLabel BindingContext="{Binding Source={x:Reference Root}, Path=BindingContext}"
-                           Text="{Binding Repetitions}"
+                           Text="{Binding SquatService.Count}"
                            TextColor="#000C2B"
                            PixelSize="40"
                            HorizontalAlignment="Center"
                            Size="{views:SizeInUnits Width=36, Height=16}"/>
                 
                 <TextLabel BindingContext="{Binding Source={x:Reference Root}, Path=BindingContext}"
-                           Text="{Binding Score}"
+                           Text="{Binding SquatService.Score}"
                            TextColor="#000C2B"
                            PixelSize="40"
                            HorizontalAlignment="Center"