コード例 #1
0
ファイル: SkewTool.cs プロジェクト: jpiolho/sledge
 public override bool FilterHandle(BaseBoxTool.ResizeHandle handle)
 {
     return handle == BaseBoxTool.ResizeHandle.Bottom
            || handle == BaseBoxTool.ResizeHandle.Left
            || handle == BaseBoxTool.ResizeHandle.Top
            || handle == BaseBoxTool.ResizeHandle.Right;
 }
コード例 #2
0
ファイル: RotateTool.cs プロジェクト: silky/sledge
        public override Matrix4? GetTransformationMatrix(Viewport2D viewport, ViewportEvent e, BaseBoxTool.BoxState state, Document doc, IEnumerable<Widget> activeWidgets)
        {
            var origin = viewport.ZeroUnusedCoordinate((state.PreTransformBoxStart + state.PreTransformBoxEnd) / 2);
            var rw = activeWidgets.OfType<RotationWidget>().FirstOrDefault();
            if (rw != null) origin = rw.GetPivotPoint();

            var forigin = viewport.Flatten(origin);

            var origv = (state.MoveStart - forigin).Normalise();
            var newv = (viewport.ScreenToWorld(e.X, viewport.Height - e.Y) - forigin).Normalise();

            var angle = DMath.Acos(Math.Max(-1, Math.Min(1, origv.Dot(newv))));
            if ((origv.Cross(newv).Z < 0)) angle = 2 * DMath.PI - angle;

            var shf = KeyboardState.Shift;
            var def = Select.RotationStyle;
            var snap = (def == RotationStyle.SnapOnShift && shf) || (def == RotationStyle.SnapOffShift && !shf);
            if (snap)
            {
                var deg = angle * (180 / DMath.PI);
                var rnd = Math.Round(deg / 15) * 15;
                angle = rnd * (DMath.PI / 180);
            }

            Matrix4 rotm;
            if (viewport.Direction == Viewport2D.ViewDirection.Top) rotm = Matrix4.CreateRotationZ((float)angle);
            else if (viewport.Direction == Viewport2D.ViewDirection.Front) rotm = Matrix4.CreateRotationX((float)angle);
            else rotm = Matrix4.CreateRotationY((float)-angle); // The Y axis rotation goes in the reverse direction for whatever reason

            var mov = Matrix4.CreateTranslation((float)-origin.X, (float)-origin.Y, (float)-origin.Z);
            var rot = Matrix4.Mult(mov, rotm);
            return Matrix4.Mult(rot, Matrix4.Invert(mov));
        }
コード例 #3
0
ファイル: SkewTool.cs プロジェクト: jpiolho/sledge
        public override Matrix4? GetTransformationMatrix(Viewport2D viewport, ViewportEvent e, BaseBoxTool.BoxState state, Document doc)
        {
            var shearUpDown = state.Handle == BaseBoxTool.ResizeHandle.Left || state.Handle == BaseBoxTool.ResizeHandle.Right;
            var shearTopRight = state.Handle == BaseBoxTool.ResizeHandle.Top || state.Handle == BaseBoxTool.ResizeHandle.Right;

            var nsmd = viewport.ScreenToWorld(e.X, viewport.Height - e.Y) - state.MoveStart;
            var mouseDiff = SnapIfNeeded(nsmd, doc);
            if (KeyboardState.Shift)
            {
                mouseDiff = doc.Snap(nsmd, doc.Map.GridSpacing / 2);
            }

            var relative = viewport.Flatten(state.PreTransformBoxEnd - state.PreTransformBoxStart);
            var shearOrigin = (shearTopRight) ? state.PreTransformBoxStart : state.PreTransformBoxEnd;

            var shearAmount = new Coordinate(mouseDiff.X / relative.Y, mouseDiff.Y / relative.X, 0);
            if (!shearTopRight) shearAmount *= -1;

            var shearMatrix = Matrix4.Identity;
            var sax = (float)shearAmount.X;
            var say = (float)shearAmount.Y;

            switch (viewport.Direction)
            {
                case Viewport2D.ViewDirection.Top:
                    if (shearUpDown) shearMatrix.M12 = say;
                    else shearMatrix.M21 = sax;
                    break;
                case Viewport2D.ViewDirection.Front:
                    if (shearUpDown) shearMatrix.M23 = say;
                    else shearMatrix.M32 = sax;
                    break;
                case Viewport2D.ViewDirection.Side:
                    if (shearUpDown) shearMatrix.M13 = say;
                    else shearMatrix.M31 = sax;
                    break;
            }

            var stran = Matrix4.CreateTranslation((float)-shearOrigin.X, (float)-shearOrigin.Y, (float)-shearOrigin.Z);
            var shear = Matrix4.Mult(stran, shearMatrix);
            return Matrix4.Mult(shear, Matrix4.Invert(stran));
        }
