//----------------------------------------------------------------------------// // // // S t a f f // // // //----------------------------------------------------------------------------// // <editor-fold defaultstate="collapsed" desc="hdr"> // // Copyright © Hervé Bitteur and others 2000-2013. All rights reserved. // // This software is released under the GNU General Public License. // // Goto http://kenai.com/projects/audiveris to report bugs or suggestions. // //----------------------------------------------------------------------------// // </editor-fold> package omr.score.entity; import omr.grid.StaffInfo; import omr.score.visitor.ScoreVisitor; import omr.util.TreeNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.awt.Point; import java.awt.Rectangle; import java.util.Iterator; /** * Class {@code Staff} handles a staff in a system part. * It is useful for its geometric parameters (topLeft corner, width and height, * ability to convert between a Point ordinate and a staff-based * pitchPosition. * But it contains no further entities, the Measure's are the actual containers. * Within a measure, some entities may be assigned a staff, more like a tag than * like a parent. * * @author Hervé Bitteur */ public class Staff extends PartNode { //~ Static fields/initializers --------------------------------------------- /** Usual logger utility */ private static final Logger logger = LoggerFactory.getLogger(Staff.class); //~ Instance fields -------------------------------------------------------- /** Top left corner of the staff (relative to the page top left corner) */ private final Point topLeft; /** Related info from sheet analysis */ private StaffInfo info; /** Id of staff in containing system part */ private final int id; /** Flag an artificial staff */ private boolean dummy; //~ Constructors ----------------------------------------------------------- //-------// // Staff // //-------// /** * Build a staff, given all its parameters. * * @param info the physical information read from the sheet * @param part the containing systemPart * @param topLeft the coordinate of the upper left corner of this staff, * usually null for dummy staves * @param width the staff width * @param height the staff height */ public Staff (StaffInfo info, SystemPart part, Point topLeft, int width, int height) { super(part); this.info = info; this.topLeft = topLeft; if (info != null) { info.setScoreStaff(this); } if (topLeft != null) { setBox(new Rectangle(topLeft.x, topLeft.y, width, height)); getCenter(); } // Assign id id = 1 + getChildIndex(); } //~ Methods ---------------------------------------------------------------- //--------// // accept // //--------// @Override public boolean accept (ScoreVisitor visitor) { return visitor.visit(this); } //-----------// // getHeight // //-----------// /** * Report the height of the staff. * * @return height in units */ public int getHeight () { return getBox().height; } //-------// // getId // //-------// /** * Report the staff id within the containing system part. * * @return the id, counting from 1 */ public int getId () { return id; } //---------// // getInfo // //---------// /** * Report the physical information retrieved from the sheet. * * @return the info entity for this staff */ public StaffInfo getInfo () { return info; } //------------// // getTopLeft // //------------// /** * Report the coordinates of the top left corner of the staff, * wrt the containing page. * * @return the top left coordinates */ public Point getTopLeft () { return topLeft; } //----------// // getWidth // //----------// /** * Report the width of the staff. * * @return the width in units */ public int getWidth () { return getBox().width; } public boolean isDummy () { return dummy; } //-----------------// // pitchPositionOf // //-----------------// /** * Compute the pitch position of a pixel point. * * @param pt the pixel point * @return the pitch position */ public double pitchPositionOf (Point pt) { return info.pitchPositionOf(pt); } //---------------// // pitchToPixels // //---------------// public int pitchToPixels (double pitchPosition) { int interline = getScale() .getInterline(); return (int) Math.rint(((pitchPosition + 4) * interline) / 2.0); } public void setDummy (boolean dummy) { this.dummy = dummy; } //----------// // setWidth // //----------// /** * Set the staff width. * * @param width width of the staff */ public void setWidth (int width) { Rectangle newBox = getBox(); reset(); newBox.width = width; setBox(newBox); getCenter(); } //----------// // toString // //----------// @Override public String toString () { StringBuilder sb = new StringBuilder("{Staff"); try { if (isDummy()) { sb.append(" dummy"); } sb.append(" topLeft=") .append(topLeft); sb.append(" width=") .append(getWidth()); sb.append(" size=") .append(getHeight()); } catch (NullPointerException e) { sb.append("NONE"); } sb.append("}"); return sb.toString(); } //~ Inner Classes ---------------------------------------------------------- //--------------// // PartIterator // //--------------// /** * Class {@code PartIterator} implements an iterator on the * sequence of staves within all parallel measures of a SystemPart. */ public static class PartIterator implements Iterator<Staff> { //~ Instance fields ---------------------------------------------------- // Constant private final Iterator<TreeNode> staffIterator; //~ Constructors ------------------------------------------------------- public PartIterator (Measure measure) { staffIterator = measure.getPart() .getStaves() .iterator(); } //~ Methods ------------------------------------------------------------ @Override public boolean hasNext () { return staffIterator.hasNext(); } @Override public Staff next () { return (Staff) staffIterator.next(); } @Override public void remove () { throw new UnsupportedOperationException("Not supported operation"); } } //----------------// // SystemIterator // //----------------// /** * Class {@code SystemIterator} implements an iterator on the * sequence of staves within all parallel measures of a system * whatever the containing part. */ public static class SystemIterator implements Iterator<Staff> { //~ Instance fields ---------------------------------------------------- // Constant private final int measureIndex; private final Iterator<TreeNode> partIterator; // Non constant private SystemPart part; private Measure measure; private PartIterator partStaffIterator; //~ Constructors ------------------------------------------------------- public SystemIterator (Measure measure) { measureIndex = measure.getParent() .getChildren() .indexOf(measure); partIterator = measure.getSystem() .getParts() .iterator(); if (partIterator.hasNext()) { toNextPart(); } } //~ Methods ------------------------------------------------------------ public Measure getMeasure () { return measure; } public SystemPart getPart () { return part; } @Override public boolean hasNext () { if (partStaffIterator == null) { return false; } else if (partStaffIterator.hasNext()) { return true; } else { // Do we have following parts? if (partIterator.hasNext()) { toNextPart(); return partStaffIterator.hasNext(); } else { // This is the end ... return false; } } } @Override public Staff next () { if (hasNext()) { return partStaffIterator.next(); } else { return null; } } @Override public void remove () { throw new UnsupportedOperationException("Not supported operation."); } private void toNextPart () { part = (SystemPart) partIterator.next(); measure = (Measure) part.getMeasures() .get(measureIndex); partStaffIterator = new PartIterator(measure); } } }