/*******************************************************************************
* Copyright (c) 2014, 2015 EclipseSource 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:
* EclipseSource - initial API and implementation
******************************************************************************/
package org.eclipse.swt.internal.widgets.displaykit;
import static org.eclipse.rap.rwt.internal.protocol.ClientMessageConst.EVENT_RESIZE;
import org.eclipse.rap.json.JsonArray;
import org.eclipse.rap.json.JsonObject;
import org.eclipse.rap.json.JsonValue;
import org.eclipse.rap.rwt.internal.lifecycle.WidgetUtil;
import org.eclipse.rap.rwt.remote.AbstractOperationHandler;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.internal.events.EventUtil;
import org.eclipse.swt.internal.widgets.IDisplayAdapter;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Widget;
public class DisplayOperationHandler extends AbstractOperationHandler {
private static final String PROP_BOUNDS = "bounds";
private static final String PROP_CURSOR_LOCATION = "cursorLocation";
private static final String PROP_FOCUS_CONTROL = "focusControl";
private final Display display;
public DisplayOperationHandler( Display display ) {
this.display = display;
}
@Override
public void handleSet( JsonObject properties ) {
handleSetBounds( display, properties );
handleSetCursorLocation( display, properties );
handleSetFocusControl( display, properties );
}
@Override
public void handleNotify( String eventName, JsonObject properties ) {
if( EVENT_RESIZE.equals( eventName ) ) {
handleNotifyResize( display );
}
}
/*
* PROTOCOL SET bounds
*
* @param bounds ([int]) the display bounds
*/
public void handleSetBounds( Display display, JsonObject properties ) {
JsonValue value = properties.get( PROP_BOUNDS );
if( value != null ) {
JsonArray arrayValue = value.asArray();
Rectangle bounds = new Rectangle( arrayValue.get( 0 ).asInt(),
arrayValue.get( 1 ).asInt(),
arrayValue.get( 2 ).asInt(),
arrayValue.get( 3 ).asInt() );
getDisplayAdapter( display ).setBounds( bounds );
}
}
/*
* PROTOCOL SET cursorLocation
*
* @param cursorLocation ([int]) the cursor location
*/
public void handleSetCursorLocation( Display display, JsonObject properties ) {
JsonValue value = properties.get( PROP_CURSOR_LOCATION );
if( value != null ) {
JsonArray arrayValue = value.asArray();
Point location = new Point( arrayValue.get( 0 ).asInt(), arrayValue.get( 1 ).asInt() );
getDisplayAdapter( display ).setCursorLocation( location.x, location.y );
}
}
/*
* PROTOCOL SET focusControl
*
* @param focusControl (string) the id of focused control
*/
public void handleSetFocusControl( Display display, JsonObject properties ) {
JsonValue value = properties.get( PROP_FOCUS_CONTROL );
// Even though the loop below would anyway result in focusControl == null
// the client may send 'null' to indicate that no control on the active
// shell currently has the input focus.
if( value != null && !value.isNull() ) {
String id = value.asString();
Control focusControl = null;
// TODO [rh] revise this: traversing the widget tree once more only to find
// out which control is focused. Could that be optimized?
Shell[] shells = getDisplayAdapter( display ).getShells();
for( int i = 0; focusControl == null && i < shells.length; i++ ) {
Widget widget = WidgetUtil.find( shells[ i ], id );
if( widget instanceof Control ) {
focusControl = ( Control )widget;
}
}
if( focusControl != null && EventUtil.isAccessible( focusControl ) ) {
getDisplayAdapter( display ).setFocusControl( focusControl, false );
}
}
}
/*
* PROTOCOL NOTIFY Resize
*/
public void handleNotifyResize( Display display ) {
Event event = new Event();
event.display = display;
event.type = SWT.Resize;
event.time = EventUtil.getLastEventTime();
event.setBounds( display.getBounds() );
getDisplayAdapter( display ).notifyListeners( SWT.Resize, event );
}
private static IDisplayAdapter getDisplayAdapter( Display display ) {
return display.getAdapter( IDisplayAdapter.class );
}
}