/**
*
*/
package org.herac.tuxguitar.gui.tools.custom.tuner;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.herac.tuxguitar.gui.TuxGuitar;
import org.herac.tuxguitar.gui.editors.TGPainter;
import org.herac.tuxguitar.gui.system.config.TGConfigKeys;
/**
* @author Nikola Kolarovic <johnny47ns@yahoo.com>
*
*/
public class TGTunerFineWidget extends Composite {
private static final int MIN_HEIGHT = 60;
private static final int MIN_WIDTH = 80;
private final float bottomY = 10.0f;
private Composite composite = null;
protected double currentFrequency = 0.0f;
protected String currentNoteString = null;
protected int currentNoteValue = -1;
protected final float FINE_TUNING_RANGE = 1.5f;
protected Font letterFont = null;
public TGTunerFineWidget(Composite parent) {
super(parent, SWT.NONE);
this.setEnabled(false);
this.init();
}
protected double getAngleRad() {
return Math.PI
* (1 - (this.stickDistance(this.getTone(this.currentFrequency)
- this.currentNoteValue) + this.FINE_TUNING_RANGE)
/ (2 * this.FINE_TUNING_RANGE));
}
private float getTone(double frequency) {
return (float) (45 + 12 * (Math.log(frequency / 110) / Math.log(2)));
}
protected void init() {
this.setLayout(new GridLayout(1, true));
this.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
this.composite = new Composite(this, SWT.BORDER | SWT.DOUBLE_BUFFERED);
this.composite.setBackground(this.getDisplay().getSystemColor(
SWT.COLOR_WHITE));
this.composite.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
TGPainter painter = new TGPainter(e.gc);
TGTunerFineWidget.this.paintWidget(painter);
}
});
GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
data.minimumHeight = MIN_HEIGHT;
data.minimumWidth = MIN_WIDTH;
data.grabExcessHorizontalSpace = true;
data.grabExcessVerticalSpace = true;
this.composite.setLayoutData(data);
this.letterFont = new Font(this.getDisplay(),
TuxGuitar.instance().getConfig().getFontDataConfigValue(
TGConfigKeys.MATRIX_FONT).getName(), 14, SWT.BOLD);
}
public void paintWidget(TGPainter painter) {
Point compositeSize = this.composite.getSize();
// margins & stuff
painter.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK));
painter.initPath();
painter.setLineWidth(2);
float height = compositeSize.y - this.bottomY - 25;
painter.moveTo(compositeSize.x / 2, compositeSize.y - this.bottomY);
painter.lineTo(compositeSize.x / 2, 25);
painter.closePath();
painter.initPath();
height = Math.min(height, compositeSize.x / 2);
painter
.moveTo(compositeSize.x / 2 - height, compositeSize.y - this.bottomY);
painter
.lineTo(compositeSize.x / 2 + height, compositeSize.y - this.bottomY);
painter.closePath();
if (this.isEnabled()) {
// tone name
painter.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLUE));
painter.setFont(this.letterFont);
painter.drawString(this.currentNoteString, compositeSize.x * 12 / 15, 10);
// pointer
if (this.currentFrequency != -1) {
painter.setLineWidth(3);
painter.setForeground(getDisplay().getSystemColor(SWT.COLOR_RED));
painter.initPath();
painter.moveTo(compositeSize.x / 2, compositeSize.y - this.bottomY);
painter.lineTo((float) (compositeSize.x / 2 + height
* Math.cos(this.getAngleRad())), (float) (compositeSize.y
- this.bottomY - height * Math.sin(this.getAngleRad())));
painter.closePath();
}
}
}
public void redraw() {
super.redraw();
this.composite.redraw();
}
public void setCurrentFrequency(double freq) {
this.currentFrequency = freq;
this.redraw();
}
public void setWantedTone(int tone) {
this.setEnabled(true);
this.currentNoteValue = tone;
this.currentNoteString = TGTunerRoughWidget.TONESSTRING[tone % 12]
+ (int) Math.floor(tone / 12);
this.redraw();
}
private double stickDistance(double diff) {
if (Math.abs(diff) > this.FINE_TUNING_RANGE)
if (diff > 0)
return this.FINE_TUNING_RANGE;
else
return -this.FINE_TUNING_RANGE;
return diff;
}
}