1 /**
2  *
3  */
4 package org.herac.tuxguitar.gui.tools.custom.tuner;
5 
6 import org.eclipse.swt.SWT;
7 import org.eclipse.swt.events.PaintEvent;
8 import org.eclipse.swt.events.PaintListener;
9 import org.eclipse.swt.graphics.Font;
10 import org.eclipse.swt.graphics.Point;
11 import org.eclipse.swt.layout.GridData;
12 import org.eclipse.swt.layout.GridLayout;
13 import org.eclipse.swt.widgets.Composite;
14 import org.herac.tuxguitar.gui.TuxGuitar;
15 import org.herac.tuxguitar.gui.editors.TGPainter;
16 import org.herac.tuxguitar.gui.system.config.TGConfigKeys;
17 
18 /**
19  * @author Nikola Kolarovic <johnny47ns@yahoo.com>
20  *
21  */
22 public class TGTunerFineWidget extends Composite {
23 
24 	private static final int MIN_HEIGHT = 60;
25 	private static final int MIN_WIDTH = 80;
26 	private final float bottomY = 10.0f;
27 
28 	private Composite composite = null;
29 	protected String currentNoteString = null;
30 	protected int currentNoteValue = -1;
31 	protected double currentFrequency = 0.0f;
32 	protected Font letterFont = null;
33 	protected final float FINE_TUNING_RANGE = 1.5f;
34 
TGTunerFineWidget(Composite parent)35 	public TGTunerFineWidget(Composite parent) {
36 		super(parent, SWT.NONE);
37 		this.setEnabled(false);
38 		this.init();
39 	}
40 
init()41 	protected void init() {
42 		this.setLayout(new GridLayout(1,true));
43 		this.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
44 
45 
46 		this.composite = new Composite(this,SWT.BORDER | SWT.DOUBLE_BUFFERED);
47 		this.composite.setBackground(this.getDisplay().getSystemColor(SWT.COLOR_WHITE));
48 		this.composite.addPaintListener(new PaintListener() {
49 			public void paintControl(PaintEvent e) {
50 				TGPainter painter = new TGPainter(e.gc);
51 				TGTunerFineWidget.this.paintWidget(painter);
52 			}
53 		});
54 
55 		GridData data = new GridData(SWT.FILL,SWT.FILL,true,true);
56 		data.minimumHeight = MIN_HEIGHT;
57 		data.minimumWidth = MIN_WIDTH;
58 		data.grabExcessHorizontalSpace=true;
59 		data.grabExcessVerticalSpace=true;
60 		this.composite.setLayoutData(data);
61 		this.letterFont = new Font(this.getDisplay(),
62 							TuxGuitar.instance().getConfig().getFontDataConfigValue(TGConfigKeys.MATRIX_FONT).getName(),
63 							14,
64 							SWT.BOLD
65 							);
66 
67 	}
68 
69 
paintWidget(TGPainter painter)70 	public void paintWidget(TGPainter painter) {
71 		Point compositeSize = this.composite.getSize();
72 
73 		// margins & stuff
74 
75 		painter.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK));
76 		painter.initPath();
77 		painter.setLineWidth(2);
78 		float height = compositeSize.y-this.bottomY-25;
79 		painter.moveTo(compositeSize.x/2, compositeSize.y-this.bottomY);
80 		painter.lineTo(compositeSize.x/2, 25);
81 		painter.closePath();
82 		painter.initPath();
83 		height = Math.min(height, compositeSize.x/2);
84 		painter.moveTo(compositeSize.x/2-height, compositeSize.y-this.bottomY);
85 		painter.lineTo(compositeSize.x/2+height, compositeSize.y-this.bottomY);
86 		painter.closePath();
87 
88 		if (this.isEnabled()) {
89 			// tone name
90 			painter.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLUE));
91 			painter.setFont(this.letterFont);
92 			painter.drawString(this.currentNoteString, compositeSize.x*12/15, 10);
93 
94 			// pointer
95 			if (this.currentFrequency!=-1) {
96 				painter.setLineWidth(3);
97 				painter.setForeground(getDisplay().getSystemColor(SWT.COLOR_RED));
98 				painter.initPath();
99 				painter.moveTo(compositeSize.x/2, compositeSize.y-this.bottomY);
100 				painter.lineTo((float)(compositeSize.x/2 + height*Math.cos(this.getAngleRad())),(float)( compositeSize.y-this.bottomY-height*Math.sin(this.getAngleRad())));
101 			painter.closePath();
102 			}
103 		}
104 
105 
106 
107 
108 	}
109 
110 
setWantedTone(int tone)111 	public void setWantedTone(int tone) {
112 		this.setEnabled(true);
113 		this.currentNoteValue = tone;
114 		this.currentNoteString = TGTunerRoughWidget.TONESSTRING[tone%12]+(int)Math.floor(tone/12);
115 		this.redraw();
116 
117 	}
118 
setCurrentFrequency(double freq)119 	public void setCurrentFrequency(double freq) {
120 		this.currentFrequency = freq;
121 		this.redraw();
122 	}
123 
redraw()124 	public void redraw(){
125 		super.redraw();
126 		this.composite.redraw();
127 	}
128 
getAngleRad()129 	protected double getAngleRad() {
130 		return Math.PI*( 1 - (this.stickDistance(this.getTone(this.currentFrequency) - this.currentNoteValue) + this.FINE_TUNING_RANGE  )/(2*this.FINE_TUNING_RANGE) );
131 	}
132 
133 
getTone(double frequency)134 	private float getTone(double frequency) {
135 		return (float)(45+12*(Math.log(frequency/110)/Math.log(2)));
136 	}
137 
stickDistance(double diff)138 	private double stickDistance(double diff) {
139 		if (Math.abs(diff) > this.FINE_TUNING_RANGE)
140 			if (diff > 0)
141 				return this.FINE_TUNING_RANGE;
142 			else
143 				return -this.FINE_TUNING_RANGE;
144 		return diff;
145 	}
146 
147 
148 }