import jalview.datamodel.SequencePoint;
import jalview.math.RotatableMatrix;
import jalview.math.RotatableMatrix.Axis;
+import jalview.util.ColorUtils;
import jalview.util.MessageManager;
import jalview.viewmodel.AlignmentViewport;
}
- public void showLabels(boolean b)
+ /**
+ * Refreshes the display with labels shown (or not)
+ *
+ * @param show
+ */
+ public void showLabels(boolean show)
{
- showLabels = b;
+ showLabels = show;
repaint();
}
* Resets axes to the initial state: x-axis to the right, y-axis up, z-axis to
* back (so obscured in a 2-D display)
*/
- public void resetAxes()
+ protected void resetAxes()
{
axisEndPoints[0] = new Point(1f, 0f, 0f);
axisEndPoints[1] = new Point(0f, 1f, 0f);
* sequence point, and also the min-max range (width) for each dimension, and
* the maximum width for all dimensions
*/
- public void findWidth()
+ protected void findWidth()
{
max = new float[DIMS];
min = new float[DIMS];
*
* @return DOCUMENT ME!
*/
- public float findScale()
+ protected float findScale()
{
int dim;
int w;
/**
* Computes and saves the position of the centre of the view
*/
- public void findCentre()
+ protected void findCentre()
{
findWidth();
* gray if sequence is currently selected
*/
SequencePoint sp = points.elementAt(i);
- SequenceI sequence = sp.getSequence();
- Color sequenceColour = av.getSequenceColour(sequence);
- g.setColor(
- sequenceColour == Color.black ? Color.white : sequenceColour);
- if (av.getSelectionGroup() != null)
- {
- if (av.getSelectionGroup().getSequences(null)
- .contains(sequence))
- {
- g.setColor(Color.gray);
- }
- }
-
- /*
- * dim sequence points 'at the back'
- */
- if (sp.coord.z < centre.z)
- {
- g.setColor(g.getColor().darker());
- }
+ Color sequenceColour = getSequencePointColour(sp);
+ g.setColor(sequenceColour);
int halfwidth = getWidth() / 2;
int halfheight = getHeight() / 2;
if (showLabels)
{
g.setColor(Color.red);
- g.drawString(sequence.getName(), x - 3, y - 4);
+ g.drawString(sp.getSequence().getName(), x - 3, y - 4);
}
}
// }
}
+ /**
+ * Determines the colour to use when drawing a sequence point. The colour is
+ * taken from the sequence id, with black converted to white, and then
+ * graduated from darker (at the back) to brighter (at the front) based on the
+ * z-axis coordinate of the point.
+ *
+ * @param sp
+ * @return
+ */
+ protected Color getSequencePointColour(SequencePoint sp)
+ {
+ SequenceI sequence = sp.getSequence();
+ Color sequenceColour = av.getSequenceColour(sequence);
+ if (sequenceColour == Color.black)
+ {
+ sequenceColour = Color.white;
+ }
+ if (av.getSelectionGroup() != null)
+ {
+ if (av.getSelectionGroup().getSequences(null).contains(sequence))
+ {
+ sequenceColour = Color.gray;
+ }
+ }
+
+ /*
+ * graduate from front (brighter) to back (darker)
+ */
+ sequenceColour = ColorUtils.getGraduatedColour(sp.coord.z, min[2],
+ max[2], sequenceColour);
+
+ return sequenceColour;
+ }
+
@Override
public void keyTyped(KeyEvent evt)
{
* @param x2
* @param y2
*/
- public void rectSelect(int x1, int y1, int x2, int y2)
+ protected void rectSelect(int x1, int y1, int x2, int y2)
{
for (int i = 0; i < npoint; i++)
{
*
* @return
*/
- public SequenceI findSequenceAtPoint(int x, int y)
+ protected SequenceI findSequenceAtPoint(int x, int y)
{
int halfwidth = getWidth() / 2;
int halfheight = getHeight() / 2;
public class ColorUtils
{
+ // constant borrowed from java.awt.Color
+ private static final float FACTOR = 0.7f;
+
private static final int MAX_CACHE_SIZE = 1729;
/*
* a cache for colours generated from text strings
return col;
}
+
+ /**
+ * Generates a colour that is interpolated between
+ * <code>colour.darker()</code> and <code>colour.brighter()</code> in
+ * proportion as <code>value</code> is between <code>min</code> and
+ * <code>max</code>. Note that the 'neutral point' (unchanged colour) is
+ * closer to 'brighter' than to 'darker'as this is a geometric range.
+ *
+ * @param value
+ * @param min
+ * @param max
+ * @param colour
+ * @return
+ */
+ public static Color getGraduatedColour(float value, float min, float max,
+ Color colour)
+ {
+ /*
+ * this computes the equivalent of
+ * getGraduatedColour(value, min, colour.darker(), max, colour.brighter())
+ * but avoiding object creation except for the return value
+ */
+ if (value < min)
+ {
+ value = min;
+ }
+ if (value > max)
+ {
+ value = max;
+ }
+
+ int r = colour.getRed();
+ int g = colour.getGreen();
+ int b = colour.getBlue();
+
+ /*
+ * rgb for colour.darker():
+ */
+ float minR = r * FACTOR;
+ float minG = g * FACTOR;
+ float minB = b * FACTOR;
+
+ /*
+ * rgb for colour.brighter():
+ */
+ float maxR = Math.min(255f, r / FACTOR);
+ float maxG = Math.min(255f, g / FACTOR);
+ float maxB = Math.min(255f, b / FACTOR);
+
+ /*
+ * interpolation
+ */
+ float p = (value - min) / (max - min);
+ int newR = (int) (minR + p * (maxR - minR));
+ int newG = (int) (minG + p * (maxG - minG));
+ int newB = (int) (minB + p * (maxB - minB));
+
+ return new Color(newR, newG, newB, colour.getAlpha());
+ }
}
assertEquals(new Color(184, 184, 184),
ColorUtils.createColourFromName("HELLO HELLO HELLO "));
}
+
+ /**
+ * Tests for the method that returns a colour graduated between darker() and
+ * brighter()
+ */
+ @Test(groups = { "Functional" })
+ public void testGetGraduatedColour_darkerToBrighter()
+ {
+ final Color colour = new Color(180, 200, 220);
+
+ /*
+ * value half-way between min and max does _not_ mean colour unchanged
+ * darker (*.7) is (126, 140, 154)
+ * brighter (*1/.7) is (255, 255, 255)
+ * midway is (190, 197, 204)
+ */
+ Color col = ColorUtils.getGraduatedColour(20f, 10f, 30f, colour);
+ assertEquals(190, col.getRed());
+ assertEquals(197, col.getGreen());
+ assertEquals(204, col.getBlue());
+
+ // minValue (or less) returns colour.darker()
+ // - or would do if Color.darker calculated better!
+ col = ColorUtils.getGraduatedColour(10f, 10f, 30f, colour);
+ assertEquals(col, new Color(126, 140, 154));
+ // Color.darker computes 125.999999 and rounds down!
+ assertEquals(new Color(125, 140, 154), colour.darker());
+ col = ColorUtils.getGraduatedColour(-10f, 10f, 30f, colour);
+ assertEquals(new Color(126, 140, 154), col);
+
+ // maxValue (or more) returns colour.brighter()
+ col = ColorUtils.getGraduatedColour(30f, 10f, 30f, colour);
+ assertEquals(colour.brighter(), col);
+ col = ColorUtils.getGraduatedColour(40f, 10f, 30f, colour);
+ assertEquals(colour.brighter(), col);
+
+ /*
+ * 'linear' mid-point between 0.7 and 1/0.7 is 1.057
+ * so the '
+ */
+ Color c = new Color(200, 200, 200);
+ col = ColorUtils.getGraduatedColour(106f, 0f, 200f, c);
+ assertEquals(c, col);
+ }
}