Merge branch 'develop' into spike/JAL-4047/JAL-4048_columns_in_sequenceID
[jalview.git] / src / jalview / gui / AnnotationColourChooser.java
index 8500888..d898398 100644 (file)
  */
 package jalview.gui;
 
-import jalview.bin.Cache;
-import jalview.datamodel.AlignmentAnnotation;
-import jalview.datamodel.GraphLine;
-import jalview.datamodel.SequenceGroup;
-import jalview.schemes.AnnotationColourGradient;
-import jalview.schemes.ColourSchemeI;
-import jalview.util.MessageManager;
-
 import java.awt.BorderLayout;
 import java.awt.Color;
 import java.awt.Dimension;
@@ -42,19 +34,25 @@ import java.util.Vector;
 import javax.swing.BorderFactory;
 import javax.swing.JButton;
 import javax.swing.JCheckBox;
-import javax.swing.JColorChooser;
 import javax.swing.JComboBox;
 import javax.swing.JInternalFrame;
 import javax.swing.JLayeredPane;
 import javax.swing.JPanel;
 
+import jalview.bin.Cache;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.GraphLine;
+import jalview.datamodel.SequenceGroup;
+import jalview.gui.JalviewColourChooser.ColourChooserListener;
+import jalview.schemes.AnnotationColourGradient;
+import jalview.schemes.ColourSchemeI;
+import jalview.util.MessageManager;
 import net.miginfocom.swing.MigLayout;
 
 @SuppressWarnings("serial")
 public class AnnotationColourChooser extends AnnotationRowFilter
 {
-  private static final int ONETHOUSAND = 1000;
-
   private ColourSchemeI oldcs;
 
   private JButton defColours;
@@ -63,19 +61,27 @@ public class AnnotationColourChooser extends AnnotationRowFilter
 
   private JCheckBox useOriginalColours = new JCheckBox();
 
-  private JPanel minColour = new JPanel();
+  JPanel minColour = new JPanel();
 
-  private JPanel maxColour = new JPanel();
+  JPanel maxColour = new JPanel();
 
   private JCheckBox thresholdIsMin = new JCheckBox();
 
+  protected static final int MIN_WIDTH = 500;
+
+  protected static final int MIN_HEIGHT = 240;
+
   public AnnotationColourChooser(AlignViewport av, final AlignmentPanel ap)
   {
+    this(av,ap,null);
+  }
+  public AnnotationColourChooser(AlignViewport av, final AlignmentPanel ap,AnnotationColourGradient initSettings)
+  {
     super(av, ap);
     oldcs = av.getGlobalColourScheme();
     if (av.getAlignment().getGroups() != null)
     {
-      oldgroupColours = new Hashtable<SequenceGroup, ColourSchemeI>();
+      oldgroupColours = new Hashtable<>();
       for (SequenceGroup sg : ap.av.getAlignment().getGroups())
       {
         if (sg.getColourScheme() != null)
@@ -85,12 +91,13 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       }
     }
     frame = new JInternalFrame();
+    frame.setFrameIcon(null);
     frame.setContentPane(this);
     frame.setLayer(JLayeredPane.PALETTE_LAYER);
     Desktop.addInternalFrame(frame,
             MessageManager.getString("label.colour_by_annotation"), 520,
             215);
-
+    frame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
     addSliderChangeListener();
     addSliderMouseListeners();
 
@@ -103,11 +110,28 @@ public class AnnotationColourChooser extends AnnotationRowFilter
     setDefaultMinMax();
 
     adjusting = true;
-    if (oldcs instanceof AnnotationColourGradient)
+    if (oldcs instanceof AnnotationColourGradient && initSettings==null)
     {
-      AnnotationColourGradient acg = (AnnotationColourGradient) oldcs;
-      useOriginalColours.setSelected(acg.isPredefinedColours()
-              || acg.getBaseColour() != null);
+      // init from oldcs
+      initialiseFrom((AnnotationColourGradient) oldcs);
+    } else {
+      // use initial colour gradient - if any..
+      initialiseFrom(initSettings);
+    }
+    
+    jbInit();
+    adjusting = false;
+
+    updateView();
+    frame.invalidate();
+    frame.pack();
+  }
+  private void initialiseFrom(AnnotationColourGradient acg)
+  {
+    if (acg!=null)
+    {
+      useOriginalColours.setSelected(
+            acg.isPredefinedColours() || acg.getBaseColour() != null);
       if (!acg.isPredefinedColours() && acg.getBaseColour() == null)
       {
         minColour.setBackground(acg.getMinColour());
@@ -116,16 +140,20 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       seqAssociated.setSelected(acg.isSeqAssociated());
 
     }
-    Vector<String> annotItems = getAnnotationItems(seqAssociated
-            .isSelected());
-    annotations = new JComboBox<String>(annotItems);
+    Vector<String> annotItems = getAnnotationItems(
+            seqAssociated.isSelected());
+    annotations = new JComboBox<>(annotItems);
 
     populateThresholdComboBox(threshold);
 
-    if (oldcs instanceof AnnotationColourGradient)
+    if (acg!=null)
     {
-      AnnotationColourGradient acg = (AnnotationColourGradient) oldcs;
       String label = getAnnotationMenuLabel(acg.getAnnotation());
+      // TODO: workaround below shouldn't be necessary - there's a bug in getAnnotationMenuLabel!
+      if (acg.isSeqAssociated())
+      {
+        label = acg.getAnnotation().label;
+      }
       annotations.setSelectedItem(label);
       switch (acg.getAboveThreshold())
       {
@@ -139,20 +167,12 @@ public class AnnotationColourChooser extends AnnotationRowFilter
         getThreshold().setSelectedIndex(2);
         break;
       default:
-        throw new Error(
-                MessageManager
-                        .getString("error.implementation_error_dont_know_about_threshold_setting"));
+        throw new Error(MessageManager.getString(
+                "error.implementation_error_dont_know_about_threshold_setting"));
       }
       thresholdIsMin.setSelected(acg.isThresholdIsMinMax());
-      thresholdValue.setText("" + acg.getAnnotationThreshold());
+      thresholdValue.setText(String.valueOf(acg.getAnnotationThreshold()));
     }
-
-    jbInit();
-    adjusting = false;
-
-    updateView();
-    frame.invalidate();
-    frame.pack();
   }
 
   @Override
@@ -171,7 +191,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       {
         if (minColour.isEnabled())
         {
-          minColour_actionPerformed();
+          showColourChooser(minColour, "label.select_colour_minimum_value");
         }
       }
     });
