Beispiel #1
0
        //============== return value ===============//
        //
        //                    -1
        //      9                           9
        //        ┌───────────────────────┐
        //        │ 1         8         4 │
        //        │                       │
        //  -1    │ 5         0         7 │    -1
        //        │                       │
        //        │ 2         6         3 │
        //        └───────────────────────┘
        //      9                           9
        //                    -1
        //
        //
        // Anchor Point : 10
        //============================================//
        public int partOfSelection(float x, float y, out int cursor)
        {
            cursor = -1;

            if (selectedItems.Count == 0)
            {
                return(-1);
            }
            if (selectedItems.Count > 1)
            {
                return(containsInSelection(x, y) ? 0 : 9);
            }

            TActor actor = selectedItems[0];

            if (currentTool == TDocument.TOOL_PUZZLE && !actor.puzzle)
            {
                return(-1);
            }

            PointF screenPos  = new PointF(x, y);
            PointF logicalPos = currentTool != TDocument.TOOL_PUZZLE ? actor.screenToLogical(new PointF(x, y)) : actor.ownerScene().screenToLogical(new PointF(x, y));

            RectangleF actorBound        = actor.bound();
            PointF     anchorPosOnScreen = actor.logicalToScreen(new PointF(actorBound.Width * actor.anchor.X, actorBound.Height * actor.anchor.Y));

            RectangleF bound;

            if (currentTool == TDocument.TOOL_BOUNDING)
            {
                bound = actor.interactionBound;
            }
            else if (currentTool == TDocument.TOOL_PUZZLE)
            {
                bound = actor.puzzleArea;
            }
            else
            {
                bound = actorBound;
            }

            PointF[] boundOnScreen;
            if (currentTool == TDocument.TOOL_BOUNDING)
            {
                boundOnScreen = actor.interactionBoundOnScreen();
            }
            else if (currentTool == TDocument.TOOL_PUZZLE)
            {
                boundOnScreen = actor.puzzleAreaOnScreen();
            }
            else
            {
                boundOnScreen = actor.boundOnScreen();
            }
            int ctrl_size = 6;

            bool leftEdge    = TUtil.distanceBetweenPointLine(screenPos, boundOnScreen[0], boundOnScreen[1]) <= ctrl_size;
            bool bottomEdge  = TUtil.distanceBetweenPointLine(screenPos, boundOnScreen[1], boundOnScreen[2]) <= ctrl_size;
            bool rightEdge   = TUtil.distanceBetweenPointLine(screenPos, boundOnScreen[2], boundOnScreen[3]) <= ctrl_size;
            bool topEdge     = TUtil.distanceBetweenPointLine(screenPos, boundOnScreen[3], boundOnScreen[0]) <= ctrl_size;
            bool insideBound = bound.Contains(logicalPos);

            int    first_cursor = 0; // cursor form part 5
            double angle        = -Math.Atan2(boundOnScreen[1].Y - boundOnScreen[0].Y, boundOnScreen[1].X - boundOnScreen[0].X) * 180 / Math.PI;

            if (angle < 0)
            {
                angle += 360;
            }
            first_cursor = (int)((angle + 22.5) / 45) % 4;

            int part = -1;

            if (leftEdge && topEdge)
            {
                part = 1; cursor = (first_cursor - 1) % 4;
            }
            else if (leftEdge && bottomEdge)
            {
                part = 2; cursor = (first_cursor + 1) % 4;
            }
            else if (rightEdge && bottomEdge)
            {
                part = 3; cursor = (first_cursor + 3) % 4;
            }
            else if (rightEdge && topEdge)
            {
                part = 4; cursor = (first_cursor + 5) % 4;
            }
            else if (leftEdge && TUtil.isPointProjectionInLineSegment(screenPos, boundOnScreen[0], boundOnScreen[1]))
            {
                part = 5; cursor = (first_cursor + 0) % 4;
            }
            else if (bottomEdge && TUtil.isPointProjectionInLineSegment(screenPos, boundOnScreen[1], boundOnScreen[2]))
            {
                part = 6; cursor = (first_cursor + 2) % 4;
            }
            else if (rightEdge && TUtil.isPointProjectionInLineSegment(screenPos, boundOnScreen[2], boundOnScreen[3]))
            {
                part = 7; cursor = (first_cursor + 4) % 4;
            }
            else if (topEdge && TUtil.isPointProjectionInLineSegment(screenPos, boundOnScreen[3], boundOnScreen[0]))
            {
                part = 8; cursor = (first_cursor + 6) % 4;
            }
            else if (TUtil.distanceBetweenPoints(screenPos, anchorPosOnScreen) <= ctrl_size)
            {
                part = 10;
            }
            else if (insideBound)
            {
                part = 0;
            }
            else if (currentTool != TDocument.TOOL_BOUNDING && currentTool != TDocument.TOOL_PUZZLE)
            {
                if (TUtil.distanceBetweenPoints(screenPos, boundOnScreen[0]) <= ctrl_size * 3 ||
                    TUtil.distanceBetweenPoints(screenPos, boundOnScreen[1]) <= ctrl_size * 3 ||
                    TUtil.distanceBetweenPoints(screenPos, boundOnScreen[2]) <= ctrl_size * 3 ||
                    TUtil.distanceBetweenPoints(screenPos, boundOnScreen[3]) <= ctrl_size * 3)
                {
                    part = 9;
                }
            }

            return(part);
        }
