示例#1
0
        SymPath PathBetweenControls(ControlPosition controlPosition1, ControlPosition controlPosition2, ForkPosition forkStart, out PointF dropTargetPosition)
        {
            float xStart = controlPosition1.x;
            float yStart = controlPosition1.y;
            float xEnd = controlPosition2.x;
            float yEnd = controlPosition2.y;

            if (forkStart != null) {
                if (forkStart.loopFallThru) {
                    dropTargetPosition = LocationFromAbstractPosition(xEnd, yEnd - 0.5F);
                }
                else {
                    // above end of fork start.
                    dropTargetPosition = LocationFromAbstractPosition(forkStart.x, forkStart.y - 0.5F);
                }
            }
            else if (xEnd != xStart) {
                // Below start control (use when a join is going)
                dropTargetPosition = LocationFromAbstractPosition(xStart, yStart + 0.5F);
            }
            else {
                // Above end control (other cases).
                dropTargetPosition = LocationFromAbstractPosition(xEnd, yEnd - 0.5F);
            }

            bool startHorizontal = false;
            if (forkStart != null)
                startHorizontal = forkStart.loopStart;

            if (forkStart != null && forkStart.x != controlPosition2.x) {
                // The fork start in a different horizontal position than it ends. This is probably due to a fork with no controls on it.
                // Create the path in two pieces.
                float xMiddle = forkStart.x;
                float yMiddle = forkStart.y;
                SymPath path1 = PathFromStartToEnd(xStart, yStart, xMiddle, yMiddle, startHorizontal, 0);
                SymPath path3 = PathFromStartToEnd(xMiddle, yMiddle, xEnd, yEnd, false, controlPosition2.loopBottom);
                SymPath path2 = new SymPath(new[] { path1.LastPoint, path3.FirstPoint });
                return SymPath.Join(SymPath.Join(path1, path2, PointKind.Normal), path3, PointKind.Normal);
            }
            else {
                return PathFromStartToEnd(xStart, yStart, xEnd, yEnd, startHorizontal, controlPosition2.loopBottom);
            }
        }
示例#2
0
        private void CreateLegBetweenControls(CourseView.ControlView controlView1, ControlPosition controlPosition1, CourseView.ControlView controlView2, ControlPosition controlPosition2, int splitLegIndex, ForkPosition forkStart)
        {
            PointF dropTargetPosition;
            SymPath path = PathBetweenControls(controlPosition1, controlPosition2, forkStart, out dropTargetPosition);
            CourseObj courseObj = new TopologyLegCourseObj(controlView1.controlId, controlView1.courseControlIds[splitLegIndex], controlView2.courseControlIds[0], scaleRatio, appearance, path);
            CourseLayer layer;

            if (LegInSpecificVariation(controlView1.courseControlIds[splitLegIndex], controlView2.courseControlIds[0]))
                layer = courseLayerSpecificVariation;
            else
                layer = courseLayerAllVariationsAndParts;

            courseObj.layer = layer;
            courseLayout.AddCourseObject(courseObj);

            // Add the drop target.
            courseObj = new TopologyDropTargetCourseObj(controlView1.controlId, controlView1.courseControlIds[splitLegIndex], controlView2.courseControlIds[0], scaleRatio, appearance, dropTargetPosition);
            courseObj.layer = layer;
            courseLayout.AddCourseObject(courseObj);

            if (forkStart != null && forkStart.variationCode != '\0') {
                // There is a variation fork.
                courseObj = CreateVariationCode(controlView1, controlPosition1, splitLegIndex, forkStart);
                courseLayout.AddCourseObject(courseObj);
            }
        }
示例#3
0
        private CourseObj CreateVariationCode(CourseView.ControlView controlView1, ControlPosition controlPosition1, int splitLegIndex, ForkPosition forkStart)
        {
            // Delta between position of fork start and position of code.
            float deltaX = (forkStart.x < controlPosition1.x) ? -0.4F : 0.4F;
            float deltaY = -0.4F;

            float x = forkStart.x + deltaX;
            float y = forkStart.y + deltaY;

            string text = "(" + forkStart.variationCode + ")";
            CourseObj courseObj = new VariationCodeCourseObj(controlView1.controlId, controlView1.courseControlIds[splitLegIndex], scaleRatio, appearance, text, LocationFromAbstractPosition(x, y));
            courseObj.layer = CourseLayer.AllVariations;
            return courseObj;
        }
