Skip to content

Commit

Permalink
feat(osmd.GraphicSheet): Add generic GetNearestObject<T>(clickPos) me…
Browse files Browse the repository at this point in the history
…thod, e.g. for GraphicalMeasure
  • Loading branch information
sschmidTU committed Apr 5, 2024
1 parent c86587e commit 2de6b62
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions src/MusicalScore/Graphical/GraphicalMusicSheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,60 @@ export class GraphicalMusicSheet {
return undefined;
}

/** Returns nearest object of type T near clickPosition.
* E.g. GetNearestObject<GraphicalMeasure>(pos, "GraphicalMeasure") returns the nearest measure.
* Note that there is also GetNearestStaffEntry(), which has a bit more specific code for staff entries.
* */
public GetNearestObject<T extends GraphicalObject>(clickPosition: PointF2D, className: string): T {
const initialSearchArea: number = 10;
const foundEntries: T[] = [];
// Prepare search area
const region: BoundingBox = new BoundingBox(undefined);
region.BorderLeft = clickPosition.x - initialSearchArea;
region.BorderTop = clickPosition.y - initialSearchArea;
region.BorderRight = clickPosition.x + initialSearchArea;
region.BorderBottom = clickPosition.y + initialSearchArea;
region.AbsolutePosition = new PointF2D(0, 0);
// Search for StaffEntries in region
for (let idx: number = 0, len: number = this.MusicPages.length; idx < len; ++idx) {
const graphicalMusicPage: GraphicalMusicPage = this.MusicPages[idx];
const entries: T[] = graphicalMusicPage.PositionAndShape.getObjectsInRegion<T>(region, false, className);
if (!entries || entries.length === 0) {
continue;
} else {
for (let idx2: number = 0, len2: number = entries.length; idx2 < len2; ++idx2) {
const entry: T = entries[idx2];
foundEntries.push(entry);
}
}
}
// Get closest entry
let closest: T = undefined;
for (let idx: number = 0, len: number = foundEntries.length; idx < len; ++idx) {
const foundEntry: T = foundEntries[idx];
if (closest === undefined) {
closest = foundEntry;
} else {
// if (!foundEntry.relInMeasureTimestamp) {
// relInMeasureTimestamp doesn't necessarily exist on generic type T, as it does on GraphicalStaffEntry
// continue;
// }
const deltaNew: number = this.CalculateDistance(foundEntry.PositionAndShape.AbsolutePosition, clickPosition);
const deltaOld: number = this.CalculateDistance(closest.PositionAndShape.AbsolutePosition, clickPosition);
if (deltaNew < deltaOld) {
closest = foundEntry;
}
}
}
if (closest) {
return closest;
}
// TODO No object of type T was found. Feedback?
// throw new ArgumentException(`No object of type ${className} found`);
return undefined;
}


public GetPossibleCommentAnchor(clickPosition: PointF2D): SourceStaffEntry {
const entry: GraphicalStaffEntry = this.GetNearestStaffEntry(clickPosition);
if (!entry) {
Expand Down

0 comments on commit 2de6b62

Please sign in to comment.