From 90492c27b61698f28d45b120209d12520770908c Mon Sep 17 00:00:00 2001 From: Serge Rider Date: Thu, 21 Jun 2018 14:11:57 +0300 Subject: [PATCH] SQL editor extra presentation UI --- .../dbeaver/ui/editors/sql/SQLEditor.java | 13 +- .../src/org/jkiss/dbeaver/ui/UIUtils.java | 2 +- .../dbeaver/ui/controls/CustomSashForm.java | 2017 +++++++++-------- 3 files changed, 1027 insertions(+), 1005 deletions(-) diff --git a/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditor.java b/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditor.java index f3d4fb4567..4fdf2192c2 100644 --- a/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditor.java +++ b/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/ui/editors/sql/SQLEditor.java @@ -91,6 +91,7 @@ import org.jkiss.dbeaver.tools.transfer.database.DatabaseTransferProducer; import org.jkiss.dbeaver.tools.transfer.wizard.DataTransferWizard; import org.jkiss.dbeaver.ui.*; import org.jkiss.dbeaver.ui.actions.datasource.DataSourceHandler; +import org.jkiss.dbeaver.ui.controls.CustomSashForm; import org.jkiss.dbeaver.ui.controls.resultset.*; import org.jkiss.dbeaver.ui.dialogs.ActiveWizardDialog; import org.jkiss.dbeaver.ui.dialogs.ConfirmationDialog; @@ -149,9 +150,9 @@ public class SQLEditor extends SQLEditorBase implements public static final String DEFAULT_TITLE_PATTERN = "<${" + VAR_CONNECTION_NAME + "}> ${" + VAR_FILE_NAME + "}"; private ResultSetOrientation resultSetOrientation = ResultSetOrientation.HORIZONTAL; - private SashForm resultsSash; + private CustomSashForm resultsSash; @Nullable - private SashForm presentationSash; + private CustomSashForm presentationSash; private Control editorControl; private CTabFolder resultTabs; @@ -488,6 +489,7 @@ public class SQLEditor extends SQLEditorBase implements parent, resultSetOrientation.getSashOrientation() | SWT.SMOOTH); resultsSash.setSashWidth(5); + UIUtils.setHelp(resultsSash, IHelpContextIds.CTX_SQL_EDITOR); SashForm editorSash = resultsSash; @@ -517,6 +519,13 @@ public class SQLEditor extends SQLEditorBase implements setAction(ITextEditorActionConstants.SHOW_INFORMATION, null); //toolTipAction.setEnabled(false); +/* + resultsSash.setSashBorders(new boolean[]{true, true}); + if (presentationSash != null) { + presentationSash.setSashBorders(new boolean[]{true, true}); + } +*/ + CoreFeatures.SQL_EDITOR_OPEN.use(); // Start output reader diff --git a/plugins/org.jkiss.dbeaver.ui/src/org/jkiss/dbeaver/ui/UIUtils.java b/plugins/org.jkiss.dbeaver.ui/src/org/jkiss/dbeaver/ui/UIUtils.java index 8f47c947bc..cc6822f54f 100644 --- a/plugins/org.jkiss.dbeaver.ui/src/org/jkiss/dbeaver/ui/UIUtils.java +++ b/plugins/org.jkiss.dbeaver.ui/src/org/jkiss/dbeaver/ui/UIUtils.java @@ -832,7 +832,7 @@ public class UIUtils { } @NotNull - public static SashForm createPartDivider(final IWorkbenchPart workbenchPart, Composite parent, int style) + public static CustomSashForm createPartDivider(final IWorkbenchPart workbenchPart, Composite parent, int style) { final CustomSashForm sash = new CustomSashForm(parent, style); diff --git a/plugins/org.jkiss.dbeaver.ui/src/org/jkiss/dbeaver/ui/controls/CustomSashForm.java b/plugins/org.jkiss.dbeaver.ui/src/org/jkiss/dbeaver/ui/controls/CustomSashForm.java index 1a6a12e331..be93e2e7d6 100644 --- a/plugins/org.jkiss.dbeaver.ui/src/org/jkiss/dbeaver/ui/controls/CustomSashForm.java +++ b/plugins/org.jkiss.dbeaver.ui/src/org/jkiss/dbeaver/ui/controls/CustomSashForm.java @@ -4,7 +4,7 @@ * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * + * * Contributors: * IBM Corporation - initial API and implementation * Sybase, Inc. - extended for DTP @@ -46,1016 +46,1029 @@ import java.util.List; /** * A SashForm that allows hide/restore controls on sash. - * + *

