*/
package jalview.viewmodel;
-import jalview.api.AlignViewportI;
-import jalview.datamodel.ColumnSelection;
+import jalview.api.AlignmentColsCollectionI;
+import jalview.api.AlignmentRowsCollectionI;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.HiddenColumns;
import jalview.datamodel.HiddenSequences;
+import java.awt.Dimension;
import java.awt.Graphics;
-public class OverviewDimensions
+public abstract class OverviewDimensions
{
- // Default width and height values
- private static final int DEFAULT_GRAPH_HEIGHT = 20;
+ protected static final int MAX_WIDTH = 400;
- private static final int MAX_WIDTH = 400;
+ protected static final int MIN_WIDTH = 120;
- private static final int MIN_WIDTH = 120;
+ protected static final int MIN_SEQ_HEIGHT = 40;
- private static final int MIN_SEQ_HEIGHT = 40;
+ protected static final int MAX_SEQ_HEIGHT = 300;
- private static final int MAX_SEQ_HEIGHT = 300;
+ private static final int DEFAULT_GRAPH_HEIGHT = 20;
- private AlignViewportI av;
+ protected int width;
- private ViewportPositionProps posProps;
+ protected int sequencesHeight;
- // width of the overview panel
- private int width;
+ protected int graphHeight = DEFAULT_GRAPH_HEIGHT;
- // height of sequences part of the overview panel
- private int sequencesHeight;
+ protected int boxX = -1;
- // height of the graphs part of the overview panel
- private int graphHeight = DEFAULT_GRAPH_HEIGHT;
+ protected int boxY = -1;
- // dimensions of box outlining current extent of view in alignment panel
- // location of left side of box
- private int boxX = -1;
+ protected int boxWidth = -1;
- // location of bottom of box
- private int boxY = -1;
+ protected int boxHeight = -1;
- // width of box
- private int boxWidth = -1;
+ protected int alwidth;
- // height of box
- private int boxHeight = -1;
+ protected int alheight;
- private int scrollCol = -1;
+ protected float widthRatio;
- private int scrollRow = -1;
+ protected float heightRatio;
- public OverviewDimensions(AlignViewportI avi, boolean showAnnotationPanel)
+ /**
+ * Create an OverviewDimensions object
+ *
+ * @param ranges
+ * positional properties of the viewport
+ * @param showAnnotationPanel
+ * true if the annotation panel is to be shown, false otherwise
+ */
+ public OverviewDimensions(ViewportRanges ranges,
+ boolean showAnnotationPanel, Dimension dim)
{
- this.av = avi;
- this.posProps = av.getPosProps();
+ if (!showAnnotationPanel)
+ {
+ graphHeight = 0;
+ }
// scale the initial size of overviewpanel to shape of alignment
- float initialScale = (float) posProps.getAlignmentWidthInCols()
- / (float) posProps.getAlignmentHeightInRows();
+ float initialScale = (float) ranges.getAbsoluteAlignmentWidth()
+ / (float) ranges.getAbsoluteAlignmentHeight();
- if (!showAnnotationPanel)
+ if (dim != null)
{
- graphHeight = 0;
+ width = dim.width;
+ sequencesHeight = dim.height;
+ return;
}
- if (posProps.getAlignmentWidthInCols() > posProps
- .getAlignmentHeightInRows())
+ if (ranges.getAbsoluteAlignmentWidth() > ranges
+ .getAbsoluteAlignmentHeight())
{
// wider
width = MAX_WIDTH;
- sequencesHeight = (int) (MAX_WIDTH / initialScale);
+ sequencesHeight = Math.round(MAX_WIDTH / initialScale);
if (sequencesHeight < MIN_SEQ_HEIGHT)
{
sequencesHeight = MIN_SEQ_HEIGHT;
else
{
// taller
- width = (int) (MAX_WIDTH * initialScale);
+ width = Math.round(MAX_WIDTH * initialScale);
sequencesHeight = MAX_SEQ_HEIGHT;
if (width < MIN_WIDTH)
}
/**
- * Check box dimensions and scroll positions and correct if necessary
- */
- public void updateViewportFromMouse(int x, int y)
- {
- int alwidth = av.getAlignment().getWidth();
- int alheight = av.getAlignment().getAbsoluteHeight();
-
- HiddenSequences hiddenSeqs = av.getAlignment().getHiddenSequences();
- ColumnSelection hiddenCols = av.getColumnSelection();
-
- if (x < 0)
- {
- x = 0;
- }
- else if (x >= alwidth)
- {
- x = alwidth - 1;
- }
-
- if (y < 0)
- {
- y = 0;
- }
- else if (y >= alheight)
- {
- y = alheight - 1;
- }
-
- //
- // Convert x value to residue position
- //
-
- // need to determine where scrollCol should be, given x
- // to do this also need to know width of viewport, and some hidden column
- // correction
-
- // convert x to residues - this is an absolute position
- int xAsRes = Math.round((float) x * alwidth / width);
-
- // get viewport width in residues
- int vpwidth = av.getPosProps().getEndRes()
- - av.getPosProps().getStartRes() + 1;
-
- // get where x should be when accounting for hidden cols
- // if x is in a hidden col region, shift to left - but we still need
- // absolute position
- // so convert back after getting visible region position
- xAsRes = hiddenCols.adjustForHiddenColumns(hiddenCols
- .findColumnPosition(xAsRes));
-
- // get where end res should be by adding the viewport width on
- int endRes = xAsRes + vpwidth;
-
- // check in case we went off the edge of the alignment
- if (endRes > alwidth)
- {
- // went past the end of the alignment, adjust backwards
- endRes = alwidth;
- // recalc xAsRes backwards from endRes
- xAsRes = endRes - vpwidth;
- }
-
- //
- // Convert y value to sequence position
- //
-
- // convert y to residues
- int yAsSeq = Math.round((float) y * alheight / sequencesHeight);
-
- // get viewport height in sequences
- int vpheight = av.getPosProps().getEndSeq()
- - av.getPosProps().getStartSeq();
-
- // get where y should be when accounting for hidden rows
- // if y is in a hidden row region, shift up - but we still need absolute
- // position,
- // so convert back after getting visible region position
- yAsSeq = hiddenSeqs.adjustForHiddenSeqs(hiddenSeqs
- .findIndexWithoutHiddenSeqs(yAsSeq));
-
- // get where end seq should be by adding the viewport height on
- int endSeq = yAsSeq + vpheight;
-
- // check in case we went off the edge of the alignment
- if (endSeq > alheight)
- {
- // went past the end of the alignment, adjust backwards
- endSeq = alheight;
- // recalc yAsSeq backwards from endSeq
- yAsSeq = endSeq - vpheight;
- }
-
- // convert absolute positions back to visible alignment positions for
- // viewport scrolling
- scrollCol = hiddenCols.findColumnPosition(xAsRes);
- scrollRow = hiddenSeqs.findIndexWithoutHiddenSeqs(yAsSeq);
- }
-
- /**
- * Update the overview panel box when the associated alignment panel is
- * changed
- *
- */
- public void setBoxPosition()
- {
- int alwidth = av.getAlignment().getWidth();
- int alheight = av.getAlignment().getAbsoluteHeight();
-
- int startRes = av.getPosProps().getAbsoluteStartRes();
- int endRes = av.getPosProps().getAbsoluteEndRes();
-
- int startSeq = av.getPosProps().getAbsoluteStartSeq();
- int endSeq = av.getPosProps().getAbsoluteEndSeq();
-
- boxX = Math.round((float) startRes * width / alwidth);
- boxY = Math.round((float) startSeq * sequencesHeight / alheight);
-
- boxWidth = Math
- .round((float) (endRes - startRes + 1) * width / alwidth);
- boxHeight = Math.round((float) (endSeq - startSeq) * sequencesHeight
- / alheight);
- }
-
- /**
* Draw the overview panel's viewport box on a graphics object
*
* @param g
g.drawRect(boxX + 1, boxY + 1, boxWidth - 2, boxHeight - 2);
}
- // don't like this, scroll vals are separate from setting code
- public int getScrollCol()
- {
- return scrollCol;
- }
-
- public int getScrollRow()
- {
- return scrollRow;
- }
-
- // TODO should be removed, when unit test has mock Graphics object available
- // to check boxX/boxY
public int getBoxX()
{
return boxX;
}
- // TODO should be removed, when unit test has mock Graphics object available
- // to check boxX/boxY
public int getBoxY()
{
return boxY;
}
- // TODO should be removed, when unit test has mock Graphics object available
public int getBoxWidth()
{
return boxWidth;
}
- // TODO should be removed, when unit test has mock Graphics object available
public int getBoxHeight()
{
return boxHeight;
}
- public void setBoxX(int x)
+ public int getWidth()
{
- boxX = x;
+ return width;
}
- public void setBoxY(int y)
+ public int getHeight()
{
- boxY = y;
+ return sequencesHeight + graphHeight;
}
- public void setWidth(int w)
+ public int getSequencesHeight()
{
- width = w;
+ return sequencesHeight;
}
- public void setHeight(int h)
+ public int getGraphHeight()
{
- sequencesHeight = h - graphHeight;
+ return graphHeight;
}
- public int getWidth()
+ public float getPixelsPerCol()
{
- return width;
+ resetAlignmentDims();
+ return 1 / widthRatio;
}
- public int getHeight()
+ public float getPixelsPerSeq()
{
- return sequencesHeight + graphHeight;
+ resetAlignmentDims();
+ return 1 / heightRatio;
}
- public int getSequencesHeight()
+ public void setWidth(int w)
{
- return sequencesHeight;
+ width = w;
+ widthRatio = (float) alwidth / width;
}
- public int getGraphHeight()
+ public void setHeight(int h)
{
- return graphHeight;
+ sequencesHeight = h - graphHeight;
+ heightRatio = (float) alheight / sequencesHeight;
+ }
+
+ /**
+ * Update the viewport location from a mouse click in the overview panel
+ *
+ * @param mousex
+ * x location of mouse
+ * @param mousey
+ * y location of mouse
+ * @param hiddenSeqs
+ * the alignment's hidden sequences
+ * @param hiddenCols
+ * the alignment's hidden columns
+ */
+ public abstract void updateViewportFromMouse(int mousex, int mousey,
+ HiddenSequences hiddenSeqs, HiddenColumns hiddenCols);
+
+ /**
+ * Update the viewport location from a mouse drag within the overview's box
+ *
+ * @param mousex
+ * x location of mouse
+ * @param mousey
+ * y location of mouse
+ * @param hiddenSeqs
+ * the alignment's hidden sequences
+ * @param hiddenCols
+ * the alignment's hidden columns
+ */
+ public abstract void adjustViewportFromMouse(int mousex, int mousey,
+ HiddenSequences hiddenSeqs, HiddenColumns hiddenCols);
+
+ /**
+ * Initialise dragging from the mouse - must be called on initial mouse click
+ * before using adjustViewportFromMouse in drag operations
+ *
+ * @param mousex
+ * x location of mouse
+ * @param mousey
+ * y location of mouse
+ * @param hiddenSeqs
+ * the alignment's hidden sequences
+ * @param hiddenCols
+ * the alignment's hidden columns
+ */
+ public abstract void setDragPoint(int x, int y,
+ HiddenSequences hiddenSeqs, HiddenColumns hiddenCols);
+
+ /*
+ * Move the viewport so that the top left corner of the overview's box
+ * is at the mouse position (leftx, topy)
+ */
+ protected abstract void updateViewportFromTopLeft(int leftx, int topy,
+ HiddenSequences hiddenSeqs, HiddenColumns hiddenCols);
+
+ /**
+ * Set the overview panel's box position to match the viewport
+ *
+ * @param hiddenSeqs
+ * the alignment's hidden sequences
+ * @param hiddenCols
+ * the alignment's hidden columns
+ */
+ public abstract void setBoxPosition(HiddenSequences hiddenSeqs,
+ HiddenColumns hiddenCols);
+
+ /**
+ * Get the collection of columns used by this overview dimensions object
+ *
+ * @param hiddenCols
+ * the alignment's hidden columns
+ * @return a column collection
+ */
+ public abstract AlignmentColsCollectionI getColumns(AlignmentI al);
+
+ /**
+ * Get the collection of rows used by this overview dimensions object
+ *
+ * @param al
+ * the alignment
+ * @return a row collection
+ */
+ public abstract AlignmentRowsCollectionI getRows(AlignmentI al);
+
+ /**
+ * Updates overview dimensions to account for current alignment dimensions
+ */
+ protected abstract void resetAlignmentDims();
+
+ /*
+ * Given the box coordinates in residues and sequences, set the box dimensions in the overview window
+ */
+ protected void setBoxPosition(int startRes, int startSeq, int vpwidth,
+ int vpheight)
+ {
+ resetAlignmentDims();
+
+ // boxX, boxY is the x,y location equivalent to startRes, startSeq
+ int xPos = Math.min(startRes, alwidth - vpwidth + 1);
+ boxX = Math.round(xPos / widthRatio);
+ boxY = Math.round(startSeq / heightRatio);
+
+ // boxWidth is the width in residues translated to pixels
+ boxWidth = Math.round(vpwidth / widthRatio);
+
+ // boxHeight is the height in sequences translated to pixels
+ boxHeight = Math.round(vpheight / heightRatio);
+ }
+
+ /**
+ * Answers if a mouse position is in the overview's red box
+ *
+ * @param x
+ * mouse x position
+ * @param y
+ * mouse y position
+ * @return true if (x,y) is inside the box
+ */
+ public boolean isPositionInBox(int x, int y)
+ {
+ return (x > boxX && y > boxY && x < boxX + boxWidth
+ && y < boxY + boxHeight);
}
-}
+
+ /*
+ * Given the centre x position, calculate the box's left x position
+ */
+ protected abstract int getLeftXFromCentreX(int mousex,
+ HiddenColumns hidden);
+
+ /*
+ * Given the centre y position, calculate the box's top y position
+ */
+ protected abstract int getTopYFromCentreY(int mousey,
+ HiddenSequences hidden);
+
+}
\ No newline at end of file