示例#4
0
        // Assign positions/sizes from startIndex upto (not including) endIndex, starting at given position.
        // Return total size used.
        private SizeF AssignControlPositions(int startIndex, int endIndex, float startX, float startY)
        {
            int index = startIndex;
            float x = startX, y = startY;
            float totalWidth = 1, totalHeight = 0;   // Always at least a width of 1.
            while (index != endIndex) {
                int numForks = (controlViewsAllVariationsAndParts[index].legTo == null) ? 0 : controlViewsAllVariationsAndParts[index].legTo.Length;

                // Simple case, no splitting.
                controlPositions[index] = new ControlPosition() {
                    x = x,
                    y = y,
                };
                totalWidth = Math.Max(totalWidth, 1);
                totalHeight += 1;
                y += 1;

                if (numForks > 1) {
                    bool loop = (controlViewsAllVariationsAndParts[index].joinIndex == index);

                    // fork or loop subsequent. Two passes -- first determine totalWidth and maxHeight;
                    float totalForkWidth = 0, maxForkHeight = 1;
                    SizeF[] forkSize = new SizeF[numForks];
                    ForkPosition[] forkStart = new ForkPosition[numForks];

                    int startFork = 0;
                    if (loop) {
                        startFork = 1;
                        totalForkWidth = 1;
                    }

                    // Get size of each fork.
                    for (int i = startFork; i < numForks; ++i) {
                        forkSize[i] = AssignControlPositions(controlViewsAllVariationsAndParts[index].legTo[i], controlViewsAllVariationsAndParts[index].joinIndex, 0, 0);
                        totalForkWidth += forkSize[i].Width;
                        maxForkHeight = Math.Max(maxForkHeight, forkSize[i].Height);
                    }

                    // Get position of each fork.
                    if (loop) {
                        float forkY = y;
                        float forkX = x;
                        forkStart[0] = new ForkPosition(forkX, forkY, false, true, '\0');
                        int halfForks = (numForks + 1) / 2;

                        totalForkWidth = 0;

                        forkX = x - 0.5F;
                        for (int i = startFork; i < halfForks; ++i) {
                            forkX -= forkSize[i].Width;
                        }

                        totalForkWidth = Math.Max(totalForkWidth, (x-forkX) * 2);

                        for (int i = startFork; i < halfForks; ++i) {
                            forkX += forkSize[i].Width / 2;
                            forkStart[i] = new ForkPosition(forkX, forkY, loop, false, variationMap[controlViewsAllVariationsAndParts[index].courseControlIds[i]]);
                            forkX += forkSize[i].Width / 2;
                        }

                        forkX = x + 0.5F;

                        for (int i = halfForks; i < numForks; ++i) {
                            forkX += forkSize[i].Width / 2;
                            forkStart[i] = new ForkPosition(forkX, forkY, loop, false, variationMap[controlViewsAllVariationsAndParts[index].courseControlIds[i]]);
                            forkX += forkSize[i].Width / 2;
                        }

                        totalForkWidth = Math.Max(totalForkWidth, (forkX-x) * 2);

                        controlPositions[index].loopBottom = y + maxForkHeight - 0.5F;
                    }
                    else {
                        float forkY = y + 0.5F;
                        float forkX = x - totalForkWidth / 2;
                        for (int i = startFork; i < numForks; ++i) {
                            forkX += forkSize[i].Width / 2;
                            forkStart[i] = new ForkPosition(forkX, forkY, loop, false, variationMap[controlViewsAllVariationsAndParts[index].courseControlIds[i]]);
                            forkX += forkSize[i].Width / 2;
                        }
                    }

                    controlPositions[index].forkStart = forkStart;

                    // Assign control positions for each fork again, now that we know the start position.
                    for (int i = startFork; i < numForks; ++i) {
                        AssignControlPositions(controlViewsAllVariationsAndParts[index].legTo[i], controlViewsAllVariationsAndParts[index].joinIndex, forkStart[i].x, forkStart[i].y);
                    }

                    float height = maxForkHeight + 1;
                    totalHeight += height;
                    y += height;
                    totalWidth = Math.Max(totalWidth, totalForkWidth);

                    if (index == controlViewsAllVariationsAndParts[index].joinIndex)
                        index = controlViewsAllVariationsAndParts[index].legTo[0];
                    else
                        index = controlViewsAllVariationsAndParts[index].joinIndex;
                }
                else {
                    if (controlViewsAllVariationsAndParts[index].legTo != null && controlViewsAllVariationsAndParts[index].legTo.Length > 0)
                        index = controlViewsAllVariationsAndParts[index].legTo[0];
                    else
                        break; // no more controls.
                }
            }

            return new SizeF(totalWidth, totalHeight);
        }
