+++ /dev/null
-package org.argeo.cms.ui.widgets;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.widgets.ScrolledPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ShellAdapter;
-import org.eclipse.swt.events.ShellEvent;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Shell;
-
-/**
- * Manages a lightweight shell which is related to a {@link Control}, typically
- * in order to reproduce a dropdown semantic, but with more flexibility.
- */
-public class ContextOverlay extends ScrolledPage {
- private static final long serialVersionUID = 6702077429573324009L;
-
-// private Shell shell;
- private Control control;
-
- private int maxHeight = 400;
-
- public ContextOverlay(Control control, int style) {
- super(createShell(control, style), SWT.NONE);
- Shell shell = getShell();
- setLayoutData(CmsSwtUtils.fillAll());
- // TODO make autohide configurable?
- //shell.addShellListener(new AutoHideShellListener());
- this.control = control;
- control.addDisposeListener((e) -> {
- dispose();
- shell.dispose();
- });
- }
-
- private static Composite createShell(Control control, int style) {
- if (control == null)
- throw new IllegalArgumentException("Control cannot be null");
- if (control.isDisposed())
- throw new IllegalArgumentException("Control is disposed");
- Shell shell = new Shell(control.getShell(), SWT.NO_TRIM);
- shell.setLayout(CmsSwtUtils.noSpaceGridLayout());
- Composite placeholder = new Composite(shell, SWT.BORDER);
- placeholder.setLayoutData(CmsSwtUtils.fillAll());
- placeholder.setLayout(CmsSwtUtils.noSpaceGridLayout());
- return placeholder;
- }
-
- public void show() {
- Point relativeControlLocation = control.getLocation();
- Point controlLocation = control.toDisplay(relativeControlLocation.x, relativeControlLocation.y);
-
- int controlWidth = control.getBounds().width;
-
- Shell shell = getShell();
-
- layout(true, true);
- shell.pack();
- shell.layout(true, true);
- int targetShellWidth = shell.getSize().x < controlWidth ? controlWidth : shell.getSize().x;
- if (shell.getSize().y > maxHeight) {
- shell.setSize(targetShellWidth, maxHeight);
- } else {
- shell.setSize(targetShellWidth, shell.getSize().y);
- }
-
- int shellHeight = shell.getSize().y;
- int controlHeight = control.getBounds().height;
- Point shellLocation = new Point(controlLocation.x, controlLocation.y + controlHeight);
- int displayHeight = shell.getDisplay().getBounds().height;
- if (shellLocation.y + shellHeight > displayHeight) {// bottom of page
- shellLocation = new Point(controlLocation.x, controlLocation.y - shellHeight);
- }
- shell.setLocation(shellLocation);
-
- if (getChildren().length != 0)
- shell.open();
- if (!control.isDisposed())
- control.setFocus();
- }
-
- public void hide() {
- getShell().setVisible(false);
- onHide();
- }
-
- public boolean isShellVisible() {
- if (isDisposed())
- return false;
- return getShell().isVisible();
- }
-
- /** to be overridden */
- protected void onHide() {
- // does nothing by default.
- }
-
- private class AutoHideShellListener extends ShellAdapter {
- private static final long serialVersionUID = 7743287433907938099L;
-
- @Override
- public void shellDeactivated(ShellEvent e) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e1) {
- // silent
- }
- if (!control.isDisposed() && !control.isFocusControl())
- hide();
- }
- }
-}