Add a confirm dialog box before deleting an annotation by drag and drop. Now the UserControlClose is a generic confirm dialog box sending a ConfirmYesOrNo Event.
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
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;
using Microsoft.Surface.Presentation.Controls;
using System.Windows.Threading;
using FingersDance.Data;
using FingersDance.ViewModels;
using FingersDance.Views;
using FingersDance.Control.Close;
namespace FingersDance.Control.TimeLine
{
public partial class UserControlTimeLine
{
#region Variables
private DispatcherTimer timer;
private bool isDragging = false;
private bool finishedDragging = false;
#endregion
public event EventHandler DragStarted;
public event EventHandler DragCompleted;
public event EventHandler TimerTick;
private double totalmilliseconds;
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;
private AnnotationViewModel canceledAnnotationVM;
#region Properties
public SurfaceSlider Slider
{
get
{
return slider;
}
set
{
slider = value;
}
}
public bool IsDragging
{
get
{
return isDragging;
}
set
{
isDragging = value;
}
}
public bool FinishedDragging
{
get
{
return finishedDragging;
}
set
{
finishedDragging = value;
}
}
public DispatcherTimer Timer
{
get
{
return timer;
}
set
{
timer = value;
}
}
#endregion
public UserControlTimeLine()
{
this.InitializeComponent();
// Insert code required on object creation below this point.
}
public void initslider(double totalmillisecondsPar)
{
totalmilliseconds = totalmillisecondsPar;
slider.Maximum = totalmilliseconds;
// When the timeline is resized, we catch the resize event to define TimelineView's good scale
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(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;
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-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);
}
#region Timer
public void initTimer()
{
timer = new DispatcherTimer();
timer.Interval = new TimeSpan(0, 0, 0, 0, 100);
timer.Tick += new EventHandler(timer_Tick);
}
public void timerStart()
{
if (timer != null)
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
OnTimerTick();
if (!isDragging)
{
//slider.Value = media.Position.TotalMilliseconds;
}
if (finishedDragging)
{
//int SliderValue = (int)slider.Value;
//TimeSpan ts = new TimeSpan(0, 0, 0, 0, SliderValue);
// media.Position = ts;
// media.Play();
// isDragging = false;
//finishedDragging = false;
}
}
protected virtual void OnTimerTick()
{
if (TimerTick != null)
TimerTick(this, new EventArgs());
}
#endregion
private void sliderPosition_DragStarted(object sender, DragStartedEventArgs e)
{
isDragging = true;
OnDragStarted();
// media.Pause();
}
protected virtual void OnDragStarted()
{
if (DragStarted != null)
DragStarted(this, new EventArgs());
}
private void sliderPosition_DragCompleted(object sender, DragCompletedEventArgs e)
{
finishedDragging = true;
OnDragCompleted();
}
protected virtual void OnDragCompleted()
{
if (DragCompleted != null)
DragCompleted(this, new EventArgs());
}
private void slider_ContactTapGesture(object sender, Microsoft.Surface.Presentation.ContactEventArgs e)
{
//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(AnnotationViewModel avm)
{
//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)
{
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);
// We check if the annotation is well one of the current annotations
if (CuttingVM != null)
{
// e.Cursor.Visual is the ContentControl, so its Content is the dragged TimelineAnnotationView
canceledAnnotationVM = (AnnotationViewModel)((TimelineAnnotationView)((ContentControl)e.Cursor.Visual).Content).DataContext;
confirmCancelPopup.Visibility = Visibility.Visible;
}
}
private void confirmCancelPopup_ConfirmYesOrNo(object sender, ConfirmEventArgs e)
{
//Console.WriteLine("Confirm = " + e.Confirmed);
// We check if the annotation is well one of the current annotations
if (CuttingVM != null && canceledAnnotationVM != null && e.Confirmed == true)
{
foreach (Annotation a in AnnotList)
{
// Check begin TcBegin, duration and gesture type
if (a.TcBegin == canceledAnnotationVM.TcBegin && a.Dur == canceledAnnotationVM.Dur && a.GestureType == canceledAnnotationVM.GestureType)
{
// We found the good annotation so we can remove it
AnnotList.Remove(a);
// We redisplay the timeline
CuttingVM.setListFromAnnotations(AnnotList, AnnotWidth);
tv.DataContext = null;
tv.DataContext = CuttingVM;
// We close the popup and return as soon as we removed the annotation to avoid an error on AnnotList, which is just modified
confirmCancelPopup.Visibility = Visibility.Hidden;
canceledAnnotationVM = null;
return;
}
}
}
confirmCancelPopup.Visibility = Visibility.Hidden;
canceledAnnotationVM = null;
}
}
}