src/FingersDance.Control.TimeLine/UserControlTimeLine.xaml.cs
changeset 143 9f157d9c725b
parent 124 14b058fc64fc
child 146 dd8ed4d3beb6
--- a/src/FingersDance.Control.TimeLine/UserControlTimeLine.xaml.cs	Tue Oct 13 19:09:46 2009 +0200
+++ b/src/FingersDance.Control.TimeLine/UserControlTimeLine.xaml.cs	Tue Oct 13 19:33:13 2009 +0200
@@ -5,15 +5,18 @@
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Data;
+using System.Windows.Input;
 using System.Windows.Media;
 using System.Windows.Media.Animation;
 using System.Windows.Navigation;
 using System.Windows.Controls.Primitives;
 using Microsoft.Surface.Presentation.Controls;
+using Microsoft.Surface.Presentation;
 using System.Windows.Threading;
 
 using FingersDance.Data;
 using FingersDance.ViewModels;
+using FingersDance.Views;
 
 namespace FingersDance.Control.TimeLine
 {
@@ -32,9 +35,11 @@
 
         private double totalmilliseconds;
 
-        private List<Annotation> annotList = new List<Annotation>();
-        private float annotWidth = 40+1;
-        private CuttingViewModel cutvm;
+        private List<Annotation> AnnotList = new List<Annotation>();
+        private float AnnotWidth = 300 + 15; // The surfaceListBox adds 15 pixels between each item
+        private CuttingViewModel CuttingVM;
+        private Boolean AnnotWaiting = false;
+        private float AnnotTcBegin;
 
         #region Properties
 
@@ -91,7 +96,7 @@
 
         
 		public UserControlTimeLine()
-		{   
+		{
 			this.InitializeComponent();
 
 			// Insert code required on object creation below this point.
@@ -106,31 +111,33 @@
             this.SizeChanged += new SizeChangedEventHandler(UserControlTimeLine_SizeChanged);
 
             // TEMP FOR DATA BINDING
-            annotList = new List<Annotation>();
-            annotList.Add(new Annotation(0, 10, "Axe Cam 1"));
-            //annotList.Add(new Annotation(20 - (1 * annotWidth), 30, "Mvt Cam 2"));
-            //annotList.Add(new Annotation(50 - (2 * annotWidth), 60, "Saut 3"));
-            //annotList.Add(new Annotation(100 - (3 * annotWidth), 20, "Saut 4"));
-            //annotList.Add(new Annotation(120 - (4 * annotWidth), 50, "Saut 5"));
-            Cutting cut = new Cutting("titre de cutting", annotList);
-            cutvm = new CuttingViewModel(cut);
-            tv.DataContext = cutvm;
+            AnnotList = new List<Annotation>();
+            AnnotList.Add(new Annotation(0, 10, "Axe Cam 1"));
+            //AnnotList.Add(new Annotation(100 - (1 * AnnotWidth), 70, "Mvt Cam 2"));
+            //AnnotList.Add(new Annotation(200 - (2 * AnnotWidth), 50, "Saut 3"));
+            //AnnotList.Add(new Annotation(100 - (3 * AnnotWidth), 20, "Saut 4"));
+            //AnnotList.Add(new Annotation(120 - (4 * AnnotWidth), 50, "Saut 5"));
+            Cutting cut = new Cutting("titre de cutting", AnnotList);
+            CuttingVM = new CuttingViewModel(cut, AnnotWidth);
+            tv.DataContext = CuttingVM;
 
-            slider_ContactTapGesture(this,null);
-            /*
-            cutvm.AnnotList.Add(new AnnotationViewModel(new Annotation(180 - (5 * annotWidth), 10, "6")));
-            tv.DataContext = null;
-            tv.DataContext = cutvm;
-            */
+            tv.listview.PreviewContactDown += listview_PreviewContactDown;
+            SurfaceDragDrop.AddDragCanceledHandler(tv.listview, onDragCanceled);
+
+            UserControlTimeLine_SizeChanged(null, null);
+
+            slider_ContactTapGesture(this, null);
+            
+
         }
 
         void UserControlTimeLine_SizeChanged(object sender, SizeChangedEventArgs e)
         {
             // When scaleX = 1, 1 second = 1 pixel. To calculate the new scale, we take the real width in account.
-            Double futurScale = this.ActualWidth / (totalmilliseconds / 1000);
-            //Double futurScale = this.ActualWidth / ((totalmilliseconds<30000) ? (totalmilliseconds/10) : (totalmilliseconds / 1000)); // TEMP
+            Double futurScale = (this.ActualWidth-30) / (totalmilliseconds / 1000);
+            //Double futurScale = this.ActualWidth / ((totalmilliseconds<30000) ? (totalmilliseconds/10) : (totalmilliseconds / 1000)); // TEMP FOR SHORT CONTENTS
             tv.RenderTransform = new ScaleTransform(futurScale,1);
-            Console.WriteLine("futurScale = " + futurScale);
+            //Console.WriteLine("futurScale = " + futurScale);
             
         }
 
@@ -172,8 +179,7 @@
 
         #endregion
 
-        private void sliderPosition_DragStarted(
-            object sender, DragStartedEventArgs e)
+        private void sliderPosition_DragStarted(object sender, DragStartedEventArgs e)
         {
             isDragging = true;
             OnDragStarted();
@@ -185,8 +191,7 @@
                 DragStarted(this, new EventArgs());
         }
 
-        private void sliderPosition_DragCompleted(
-            object sender, DragCompletedEventArgs e)
+        private void sliderPosition_DragCompleted(object sender, DragCompletedEventArgs e)
         {
             finishedDragging = true;
             OnDragCompleted();
@@ -199,20 +204,227 @@
 
         private void slider_ContactTapGesture(object sender, Microsoft.Surface.Presentation.ContactEventArgs e)
         {
-            //addAnnotation();
+            //startOrEndAnnotation();
+        }
+
+        public Boolean isAnnotationAccepted(AnnotationViewModel avm)
+        {
+            Boolean annotOk = true;
+            // We check if the annotation's begin and end timecodes allow a new annotation creation
+            if (CuttingVM != null && AnnotWaiting == false)
+            {
+                foreach (Annotation a in AnnotList)
+                {
+                    //Console.WriteLine("a.TcBegin = " + a.TcBegin + ", avm.TcBegin = " + avm.TcBegin + ", tcOut = " + (a.TcBegin + a.Dur));
+                    // Check begin TC
+                    if (a.TcBegin <= avm.TcBegin && avm.TcBegin <= (a.TcBegin + a.Dur))
+                    {
+                        annotOk = false;
+                    }
+                    // Check end tc and if the new annotation will not cover any other
+                    float endTC = avm.TcBegin + avm.Dur;
+                    //Console.WriteLine("a.TcBegin = " + a.TcBegin + ", tcOut = " + (a.TcBegin + a.Dur) + ", AnnotTcBegin = " + AnnotTcBegin + ", currentTC = " + currentTC);
+                    if (a.TcBegin <= endTC && endTC <= (a.TcBegin + a.Dur) || (avm.TcBegin < a.TcBegin && (a.TcBegin + a.Dur) < endTC))
+                    {
+                        annotOk = false;
+                    }
+                }
+            }
+            else
+            {
+                annotOk = false;
+            }
+            return annotOk;
+
         }
 
-        public void addAnnotation()
+        public void addAnnotation(AnnotationViewModel avm)
         {
-            if (cutvm!=null)
+            //Console.WriteLine("addAnnotation = " + avm.TcBegin + ", " + avm.Dur + ", " + avm.GestureType);
+            Boolean annotOk = true;
+            // We check if the annotation's begin and end timecodes allow a new annotation creation
+            if (CuttingVM != null && AnnotWaiting == false)
+            {
+                foreach (Annotation a in AnnotList)
+                {
+                    //Console.WriteLine("a.TcBegin = " + a.TcBegin + ", avm.TcBegin = " + avm.TcBegin + ", tcOut = " + (a.TcBegin + a.Dur));
+                    // Check begin TC
+                    if (a.TcBegin <= avm.TcBegin && avm.TcBegin <= (a.TcBegin + a.Dur))
+                    {
+                        annotOk = false;
+                    }
+                    // Check end tc and if the new annotation will not cover any other
+                    float endTC = avm.TcBegin + avm.Dur;
+                    //Console.WriteLine("a.TcBegin = " + a.TcBegin + ", tcOut = " + (a.TcBegin + a.Dur) + ", AnnotTcBegin = " + AnnotTcBegin + ", currentTC = " + currentTC);
+                    if (a.TcBegin <= endTC && endTC <= (a.TcBegin + a.Dur) || (avm.TcBegin < a.TcBegin && (a.TcBegin + a.Dur) < endTC))
+                    {
+                        annotOk = false;
+                    }
+                }
+                // If everything's fine, we create the new one
+                if (annotOk == true)
+                {
+                    AnnotList.Add(new Annotation(avm.TcBegin, avm.Dur, avm.GestureType));
+                    CuttingVM.setListFromAnnotations(AnnotList, AnnotWidth);
+                    tv.DataContext = null;
+                    tv.DataContext = CuttingVM;
+                    AnnotWaiting = false;
+                }
+
+            }
+
+        }
+
+        public void startOrEndAnnotation()
+        {
+            Boolean annotOk = true;
+            // We open a new annotation
+            if (CuttingVM != null && AnnotWaiting == false)
             {
-                float currentTimecode = (float)slider.Value / 1000;
-                cutvm.AnnotList.Add(new AnnotationViewModel(new Annotation(currentTimecode - (cutvm.AnnotList.Count * annotWidth), 10, cutvm.AnnotList.Count.ToString())));
-                Console.WriteLine("currentTimecode = " + currentTimecode + ", nb = " + cutvm.AnnotList.Count + ", res = " + (currentTimecode - (cutvm.AnnotList.Count * annotWidth)));
-                tv.DataContext = null;
-                tv.DataContext = cutvm;
+                AnnotTcBegin = (float)slider.Value / 1000;
+
+                // First we check if the new annotation will not cover any
+                foreach (Annotation a in AnnotList)
+                {
+                    //Console.WriteLine("a.TcBegin = " + a.TcBegin + ", AnnotTcBegin = " + AnnotTcBegin + ", tcOut = " + (a.TcBegin + a.Dur));
+                    if (a.TcBegin <= AnnotTcBegin && AnnotTcBegin <= (a.TcBegin + a.Dur))
+                    {
+                        annotOk = false;
+                    }
+                }
+                // if not, we mark the beginning
+                if (annotOk == true)
+                {
+                    AnnotList.Add(new Annotation(AnnotTcBegin, 0, AnnotList.Count.ToString()));
+                    CuttingVM.setListFromAnnotations(AnnotList, AnnotWidth);
+                    //Console.WriteLine("BEGIN currentTimecode = " + AnnotTcBegin + ", nb = " + AnnotList.Count + ", res = " + (AnnotTcBegin - (AnnotList.Count * AnnotWidth)));
+                    tv.DataContext = null;
+                    tv.DataContext = CuttingVM;
+                    AnnotWaiting = true;
+                }
+            }
+            // We close the current opened annotation...
+            else if (CuttingVM != null && AnnotWaiting == true && (((float)slider.Value/1000)>AnnotTcBegin))
+            {
+                // ... by setting setting the good beginning and the good duration
+                float currentTC = (float)slider.Value / 1000;
+                float currentDuration = currentTC - AnnotTcBegin;
+
+                // First we check if the new annotation will not cover any (AnnotTcBegin was already checked)
+                foreach (Annotation a in AnnotList)
+                {
+                    //Console.WriteLine("a.TcBegin = " + a.TcBegin + ", tcOut = " + (a.TcBegin + a.Dur) + ", AnnotTcBegin = " + AnnotTcBegin + ", currentTC = " + currentTC);
+                    if (a.TcBegin <= currentTC && currentTC <= (a.TcBegin + a.Dur) || (AnnotTcBegin < a.TcBegin && (a.TcBegin + a.Dur) < currentTC))
+                    {
+                        annotOk = false;
+                    }
+                }
+
+                if (annotOk == true)
+                {
+                    AnnotList.RemoveAt(AnnotList.Count - 1);
+                    AnnotList.Add(new Annotation(AnnotTcBegin, currentDuration, AnnotList.Count.ToString()));
+                    CuttingVM.setListFromAnnotations(AnnotList, AnnotWidth);
+                    //Console.WriteLine("currentTimecode = " + AnnotTcBegin + ", curDur = " + currentDuration + ", nb = " + AnnotList.Count + ", res = " + (AnnotTcBegin - (AnnotList.Count * AnnotWidth)));
+                    tv.DataContext = null;
+                    tv.DataContext = CuttingVM;
+                    AnnotWaiting = false;
+                }
             }
         }
 
+
+        private void listview_PreviewContactDown(object sender, Microsoft.Surface.Presentation.ContactEventArgs e)
+        {
+            FrameworkElement findSource = e.OriginalSource as FrameworkElement;
+            SurfaceListBoxItem draggedElement = null;
+
+            // Find the touched SurfaceListBoxItem object.
+            while (draggedElement == null && findSource != null)
+            {
+                if ((draggedElement = findSource as SurfaceListBoxItem) == null)
+                {
+                    findSource = VisualTreeHelper.GetParent(findSource) as FrameworkElement;
+                }
+            }
+
+            if (draggedElement == null)
+            {
+                return;
+            }
+
+            // Create the cursor visual.
+            ContentControl cursorVisual = new ContentControl()
+            {
+                Content = new TimelineAnnotationView()
+                {
+                    DataContext = findSource.DataContext
+                }
+            };
+
+            // We apply the current scale to the dragged annotation
+            ((TimelineAnnotationView)cursorVisual.Content).RenderTransform = this.RenderTransform;
+
+            // Add a handler. This will enable the application to change the visual cues. (NOT USEFUL IN FINGERSDANCE CASE)
+            //SurfaceDragDrop.AddTargetChangedHandler(cursorVisual, OnTargetChanged);
+
+            // Create a list of input devices. Add the contacts that
+            // are currently captured within the dragged element and
+            // the current contact (if it isn't already in the list).
+            List<InputDevice> devices = new List<InputDevice>();
+            devices.Add(e.Contact);
+            foreach (Contact contact in draggedElement.ContactsCapturedWithin)
+            {
+                if (contact != e.Contact)
+                {
+                    devices.Add(contact);
+                }
+            }
+
+            // Get the drag source object
+            ItemsControl dragSource = ItemsControl.ItemsControlFromItemContainer(draggedElement);
+
+            bool startDragOkay =
+                SurfaceDragDrop.BeginDragDrop(
+                  dragSource,                 // The SurfaceListBox object that the cursor is dragged out from.
+                  draggedElement,             // The SurfaceListBoxItem object that is dragged from the drag source.
+                  cursorVisual,               // The visual element of the cursor.
+                  draggedElement.DataContext, // The data associated with the cursor.
+                  devices,                    // The input devices that start dragging the cursor.
+                  DragDropEffects.Move);      // The allowed drag-and-drop effects of the operation.
+
+            // If the drag began successfully, set e.Handled to true. 
+            // Otherwise SurfaceListBoxItem captures the contact 
+            // and causes the drag operation to fail.
+            e.Handled = startDragOkay;
+        }
+
+        private void onDragCanceled(Object sender, SurfaceDragDropEventArgs e)
+        {
+            Console.WriteLine("onDragCanceled = " + sender + ", ((ContentControl)e.Cursor.Visual).Content = " + ((ContentControl)e.Cursor.Visual).Content);
+            // e.Cursor.Visual is the ContentControl, so its Content is the dragged TimelineAnnotationView
+            AnnotationViewModel annotationDataVM = (AnnotationViewModel)((TimelineAnnotationView)((ContentControl)e.Cursor.Visual).Content).DataContext;
+            // We check if the annotation is well one of the current annotations
+            if (CuttingVM != null)
+            {
+                foreach (Annotation a in AnnotList)
+                {
+                    //Console.WriteLine("a.TcBegin = " + a.TcBegin + ", avm.TcBegin = " + avm.TcBegin + ", tcOut = " + (a.TcBegin + a.Dur));
+                    // Check begin TC
+                    if (a.TcBegin == annotationDataVM.TcBegin && a.Dur == annotationDataVM.Dur && a.GestureType==annotationDataVM.GestureType)
+                    {
+                        // We found the good annotation so we can delete it
+                        AnnotList.Remove(a);
+                        // We redisplay the timeline
+                        CuttingVM.setListFromAnnotations(AnnotList, AnnotWidth);
+                        tv.DataContext = null;
+                        tv.DataContext = CuttingVM;
+                        return;
+                    }
+                }
+            }
+        }
+
+
 	}
 }
\ No newline at end of file