1 package org.herac.tuxguitar.gui.editors.tab.edit;
2 
3 import java.util.Iterator;
4 
5 import org.eclipse.swt.events.MenuEvent;
6 import org.eclipse.swt.events.MenuListener;
7 import org.eclipse.swt.events.MouseEvent;
8 import org.eclipse.swt.events.MouseListener;
9 import org.eclipse.swt.events.MouseMoveListener;
10 import org.eclipse.swt.events.MouseTrackListener;
11 import org.eclipse.swt.graphics.Point;
12 import org.herac.tuxguitar.gui.TuxGuitar;
13 import org.herac.tuxguitar.gui.editors.tab.TGBeatImpl;
14 import org.herac.tuxguitar.gui.editors.tab.TGMeasureImpl;
15 import org.herac.tuxguitar.gui.editors.tab.TGTrackImpl;
16 import org.herac.tuxguitar.gui.editors.tab.TGTrackSpacing;
17 import org.herac.tuxguitar.gui.editors.tab.Tablature;
18 import org.herac.tuxguitar.gui.editors.tab.layout.ViewLayout;
19 import org.herac.tuxguitar.gui.system.config.TGConfigKeys;
20 import org.herac.tuxguitar.song.models.TGBeat;
21 import org.herac.tuxguitar.song.models.TGString;
22 
23 public class EditorKit implements MouseListener,MouseMoveListener,MouseTrackListener,MenuListener{
24 
25 	public static final int MOUSE_MODE_SELECTION = 1;
26 	public static final int MOUSE_MODE_EDITION = 2;
27 
28 	private int mouseMode;
29 	private boolean natural;
30 	private Tablature tablature;
31 	private MouseKit mouseKit;
32 	private Point position;
33 	private boolean menuOpen;
34 
EditorKit(Tablature tablature)35 	public EditorKit(Tablature tablature){
36 		this.tablature = tablature;
37 		this.mouseKit = new MouseKit(this);
38 		this.position = new Point(0,0);
39 		this.menuOpen = false;
40 		this.tablature.addMouseListener(this);
41 		this.tablature.addMouseMoveListener(this);
42 		this.tablature.addMouseTrackListener(this);
43 		this.setDefaults();
44 	}
45 
setDefaults()46 	private void setDefaults(){
47 		this.setMouseMode(TuxGuitar.instance().getConfig().getIntConfigValue(TGConfigKeys.EDITOR_MOUSE_MODE,MOUSE_MODE_EDITION));
48 		this.setNatural(TuxGuitar.instance().getConfig().getBooleanConfigValue(TGConfigKeys.EDITOR_NATURAL_KEY_MODE,true));
49 	}
50 
getMouseMode()51 	public int getMouseMode() {
52 		return this.mouseMode;
53 	}
54 
setMouseMode(int mouseMode)55 	public void setMouseMode(int mouseMode) {
56 		this.mouseMode = mouseMode;
57 	}
58 
isNatural()59 	public boolean isNatural() {
60 		return this.natural;
61 	}
62 
setNatural(boolean natural)63 	public void setNatural(boolean natural) {
64 		this.natural = natural;
65 	}
66 
getTablature()67 	public Tablature getTablature() {
68 		return this.tablature;
69 	}
70 
tryBack()71 	public void tryBack(){
72 		this.mouseKit.tryBack();
73 	}
74 
select()75 	public boolean select() {
76 		int x = this.position.x;
77 		int y = this.position.y;
78 		if(x >= 0 && y >= 0){
79 			TGTrackImpl track = findSelectedTrack(y);
80 			if (track != null) {
81 				TGMeasureImpl measure = findSelectedMeasure(track, x, y);
82 				if (measure != null) {
83 					TGBeat beat = findSelectedBeat(measure, x);
84 					TGString tgString = findSelectedString(measure, y);
85 					if (beat != null) {
86 						int string = (tgString != null)?tgString.getNumber():getTablature().getCaret().getSelectedString().getNumber();
87 						getTablature().getCaret().moveTo(track, measure, beat, string);
88 					}
89 					return true;
90 				}
91 			}
92 		}
93 		return false;
94 	}
95 
isScoreEnabled()96 	private boolean isScoreEnabled(){
97 		return ( (getTablature().getViewLayout().getStyle() & ViewLayout.DISPLAY_SCORE) != 0 );
98 	}
99 
findSelectedTrack(int y)100 	public TGTrackImpl findSelectedTrack(int y){
101 		ViewLayout layout = getTablature().getViewLayout();
102 		int number = layout.getTrackNumberAt(y);
103 		if(number >= 0){
104 			return (TGTrackImpl)layout.getSongManager().getTrack(number);
105 		}
106 		return null;
107 	}
108 
findSelectedMeasure(TGTrackImpl track,int x,int y)109 	public TGMeasureImpl findSelectedMeasure(TGTrackImpl track,int x,int y){
110 		TGMeasureImpl measure = null;
111 		int minorDistance = 0;
112 
113 		Iterator it = track.getMeasures();
114 		while(it.hasNext()){
115 			TGMeasureImpl m = (TGMeasureImpl)it.next();
116 			if(!m.isOutOfBounds() && m.getTs() != null){
117 				boolean isAtX = (x >= m.getPosX() && x <= m.getPosX() + m.getWidth(getTablature().getViewLayout()) + m.getSpacing());
118 				if(isAtX){
119 					int measureHeight = m.getTs().getSize();
120 					int distanceY = Math.min(Math.abs(y - (m.getPosY())),Math.abs(y - ( m.getPosY() + measureHeight - 10)));
121 					if(measure == null || distanceY < minorDistance){
122 						measure = m;
123 						minorDistance = distanceY;
124 					}
125 				}
126 			}
127 		}
128 		return measure;
129 	}
130 
findSelectedBeat(TGMeasureImpl measure, int x)131 	public TGBeatImpl findSelectedBeat(TGMeasureImpl measure, int x){
132 		int voice = getTablature().getCaret().getVoice();
133 		int posX = measure.getHeaderImpl().getLeftSpacing(getTablature().getViewLayout()) + measure.getPosX();
134 		int bestDiff = -1;
135 		TGBeatImpl bestBeat = null;
136 		Iterator it = measure.getBeats().iterator();
137 		while(it.hasNext()){
138 			TGBeatImpl beat = (TGBeatImpl)it.next();
139 			if(!beat.getVoice(voice).isEmpty()){
140 				int diff = Math.abs(x - (posX + (beat.getPosX() + beat.getSpacing())));
141 				if(bestDiff == -1 || diff < bestDiff){
142 					bestBeat = beat;
143 					bestDiff = diff;
144 				}
145 			}
146 		}
147 		if( bestBeat == null ){
148 			bestBeat = (TGBeatImpl)getTablature().getViewLayout().getSongManager().getMeasureManager().getFirstBeat(measure.getBeats());
149 		}
150 		return bestBeat;
151 	}
152 
findSelectedString(TGMeasureImpl measure,int y)153 	public TGString findSelectedString(TGMeasureImpl measure,int y) {
154 		TGString string = null;
155 		int stringSpacing = getTablature().getViewLayout().getStringSpacing();
156 		int minorDistance = 0;
157 		int firstStringY = measure.getPosY() + measure.getTs().getPosition(TGTrackSpacing.POSITION_TABLATURE);
158 
159 		Iterator it = measure.getTrack().getStrings().iterator();
160 		while(it.hasNext()){
161 			TGString currString = (TGString)it.next();
162 			int distanceX = Math.abs(y - (firstStringY + ((currString.getNumber() * stringSpacing) - stringSpacing)));
163 			if(string == null || distanceX < minorDistance){
164 				string = currString;
165 				minorDistance = distanceX;
166 			}
167 		}
168 
169 		return string;
170 	}
171 
mouseDown(MouseEvent e)172 	public void mouseDown(MouseEvent e) {
173 		this.position.x = e.x;
174 		this.position.y = e.y;
175 	}
176 
mouseUp(MouseEvent e)177 	public void mouseUp(MouseEvent e) {
178 		this.position.x = e.x;
179 		this.position.y = e.y;
180 		this.tablature.setFocus();
181 		if(select()){
182 			TuxGuitar.instance().updateCache(true);
183 			if(!this.menuOpen && e.button == 1 && !TuxGuitar.instance().getPlayer().isRunning() && isScoreEnabled() && getMouseMode() == MOUSE_MODE_EDITION){
184 				this.mouseKit.mouseUp(e);
185 			}
186 		}
187 	}
188 
mouseMove(MouseEvent e)189 	public void mouseMove(MouseEvent e) {
190 		if(!this.menuOpen && !TuxGuitar.instance().getPlayer().isRunning()){
191 			if(isScoreEnabled() && getMouseMode() == MOUSE_MODE_EDITION){
192 				this.mouseKit.mouseMove(e);
193 			}
194 		}
195 	}
196 
mouseExit(MouseEvent e)197 	public void mouseExit(MouseEvent e) {
198 		if(!this.menuOpen && !TuxGuitar.instance().getPlayer().isRunning()){
199 			if(isScoreEnabled() && getMouseMode() == MOUSE_MODE_EDITION){
200 				this.mouseKit.mouseExit();
201 			}
202 		}
203 	}
204 
menuShown(MenuEvent e)205 	public void menuShown(MenuEvent e) {
206 		this.menuOpen = true;
207 		this.select();
208 		TuxGuitar.instance().updateCache(true);
209 	}
210 
menuHidden(MenuEvent e)211 	public void menuHidden(MenuEvent e){
212 		this.menuOpen = false;
213 		TuxGuitar.instance().updateCache(true);
214 	}
215 
mouseDoubleClick(MouseEvent e)216 	public void mouseDoubleClick(MouseEvent e) {
217 		//not implemented
218 	}
219 
mouseEnter(MouseEvent e)220 	public void mouseEnter(MouseEvent e) {
221 		//not implemented
222 	}
223 
mouseHover(MouseEvent e)224 	public void mouseHover(MouseEvent e) {
225 		//not implemented
226 	}
227 }
228