@@ -186,7 +206,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       {
         if (maxColour.isEnabled())
         {
-          maxColour_actionPerformed();
+          showColourChooser(maxColour, "label.select_colour_maximum_value");
         }
       }
     });
@@ -208,8 +228,8 @@ public class AnnotationColourChooser extends AnnotationRowFilter
 
     useOriginalColours.setFont(JvSwingUtils.getLabelFont());
     useOriginalColours.setOpaque(false);
-    useOriginalColours.setText(MessageManager
-            .getString("label.use_original_colours"));
+    useOriginalColours.setText(
+            MessageManager.getString("label.use_original_colours"));
     useOriginalColours.addActionListener(new ActionListener()
     {
       @Override
@@ -220,8 +240,8 @@ public class AnnotationColourChooser extends AnnotationRowFilter
     });
     thresholdIsMin.setBackground(Color.white);
     thresholdIsMin.setFont(JvSwingUtils.getLabelFont());
-    thresholdIsMin.setText(MessageManager
-            .getString("label.threshold_minmax"));
+    thresholdIsMin
+            .setText(MessageManager.getString("label.threshold_minmax"));
     thresholdIsMin.addActionListener(new ActionListener()
     {
       @Override
@@ -232,8 +252,8 @@ public class AnnotationColourChooser extends AnnotationRowFilter
     });
     seqAssociated.setBackground(Color.white);
     seqAssociated.setFont(JvSwingUtils.getLabelFont());
