/** * PUBLIC METHODS **/ /// <summary> /// Adds a new picture element to the timeline (before the given element) /// </summary> /// <param name="startTime">the start time for the new element</param> /// <param name="endTime">the end time for the new element</param> /// <param name="thumbnail">The path to the picture (should be absolute)</param> /// <param name="transitionId">The ID of the transition which should be shown before the slide (-1 for no transition)</param> /// <param name="transitionExecutionTime">The time the transition should last (in ms). Parameter is ignored if the transition id is invalid</param> /// <param name="addBefore">The element id of the element which should be after the added element</param> public void AddPictureElement(double startTime, double endTime, string thumbnail, int transitionId, int transitionExecutionTime, int addBefore) { TimelinePictureElementControl element = new TimelinePictureElementControl(this, startTime, endTime, thumbnail); element.Transition = Transition.getByID(transitionId); if (element.Transition != null) { element.Transition.ExecutionTime = transitionExecutionTime; } if (addBefore > -1) { //Push All elements and add new element double pushAllTime = endTime - startTime; for (int i = addBefore; i < PictureElements.Count; i++) { PictureElements[i].StartTime += pushAllTime; PictureElements[i].EndTime += pushAllTime; } PictureElements.Insert(addBefore, element); Pack(); } else { PictureElements.Add(element); } if (MainCanvas.ActualWidth < GetLastPictureElementEndtime()) { MainCanvas.Width = GetLastPictureElementEndtime() + 100; MainScrollbar.ScrollToRightEnd(); } UpdateExportButton(); }
/// <summary> /// Adds a new picture element to the timeline (before the given element) /// </summary> /// <param name="insertImgPath">The path to the picture (should be absolute)</param> /// <param name="successor">THe element of the successor picture</param> public void AddPictureElement(string insertImgPath, TimelinePictureElementControl successor) { double newEndTime = successor.StartTime; double newStartTime = newEndTime - 200; AddPictureElement(newStartTime, newEndTime, insertImgPath, -1, 0, PictureElements.IndexOf(successor)); }
/// <summary> /// Event for start of resizing, moving and markingof elements /// </summary> /// <param name="sender">event sender</param> /// <param name="e">event args</param> private void MainCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Point p = Mouse.GetPosition(MainCanvas); double x = p.X; double y = p.Y; if (isBetweenPictureElementsOrAtEnd(x, y)) { _resizing = GetPictureElementAt(x - 15, y); } else if (GetPictureElementAt(x, y) != null) { if (Marked != null) { Marked.PictureBorder.Background = FindResource("SC_BG_COLOR_BRIGHT") as SolidColorBrush; } Marked = GetPictureElementAt(x, y); Marked.PictureBorder.Background = FindResource("SC_BG_COLOR_MEDIUM") as SolidColorBrush; Marked.Select(); _mayMove = true; _movingOffset = x - GetPictureElementAt(x, y).StartTime; } //else if (isAtMusicElement(x, y) != null) //{ // TimelineMusicElementControl ElementSelect = isAtMusicElement(x, y); // ElementSelect.MovingMusicElement((int)Math.Round(x)); //} else { MoveMarker((int)Math.Round(x)); } }
/// <summary> /// Returns if the given picture element is currently in the visible rendered viewport (used for RAM-savings) /// </summary> /// <param name="element">The picture element to check if it is currently visible</param> /// <returns>the visibility state</returns> private bool isVisible(TimelinePictureElementControl element) { if (element.EndTime > MainScrollbar.HorizontalOffset && element.StartTime < MainScrollbar.HorizontalOffset + MainScrollbar.ActualWidth) { return(true); } return(false); }
/// <summary> /// Returns the latest picture element endtime /// </summary> /// <returns>latest picture element endtime</returns> private double GetLastPictureElementEndtime() { if (PictureElements.Count > 0) { TimelinePictureElementControl last = PictureElements[PictureElements.Count - 1]; return(last.EndTime); } return(0); }
/// <summary> /// Moved the marker to the given x-Coordinate /// </summary> /// <param name="x">The coordinate the marker should move to</param> private void MoveMarker(int x) { Canvas.SetLeft(tlMarker, Math.Max(x - 5, -5)); TimelinePictureElementControl elementAtMarker = GetPictureElementAtMarker(); if (elementAtMarker == null) { return; } UpdatePreview(); }
/// <summary> /// Removes a picture element and re-pack all following elements /// </summary> /// <param name="element">The element which should be removed</param> public void RemovePictureElement(TimelinePictureElementControl element) { if (!PictureElements.Contains(element)) { return; } PictureElements.Remove(element); Pack(); UpdateDrawings(); UpdateExportButton(); }
/// <summary> /// Adds an empty slide (blank, black) at the end /// </summary> public void AddEmptySlide() { TimelinePictureElementControl element = new TimelinePictureElementControl(this, GetLastPictureElementEndtime(), GetLastPictureElementEndtime() + 200, null); PictureElements.Add(element); if (MainCanvas.ActualWidth < GetLastPictureElementEndtime()) { MainCanvas.Width = GetLastPictureElementEndtime() + 100; MainScrollbar.ScrollToRightEnd(); } }
/// <summary> /// Returns true if the given coordinates are currently between two picture elements or at the ending element (used for resizing) /// </summary> /// <param name="x">The given x-Coordinate (typically the mouse cursor)</param> /// <param name="y">The given y-Coordinate (typically the mouse cursor)</param> /// <returns>the visibility state</returns> private bool isBetweenPictureElementsOrAtEnd(double x, double y) { bool between = isBetweenPictureElements(x, y); bool end = false; if (PictureElements.Count > 0) { TimelinePictureElementControl last = PictureElements[PictureElements.Count - 1]; end = x >= last.EndTime - 6 && x <= last.EndTime + 6 && y > last.TopSpacing && y <= last.TopSpacing + last.ElementHeight; } return(between || end); }
/// <summary> /// Returns true if the given coordinates are currently between two picture elements (used for resizing) /// </summary> /// <param name="x">The given x-Coordinate (typically the mouse cursor)</param> /// <param name="y">The given y-Coordinate (typically the mouse cursor)</param> /// <returns>the visibility state</returns> private bool isBetweenPictureElements(double x, double y) { for (int i = 0; i < PictureElements.Count; i++) { TimelinePictureElementControl element = PictureElements[i]; if (x >= element.StartTime - 6 && x <= element.StartTime + 6 && y > element.TopSpacing && y <= element.TopSpacing + element.ElementHeight) { return(true); } } return(false); }
/// <summary> /// Cancel all actions: Moving, Resizing. And re-pack all picture elements /// </summary> private void cancelAllActions() { if (_mayMove == true) { Marked.Grabbed = false; Pack(); } _resizing = null; _mayMove = false; Mouse.OverrideCursor = null; MainCanvas.Width = ActualWidth > GetLastPictureElementEndtime() + 100 ? ActualWidth : GetLastPictureElementEndtime() + 100; Pack(); UpdateDrawings(); }
/// <summary> /// Returns the TimelinePictureElement at given coordinates. /// Returns null, if no element is present at the given coordinates /// </summary> /// <param name="x">The given x-Coordinate</param> /// <param name="y">The given y-Coordinate (-1 to disable y check)</param> /// <returns></returns> private TimelinePictureElementControl GetPictureElementAt(double x, double y) { TimelinePictureElementControl fittingElement = null; foreach (TimelinePictureElementControl element in PictureElements) { if (x >= element.StartTime && x <= element.EndTime && (y == -1 || (y > element.TopSpacing && y <= element.TopSpacing + element.ElementHeight))) { fittingElement = element; break; } } return(fittingElement); }
/// <summary> /// Returns the picture element at the marker /// </summary> /// <returns>the picture element at the marker</returns> private TimelinePictureElementControl GetPictureElementAtMarker() { int left = (int)Math.Round(Canvas.GetLeft(tlMarker)) + 5; TimelinePictureElementControl fittingElement = null; foreach (TimelinePictureElementControl element in PictureElements) { if (left >= element.StartTime && left <= element.EndTime) { fittingElement = element; break; } } return(fittingElement); }
/// <summary> /// Prevent overlapping picture elements and gaps between picture elements /// </summary> public void Pack() { if (PictureElements.Count < 1) { return; } TimelinePictureElementControl lastElement = null; foreach (TimelinePictureElementControl element in PictureElements) { double alltime = element.EndTime - element.StartTime; element.StartTime = lastElement == null ? 0 : lastElement.EndTime; element.EndTime = element.StartTime + alltime; element.Update(); lastElement = element; } }
/// <summary> /// Pack following elements to fit without gaps and overlaps /// </summary> public void PackFollowing() { Update(); TimelinePictureElementControl lastElement = this; foreach (TimelinePictureElementControl element in timeline.PictureElements) { if (element.StartTime > StartTime) { double alltime = element.EndTime - element.StartTime; element.StartTime = lastElement.EndTime; element.EndTime = element.StartTime + alltime; element.Update(); lastElement = element; } } }
/// <summary> /// Moving, resizing elements and moving the cursor event /// </summary> /// <param name="sender">event sender</param> /// <param name="e">event args</param> private void MainCanvas_MouseMove(object sender, MouseEventArgs e) { Point p = Mouse.GetPosition(MainCanvas); double x = p.X; double y = p.Y; //change cursor to corresponding: resize, move elemenent if (_mayMove == false && (isBetweenPictureElementsOrAtEnd(x, y) || _resizing != null)) { Mouse.OverrideCursor = Cursors.SizeWE; } else if (_mayMove == false) { Mouse.OverrideCursor = Cursors.Arrow; _resizing = null; } //resize element if (_resizing != null) { if (_resizing.EndTime == GetLastPictureElementEndtime()) { MainCanvas.Width = ActualWidth > _resizing.EndTime + 100 ? ActualWidth : _resizing.EndTime + 100; } _resizing.ResizeAndPush(x); UpdateDrawings(); return; } //move element if (_mayMove == true) { Mouse.OverrideCursor = ((TextBlock)Resources["CursorGrabbing"]).Cursor; Marked.MoveAndSwap(x, _movingOffset); Marked.Grabbed = true; return; } //move marker if (e.LeftButton.HasFlag(MouseButtonState.Pressed)) { MoveMarker((int)Math.Round(x)); } }
/// <summary> /// The drag and drop implementation for the elements /// </summary> /// <param name="sender">event sender</param> /// <param name="e">event args</param> private void UserControl_Drop(object sender, DragEventArgs e) { string imgPath = e.Data.GetData(typeof(string)) as string; Point p = e.GetPosition(MainCanvas); double x = p.X; if (imgPath == null || !File.Exists(imgPath)) { return; } TimelinePictureElementControl targetElement = GetPictureElementAt(x, -1); if (targetElement != null) { AddPictureElement(imgPath, targetElement); } else { AddPictureElement(imgPath); } }