예제 #1
0
        private void OnMouseMoveImpl(MouseEventArgs e, StringBuilder sbLogger)
        {
            if (!this.tracking)
            {
                sbLogger.Append("1 ");
                Cursor cursor = this.moveToolCursor;

                for (int i = 0; i < this.moveNubs.Length; ++i)
                {
                    sbLogger.Append("2 ");
                    MoveNubRenderer nub = this.moveNubs[i];
                    sbLogger.Append("3 ");

                    if (nub.Visible && nub.IsPointTouching(new Point(e.X, e.Y), true))
                    {
                        sbLogger.Append("4 ");
                        cursor = this.handCursor;
                        break;
                    }
                }

                this.Cursor = cursor;
                sbLogger.Append("5 ");
            }
            else
            {
                sbLogger.Append("6 ");
                if (this.context.currentMode != Mode.Translate)
                {
                    sbLogger.Append("7 ");
                    this.Cursor = this.handCursorMouseDown;
                }

                sbLogger.Append("8 ");
                Point newMouseXY = new Point(e.X, e.Y);
                Point newOffset  = new Point(newMouseXY.X - context.startMouseXY.X, newMouseXY.Y - context.startMouseXY.Y);

                PreRender();

                this.dontDrop = true;

                sbLogger.Append("9 ");
                Selection.PerformChanging();

                using (Matrix translateMatrix = new Matrix())
                {
                    RectangleF rect;
                    translateMatrix.Reset();

                    if (this.context.baseTransform != null)
                    {
                        Selection.SetInterimTransform(this.context.baseTransform);
                    }

                    Matrix interim = Selection.GetInterimTransformCopy();

                    switch (this.context.currentMode)
                    {
                    case Mode.Translate:
                        translateMatrix.Translate((float)newOffset.X, (float)newOffset.Y, MatrixOrder.Append);
                        break;

                    case Mode.Rotate:
                        rect = this.context.liftedBounds;
                        PointF center = new PointF(rect.X + (rect.Width / 2.0f), rect.Y + (rect.Height / 2.0f));
                        center = Utility.TransformOnePoint(interim, center);
                        double theta1     = Math.Atan2(context.startMouseXY.Y - center.Y, context.startMouseXY.X - center.X);
                        double theta2     = Math.Atan2(e.Y - center.Y, e.X - center.X);
                        double thetaDelta = theta2 - theta1;
                        this.angleDelta = (float)(thetaDelta * (180.0f / Math.PI));
                        float angle = this.context.startAngle + this.angleDelta;

                        if ((ModifierKeys & Keys.Shift) != 0)
                        {
                            angle      = ConstrainAngle(angle);
                            angleDelta = angle - this.context.startAngle;
                        }

                        translateMatrix.RotateAt(angleDelta, center, MatrixOrder.Append);
                        this.rotateNub.Location = center;
                        this.rotateNub.Angle    = this.context.startAngle + angleDelta;
                        break;

                    case Mode.Scale:
                        PointF xyAxes = GetEdgeVector(this.context.startEdge);
                        PointF xAxis  = new PointF(xyAxes.X, 0);
                        PointF yAxis  = new PointF(0, xyAxes.Y);
                        PointF edgeX  = Utility.TransformOneVector(interim, xAxis);
                        PointF edgeY  = Utility.TransformOneVector(interim, yAxis);
                        PointF edgeXN = Utility.NormalizeVector2(edgeX);
                        PointF edgeYN = Utility.NormalizeVector2(edgeY);

                        PointF xu;
                        float  xulen;
                        PointF xv;
                        Utility.GetProjection((PointF)newOffset, edgeXN, out xu, out xulen, out xv);

                        PointF yu;
                        float  yulen;
                        PointF yv;
                        Utility.GetProjection((PointF)newOffset, edgeYN, out yu, out yulen, out yv);

                        PdnGraphicsPath startPath2 = this.context.startPath.Clone();
                        RectangleF      sp2Bounds  = startPath2.GetBounds();

                        PointF sp2BoundsCenter = new PointF((sp2Bounds.Left + sp2Bounds.Right) / 2.0f,
                                                            (sp2Bounds.Top + sp2Bounds.Bottom) / 2.0f);

                        float tAngle    = Utility.GetAngleOfTransform(interim);
                        bool  isFlipped = Utility.IsTransformFlipped(interim);

                        using (Matrix spm = new Matrix())
                        {
                            spm.Reset();
                            spm.RotateAt(-tAngle, sp2BoundsCenter, MatrixOrder.Append);
                            translateMatrix.RotateAt(-tAngle, sp2BoundsCenter, MatrixOrder.Append);
                            startPath2.Transform(spm);
                        }

                        RectangleF spBounds2 = startPath2.GetBounds();

                        startPath2.Dispose();
                        startPath2 = null;

                        float xTranslate;
                        float yTranslate;
                        bool  allowConstrain;

                        Edge theEdge = this.context.startEdge;

                        // If the transform is flipped, then GetTransformAngle will return 180 degrees
                        // even though no rotation has actually taken place. Thus we have to scratch
                        // our head and go "hmm, let's make some adjustments to this." Otherwise stretching
                        // the top and bottom nubs goes in the wrong direction.
                        if (isFlipped)
                        {
                            theEdge = FlipEdgeVertically(theEdge);
                        }

                        switch (theEdge)
                        {
                        default:
                            throw new InvalidEnumArgumentException();

                        case Edge.TopLeft:
                            allowConstrain = true;
                            xTranslate     = -spBounds2.X - spBounds2.Width;
                            yTranslate     = -spBounds2.Y - spBounds2.Height;
                            break;

                        case Edge.Top:
                            allowConstrain = false;
                            xTranslate     = 0;
                            yTranslate     = -spBounds2.Y - spBounds2.Height;
                            break;

                        case Edge.TopRight:
                            allowConstrain = true;
                            xTranslate     = -spBounds2.X;
                            yTranslate     = -spBounds2.Y - spBounds2.Height;
                            break;

                        case Edge.Left:
                            allowConstrain = false;
                            xTranslate     = -spBounds2.X - spBounds2.Width;
                            yTranslate     = 0;
                            break;

                        case Edge.Right:
                            allowConstrain = false;
                            xTranslate     = -spBounds2.X;
                            yTranslate     = 0;
                            break;

                        case Edge.BottomLeft:
                            allowConstrain = true;
                            xTranslate     = -spBounds2.X - spBounds2.Width;
                            yTranslate     = -spBounds2.Y;
                            break;

                        case Edge.Bottom:
                            allowConstrain = false;
                            xTranslate     = 0;
                            yTranslate     = -spBounds2.Y;
                            break;

                        case Edge.BottomRight:
                            allowConstrain = true;
                            xTranslate     = -spBounds2.X;
                            yTranslate     = -spBounds2.Y;
                            break;
                        }

                        translateMatrix.Translate(xTranslate, yTranslate, MatrixOrder.Append);

                        float newWidth  = spBounds2.Width + xulen;
                        float newHeight = spBounds2.Height + yulen;
                        float xScale    = newWidth / spBounds2.Width;
                        float yScale    = newHeight / spBounds2.Height;

                        if (allowConstrain && (this.ModifierKeys & Keys.Shift) != 0)
                        {
                            ConstrainScaling(this.context.liftedBounds, spBounds2.Width, spBounds2.Height,
                                             newWidth, newHeight, out xScale, out yScale);
                        }

                        translateMatrix.Scale(xScale, yScale, MatrixOrder.Append);
                        translateMatrix.Translate(-xTranslate, -yTranslate, MatrixOrder.Append);
                        translateMatrix.RotateAt(+tAngle, sp2BoundsCenter, MatrixOrder.Append);

                        break;

                    default:
                        throw new InvalidEnumArgumentException();
                    }

                    this.context.deltaTransform.Reset();
                    this.context.deltaTransform.Multiply(this.context.liftTransform, MatrixOrder.Append);
                    this.context.deltaTransform.Multiply(translateMatrix, MatrixOrder.Append);

                    translateMatrix.Multiply(this.context.baseTransform, MatrixOrder.Prepend);

                    Selection.SetInterimTransform(translateMatrix);

                    interim.Dispose();
                    interim = null;
                }

                // advertise our angle of rotation to any host (i.e. mainform) that might want to use that information
                this.hostShouldShowAngle = this.rotateNub.Visible;
                this.hostAngle           = -this.rotateNub.Angle;

                Selection.PerformChanged();
                dontDrop = false;

                Render(newOffset, true);
                Update();

                sbLogger.Append("a ");
                this.context.offset = newOffset;

                sbLogger.Append("b ");

                if (this.enableOutline)
                {
                    DocumentWorkspace.ResetOutlineWhiteOpacity();
                }

                sbLogger.Append("c ");
            }

            sbLogger.Append("d ");
        }