Beispiel #2
0
        private void drawSelectedBound(Graphics g)
        {
            PointF[] bound = null;
            TActor   actor = this.selectedActor();

            if (currentTool == TDocument.TOOL_BOUNDING)
            {
                if (actor != null)
                {
                    bound = actor.interactionBoundOnScreen();
                }
            }
            else if (currentTool == TDocument.TOOL_PUZZLE)
            {
                if (actor != null && actor.puzzle)
                {
                    bound = actor.puzzleAreaOnScreen();
                }
            }
            else
            {
                bound = this.selectedBound();
            }

            if (bound != null)
            {
                Color boundColor;
                switch (currentTool)
                {
                case TDocument.TOOL_BOUNDING:
                    boundColor = Color.Red;
                    break;

                case TDocument.TOOL_PUZZLE:
                    boundColor = Color.Blue;
                    break;

                default:
                    boundColor = Color.Black;
                    break;
                }

                // draw rectangle
                Pen pen = new Pen(boundColor, 1);
                pen.DashStyle   = DashStyle.Custom;
                pen.DashPattern = new float[] { 4, 4 };
                g.DrawPolygon(pen, bound);

                // draw control point
                const int ctrl_size  = 6;
                Pen       ctrl_pen   = new Pen(boundColor, 1);
                Brush     ctrl_brush = new SolidBrush(Color.White);
                Rectangle ctrl_rect;
                for (int i = 0; i < bound.Length; i++)
                {
                    // corner
                    ctrl_rect = new Rectangle((int)(bound[i].X - ctrl_size / 2), (int)(bound[i].Y - ctrl_size / 2), ctrl_size, ctrl_size);
                    g.FillRectangle(ctrl_brush, ctrl_rect);
                    g.DrawRectangle(ctrl_pen, ctrl_rect);

                    // edge
                    int j = (i + 1) % bound.Length;
                    ctrl_rect = new Rectangle((int)((bound[i].X + bound[j].X - ctrl_size) / 2), (int)((bound[i].Y + bound[j].Y - ctrl_size) / 2), ctrl_size, ctrl_size);
                    g.FillRectangle(ctrl_brush, ctrl_rect);
                    g.DrawRectangle(ctrl_pen, ctrl_rect);
                }

                // draw anchor point
                if (actor != null && (currentTool != TDocument.TOOL_BOUNDING && currentTool != TDocument.TOOL_PUZZLE))
                {
                    const int anchor_line_size   = 10;
                    const int anchor_circle_size = 6;

                    RectangleF actorBound = actor.bound();
                    PointF     anchorPosF = actor.logicalToScreen(new PointF(actor.anchor.X * actorBound.Width, actor.anchor.Y * actorBound.Height));
                    Point      anchorPos  = new Point((int)anchorPosF.X, (int)anchorPosF.Y);
                    g.DrawLine(ctrl_pen, anchorPos.X - anchor_line_size / 2, anchorPos.Y, anchorPos.X - anchor_circle_size / 2, anchorPos.Y);
                    g.DrawLine(ctrl_pen, anchorPos.X + anchor_line_size / 2, anchorPos.Y, anchorPos.X + anchor_circle_size / 2, anchorPos.Y);
                    g.DrawLine(ctrl_pen, anchorPos.X, anchorPos.Y - anchor_line_size / 2, anchorPos.X, anchorPos.Y - anchor_circle_size / 2);
                    g.DrawLine(ctrl_pen, anchorPos.X, anchorPos.Y + anchor_line_size / 2, anchorPos.X, anchorPos.Y + anchor_circle_size / 2);
                    g.DrawEllipse(ctrl_pen, anchorPos.X - anchor_circle_size / 2, anchorPos.Y - anchor_circle_size / 2, anchor_circle_size, anchor_circle_size);
                    g.FillRectangle(Brushes.Black, anchorPos.X, anchorPos.Y, 1, 1);
                }
            }
        }