-    seqAssociated.setText(MessageManager
-            .getString("label.per_sequence_only"));
+    seqAssociated
+            .setText(MessageManager.getString("label.per_sequence_only"));
     seqAssociated.addActionListener(new ActionListener()
     {
 
@@ -279,42 +299,33 @@ public class AnnotationColourChooser extends AnnotationRowFilter
 
   private void setDefaultMinMax()
   {
-    minColour.setBackground(Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN",
-            Color.orange));
-    maxColour.setBackground(Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX",
-            Color.red));
-  }
-
-  public void minColour_actionPerformed()
-  {
-    Color col = JColorChooser.showDialog(this,
-            MessageManager.getString("label.select_colour_minimum_value"),
-            minColour.getBackground());
-    if (col != null)
-    {
-      minColour.setBackground(col);
-    }
-    minColour.repaint();
-    updateView();
+    minColour.setBackground(
+            Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN", Color.orange));
+    maxColour.setBackground(
+            Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", Color.red));
   }
 
-  public void maxColour_actionPerformed()
+  protected void showColourChooser(JPanel colourPanel, String titleKey)
   {
-    Color col = JColorChooser.showDialog(this,
-            MessageManager.getString("label.select_colour_maximum_value"),
-            maxColour.getBackground());
-    if (col != null)
+    String ttl = MessageManager.getString(titleKey);
+    ColourChooserListener listener = new ColourChooserListener()
     {
-      maxColour.setBackground(col);
-    }
-    maxColour.repaint();
-    updateView();
+      @Override
+      public void colourSelected(Color c)
+      {
+        colourPanel.setBackground(c);
+        colourPanel.repaint();
+        updateView();
+      }
+    };
+    JalviewColourChooser.showColourChooser(Desktop.getDesktop(), ttl,
+            colourPanel.getBackground(), listener);
   }
 
   @Override
   public void reset()
   {
-    av.setGlobalColourScheme(oldcs);
+    this.ap.alignFrame.changeColour(oldcs);
     if (av.getAlignment().getGroups() != null)
     {
 
@@ -330,15 +341,15 @@ public class AnnotationColourChooser extends AnnotationRowFilter
   {
     if (slider.isEnabled())
     {
-      if (useOriginalColours.isSelected()
-              && !(av.getGlobalColourScheme() instanceof AnnotationColourGradient))
+      if (useOriginalColours.isSelected() && !(av
+              .getGlobalColourScheme() instanceof AnnotationColourGradient))
       {
         updateView();
       }
-      getCurrentAnnotation().threshold.value = slider.getValue() / 1000f;
+      getCurrentAnnotation().threshold.value = getSliderValue();
       propagateSeqAssociatedThreshold(updateAllAnnotation,
               getCurrentAnnotation());
-      ap.paintAlignment(false);
+      ap.paintAlignment(false, false);
     }
   }
 
@@ -364,16 +375,20 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       return;
     }
 
-    setCurrentAnnotation(av.getAlignment().getAlignmentAnnotation()[annmap[annotations
-            .getSelectedIndex()]]);
+    int selIndex = annotations
+            .getSelectedIndex();
+    int annIndex = annmap[selIndex];
+    setCurrentAnnotation(
+            av.getAlignment().getAlignmentAnnotation()[annIndex]);
 
-    int selectedThresholdItem = getSelectedThresholdItem(getThreshold()
-            .getSelectedIndex());
+    int selectedThresholdItem = getSelectedThresholdItem(
+            getThreshold().getSelectedIndex());
 
     slider.setEnabled(true);
     thresholdValue.setEnabled(true);
     thresholdIsMin.setEnabled(!useOriginalColours.isSelected());
 
+    final AlignmentAnnotation currentAnnotation = getCurrentAnnotation();
     if (selectedThresholdItem == AnnotationColourGradient.NO_THRESHOLD)
     {
       slider.setEnabled(false);
@@ -382,41 +397,34 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       thresholdIsMin.setEnabled(false);
     }
     else if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD
-            && getCurrentAnnotation().threshold == null)
+            && currentAnnotation.threshold == null)
     {
-      getCurrentAnnotation()
-              .setThreshold(
-                      new GraphLine(
-                              (getCurrentAnnotation().graphMax - getCurrentAnnotation().graphMin) / 2f,
-                              "Threshold", Color.black));
+      currentAnnotation.setThreshold(new GraphLine(
+              (currentAnnotation.graphMax - currentAnnotation.graphMin)
+                      / 2f,
+              "Threshold", Color.black));
     }
 
     if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD)
     {
       adjusting = true;
-      float range = getCurrentAnnotation().graphMax * ONETHOUSAND
-              - getCurrentAnnotation().graphMin * ONETHOUSAND;
-
-      slider.setMinimum((int) (getCurrentAnnotation().graphMin * ONETHOUSAND));
-      slider.setMaximum((int) (getCurrentAnnotation().graphMax * ONETHOUSAND));
-      slider.setValue((int) (getCurrentAnnotation().threshold.value * ONETHOUSAND));
-      thresholdValue.setText(getCurrentAnnotation().threshold.value + "");
-      slider.setMajorTickSpacing((int) (range / 10f));
+      setSliderModel(currentAnnotation.graphMin, currentAnnotation.graphMax,
+              currentAnnotation.threshold.value);
       slider.setEnabled(true);
+
+      setThresholdValueText();
       thresholdValue.setEnabled(true);
       adjusting = false;
     }