コード例 #4
0
ファイル: ResizeTool.cs プロジェクト: jpiolho/sledge
 private static Coordinate GetOriginForTransform(Viewport2D viewport, BaseBoxTool.BoxState state)
 {
     decimal x = 0;
     decimal y = 0;
     var cstart = viewport.Flatten(state.PreTransformBoxStart);
     var cend = viewport.Flatten(state.PreTransformBoxEnd);
     switch (state.Handle)
     {
         case BaseBoxTool.ResizeHandle.TopLeft:
         case BaseBoxTool.ResizeHandle.Top:
         case BaseBoxTool.ResizeHandle.TopRight:
         case BaseBoxTool.ResizeHandle.Left:
         case BaseBoxTool.ResizeHandle.Right:
             y = cstart.Y;
             break;
         case BaseBoxTool.ResizeHandle.BottomLeft:
         case BaseBoxTool.ResizeHandle.Bottom:
         case BaseBoxTool.ResizeHandle.BottomRight:
             y = cend.Y;
             break;
     }
     switch (state.Handle)
     {
         case BaseBoxTool.ResizeHandle.Top:
         case BaseBoxTool.ResizeHandle.TopRight:
         case BaseBoxTool.ResizeHandle.Right:
         case BaseBoxTool.ResizeHandle.BottomRight:
         case BaseBoxTool.ResizeHandle.Bottom:
             x = cstart.X;
             break;
         case BaseBoxTool.ResizeHandle.TopLeft:
         case BaseBoxTool.ResizeHandle.Left:
         case BaseBoxTool.ResizeHandle.BottomLeft:
             x = cend.X;
             break;
     }
     return viewport.Expand(new Coordinate(x, y, 0));
 }
コード例 #5
0
ファイル: ResizeTool.cs プロジェクト: jpiolho/sledge
 public override Matrix4? GetTransformationMatrix(Viewport2D viewport, ViewportEvent e, BaseBoxTool.BoxState state, Document doc)
 {
     var coords = GetBoxCoordinatesForSelectionResize(viewport, e, state, doc);
     state.BoxStart = coords.Item1;
     state.BoxEnd = coords.Item2;
     Matrix4 resizeMatrix;
     if (state.Handle == BaseBoxTool.ResizeHandle.Center)
     {
         var movement = state.BoxStart - state.PreTransformBoxStart;
         resizeMatrix = Matrix4.CreateTranslation((float)movement.X, (float)movement.Y, (float)movement.Z);
     }
     else
     {
         var resize = (state.PreTransformBoxStart - state.BoxStart) +
                      (state.BoxEnd - state.PreTransformBoxEnd);
         resize = resize.ComponentDivide(state.PreTransformBoxEnd - state.PreTransformBoxStart);
         resize += new Coordinate(1, 1, 1);
         var offset = -GetOriginForTransform(viewport, state);
         var trans = Matrix4.CreateTranslation((float)offset.X, (float)offset.Y, (float)offset.Z);
         var scale = Matrix4.Mult(trans, Matrix4.Scale((float)resize.X, (float)resize.Y, (float)resize.Z));
         resizeMatrix = Matrix4.Mult(scale, Matrix4.Invert(trans));
     }
     return resizeMatrix;
 }
コード例 #6
0
 public abstract Matrix4? GetTransformationMatrix(Viewport2D viewport, ViewportEvent mouseEventArgs, BaseBoxTool.BoxState state, Document doc, IEnumerable<Widget> activeWidgets);
コード例 #7
0
 public abstract bool FilterHandle(BaseBoxTool.ResizeHandle handle);
コード例 #8
0
 public abstract Cursor CursorForHandle(BaseBoxTool.ResizeHandle handle);
コード例 #9
0
ファイル: TransformationTool.cs プロジェクト: jpiolho/sledge
 public abstract Matrix4? GetTransformationMatrix(Viewport2D viewport, ViewportEvent mouseEventArgs, BaseBoxTool.BoxState state, Document doc);
コード例 #10
0
ファイル: ResizeTool.cs プロジェクト: jpiolho/sledge
 public override bool FilterHandle(BaseBoxTool.ResizeHandle handle)
 {
     return true;
 }