示例#5
0
        // Assign positions/sizes from startIndex upto (not including) endIndex, starting at given position.
        // Return total size used.
        private SizeF AssignControlPositions(int startIndex, int endIndex, float startX, float startY)
        {
            int   index = startIndex;
            float x = startX, y = startY;
            float totalWidth = 1, totalHeight = 0;   // Always at least a width of 1.

            while (index != endIndex)
            {
                int numForks = (controlViewsAllVariationsAndParts[index].legTo == null) ? 0 : controlViewsAllVariationsAndParts[index].legTo.Length;

                // Simple case, no splitting.
                controlPositions[index] = new ControlPosition()
                {
                    x = x,
                    y = y,
                };
                totalWidth   = Math.Max(totalWidth, 1);
                totalHeight += 1;
                y           += 1;

                if (numForks > 1)
                {
                    bool loop = (controlViewsAllVariationsAndParts[index].joinIndex == index);

                    // fork or loop subsequent. Two passes -- first determine totalWidth and maxHeight;
                    float          totalForkWidth = 0, maxForkHeight = 1;
                    SizeF[]        forkSize  = new SizeF[numForks];
                    ForkPosition[] forkStart = new ForkPosition[numForks];

                    int startFork = 0;
                    if (loop)
                    {
                        startFork      = 1;
                        totalForkWidth = 1;
                    }

                    // Get size of each fork.
                    for (int i = startFork; i < numForks; ++i)
                    {
                        forkSize[i]     = AssignControlPositions(controlViewsAllVariationsAndParts[index].legTo[i], controlViewsAllVariationsAndParts[index].joinIndex, 0, 0);
                        totalForkWidth += forkSize[i].Width;
                        maxForkHeight   = Math.Max(maxForkHeight, forkSize[i].Height);
                    }

                    // Get position of each fork.
                    if (loop)
                    {
                        float forkY = y;
                        float forkX = x;
                        forkStart[0] = new ForkPosition(forkX, forkY, false, true, '\0');
                        int halfForks = (numForks + 1) / 2;

                        totalForkWidth = 0;

                        forkX = x - 0.5F;
                        for (int i = startFork; i < halfForks; ++i)
                        {
                            forkX -= forkSize[i].Width;
                        }

                        totalForkWidth = Math.Max(totalForkWidth, (x - forkX) * 2);

                        for (int i = startFork; i < halfForks; ++i)
                        {
                            forkX       += forkSize[i].Width / 2;
                            forkStart[i] = new ForkPosition(forkX, forkY, loop, false, variationMap[controlViewsAllVariationsAndParts[index].courseControlIds[i]]);
                            forkX       += forkSize[i].Width / 2;
                        }

                        forkX = x + 0.5F;

                        for (int i = halfForks; i < numForks; ++i)
                        {
                            forkX       += forkSize[i].Width / 2;
                            forkStart[i] = new ForkPosition(forkX, forkY, loop, false, variationMap[controlViewsAllVariationsAndParts[index].courseControlIds[i]]);
                            forkX       += forkSize[i].Width / 2;
                        }

                        totalForkWidth = Math.Max(totalForkWidth, (forkX - x) * 2);

                        controlPositions[index].loopBottom = y + maxForkHeight - 0.5F;
                    }
                    else
                    {
                        float forkY = y + 0.5F;
                        float forkX = x - totalForkWidth / 2;
                        for (int i = startFork; i < numForks; ++i)
                        {
                            forkX       += forkSize[i].Width / 2;
                            forkStart[i] = new ForkPosition(forkX, forkY, loop, false, variationMap[controlViewsAllVariationsAndParts[index].courseControlIds[i]]);
                            forkX       += forkSize[i].Width / 2;
                        }
                    }

                    controlPositions[index].forkStart = forkStart;

                    // Assign control positions for each fork again, now that we know the start position.
                    for (int i = startFork; i < numForks; ++i)
                    {
                        AssignControlPositions(controlViewsAllVariationsAndParts[index].legTo[i], controlViewsAllVariationsAndParts[index].joinIndex, forkStart[i].x, forkStart[i].y);
                    }

                    float height = maxForkHeight + 1;
                    totalHeight += height;
                    y           += height;
                    totalWidth   = Math.Max(totalWidth, totalForkWidth);

                    if (index == controlViewsAllVariationsAndParts[index].joinIndex)
                    {
                        index = controlViewsAllVariationsAndParts[index].legTo[0];
                    }
                    else
                    {
                        index = controlViewsAllVariationsAndParts[index].joinIndex;
                    }
                }
                else
                {
                    if (controlViewsAllVariationsAndParts[index].legTo != null && controlViewsAllVariationsAndParts[index].legTo.Length > 0)
                    {
                        index = controlViewsAllVariationsAndParts[index].legTo[0];
                    }
                    else
                    {
                        break; // no more controls.
                    }
                }
            }

            return(new SizeF(totalWidth, totalHeight));
        }
