/// <summary>
        /// Handle thumb drag
        /// </summary>
        private void MoveThumbDragDelta(object sender, DragDeltaEventArgs e)
        {
            // dragging content - question or bubble
            DependencyObject content;

            // find dragging content - layout different for question and bubbles
            Adorner adorner = VisualTreeHelper.GetParent(this) as Adorner;

            if (adorner != null)
            {
                content = adorner.AdornedElement;
            }
            else
            {
                var grid = VisualTreeHelper.GetParent(this);
                content = VisualTreeHelper.GetParent(grid);
            }

            // presenter that holds omr item
            ContentPresenter presenter = (ContentPresenter)VisualTreeHelper.GetParent(content);

            // parent canvas
            CustomCanvas canvas = (CustomCanvas)VisualTreeHelper.GetParent(presenter);

            // get all selected elements
            List <ContentPresenter> presenters = ControlHelper.GetSelectedChildPresenters(canvas);

            double deltaHorizontal = e.HorizontalChange;
            double deltaVertical   = e.VerticalChange;

            // check out of bounds for each item
            for (int i = 0; i < presenters.Count; i++)
            {
                if (Canvas.GetLeft(presenters[i]) + deltaHorizontal > canvas.ActualWidth - presenters[i].ActualWidth - BorderThreshold
                    ||
                    Canvas.GetLeft(presenters[i]) + deltaHorizontal < BorderThreshold)
                {
                    deltaHorizontal = 0;
                }

                if (Canvas.GetTop(presenters[i]) + deltaVertical > canvas.ActualHeight - presenters[i].ActualHeight - BorderThreshold
                    ||
                    Canvas.GetTop(presenters[i]) + deltaVertical < BorderThreshold)
                {
                    deltaVertical = 0;
                }
            }

            // apply change for each item
            for (int i = 0; i < presenters.Count; i++)
            {
                Canvas.SetLeft(presenters[i], Canvas.GetLeft(presenters[i]) + deltaHorizontal);
                Canvas.SetTop(presenters[i], Canvas.GetTop(presenters[i]) + deltaVertical);
            }

            // canvas.InvalidateMeasure();
            e.Handled = true;
        }
Exemple #2
0
        /// <summary>
        /// Occurs as the mouse changes position when a Thumb control has logical focus and mouse capture
        /// </summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The event args</param>
        private void ResizeDragDelta(object sender, DragDeltaEventArgs e)
        {
            // get to resized element
            Grid        thumbsGrid  = (Grid)VisualTreeHelper.GetParent(this);
            ResizeThumb parentThumb = (ResizeThumb)VisualTreeHelper.GetParent(thumbsGrid);
            Adorner     adorner     = (Adorner)VisualTreeHelper.GetParent(parentThumb);

            // presenter that holds dragged item
            ContentPresenter presenter = (ContentPresenter)VisualTreeHelper.GetParent(adorner.AdornedElement);

            // parent canvas
            CustomCanvas canvas = (CustomCanvas)VisualTreeHelper.GetParent(presenter);

            // prepare items for resize depending on item level (question or bubble)
            List <ContentPresenter> presenters;

            if (canvas.Name.Equals(Properties.Resources.RootCanvasName))
            {
                // here we resize questions (e.g. choicebox), so take selected items
                presenters = ControlHelper.GetSelectedChildPresenters(canvas);
            }
            else
            {
                // here we resize bubbles, so get neighbor bubbles inside question (always resize bubbles equally)
                presenters = ControlHelper.GetChildPresenters(canvas);
            }

            double minLeft, minTop, minDeltaHorizontal, minDeltaVertical;
            double maxDeltaVertical, maxDeltaHorizontal;

            double maxHorizontalDeltaToChild = double.MaxValue;
            double maxVerticalDeltaToChild   = double.MaxValue;

            this.CalculateLimits(canvas, presenters, out minLeft, out minTop, out minDeltaHorizontal, out minDeltaVertical,
                                 out maxDeltaHorizontal, out maxDeltaVertical);

            minDeltaVertical   = Math.Min(minDeltaVertical, maxVerticalDeltaToChild);
            minDeltaHorizontal = Math.Min(minDeltaHorizontal, maxHorizontalDeltaToChild);

            foreach (ContentPresenter element in presenters)
            {
                double newHeight = element.ActualHeight;
                double newWidth  = element.ActualWidth;

                double newTop  = Canvas.GetTop(element);
                double newLeft = Canvas.GetLeft(element);

                double scale, dragDeltaVertical;
                switch (this.VerticalAlignment)
                {
                case VerticalAlignment.Bottom:
                    dragDeltaVertical = Math.Max(Math.Min(-e.VerticalChange, minDeltaVertical), -maxDeltaVertical);
                    newHeight         = element.ActualHeight - dragDeltaVertical;
                    break;

                case VerticalAlignment.Top:
                    dragDeltaVertical = Math.Min(Math.Max(-minTop, e.VerticalChange), minDeltaVertical);
                    scale             = (element.ActualHeight - dragDeltaVertical) / element.ActualHeight;

                    newTop    = newTop - element.Height * (scale - 1);
                    newHeight = element.ActualHeight - dragDeltaVertical;
                    break;
                }

                double dragDeltaHorizontal;
                switch (this.HorizontalAlignment)
                {
                case HorizontalAlignment.Left:
                    dragDeltaHorizontal = Math.Min(Math.Max(-minLeft, e.HorizontalChange), minDeltaHorizontal);
                    scale = (element.ActualWidth - dragDeltaHorizontal) / element.ActualWidth;

                    newLeft  = Canvas.GetLeft(element) - element.Width * (scale - 1);
                    newWidth = element.ActualWidth * scale;
                    break;

                case HorizontalAlignment.Right:
                    dragDeltaHorizontal = Math.Max(Math.Min(-e.HorizontalChange, minDeltaHorizontal), -maxDeltaHorizontal);
                    newWidth            = element.ActualWidth - dragDeltaHorizontal;
                    break;
                }

                var childs = this.GetChildElements(element);
                if (childs == null)
                {
                    element.Width  = newWidth;
                    element.Height = newHeight;
                    Canvas.SetTop(element, newTop);
                    Canvas.SetLeft(element, newLeft);
                }
                else
                {
                    double scaleH = newHeight / element.ActualHeight;
                    double scaleW = newWidth / element.ActualWidth;

                    if (this.CanTransformChildsRecursive(childs, scaleH, scaleW))
                    {
                        this.TransformChildsRecursive(childs, scaleH, scaleW);

                        element.Width  = newWidth;
                        element.Height = newHeight;
                        Canvas.SetTop(element, newTop);
                        Canvas.SetLeft(element, newLeft);
                    }
                }
            }

            e.Handled = true;
        }