public override void LeftButtonDrag(Pane pane, PointF location, PointF locationStart, float pixelSize, ref bool displayUpdateNeeded) { Debug.Assert(pane == Pane.Map); // Get the new set of gaps. CircleGap[] newGaps = CircleGap.AddGap(courseObjStart.location, courseObjStart.gaps, startDrag, location); CircleGap[] newMovableGaps = CircleGap.AddGap(courseObjStart.location, courseObjStart.movableGaps, startDrag, location); // Put the new gaps into the highlight. courseObjDrag = (PointCourseObj)courseObjStart.Clone(); courseObjDrag.gaps = newGaps; courseObjDrag.movableGaps = newMovableGaps; displayUpdateNeeded = true; }
// Hit test a point to see if it is over an existing control, or will create a new control. Id <ControlPoint> HitTestPoint(PointF mouseLocation, float pixelSize, out PointF highlightLocation) { if (allControls) { // If all controls, always new control. highlightLocation = new PointF(mouseLocation.X + PIXELOFFSETX * pixelSize, mouseLocation.Y + PIXELOFFSETY * pixelSize); return(Id <ControlPoint> .None); } else { // Are we over a control we might add? CourseLayout layout = controller.GetCourseLayout(); PointCourseObj courseObj = layout.HitTest(mouseLocation, pixelSize, CourseLayer.AllControls, (co => co is PointCourseObj)) as PointCourseObj; if (courseObj != null) { highlightLocation = courseObj.location; return(courseObj.controlId); } else { courseObj = layout.HitTest(mouseLocation, pixelSize, CourseLayer.MainCourse, (co => co is PointCourseObj)) as PointCourseObj; if (courseObj != null && courseObj.controlId.IsNotNone) { // Allow selecting a control in the current course for a butterfly course. But -- it must be a normal control or crossing point, and not adjacent to the control being inserted. if (eventDB.GetControl(courseObj.controlId).kind == controlKind && (controlKind == ControlPointKind.Normal || controlKind == ControlPointKind.CrossingPoint)) { Id <CourseControl> courseControl1, courseControl2; CourseDesignator courseDesignator; LegInsertionLoc legInsertionLoc; GetControlInsertionPoint(courseObj.location, out courseDesignator, out courseControl1, out courseControl2, out legInsertionLoc); if (eventDB.GetCourse(courseDesignator.CourseId).kind != CourseKind.Score && (exchangeAtControl || (courseObj.courseControlId != courseControl1 && courseObj.courseControlId != courseControl2))) { highlightLocation = courseObj.location; return(courseObj.controlId); } } } highlightLocation = new PointF(mouseLocation.X + PIXELOFFSETX * pixelSize, mouseLocation.Y + PIXELOFFSETY * pixelSize); return(Id <ControlPoint> .None); } } }
// Create the highlight, and put it at the given location. // Set displayUpdateNeeded to true if the highlight was just created or was moved. void SetHighlightLocation(PointF highlightLocation, float pixelSize, ref bool displayUpdateNeeded) { if (highlight != null && highlight.location == highlightLocation) { return; } // Note, we cannot change this existing highlight because it is needed for erasing. switch (specialKind) { case SpecialKind.FirstAid: highlight = new FirstAidCourseObj(Id <Special> .None, courseObjRatio, appearance, highlightLocation); break; case SpecialKind.Water: highlight = new WaterCourseObj(Id <Special> .None, courseObjRatio, appearance, highlightLocation); break; case SpecialKind.OptCrossing: highlight = new CrossingCourseObj(Id <ControlPoint> .None, Id <CourseControl> .None, Id <Special> .None, courseObjRatio, appearance, 0, 0, highlightLocation); break; case SpecialKind.Forbidden: highlight = new ForbiddenCourseObj(Id <Special> .None, courseObjRatio, appearance, highlightLocation); break; case SpecialKind.RegMark: highlight = new RegMarkCourseObj(Id <Special> .None, courseObjRatio, appearance, highlightLocation); break; default: throw new Exception("bad special kind"); } highlight.location = highlightLocation; displayUpdateNeeded = true; }
public AddControlGapMode(Controller controller, PointCourseObj courseObj) { this.controller = controller; this.courseObjStart = (PointCourseObj)courseObj.Clone(); this.courseObjDrag = (PointCourseObj)courseObj.Clone(); }
PointCourseObj courseObj; // object to modify. public RemoveControlGapMode(Controller controller, PointCourseObj courseObj) { this.controller = controller; this.courseObj = (PointCourseObj)courseObj.Clone(); }
// Create the highlight, and put it at the given location. // Set displayUpdateNeeded to true if the highlight was just created or was moved. void SetHighlightLocation(PointF highlightLocation, float pixelSize, ref bool displayUpdateNeeded) { if (highlight != null && highlight.location == highlightLocation) { return; } PointF unused; Id <ControlPoint> existingControl = HitTestPoint(highlightLocation, pixelSize, out unused); // Get where the control is being inserted. CourseDesignator courseDesignator; Id <CourseControl> courseControl1, courseControl2; LegInsertionLoc legInsertionLoc; GetControlInsertionPoint(highlightLocation, out courseDesignator, out courseControl1, out courseControl2, out legInsertionLoc); // Note, we cannot changed this existing highlight because it is needed for erasing. additionalHighlights = null; switch (controlKind) { case ControlPointKind.Normal: highlight = new ControlCourseObj(Id <ControlPoint> .None, Id <CourseControl> .None, courseObjRatio, appearance, null, highlightLocation); if (courseDesignator.IsNotAllControls && !(exchangeAtControl && existingControl.IsNotNone && QueryEvent.CourseUsesControl(eventDB, courseDesignator, existingControl)) && eventDB.GetCourse(courseDesignator.CourseId).kind != CourseKind.Score) { // Show the legs to and from the control also as additional highlights. additionalHighlights = CreateLegHighlights(eventDB, highlightLocation, Id <ControlPoint> .None, controlKind, courseControl1, courseControl2, courseObjRatio, appearance); } break; case ControlPointKind.MapIssue: highlight = new MapIssueCourseObj(Id <ControlPoint> .None, Id <CourseControl> .None, courseObjRatio, appearance, 0, highlightLocation, MapIssueCourseObj.RenderStyle.WithTail); break; case ControlPointKind.Start: highlight = new StartCourseObj(Id <ControlPoint> .None, Id <CourseControl> .None, courseObjRatio, appearance, 0, highlightLocation, CrossHairOptions.HighlightCrossHair); break; case ControlPointKind.MapExchange: highlight = new StartCourseObj(Id <ControlPoint> .None, Id <CourseControl> .None, courseObjRatio, appearance, 0, highlightLocation, CrossHairOptions.HighlightCrossHair); if (courseDesignator.IsNotAllControls && eventDB.GetCourse(courseDesignator.CourseId).kind != CourseKind.Score) { // Show the legs to and from the control also as additional highlights. additionalHighlights = CreateLegHighlights(eventDB, highlightLocation, Id <ControlPoint> .None, controlKind, courseControl1, courseControl2, courseObjRatio, appearance); } break; case ControlPointKind.Finish: highlight = new FinishCourseObj(Id <ControlPoint> .None, Id <CourseControl> .None, courseObjRatio, appearance, null, highlightLocation, CrossHairOptions.HighlightCrossHair); break; case ControlPointKind.CrossingPoint: highlight = new CrossingCourseObj(Id <ControlPoint> .None, Id <CourseControl> .None, Id <Special> .None, courseObjRatio, appearance, 0, 0, highlightLocation); if (courseDesignator.IsNotAllControls && eventDB.GetCourse(courseDesignator.CourseId).kind != CourseKind.Score) { // Show the legs to and from the control also as additional highlights. additionalHighlights = CreateLegHighlights(eventDB, highlightLocation, Id <ControlPoint> .None, controlKind, courseControl1, courseControl2, courseObjRatio, appearance); } break; default: throw new Exception("bad control kind"); } highlight.location = highlightLocation; displayUpdateNeeded = true; }
public override void LeftButtonEndDrag(Pane pane, PointF location, PointF locationStart, float pixelSize, ref bool displayUpdateNeeded) { Debug.Assert(pane == Pane.Map); float deltaX = (location.X - startDrag.X); float deltaY = (location.Y - startDrag.Y); PointF newHandleLocation = new PointF(handleLocation.X + deltaX, handleLocation.Y + deltaY); if (courseObjectStart.specialId.IsNotNone) { // Moving a corner of a special Id <Special> specialId = courseObjectStart.specialId; if (courseObjectStart is DescriptionCourseObj) { // Moving a description. Descriptions are rather special in the way their locations are used. DescriptionCourseObj descObj = (DescriptionCourseObj)courseObjectStart.Clone(); descObj.MoveHandle(handleLocation, location); controller.MoveSpecial(specialId, new PointF[2] { new PointF(descObj.rect.Left, descObj.rect.Bottom), new PointF(descObj.rect.Left + descObj.CellSize, descObj.rect.Bottom) }, descObj.NumberOfColumns); } else if (courseObjectStart is RectCourseObj) { // Moving rectangle handles is sort of special too. RectCourseObj rectObj = (RectCourseObj)courseObjectStart.Clone(); rectObj.MoveHandle(handleLocation, location); RectangleF rect = rectObj.rect; controller.MoveSpecial(specialId, new PointF[2] { new PointF(rect.Left, rect.Bottom), new PointF(rect.Right, rect.Top) }); } else if (courseObjectStart is BasicTextCourseObj) { // Moving text handles is sort of special too. BasicTextCourseObj textObj = (BasicTextCourseObj)courseObjectStart.Clone(); textObj.MoveHandle(handleLocation, location); RectangleF rect = textObj.GetHighlightBounds(); rect = textObj.AdjustBoundingRect(rect); controller.MoveSpecial(specialId, new PointF[2] { new PointF(rect.Left, rect.Bottom), new PointF(rect.Right, rect.Top) }); } else { controller.MoveSpecialPoint(specialId, handleLocation, newHandleLocation); } } else if ((courseObjectStart is LegCourseObj) || (courseObjectStart is FlaggedLegCourseObj)) { // Moving a leg bend. LineCourseObj lineCourseObj = (LineCourseObj)courseObjectStart; controller.MoveLegBendOrGap(lineCourseObj.courseControlId, lineCourseObj.courseControlId2, handleLocation, newHandleLocation); } else if ((courseObjectStart is ControlCourseObj) || (courseObjectStart is FinishCourseObj)) { PointCourseObj pointObj = (PointCourseObj)courseObjectStart.Clone(); pointObj.MoveHandle(handleLocation, location); controller.MoveControlGap(courseObjectStart.controlId, pointObj.movableGaps); } else { Debug.Fail("unknown situation"); } controller.DefaultCommandMode(); }