blob: 61cfe7f9a18863ba91514174ea57553511cf48dd [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 BSI Business Systems Integration AG.
* All rights reserved. This program and the accompanying materials
* 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:
* BSI Business Systems Integration AG - initial API and implementation
*******************************************************************************/
package org.eclipse.scout.rt.ui.rap.window.desktop;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.rap.rwt.lifecycle.WidgetUtil;
import org.eclipse.scout.rt.client.ui.desktop.DesktopEvent;
import org.eclipse.scout.rt.client.ui.desktop.DesktopListener;
import org.eclipse.scout.rt.client.ui.desktop.IDesktop;
import org.eclipse.scout.rt.client.ui.form.IForm;
import org.eclipse.scout.rt.ui.rap.IRwtEnvironment;
import org.eclipse.scout.rt.ui.rap.util.BrowserInfo;
import org.eclipse.scout.rt.ui.rap.util.RwtUtility;
import org.eclipse.scout.rt.ui.rap.window.DefaultFormBoundsProvider;
import org.eclipse.scout.rt.ui.rap.window.IFormBoundsProvider;
import org.eclipse.scout.rt.ui.rap.window.IRwtScoutPart;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
/**
* @author Andreas Hoegger
* @since 3.8.0
*/
public class RwtScoutViewStack extends Composite implements IRwtScoutViewStack {
private static final long serialVersionUID = 1L;
private static final String VARIANT_VIEW_PART = "viewPart";
private static final String VARIANT_VIEW_PART_NO_RADIUS = "viewPartNoRadius";
private static final String VARIANT_VIEW_TAB_AREA = "formTabArea";
private int heightHint = SWT.DEFAULT;
private int widthHint = SWT.DEFAULT;
private IRwtEnvironment m_uiEnvironment;
private HashMap<IForm, RwtScoutDesktopForm> m_openForms;
private ArrayList<RwtScoutDesktopForm> m_formStack;
private Map<IForm, IFormBoundsProvider> m_formBoundsProviders;
private P_DesktopListner m_desktopListener;
private Composite m_tabBar;
private Composite m_container;
public RwtScoutViewStack(Composite parent, IRwtEnvironment uiEnvironment) {
super(parent, SWT.NONE);
m_uiEnvironment = uiEnvironment;
m_openForms = new HashMap<IForm, RwtScoutDesktopForm>();
m_formStack = new ArrayList<RwtScoutDesktopForm>(3);
m_formBoundsProviders = new HashMap<IForm, IFormBoundsProvider>();
addListener(SWT.Resize, new P_ResizeListener());
m_desktopListener = new P_DesktopListner();
getUiEnvironment().getScoutDesktop().addDesktopListener(m_desktopListener);
setData(WidgetUtil.CUSTOM_VARIANT, getVariant());
createContent(this);
}
protected String getVariant() {
BrowserInfo info = RwtUtility.getBrowserInfo();
if (info != null && info.isMozillaFirefox()) {
return VARIANT_VIEW_PART;
}
else {
return VARIANT_VIEW_PART_NO_RADIUS;
}
}
protected void createContent(Composite parent) {
if (isTabBarCreationEnabled()) {
m_tabBar = getUiEnvironment().getFormToolkit().createComposite(parent);
m_tabBar.setData(WidgetUtil.CUSTOM_VARIANT, VARIANT_VIEW_TAB_AREA);
}
m_container = getUiEnvironment().getFormToolkit().createComposite(parent);
// layout
GridLayout layout = new GridLayout(1, true);
layout.horizontalSpacing = 0;
layout.marginHeight = 0;
layout.marginTop = 0;
layout.marginWidth = 0;
layout.verticalSpacing = 0;
parent.setLayout(layout);
if (m_tabBar != null) {
GridData tabBarData = new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL);
tabBarData.exclude = false;
m_tabBar.setLayoutData(tabBarData);
RowLayout tabBarLayout = new RowLayout();
tabBarLayout.marginBottom = 0;
tabBarLayout.marginLeft = 0;
tabBarLayout.marginTop = 0;
m_tabBar.setLayout(tabBarLayout);
}
GridData containerData = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
m_container.setLayoutData(containerData);
StackLayout containerLayout = new StackLayout();
m_container.setLayout(containerLayout);
}
@Override
public IRwtEnvironment getUiEnvironment() {
return m_uiEnvironment;
}
protected Map<IForm, IFormBoundsProvider> getFormBoundsProviders() {
return m_formBoundsProviders;
}
@Override
public IRwtScoutPart addForm(IForm form) {
IFormBoundsProvider formBoundsProvider = createFormBoundsProvider(form, getUiEnvironment());
m_formBoundsProviders.put(form, formBoundsProvider);
initPreferredSize(formBoundsProvider);
RwtScoutDesktopForm ui = createRwtScoutDesktopForm();
ViewStackTabButton button = null;
if (m_tabBar != null) {
button = new ViewStackTabButton(m_tabBar);
button.setLayoutData(new RowData(SWT.DEFAULT, 22));
button.addViewTabListener(new P_ViewTabSelectionListener(ui));
}
ui.createPart(this, m_container, button, form, getUiEnvironment());
m_formStack.add(0, ui);
m_openForms.put(form, ui);
setPartVisibleImpl(form);
return ui;
}
/**
* Creates a new instance of {@link RwtScoutDesktopForm}.
* <p>
* May be overridden to create a custom instance.
*/
protected RwtScoutDesktopForm createRwtScoutDesktopForm() {
return new RwtScoutDesktopForm();
}
protected void initPreferredSize(IFormBoundsProvider boundsProvider) {
if (boundsProvider == null) {
return;
}
Rectangle formBounds = boundsProvider.getBounds();
if (formBounds != null) {
setWidthHint(formBounds.width);
setHeightHint(formBounds.height);
}
else {
setWidthHint(-1);
setHeightHint(-1);
}
}
protected IFormBoundsProvider createFormBoundsProvider(IForm scoutForm, IRwtEnvironment uiEnvironment) {
return new DefaultFormBoundsProvider(scoutForm, uiEnvironment);
}
@Override
public boolean isPartVisible(IRwtScoutPart part) {
//resolve
part = m_openForms.get(part.getScoutObject());
if (part == null) {
return false;
}
StackLayout stackLayout = (StackLayout) m_container.getLayout();
return RwtUtility.isAncestorOf(stackLayout.topControl, part.getUiContainer());
}
@Override
public void setPartVisible(IRwtScoutPart part) {
//resolve
part = m_openForms.get(part.getScoutObject());
if (part == null) {
return;
}
setPartVisibleImpl(part.getScoutObject());
}
private void removeForm(IForm form) {
RwtScoutDesktopForm uiForm = m_openForms.remove(form);
if (uiForm != null) {
m_formStack.remove(uiForm);
IForm topForm = null;
if (m_formStack.size() > 0) {
topForm = m_formStack.get(0).getScoutObject();
}
setPartVisibleImpl(topForm);
}
m_formBoundsProviders.remove(form);
}
protected void setPartVisibleImpl(IForm form) {
RwtScoutDesktopForm uiForm = m_openForms.get(form);
if (uiForm != null) {
StackLayout stackLayout = (StackLayout) m_container.getLayout();
stackLayout.topControl = uiForm.getUiContainer();
if (m_tabBar != null && m_formStack.remove(uiForm)) {
GridData tabBarData = (GridData) m_tabBar.getLayoutData();
if (m_formStack.isEmpty()) {
m_tabBar.setVisible(false);
tabBarData.exclude = true;
}
else {
m_tabBar.setVisible(true);
tabBarData.exclude = false;
for (RwtScoutDesktopForm f : m_formStack) {
f.getTabButton().setActive(false);
}
uiForm.getTabButton().setActive(true);
}
m_formStack.add(0, uiForm);
}
}
getParent().layout(true, true);
}
/**
* Controls whether the tab bar should be created at all. May be overridden.
* <p>
* Default is true.
*/
protected boolean isTabBarCreationEnabled() {
return true;
}
@Override
public boolean getVisible() {
return m_container.getChildren().length > 0;
}
@Override
public int getHeightHint() {
return heightHint;
}
@Override
public void setHeightHint(int heightHint) {
this.heightHint = heightHint;
}
@Override
public int getWidthHint() {
return widthHint;
}
@Override
public void setWidthHint(int widthHint) {
this.widthHint = widthHint;
}
private void handleScoutDesktopEvent(DesktopEvent e) {
switch (e.getType()) {
case DesktopEvent.TYPE_FORM_ENSURE_VISIBLE:
setPartVisibleImpl(e.getForm());
break;
case DesktopEvent.TYPE_FORM_REMOVED:
removeForm(e.getForm());
break;
case DesktopEvent.TYPE_DESKTOP_CLOSED:
handleDesktopClosed(e.getDesktop());
break;
}
}
private void handleDesktopClosed(IDesktop desktop) {
desktop.removeDesktopListener(m_desktopListener);
m_desktopListener = null;
}
private class P_ViewTabSelectionListener implements IViewTabSelectionListener {
private final RwtScoutDesktopForm m_form;
public P_ViewTabSelectionListener(RwtScoutDesktopForm form) {
m_form = form;
}
@Override
public void handleEvent(ViewTabSelectionEvent event) {
if (event.getEventType() == ViewTabSelectionEvent.TYPE_VIEW_TAB_SELECTION) {
Runnable job = new Runnable() {
@Override
public void run() {
m_form.getScoutObject().getUIFacade().fireFormActivatedFromUI();
}
};
getUiEnvironment().invokeScoutLater(job, 0);
setPartVisibleImpl(m_form.getScoutObject());
}
else if (event.getEventType() == ViewTabSelectionEvent.TYPE_VIEW_TAB_CLOSE_SELECTION) {
Runnable job = new Runnable() {
@Override
public void run() {
m_form.getScoutObject().getUIFacade().fireFormClosingFromUI();
}
};
getUiEnvironment().invokeScoutLater(job, 0);
}
}
} // end class P_ViewTabSelectionListener
private class P_DesktopListner implements DesktopListener {
@Override
public void desktopChanged(final DesktopEvent e) {
if (getUiEnvironment().getDisplay() != null && !getUiEnvironment().getDisplay().isDisposed()) {
Runnable t = new Runnable() {
@Override
public void run() {
handleScoutDesktopEvent(e);
}
};
getUiEnvironment().invokeUiLater(t);
}
}
}
private class P_ResizeListener implements Listener {
private static final long serialVersionUID = 1L;
@Override
public void handleEvent(Event event) {
if (event.type == SWT.Resize) {
handleResized();
}
}
private void handleResized() {
if (isDisposed() || m_formBoundsProviders.isEmpty()) {
return;
}
for (IFormBoundsProvider formBoundsProvider : m_formBoundsProviders.values()) {
formBoundsProvider.storeBounds(getBounds());
}
}
}
}