use of com.xenoage.utils.math.geom.Point2f in project Zong by Xenoage.
the class Content method onClick.
/**
* This method is called when the mouse was clicked on the content.
* A message with the clicked element is shown to the user.
*/
public void onClick(Point2f positionPx) {
if (layout.getScoreFrames().size() == 0)
return;
// get the layout of first score frame
ScoreFrame frame = layout.getScoreFrames().get(0);
ScoreFrameLayout frameLayout = frame.getScoreFrameLayout();
// convert position from screen space to page space, then from page space
// to frame space, and them from frame space to score frame space
Point2f positionMm = positionPx.scale(Units.pxToMm(1, mainWindow.getZoom()));
Point2f framePositionMm = positionMm.sub(frame.getAbsolutePosition());
Point2f scorePositionMm = frame.getScoreLayoutPosition(framePositionMm);
// find elements under this position
for (Stamping stamping : frameLayout.getAllStampings()) {
if (stamping.getBoundingShape() != null && stamping.getBoundingShape().contains(scorePositionMm)) {
MusicElement element = stamping.getMusicElement();
if (element != null) {
// music element found
String message = "An element was clicked: " + element;
if (element instanceof MPElement) {
// music element with a known musical position found
MPElement mpElement = (MPElement) element;
if (mpElement.getParent() != null)
message += " at " + mpElement.getMP();
}
mainWindow.showMessageDialog(message);
}
}
}
}
use of com.xenoage.utils.math.geom.Point2f in project Zong by Xenoage.
the class PageViewManagerTest method getPageDisplayOffset.
@Test
public void getPageDisplayOffset() {
float distance = view.pageDisplayDistance;
float d = Delta.DELTA_FLOAT;
// page 1
Point2f p = view.getPageDisplayOffset(0);
assertEquals(-100 / 2, p.x, d);
assertEquals(-200 / 2, p.y, d);
// page 2
p = view.getPageDisplayOffset(1);
assertEquals(100 / 2 + distance, p.x, d);
assertEquals(-100 / 2, p.y, d);
// page 3
p = view.getPageDisplayOffset(2);
assertEquals(100 / 2 + distance + 200 + distance, p.x, d);
assertEquals(-200 / 2, p.y, d);
}
use of com.xenoage.utils.math.geom.Point2f in project Zong by Xenoage.
the class PageViewManagerTest method computeScreenPosition.
@Test
public void computeScreenPosition() {
Size2i viewSize = new Size2i(800, 600);
float viewScaling = 1;
Point2f viewScroll = new Point2f(0, 0);
ViewState viewState = new ViewState(viewSize, viewScaling, viewScroll);
// center point of the page must have screen coordinates 400/300
Point2i pos = view.computePositionPx(layoutPos(null, 0, p(50, 100)), viewState);
assertEquals(pos.x, 400);
assertEquals(pos.y, 300);
// set zoom to 200%, must still be 400/300
viewScaling = 2;
viewState = new ViewState(viewSize, viewScaling, viewScroll);
pos = view.computePositionPx(layoutPos(null, 0, p(50, 100)), viewState);
assertEquals(pos.x, 400);
assertEquals(pos.y, 300);
// scroll to -5/10
// page point 45/110 must be 400/300
viewScroll = new Point2f(-5, 10);
viewState = new ViewState(viewSize, viewScaling, viewScroll);
pos = view.computePositionPx(layoutPos(null, 0, p(45, 110)), viewState);
assertEquals(pos.x, 400);
assertEquals(pos.y, 300);
// page center point must be
// 400-(-5*MmToPx*zoom); 300-(10*MmToPx*zoom)
pos = view.computePositionPx(layoutPos(null, 0, p(50, 100)), viewState);
assertEquals(pos.x, Math.round(400 - Units.mmToPx(-5, viewScaling)));
assertEquals(pos.y, Math.round(300 - Units.mmToPx(10, viewScaling)));
}
use of com.xenoage.utils.math.geom.Point2f in project Zong by Xenoage.
the class ScoreDocScoreView method updateScreen.
@Override
public void updateScreen(Size2i screenSizePx, float zoom) {
this.screenSizePx = screenSizePx;
this.zoom = zoom;
// recompute the layout, so that each page fits into the available screen space
Size2f pageSizeMm = pxToMm(screenSizePx, zoom);
float marginMm = pxToMm(marginPx, zoom);
PageFormat pageFormat = new PageFormat(pageSizeMm, new PageMargins(marginMm, marginMm, marginMm, marginMm));
Size2f frameSizeMm = new Size2f(pageFormat.getUseableWidth(), pageFormat.getUseableHeight());
// first page needs space for title text
titleTextHeightPx = screenSizePx.height / 20f;
float firstFrameOffsetY = pxToMm(titleTextHeightPx, zoom);
Size2f firstFrameSizeMm = new Size2f(frameSizeMm.width, frameSizeMm.height - firstFrameOffsetY);
// delete unnecessary layout information, like system distances or system breaks
Score score = doc.getScore();
score.setFormat(new ScoreFormat());
ScoreHeader header = score.getHeader();
for (int i : range(header.getSystemLayouts())) {
SystemLayout sl = header.getSystemLayout(i);
if (sl != null)
sl.setDistance(SystemLayout.defaultDistance);
}
for (int i : range(header.getColumnHeaders())) {
ColumnHeader ch = header.getColumnHeader(i);
if (ch.getMeasureBreak() != null)
ch.setBreak(null);
}
// layout the score to find out the needed space
Context context = new Context(score, App.getSymbolPool(), doc.getLayout().getDefaults().getLayoutSettings());
Target target = new Target(alist(new ScoreLayoutArea(firstFrameSizeMm)), new ScoreLayoutArea(frameSizeMm), true);
ScoreLayouter layouter = new ScoreLayouter(context, target);
ScoreLayout scoreLayout = layouter.createScoreLayout();
// create and fill at least one page
Layout layout = new Layout(doc.getLayout().getDefaults());
ScoreFrameChain chain = null;
for (int i = 0; i < scoreLayout.frames.size(); i++) {
Page page = new Page(pageFormat);
Point2f position;
Size2f size;
if (i == 0) {
// first page
position = new Point2f(pageSizeMm.width / 2, pageSizeMm.height / 2 + firstFrameOffsetY);
size = firstFrameSizeMm;
} else {
// other pages
position = new Point2f(pageSizeMm.width / 2, pageSizeMm.height / 2);
size = frameSizeMm;
}
ScoreFrame frame = new ScoreFrame();
frame.setPosition(position);
frame.setSize(size);
page.addFrame(frame);
layout.addPage(page);
if (chain == null) {
chain = new ScoreFrameChain(score);
chain.setScoreLayout(scoreLayout);
}
chain.add(frame);
}
this.layout = layout;
}
use of com.xenoage.utils.math.geom.Point2f in project Zong by Xenoage.
the class Frame method getFP.
/**
* Transforms the given coordinates in page space to a {@link FP}.
* If the given coordinates are not within this frame and force is false,
* null is returned. Otherwise the computed coordinates are returned, even if
* they are outside the frame.
*/
public FP getFP(Point2f p, boolean force) {
Point2f pos = getAbsolutePosition();
float rot = getAbsoluteRotation();
float hw = size.width / 2;
float hh = size.height / 2;
// two cases: no rotation or rotation
if (rot == 0f) {
// no rotation. this is easy to compute.
if (force || (p.x >= pos.x - hw && p.x <= pos.x + hw && p.y >= pos.y - hh && p.y <= pos.y + hh)) {
return new FP(this, new Point2f(p.x - pos.x, p.y - pos.y));
}
} else {
// rotated frame. this is more complicated.
// first fast check: point within circle around center point?
float radius = max(size.width, size.height);
Point2f pRel = new Point2f(p.x - pos.x, p.y - pos.y);
float distanceSq = pRel.x * pRel.x + pRel.y * pRel.y;
if (force || (distanceSq <= radius * radius)) {
// the given point could be within the frame. rotate the
// point and check again.
pRel = MathUtils.INSTANCE.rotate(pRel, -rot);
if (force || (pRel.x >= -hw && pRel.x <= +hw && pRel.y >= -hh && pRel.y <= +hh)) {
return new FP(this, new Point2f(pRel.x, pRel.y));
}
}
}
return null;
}
Aggregations