private void AddStructureLink(StructureObj SourceObj, SortedList<long, GridVector2> SourcePositions, long TargetStructID) { ConcurrentDictionary<long, LocationObj> LinkedLocationsOnSection; bool success = LocationsForStructure.TryGetValue(TargetStructID, out LinkedLocationsOnSection); if (success == false) return; SortedList<long, GridVector2> TargetPositions = new SortedList<long, GridVector2>(LinkedLocationsOnSection.Count); foreach (long locID in LinkedLocationsOnSection.Keys) { GridVector2 position; bool Success = TransformedLocationPositionDict.TryGetValue(locID, out position); if (Success) TargetPositions.Add(locID, position); } long BestSourceLocID = -1; long BestTargetLocID = -1; GridVector2 Origin = new GridVector2(); GridVector2 Destination = new GridVector2(); double MinDistance = double.MaxValue; //Brute force a search for the shortest distance between the two structures. foreach (long SourceID in SourcePositions.Keys) { GridVector2 SourcePos = SourcePositions[SourceID]; foreach (long TargetID in TargetPositions.Keys) { GridVector2 TargetPos = TargetPositions[TargetID]; double dist = GridVector2.Distance(SourcePos, TargetPos); if (dist < MinDistance) { BestSourceLocID = SourceID; BestTargetLocID = TargetID; Origin = SourcePos; Destination = TargetPos; MinDistance = dist; } } } //Could not find a pair if (MinDistance == double.MaxValue) return; StructureObj TargetStruct = Store.Structures.GetObjectByID(TargetStructID); GridLineSegment lineSegment = new GridLineSegment(Origin, Destination); StructureLinkObj StructLink = new StructureLinkObj(SourceObj.ID, TargetStructID, Locations[BestSourceLocID], Locations[BestTargetLocID], lineSegment); StructLink.AfterDelete += StructureLinkDeletedEventHandler; if (StructureLinksSearch.Contains(lineSegment)) { StructureLinkObj oldLink = StructureLinksSearch[lineSegment]; oldLink.AfterDelete -= StructureLinkDeletedEventHandler; StructureLinksSearch.Remove(lineSegment); } StructureLinksSearch.Add(lineSegment, StructLink); }
protected override void OnMouseUp(object sender, MouseEventArgs e) { //Figure out if we've clicked another structure and create the structure if (e.Button == MouseButtons.Left) { GridVector2 WorldPos = Parent.ScreenToWorld(e.X, e.Y); SectionLocationsViewModel sectionAnnotations = AnnotationOverlay.GetAnnotationsForSection(Parent.Section.Number); if (sectionAnnotations == null) return; //Find if we are close enough to a location to "snap" the line to the target double distance; NearestTarget = Overlay.GetNearestLocation(WorldPos, out distance); NearestTarget = ValidateTarget(NearestTarget); if(NearestTarget == null) { this.Deactivated = true; return; } if(NearestTarget.ParentID == OriginObj.ParentID) { try { Store.LocationLinks.CreateLink(OriginObj.modelObj.ID, NearestTarget.modelObj.ID); } catch (Exception except) { MessageBox.Show("Could not create link between locations: " + except.Message, "Recoverable Error"); } finally { this.Deactivated = true; } } else { try { StructureLinkObj linkStruct = new StructureLinkObj(OriginObj.ParentID.Value, NearestTarget.ParentID.Value, false); linkStruct = Store.StructureLinks.Create(linkStruct); } catch (Exception except) { MessageBox.Show("Could not create link between structures: " + except.Message, "Recoverable Error"); } finally { this.Deactivated = true; } //HACK: This updates the UI to show the new structure link. It should be automatic, but force it for now... //sectionAnnotations.AddStructureLinks(OriginObj.Parent); //sectionAnnotations.AddStructureLinks(NearestTarget.Parent); } this.Execute(); } base.OnMouseDown(sender, e); }