示例#6
0
        private CourseObj CreateVariationCode(CourseView.ControlView controlView1, ControlPosition controlPosition1, int splitLegIndex, ForkPosition forkStart)
        {
            // Delta between position of fork start and position of code.
            float deltaX = (forkStart.x < controlPosition1.x) ? -0.4F : 0.4F;
            float deltaY = -0.4F;

            float x = forkStart.x + deltaX;
            float y = forkStart.y + deltaY;

            string    text      = "(" + forkStart.variationCode + ")";
            CourseObj courseObj = new VariationCodeCourseObj(controlView1.controlId, controlView1.courseControlIds[splitLegIndex], courseObjRatio, appearance, text, LocationFromAbstractPosition(x, y));

            courseObj.layer = CourseLayer.AllVariations;
            return(courseObj);
        }
示例#7
0
        // Determine the path between controls, and the drop targets.
        SymPath PathBetweenControls(ControlPosition controlPosition1, ControlPosition controlPosition2, ForkPosition forkStart, out List <DropTarget> dropTargets)
        {
            float xStart = controlPosition1.x;
            float yStart = controlPosition1.y;
            float xEnd   = controlPosition2.x;
            float yEnd   = controlPosition2.y;

            dropTargets = new List <DropTarget>();

            if (forkStart != null)
            {
                if (forkStart.loopFallThru)
                {
                    dropTargets.Add(new DropTarget(xEnd, yEnd - 0.5F, LegInsertionLoc.Normal));
                }
                else if (forkStart.loopStart)
                {
                    dropTargets.Add(new DropTarget(forkStart.x, forkStart.y - 0.5F, LegInsertionLoc.Normal));
                }
                else
                {
                    dropTargets.Add(new DropTarget(xStart, yStart + 0.5F, LegInsertionLoc.PreSplit));
                    dropTargets.Add(new DropTarget(forkStart.x, forkStart.y - 0.5F, LegInsertionLoc.Normal));
                    if (forkStart.x != xEnd)
                    {
                        // Empty fork.
                        dropTargets.Add(new DropTarget(xEnd, yEnd - 0.5F, LegInsertionLoc.PostJoin));
                    }
                }
            }
            else if (xEnd != xStart)
            {
                // Below start control (use when a join is going)
                dropTargets.Add(new DropTarget(xStart, yStart + 0.5F, LegInsertionLoc.Normal));
                if (yEnd > yStart)
                {
                    // Right before join point.
                    dropTargets.Add(new DropTarget(xEnd, yEnd - 0.5F, LegInsertionLoc.PostJoin));
                }
            }
            else if (yEnd > yStart + 1.25)
            {
                // Straight down, but must have join at end.
                dropTargets.Add(new DropTarget(xStart, yStart + 0.5F, LegInsertionLoc.Normal));
                dropTargets.Add(new DropTarget(xEnd, yEnd - 0.5F, LegInsertionLoc.PostJoin));
            }
            else
            {
                // Above end control (other cases).
                dropTargets.Add(new DropTarget(xEnd, yEnd - 0.5F, LegInsertionLoc.Normal));
            }

            bool startHorizontal = false;

            if (forkStart != null)
            {
                startHorizontal = forkStart.loopStart;
            }

            if (forkStart != null && forkStart.x != controlPosition2.x)
            {
                // The fork start in a different horizontal position than it ends. This is probably due to a fork with no controls on it.
                // Create the path in two pieces.
                float   xMiddle = forkStart.x;
                float   yMiddle = forkStart.y;
                SymPath path1   = PathFromStartToEnd(xStart, yStart, xMiddle, yMiddle, startHorizontal, 0);
                SymPath path3   = PathFromStartToEnd(xMiddle, yMiddle, xEnd, yEnd, false, controlPosition2.loopBottom);
                SymPath path2   = new SymPath(new[] { path1.LastPoint, path3.FirstPoint });
                return(SymPath.Join(SymPath.Join(path1, path2, PointKind.Normal), path3, PointKind.Normal));
            }
            else
            {
                return(PathFromStartToEnd(xStart, yStart, xEnd, yEnd, startHorizontal, controlPosition2.loopBottom));
            }
        }
