/******************************************************************************* * Copyright (c) 2002, 2015 Innoopract Informationssysteme GmbH and others. * 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: * Innoopract Informationssysteme GmbH - initial API and implementation * EclipseSource - ongoing development ******************************************************************************/ package org.eclipse.swt.internal.widgets.shellkit; import static org.eclipse.rap.rwt.internal.protocol.JsonUtil.createJsonArray; import static org.eclipse.rap.rwt.internal.protocol.RemoteObjectFactory.createRemoteObject; import static org.eclipse.rap.rwt.internal.protocol.RemoteObjectFactory.getRemoteObject; import static org.eclipse.rap.rwt.internal.lifecycle.WidgetLCAUtil.getStyles; import static org.eclipse.rap.rwt.internal.lifecycle.WidgetLCAUtil.hasChanged; import static org.eclipse.rap.rwt.internal.lifecycle.WidgetLCAUtil.preserveProperty; import static org.eclipse.rap.rwt.internal.lifecycle.WidgetLCAUtil.renderProperty; import static org.eclipse.rap.rwt.internal.lifecycle.WidgetUtil.getAdapter; import static org.eclipse.rap.rwt.internal.lifecycle.WidgetUtil.getId; import java.io.IOException; import org.eclipse.rap.json.JsonArray; import org.eclipse.rap.rwt.internal.lifecycle.WidgetLCA; import org.eclipse.rap.rwt.internal.lifecycle.ControlLCAUtil; import org.eclipse.rap.rwt.internal.lifecycle.WidgetLCAUtil; import org.eclipse.rap.rwt.internal.lifecycle.WidgetUtil; import org.eclipse.rap.rwt.remote.RemoteObject; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.internal.widgets.IShellAdapter; import org.eclipse.swt.internal.widgets.Props; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Shell; public final class ShellLCA extends WidgetLCA<Shell> { public static final ShellLCA INSTANCE = new ShellLCA(); private static final String TYPE = "rwt.widgets.Shell"; private static final String[] ALLOWED_STYLES = { "CLOSE", "MIN", "MAX", "NO_TRIM", "RESIZE", "TITLE", "ON_TOP", "TOOL", "SHEET", "APPLICATION_MODAL", "MODELESS", "PRIMARY_MODAL", "SYSTEM_MODAL", "BORDER" }; private static final String PROP_TEXT = "text"; private static final String PROP_IMAGE = "image"; private static final String PROP_ALPHA = "alpha"; static final String PROP_ACTIVE_CONTROL = "activeControl"; static final String PROP_ACTIVE_SHELL = "activeShell"; static final String PROP_MODE = "mode"; static final String PROP_FULLSCREEN = "fullScreen"; static final String PROP_MINIMUM_SIZE = "minimumSize"; private static final String PROP_ACTIVATE_LISTENER = "Activate"; private static final String PROP_CLOSE_LISTENER = "Close"; private static final String PROP_RESIZE_LISTENER = "Resize"; private static final String PROP_MOVE_LISTENER = "Move"; private static final String PROP_DEFAULT_BUTTON = "defaultButton"; @Override public void preserveValues( Shell shell ) { preserveProperty( shell, PROP_ACTIVE_CONTROL, getActiveControl( shell ) ); preserveProperty( shell, PROP_ACTIVE_SHELL, shell.getDisplay().getActiveShell() ); preserveProperty( shell, PROP_TEXT, shell.getText() ); preserveProperty( shell, PROP_IMAGE, shell.getImage() ); preserveProperty( shell, PROP_ALPHA, Integer.valueOf( shell.getAlpha() ) ); preserveProperty( shell, PROP_MODE, getMode( shell ) ); preserveProperty( shell, PROP_FULLSCREEN, Boolean.valueOf( shell.getFullScreen() ) ); preserveProperty( shell, PROP_MINIMUM_SIZE, shell.getMinimumSize() ); preserveProperty( shell, PROP_DEFAULT_BUTTON, shell.getDefaultButton() ); } @Override public void readData( Shell shell ) { // [if] Preserve the menu bounds before setting the new shell bounds. preserveMenuBounds( shell ); super.readData( shell ); } @Override public void renderInitialization( Shell shell ) throws IOException { RemoteObject remoteObject = createRemoteObject( shell, TYPE ); remoteObject.setHandler( new ShellOperationHandler( shell ) ); remoteObject.set( "style", createJsonArray( getStyles( shell, ALLOWED_STYLES ) ) ); Composite parent = shell.getParent(); if( parent instanceof Shell ) { remoteObject.set( "parentShell", getId( parent ) ); } // TODO [tb] : These should be rendered only when there is an actual listener attached: remoteObject.listen( PROP_MOVE_LISTENER, true ); remoteObject.listen( PROP_RESIZE_LISTENER, true ); // Always listen for "Activate" and "Close" events. Client send these events regardless // listeners attached remoteObject.listen( PROP_ACTIVATE_LISTENER, true ); remoteObject.listen( PROP_CLOSE_LISTENER, true ); } @Override public void renderChanges( Shell shell ) throws IOException { WidgetLCAUtil.renderCustomVariant( shell ); // Order matters for animation renderImage( shell ); renderText( shell ); renderAlpha( shell ); renderActiveShell( shell ); renderMode( shell ); renderMinimumSize( shell ); renderDefaultButton( shell ); renderActiveControl( shell ); ControlLCAUtil.renderChanges( shell ); } @Override public void renderDispose( Shell shell ) throws IOException { getRemoteObject( shell ).destroy(); } ////////////////// // Helping methods private static void renderText( Shell shell ) { renderProperty( shell, PROP_TEXT, shell.getText(), "" ); } private static void renderAlpha( Shell shell ) { renderProperty( shell, PROP_ALPHA, shell.getAlpha(), 0xFF ); } private static void renderMinimumSize( Shell shell ) { Point newValue = shell.getMinimumSize(); if( hasChanged( shell, PROP_MINIMUM_SIZE, newValue ) ) { RemoteObject remoteObject = getRemoteObject( shell ); remoteObject.set( "minimumSize", new JsonArray().add( newValue.x ).add( newValue.y ) ); } } private static void renderDefaultButton( Shell shell ) { Button defaultButton = shell.getDefaultButton(); if( hasChanged( shell, PROP_DEFAULT_BUTTON, defaultButton, null ) ) { String defaultButtonId = null; if( defaultButton != null ) { defaultButtonId = WidgetUtil.getId( defaultButton ); } getRemoteObject( shell ).set( "defaultButton", defaultButtonId ); } } ///////////////////////////////////////////// // Methods to read and write the active shell private static void renderActiveShell( Shell shell ) { Shell activeShell = shell.getDisplay().getActiveShell(); boolean hasChanged = hasChanged( shell, PROP_ACTIVE_SHELL, activeShell, null ); if( shell == activeShell && hasChanged ) { getRemoteObject( shell ).set( "active", true ); } } private static void renderActiveControl( Shell shell ) { final Control activeControl = getActiveControl( shell ); if( hasChanged( shell, PROP_ACTIVE_CONTROL, activeControl, null ) ) { String activeControlId = null; if( activeControl != null ) { activeControlId = getId( activeControl ); } getRemoteObject( shell ).set( "activeControl", activeControlId ); } } private static void renderImage( Shell shell ) { if( ( shell.getStyle() & SWT.TITLE ) != 0 ) { Image image = shell.getImage(); if( image == null ) { Image[] defaultImages = shell.getImages(); if( defaultImages.length > 0 ) { image = defaultImages[0]; } } renderProperty( shell, PROP_IMAGE, image, null ); } } private static void renderMode( Shell shell ) { renderProperty( shell, PROP_MODE, getMode( shell), null ); } private static Control getActiveControl( Shell shell ) { return shell.getAdapter( IShellAdapter.class ).getActiveControl(); } private static String getMode( Shell shell ) { String result = null; if( shell.getMinimized() ) { result = "minimized"; } else if( shell.getFullScreen() ) { result = "fullscreen"; } else if( shell.getMaximized() ) { result = "maximized"; } return result; } private static void preserveMenuBounds( Shell shell ) { Menu menuBar = shell.getMenuBar(); if( menuBar != null ) { IShellAdapter shellAdapter = shell.getAdapter( IShellAdapter.class ); getAdapter( menuBar ).preserve( Props.BOUNDS, shellAdapter.getMenuBounds() ); } } private ShellLCA() { // prevent instantiation } }