// Get the text for a control lable private static string GetControlLabelText(EventDB eventDB, ControlLabelKind labelKind, CourseView.ControlView controlView, CourseView courseView) { string text = ""; List<CourseView.ControlView> repeatedControlViews = FindControlViewsWithControlId(courseView, controlView.controlId); if (repeatedControlViews.Count > 1 && repeatedControlViews[0] != controlView) { // This control is repeated (e.g., like a butterfly course) and is not the first use of this control. Don't put any text. return ""; } if (labelKind == ControlLabelKind.Sequence || labelKind == ControlLabelKind.SequenceAndCode || labelKind == ControlLabelKind.SequenceAndScore) { text += controlView.ordinal.ToString(); // Add in numbers for repeated controls. for (int i = 1; i < repeatedControlViews.Count; ++i) { text += "/"; text += repeatedControlViews[i].ordinal.ToString(); } } if (labelKind == ControlLabelKind.SequenceAndCode) text += "-"; if (labelKind == ControlLabelKind.SequenceAndCode || labelKind == ControlLabelKind.Code || labelKind == ControlLabelKind.CodeAndScore) { ControlPoint control = eventDB.GetControl(controlView.controlId); text += control.code; } if (labelKind == ControlLabelKind.CodeAndScore || labelKind == ControlLabelKind.SequenceAndScore) { int points = eventDB.GetCourseControl(controlView.courseControlIds[0]).points; if (points > 0) { text += "(" + points.ToString() + ")"; } } return text; }
// Create the control number text object, avoiding existing objects on the map. This can be in the form of a sequence number, code, or both. private static CourseObj CreateControlNumber(EventDB eventDB, float scaleRatio, CourseAppearance appearance, ControlLabelKind labelKind, CourseView.ControlView controlView, CourseView courseView, IEnumerable<CourseObj> existingObjects) { ControlPoint control = eventDB.GetControl(controlView.controlId); CourseControl courseControl = eventDB.GetCourseControl(controlView.courseControlIds[0]); PointF controlLocation = control.location; PointF textCenterLocation; string text; if (control.kind == ControlPointKind.Normal) { text = GetControlLabelText(eventDB, labelKind, controlView, courseView); // Figure out where the control number goes. if (courseControl.customNumberPlacement) { textCenterLocation = new PointF(controlLocation.X + courseControl.numberDeltaX, controlLocation.Y + courseControl.numberDeltaY); } else { FontDesc fontDesc = appearance.numberBold ? NormalCourseAppearance.controlNumberFont : NormalCourseAppearance.controlNumberFontBold; textCenterLocation = GetTextLocation(controlLocation, (NormalCourseAppearance.controlOutsideDiameter / 2F + NormalCourseAppearance.controlNumberCircleDistance) * scaleRatio * appearance.controlCircleSize, text, fontDesc, scaleRatio * appearance.numberHeight, existingObjects); } return new ControlNumberCourseObj(controlView.controlId, controlView.courseControlIds[0], scaleRatio, appearance, text, textCenterLocation); } else { // Only normal controls have numbers. return null; } }
// Change the attributes of a course. public static void ChangeCourseProperties(EventDB eventDB, Id<Course> courseId, CourseKind courseKind, string courseName, ControlLabelKind labelKind, int scoreColumn, string secondaryTitle, float printScale, float climb, float? length, DescriptionKind descriptionKind, int firstControlOrdinal) { Course course = eventDB.GetCourse(courseId); course = (Course) course.Clone(); course.kind = courseKind; course.labelKind = labelKind; course.scoreColumn = scoreColumn; course.name = courseName; course.secondaryTitle = secondaryTitle; course.printScale = printScale; course.climb = climb; course.overrideCourseLength = length; course.descKind = descriptionKind; course.firstControlOrdinal = firstControlOrdinal; eventDB.ReplaceCourse(courseId, course); }
// Create a new course with the given attributes. The course sorts after all existing courses. // If addStartAndFinish is true, then if exact one start control exists, it is added. If exactly one finish control exists, it is added. public static Id<Course> CreateCourse(EventDB eventDB, CourseKind courseKind, string name, ControlLabelKind labelKind, int scoreColumn, string secondaryTitle, float printScale, float climb, float? length, DescriptionKind descriptionKind, int firstControlOrdinal, bool addStartAndFinish) { // Find max sort order in use. int maxSortOrder = 0; foreach (Course course in eventDB.AllCourses) if (course.sortOrder > maxSortOrder) maxSortOrder = course.sortOrder; PrintArea printArea = (PrintArea) eventDB.GetEvent().printArea.Clone(); Course newCourse = new Course(courseKind, name, printScale, maxSortOrder + 1); newCourse.secondaryTitle = secondaryTitle; newCourse.climb = climb; newCourse.overrideCourseLength = length; newCourse.descKind = descriptionKind; newCourse.labelKind = labelKind; newCourse.scoreColumn = scoreColumn; newCourse.firstControlOrdinal = firstControlOrdinal; newCourse.printArea = printArea; Id<Course> newCourseId = eventDB.AddCourse(newCourse); if (addStartAndFinish) { // Add unique start and finish, if they exist. Id<ControlPoint> uniqueStart = FindUniqueControl(eventDB, newCourseId, ControlPointKind.Start); if (uniqueStart.IsNotNone) AddStartToCourse(eventDB, uniqueStart, newCourseId, false); Id<ControlPoint> uniqueFinish = FindUniqueControl(eventDB, newCourseId, ControlPointKind.Finish); if (uniqueFinish.IsNotNone) AddFinishToCourse(eventDB, uniqueFinish, newCourseId, false); } return newCourseId; }
public override void ReadAttributesAndContent(XmlInput xmlinput) { string kindText = xmlinput.GetAttributeString("kind"); switch (kindText) { case "normal": kind = CourseKind.Normal; break; case "score": kind = CourseKind.Score; break; default: xmlinput.BadXml("Invalid course kind '{0}'", kindText); break; } sortOrder = xmlinput.GetAttributeInt("order", 0); // 0 sort orders fixed up later in EventDB.FixCourseSortOrders() name = ""; printScale = 15000; descKind = DescriptionKind.Symbols; firstCourseControl = Id<CourseControl>.None; firstControlOrdinal = 1; labelKind = (kind == CourseKind.Score) ? ControlLabelKind.Code : ControlLabelKind.Sequence; scoreColumn = (kind == CourseKind.Score) ? 0 : -1; bool first = true; while (xmlinput.FindSubElement(first, "name", "secondary-title", "first", "print-area", "options", "labels", "part-options", "relay")) { switch (xmlinput.Name) { case "name": name = xmlinput.GetContentString(); break; case "secondary-title": secondaryTitle = xmlinput.GetContentString(); break; case "first": firstCourseControl = new Id<CourseControl>(xmlinput.GetAttributeInt("course-control")); firstControlOrdinal = xmlinput.GetAttributeInt("control-number", 1); xmlinput.Skip(); break; case "print-area": PrintArea area = new PrintArea(); int part = xmlinput.GetAttributeInt("part", -1); area.ReadAttributesAndContent(xmlinput); if (part == -1) printArea = area; else partPrintAreas[part] = area; break; case "options": printScale = xmlinput.GetAttributeFloat("print-scale"); climb = xmlinput.GetAttributeFloat("climb", -1F); load = xmlinput.GetAttributeInt("load", -1); if (kind == CourseKind.Score) scoreColumn = EventDBUtil.ReadScoreColumnAttribute(xmlinput); descKind = EventDBUtil.ReadDescriptionKindAttribute(xmlinput); float len = xmlinput.GetAttributeFloat("course-length", -1F); if (len > 0) overrideCourseLength = len; else overrideCourseLength = null; xmlinput.Skip(); break; case "part-options": part = xmlinput.GetAttributeInt("part", -1); bool showFinish = xmlinput.GetAttributeBool("show-finish"); if (part != -1) partOptions[part] = new PartOptions() { ShowFinish = showFinish }; xmlinput.Skip(); break; case "labels": string labelKindText = xmlinput.GetAttributeString("label-kind"); switch (labelKindText) { case "sequence": labelKind = ControlLabelKind.Sequence; break; case "code": labelKind = ControlLabelKind.Code; break; case "sequence-and-code": labelKind = ControlLabelKind.SequenceAndCode; break; case "sequence-and-score": labelKind = ControlLabelKind.SequenceAndScore; break; case "code-and-score": labelKind = ControlLabelKind.CodeAndScore; break; default: labelKind = ControlLabelKind.Sequence; break; } xmlinput.Skip(); break; case "relay": relayTeams = xmlinput.GetAttributeInt("teams", 0); relayLegs = xmlinput.GetAttributeInt("legs", 1); xmlinput.Skip(); break; } first = false; } if (printArea == null) printArea = PrintArea.DefaultPrintArea; }
public Course(CourseKind kind, string name, float printScale, int sortOrder): this() { this.kind = kind; this.name = name; this.printScale = printScale; this.sortOrder = sortOrder; this.labelKind = (kind == CourseKind.Score) ? ControlLabelKind.Code : ControlLabelKind.Sequence; this.overrideCourseLength = null; this.climb = -1; this.load = -1; this.firstControlOrdinal = 1; this.scoreColumn = -1; this.printArea = PrintArea.DefaultPrintArea; }