X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FAnnotationLabels.java;h=20e1b1bbe65e88b4bad42b99f26e9cf93bb9e716;hb=163eca0e8ab247f095a9d4dcbb9af20ea195e74d;hp=2c563f1d64b68d2ed8592e55c6a1354d7f5ca309;hpb=4bae495df9a00ece3d4f7672639c3a669446d461;p=jalview.git diff --git a/src/jalview/gui/AnnotationLabels.java b/src/jalview/gui/AnnotationLabels.java index 2c563f1..20e1b1b 100755 --- a/src/jalview/gui/AnnotationLabels.java +++ b/src/jalview/gui/AnnotationLabels.java @@ -20,6 +20,7 @@ */ package jalview.gui; +import java.awt.Canvas; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; @@ -50,9 +51,13 @@ import javax.swing.ToolTipManager; import jalview.analysis.AlignSeq; import jalview.analysis.AlignmentUtils; +import jalview.bin.Cache; +import jalview.bin.Jalview; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.Annotation; +import jalview.datamodel.ContactMatrixI; +import jalview.datamodel.GroupSet; import jalview.datamodel.HiddenColumns; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceGroup; @@ -83,7 +88,7 @@ public class AnnotationLabels extends JPanel /** * height in pixels for allowing height adjuster to be active */ - private static int HEIGHT_ADJUSTER_HEIGHT = 10; + public static int HEIGHT_ADJUSTER_HEIGHT = 10; private static final Font font = new Font("Arial", Font.PLAIN, 11); @@ -111,6 +116,8 @@ public class AnnotationLabels extends JPanel private static final String COPYCONS_SEQ = MessageManager .getString("label.copy_consensus_sequence"); + private static final String ADJUST_ANNOTATION_LABELS_WIDTH_PREF = "ADJUST_ANNOTATION_LABELS_WIDTH"; + private final boolean debugRedraw = false; private AlignmentPanel ap; @@ -129,6 +136,10 @@ public class AnnotationLabels extends JPanel private boolean resizePanel = false; + private int annotationIdWidth = -1; + + public static final String RESIZE_MARGINS_MARK_PREF = "RESIZE_MARGINS_MARK"; + /** * Creates a new AnnotationLabels object * @@ -136,7 +147,6 @@ public class AnnotationLabels extends JPanel */ public AnnotationLabels(AlignmentPanel ap) { - this.ap = ap; av = ap.av; ToolTipManager.sharedInstance().registerComponent(this); @@ -292,25 +302,20 @@ public class AnnotationLabels extends JPanel EditNameDialog dialog = new EditNameDialog(annotation.label, annotation.description, name, description); - dialog.showDialog(ap.alignFrame, title, new Runnable() - { - @Override - public void run() + dialog.showDialog(ap.alignFrame, title, () -> { + annotation.label = dialog.getName(); + String text = dialog.getDescription(); + if (text != null && text.length() == 0) { - annotation.label = dialog.getName(); - String text = dialog.getDescription(); - if (text != null && text.length() == 0) - { - text = null; - } - annotation.description = text; - if (addNew) - { - ap.av.getAlignment().addAnnotation(annotation); - ap.av.getAlignment().setAnnotationIndex(annotation, 0); - } - ap.refresh(true); + text = null; } + annotation.description = text; + if (addNew) + { + ap.av.getAlignment().addAnnotation(annotation); + ap.av.getAlignment().setAnnotationIndex(annotation, 0); + } + ap.refresh(true); }); } @@ -420,10 +425,162 @@ public class AnnotationLabels extends JPanel consclipbrd.addActionListener(this); pop.add(consclipbrd); } + + addColourOrFilterByOptions(ap, aa[selectedRow], pop); + + if (aa[selectedRow].graph == AlignmentAnnotation.CONTACT_MAP) + { + addContactMatrixOptions(ap, aa[selectedRow], pop); + // Set/adjust threshold for grouping ? + // colour alignment by this [type] + // select/hide columns by this row + + } } + pop.show(this, evt.getX(), evt.getY()); } + static void addColourOrFilterByOptions(final AlignmentPanel ap, + final AlignmentAnnotation alignmentAnnotation, + final JPopupMenu pop) + { + JMenuItem item; + item = new JMenuItem( + MessageManager.getString("label.colour_by_annotation")); + item.addActionListener(new ActionListener() + { + + @Override + public void actionPerformed(ActionEvent e) + { + AnnotationColourChooser.displayFor(ap.av, ap, alignmentAnnotation, + false); + }; + }); + pop.add(item); + if (alignmentAnnotation.sequenceRef != null) + { + item = new JMenuItem( + MessageManager.getString("label.colour_by_annotation") + " (" + + MessageManager.getString("label.per_seq") + ")"); + item.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + AnnotationColourChooser.displayFor(ap.av, ap, alignmentAnnotation, + true); + }; + }); + pop.add(item); + } + item = new JMenuItem( + MessageManager.getString("action.select_by_annotation")); + item.addActionListener(new ActionListener() + { + + @Override + public void actionPerformed(ActionEvent e) + { + AnnotationColumnChooser.displayFor(ap.av, ap, alignmentAnnotation); + }; + }); + pop.add(item); + } + + static void addContactMatrixOptions(final AlignmentPanel ap, + final AlignmentAnnotation alignmentAnnotation, + final JPopupMenu pop) + { + + final ContactMatrixI cm = ap.av.getContactMatrix(alignmentAnnotation); + JMenuItem item; + if (cm != null) + { + pop.addSeparator(); + + if (cm.hasGroups()) + { + JCheckBoxMenuItem chitem = new JCheckBoxMenuItem( + MessageManager.getString("action.show_groups_on_matrix")); + chitem.setToolTipText(MessageManager + .getString("action.show_groups_on_matrix_tooltip")); + boolean showGroups = alignmentAnnotation + .isShowGroupsForContactMatrix(); + final AlignmentAnnotation sel_row = alignmentAnnotation; + chitem.setState(showGroups); + chitem.addActionListener(new ActionListener() + { + + @Override + public void actionPerformed(ActionEvent e) + { + sel_row.setShowGroupsForContactMatrix(chitem.getState()); + // so any annotation colour changes are propagated - though they + // probably won't be unless the annotation row colours are removed + // too! + ap.alignmentChanged(); + } + }); + pop.add(chitem); + } + if (cm.hasTree()) + { + item = new JMenuItem( + MessageManager.getString("action.show_tree_for_matrix")); + item.setToolTipText(MessageManager + .getString("action.show_tree_for_matrix_tooltip")); + item.addActionListener(new ActionListener() + { + + @Override + public void actionPerformed(ActionEvent e) + { + + ap.alignFrame.showContactMapTree(alignmentAnnotation, cm); + + } + }); + pop.add(item); + } + else + { + item = new JMenuItem( + MessageManager.getString("action.cluster_matrix")); + item.setToolTipText( + MessageManager.getString("action.cluster_matrix_tooltip")); + item.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + new Thread(new Runnable() + { + @Override + public void run() + { + final long progBar; + ap.alignFrame.setProgressBar( + MessageManager.formatMessage( + "action.clustering_matrix_for", + cm.getAnnotDescr(), 5f), + progBar = System.currentTimeMillis()); + cm.setGroupSet(GroupSet.makeGroups(cm, true)); + cm.randomlyReColourGroups(); + cm.transferGroupColorsTo(alignmentAnnotation); + ap.alignmentChanged(); + ap.alignFrame.showContactMapTree(alignmentAnnotation, cm); + ap.alignFrame.setProgressBar(null, progBar); + } + }).start(); + } + }); + pop.add(item); + } + } + } + /** * A helper method that adds menu options for calculation and visualisation of * group and/or alignment consensus annotation to a popup menu. This is @@ -1012,7 +1169,6 @@ public class AnnotationLabels extends JPanel } drawComponent(g2, true, width); - } /** @@ -1042,31 +1198,146 @@ public class AnnotationLabels extends JPanel * @param width * Width for scaling labels */ - public void drawComponent(Graphics g, boolean clip, int width) + public void drawComponent(Graphics g, boolean clip, int givenWidth) { - if (av.getFont().getSize() < 10) + int width = givenWidth; + IdwidthAdjuster iwa = null; + if (ap != null) { - g.setFont(font); + iwa = ap.idwidthAdjuster; + if ((Cache.getDefault(ADJUST_ANNOTATION_LABELS_WIDTH_PREF, true) + || Jalview.isHeadlessMode())) + { + Graphics2D g2d = (Graphics2D) g; + Graphics dummy = g2d.create(); + int newAnnotationIdWidth = drawLabels(dummy, clip, width, false, + null); + dummy.dispose(); + Dimension d = ap.calculateDefaultAlignmentIdWidth(); + int alignmentIdWidth = d.width; + if (iwa != null && !iwa.manuallyAdjusted()) + { + // If no manual adjustment to ID column with has been made then adjust + // width match widest of alignment or annotation id widths + boolean allowShrink = Cache.getDefault("ALLOW_SHRINK_ID_WIDTH", + false); + width = Math.max(alignmentIdWidth, newAnnotationIdWidth); + if (clip && width < givenWidth && !allowShrink) + { + width = givenWidth; + } + } + else if (newAnnotationIdWidth != annotationIdWidth + && newAnnotationIdWidth > givenWidth + && newAnnotationIdWidth > alignmentIdWidth) + { + // otherwise if the annotation id width has become larger than the + // current id width, increase + width = newAnnotationIdWidth; + annotationIdWidth = newAnnotationIdWidth; + } + // set the width if it's changed + if (width != ap.av.getIdWidth()) + { + iwa.setWidth(width); + } + } } else { - g.setFont(av.getFont()); + int newAnnotationIdWidth = drawLabels(g, clip, width, false, null); + width = Math.max(newAnnotationIdWidth, givenWidth); + } + drawLabels(g, clip, width, true, null); + } + + /** + * Render the full set of annotation Labels for the alignment at the given + * cursor. If actuallyDraw is false or g is null then no actual drawing will + * occur, but the widest label width will be returned. If g is null then + * fmetrics must be supplied. + * + * Returns the width of the annotation labels. + * + * @param g + * Graphics2D instance (needed for font scaling) + * @param clip + * - true indicates that only current visible area needs to be + * rendered + * @param width + * Width for scaling labels + * @param fmetrics + * FontMetrics if Graphics object g is null + */ + public int drawLabels(Graphics g0, boolean clip, int width, + boolean actuallyDraw, FontMetrics fmetrics) + { + if (clip) + { + clip = Cache.getDefault("MOVE_SEQUENCE_ID_WITH_VISIBLE_ANNOTATIONS", + true); + } + Graphics g = null; + // create a dummy Graphics object if not drawing and one is supplied + if (g0 != null) + { + if (!actuallyDraw) + { + Graphics2D g2d = (Graphics2D) g0; + g = g2d.create(); + } + else + { + g = g0; + } + } + int actualWidth = 0; + if (g != null) + { + if (av.getFont().getSize() < 10) + { + g.setFont(font); + } + else + { + g.setFont(av.getFont()); + } } - FontMetrics fm = g.getFontMetrics(g.getFont()); - g.setColor(Color.white); - g.fillRect(0, 0, getWidth(), getHeight()); + FontMetrics fm = fmetrics == null ? g.getFontMetrics(g.getFont()) + : fmetrics; + if (actuallyDraw) + { + g.setColor(Color.white); + g.fillRect(0, 0, getWidth(), getHeight()); + + if (!Cache.getDefault(RESIZE_MARGINS_MARK_PREF, false) + && !av.getWrapAlignment()) + { + g.setColor(Color.LIGHT_GRAY); + g.drawLine(0, HEIGHT_ADJUSTER_HEIGHT / 4, HEIGHT_ADJUSTER_WIDTH / 4, + HEIGHT_ADJUSTER_HEIGHT / 4); + g.drawLine(0, 3 * HEIGHT_ADJUSTER_HEIGHT / 4, + HEIGHT_ADJUSTER_WIDTH / 4, 3 * HEIGHT_ADJUSTER_HEIGHT / 4); - g.translate(0, getScrollOffset()); - g.setColor(Color.black); + } + } + + if (actuallyDraw) + { + g.translate(0, getScrollOffset()); + g.setColor(Color.black); + } SequenceI lastSeqRef = null; + String lastLabel = null; AlignmentAnnotation[] aa = av.getAlignment().getAlignmentAnnotation(); - int fontHeight = g.getFont().getSize(); + int fontHeight = g != null ? g.getFont().getSize() + : fm.getFont().getSize(); int y = 0; int x = 0; int graphExtras = 0; int offset = 0; - Font baseFont = g.getFont(); + Font baseFont = g != null ? g.getFont() : fm.getFont(); FontMetrics baseMetrics = fm; int ofontH = fontHeight; int sOffset = 0; @@ -1084,6 +1355,7 @@ public class AnnotationLabels extends JPanel { hasHiddenRows = false; int olY = 0; + int nexAA = 0; for (int i = 0; i < aa.length; i++) { visible = true; @@ -1093,6 +1365,10 @@ public class AnnotationLabels extends JPanel continue; } olY = y; + // look ahead to next annotation + for (nexAA = i + 1; nexAA < aa.length + && !aa[nexAA].visible; nexAA++) + ; y += aa[i].height; if (clip) { @@ -1102,7 +1378,7 @@ public class AnnotationLabels extends JPanel { if (debugRedraw) { - System.out.println("before vis: " + i); + jalview.bin.Console.outPrintln("before vis: " + i); } before = true; } @@ -1116,7 +1392,7 @@ public class AnnotationLabels extends JPanel { if (debugRedraw) { - System.out.println( + jalview.bin.Console.outPrintln( "Scroll offset: " + sOffset + " after vis: " + i); } after = true; @@ -1125,8 +1401,10 @@ public class AnnotationLabels extends JPanel continue; } } - g.setColor(Color.black); - + if (actuallyDraw && g != null) + { + g.setColor(Color.black); + } offset = -aa[i].height / 2; if (aa[i].hasText) @@ -1140,6 +1418,24 @@ public class AnnotationLabels extends JPanel } String label = aa[i].label; boolean vertBar = false; + if ((lastLabel != null && lastLabel.equals(label))) + { + label = aa[i].description; + } + else + { + if (nexAA < aa.length && label.equals(aa[nexAA].label)) // && + // aa[nexY].sequenceRef==aa[i].sequenceRef) + { + lastLabel = label; + // next label is the same as this label + label = aa[i].description; + } + else + { + lastLabel = label; + } + } if (aa[i].sequenceRef != null) { if (aa[i].sequenceRef != lastSeqRef) @@ -1153,7 +1449,9 @@ public class AnnotationLabels extends JPanel vertBar = true; } } - x = width - fm.stringWidth(label) - 3; + + int labelWidth = fm.stringWidth(label) + 3; + x = width - labelWidth; if (aa[i].graphGroup > -1) { @@ -1186,10 +1484,15 @@ public class AnnotationLabels extends JPanel s = ((float) fontHeight) / (float) ofontH; Font f = baseFont .deriveFont(AffineTransform.getScaleInstance(s, s)); - g.setFont(f); - fm = g.getFontMetrics(); - graphExtras = (aa[i].height - (groupSize * (fontHeight + 8))) - / 2; + Canvas c = new Canvas(); + fm = c.getFontMetrics(f); + if (actuallyDraw && g != null) + { + g.setFont(f); + // fm = g.getFontMetrics(); + graphExtras = (aa[i].height + - (groupSize * (fontHeight + 8))) / 2; + } } } if (visible) @@ -1198,57 +1501,81 @@ public class AnnotationLabels extends JPanel { if (aa[gg].graphGroup == aa[i].graphGroup) { - x = width - fm.stringWidth(aa[gg].label) - 3; - g.drawString(aa[gg].label, x, y - graphExtras); - - if (aa[gg]._linecolour != null) + labelWidth = fm.stringWidth(aa[gg].label) + 3; + x = width - labelWidth; + if (actuallyDraw && g != null) { + g.drawString(aa[gg].label, x, y - graphExtras); - g.setColor(aa[gg]._linecolour); - g.drawLine(x, y - graphExtras + 3, - x + fm.stringWidth(aa[gg].label), - y - graphExtras + 3); - } + if (aa[gg]._linecolour != null) + { + + g.setColor(aa[gg]._linecolour); + g.drawLine(x, y - graphExtras + 3, + x + fm.stringWidth(aa[gg].label), + y - graphExtras + 3); + } - g.setColor(Color.black); + g.setColor(Color.black); + } graphExtras += fontHeight + 8; } } } - g.setFont(baseFont); + if (actuallyDraw && g != null) + { + g.setFont(baseFont); + } fm = baseMetrics; fontHeight = ofontH; } else { - if (vertBar) + if (actuallyDraw && g != null) { - g.drawLine(20, y + offset, 20, y - aa[i].height); - g.drawLine(20, y + offset, x - 20, y + offset); + if (vertBar) + { + g.drawLine(width - 3, y + offset - fontHeight, width - 3, + (int) (y - 1.5 * aa[i].height - offset - fontHeight)); + // g.drawLine(20, y + offset, x - 20, y + offset); + } + g.drawString(label, x, y + offset); } - g.drawString(label, x, y + offset); } lastSeqRef = aa[i].sequenceRef; + + if (labelWidth > actualWidth) + { + actualWidth = labelWidth; + } } } if (!resizePanel && dragEvent != null && aa != null) { - g.setColor(Color.lightGray); - g.drawString( - (aa[selectedRow].sequenceRef == null ? "" - : aa[selectedRow].sequenceRef.getName()) - + aa[selectedRow].label, - dragEvent.getX(), dragEvent.getY() - getScrollOffset()); + if (actuallyDraw && g != null) + { + g.setColor(Color.lightGray); + g.drawString( + (aa[selectedRow].sequenceRef == null ? "" + : aa[selectedRow].sequenceRef.getName()) + + aa[selectedRow].label, + dragEvent.getX(), dragEvent.getY() - getScrollOffset()); + } } if (!av.getWrapAlignment() && ((aa == null) || (aa.length < 1))) { - g.drawString(MessageManager.getString("label.right_click"), 2, 8); - g.drawString(MessageManager.getString("label.to_add_annotation"), 2, - 18); + if (actuallyDraw && g != null) + { + g.drawString(MessageManager.getString("label.right_click"), 2, 8); + g.drawString(MessageManager.getString("label.to_add_annotation"), 2, + 18); + } } + + return actualWidth; } public int getScrollOffset()