Fit to Window bug fixed
[jalview.git] / src / jalview / appletgui / TreeCanvas.java
index 38d23db..0d80535 100755 (executable)
@@ -1,6 +1,6 @@
 /*\r
  * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
  *\r
  * This program is free software; you can redistribute it and/or\r
  * modify it under the terms of the GNU General Public License\r
@@ -30,46 +30,45 @@ import jalview.schemes.*;
 import jalview.util.*;\r
 \r
 public class TreeCanvas\r
-    extends Panel implements MouseListener\r
+    extends Panel implements MouseListener, MouseMotionListener\r
 {\r
   NJTree tree;\r
   ScrollPane scrollPane;\r
   AlignViewport av;\r
   public static final String PLACEHOLDER = " * ";\r
   Font font;\r
-  int fontSize = 12;\r
-\r
   boolean fitToWindow = true;\r
   boolean showDistances = false;\r
   boolean showBootstrap = false;\r
   boolean markPlaceholders = false;\r
 \r
   int offx = 20;\r
-  int offy = 20;\r
+  int offy;\r
 \r
   float threshold;\r
 \r
   String longestName;\r
   int labelLength = -1;\r
 \r
-  //RubberbandRectangle rubberband;\r
-\r
-  Vector listeners;\r
-\r
   Hashtable nameHash = new Hashtable();\r
   Hashtable nodeHash = new Hashtable();\r
 \r
+  SequenceNode highlightNode;\r
+\r
+\r
   public TreeCanvas(AlignViewport av, ScrollPane scroller)\r
   {\r
     this.av = av;\r
+    font = av.getFont();\r
     scrollPane = scroller;\r
     addMouseListener(this);\r
+    addMouseMotionListener(this);\r
     setLayout(null);\r
 \r
-    PaintRefresher.Register(this, av.alignment);\r
+    PaintRefresher.Register(this, av.getSequenceSetId());\r
   }\r
 \r
-  public void TreeSelectionChanged(Sequence sequence)\r
+  public void treeSelectionChanged(SequenceI sequence)\r
   {\r
     SequenceGroup selected = av.getSelectionGroup();\r
     if (selected == null)\r
@@ -80,9 +79,6 @@ public class TreeCanvas
 \r
     selected.setEndRes(av.alignment.getWidth()-1);\r
     selected.addOrRemove(sequence, true);\r
-\r
-    PaintRefresher.Refresh(this, av.alignment);\r
-    repaint();\r
   }\r
 \r
   public void setTree(NJTree tree)\r
@@ -137,15 +133,15 @@ public class TreeCanvas
 \r
       if (node.element() instanceof SequenceI)\r
       {\r
-        if ( ( (SequenceI) ( (SequenceNode) node).element()).getColor() ==\r
-            Color.white)\r
+        SequenceI seq = (SequenceI) ( (SequenceNode) node).element();\r
+\r
+        if (av.getSequenceColour(seq) == Color.white)\r
         {\r
           g.setColor(Color.black);\r
         }\r
         else\r
         {\r
-          g.setColor( ( (SequenceI) ( (SequenceNode) node).element()).getColor().\r
-                     darker());\r
+          g.setColor(av.getSequenceColour(seq).darker());\r
         }\r
 \r
       }\r
@@ -172,7 +168,7 @@ public class TreeCanvas
       }\r
       if (!nodeLabel.equals(""))\r
       {\r
-        g.drawString(nodeLabel, xstart, ypos - 10);\r
+        g.drawString(nodeLabel, xstart+2, ypos - 2);\r
       }\r
 \r
       String name = (markPlaceholders && node.isPlaceholder()) ?\r
@@ -181,7 +177,7 @@ public class TreeCanvas
       int charWidth = fm.stringWidth(name) + 3;\r
       int charHeight = fm.getHeight();\r
 \r
-      Rectangle rect = new Rectangle(xend + 20, ypos - charHeight,\r
+      Rectangle rect = new Rectangle(xend + 10, ypos - charHeight,\r
                                      charWidth, charHeight);\r
 \r
       nameHash.put( (SequenceI) node.element(), rect);\r
@@ -189,7 +185,7 @@ public class TreeCanvas
       // Colour selected leaves differently\r
       SequenceGroup selected = av.getSelectionGroup();\r
       if (selected != null &&\r
-          selected.sequences.contains( (SequenceI) node.element()))\r
+          selected.getSequences(false).contains( (SequenceI) node.element()))\r
       {\r
         g.setColor(Color.gray);\r
 \r
@@ -215,7 +211,10 @@ public class TreeCanvas
 \r
       // Draw horizontal line\r
       g.drawLine(xstart, ypos, xend, ypos);\r
-      g.fillRect(xend - 2, ypos - 2, 4, 4);\r
+      if (node == highlightNode)\r
+        g.fillRect(xend - 3, ypos - 3, 6, 6);\r
+      else\r
+        g.fillRect(xend - 2, ypos - 2, 4, 4);\r
 \r
       int ystart = (int) ( ( (SequenceNode) node.left()).ycount * chunk) + offy;\r
       int yend = (int) ( ( (SequenceNode) node.right()).ycount * chunk) + offy;\r
@@ -228,7 +227,7 @@ public class TreeCanvas
 \r
       if (showDistances && node.dist > 0)\r
       {\r
-        g.drawString(new Format("%-.2f").form(node.dist), xstart, ypos - 5);\r
+        g.drawString(new Format("%-.2f").form(node.dist), xstart+2, ypos - 2);\r
       }\r
 \r
     }\r
@@ -280,7 +279,7 @@ public class TreeCanvas
       top.count = ( (SequenceNode) top.left()).count +\r
           ( (SequenceNode) top.right()).count;\r
     }\r
-    float chunk = (float) (height - offy * 2) / top.count;\r
+    float chunk = (float) (height - offy) / top.count;\r
 \r
     pickNode(pickBox, top, chunk, wscale, width, offx, offy);\r
   }\r
@@ -296,9 +295,9 @@ public class TreeCanvas
     if (node.left() == null && node.right() == null)\r
     {\r
       float height = node.height;\r
-      float dist = node.dist;\r
+      //float dist = node.dist;\r
 \r
-      int xstart = (int) ( (height - dist) * scale) + offx;\r
+      //int xstart = (int) ( (height - dist) * scale) + offx;\r
       int xend = (int) (height * scale) + offx;\r
 \r
       int ypos = (int) (node.ycount * chunk) + offy;\r
@@ -338,7 +337,7 @@ public class TreeCanvas
 \r
       if (node.element() instanceof SequenceI)\r
       {\r
-        ( (SequenceI) node.element()).setColor(c);\r
+        av.setSequenceColour((SequenceI) node.element(), c);\r
       }\r
     }\r
     else\r
@@ -349,48 +348,48 @@ public class TreeCanvas
     }\r
   }\r
 \r
-  public void paint(Graphics g)\r
+  public void update(Graphics g)\r
   {\r
+    paint(g);\r
+  }\r
 \r
-    font = new Font("Verdana", Font.PLAIN, fontSize);\r
-    g.setFont(font);\r
-\r
-    FontMetrics fm = g.getFontMetrics(font);\r
+  public void paint(Graphics g)\r
+  {\r
+    if(tree==null)\r
+      return;\r
 \r
     if (nameHash.size() == 0)\r
     {\r
       repaint();\r
     }\r
 \r
-    if (fitToWindow ||\r
-        (!fitToWindow &&\r
-         scrollPane.getSize().height > fm.getHeight() * nameHash.size() + offy))\r
+    int width = scrollPane.getSize().width;\r
+    int height = scrollPane.getSize().height;\r
+    if(!fitToWindow)\r
     {\r
-      draw(g, scrollPane.getSize().width, scrollPane.getSize().height);\r
+      height = g.getFontMetrics(font).getHeight() * nameHash.size();\r
     }\r
-    else\r
+\r
+    if(getSize().width>width)\r
     {\r
-      setSize(new Dimension(scrollPane.getSize().width,\r
-                            fm.getHeight() * nameHash.size()));\r
-      draw(g, scrollPane.getSize().width, fm.getHeight() * nameHash.size());\r
+      setSize(new Dimension(width,height));\r
+      scrollPane.validate();\r
+      return;\r
     }\r
 \r
-    scrollPane.validate();\r
-  }\r
+    setSize(new Dimension(width,height));\r
 \r
-  public int getFontSize()\r
-  {\r
-    return fontSize;\r
-  }\r
 \r
-  public void setFontSize(int fontSize)\r
-  {\r
-    this.fontSize = fontSize;\r
-    repaint();\r
+    g.setFont(font);\r
+\r
+    draw(g, width, height);\r
+\r
   }\r
 \r
+\r
   public void draw(Graphics g, int width, int height)\r
   {\r
+    offy = font.getSize()+10;\r
 \r
     g.setColor(Color.white);\r
     g.fillRect(0, 0, width, height);\r
@@ -406,7 +405,7 @@ public class TreeCanvas
       top.count = ( (SequenceNode) top.left()).count +\r
           ( (SequenceNode) top.right()).count;\r
     }\r
-    float chunk = (float) (height - offy * 2) / top.count;\r
+    float chunk = (float) (height - offy) / top.count;\r
 \r
     drawNode(g, tree.getTopNode(), chunk, wscale, width, offx, offy);\r
 \r
@@ -438,8 +437,57 @@ public class TreeCanvas
   public void mouseExited(MouseEvent e)\r
   {}\r
 \r
-  public void mouseClicked(MouseEvent e)\r
+  public void mouseClicked(MouseEvent evt)\r
+  {\r
+    if (highlightNode != null)\r
+    {\r
+      if (evt.getClickCount() > 1)\r
+      {\r
+        tree.swapNodes(highlightNode);\r
+        tree.reCount(tree.getTopNode());\r
+        tree.findHeight(tree.getTopNode());\r
+      }\r
+      else\r
+      {\r
+        Vector leaves = new Vector();\r
+        tree.findLeaves(highlightNode, leaves);\r
+\r
+        for (int i = 0; i < leaves.size(); i++)\r
+        {\r
+          SequenceI seq =\r
+              (SequenceI) ( (SequenceNode) leaves.elementAt(i)).element();\r
+          treeSelectionChanged(seq);\r
+        }\r
+      }\r
+\r
+      PaintRefresher.Refresh(this, av.getSequenceSetId());\r
+      repaint();\r
+    }\r
+  }\r
+\r
+  public void mouseDragged(MouseEvent ect)\r
+  {}\r
+\r
+\r
+  public void mouseMoved(MouseEvent evt)\r
   {\r
+    av.setCurrentTree(tree);\r
+\r
+    Object ob = findElement(evt.getX(), evt.getY());\r
+\r
+    if (ob instanceof SequenceNode)\r
+    {\r
+      highlightNode = (SequenceNode) ob;\r
+      repaint();\r
+    }\r
+    else\r
+    {\r
+      if (highlightNode != null)\r
+      {\r
+        highlightNode = null;\r
+        repaint();\r
+      }\r
+    }\r
   }\r
 \r
   public void mousePressed(MouseEvent e)\r
@@ -453,19 +501,12 @@ public class TreeCanvas
 \r
     if (ob instanceof SequenceI)\r
     {\r
-      TreeSelectionChanged( (Sequence) ob);\r
+      treeSelectionChanged( (Sequence) ob);\r
+      PaintRefresher.Refresh(this, av.getSequenceSetId());\r
       repaint();\r
       return;\r
-\r
-    }\r
-    else if (ob instanceof SequenceNode)\r
-    {\r
-      SequenceNode tmpnode = (SequenceNode) ob;\r
-      tree.swapNodes(tmpnode);\r
-      tree.reCount(tree.getTopNode());\r
-      tree.findHeight(tree.getTopNode());\r
     }\r
-    else\r
+    else if ( !(ob instanceof SequenceNode))\r
     {\r
       // Find threshold\r
 \r
@@ -480,8 +521,21 @@ public class TreeCanvas
 \r
         av.setSelectionGroup(null);\r
         av.alignment.deleteAllGroups();\r
+        av.sequenceColours=null;\r
+\r
+        colourGroups();\r
+\r
+      }\r
+    }\r
 \r
-        for (int i = 0; i < tree.getGroups().size(); i++)\r
+    PaintRefresher.Refresh(this, av.getSequenceSetId());\r
+    repaint();\r
+\r
+  }\r
+\r
+  void colourGroups()\r
+  {\r
+    for (int i = 0; i < tree.getGroups().size(); i++)\r
         {\r
 \r
           Color col = new Color( (int) (Math.random() * 255),\r
@@ -530,7 +584,8 @@ public class TreeCanvas
             {\r
             Conservation c = new Conservation("Group",\r
                                               ResidueProperties.propHash, 3,\r
-                                              sg.sequences, sg.getStartRes(),\r
+                                              sg.getSequences(false),\r
+                                              sg.getStartRes(),\r
                                               sg.getEndRes());\r
 \r
             c.calculate();\r
@@ -544,11 +599,6 @@ public class TreeCanvas
           av.alignment.addGroup(sg);\r
 \r
         }\r
-      }\r
-    }\r
-\r
-    PaintRefresher.Refresh(this, av.alignment);\r
-    repaint();\r
 \r
   }\r
 \r