From b0842a6ddaef0ceb4de3e1534c3772515d4b103d Mon Sep 17 00:00:00 2001 From: gmungoc Date: Fri, 25 Sep 2015 11:46:11 +0100 Subject: [PATCH] JAL-1815 restore split frame geometry correctly including position --- src/jalview/gui/Desktop.java | 12 +++-- src/jalview/gui/Jalview2XML.java | 26 +++++++++-- src/jalview/gui/SplitFrame.java | 24 +++++++++- src/jalview/jbgui/GSplitFrame.java | 89 ++++++++++++++++++++++++++++++------ 4 files changed, 125 insertions(+), 26 deletions(-) diff --git a/src/jalview/gui/Desktop.java b/src/jalview/gui/Desktop.java index 270805a..d03e3f2 100644 --- a/src/jalview/gui/Desktop.java +++ b/src/jalview/gui/Desktop.java @@ -2933,7 +2933,11 @@ public class Desktop extends jalview.jbgui.GDesktop implements } /** - * Explode the views in the given frame into separate AlignFrame windows. + * Explode the views in the given SplitFrame into separate SplitFrame windows. + * This respects (remembers) any previous 'exploded geometry' i.e. the size + * and location last time the view was expanded (if any). However it does not + * remember the split pane divider location - this is set to match the + * 'exploding' frame. * * @param sf */ @@ -2965,13 +2969,11 @@ public class Desktop extends jalview.jbgui.GDesktop implements */ AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i); AlignFrame newTopFrame = new AlignFrame(topPanel); - newTopFrame.setSize(new Dimension(AlignFrame.DEFAULT_WIDTH, - AlignFrame.DEFAULT_HEIGHT)); + newTopFrame.setSize(oldTopFrame.getSize()); newTopFrame.setVisible(true); AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i); AlignFrame newBottomFrame = new AlignFrame(bottomPanel); - newBottomFrame.setSize(new Dimension(AlignFrame.DEFAULT_WIDTH, - AlignFrame.DEFAULT_HEIGHT)); + newBottomFrame.setSize(oldBottomFrame.getSize()); newBottomFrame.setVisible(true); topPanel.av.setGatherViewsHere(false); bottomPanel.av.setGatherViewsHere(false); diff --git a/src/jalview/gui/Jalview2XML.java b/src/jalview/gui/Jalview2XML.java index a448d19..50a8167 100644 --- a/src/jalview/gui/Jalview2XML.java +++ b/src/jalview/gui/Jalview2XML.java @@ -1092,15 +1092,26 @@ public class Jalview2XML view.setViewName(av.viewName); view.setGatheredViews(av.isGatherViewsHere()); - Rectangle position = ap.av.getExplodedGeometry(); - if (position == null) + Rectangle size = ap.av.getExplodedGeometry(); + Rectangle position = size; + if (size == null) { - position = ap.alignFrame.getBounds(); + size = ap.alignFrame.getBounds(); + if (av.getCodingComplement() != null) + { + position = ((SplitFrame) ap.alignFrame.getSplitViewContainer()) + .getBounds(); + } + else + { + position = size; + } } view.setXpos(position.x); view.setYpos(position.y); - view.setWidth(position.width); - view.setHeight(position.height); + + view.setWidth(size.width); + view.setHeight(size.height); view.setStartRes(av.startRes); view.setStartSeq(av.startSeq); @@ -2453,6 +2464,11 @@ public class Jalview2XML int width = (int) dnaFrame.getBounds().getWidth(); int height = (int) (dnaFrame.getBounds().getHeight() + proteinFrame.getBounds().getHeight() + 50); + + /* + * SplitFrame location is saved to both enclosed frames + */ + splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY()); Desktop.addInternalFrame(splitFrame, title, width, height); /* diff --git a/src/jalview/gui/SplitFrame.java b/src/jalview/gui/SplitFrame.java index b790d62..9da8240 100644 --- a/src/jalview/gui/SplitFrame.java +++ b/src/jalview/gui/SplitFrame.java @@ -85,8 +85,7 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI // about 50 pixels for the SplitFrame's title bar etc int height = ((AlignFrame) getTopFrame()).getHeight() + ((AlignFrame) getBottomFrame()).getHeight() + 50; - // about 65 pixels for Desktop decorators on Windows - height = Math.min(height, Desktop.instance.getHeight() - 65); + height = fitHeightToDesktop(height); setSize(width, height); adjustLayout(); @@ -101,6 +100,27 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI } /** + * Reduce the height if too large to fit in the Desktop. Also adjust the + * divider location in proportion. + * + * @param height + * in pixels + * @return original or reduced height + */ + public int fitHeightToDesktop(int height) + { + // allow about 65 pixels for Desktop decorators on Windows + + int newHeight = Math.min(height, Desktop.instance.getHeight() - 65); + if (newHeight != height) + { + int oldDividerLocation = getDividerLocation(); + setDividerLocation(oldDividerLocation * newHeight / height); + } + return newHeight; + } + + /** * Set the top and bottom frames to listen to each others Commands (e.g. Edit, * Order). */ diff --git a/src/jalview/jbgui/GSplitFrame.java b/src/jalview/jbgui/GSplitFrame.java index 5661ab0..daad4fd 100644 --- a/src/jalview/jbgui/GSplitFrame.java +++ b/src/jalview/jbgui/GSplitFrame.java @@ -33,6 +33,8 @@ import javax.swing.plaf.basic.BasicInternalFrameUI; public class GSplitFrame extends JInternalFrame { + private static final int DIVIDER_SIZE = 5; + private static final long serialVersionUID = 1L; private GAlignFrame topFrame; @@ -41,6 +43,12 @@ public class GSplitFrame extends JInternalFrame private JSplitPane splitPane; + /* + * proportional position of split divider; saving this allows it to be + * restored after hiding one half and resizing + */ + private double dividerRatio; + /** * Constructor * @@ -65,12 +73,23 @@ public class GSplitFrame extends JInternalFrame splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, topFrame, bottomFrame); splitPane.setVisible(true); - final double ratio = bottomFrame.getHeight() == 0 ? 0.5d : topFrame - .getHeight() - / (double) (topFrame.getHeight() + bottomFrame.getHeight()); - splitPane.setDividerLocation(ratio); - splitPane.setResizeWeight(ratio); - splitPane.setDividerSize(5); + + /* + * set divider split at 50:50, or restore saved split if loading from + * project + */ + int topFrameHeight = topFrame.getHeight(); + splitPane.setDividerSize(DIVIDER_SIZE); + if (topFrameHeight == 0) + { + setRelativeDividerLocation(0.5d); // as a proportion + } + else + { + int dividerPosition = topFrameHeight + DIVIDER_SIZE / 2; + splitPane.setDividerLocation(dividerPosition); // absolute position + } + splitPane.setResizeWeight(0.5d); add(splitPane); } @@ -139,11 +158,25 @@ public class GSplitFrame extends JInternalFrame } /** - * Make the complement of the specified split component visible or hidden, - * adjusting the position of the split divide. + * Makes the complement of the specified split component visible or hidden, + * restoring or saving the position of the split divide. */ public void setComplementVisible(Object alignFrame, boolean show) { + /* + * save divider ratio on hide, restore on show + */ + if (show) + { + setRelativeDividerLocation(dividerRatio); + } + else + { + this.dividerRatio = splitPane.getDividerLocation() + / (double) (splitPane.getHeight() - splitPane + .getDividerSize()); + } + if (alignFrame == this.topFrame) { this.bottomFrame.setVisible(show); @@ -152,12 +185,40 @@ public class GSplitFrame extends JInternalFrame { this.topFrame.setVisible(show); } - if (show) - { - // SplitPane needs nudging to restore 50-50 split - // TODO save/restore other ratios - splitPane.setDividerLocation(0.5d); - } + validate(); } + + /** + * Set the divider location as a proportion (0 <= r <= 1) of the height
+ * Warning: this overloads setDividerLocation(int), and getDividerLocation() + * returns the int (pixel count) value + * + * @param r + */ + public void setRelativeDividerLocation(double r) + { + this.dividerRatio = r; + splitPane.setDividerLocation(r); + } + + /** + * Sets the divider location (in pixels from top) + * + * @return + */ + protected void setDividerLocation(int p) + { + splitPane.setDividerLocation(p); + } + + /** + * Returns the divider location (in pixels from top) + * + * @return + */ + protected int getDividerLocation() + { + return splitPane.getDividerLocation(); + } } -- 1.7.10.2