### Eclipse Workspace Patch 1.0 #P org.eclipse.jface.text Index: src/org/eclipse/jface/text/AbstractInformationControl.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jface.text/src/org/eclipse/jface/text/AbstractInformationControl.java,v retrieving revision 1.1 diff -u -r1.1 AbstractInformationControl.java --- src/org/eclipse/jface/text/AbstractInformationControl.java 20 Feb 2008 15:22:27 -0000 1.1 +++ src/org/eclipse/jface/text/AbstractInformationControl.java 21 Feb 2008 14:48:36 -0000 @@ -10,8 +10,11 @@ *******************************************************************************/ package org.eclipse.jface.text; -import java.util.List; - +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.jface.action.ToolBarManager; +import org.eclipse.jface.internal.text.html.BrowserInformationControl; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.util.Geometry; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.FocusEvent; @@ -19,7 +22,10 @@ import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Cursor; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.GC; @@ -27,26 +33,21 @@ import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Layout; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Slider; import org.eclipse.swt.widgets.ToolBar; -import org.eclipse.core.runtime.ListenerList; - -import org.eclipse.jface.action.ToolBarManager; -import org.eclipse.jface.dialogs.PopupDialog; -import org.eclipse.jface.internal.text.html.BrowserInformationControl; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.util.Geometry; - /** - * The abstract information control can show any content inside a popup window. + * The abstract information control can show any content inside a shell. * Additionally it can present either a status line containing a status text or * a toolbar containing toolbar buttons. *
@@ -62,13 +63,14 @@
*/
public abstract class AbstractInformationControl implements IInformationControl, IInformationControlExtension, IInformationControlExtension3, IInformationControlExtension5 {
+ private static final int BORDER= 1;
- /** The control's popup dialog. */
- private PopupDialog fPopupDialog;
+ /** The information controls shell. */
+ private final Shell fShell;
/** Composite containing the content created by subclasses. */
- private Composite fContentComposite;
+ private final Composite fContentComposite;
/** Composite containing the status line content or null
if none. */
- private Composite fStatusComposite;
+ private final Composite fStatusComposite;
/** Separator between content and status line or null
if none. */
private Label fSeparator;
/** Label in the status line or null
if none. */
@@ -83,7 +85,8 @@
private Point fSizeConstaints;
/** The toolbar manager used by the toolbar or null
if none. */
private final ToolBarManager fToolBarManager;
-
+ /** The size of the resize handle if already set, -1 otherwise */
+ private int fResizeHandleSize;
/**
* Creates an abstract information control with the given shell as parent.
@@ -122,78 +125,53 @@
* @param toolBarManager the manager of the popup tool bar, if any
*/
private AbstractInformationControl(Shell parentShell, int shellStyle, final String statusFieldText, final ToolBarManager toolBarManager) {
+ fResizeHandleSize= -1;
fToolBarManager= toolBarManager;
- fPopupDialog= new PopupDialog(parentShell, shellStyle | SWT.NO_FOCUS | SWT.ON_TOP, false, false, false, false, null, null) {
-
- /*
- * @see org.eclipse.jface.dialogs.PopupDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
- */
- protected Control createDialogArea(Composite parent) {
- Composite composite= new Composite(parent, SWT.NONE);
-
- composite.setLayoutData(new GridData(GridData.BEGINNING | GridData.FILL_BOTH));
-
- GridLayout layout= new GridLayout();
- layout.marginHeight= 0;
- layout.marginWidth= 0;
- layout.verticalSpacing= 0;
- composite.setLayout(layout);
-
- fContentComposite= new Composite(composite, SWT.NONE);
- fContentComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- GridLayout contentLayout= new GridLayout(1, false);
- contentLayout.marginHeight= 0;
- contentLayout.marginWidth= 0;
- fContentComposite.setLayout(contentLayout);
- createContent(fContentComposite);
-
- if (toolBarManager != null || statusFieldText != null) {
- fStatusComposite= new Composite(composite, SWT.NONE);
- GridData gridData= new GridData(SWT.FILL, SWT.BOTTOM, true, false);
- fStatusComposite.setLayoutData(gridData);
- GridLayout gridLayout= new GridLayout(1, false);
- gridLayout.marginHeight= 0;
- gridLayout.marginWidth= 0;
- gridLayout.verticalSpacing= 0;
- fStatusComposite.setLayout(gridLayout);
-
- createStatusLine(fStatusComposite, statusFieldText, toolBarManager);
- }
-
- return composite;
- }
-
- /*
- * @see org.eclipse.jface.dialogs.PopupDialog#getBackgroundColorExclusions()
- */
- protected List getBackgroundColorExclusions() {
- List result= super.getBackgroundColorExclusions();
-
- if (fToolBar != null) {
- result.add(fStatusComposite);
- result.add(fSeparator);
- result.add(fToolBar);
- }
-
- return result;
- }
-
- /*
- * @see org.eclipse.jface.dialogs.PopupDialog#getForegroundColorExclusions()
- */
- protected List getForegroundColorExclusions() {
- List result= super.getForegroundColorExclusions();
-
- if (fStatusLabel != null) {
- result.add(fStatusLabel);
- }
-
- return result;
+
+ fShell= new Shell(parentShell, SWT.ON_TOP | shellStyle);
+ Display display= fShell.getDisplay();
+
+ GridLayout layout= new GridLayout(1, false);
+ int border;
+ if ((shellStyle & SWT.NO_TRIM) == 0) {
+ border= 0;
+ } else {
+ border= BORDER;
+ fShell.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
+ }
+ layout.marginHeight= border;
+ layout.marginWidth= border;
+ layout.verticalSpacing= 0;
+ fShell.setLayout(layout);
+
+ fContentComposite= new Composite(fShell, SWT.NONE);
+ fContentComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ GridLayout contentLayout= new GridLayout(1, false);
+ contentLayout.marginHeight= 0;
+ contentLayout.marginWidth= 0;
+ fContentComposite.setLayout(contentLayout);
+ createContent(fContentComposite);
+
+ setColor(fContentComposite, display.getSystemColor(SWT.COLOR_INFO_FOREGROUND), display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+
+ if (toolBarManager != null || statusFieldText != null) {
+ fStatusComposite= new Composite(fShell, SWT.NONE);
+ GridData gridData= new GridData(SWT.FILL, SWT.BOTTOM, true, false);
+ fStatusComposite.setLayoutData(gridData);
+ GridLayout statusLayout= new GridLayout(1, false);
+ statusLayout.marginHeight= 0;
+ statusLayout.marginWidth= 0;
+ statusLayout.verticalSpacing= 0;
+ fStatusComposite.setLayout(statusLayout);
+
+ createStatusLine(fStatusComposite, statusFieldText, toolBarManager);
+
+ if (statusFieldText != null) {
+ setColor(fStatusComposite, display.getSystemColor(SWT.COLOR_INFO_FOREGROUND), display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
}
- };
-
- // Force create early so that listeners can be added at all times with API.
- fPopupDialog.create();
+ } else {
+ fStatusComposite= null;
+ }
}
/**
@@ -202,7 +180,7 @@
* @return the shell used for the popup window
*/
protected Shell getShell() {
- return fPopupDialog.getShell();
+ return fShell;
}
/**
@@ -226,32 +204,32 @@
* @see IInformationControl#setVisible(boolean)
*/
public void setVisible(boolean visible) {
- if (visible)
- fPopupDialog.open();
- else
- fPopupDialog.getShell().setVisible(false);
+ if (getShell().isVisible() == visible)
+ return;
+
+ getShell().setVisible(visible);
}
/*
* @see IInformationControl#dispose()
*/
public void dispose() {
- fPopupDialog.close();
- fPopupDialog= null;
+ if (fShell != null && !fShell.isDisposed())
+ fShell.dispose();
}
/*
* @see IInformationControl#setSize(int, int)
*/
public void setSize(int width, int height) {
- fPopupDialog.getShell().setSize(width, height);
+ getShell().setSize(width, height);
}
/*
* @see IInformationControl#setLocation(Point)
*/
public void setLocation(Point location) {
- fPopupDialog.getShell().setLocation(location);
+ getShell().setLocation(location);
}
/*
@@ -277,17 +255,23 @@
public Point computeSizeHint() {
Point constrains= getSizeConstraints();
if (constrains == null)
- return fPopupDialog.getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
+ return getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
- return fPopupDialog.getShell().computeSize(constrains.x, constrains.y, true);
+ return getShell().computeSize(constrains.x, constrains.y, true);
}
/*
* @see org.eclipse.jface.text.IInformationControlExtension3#computeTrim()
*/
public Rectangle computeTrim() {
- Shell shell= fPopupDialog.getShell();
- Rectangle trim= shell.computeTrim(0, 0, 0, 0);
+ Rectangle trim= getShell().computeTrim(0, 0, 0, 0);
+
+ if ((getShell().getStyle() & SWT.NO_TRIM) != 0) {
+ trim.x-= BORDER;
+ trim.y-= BORDER;
+ trim.width+= 2 * BORDER;
+ trim.height+= 2 * BORDER;
+ }
if (fToolBar != null) {
trim.height+= fSeparator.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
@@ -298,7 +282,7 @@
}
// Popup dialog adds a 1 pixel border when SWT.NO_TRIM is set:
- Layout layout= shell.getLayout();
+ Layout layout= getShell().getLayout();
if (layout instanceof GridLayout) {
GridLayout gridLayout= (GridLayout) layout;
int left= gridLayout.marginLeft + gridLayout.marginWidth;
@@ -332,7 +316,7 @@
* @see org.eclipse.jface.text.IInformationControlExtension3#getBounds()
*/
public Rectangle getBounds() {
- return fPopupDialog.getShell().getBounds();
+ return getShell().getBounds();
}
/*
@@ -353,14 +337,14 @@
* @see IInformationControl#addDisposeListener(DisposeListener)
*/
public void addDisposeListener(DisposeListener listener) {
- fPopupDialog.getShell().addDisposeListener(listener);
+ getShell().addDisposeListener(listener);
}
/*
* @see IInformationControl#removeDisposeListener(DisposeListener)
*/
public void removeDisposeListener(DisposeListener listener) {
- fPopupDialog.getShell().removeDisposeListener(listener);
+ getShell().removeDisposeListener(listener);
}
/*
@@ -381,15 +365,14 @@
* @see IInformationControl#isFocusControl()
*/
public boolean isFocusControl() {
- Shell shell= fPopupDialog.getShell();
- return shell.getDisplay().getActiveShell() == shell;
+ return getShell().getDisplay().getActiveShell() == getShell();
}
/*
* @see IInformationControl#setFocus()
*/
public void setFocus() {
- fPopupDialog.getShell().forceFocus();
+ getShell().forceFocus();
}
/*
@@ -441,8 +424,7 @@
*/
public boolean containsControl(Control control) {
do {
- Shell popupShell= fPopupDialog.getShell();
- if (control == popupShell)
+ if (control == getShell())
return true;
if (control instanceof Shell)
return false;
@@ -455,8 +437,8 @@
* @see org.eclipse.jface.text.IInformationControlExtension5#isVisible()
*/
public boolean isVisible() {
- Shell popupShell= fPopupDialog.getShell();
- return popupShell != null && !popupShell.isDisposed() && popupShell.isVisible();
+ Shell shell= getShell();
+ return shell != null && !shell.isDisposed() && shell.isVisible();
}
/*
@@ -484,10 +466,7 @@
fSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
if (toolBarManager != null) {
- fToolBar= toolBarManager.createControl(parent);
- fToolBar.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
-
- addMoveSupport(parent);
+ createToolBar(parent, toolBarManager);
} else {
fStatusLabel= new Label(parent, SWT.RIGHT);
fStatusLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
@@ -502,6 +481,93 @@
}
}
+ private void createToolBar(Composite parent, ToolBarManager toolBarManager) {
+ final Composite bars= new Composite(parent, SWT.NONE);
+ bars.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
+
+ GridLayout layout= new GridLayout(3, false);
+ layout.marginHeight= 0;
+ layout.marginWidth= 0;
+ layout.horizontalSpacing= 0;
+ layout.verticalSpacing= 0;
+ bars.setLayout(layout);
+
+ fToolBar= toolBarManager.createControl(bars);
+ GridData gd= new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false);
+ fToolBar.setLayoutData(gd);
+
+ Composite spacer= new Composite(bars, SWT.NONE);
+ gd= new GridData(SWT.FILL, SWT.FILL, true, true);
+ gd.widthHint= 0;
+ gd.heightHint= 0;
+ spacer.setLayoutData(gd);
+
+ addMoveSupport(spacer);
+
+ // XXX: workaround for
+ // - https://bugs.eclipse.org/bugs/show_bug.cgi?id=219139 : API to add resize grip / grow box in lower right corner of shell
+ // - https://bugs.eclipse.org/bugs/show_bug.cgi?id=23980 : platform specific shell resize behavior
+ String platform= SWT.getPlatform();
+ final boolean isWin= platform.equals("win32"); //$NON-NLS-1$
+ if (isWin || platform.equals("gtk")) { //$NON-NLS-1$
+ final Canvas resizer= new Canvas(bars, SWT.NONE);
+
+ int size= getResizeHandleSize(bars);
+
+ GridData data= new GridData(SWT.END, SWT.END, false, true);
+ data.widthHint= size;
+ data.heightHint= size;
+ resizer.setLayoutData(data);
+ resizer.addPaintListener(new PaintListener() {
+ public void paintControl(PaintEvent e) {
+ Point s= resizer.getSize();
+ int x= s.x - 2;
+ int y= s.y - 2;
+ int min= Math.min(x, y);
+ if (isWin) {
+ // draw dots
+ e.gc.setBackground(resizer.getDisplay().getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));
+ int end= min - 1;
+ for (int i= 0; i <= 2; i++)
+ for (int j= 0; j <= 2 - i; j++)
+ e.gc.fillRectangle(end - 4 * i, end - 4 * j, 2, 2);
+ end--;
+ e.gc.setBackground(resizer.getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
+ for (int i= 0; i <= 2; i++)
+ for (int j= 0; j <= 2 - i; j++)
+ e.gc.fillRectangle(end - 4 * i, end - 4 * j, 2, 2);
+
+ } else {
+ // draw diagonal lines
+ e.gc.setForeground(resizer.getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
+ for (int i= 1; i < min; i+= 4) {
+ e.gc.drawLine(i, y, x, i);
+ }
+ e.gc.setForeground(resizer.getDisplay().getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));
+ for (int i= 2; i < min; i+= 4) {
+ e.gc.drawLine(i, y, x, i);
+ }
+ }
+ }
+ });
+ addResizeSupport(resizer);
+ }
+ }
+
+ private int getResizeHandleSize(Composite parent) {
+ if (fResizeHandleSize == -1) {
+ Slider sliderV= new Slider(parent, SWT.VERTICAL);
+ Slider sliderH= new Slider(parent, SWT.HORIZONTAL);
+ int width= sliderV.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
+ int height= sliderH.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
+ sliderV.dispose();
+ sliderH.dispose();
+ fResizeHandleSize= Math.min(width, height);
+ }
+
+ return fResizeHandleSize;
+ }
+
/**
* Adds support to move the shell by dragging the given control.
*
@@ -512,7 +578,7 @@
private MouseMoveListener fMoveListener;
public void mouseDown(MouseEvent e) {
- Point shellLoc= fPopupDialog.getShell().getLocation();
+ Point shellLoc= getShell().getLocation();
final int shellX= shellLoc.x;
final int shellY= shellLoc.y;
Point mouseLoc= control.toDisplay(e.x, e.y);
@@ -523,7 +589,7 @@
Point mouseLoc2= control.toDisplay(e2.x, e2.y);
int dx= mouseLoc2.x - mouseX;
int dy= mouseLoc2.y - mouseY;
- fPopupDialog.getShell().setLocation(shellX + dx, shellY + dy);
+ getShell().setLocation(shellX + dx, shellY + dy);
}
};
control.addMouseMoveListener(fMoveListener);
@@ -537,4 +603,61 @@
control.addMouseListener(moveSupport);
}
+ /**
+ * Adds support to resize the shell by dragging the given control.
+ *
+ * @param control the control that can be used to resize the shell
+ * @since 3.4
+ */
+ private void addResizeSupport(final Control control) {
+ control.setCursor(new Cursor(control.getDisplay(), SWT.CURSOR_SIZESE));
+ MouseAdapter resizeSupport= new MouseAdapter() {
+ private MouseMoveListener fResizeListener;
+
+ public void mouseDown(MouseEvent e) {
+ Point shellSize= fShell.getSize();
+ final int shellX= shellSize.x;
+ final int shellY= shellSize.y;
+ Point mouseLoc= control.toDisplay(e.x, e.y);
+ final int mouseX= mouseLoc.x;
+ final int mouseY= mouseLoc.y;
+ fResizeListener= new MouseMoveListener() {
+ public void mouseMove(MouseEvent e2) {
+ Point mouseLoc2= control.toDisplay(e2.x, e2.y);
+ int dx= mouseLoc2.x - mouseX;
+ int dy= mouseLoc2.y - mouseY;
+ setSize(shellX + dx, shellY + dy);
+ }
+ };
+ control.addMouseMoveListener(fResizeListener);
+ }
+
+ public void mouseUp(MouseEvent e) {
+ control.removeMouseMoveListener(fResizeListener);
+ fResizeListener= null;
+ }
+ };
+ control.addMouseListener(resizeSupport);
+ }
+
+ /**
+ * Utility to set the foreground and the background color of the given
+ * control and of all its children.
+ *
+ * @param control the control to modify
+ * @param foreground the color to use for the foreground
+ * @param background the color to use for the background
+ */
+ private static void setColor(Control control, Color foreground, Color background) {
+ control.setForeground(foreground);
+ control.setBackground(background);
+
+ if (control instanceof Composite) {
+ Control[] children= ((Composite) control).getChildren();
+ for (int i= 0; i < children.length; i++) {
+ setColor(children[i], foreground, background);
+ }
+ }
+ }
+
}