/** * This file is part of ObjectFabric (http://objectfabric.org). * * ObjectFabric is licensed under the Apache License, Version 2.0, the terms * of which may be found at http://www.apache.org/licenses/LICENSE-2.0.html. * * Copyright ObjectFabric Inc. * * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ package examples.client; import org.objectfabric.AbstractKeyListener; import org.objectfabric.AsyncCallback; import org.objectfabric.GWTWorkspace; import org.objectfabric.IndexListener; import org.objectfabric.IndexedDB; import org.objectfabric.Remote; import org.objectfabric.Resource; import org.objectfabric.TArrayDouble; import org.objectfabric.TSet; import org.objectfabric.WebSocket; import org.objectfabric.Workspace; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.MouseDownEvent; import com.google.gwt.event.dom.client.MouseDownHandler; import com.google.gwt.event.dom.client.MouseMoveEvent; import com.google.gwt.event.dom.client.MouseMoveHandler; import com.google.gwt.event.dom.client.MouseUpEvent; import com.google.gwt.event.dom.client.MouseUpHandler; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Random; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.Widget; /** * This client is designed to connect to the Java version of the Images demo. First launch * /objectfabric.examples/samples/images/generator/Main.java, then this Web application. */ @SuppressWarnings("unchecked") public class Main implements EntryPoint { private TSet<TArrayDouble> positions; private Button button; private boolean _dragging; private int _left, _top; public void onModuleLoad() { Workspace workspace = new GWTWorkspace(); if (WebSocket.isSupported()) workspace.addURIHandler(new WebSocket()); // else // TODO // workspace.addURIHandler(new CometURIHandler()); if (IndexedDB.isSupported()) workspace.addCache(new IndexedDB()); workspace.openAsync("ws://localhost:8888/images", new AsyncCallback<Resource>() { @Override public void onSuccess(Resource result) { positions = (TSet<TArrayDouble>) result.get(); onReceivedImages(); } @Override public void onFailure(Exception e) { } }); button = new Button("New Image"); button.setWidth("200px"); button.setEnabled(false); RootPanel.get().add(button, 20, 100); button.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { TArrayDouble position = new TArrayDouble(positions.resource(), 2); position.set(0, Random.nextInt(100) + 50); position.set(1, Random.nextInt(100) + 50); positions.add(position); } }); } private void onReceivedImages() { button.setEnabled(true); /* * Register a listener on the shared object to be notified when an ImageInfo is * shared. When this happen, add an image to the UI. */ positions.addListener(new AbstractKeyListener<TArrayDouble>() { @Override public void onPut(TArrayDouble key) { addImage(key); } }); /* * Some images might already be shared, show them. Iterators on transactional * collections provide a stable view of the collection. */ positions.atomicRead(new Runnable() { public void run() { for (TArrayDouble position : positions) addImage(position); } }); final Image disconnected = new Image("sync-disconnected-24.png"); final Image ongoing = new Image("sync-24.gif"); final Image complete = new Image("sync-complete-24.png"); final Label label = new Label(); RootPanel.get().add(disconnected, 20, 130); RootPanel.get().add(ongoing, 20, 130); RootPanel.get().add(complete, 20, 130); RootPanel.get().add(label, 50, 130); new Timer() { @Override public void run() { disconnected.setVisible(false); ongoing.setVisible(false); complete.setVisible(false); switch (((Remote) positions.resource().origin()).status()) { case DISCONNECTED: disconnected.setVisible(true); label.setText("Disconnected"); break; case CONNECTING: ongoing.setVisible(true); label.setText("Connecting..."); break; case WAITING_RETRY: disconnected.setVisible(true); label.setText("Waiting retry..."); break; case SYNCHRONIZING: ongoing.setVisible(true); label.setText("Synchronizing..."); break; case UP_TO_DATE: complete.setVisible(true); label.setText("Up to date"); break; } } }.scheduleRepeating(100); } private void addImage(final TArrayDouble position) { final Image image = new Image("image.png"); RootPanel.get().add(image, (int) position.get(0), (int) position.get(1)); // Listen to image info events position.addListener(new IndexListener() { public void onSet(int i) { RootPanel.get().setWidgetPosition(image, (int) position.get(0), (int) position.get(1)); } }); // Listen to image mouse events image.addMouseDownHandler(new MouseDownHandler() { public void onMouseDown(MouseDownEvent event) { DOM.setCapture(((Widget) event.getSource()).getElement()); _left = event.getX(); _top = event.getY(); _dragging = true; // Prevent browser from starting a drag and drop (E.g. Chrome) event.preventDefault(); } }); image.addMouseMoveHandler(new MouseMoveHandler() { public void onMouseMove(MouseMoveEvent event) { if (_dragging) { // convert from local to global coordinates int xAbs = event.getX() + ((Widget) event.getSource()).getAbsoluteLeft(); int yAbs = event.getY() + ((Widget) event.getSource()).getAbsoluteTop(); if ((int) position.get(0) != xAbs - _left || (int) position.get(1) != yAbs - _top) { position.set(0, xAbs - _left); position.set(1, yAbs - _top); } } } }); image.addMouseUpHandler(new MouseUpHandler() { public void onMouseUp(MouseUpEvent event) { DOM.releaseCapture(((Widget) event.getSource()).getElement()); _dragging = false; } }); } }