blob: 734c0185d9a85bfadc5486416ad98bf5846da9dc [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2002, 2012 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.lifecycle.WidgetLCAUtil.preserveListener;
import static org.eclipse.rap.rwt.lifecycle.WidgetLCAUtil.preserveProperty;
import static org.eclipse.rap.rwt.lifecycle.WidgetLCAUtil.renderListener;
import static org.eclipse.rap.rwt.lifecycle.WidgetLCAUtil.renderProperty;
import static org.eclipse.rap.rwt.lifecycle.WidgetUtil.getId;
import java.io.IOException;
import org.eclipse.rap.rwt.internal.protocol.ClientMessageConst;
import org.eclipse.rap.rwt.internal.protocol.ClientObjectFactory;
import org.eclipse.rap.rwt.internal.protocol.IClientObject;
import org.eclipse.rap.rwt.internal.protocol.ProtocolUtil;
import org.eclipse.rap.rwt.lifecycle.AbstractWidgetLCA;
import org.eclipse.rap.rwt.lifecycle.ControlLCAUtil;
import org.eclipse.rap.rwt.lifecycle.IWidgetAdapter;
import org.eclipse.rap.rwt.lifecycle.WidgetLCAUtil;
import org.eclipse.rap.rwt.lifecycle.WidgetUtil;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.internal.widgets.IDisplayAdapter;
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;
import org.eclipse.swt.widgets.Widget;
public final class ShellLCA extends AbstractWidgetLCA {
private static final String TYPE = "rwt.widgets.Shell";
private static final String[] ALLOWED_STYLES = new String[] {
"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";
static final String PROP_SHELL_LISTENER = "shell";
static final String PROP_RESIZE_LISTENER = "Resize";
static final String PROP_MOVE_LISTENER = "Move";
private static final String PROP_DEFAULT_BUTTON = "defaultButton";
@Override
public void preserveValues( Widget widget ) {
Shell shell = ( Shell )widget;
ControlLCAUtil.preserveValues( shell );
WidgetLCAUtil.preserveCustomVariant( 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, new Integer( 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() );
preserveListener( shell, PROP_SHELL_LISTENER, hasShellListener( shell ) );
}
public void readData( Widget widget ) {
Shell shell = ( Shell )widget;
// [if] Preserve the menu bounds before setting the new shell bounds.
preserveMenuBounds( shell );
// Important: Order matters, readMode() before readBounds()
readMode( shell );
readBounds( shell );
if( WidgetLCAUtil.wasEventSent( shell, ClientMessageConst.EVENT_SHELL_CLOSED ) ) {
shell.close();
}
processActiveShell( shell );
ControlLCAUtil.processEvents( shell );
ControlLCAUtil.processKeyEvents( shell );
ControlLCAUtil.processMenuDetect( shell );
WidgetLCAUtil.processHelp( shell );
}
@Override
public void renderInitialization( Widget widget ) throws IOException {
Shell shell = ( Shell )widget;
IClientObject clientObject = ClientObjectFactory.getClientObject( shell );
clientObject.create( TYPE );
clientObject.set( "style", WidgetLCAUtil.getStyles( shell, ALLOWED_STYLES ) );
Composite parent = shell.getParent();
if( parent instanceof Shell ) {
clientObject.set( "parentShell", WidgetUtil.getId( parent ) );
}
// TODO [tb] : These should be rendered only when there is an actual listener attached:
clientObject.listen( PROP_MOVE_LISTENER, true );
clientObject.listen( PROP_RESIZE_LISTENER, true );
}
@Override
public void renderChanges( Widget widget ) throws IOException {
Shell shell = ( Shell )widget;
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 );
renderListenShell( shell );
}
@Override
public void renderDispose( Widget widget ) throws IOException {
IClientObject clientObject = ClientObjectFactory.getClientObject( widget );
clientObject.destroy();
}
//////////////////
// Helping methods
private static void renderText( Shell shell ) {
renderProperty( shell, PROP_TEXT, shell.getText(), "" );
}
private void renderAlpha( Shell shell ) {
renderProperty( shell, PROP_ALPHA, new Integer( shell.getAlpha() ), new Integer( 0xFF ) );
}
private static void renderMinimumSize( Shell shell ) {
Point newValue = shell.getMinimumSize();
if( WidgetLCAUtil.hasChanged( shell, PROP_MINIMUM_SIZE, newValue ) ) {
IClientObject clientObject = ClientObjectFactory.getClientObject( shell );
clientObject.set( "minimumSize", new int[]{ newValue.x, newValue.y } );
}
}
private static void renderDefaultButton( Shell shell ) {
Button defaultButton = shell.getDefaultButton();
if( WidgetLCAUtil.hasChanged( shell, PROP_DEFAULT_BUTTON, defaultButton, null ) ) {
IClientObject clientObject = ClientObjectFactory.getClientObject( shell );
String defaultButtonId = null;
if( defaultButton != null ) {
defaultButtonId = WidgetUtil.getId( defaultButton );
}
clientObject.set( "defaultButton", defaultButtonId );
}
}
/////////////////////////////////////////////
// Methods to read and write the active shell
private static void renderActiveShell( Shell shell ) {
Shell activeShell = shell.getDisplay().getActiveShell();
boolean hasChanged = WidgetLCAUtil.hasChanged( shell, PROP_ACTIVE_SHELL, activeShell, null );
if( shell == activeShell && hasChanged ) {
IClientObject clientObject = ClientObjectFactory.getClientObject( shell );
clientObject.set( "active", true );
}
}
private static void processActiveShell( Shell shell ) {
if( WidgetLCAUtil.wasEventSent( shell, ClientMessageConst.EVENT_SHELL_ACTIVATED ) ) {
IDisplayAdapter displayAdapter = shell.getDisplay().getAdapter( IDisplayAdapter.class );
displayAdapter.setActiveShell( shell );
}
}
private static void renderActiveControl( Shell shell ) {
final Control activeControl = getActiveControl( shell );
String prop = PROP_ACTIVE_CONTROL;
if( WidgetLCAUtil.hasChanged( shell, prop, activeControl, null ) ) {
String activeControlId = null;
if( activeControl != null ) {
activeControlId = WidgetUtil.getId( activeControl );
}
IClientObject clientObject = ClientObjectFactory.getClientObject( shell );
clientObject.set( "activeControl", activeControlId );
}
}
private static Control getActiveControl( Shell shell ) {
IShellAdapter shellAdapter = shell.getAdapter( IShellAdapter.class );
Control activeControl = shellAdapter.getActiveControl();
return activeControl;
}
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 readBounds( Shell shell ) {
Rectangle bounds = ProtocolUtil.readPropertyValueAsRectangle( getId( shell ), "bounds" );
if( bounds != null ) {
IShellAdapter shellAdapter = shell.getAdapter( IShellAdapter.class );
shellAdapter.setBounds( bounds );
}
}
private static void readMode( Shell shell ) {
final String value = WidgetLCAUtil.readPropertyValue( shell, "mode" );
if( value != null ) {
if( "maximized".equals( value ) ) {
shell.setMaximized( true );
} else if( "minimized".equals( value ) ) {
shell.setMinimized( true );
} else {
shell.setMinimized( false );
shell.setMaximized( false );
}
}
}
private static void renderMode( Shell shell ) {
Object defValue = null;
Object newValue = getMode( shell );
if( WidgetLCAUtil.hasChanged( shell, PROP_MODE, newValue, defValue ) ) {
IClientObject clientObject = ClientObjectFactory.getClientObject( shell );
clientObject.set( "mode", newValue );
}
}
private static void renderListenShell( Shell shell ) {
// Note that "shell" events include "activate", "deactivate" and "close" events.
// "shellActivated" is sent the client in any case, event without listener.
// "Shell_close" events are also always being sent, but with a listener the shell is not closed
// by the client itself but by the server. Also, the "shellActivated" events are different from #
// the "activeControl" property and "controlActivated" event (also sent by the shell and
// processed in ShellLCA#processActivate).
// The listener property for this event is rendered by ControlLCAUtil#renderActivateListener
boolean newValue = hasShellListener( shell );
renderListener( shell, PROP_SHELL_LISTENER, newValue, false );
}
private static boolean hasShellListener( Shell shell ) {
return shell.isListening( SWT.Close )
|| shell.isListening( SWT.Activate )
|| shell.isListening( SWT.Deactivate );
}
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 );
Rectangle menuBounds = shellAdapter.getMenuBounds();
IWidgetAdapter widgetAdapter = WidgetUtil.getAdapter( menuBar );
widgetAdapter.preserve( Props.BOUNDS, menuBounds );
}
}
}