示例#8
0
        private void CreateLegBetweenControls(CourseView.ControlView controlView1, ControlPosition controlPosition1, CourseView.ControlView controlView2, ControlPosition controlPosition2, int splitLegIndex, ForkPosition forkStart)
        {
            List <DropTarget> dropTargets;
            SymPath           path      = PathBetweenControls(controlPosition1, controlPosition2, forkStart, out dropTargets);
            CourseObj         courseObj = new TopologyLegCourseObj(controlView1.controlId, controlView1.courseControlIds[splitLegIndex], controlView2.courseControlIds[0], courseObjRatio, appearance, path);
            CourseLayer       layer;

            if (LegInSpecificVariation(controlView1.courseControlIds[splitLegIndex], controlView2.courseControlIds[0]))
            {
                layer = courseLayerSpecificVariation;
            }
            else
            {
                layer = courseLayerAllVariationsAndParts;
            }

            courseObj.layer = layer;
            courseLayout.AddCourseObject(courseObj);

            // No drop targets between map issue and start.
            if (!(eventDB.GetControl(controlView1.controlId).kind == ControlPointKind.MapIssue &&
                  eventDB.GetControl(controlView2.controlId).kind == ControlPointKind.Start))
            {
                // Add the drop targets
                foreach (DropTarget dropTarget in dropTargets)
                {
                    courseObj = new TopologyDropTargetCourseObj(controlView1.controlId, controlView1.courseControlIds[splitLegIndex], controlView2.courseControlIds[0], courseObjRatio, appearance,
                                                                LocationFromAbstractPosition(dropTarget.abstractX, dropTarget.abstractY), dropTarget.insertionLoc);

                    // Along the selected leg, show the drop targets in light gray. Along other legs, drop targets are invisible.
                    if (controlView1.courseControlIds[splitLegIndex] == courseControlIdSelection1 && controlView2.courseControlIds.Contains(courseControlIdSelection2))
                    {
                        courseObj.layer = CourseLayer.AllVariations;
                    }
                    else
                    {
                        courseObj.layer = CourseLayer.InvisibleObjects;
                    }
                    courseLayout.AddCourseObject(courseObj);
                }
            }

            if (forkStart != null && forkStart.variationCode != '\0')
            {
                // There is a variation fork.
                courseObj = CreateVariationCode(controlView1, controlPosition1, splitLegIndex, forkStart);
                courseLayout.AddCourseObject(courseObj);
            }
        }