//----------------------------------------------------------------------------//
// //
// S h e e t P a i n t e r //
// //
//----------------------------------------------------------------------------//
// <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.sheet.ui;
import omr.glyph.facets.Glyph;
import omr.grid.StaffInfo;
import omr.score.entity.Measure;
import omr.score.entity.Page;
import omr.score.entity.ScoreSystem;
import omr.score.entity.SystemPart;
import omr.score.visitor.AbstractScoreVisitor;
import omr.sheet.Sheet;
import omr.sheet.SystemInfo;
import omr.ui.Colors;
import omr.ui.symbol.Alignment;
import omr.ui.symbol.MusicFont;
import omr.ui.symbol.ShapeSymbol;
import omr.ui.symbol.Symbols;
import omr.ui.util.UIUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Stroke;
import java.util.ConcurrentModificationException;
/**
* Class {@code SheetPainter} defines for every node in Page hierarchy
* the rendering of related sections (with preset colors) in the dedicated
* <b>Sheet</b> display.
*
* <p>Nota: It has been extended to deal with rendering of initial sheet
* elements.
*
* @author Hervé Bitteur
*/
public class SheetPainter
extends AbstractScoreVisitor
{
//~ Static fields/initializers ---------------------------------------------
/** Usual logger utility */
private static final Logger logger = LoggerFactory.getLogger(
SheetPainter.class);
//~ Instance fields --------------------------------------------------------
/** Graphic context */
private final Graphics2D g;
/** Saved stroke for restoration at the end of the painting */
private final Stroke oldStroke;
/** Are we drawing editable boundaries? */
private final boolean editableBoundaries;
/** Music font properly scaled */
private MusicFont musicFont;
//~ Constructors -----------------------------------------------------------
//--------------//
// SheetPainter //
//--------------//
/**
* Creates a new SheetPainter object.
*
* @param g Graphic context
* @param editableBoundaries flag to draw editable boundaries
*/
public SheetPainter (Graphics g,
boolean editableBoundaries)
{
this.g = (Graphics2D) g;
this.editableBoundaries = editableBoundaries;
oldStroke = UIUtil.setAbsoluteStroke(g, 1f);
}
//~ Methods ----------------------------------------------------------------
//---------------//
// visit Measure //
//---------------//
@Override
public boolean visit (Measure measure)
{
try {
// Render the measure ending barline
if (measure.getBarline() != null) {
measure.getBarline()
.renderLine(g);
}
} catch (ConcurrentModificationException ignored) {
} catch (Exception ex) {
logger.warn(
getClass().getSimpleName() + " Error visiting " + measure,
ex);
}
// Nothing lower than measure
return false;
}
//------------//
// visit Page //
//------------//
@Override
public boolean visit (Page page)
{
try {
Sheet sheet = page.getSheet();
// Use specific color
g.setColor(Colors.ENTITY_MINOR);
if (!page.getSystems()
.isEmpty()) {
// Small protection about changing data...
if (sheet.getScale() == null) {
return false;
}
// Determine proper font
musicFont = MusicFont.getFont(sheet.getInterline());
// Normal (full) rendering of the score
page.acceptChildren(this);
} else {
// Render what we have got so far
sheet.getStaffManager()
.render(g);
}
} catch (ConcurrentModificationException ignored) {
} catch (Exception ex) {
logger.warn(
getClass().getSimpleName() + " Error visiting " + page,
ex);
} finally {
g.setStroke(oldStroke);
}
return false;
}
//------------------//
// visit SystemPart //
//------------------//
@Override
public boolean visit (SystemPart part)
{
try {
// Render the part starting barline, if any
if (part.getStartingBarline() != null) {
part.getStartingBarline()
.renderLine(g);
}
} catch (ConcurrentModificationException ignored) {
} catch (Exception ex) {
logger.warn(
getClass().getSimpleName() + " Error visiting " + part,
ex);
}
return true;
}
//--------------//
// visit System //
//--------------//
@Override
public boolean visit (ScoreSystem system)
{
try {
if (system == null) {
return false;
}
return visit(system.getInfo());
} catch (ConcurrentModificationException ignored) {
return false;
} catch (Exception ex) {
logger.warn(
getClass().getSimpleName() + " Error visiting " + system,
ex);
return false;
}
}
//------------------//
// visit SystemInfo //
//------------------//
public boolean visit (SystemInfo systemInfo)
{
try {
Rectangle bounds = systemInfo.getBounds();
if (bounds == null) {
return false;
}
// Check that this system is visible
if (bounds.intersects(g.getClipBounds())) {
g.setColor(Colors.ENTITY_MINOR);
// System boundary
systemInfo.getBoundary()
.render(g, editableBoundaries);
// Staff lines
for (StaffInfo staff : systemInfo.getStaves()) {
staff.renderAttachments(g);
}
// // Stems
// for (Glyph glyph : systemInfo.getGlyphs()) {
// if (glyph.isStem()) {
// glyph.renderLine(g);
// }
// }
// Virtual glyphs
paintVirtualGlyphs(systemInfo);
return true;
}
} catch (ConcurrentModificationException ignored) {
return false;
} catch (Exception ex) {
logger.warn(
getClass().getSimpleName() + " Error visiting " +
systemInfo.idString(),
ex);
}
return false;
}
//--------------------//
// paintVirtualGlyphs //
//--------------------//
/**
* Paint the virtual glyphs on the sheet view
*
* @param systemInfo the containing system
*/
private void paintVirtualGlyphs (SystemInfo systemInfo)
{
g.setColor(Colors.ENTITY_VIRTUAL);
for (Glyph glyph : systemInfo.getGlyphs()) {
if (glyph.isVirtual()) {
ShapeSymbol symbol = Symbols.getSymbol(glyph.getShape());
if (symbol == null) {
systemInfo.getScoreSystem()
.addError(
glyph,
"No symbol for " + glyph.idString());
} else {
symbol.paintSymbol(
g,
musicFont,
glyph.getAreaCenter(),
Alignment.AREA_CENTER);
}
}
}
}
}