コード例 #11
0
ファイル: ResizeTool.cs プロジェクト: jpiolho/sledge
 public override Cursor CursorForHandle(BaseBoxTool.ResizeHandle handle)
 {
     return null;
 }
コード例 #12
0
ファイル: ResizeTool.cs プロジェクト: jpiolho/sledge
        private Tuple<Coordinate, Coordinate> SnapBoxCoordinatesIfNeeded(Viewport2D viewport, BaseBoxTool.BoxState state, Document document, Coordinate start, Coordinate end)
        {
            if (state.Action == BaseBoxTool.BoxAction.Resizing && state.Handle == BaseBoxTool.ResizeHandle.Center)
            {
                // Pick the corner to snap
                var ms = state.MoveStart;
                var pts = viewport.Flatten(state.PreTransformBoxStart);
                var pte = viewport.Flatten(state.PreTransformBoxEnd);
                var ss = SnapIfNeeded(start, document);
                var se = SnapIfNeeded(end, document);
                var middle = (pts + pte) / 2;
                var delta = ss - start;
                if (ms.Y > middle.Y)
                {
                    // Top
                    delta.Y = se.Y - end.Y;
                }
                if (ms.X > middle.X)
                {
                    // Right
                    delta.X = se.X - end.X;
                }
                start += delta;
                end += delta;
            }

            var cstart = viewport.Expand(start) + viewport.GetUnusedCoordinate(state.BoxStart);
            var cend = viewport.Expand(end) + viewport.GetUnusedCoordinate(state.BoxEnd);
            return Tuple.Create(cstart, cend);
        }
コード例 #13
0
ファイル: ResizeTool.cs プロジェクト: jpiolho/sledge
 private Tuple<Coordinate, Coordinate> GetBoxCoordinatesForSelectionResize(Viewport2D viewport, ViewportEvent e, BaseBoxTool.BoxState state, Document document)
 {
     if (state.Action != BaseBoxTool.BoxAction.Resizing) return Tuple.Create(state.BoxStart, state.BoxEnd);
     var now = SnapIfNeeded(viewport.ScreenToWorld(e.X, viewport.Height - e.Y), document);
     var cstart = viewport.Flatten(state.BoxStart);
     var cend = viewport.Flatten(state.BoxEnd);
     switch (state.Handle)
     {
         case BaseBoxTool.ResizeHandle.TopLeft:
             cstart.X = Math.Min(now.X, cend.X - 1);
             cend.Y = Math.Max(now.Y, cstart.Y + 1);
             break;
         case BaseBoxTool.ResizeHandle.Top:
             cend.Y = Math.Max(now.Y, cstart.Y + 1);
             break;
         case BaseBoxTool.ResizeHandle.TopRight:
             cend.X = Math.Max(now.X, cstart.X + 1);
             cend.Y = Math.Max(now.Y, cstart.Y + 1);
             break;
         case BaseBoxTool.ResizeHandle.Left:
             cstart.X = Math.Min(now.X, cend.X - 1);
             break;
         case BaseBoxTool.ResizeHandle.Center:
             var cdiff = cend - cstart;
             cstart = viewport.Flatten(state.PreTransformBoxStart) + now - SnapIfNeeded(state.MoveStart, document);
             cend = cstart + cdiff;
             break;
         case BaseBoxTool.ResizeHandle.Right:
             cend.X = Math.Max(now.X, cstart.X + 1);
             break;
         case BaseBoxTool.ResizeHandle.BottomLeft:
             cstart.X = Math.Min(now.X, cend.X - 1);
             cstart.Y = Math.Min(now.Y, cend.Y - 1);
             break;
         case BaseBoxTool.ResizeHandle.Bottom:
             cstart.Y = Math.Min(now.Y, cend.Y - 1);
             break;
         case BaseBoxTool.ResizeHandle.BottomRight:
             cend.X = Math.Max(now.X, cstart.X + 1);
             cstart.Y = Math.Min(now.Y, cend.Y - 1);
             break;
         default:
             throw new ArgumentOutOfRangeException();
     }
     return SnapBoxCoordinatesIfNeeded(viewport, state, document, cstart, cend);
 }