-    colorAlignmentContaining(getCurrentAnnotation(), selectedThresholdItem);
+    colorAlignmentContaining(currentAnnotation, selectedThresholdItem);
 
     ap.alignmentChanged();
-    // ensure all associated views (overviews, structures, etc) are notified of
-    // updated colours.
-    ap.paintAlignment(true);
   }
 
-  protected boolean colorAlignmentContaining(AlignmentAnnotation currentAnn, int selectedThresholdOption)
+  protected void colorAlignmentContaining(AlignmentAnnotation currentAnn,
+          int selectedThresholdOption)
   {
-  
+
     AnnotationColourGradient acg = null;
     if (useOriginalColours.isSelected())
     {
@@ -430,44 +438,63 @@ public class AnnotationColourChooser extends AnnotationRowFilter
               selectedThresholdOption);
     }
     acg.setSeqAssociated(seqAssociated.isSelected());
-  
+
     if (currentAnn.graphMin == 0f && currentAnn.graphMax == 0f)
     {
       acg.setPredefinedColours(true);
     }
-  
+
     acg.setThresholdIsMinMax(thresholdIsMin.isSelected());
-  
-    av.setGlobalColourScheme(acg);
-  
+
+    this.ap.alignFrame.changeColour(acg);
+
     if (av.getAlignment().getGroups() != null)
     {
-  
+
       for (SequenceGroup sg : ap.av.getAlignment().getGroups())
       {
         if (sg.cs == null)
         {
           continue;
         }
-  
-        if (useOriginalColours.isSelected())
-        {
-          sg.setColourScheme(new AnnotationColourGradient(currentAnn, sg
-                  .getColourScheme(), selectedThresholdOption));
-          ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated
-                  .isSelected());
-        }
-        else
-        {
-          sg.setColourScheme(new AnnotationColourGradient(currentAnn,
-                  minColour.getBackground(), maxColour.getBackground(),
-                  selectedThresholdOption));
-          ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated
-                  .isSelected());
-        }
+        sg.setColourScheme(acg.getInstance(av, sg));
       }
     }
-    return false;
   }
 
+  @Override
+  protected void sliderDragReleased()
+  {
+    super.sliderDragReleased();
+    ap.paintAlignment(true, true);
+  }
+
+  /**
+   * construct and display a colourchooser for a given annotation row
+   * 
+   * @param av
+   * @param ap
+   * @param alignmentAnnotation
+   * @param perseq - when true, enable per-sequence if alignment annotation is per sequence 
+   */
+  public static void displayFor(AlignViewport av, AlignmentPanel ap,
+          AlignmentAnnotation alignmentAnnotation, boolean perSeq)
+  {
+    ColourSchemeI global = av.getGlobalColourScheme();
+    AnnotationColourGradient newCS = new AnnotationColourGradient(alignmentAnnotation, global, alignmentAnnotation.threshold!=null ? AnnotationColourGradient.ABOVE_THRESHOLD:AnnotationColourGradient.NO_THRESHOLD);
+    if (alignmentAnnotation.sequenceRef!=null)
+    {
+      newCS.setSeqAssociated(perSeq);
+    }
+    for (int i=0;i<alignmentAnnotation.annotations.length;i++)
+    {
+      Annotation ann = alignmentAnnotation.annotations[i];
+      if (ann!=null && ann.colour!=null && !ann.colour.equals(Color.white))
+      {
+        newCS.setPredefinedColours(true);
+        break;
+      }
+    }
+    AnnotationColourChooser achooser = new AnnotationColourChooser(av,ap,newCS);
+  }
 }