1 package jalview.appletgui;
\r
3 import jalview.math.*;
\r
4 import jalview.datamodel.*;
\r
5 import jalview.util.*;
\r
8 import java.awt.event.*;
\r
12 public class RotatableCanvas extends Panel implements MouseListener,
\r
13 MouseMotionListener,
\r
15 //RubberbandListener,
\r
16 //SequenceSelectionListener
\r
18 RotatableMatrix idmat = new RotatableMatrix(3,3);
\r
19 RotatableMatrix objmat = new RotatableMatrix(3,3);
\r
20 RotatableMatrix rotmat = new RotatableMatrix(3,3);
\r
22 //RubberbandRectangle rubberband;
\r
24 boolean drawAxes = true;
\r
36 float centre[] = new float[3];
\r
37 float width[] = new float[3];
\r
39 float max[] = new float[3];
\r
40 float min[] = new float[3];
\r
62 float scalefactor = 1;
\r
65 // Controller controller;
\r
68 public RotatableCanvas(AlignViewport av,
\r
69 Vector points, int npoint) {
\r
70 this.points = points;
\r
71 this.npoint = npoint;
\r
73 PaintRefresher.Register(this);
\r
75 prefsize = getPreferredSize();
\r
76 orig = new float[npoint][3];
\r
78 for (int i=0; i < npoint; i++) {
\r
79 SequencePoint sp = (SequencePoint)points.elementAt(i);
\r
80 for (int j=0; j < 3; j++) {
\r
81 orig[i][j] = sp.coord[j];
\r
84 //Initialize the matrices to identity
\r
86 for (int i = 0; i < 3; i++) {
\r
87 for (int j = 0; j < 3 ; j++) {
\r
89 idmat.addElement(i,j,0);
\r
90 objmat.addElement(i,j,0);
\r
91 rotmat.addElement(i,j,0);
\r
93 idmat.addElement(i,j,0);
\r
94 objmat.addElement(i,j,0);
\r
95 rotmat.addElement(i,j,0);
\r
100 axes = new float[3][3];
\r
106 scale = findScale();
\r
108 // System.out.println("Scale factor = " + scale);
\r
110 addMouseListener(this);
\r
111 addKeyListener(this);
\r
112 // if (getParent() != null) {
\r
113 // getParent().addKeyListener(this);
\r
115 addMouseMotionListener(this);
\r
118 // rubberband = new RubberbandRectangle(this);
\r
119 // rubberband.setActive(true);
\r
120 // rubberband.addListener(this);
\r
123 /* public boolean handleSequenceSelectionEvent(SequenceSelectionEvent evt) {
\r
124 redrawneeded = true;
\r
129 public void removeNotify() {
\r
130 controller.removeListener(this);
\r
131 super.removeNotify();
\r
134 public void initAxes() {
\r
135 for (int i = 0; i < 3; i++) {
\r
136 for (int j=0; j < 3; j++) {
\r
146 public void findWidth() {
\r
147 max = new float[3];
\r
148 min = new float[3];
\r
150 max[0] = (float)-1e30;
\r
151 max[1] = (float)-1e30;
\r
152 max[2] = (float)-1e30;
\r
154 min[0] = (float)1e30;
\r
155 min[1] = (float)1e30;
\r
156 min[2] = (float)1e30;
\r
158 for (int i = 0; i < 3; i++) {
\r
159 for (int j = 0; j < npoint; j++) {
\r
160 SequencePoint sp = (SequencePoint)points.elementAt(j);
\r
161 if (sp.coord[i] >= max[i]) {
\r
162 max[i] = sp.coord[i];
\r
164 if (sp.coord[i] <= min[i]) {
\r
165 min[i] = sp.coord[i];
\r
170 // System.out.println("xmax " + max[0] + " min " + min[0]);
\r
171 //System.out.println("ymax " + max[1] + " min " + min[1]);
\r
172 //System.out.println("zmax " + max[2] + " min " + min[2]);
\r
174 width[0] = Math.abs(max[0] - min[0]);
\r
175 width[1] = Math.abs(max[1] - min[1]);
\r
176 width[2] = Math.abs(max[2] - min[2]);
\r
178 maxwidth = width[0];
\r
180 if (width[1] > width[0])
\r
181 maxwidth = width[1];
\r
182 if (width[2] > width[1])
\r
183 maxwidth = width[2];
\r
185 //System.out.println("Maxwidth = " + maxwidth);
\r
188 public float findScale() {
\r
189 int dim, width, height;
\r
190 if (getSize().width != 0) {
\r
191 width = getSize().width;
\r
192 height = getSize().height;
\r
194 width = prefsize.width;
\r
195 height = prefsize.height;
\r
198 if (width < height) {
\r
204 return (float)(dim*scalefactor/(2*maxwidth));
\r
207 public void findCentre() {
\r
208 //Find centre coordinate
\r
211 centre[0] = (max[0] + min[0])/2;
\r
212 centre[1] = (max[1] + min[1])/2;
\r
213 centre[2] = (max[2] + min[2])/2;
\r
215 // System.out.println("Centre x " + centre[0]);
\r
216 //System.out.println("Centre y " + centre[1]);
\r
217 //System.out.println("Centre z " + centre[2]);
\r
220 public Dimension getPreferredSize() {
\r
221 if (prefsize != null) {
\r
224 return new Dimension(400,400);
\r
228 public Dimension getMinimumSize() {
\r
229 return getPreferredSize();
\r
232 public void paint(Graphics g) {
\r
233 //Only create the image at the beginning -
\r
234 if ((img == null) || (prefsize.width != getSize().width) || (prefsize.height != getSize().height)) {
\r
235 prefsize.width = getSize().width;
\r
236 prefsize.height = getSize().height;
\r
238 scale = findScale();
\r
240 // System.out.println("New scale = " + scale);
\r
241 img = createImage(getSize().width,getSize().height);
\r
242 ig = img.getGraphics();
\r
247 drawBackground(ig,Color.black);
\r
249 if (drawAxes == true)
\r
255 g.drawImage(img,0,0,this);
\r
258 public void drawAxes(Graphics g) {
\r
260 g.setColor(Color.yellow);
\r
261 for (int i=0; i < 3 ; i++) {
\r
262 g.drawLine(getSize().width/2,getSize().height/2,
\r
263 (int)(axes[i][0]*scale*max[0] + getSize().width/2),
\r
264 (int)(axes[i][1]*scale*max[1] + getSize().height/2));
\r
268 public void drawBackground(Graphics g, Color col) {
\r
270 g.fillRect(0,0,prefsize.width,prefsize.height);
\r
274 public void drawScene(Graphics g) {
\r
275 boolean darker = false;
\r
277 int halfwidth = getSize().width/2;
\r
278 int halfheight = getSize().height/2;
\r
280 for (int i = 0; i < npoint; i++) {
\r
281 SequencePoint sp = (SequencePoint)points.elementAt(i);
\r
282 int x = (int)((float)(sp.coord[0] - centre[0])*scale) + halfwidth;
\r
283 int y = (int)((float)(sp.coord[1] - centre[1])*scale) + halfheight;
\r
284 float z = sp.coord[1] - centre[2];
\r
289 if (sp.sequence.getColor() == Color.black)
\r
290 g.setColor(Color.white);
\r
292 g.setColor(sp.sequence.getColor());
\r
295 if (av.getSelectionGroup() != null)
\r
297 if (av.getSelectionGroup().sequences.contains(((SequencePoint)points.elementAt(i)).sequence))
\r
298 g.setColor(Color.gray);
\r
301 g.setColor(g.getColor().darker());
\r
304 g.fillRect(x-3,y-3,6,6);
\r
305 g.setColor(Color.red);
\r
307 // //Now the rectangle
\r
308 // if (rectx2 != -1 && recty2 != -1) {
\r
309 // g.setColor(Color.white);
\r
311 // g.drawRect(rectx1,recty1,rectx2-rectx1,recty2-recty1);
\r
315 public Dimension minimumsize() {
\r
319 public Dimension preferredsize() {
\r
323 public void keyTyped(KeyEvent evt) { }
\r
324 public void keyReleased(KeyEvent evt) { }
\r
326 public void keyPressed(KeyEvent evt) {
\r
328 if (evt.getKeyCode() == KeyEvent.VK_UP) {
\r
329 scalefactor = (float)(scalefactor * 1.1);
\r
330 scale = findScale();
\r
331 } else if (evt.getKeyCode() == KeyEvent.VK_DOWN) {
\r
332 scalefactor = (float)(scalefactor * 0.9);
\r
333 scale = findScale();
\r
334 } else if (evt.getKeyChar() == 's') {
\r
335 System.err.println("DEBUG: Rectangle selection"); // log.debug
\r
336 if (rectx2 != -1 && recty2 != -1) {
\r
337 rectSelect(rectx1,recty1,rectx2,recty2);
\r
344 public void printPoints() {
\r
345 for (int i=0; i < npoint; i++) {
\r
346 SequencePoint sp = (SequencePoint)points.elementAt(i);
\r
347 Format.print(System.out,"%5d ", i);
\r
348 for (int j=0; j < 3;j++) {
\r
349 Format.print(System.out,"%13.3f ",sp.coord[j]);
\r
351 System.out.println();
\r
355 public void mouseClicked(MouseEvent evt) { }
\r
356 public void mouseEntered(MouseEvent evt) { }
\r
357 public void mouseExited(MouseEvent evt) { }
\r
358 public void mouseReleased(MouseEvent evt) { }
\r
360 public void mousePressed(MouseEvent evt) {
\r
361 int x = evt.getX();
\r
362 int y = evt.getY();
\r
379 SequenceI found = findPoint(x,y);
\r
383 if (av.getSelectionGroup() != null)
\r
385 av.getSelectionGroup().addOrRemove(found);
\r
386 PaintRefresher.Refresh(this);
\r
390 av.setSelectionGroup(new SequenceGroup());
\r
391 av.getSelectionGroup().addOrRemove(found);
\r
392 av.getSelectionGroup().setEndRes(av.alignment.getWidth());
\r
399 // private void fireSequenceSelectionEvent(Selection sel) {
\r
400 // controller.handleSequenceSelectionEvent(new SequenceSelectionEvent(this,sel));
\r
403 public void mouseMoved(MouseEvent evt)
\r
405 // SequenceI found = findPoint(evt.getX(), evt.getY());
\r
408 public void mouseDragged(MouseEvent evt) {
\r
411 //Check if this is a rectangle drawing drag
\r
412 if ((evt.getModifiers() & InputEvent.BUTTON2_MASK) != 0) {
\r
413 // rectx2 = evt.getX();
\r
414 // recty2 = evt.getY();
\r
416 rotmat.setIdentity();
\r
418 rotmat.rotate((float)(my-omy),'x');
\r
419 rotmat.rotate((float)(mx-omx),'y');
\r
421 for (int i = 0; i < npoint; i++) {
\r
422 SequencePoint sp = (SequencePoint)points.elementAt(i);
\r
423 sp.coord[0] -= centre[0];
\r
424 sp.coord[1] -= centre[1];
\r
425 sp.coord[2] -= centre[2];
\r
427 //Now apply the rotation matrix
\r
428 sp.coord= rotmat.vectorMultiply(sp.coord);
\r
430 //Now translate back again
\r
431 sp.coord[0] += centre[0];
\r
432 sp.coord[1] += centre[1];
\r
433 sp.coord[2] += centre[2];
\r
436 for (int i=0; i < 3; i++) {
\r
437 axes[i] = rotmat.vectorMultiply(axes[i]);
\r
442 paint(this.getGraphics());
\r
447 public void rectSelect(int x1, int y1, int x2, int y2) {
\r
448 boolean changedSel = false;
\r
449 for (int i=0; i < npoint; i++) {
\r
450 SequencePoint sp = (SequencePoint)points.elementAt(i);
\r
451 int tmp1 = (int)((sp.coord[0] - centre[0])*scale + (float)getSize().width/2.0);
\r
452 int tmp2 = (int)((sp.coord[1] - centre[1])*scale + (float)getSize().height/2.0);
\r
454 if (tmp1 > x1 && tmp1 < x2 && tmp2 > y1 && tmp2 < y2) {
\r
456 if (!av.getSelectionGroup().sequences.contains(sp.sequence))
\r
459 av.getSelectionGroup().addSequence(sp.sequence);
\r
464 // if (changedSel) {
\r
465 // fireSequenceSelectionEvent(av.getSelection());
\r
468 public SequenceI findPoint(int x, int y) {
\r
470 int halfwidth = getSize().width/2;
\r
471 int halfheight = getSize().height/2;
\r
475 for (int i=0; i < npoint; i++) {
\r
477 SequencePoint sp = (SequencePoint)points.elementAt(i);
\r
478 int px = (int)((float)(sp.coord[0] - centre[0])*scale) + halfwidth;
\r
479 int py = (int)((float)(sp.coord[1] - centre[1])*scale) + halfheight;
\r
482 if (Math.abs(px-x)<3 && Math.abs(py - y) < 3 ) {
\r
487 return ((SequencePoint)points.elementAt(found)).sequence;
\r
492 /* public boolean handleRubberbandEvent(RubberbandEvent evt) {
\r
493 System.out.println("Rubberband handler called in RotatableCanvas with " +
\r
496 Rubberband rb = (Rubberband)evt.getSource();
\r
498 // Clear the current selection (instance variable)
\r
499 //if ((rb.getModifiers() & Event.SHIFT_MASK) == 0) {
\r
500 // clearSelection();
\r
503 if (rb.getComponent() == this) {
\r
504 Rectangle bounds = evt.getBounds();
\r
505 rectSelect(bounds.x,bounds.y,bounds.x+bounds.width,bounds.y+bounds.height);
\r
508 redrawneeded = true;
\r
509 paint(this.getGraphics());
\r