1 package org
.argeo
.cms
.ui
.widgets
;
3 import org
.argeo
.cms
.ui
.util
.CmsUiUtils
;
4 import org
.eclipse
.swt
.SWT
;
5 import org
.eclipse
.swt
.events
.ShellAdapter
;
6 import org
.eclipse
.swt
.events
.ShellEvent
;
7 import org
.eclipse
.swt
.graphics
.Point
;
8 import org
.eclipse
.swt
.widgets
.Composite
;
9 import org
.eclipse
.swt
.widgets
.Control
;
10 import org
.eclipse
.swt
.widgets
.Shell
;
13 * Manages a lightweight shell which is related to a {@link Control}, typically
14 * in order to reproduce a dropdown semantic, but with more flexibility.
16 public class ContextOverlay
extends ScrolledPage
{
17 private static final long serialVersionUID
= 6702077429573324009L;
19 // private Shell shell;
20 private Control control
;
22 private int maxHeight
= 400;
24 public ContextOverlay(Control control
, int style
) {
25 super(createShell(control
, style
), SWT
.NONE
);
26 Shell shell
= getShell();
27 setLayoutData(CmsUiUtils
.fillAll());
28 // TODO make autohide configurable?
29 //shell.addShellListener(new AutoHideShellListener());
30 this.control
= control
;
31 control
.addDisposeListener((e
) -> {
37 private static Composite
createShell(Control control
, int style
) {
39 throw new IllegalArgumentException("Control cannot be null");
40 if (control
.isDisposed())
41 throw new IllegalArgumentException("Control is disposed");
42 Shell shell
= new Shell(control
.getShell(), SWT
.NO_TRIM
);
43 shell
.setLayout(CmsUiUtils
.noSpaceGridLayout());
44 Composite placeholder
= new Composite(shell
, SWT
.BORDER
);
45 placeholder
.setLayoutData(CmsUiUtils
.fillAll());
46 placeholder
.setLayout(CmsUiUtils
.noSpaceGridLayout());
51 Point relativeControlLocation
= control
.getLocation();
52 Point controlLocation
= control
.toDisplay(relativeControlLocation
.x
, relativeControlLocation
.y
);
54 int controlWidth
= control
.getBounds().width
;
56 Shell shell
= getShell();
60 shell
.layout(true, true);
61 int targetShellWidth
= shell
.getSize().x
< controlWidth ? controlWidth
: shell
.getSize().x
;
62 if (shell
.getSize().y
> maxHeight
) {
63 shell
.setSize(targetShellWidth
, maxHeight
);
65 shell
.setSize(targetShellWidth
, shell
.getSize().y
);
68 int shellHeight
= shell
.getSize().y
;
69 int controlHeight
= control
.getBounds().height
;
70 Point shellLocation
= new Point(controlLocation
.x
, controlLocation
.y
+ controlHeight
);
71 int displayHeight
= shell
.getDisplay().getBounds().height
;
72 if (shellLocation
.y
+ shellHeight
> displayHeight
) {// bottom of page
73 shellLocation
= new Point(controlLocation
.x
, controlLocation
.y
- shellHeight
);
75 shell
.setLocation(shellLocation
);
77 if (getChildren().length
!= 0)
79 if (!control
.isDisposed())
84 getShell().setVisible(false);
88 public boolean isShellVisible() {
91 return getShell().isVisible();
94 /** to be overridden */
95 protected void onHide() {
96 // does nothing by default.
99 private class AutoHideShellListener
extends ShellAdapter
{
100 private static final long serialVersionUID
= 7743287433907938099L;
103 public void shellDeactivated(ShellEvent e
) {
106 } catch (InterruptedException e1
) {
109 if (!control
.isDisposed() && !control
.isFocusControl())