/* * Created on 29-nov-2005 * * TODO To change the template for this generated file go to Window - * Preferences - Java - Code Style - Code Templates */ package org.herac.tuxguitar.gui.editors.tab; import org.apache.log4j.Logger; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.ScrollBar; import org.herac.tuxguitar.gui.TuxGuitar; import org.herac.tuxguitar.gui.editors.TGPainter; import org.herac.tuxguitar.gui.editors.chord.ChordSelector; import org.herac.tuxguitar.gui.editors.tab.edit.EditorKit; import org.herac.tuxguitar.gui.editors.tab.layout.LinearViewLayout; import org.herac.tuxguitar.gui.editors.tab.layout.PageViewLayout; import org.herac.tuxguitar.gui.editors.tab.layout.ViewLayout; import org.herac.tuxguitar.gui.system.config.TGConfigKeys; import org.herac.tuxguitar.song.managers.TGSongManager; import org.herac.tuxguitar.song.models.TGDuration; /** * @author julian * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class Tablature extends Composite { private static final int SCROLL_DELAY = 15; private static final int SCROLL_INCREMENT = 50; private Caret caret; private EditorKit editorKit; private int height; protected long lastHScrollTime; protected long lastVScrollTime; private boolean painting; private TGBeatImpl playedBeat; private TGMeasureImpl playedMeasure; private boolean resetScroll; private int scrollX; private int scrollY; private TGSongManager songManager; private ViewLayout viewLayout; private int width; public Tablature(final Composite parent) { this(parent, SWT.NONE); } public Tablature(final Composite parent, int style) { super(parent, style); this.editorKit = new EditorKit(this); } public void checkScroll() { if (this.resetScroll) { getHorizontalBar().setSelection(0); getVerticalBar().setSelection(0); this.resetScroll = false; } } public void dispose() { super.dispose(); this.getViewLayout().disposeLayout(); } public Caret getCaret() { return this.caret; } public EditorKit getEditorKit() { return this.editorKit; } public TGSongManager getSongManager() { return this.songManager; } public ViewLayout getViewLayout() { return this.viewLayout; } public void initCaret() { this.caret.update(1, TGDuration.QUARTER_TIME, 1); } public void initDefaults() { this.caret = new Caret(this); } public void initGUI() { this.addPaintListener(new TablaturePaintListener(this)); final ScrollBar hBar = getHorizontalBar(); hBar.setIncrement(SCROLL_INCREMENT); hBar.addListener(SWT.Selection, new Listener() { public void handleEvent(Event e) { if (Tablature.this.lastHScrollTime + SCROLL_DELAY < System .currentTimeMillis()) { redraw(); Tablature.this.lastHScrollTime = System.currentTimeMillis(); } } }); final ScrollBar vBar = getVerticalBar(); vBar.setIncrement(SCROLL_INCREMENT); vBar.addListener(SWT.Selection, new Listener() { public void handleEvent(Event e) { if (Tablature.this.lastVScrollTime + SCROLL_DELAY < System .currentTimeMillis()) { redraw(); Tablature.this.lastVScrollTime = System.currentTimeMillis(); } } }); this.addControlListener(new ControlAdapter() { public void controlResized(ControlEvent arg0) { updateScroll(); } }); } public boolean isPainting() { return this.painting; } private void loadViewLayout(int style, int mode) { switch (mode) { case ViewLayout.MODE_PAGE: setViewLayout(new PageViewLayout(this, style)); break; case ViewLayout.MODE_LINEAR: setViewLayout(new LinearViewLayout(this, style)); break; default: if (mode != ViewLayout.DEFAULT_MODE) { this.loadViewLayout(style, ViewLayout.DEFAULT_MODE); } break; } } public boolean moveScrollTo(TGMeasureImpl measure) { return moveScrollTo(measure, getHorizontalBar(), getVerticalBar(), getClientArea()); } public boolean moveScrollTo(TGMeasureImpl measure, ScrollBar xScroll, ScrollBar yScroll, Rectangle area) { boolean success = false; if (measure != null && measure.getTs() != null) { int mX = measure.getPosX(); int mY = measure.getPosY(); int mWidth = measure.getWidth(getViewLayout()); int mHeight = measure.getTs().getSize(); int marginWidth = getViewLayout().getFirstMeasureSpacing(); int marginHeight = getViewLayout().getFirstTrackSpacing(); boolean forceRedraw = false; // Solo se ajusta si es necesario // si el largo del compas es mayor al de la pantalla. nunca se puede // ajustar a la medida. if (mX < 0 || ((mX + mWidth) > area.width && (area.width >= mWidth + marginWidth || mX > marginWidth))) { xScroll.setSelection((this.scrollX + mX) - marginWidth); success = true; } // Solo se ajusta si es necesario // si el alto del compas es mayor al de la pantalla. nunca se puede // ajustar a la medida. if (mY < 0 || ((mY + mHeight) > area.height && (area.height >= mHeight + marginHeight || mY > marginHeight))) { yScroll.setSelection((this.scrollY + mY) - marginHeight); success = true; } if (!success) { // Si la seleccion "real" del scroll es distinta a la anterior, se // fuerza el redraw forceRedraw = (this.scrollX != xScroll.getSelection() || this.scrollY != yScroll .getSelection()); } if (forceRedraw || success) { redraw(); } } return success; } public synchronized void paintTablature(TGPainter painter) { if (!TuxGuitar.instance().isLocked()) { TuxGuitar.instance().lock(); this.setPainting(true); try { this.checkScroll(); Rectangle area = getClientArea(); ScrollBar xScroll = getHorizontalBar(); ScrollBar yScroll = getVerticalBar(); this.scrollX = xScroll.getSelection(); this.scrollY = yScroll.getSelection(); this.getViewLayout().paint(painter, area, -this.scrollX, -this.scrollY); this.width = this.viewLayout.getWidth(); this.height = this.viewLayout.getHeight(); this.updateScroll(); if (TuxGuitar.instance().getPlayer().isRunning()) { redrawPlayingMode(painter, true); } // Si no estoy reproduciendo y hay cambios // muevo el scroll al compas que tiene el caret else if (getCaret().hasChanges()) { // Mover el scroll puede necesitar redibujar // por eso es importante desmarcar los cambios antes de hacer el // moveScrollTo getCaret().setChanges(false); moveScrollTo(getCaret().getMeasure(), xScroll, yScroll, area); } } catch (Throwable throwable) { LOG.error(throwable); } this.setPainting(false); TuxGuitar.instance().unlock(); } } public void redraw() { if (!super.isDisposed() && !TuxGuitar.instance().isLocked()) { this.playedBeat = null; this.playedMeasure = null; this.editorKit.tryBack(); this.setPainting(true); super.redraw(); } } public void redrawPlayingMode() { if (!super.isDisposed() && !isPainting() && !TuxGuitar.instance().isLocked()) { // TuxGuitar.instance().lock(); if (TuxGuitar.instance().getPlayer().isRunning()) { this.editorKit.tryBack(); this.setPainting(true); TGPainter painter = new TGPainter(new GC(this)); redrawPlayingMode(painter, false); painter.dispose(); this.setPainting(false); } // TuxGuitar.instance().unlock(); } } private void redrawPlayingMode(TGPainter painter, boolean force) { if (!super.isDisposed() && !TuxGuitar.instance().isLocked()) { try { TGMeasureImpl measure = TuxGuitar.instance().getEditorCache() .getPlayMeasure(); TGBeatImpl beat = TuxGuitar.instance().getEditorCache().getPlayBeat(); if (measure != null && beat != null && measure.hasTrack(getCaret().getTrack().getNumber())) { if (!moveScrollTo(measure) || force) { boolean paintMeasure = (force || this.playedMeasure == null || !this.playedMeasure .equals(measure)); if (this.playedMeasure != null && this.playedBeat != null && !this.playedMeasure.isOutOfBounds() && this.playedMeasure.hasTrack(getCaret().getTrack() .getNumber())) { getViewLayout().paintPlayMode(painter, this.playedMeasure, this.playedBeat, paintMeasure); } if (!measure.isOutOfBounds()) { getViewLayout().paintPlayMode(painter, measure, beat, paintMeasure); } this.playedBeat = beat; this.playedMeasure = measure; } } } catch (Throwable throwable) { LOG.error(throwable); } } } /** The Logger for this class. */ public static final transient Logger LOG = Logger.getLogger(Tablature.class); public void reloadStyles() { if (this.getViewLayout() != null) { this.getViewLayout().reloadStyles(); this.setBackground(getViewLayout().getResources().getBackgroundColor()); } } public void reloadViewLayout() { int style = TuxGuitar.instance().getConfig().getIntConfigValue( TGConfigKeys.LAYOUT_STYLE); int mode = TuxGuitar.instance().getConfig().getIntConfigValue( TGConfigKeys.LAYOUT_MODE); this.loadViewLayout(style, mode); } public void resetScroll() { this.resetScroll = true; } public void setPainting(boolean painting) { this.painting = painting; } public void setSongManager(TGSongManager songManager) { this.songManager = songManager; } public void setViewLayout(ViewLayout viewLayout) { if (getViewLayout() != null) { getViewLayout().disposeLayout(); } this.viewLayout = viewLayout; if (this.getHorizontalBar() != null) { this.getHorizontalBar().setSelection(0); } if (this.getVerticalBar() != null) { this.getVerticalBar().setSelection(0); } this.reloadStyles(); } public void updateScroll() { Rectangle bounds = getBounds(); Rectangle client = getClientArea(); ScrollBar hBar = getHorizontalBar(); ScrollBar vBar = getVerticalBar(); hBar.setMaximum(this.width); vBar.setMaximum(this.height); hBar.setThumb(Math.min(bounds.width, client.width)); vBar.setThumb(Math.min(bounds.height, client.height)); } public void updateTablature() { this.playedBeat = null; this.playedMeasure = null; getViewLayout().updateSong(); } }