public SketchView(SketchViewModel viewModel, UiState uiState, IEventAggregator eventAggregator, IUnityContainer container, ISnapper snapper, ILoggerFacade logger = null)
            : this()
        {
            this.logger = logger ?? new EmptyLogger();

            DataContext = viewModel;
            viewModel.PropertyChanged  += OnViewModelPropertyChanged;
            this.viewModel              = viewModel;
            this.duplicateEditorFactory = new DuplicateEditorFactory(this);
            this.snapper = snapper;

            sketchModellingView =
                container.Resolve <SketchModellingView>(
                    new DependencyOverride <SketchModellingViewModel>(viewModel.SketchModellingViewModel));
            root3d.Children.Add(sketchModellingView);

            sketchImageView =
                container.Resolve <SketchImageView>(
                    new DependencyOverride <SketchImageViewModel>(viewModel.SketchImageViewModel));
            Grid.SetRow(sketchImageView, 2);
            sketchImageView.Margin = vpRoot.Margin;
            root.Children.Insert(2, sketchImageView);

            newPrimitiveDragStrategy = new PrimitiveDragStrategy(uiState, sketchModellingView, snapper);
            snappedDragStrategy      = new SnappedDragStrategy(uiState, duplicateEditorFactory.Create(), eventAggregator);
            curveDragStrategy        = new CurveDragStrategy(uiState, sketchImageView, selectionRectangle);
            assignDragStrategy       = new AssignDragStrategy(uiState, primitiveCurvesRoot, sketchImageView, eventAggregator);

            eventAggregator.GetEvent <PrimitiveCurvesChangedEvent>().Subscribe(OnPrimitiveCurvesChanged);
        }
 private void vpRoot_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
 {
     if (currentDragStrategy == curveDragStrategy || currentDragStrategy == assignDragStrategy)
     {
         currentDragStrategy.OnMouseUp(GetPosition3D(e));
         currentDragStrategy = null;
         vpRoot.ReleaseMouseCapture();
     }
 }
        private void primitivesPalette_MouseMove(object sender, MouseEventArgs e)
        {
            Debug.WriteLine("Primitives pallette mouse move");
            if (paletteElement == null) // this means that the user has not started dragging an element from the palette
            {
                return;
            }

            if (currentDragStrategy != null) // we are currently doing something else (for example, dragging a primitive over the sketch)
            {
                return;                      // we don't want to do anything while doing something else with the mouse.. surely not to add a new primitive.
            }
            Debug.WriteLine("Current drag strategy is null");

            var isMouseOverViewportRoot = IsMouseOverViewportRoot(e);

            // we will add a primitive and transfer the "responsibility" to the primitive drag strategy
            // so that from now on it handles mouse events
            if (isMouseOverViewportRoot)
            {
                Debug.WriteLine("Mouse is over viewport root");

                var pos3d = GetPosition3D(e);
                if (pos3d.Ray3D == null)
                {
                    return;
                }

                Debug.WriteLine("Successfully got a ray");

                // we add a new primitive and pick its visual so that we can later give it to the drag strategy
                var newPrimitive = viewModel.AddNewPrimitive(palettePrimitiveKind, pos3d.Ray3D.Value);

                Debug.WriteLine("Successfully locked on the primitive visual");

                viewModel.SelectPrimitive(newPrimitive);

                var primitiveVisual =
                    (from view in sketchModellingView.GetNewPrimitiveViews()
                     let primitiveData = PrimitivesPickService.GetPrimitiveData(view)
                                         where object.ReferenceEquals(primitiveData, newPrimitive)
                                         select view).First();

                // we make the current mouse drag strategy to be the strategy for "new primitive" objects. This strategy
                // will be used from now on until the primitive is snapped.
                currentDragStrategy = newPrimitiveDragStrategy;
                currentDragStrategy.OnMouseDown(GetPosition3D(e), Tuple.Create(primitiveVisual, newPrimitive));

                // we transfer the responsibility of capturing subsequent mouse events to the vpRoot
                paletteElement.ReleaseMouseCapture();
                vpRoot.CaptureMouse();
                paletteElement = null;
            }
        }
        private void vpRoot_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (currentDragStrategy != null)
            {
                vpRoot.ReleaseMouseCapture();

                currentDragStrategy.OnMouseUp(GetPosition3D(e));
                currentDragStrategy = null;

                viewModel.SnapPrimitive();
            }
        }
 private void vpRoot_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
 {
     if (currentDragStrategy == null)
     {
         if (assignDragStrategy.IsReadyToAssign)
         {
             currentDragStrategy = assignDragStrategy;
         }
         else
         {
             currentDragStrategy = curveDragStrategy;
         }
         currentDragStrategy.OnMouseDown(GetPosition3D(e), null);
         vpRoot.CaptureMouse();
     }
 }
        private void vpRoot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (currentDragStrategy == null)
            {
                var positionInfo    = GetPosition3D(e);
                var primitiveVisual = PrimitivesPickService.PickPrimitiveVisual(viewport3d, positionInfo.Pos2D);
                if (primitiveVisual != null)
                {
                    var primitiveData = PrimitivesPickService.GetPrimitiveData(primitiveVisual);
                    viewModel.SelectPrimitive(primitiveData);

                    primitiveData.MatchClass <NewPrimitive>(_ => currentDragStrategy     = newPrimitiveDragStrategy);
                    primitiveData.MatchClass <SnappedPrimitive>(_ => currentDragStrategy = snappedDragStrategy);
                    Debug.Assert(currentDragStrategy != null);

                    currentDragStrategy.OnMouseDown(GetPosition3D(e), Tuple.Create(primitiveVisual, primitiveData));
                    vpRoot.CaptureMouse();
                }
                else
                {
                    viewModel.UnselectPrimitives();
                }
            }
        }