コード例 #14
0
ファイル: ResizeTool.cs プロジェクト: KonstantinUb/sledge
        private Tuple<Coordinate, Coordinate> GetBoxCoordinatesForSelectionResize(Viewport2D viewport, ViewportEvent e, BaseBoxTool.BoxState state, Document document)
        {
            if (state.Action != BaseBoxTool.BoxAction.Resizing) return Tuple.Create(state.BoxStart, state.BoxEnd);
            var now = SnapIfNeeded(viewport.ScreenToWorld(e.X, viewport.Height - e.Y), document);
            var cstart = viewport.Flatten(state.BoxStart);
            var cend = viewport.Flatten(state.BoxEnd);

            // Proportional scaling
            var ostart = viewport.Flatten(state.PreTransformBoxStart ?? Coordinate.Zero);
            var oend = viewport.Flatten(state.PreTransformBoxEnd ?? Coordinate.Zero);
            var owidth = oend.X - ostart.X;
            var oheight = oend.Y - ostart.Y;
            var proportional = KeyboardState.Ctrl && state.Action == BaseBoxTool.BoxAction.Resizing && owidth != 0 && oheight != 0;

            switch (state.Handle)
            {
                case BaseBoxTool.ResizeHandle.TopLeft:
                    cstart.X = Math.Min(now.X, cend.X - 1);
                    cend.Y = Math.Max(now.Y, cstart.Y + 1);
                    break;
                case BaseBoxTool.ResizeHandle.Top:
                    cend.Y = Math.Max(now.Y, cstart.Y + 1);
                    break;
                case BaseBoxTool.ResizeHandle.TopRight:
                    cend.X = Math.Max(now.X, cstart.X + 1);
                    cend.Y = Math.Max(now.Y, cstart.Y + 1);
                    break;
                case BaseBoxTool.ResizeHandle.Left:
                    cstart.X = Math.Min(now.X, cend.X - 1);
                    break;
                case BaseBoxTool.ResizeHandle.Center:
                    var cdiff = cend - cstart;
                    cstart = viewport.Flatten(state.PreTransformBoxStart) + now - SnapIfNeeded(state.MoveStart, document);
                    cend = cstart + cdiff;
                    break;
                case BaseBoxTool.ResizeHandle.Right:
                    cend.X = Math.Max(now.X, cstart.X + 1);
                    break;
                case BaseBoxTool.ResizeHandle.BottomLeft:
                    cstart.X = Math.Min(now.X, cend.X - 1);
                    cstart.Y = Math.Min(now.Y, cend.Y - 1);
                    break;
                case BaseBoxTool.ResizeHandle.Bottom:
                    cstart.Y = Math.Min(now.Y, cend.Y - 1);
                    break;
                case BaseBoxTool.ResizeHandle.BottomRight:
                    cend.X = Math.Max(now.X, cstart.X + 1);
                    cstart.Y = Math.Min(now.Y, cend.Y - 1);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
            if (proportional)
            {
                var nwidth = cend.X - cstart.X;
                var nheight = cend.Y - cstart.Y;
                var mult = Math.Max(nwidth / owidth, nheight / oheight);
                var pwidth = owidth * mult;
                var pheight = oheight * mult;
                var wdiff = pwidth - nwidth;
                var hdiff = pheight - nheight;
                switch (state.Handle)
                {
                    case BaseBoxTool.ResizeHandle.TopLeft:
                        cstart.X -= wdiff;
                        cend.Y += hdiff;
                        break;
                    case BaseBoxTool.ResizeHandle.TopRight:
                        cend.X += wdiff;
                        cend.Y += hdiff;
                        break;
                    case BaseBoxTool.ResizeHandle.BottomLeft:
                        cstart.X -= wdiff;
                        cstart.Y -= hdiff;
                        break;
                    case BaseBoxTool.ResizeHandle.BottomRight:
                        cend.X += wdiff;
                        cstart.Y -= hdiff;
                        break;
                }
            }
            return SnapBoxCoordinatesIfNeeded(viewport, state, document, cstart, cend);
        }
コード例 #15
0
ファイル: SkewTool.cs プロジェクト: jpiolho/sledge
 public override Cursor CursorForHandle(BaseBoxTool.ResizeHandle handle)
 {
     return (handle == BaseBoxTool.ResizeHandle.Top || handle == BaseBoxTool.ResizeHandle.Bottom)
                ? Cursors.SizeWE
                : Cursors.SizeNS;
 }
コード例 #16
0
ファイル: RotateTool.cs プロジェクト: silky/sledge
 public override Cursor CursorForHandle(BaseBoxTool.ResizeHandle handle)
 {
     return SledgeCursors.RotateCursor;
 }