* It only works with one sash (two children). It doesn't make sense * for the arrows when there is more than one sash. Things get confusing for * a restore position. - * */ public class CustomSashForm extends SashForm { - /** - * Custom style bits. They set whether hide to one side of the other - * is not permitted. For example, if NO_HIDE_UP, then there will be only - * one arrow. When not hidden, it will point down (and will do a hide down), - * and when hidden down, it will point up (and will do a restore to the - * previous weight). There won't be a hide to the top arrow. - */ - public static final int - NO_HIDE_LEFT = 0x1, // Custom style bit for not allow hide left - NO_HIDE_UP = NO_HIDE_LEFT, // Custom style bit for not allow hide up - NO_HIDE_RIGHT = 0x2, // Custom style bit for not allow hide right - NO_HIDE_DOWN = NO_HIDE_RIGHT; // Custom style bit for not allow hide down - - - private static final int NO_WEIGHT = -1; - private static final int NO_ARROW = -1; - private class SashInfo { - public Sash sash; - public boolean enabled; // Whether this sashinfo is enabled (i.e. if there is more than one, this will be disabled). - public int restoreWeight = NO_WEIGHT; // If slammed to an edge this is the restore weight. -1 means not slammed. This is the restoreWeight in the 2nd section form, i.e. weights[1]. - public int cursorOver = NO_ARROW; // Which arrow is cursor over, - public boolean sashBorderLeft; // Draw sash border left/top - public boolean sashBorderRight; // Draw sash border right/bottom - public int[][] sashLocs; // There is one entry for each arrow, It is arrowType/arrowDrawn/x/y/height/width of the arrow area. - // There may not be a second entry, in which case we have only one arrow. - public Point[] savedSizes = new Point[2]; // Saved sizes of controls - saved whenever a control is hidden or restored - public SashInfo(Sash sash) { - this.sash = sash; - } - }; - - public interface ICustomSashFormListener{ - void dividerMoved(int firstControlWeight, int secondControlWeight); - } - - protected SashInfo currentSashInfo = null; // When the sash goes away, its entry is made null. - protected boolean inMouseClick = false; // Because we can't stop drag even when we are in the arrow area, we need - // to know that mouse down is in process so that when drag is completed, we - // know not to recompute our position because a mouse up is about to happen - // and we want the correct arrow handled correctly. - - protected boolean sashBorders[]; // Whether corresponding control needs a sash border - - protected boolean noHideUp, noHideDown; - protected List customSashFormListeners = null; - - protected static final int - UP_RESTORE_ARROW = 0, - UP_HIDE_ARROW = 1, - DOWN_RESTORE_ARROW = 2, - DOWN_HIDE_ARROW = 3, - - HIDE_ARROWS = 4; - - protected static final int - ARROW_TYPE_INDEX = 0, - ARROW_DRAWN_INDEX = 1, - X_INDEX = 2, - Y_INDEX = 3, - WIDTH_INDEX = 4, - HEIGHT_INDEX = 5; - - // These are for the up/down arrow. Just swap them for left/right arrow. - protected static final int - ARROW_WIDTH = 8, - ARROW_HEIGHT = 8, - ARROW_MARGIN = 3; // Margin on each side of arrow - - protected Color arrowColor, borderColor; - - - public CustomSashForm(Composite parent, int style) { - this(parent, style, SWT.NONE); - } - - /** - * Constructor taking a custom style too. - * Or in the Custom style bits defined above (e.g. NO_HIDE_RIGHT,...) - */ - public CustomSashForm(Composite parent, int style, int customStyle) { - super(parent, style); + /** + * Custom style bits. They set whether hide to one side of the other + * is not permitted. For example, if NO_HIDE_UP, then there will be only + * one arrow. When not hidden, it will point down (and will do a hide down), + * and when hidden down, it will point up (and will do a restore to the + * previous weight). There won't be a hide to the top arrow. + */ + public static final int + NO_HIDE_LEFT = 0x1, // Custom style bit for not allow hide left + NO_HIDE_UP = NO_HIDE_LEFT, // Custom style bit for not allow hide up + NO_HIDE_RIGHT = 0x2, // Custom style bit for not allow hide right + NO_HIDE_DOWN = NO_HIDE_RIGHT; // Custom style bit for not allow hide down + + + private static final int NO_WEIGHT = -1; + private static final int NO_ARROW = -1; + + private class SashInfo { + public Sash sash; + public boolean enabled; // Whether this sashinfo is enabled (i.e. if there is more than one, this will be disabled). + public int restoreWeight = NO_WEIGHT; // If slammed to an edge this is the restore weight. -1 means not slammed. This is the restoreWeight in the 2nd section form, i.e. weights[1]. + public int cursorOver = NO_ARROW; // Which arrow is cursor over, + public boolean sashBorderLeft; // Draw sash border left/top + public boolean sashBorderRight; // Draw sash border right/bottom + public int[][] sashLocs; // There is one entry for each arrow, It is arrowType/arrowDrawn/x/y/height/width of the arrow area. + // There may not be a second entry, in which case we have only one arrow. + public Point[] savedSizes = new Point[2]; // Saved sizes of controls - saved whenever a control is hidden or restored + + public SashInfo(Sash sash) { + this.sash = sash; + } + } + + ; + + public interface ICustomSashFormListener { + void dividerMoved(int firstControlWeight, int secondControlWeight); + } + + protected SashInfo currentSashInfo = null; // When the sash goes away, its entry is made null. + protected boolean inMouseClick = false; // Because we can't stop drag even when we are in the arrow area, we need + // to know that mouse down is in process so that when drag is completed, we + // know not to recompute our position because a mouse up is about to happen + // and we want the correct arrow handled correctly. + + protected boolean sashBorders[]; // Whether corresponding control needs a sash border + + protected boolean noHideUp, noHideDown; + protected List customSashFormListeners = null; + + protected static final int + UP_RESTORE_ARROW = 0, + UP_HIDE_ARROW = 1, + DOWN_RESTORE_ARROW = 2, + DOWN_HIDE_ARROW = 3, + + HIDE_ARROWS = 4; + + protected static final int + ARROW_TYPE_INDEX = 0, + ARROW_DRAWN_INDEX = 1, + X_INDEX = 2, + Y_INDEX = 3, + WIDTH_INDEX = 4, + HEIGHT_INDEX = 5; + + // These are for the up/down arrow. Just swap them for left/right arrow. + protected static final int + ARROW_WIDTH = 8, + ARROW_HEIGHT = 8, + ARROW_MARGIN = 3; // Margin on each side of arrow + + protected Color arrowColor, borderColor; + + + public CustomSashForm(Composite parent, int style) { + this(parent, style, SWT.NONE); + } + + /** + * Constructor taking a custom style too. + * Or in the Custom style bits defined above (e.g. NO_HIDE_RIGHT,...) + */ + public CustomSashForm(Composite parent, int style, int customStyle) { + super(parent, style); // FIXME: Do we need extra re-layout? - // Need listener to force a layout - this.addListener(SWT.Resize, new Listener() { - public void handleEvent(Event e) { - layout(true); - } - }); - - noHideUp = ((customStyle & NO_HIDE_UP) != 0); - noHideDown = ((customStyle & NO_HIDE_DOWN) != 0); - - if (noHideUp & noHideDown) - return; // If you can't hide up or down, there there is no need for arrows. - - SASH_WIDTH = 3 + getOrientation() == SWT.VERTICAL ? ARROW_HEIGHT : ARROW_WIDTH; - - arrowColor = new Color(parent.getDisplay(), 99, 101, 156); - borderColor = new Color(parent.getDisplay(), 132, 130, 132); - - addDisposeListener(new DisposeListener() { - /** - * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(DisposeEvent) - */ - public void widgetDisposed(DisposeEvent e) { - arrowColor.dispose(); - borderColor.dispose(); - arrowColor = borderColor = null; - } - - }); - } - - /** - * Returns the noHideUp setting for vertical CustomSashForm. - */ - public boolean isNoHideUp(){ - return noHideUp; - } - - /** - * Returns the noHideDown setting for vertical CustomSashForm. - */ - public boolean isNoHideDown(){ - return noHideDown; - } - - /** - * Returns the noHideLeft setting for horizontal CustomSashForm. - */ - public boolean isNoHideLeft(){ - return noHideUp; - } - - /** - * Returns the noHideRight setting for horizontal CustomSashForm. - */ - public boolean isNoHideRight(){ - return noHideDown; - } - - /** - * Sets the noHideUp setting for vertical CustomSashForm. - */ - public void setNoHideUp(boolean bHide) { - noHideUp = bHide; - } - - /** - * Sets the noHideDown setting for vertical CustomSashForm. - */ - public void setNoHideDown(boolean bHide) { - noHideDown = bHide; - } - - /** - * Sets the noHideLeft setting for horizontal CustomSashForm. - */ - public void setNoHideLeft(boolean bHide) { - setNoHideUp(bHide); - } - - /** - * Sets the noHideRight setting for horizontal CustomSashForm. - */ - public void setNoHideRight(boolean bHide) { - setNoHideDown(bHide); - } - - /** - * Call to set to hide up - */ - public void hideUp() { - if (noHideUp) - return; - - if (currentSashInfo == null) - currentSashInfo = new SashInfo(null); - upHideClicked(currentSashInfo); - } - - /** - * Call to set to hide left - */ - public void hideLeft() { - hideUp(); - } - - - /** - * Call to set to hide down - */ - public void hideDown() { - if (noHideDown) - return; - - if (currentSashInfo == null) - currentSashInfo = new SashInfo(null); - - downHideClicked(currentSashInfo); - } - - /** - * Call to set to hide right - */ - public void hideRight() { - hideDown(); - } - - /** - * Set the need sash borders for the controls. - */ - public void setSashBorders(boolean[] sashBorders) { - int[] weights = getWeights(); // KLUDGE This is a kludge just to see how many controls we have. - if (weights.length != 2 || (sashBorders != null && sashBorders.length != 2)) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - this.sashBorders = sashBorders; - } - - /** - * @see org.eclipse.swt.widgets.Composite#layout(boolean) - */ - public void layout(boolean changed) { - super.layout(changed); - - if (noHideUp && noHideDown) - return; // No arrows to handle in this case. - - if (getMaximizedControl() != null) - return; // We have a maximized control, so we don't need to worry about the sash. - - // Let's get the list of all sashes the sash form now has. If there is more than one then just disable the sashinfo. - // If there is no current sash, and there is only one sash, then create the sashinfo for it. - Control[] children = getChildren(); - Sash newSash = null; - for (int i = 0; i < children.length; i++) { - if (children[i] instanceof Sash) - if (newSash == null) - newSash = (Sash) children[i]; - else { - // We have more than one sash, so need to disable current sash, if we have one. - if (currentSashInfo != null) - currentSashInfo.enabled = false; - return; // Don't go on. - } - } - - if (newSash == null) - return; // We have no sashes at all. - - // Now we need to see if this is a new sash. - if (currentSashInfo == null || currentSashInfo.sash == null) { - if (currentSashInfo == null) - currentSashInfo = new SashInfo(newSash); - else - currentSashInfo.sash = newSash; - newSash.addPaintListener(new PaintListener() { - /** - * @see org.eclipse.swt.events.PaintListener#paintControl(PaintEvent) - */ - public void paintControl(PaintEvent e) { - // Need to find the index of the sash we're interested in. - - GC gc = e.gc; - Color oldFg = gc.getForeground(); - Color oldBg = gc.getBackground(); - - drawArrow(gc, currentSashInfo.sashLocs[0], currentSashInfo.cursorOver == 0); // Draw first arrow - if (currentSashInfo.sashLocs.length > 1) - drawArrow(gc, currentSashInfo.sashLocs[1], currentSashInfo.cursorOver == 1); // Draw second arrow - - if (currentSashInfo.sashBorderLeft) - drawSashBorder(gc, currentSashInfo.sash, true); - if (currentSashInfo.sashBorderRight) - drawSashBorder(gc, currentSashInfo.sash, false); - - gc.setForeground(oldFg); - gc.setBackground(oldBg); - } - - }); - - newSash.addControlListener(new ControlListener() { - /** - * @see org.eclipse.swt.events.ControlAdapter#controlMoved(ControlEvent) - */ - public void controlMoved(ControlEvent e) { - //System.out.println("controlMoved"); - recomputeSashInfo(); - } - - /** - * @see org.eclipse.swt.events.ControlAdapter#controlResized(ControlEvent) - */ - public void controlResized(ControlEvent e) { - recomputeSashInfo(); - } - - - }); - - newSash.addDisposeListener(new DisposeListener() { - /** - * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(DisposeEvent) - */ - public void widgetDisposed(DisposeEvent e) { - // Need to clear out the widget from current. - currentSashInfo= null; - } - }); - - // This is a kludge because we can't override the set cursor hit test. - newSash.addMouseMoveListener(new MouseMoveListener() { - /** - * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(MouseEvent) - */ - public void mouseMove(MouseEvent e) { - // See if within one of the arrows. - int x = e.x; - int y = e.y; - for (int i=0; i= clientArea.height-DRAG_MINIMUM){ - slammed = SLAMMED_TO_BOTTOM; - } - } - else { - if (currentSashInfo.restoreWeight != NO_WEIGHT && sashBounds.x <= DRAG_MINIMUM){ - slammed = SLAMMED_TO_TOP; - } - else if (currentSashInfo.restoreWeight != NO_WEIGHT && sashBounds.x+sashBounds.width >= clientArea.width-DRAG_MINIMUM){ - slammed = SLAMMED_TO_BOTTOM; - } - } - - // - // Now decide which arrows to add, according to whether noHideUp, noHideDown and the slammed status. - // - if (noHideUp) { - if (slammed == SLAMMED_TO_BOTTOM) { - addArrows = new int[1]; - drawArrows = new int[1]; - - addArrows[0] = UP_RESTORE_ARROW; - drawArrows[0] = UP_RESTORE_ARROW; - currentSashInfo.sashBorderLeft = sashBorders != null && sashBorders[0]; - currentSashInfo.sashBorderRight = false; - } else { - //Not slammed - addArrows = new int[1]; - drawArrows = new int[1]; - - addArrows[0] = DOWN_HIDE_ARROW; - drawArrows[0] = DOWN_RESTORE_ARROW; - currentSashInfo.restoreWeight = NO_WEIGHT; // Since we are in the middle, there is no restoreWeight. We've could of been dragged here. - currentSashInfo.sashBorderLeft = sashBorders != null && sashBorders[0]; - currentSashInfo.sashBorderRight = sashBorders != null && sashBorders[1]; - } - } else if (noHideDown) { - if (slammed == SLAMMED_TO_TOP) { - addArrows = new int[1]; - drawArrows = new int[1]; - - addArrows[0] = DOWN_RESTORE_ARROW; - drawArrows[0] = DOWN_RESTORE_ARROW; - currentSashInfo.sashBorderLeft = false; - currentSashInfo.sashBorderRight = sashBorders != null && sashBorders[1]; - } else { - //Not slammed - addArrows = new int[1]; - drawArrows = new int[1]; - - addArrows[0] = UP_HIDE_ARROW; - drawArrows[0] = UP_RESTORE_ARROW; - currentSashInfo.restoreWeight = NO_WEIGHT; // Since we are in the middle, there is no restoreWeight. We've could of been dragged here. - currentSashInfo.sashBorderLeft = sashBorders != null && sashBorders[0]; - currentSashInfo.sashBorderRight = sashBorders != null && sashBorders[1]; - } - } else { - if (slammed == SLAMMED_TO_TOP) { - addArrows = new int[1]; - drawArrows = new int[1]; - - addArrows[0] = DOWN_RESTORE_ARROW; - drawArrows[0] = DOWN_RESTORE_ARROW; - currentSashInfo.sashBorderLeft = false; - currentSashInfo.sashBorderRight = sashBorders != null && sashBorders[1]; - } else if (slammed == SLAMMED_TO_BOTTOM) { - addArrows = new int[1]; - drawArrows = new int[1]; - - addArrows[0] = UP_RESTORE_ARROW; - drawArrows[0] = UP_RESTORE_ARROW; - currentSashInfo.sashBorderLeft = sashBorders != null && sashBorders[0]; - currentSashInfo.sashBorderRight = false; - } else { - //Not slammed - addArrows = new int[2]; - drawArrows = new int[2]; - - addArrows[0] = UP_HIDE_ARROW; - drawArrows[0] = UP_RESTORE_ARROW; - addArrows[1] = DOWN_HIDE_ARROW; - drawArrows[1] = DOWN_RESTORE_ARROW; - currentSashInfo.restoreWeight = NO_WEIGHT; // Since we are in the middle, there is no restoreWeight. We've could of been dragged here. - currentSashInfo.sashBorderLeft = sashBorders != null && sashBorders[0]; - currentSashInfo.sashBorderRight = sashBorders != null && sashBorders[1]; - } - } - getNewSashArray(currentSashInfo, addArrows, drawArrows); - - currentSashInfo.sash.redraw(); // Need to schedule a redraw because it has already drawn the old ones during the set bounds in super layout. - } - - protected void upRestoreClicked(SashInfo sashinfo) { - // This means restore just the sash below restoreWeight and reduce the above restoreWeight by the right amount. - int[] weights = getWeights(); - - weights[0] = 1000-sashinfo.restoreWeight; // Assume weights are always in units of 1000. - weights[1] = sashinfo.restoreWeight; - sashinfo.restoreWeight = NO_WEIGHT; - - try { - setWeights(weights); - } catch (SWTError e) { - // Sometimes it happens if sash controls aren't yet created - // Just ignore - } - fireDividerMoved(); - } - - protected void upHideClicked(SashInfo sashinfo) { - int[] weights = getWeights(); - if (weights.length != 2) { - return; - } - - // Up hide, so save the current restoreWeight of 1 into the sash info, and move to the top. - if (currentSashInfo.restoreWeight == NO_WEIGHT){ - currentSashInfo.restoreWeight = weights[1]; // Not currently maxed, save position. - - saveChildControlSizes(); - } - weights[0] = 0; - weights[1] = 1000; - - // If the upper panel has focus, flip focus to the lower panel because the upper panel is now hidden. - Control[] children = getChildren(); - boolean upperFocus = isFocusAncestorA(children[0]); - try { - setWeights(weights); - } catch (SWTError e) { - - } - setWeights(weights); - if (upperFocus) - children[1].setFocus(); - fireDividerMoved(); - } - - protected void downRestoreClicked(SashInfo sashinfo) { - // This means restore just the sash below restoreWeight and increase the above restoreWeight by that amount. - int[] weights = getWeights(); - - weights[0] = 1000-sashinfo.restoreWeight; // Assume weights are always in units of 1000. - weights[1] = sashinfo.restoreWeight; - sashinfo.restoreWeight = NO_WEIGHT; - - setWeights(weights); - fireDividerMoved(); - } - - protected void downHideClicked(SashInfo sashinfo) { - int[] weights = getWeights(); - - // Down hide, so save the current restoreWeight of 1 into the sash info, and move to the bottom. - if (currentSashInfo.restoreWeight == NO_WEIGHT) { - currentSashInfo.restoreWeight = weights[1]; // Not currently maxed, save current restoreWeight. - saveChildControlSizes(); - } - weights[0] = 1000; - weights[1] = 0; - - // If the lower panel has focus, flip focus to the upper panel because the lower panel is now hidden. - Control[] children = getChildren(); - boolean lowerFocus = isFocusAncestorA(children[1]); - setWeights(weights); - if (lowerFocus) - children[0].setFocus(); - fireDividerMoved(); - } - - /* - * Helper method for upHideClicked / downHideClicked - */ - private void saveChildControlSizes() { - // Save control sizes - Control [] children = getChildren(); - int iChildToSave = 0; - for (int i = 0; i < children.length && iChildToSave < 2; i++){ - Control child = children[i]; - if (! (child instanceof Sash)){ - currentSashInfo.savedSizes[iChildToSave] = child.getSize(); - iChildToSave++; - } - } - } - - /* - * This determines if the control or one of its children - * has the focus. Control.isFocusAncestor is hidden by SWT, but it is really useful. - */ - protected boolean isFocusAncestorA (Control control) { - Display display = getDisplay (); - Control focusControl = display.getFocusControl (); - while (focusControl != null && focusControl != control) { - focusControl = focusControl. getParent(); - } - return control == focusControl; - } - - protected void getNewSashArray(SashInfo sashInfo, int[] addArrowTypes, int[] drawArrowTypes) { + // Need listener to force a layout + this.addListener(SWT.Resize, new Listener() { + public void handleEvent(Event e) { + layout(true); + } + }); + + noHideUp = ((customStyle & NO_HIDE_UP) != 0); + noHideDown = ((customStyle & NO_HIDE_DOWN) != 0); + + if (noHideUp & noHideDown) + return; // If you can't hide up or down, there there is no need for arrows. + + SASH_WIDTH = 3 + getOrientation() == SWT.VERTICAL ? ARROW_HEIGHT : ARROW_WIDTH; + + arrowColor = new Color(parent.getDisplay(), 99, 101, 156); + borderColor = new Color(parent.getDisplay(), 132, 130, 132); + + addDisposeListener(new DisposeListener() { + /** + * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(DisposeEvent) + */ + public void widgetDisposed(DisposeEvent e) { + arrowColor.dispose(); + borderColor.dispose(); + arrowColor = borderColor = null; + } + + }); + } + + /** + * Returns the noHideUp setting for vertical CustomSashForm. + */ + public boolean isNoHideUp() { + return noHideUp; + } + + /** + * Returns the noHideDown setting for vertical CustomSashForm. + */ + public boolean isNoHideDown() { + return noHideDown; + } + + /** + * Returns the noHideLeft setting for horizontal CustomSashForm. + */ + public boolean isNoHideLeft() { + return noHideUp; + } + + /** + * Returns the noHideRight setting for horizontal CustomSashForm. + */ + public boolean isNoHideRight() { + return noHideDown; + } + + /** + * Sets the noHideUp setting for vertical CustomSashForm. + */ + public void setNoHideUp(boolean bHide) { + noHideUp = bHide; + } + + /** + * Sets the noHideDown setting for vertical CustomSashForm. + */ + public void setNoHideDown(boolean bHide) { + noHideDown = bHide; + } + + /** + * Sets the noHideLeft setting for horizontal CustomSashForm. + */ + public void setNoHideLeft(boolean bHide) { + setNoHideUp(bHide); + } + + /** + * Sets the noHideRight setting for horizontal CustomSashForm. + */ + public void setNoHideRight(boolean bHide) { + setNoHideDown(bHide); + } + + /** + * Call to set to hide up + */ + public void hideUp() { + if (noHideUp) + return; + + if (currentSashInfo == null) + currentSashInfo = new SashInfo(null); + upHideClicked(currentSashInfo); + } + + /** + * Call to set to hide left + */ + public void hideLeft() { + hideUp(); + } + + + /** + * Call to set to hide down + */ + public void hideDown() { + if (noHideDown) + return; + + if (currentSashInfo == null) + currentSashInfo = new SashInfo(null); + + downHideClicked(currentSashInfo); + } + + /** + * Call to set to hide right + */ + public void hideRight() { + hideDown(); + } + + /** + * Set the need sash borders for the controls. + */ + public void setSashBorders(boolean[] sashBorders) { + int[] weights = getWeights(); // KLUDGE This is a kludge just to see how many controls we have. + if (weights.length != 2 || (sashBorders != null && sashBorders.length != 2)) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + this.sashBorders = sashBorders; + } + + /** + * @see org.eclipse.swt.widgets.Composite#layout(boolean) + */ + public void layout(boolean changed) { + super.layout(changed); + + if (noHideUp && noHideDown) + return; // No arrows to handle in this case. + + if (getMaximizedControl() != null) + return; // We have a maximized control, so we don't need to worry about the sash. + + // Let's get the list of all sashes the sash form now has. If there is more than one then just disable the sashinfo. + // If there is no current sash, and there is only one sash, then create the sashinfo for it. + Control[] children = getChildren(); + Sash newSash = null; + for (int i = 0; i < children.length; i++) { + if (children[i] instanceof Sash) + if (newSash == null) + newSash = (Sash) children[i]; + else { + // We have more than one sash, so need to disable current sash, if we have one. + if (currentSashInfo != null) + currentSashInfo.enabled = false; + return; // Don't go on. + } + } + + if (newSash == null) + return; // We have no sashes at all. + + // Now we need to see if this is a new sash. + if (currentSashInfo == null || currentSashInfo.sash == null) { + if (currentSashInfo == null) + currentSashInfo = new SashInfo(newSash); + else + currentSashInfo.sash = newSash; + newSash.addPaintListener(new PaintListener() { + /** + * @see org.eclipse.swt.events.PaintListener#paintControl(PaintEvent) + */ + public void paintControl(PaintEvent e) { + // Need to find the index of the sash we're interested in. + + GC gc = e.gc; + Color oldFg = gc.getForeground(); + Color oldBg = gc.getBackground(); + +/* + gc.setBackground(borderColor); + gc.setFillRule(SWT.FILL_EVEN_ODD); + Point bounds = currentSashInfo.sash.getSize(); + gc.fillRectangle(1, 1, bounds.x - 2, bounds.y - 2); +*/ +/* + Point size = currentSashInfo.sash.getSize(); + gc.setLineStyle(SWT.LINE_DOT); + if (getOrientation() == SWT.HORIZONTAL) { + gc.drawLine(size.x / 2, 0, size.x / 2, size.y); + } else { + gc.drawLine(0, size.y / 2, size.x, size.y / 2); + } +*/ + + drawArrow(gc, currentSashInfo.sashLocs[0], currentSashInfo.cursorOver == 0); // Draw first arrow + if (currentSashInfo.sashLocs.length > 1) + drawArrow(gc, currentSashInfo.sashLocs[1], currentSashInfo.cursorOver == 1); // Draw second arrow + + if (currentSashInfo.sashBorderLeft) + drawSashBorder(gc, currentSashInfo.sash, true); + if (currentSashInfo.sashBorderRight) + drawSashBorder(gc, currentSashInfo.sash, false); + + gc.setForeground(oldFg); + gc.setBackground(oldBg); + } + + }); + + newSash.addControlListener(new ControlListener() { + /** + * @see org.eclipse.swt.events.ControlAdapter#controlMoved(ControlEvent) + */ + public void controlMoved(ControlEvent e) { + //System.out.println("controlMoved"); + recomputeSashInfo(); + } + + /** + * @see org.eclipse.swt.events.ControlAdapter#controlResized(ControlEvent) + */ + public void controlResized(ControlEvent e) { + recomputeSashInfo(); + } + + + }); + + newSash.addDisposeListener(new DisposeListener() { + /** + * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(DisposeEvent) + */ + public void widgetDisposed(DisposeEvent e) { + // Need to clear out the widget from current. + currentSashInfo = null; + } + }); + + // This is a kludge because we can't override the set cursor hit test. + newSash.addMouseMoveListener(new MouseMoveListener() { + /** + * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(MouseEvent) + */ + public void mouseMove(MouseEvent e) { + // See if within one of the arrows. + int x = e.x; + int y = e.y; + for (int i = 0; i < currentSashInfo.sashLocs.length; i++) { + int[] locs = currentSashInfo.sashLocs[i]; + boolean vertical = getOrientation() == SWT.VERTICAL; + int loc = vertical ? x : y; + int locIndex = vertical ? X_INDEX : Y_INDEX; + int sizeIndex = vertical ? WIDTH_INDEX : HEIGHT_INDEX; + // Does the mouse position lie within the bounds of the arrow? + if (locs[locIndex] <= loc && loc <= locs[locIndex] + locs[sizeIndex]) { + if (currentSashInfo.cursorOver == NO_ARROW) { + currentSashInfo.sash.setCursor(getDisplay().getSystemCursor(SWT.CURSOR_ARROW)); + } + if (currentSashInfo.cursorOver != i) { + currentSashInfo.cursorOver = i; + currentSashInfo.sash.redraw(); + switch (locs[ARROW_TYPE_INDEX]) { + case UP_RESTORE_ARROW: + case DOWN_RESTORE_ARROW: + currentSashInfo.sash.setToolTipText("Restore"); + break; + case UP_HIDE_ARROW: + case DOWN_HIDE_ARROW: + currentSashInfo.sash.setToolTipText("Hide"); + break; + } + } + return; + } + } + // If we got here, the mouse position does not lie within the bounds of an arrow + if (currentSashInfo.cursorOver != NO_ARROW) { + currentSashInfo.sash.setCursor(null); + currentSashInfo.cursorOver = NO_ARROW; + currentSashInfo.sash.redraw(); + currentSashInfo.sash.setToolTipText(null); + } + } + + }); + + // Need to know when we leave so that we can clear the cursor feedback if set. + newSash.addMouseTrackListener(new MouseTrackAdapter() { + /** + * @see org.eclipse.swt.events.MouseTrackAdapter#mouseExit(MouseEvent) + */ + public void mouseExit(MouseEvent e) { + if (currentSashInfo.cursorOver != NO_ARROW) { + // Undo the cursor. + currentSashInfo.sash.setCursor(null); + currentSashInfo.cursorOver = NO_ARROW; + currentSashInfo.sash.redraw(); + currentSashInfo.sash.setToolTipText(null); + } + } + }); + + // Want to handle mouse down as a selection. + newSash.addMouseListener(new MouseAdapter() { + /** + * @see org.eclipse.swt.events.MouseAdapter#mouseDown(MouseEvent) + */ + public void mouseDown(MouseEvent e) { + //System.out.println("mouseDown"); + inMouseClick = true; + // If we're within a button, then redraw to wipe out stipple and get button push effect. + int x = e.x; + int y = e.y; + for (int i = 0; i < currentSashInfo.sashLocs.length; i++) { + int[] locs = currentSashInfo.sashLocs[i]; + boolean vertical = getOrientation() == SWT.VERTICAL; + int loc = vertical ? x : y; + int locIndex = vertical ? X_INDEX : Y_INDEX; + int sizeIndex = vertical ? WIDTH_INDEX : HEIGHT_INDEX; + if (locs[locIndex] <= loc && loc <= locs[locIndex] + locs[sizeIndex]) { + currentSashInfo.sash.redraw(); + break; + } + } + } + + /** + * @see org.eclipse.swt.events.MouseListener#mouseDown(MouseEvent) + */ + public void mouseUp(MouseEvent e) { + //System.out.println("mouseUp"); + // See if within one of the arrows. + inMouseClick = false; // No longer in down click + int x = e.x; + int y = e.y; + for (int i = 0; i < currentSashInfo.sashLocs.length; i++) { + int[] locs = currentSashInfo.sashLocs[i]; + boolean vertical = getOrientation() == SWT.VERTICAL; + int loc = vertical ? x : y; + int locIndex = vertical ? X_INDEX : Y_INDEX; + int sizeIndex = vertical ? WIDTH_INDEX : HEIGHT_INDEX; + // Does the mouse position lie within the bounds of the arrow? + if (locs[locIndex] <= loc && loc <= locs[locIndex] + locs[sizeIndex]) { + // We found it. + switch (locs[ARROW_TYPE_INDEX]) { + case UP_RESTORE_ARROW: + upRestoreClicked(currentSashInfo); + break; + case UP_HIDE_ARROW: + upHideClicked(currentSashInfo); + break; + case DOWN_RESTORE_ARROW: + downRestoreClicked(currentSashInfo); + break; + case DOWN_HIDE_ARROW: + downHideClicked(currentSashInfo); + break; + } + break; + } + } + + currentSashInfo.sash.redraw(); // Make sure stipple goes away from the mouse up if not over an arrow button. + fireDividerMoved(); + } + + }); + recomputeSashInfo(); // Get initial setting + } + + } + + + /* + * Constants for recording whether the sash is slammed to the top/bottom or not slammed + */ + private final static int NOT_SLAMMED = 1; + private final static int SLAMMED_TO_BOTTOM = 2; + private final static int SLAMMED_TO_TOP = 3; + + protected void recomputeSashInfo() { + if (inMouseClick && currentSashInfo.cursorOver != NO_ARROW) { + return; // Don't process because we are in the down mouse button on an arrow. + } + + // addArrows are the types of the arrows - hide/restore/up/down and + // drawArrows are the types of the arrows actually drawn. Here + // drawArrows are always RESTORE arrow types, so that the UI only + // has a single arrow type showing. + int[] addArrows; + int[] drawArrows; + + // We need to refigure size for the sash arrows. + int[] weights = getWeights(); // This should be two entries only. We shouldn't have got here if there were more than two. + + // TODO: Use of DRAG_MINIMUM is a kludge, required because SashForm only allows you to close each part so far + final int DRAG_MINIMUM = 20; // TODO: kludge see SashForm.DRAG_MINIMUM + Rectangle sashBounds = currentSashInfo.sash.getBounds(); + Rectangle clientArea = getClientArea(); + boolean vertical = getOrientation() == SWT.VERTICAL; + + // + // Work out whether the sash is slammed to the top / bottom or not slammed + // + int slammed = NOT_SLAMMED; + if (weights[1] == 0) { + slammed = SLAMMED_TO_BOTTOM; + } else if (weights[0] == 0) { + slammed = SLAMMED_TO_TOP; + } else if (vertical) { + if (currentSashInfo.restoreWeight != NO_WEIGHT && sashBounds.y <= DRAG_MINIMUM) { + slammed = SLAMMED_TO_TOP; + } else if (currentSashInfo.restoreWeight != NO_WEIGHT && sashBounds.y + sashBounds.height >= clientArea.height - DRAG_MINIMUM) { + slammed = SLAMMED_TO_BOTTOM; + } + } else { + if (currentSashInfo.restoreWeight != NO_WEIGHT && sashBounds.x <= DRAG_MINIMUM) { + slammed = SLAMMED_TO_TOP; + } else if (currentSashInfo.restoreWeight != NO_WEIGHT && sashBounds.x + sashBounds.width >= clientArea.width - DRAG_MINIMUM) { + slammed = SLAMMED_TO_BOTTOM; + } + } + + // + // Now decide which arrows to add, according to whether noHideUp, noHideDown and the slammed status. + // + if (noHideUp) { + if (slammed == SLAMMED_TO_BOTTOM) { + addArrows = new int[1]; + drawArrows = new int[1]; + + addArrows[0] = UP_RESTORE_ARROW; + drawArrows[0] = UP_RESTORE_ARROW; + currentSashInfo.sashBorderLeft = sashBorders != null && sashBorders[0]; + currentSashInfo.sashBorderRight = false; + } else { + //Not slammed + addArrows = new int[1]; + drawArrows = new int[1]; + + addArrows[0] = DOWN_HIDE_ARROW; + drawArrows[0] = DOWN_RESTORE_ARROW; + currentSashInfo.restoreWeight = NO_WEIGHT; // Since we are in the middle, there is no restoreWeight. We've could of been dragged here. + currentSashInfo.sashBorderLeft = sashBorders != null && sashBorders[0]; + currentSashInfo.sashBorderRight = sashBorders != null && sashBorders[1]; + } + } else if (noHideDown) { + if (slammed == SLAMMED_TO_TOP) { + addArrows = new int[1]; + drawArrows = new int[1]; + + addArrows[0] = DOWN_RESTORE_ARROW; + drawArrows[0] = DOWN_RESTORE_ARROW; + currentSashInfo.sashBorderLeft = false; + currentSashInfo.sashBorderRight = sashBorders != null && sashBorders[1]; + } else { + //Not slammed + addArrows = new int[1]; + drawArrows = new int[1]; + + addArrows[0] = UP_HIDE_ARROW; + drawArrows[0] = UP_RESTORE_ARROW; + currentSashInfo.restoreWeight = NO_WEIGHT; // Since we are in the middle, there is no restoreWeight. We've could of been dragged here. + currentSashInfo.sashBorderLeft = sashBorders != null && sashBorders[0]; + currentSashInfo.sashBorderRight = sashBorders != null && sashBorders[1]; + } + } else { + if (slammed == SLAMMED_TO_TOP) { + addArrows = new int[1]; + drawArrows = new int[1]; + + addArrows[0] = DOWN_RESTORE_ARROW; + drawArrows[0] = DOWN_RESTORE_ARROW; + currentSashInfo.sashBorderLeft = false; + currentSashInfo.sashBorderRight = sashBorders != null && sashBorders[1]; + } else if (slammed == SLAMMED_TO_BOTTOM) { + addArrows = new int[1]; + drawArrows = new int[1]; + + addArrows[0] = UP_RESTORE_ARROW; + drawArrows[0] = UP_RESTORE_ARROW; + currentSashInfo.sashBorderLeft = sashBorders != null && sashBorders[0]; + currentSashInfo.sashBorderRight = false; + } else { + //Not slammed + addArrows = new int[2]; + drawArrows = new int[2]; + + addArrows[0] = UP_HIDE_ARROW; + drawArrows[0] = UP_RESTORE_ARROW; + addArrows[1] = DOWN_HIDE_ARROW; + drawArrows[1] = DOWN_RESTORE_ARROW; + currentSashInfo.restoreWeight = NO_WEIGHT; // Since we are in the middle, there is no restoreWeight. We've could of been dragged here. + currentSashInfo.sashBorderLeft = sashBorders != null && sashBorders[0]; + currentSashInfo.sashBorderRight = sashBorders != null && sashBorders[1]; + } + } + getNewSashArray(currentSashInfo, addArrows, drawArrows); + + currentSashInfo.sash.redraw(); // Need to schedule a redraw because it has already drawn the old ones during the set bounds in super layout. + } + + protected void upRestoreClicked(SashInfo sashinfo) { + // This means restore just the sash below restoreWeight and reduce the above restoreWeight by the right amount. + int[] weights = getWeights(); + + weights[0] = 1000 - sashinfo.restoreWeight; // Assume weights are always in units of 1000. + weights[1] = sashinfo.restoreWeight; + sashinfo.restoreWeight = NO_WEIGHT; + + try { + setWeights(weights); + } catch (SWTError e) { + // Sometimes it happens if sash controls aren't yet created + // Just ignore + } + fireDividerMoved(); + } + + protected void upHideClicked(SashInfo sashinfo) { + int[] weights = getWeights(); + if (weights.length != 2) { + return; + } + + // Up hide, so save the current restoreWeight of 1 into the sash info, and move to the top. + if (currentSashInfo.restoreWeight == NO_WEIGHT) { + currentSashInfo.restoreWeight = weights[1]; // Not currently maxed, save position. + + saveChildControlSizes(); + } + weights[0] = 0; + weights[1] = 1000; + + // If the upper panel has focus, flip focus to the lower panel because the upper panel is now hidden. + Control[] children = getChildren(); + boolean upperFocus = isFocusAncestorA(children[0]); + try { + setWeights(weights); + } catch (SWTError e) { + + } + setWeights(weights); + if (upperFocus) + children[1].setFocus(); + fireDividerMoved(); + } + + protected void downRestoreClicked(SashInfo sashinfo) { + // This means restore just the sash below restoreWeight and increase the above restoreWeight by that amount. + int[] weights = getWeights(); + + weights[0] = 1000 - sashinfo.restoreWeight; // Assume weights are always in units of 1000. + weights[1] = sashinfo.restoreWeight; + sashinfo.restoreWeight = NO_WEIGHT; + + setWeights(weights); + fireDividerMoved(); + } + + protected void downHideClicked(SashInfo sashinfo) { + int[] weights = getWeights(); + + // Down hide, so save the current restoreWeight of 1 into the sash info, and move to the bottom. + if (currentSashInfo.restoreWeight == NO_WEIGHT) { + currentSashInfo.restoreWeight = weights[1]; // Not currently maxed, save current restoreWeight. + saveChildControlSizes(); + } + weights[0] = 1000; + weights[1] = 0; + + // If the lower panel has focus, flip focus to the upper panel because the lower panel is now hidden. + Control[] children = getChildren(); + boolean lowerFocus = isFocusAncestorA(children[1]); + setWeights(weights); + if (lowerFocus) + children[0].setFocus(); + fireDividerMoved(); + } + + /* + * Helper method for upHideClicked / downHideClicked + */ + private void saveChildControlSizes() { + // Save control sizes + Control[] children = getChildren(); + int iChildToSave = 0; + for (int i = 0; i < children.length && iChildToSave < 2; i++) { + Control child = children[i]; + if (!(child instanceof Sash)) { + currentSashInfo.savedSizes[iChildToSave] = child.getSize(); + iChildToSave++; + } + } + } + + /* + * This determines if the control or one of its children + * has the focus. Control.isFocusAncestor is hidden by SWT, but it is really useful. + */ + protected boolean isFocusAncestorA(Control control) { + Display display = getDisplay(); + Control focusControl = display.getFocusControl(); + while (focusControl != null && focusControl != control) { + focusControl = focusControl.getParent(); + } + return control == focusControl; + } + + protected void getNewSashArray(SashInfo sashInfo, int[] addArrowTypes, int[] drawArrowTypes) { // int[][] thisSash = sashInfo.sashLocs; // if (thisSash == null) - sashInfo.sashLocs = new int[addArrowTypes.length][]; - int[][] thisSash = sashInfo.sashLocs; - - int aSize = ARROW_WIDTH; // Width of arrow - int tSize = aSize+2*ARROW_MARGIN; // Total Width (arrow + margin) - int neededSize = tSize*addArrowTypes.length; - - boolean vertical = getOrientation() == SWT.VERTICAL; - Point s = sashInfo.sash.getSize(); - int start; - int x; - int y; - int width; - int height; - if (vertical) { - start = (s.x - neededSize) / 2; - x = start; - y = (s.y - ARROW_HEIGHT) / 2; // Center vertically, no margin required. - width = tSize; - height = aSize; - } else { - start = (s.y - neededSize) / 2; - y = start; - x = (s.x - ARROW_HEIGHT) / 2; // Center horizontally, no margin required. - width = aSize; - height = tSize; - } - for (int j=0; j=0 && currentSashInfo!=null) { - //recomputeSashInfo(); - currentSashInfo.restoreWeight=weight; - } - } - - public Point[] getSavedSizes(){ - if (currentSashInfo!=null){ - return currentSashInfo.savedSizes; - } - else { - return null; - } - } - - /** - * Adds a custom sashform listener. This listener will be removed when - * this control is disposed. - * - * @since 1.2.0 - */ - public void addCustomSashFormListener(ICustomSashFormListener listener){ - if(customSashFormListeners==null) - customSashFormListeners = new ArrayList(); - customSashFormListeners.add(listener); - } - - /** - * Removes the custom sashform listener. - * - * @since 1.2.0 - */ - public void removeCustomSashFormListener(ICustomSashFormListener listener){ - if(customSashFormListeners!=null){ - customSashFormListeners.remove(listener); - } - } - - protected void fireDividerMoved(){ - if(customSashFormListeners!=null && customSashFormListeners.size()>0){ - int[] weights = getWeights(); - if(weights!=null && weights.length==2){ - int firstControlWeight = weights[0]; - int secondControlWeight = weights[1]; - for (Iterator listenerItr = customSashFormListeners.iterator(); listenerItr.hasNext();) { - ICustomSashFormListener listener = (ICustomSashFormListener) listenerItr.next(); - listener.dividerMoved(firstControlWeight, secondControlWeight); - } - } - } - } - + sashInfo.sashLocs = new int[addArrowTypes.length][]; + int[][] thisSash = sashInfo.sashLocs; + + int aSize = ARROW_WIDTH; // Width of arrow + int tSize = aSize + 2 * ARROW_MARGIN; // Total Width (arrow + margin) + int neededSize = tSize * addArrowTypes.length; + + boolean vertical = getOrientation() == SWT.VERTICAL; + Point s = sashInfo.sash.getSize(); + int start; + int x; + int y; + int width; + int height; + if (vertical) { + start = (s.x - neededSize) / 2; + x = start; + y = (s.y - ARROW_HEIGHT) / 2; // Center vertically, no margin required. + width = tSize; + height = aSize; + } else { + start = (s.y - neededSize) / 2; + y = start; + x = (s.x - ARROW_HEIGHT) / 2; // Center horizontally, no margin required. + width = aSize; + height = tSize; + } + for (int j = 0; j < addArrowTypes.length; j++) { + if (thisSash[j] == null) + thisSash[j] = new int[]{addArrowTypes[j], drawArrowTypes[j], x, y, width, height}; + else { + // Reuse the array + thisSash[j][ARROW_TYPE_INDEX] = addArrowTypes[j]; + thisSash[j][ARROW_DRAWN_INDEX] = drawArrowTypes[j]; + thisSash[j][X_INDEX] = x; + thisSash[j][Y_INDEX] = y; + thisSash[j][WIDTH_INDEX] = width; + thisSash[j][HEIGHT_INDEX] = height; + } + if (vertical) + x += tSize; + else + y += tSize; + } + } + + protected void drawSashBorder(GC gc, Sash sash, boolean leftBorder) { + gc.setForeground(borderColor); + if (getOrientation() == SWT.VERTICAL) { + Point s = sash.getSize(); + if (leftBorder) // i.e. top for VERTICAL sash + gc.drawLine(0, 0, s.x - 1, 0); + else // i.e. bottom for VERTICAL sash + gc.drawLine(0, s.y - 1, s.x - 1, s.y - 1); + } else { + Point s = sash.getSize(); + if (leftBorder) + gc.drawLine(0, 0, 0, s.y - 1); + else + gc.drawLine(s.x - 1, 0, s.x - 1, s.y - 1); + } + } + + protected void drawArrow(GC gc, int[] sashLoc, boolean selected) { + int indent = 0; + if (selected) { + if (!inMouseClick) { + // Draw the selection box. + Color highlightShadow = getDisplay().getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW); + Color normalShadow = getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); + gc.setForeground(highlightShadow); + gc.drawLine(sashLoc[X_INDEX], sashLoc[Y_INDEX] + sashLoc[HEIGHT_INDEX], sashLoc[X_INDEX], sashLoc[Y_INDEX]); + gc.drawLine(sashLoc[X_INDEX], sashLoc[Y_INDEX], sashLoc[X_INDEX] + sashLoc[WIDTH_INDEX], sashLoc[Y_INDEX]); + + gc.setForeground(normalShadow); + gc.drawLine(sashLoc[X_INDEX], sashLoc[Y_INDEX] + sashLoc[HEIGHT_INDEX], sashLoc[X_INDEX] + sashLoc[WIDTH_INDEX], sashLoc[Y_INDEX] + sashLoc[HEIGHT_INDEX]); + gc.drawLine(sashLoc[X_INDEX] + sashLoc[WIDTH_INDEX], sashLoc[Y_INDEX] + sashLoc[HEIGHT_INDEX], sashLoc[X_INDEX] + sashLoc[WIDTH_INDEX], sashLoc[Y_INDEX]); + } else { + // Draw pushed selection box. + indent = 1; + Color highlightShadow = getDisplay().getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW); + Color normalShadow = getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); + gc.setForeground(normalShadow); + gc.drawLine(sashLoc[X_INDEX], sashLoc[Y_INDEX] + sashLoc[HEIGHT_INDEX], sashLoc[X_INDEX], sashLoc[Y_INDEX]); + gc.drawLine(sashLoc[X_INDEX], sashLoc[Y_INDEX], sashLoc[X_INDEX] + sashLoc[WIDTH_INDEX], sashLoc[Y_INDEX]); + + gc.setForeground(highlightShadow); + gc.drawLine(sashLoc[X_INDEX], sashLoc[Y_INDEX] + sashLoc[HEIGHT_INDEX], sashLoc[X_INDEX] + sashLoc[WIDTH_INDEX], sashLoc[Y_INDEX] + sashLoc[HEIGHT_INDEX]); + gc.drawLine(sashLoc[X_INDEX] + sashLoc[WIDTH_INDEX], sashLoc[Y_INDEX] + sashLoc[HEIGHT_INDEX], sashLoc[X_INDEX] + sashLoc[WIDTH_INDEX], sashLoc[Y_INDEX]); + } + } + if (getOrientation() == SWT.VERTICAL) { + switch (sashLoc[ARROW_DRAWN_INDEX]) { + case UP_RESTORE_ARROW: + drawUpRestoreArrow(gc, sashLoc[X_INDEX] + indent, sashLoc[Y_INDEX] + indent); + break; + case DOWN_RESTORE_ARROW: + drawDownRestoreArrow(gc, sashLoc[X_INDEX] + indent, sashLoc[Y_INDEX] + indent); + break; + case UP_HIDE_ARROW: + drawUpHideArrow(gc, sashLoc[X_INDEX] + indent, sashLoc[Y_INDEX] + indent); + break; + case DOWN_HIDE_ARROW: + drawDownHideArrow(gc, sashLoc[X_INDEX] + indent, sashLoc[Y_INDEX] + indent); + break; + } + } else { + switch (sashLoc[ARROW_DRAWN_INDEX]) { + case UP_RESTORE_ARROW: + drawLeftRestoreArrow(gc, sashLoc[X_INDEX] + indent, sashLoc[Y_INDEX] + indent); + break; + case DOWN_RESTORE_ARROW: + drawRightRestoreArrow(gc, sashLoc[X_INDEX] + indent, sashLoc[Y_INDEX] + indent); + break; + case UP_HIDE_ARROW: + drawLeftHideArrow(gc, sashLoc[X_INDEX] + indent, sashLoc[Y_INDEX] + indent); + break; + case DOWN_HIDE_ARROW: + drawRightHideArrow(gc, sashLoc[X_INDEX] + indent, sashLoc[Y_INDEX] + indent); + break; + } + } + } + + // Draw at the given x/y (upper left corner of arrow area). + protected void drawUpRestoreArrow(GC gc, int x, int y) { + gc.setForeground(arrowColor); + + x += ARROW_MARGIN; + gc.drawLine(x + 4, y + 2, x + 7, y + 5); + gc.drawLine(x + 3, y + 2, x + 3, y + 2); + + gc.drawLine(x + 2, y + 3, x + 4, y + 3); + gc.drawLine(x + 1, y + 4, x + 5, y + 4); + gc.drawLine(x, y + 5, x + 6, y + 5); + } + + // Draw at the given x/y (upper left corner of arrow area). + protected void drawUpHideArrow(GC gc, int x, int y) { + gc.setForeground(arrowColor); + + x += ARROW_MARGIN; + gc.drawLine(x, y, x + 7, y); + gc.drawLine(x, y + 1, x + 7, y + 1); + + gc.drawLine(x + 4, y + 2, x + 7, y + 5); + gc.drawLine(x + 3, y + 2, x + 3, y + 2); + + gc.drawLine(x + 2, y + 3, x + 4, y + 3); + gc.drawLine(x + 1, y + 4, x + 5, y + 4); + gc.drawLine(x, y + 5, x + 6, y + 5); + } + + // Draw at the given x/y (upper left corner of arrow area). + protected void drawDownRestoreArrow(GC gc, int x, int y) { + gc.setForeground(arrowColor); + + x += ARROW_MARGIN; + gc.drawLine(x, y + 2, x + 3, y + 5); + gc.drawLine(x + 4, y + 5, x + 4, y + 5); + + gc.drawLine(x + 3, y + 4, x + 5, y + 4); + gc.drawLine(x + 1, y + 3, x + 6, y + 3); + gc.drawLine(x + 1, y + 2, x + 7, y + 2); + } + + // Draw at the given x/y (upper left corner of arrow area). + protected void drawDownHideArrow(GC gc, int x, int y) { + gc.setForeground(arrowColor); + + x += ARROW_MARGIN; + gc.drawLine(x, y + 6, x + 7, y + 6); + gc.drawLine(x, y + 7, x + 7, y + 7); + + gc.drawLine(x, y + 2, x + 3, y + 5); + gc.drawLine(x + 4, y + 5, x + 4, y + 5); + + gc.drawLine(x + 3, y + 4, x + 5, y + 4); + gc.drawLine(x + 1, y + 3, x + 6, y + 3); + gc.drawLine(x + 1, y + 2, x + 7, y + 2); + } + + // Draw at the given x/y (upper left corner of arrow area). + protected void drawLeftRestoreArrow(GC gc, int x, int y) { + gc.setForeground(arrowColor); + + y += ARROW_MARGIN; + gc.drawLine(x + 2, y + 4, x + 5, y + 7); + gc.drawLine(x + 2, y + 3, x + 2, y + 3); + + gc.drawLine(x + 3, y + 2, x + 3, y + 4); + gc.drawLine(x + 4, y + 1, x + 4, y + 5); + gc.drawLine(x + 5, y, x + 5, y + 6); + } + + // Draw at the given x/y (upper left corner of arrow area). + protected void drawLeftHideArrow(GC gc, int x, int y) { + gc.setForeground(arrowColor); + + y += ARROW_MARGIN; + gc.drawLine(x, y, x, y + 7); + gc.drawLine(x + 1, y, x + 1, y + 7); + + gc.drawLine(x + 2, y + 4, x + 5, y + 7); + gc.drawLine(x + 2, y + 3, x + 2, y + 3); + + gc.drawLine(x + 3, y + 2, x + 3, y + 4); + gc.drawLine(x + 4, y + 1, x + 4, y + 5); + gc.drawLine(x + 5, y, x + 5, y + 6); + } + + // Draw at the given x/y (upper left corner of arrow area). + protected void drawRightRestoreArrow(GC gc, int x, int y) { + gc.setForeground(arrowColor); + + y += ARROW_MARGIN; + gc.drawLine(x + 2, y, x + 5, y + 3); + gc.drawLine(x + 5, y + 4, x + 5, y + 4); + + gc.drawLine(x + 4, y + 3, x + 4, y + 5); + gc.drawLine(x + 3, y + 1, x + 3, y + 6); + gc.drawLine(x + 2, y + 1, x + 2, y + 7); + } + + // Draw at the given x/y (upper left corner of arrow area). + protected void drawRightHideArrow(GC gc, int x, int y) { + gc.setForeground(arrowColor); + + y += ARROW_MARGIN; + gc.drawLine(x + 6, y, x + 6, y + 7); + gc.drawLine(x + 7, y, x + 7, y + 7); + + gc.drawLine(x + 2, y, x + 5, y + 3); + gc.drawLine(x + 5, y + 4, x + 5, y + 4); + + gc.drawLine(x + 4, y + 3, x + 4, y + 5); + gc.drawLine(x + 3, y + 1, x + 3, y + 6); + gc.drawLine(x + 2, y + 1, x + 2, y + 7); + } + + + public int getRestoreWeight() { + if (currentSashInfo != null) + return currentSashInfo.restoreWeight; + else + return -1; + } + + + protected Sash getSash() { + Control[] kids = getChildren(); + for (int i = 0; i < kids.length; i++) { + if (kids[i] instanceof Sash) + return (Sash) kids[i]; + } + return null; + } + + public void setRestoreWeight(int weight) { + if (weight >= 0 && currentSashInfo != null) { + //recomputeSashInfo(); + currentSashInfo.restoreWeight = weight; + } + } + + public Point[] getSavedSizes() { + if (currentSashInfo != null) { + return currentSashInfo.savedSizes; + } else { + return null; + } + } + + /** + * Adds a custom sashform listener. This listener will be removed when + * this control is disposed. + * + * @since 1.2.0 + */ + public void addCustomSashFormListener(ICustomSashFormListener listener) { + if (customSashFormListeners == null) + customSashFormListeners = new ArrayList(); + customSashFormListeners.add(listener); + } + + /** + * Removes the custom sashform listener. + * + * @since 1.2.0 + */ + public void removeCustomSashFormListener(ICustomSashFormListener listener) { + if (customSashFormListeners != null) { + customSashFormListeners.remove(listener); + } + } + + protected void fireDividerMoved() { + if (customSashFormListeners != null && customSashFormListeners.size() > 0) { + int[] weights = getWeights(); + if (weights != null && weights.length == 2) { + int firstControlWeight = weights[0]; + int secondControlWeight = weights[1]; + for (Iterator listenerItr = customSashFormListeners.iterator(); listenerItr.hasNext(); ) { + ICustomSashFormListener listener = (ICustomSashFormListener) listenerItr.next(); + listener.dividerMoved(firstControlWeight, secondControlWeight); + } + } + } + } + } -- GitLab