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 }