/******************************************************************************* * Copyright (c) 2013 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.openshift.internal.common.ui.utils; import org.eclipse.core.runtime.Assert; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.ControlListener; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Shell; /** * An adapter that toggles the dialog height when showing/hiding a given child control. * * * @author Andre Dietisheim */ public class DialogChildVisibilityAdapter { private boolean visible; private final Composite composite; private final GridData gridData; private final Shell shell; private int invisibleChildShellHeight; private boolean resizing; public DialogChildVisibilityAdapter(Composite child, boolean visible) { Assert.isTrue(child != null && !child.isDisposed()); this.composite = child; Object layoutData = child.getLayoutData(); Assert.isTrue(layoutData instanceof GridData, "only supports GridLayout"); this.gridData = (GridData) layoutData; gridData.exclude = !visible; Assert.isTrue(child.getShell() != null && !child.getShell().isDisposed()); this.shell = child.getShell(); shell.addControlListener(onShellResized(shell)); this.invisibleChildShellHeight = computeChildHeight(visible, child, shell); this.visible = visible; child.setVisible(visible); } private ControlListener onShellResized(final Shell shell) { final ControlListener listener = new ControlAdapter() { @Override public void controlResized(ControlEvent e) { if (!resizing) { DialogChildVisibilityAdapter.this.invisibleChildShellHeight = shell.getSize().y; } } }; shell.addDisposeListener(new DisposeListener() { @Override public void widgetDisposed(DisposeEvent e) { shell.removeControlListener(listener); } }); return listener; } private int computeChildHeight(boolean visible, Composite child, Shell shell) { Point size = shell.getSize(); if (visible) { Point childSize = child.computeSize(child.getSize().x, SWT.DEFAULT); size.y = size.y - childSize.y ; } return size.y; } public void setVisible(boolean visible) { if (this.visible == visible) { return; } toggle(); } public boolean toggle() { this.resizing = true; this.visible = !visible; composite.setVisible(visible); gridData.exclude = !visible; int newShellHeight= computeShellHeight(shell.getSize()); shell.setSize(shell.getSize().x, newShellHeight); shell.layout(true, true); this.resizing = false; return visible; } protected int computeShellHeight(Point shellSize) { if (visible) { return shell.computeSize(shellSize.x, SWT.DEFAULT, true).y; } else { return new Point(shellSize.x, invisibleChildShellHeight).y; } } public boolean isVisible() { return visible; } }