/******************************************************************************* * Copyright (c) 2014 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 com.eclipsesource.tabris.widgets.enhancement; import static com.eclipsesource.tabris.internal.Clauses.whenNull; import static com.eclipsesource.tabris.internal.Constants.EVENT_REFRESH; import static com.eclipsesource.tabris.internal.Constants.METHOD_DONE; import static com.eclipsesource.tabris.internal.Constants.PROPERTY_MESSAGE; import static com.eclipsesource.tabris.internal.Constants.PROPERTY_WIDGET; import static com.eclipsesource.tabris.internal.Constants.TYPE_REFRESH_HANDLER; import java.util.ArrayList; import java.util.List; import org.eclipse.rap.json.JsonObject; import org.eclipse.rap.json.JsonValue; import org.eclipse.rap.rwt.RWT; import org.eclipse.rap.rwt.internal.lifecycle.ProcessActionRunner; import org.eclipse.rap.rwt.internal.lifecycle.WidgetUtil; import org.eclipse.rap.rwt.remote.AbstractOperationHandler; import org.eclipse.rap.rwt.remote.RemoteObject; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.Widget; import com.eclipsesource.tabris.widgets.RefreshListener; /** * <p> * A {@link RefreshHandler} can be added to a {@link Tree} using a {@link TreeDecorator}. You can use the handler to * define the refresh behavior by e.g. setting a message or calling the refresh done. Clients will use native refresh * facilities e.g. pull down. * </p> * * @see TreeDecorator * * @since 1.4 */ @SuppressWarnings("restriction") public class RefreshHandler { private final List<RefreshListener> listeners; private final RemoteObject remoteObject; private String message; public RefreshHandler() { listeners = new ArrayList<RefreshListener>(); remoteObject = RWT.getUISession().getConnection().createRemoteObject( TYPE_REFRESH_HANDLER ); remoteObject.setHandler( new RefreshHandlerOperator() ); } /** * <p> * Sets the message the client should show during a refresh. * </p> * * @param message the message to show. Must not be <code>null</code>. */ public void setMessage( String message ) { whenNull( message ).throwIllegalArgument( "Message must not be null" ); remoteObject.set( PROPERTY_MESSAGE, JsonValue.valueOf( message ) ); this.message = message; } public String getMessage() { return message; } /** * <p> * Adds a {@link RefreshListener} that will be notified when the user has triggered a refresh. After the refresh * is done you need to call {@link RefreshHandler#done()} to hide the refresh UI on the client. * </p> * * @param listener the listener to add. Must not be <code>null</code>. */ public void addRefreshListener( RefreshListener listener ) { whenNull( listener ).throwIllegalArgument( "RefreshListener must not be null" ); listeners.add( listener ); if( listeners.size() == 1 ) { remoteObject.listen( EVENT_REFRESH, true ); } } /** * <p> * Removes a {@link RefreshListener}. * </p> * * @param listener the listener to remove. Must not be <code>null</code>. */ public void removeRefreshListener( RefreshListener listener ) { whenNull( listener ).throwIllegalArgument( "RefreshListener must not be null" ); listeners.remove( listener ); if( listeners.isEmpty() ) { remoteObject.listen( EVENT_REFRESH, false ); } } /** * <p> * Returns the added {@link RefreshListener}s * </p> */ public List<RefreshListener> getRefreshListeners() { return new ArrayList<RefreshListener>( listeners ); } /** * <p> * Instructs a client to hide it's refresh UI. Usually this method will be called within a * {@link RefreshListener#refresh()} method after the refreshing is done. * </p> */ public void done() { remoteObject.call( METHOD_DONE, null ); } private class RefreshHandlerOperator extends AbstractOperationHandler { @Override public void handleNotify( String event, JsonObject properties ) { if( EVENT_REFRESH.equals( event ) ) { notifyRefreshListeners(); } } } private void notifyRefreshListeners() { ProcessActionRunner.add( new Runnable() { @Override public void run() { List<RefreshListener> refreshListeners = getRefreshListeners(); for( RefreshListener refreshListener : refreshListeners ) { refreshListener.refresh(); } } } ); } void hookToWidget( Widget widget ) { remoteObject.set( PROPERTY_WIDGET, WidgetUtil.getId( widget ) ); } String getId() { return remoteObject.getId(); } }