simplify map listener handling

This commit is contained in:
Hannes Janetzek 2013-11-01 17:58:37 +01:00
parent 0b880e0f0c
commit 1d6bdcb0f2
13 changed files with 73 additions and 190 deletions

View File

@ -218,7 +218,7 @@ public class MapView extends RelativeLayout {
mPausing = false;
}
AndroidMotionEvent mMotionEvent = new AndroidMotionEvent(this);
AndroidMotionEvent mMotionEvent = new AndroidMotionEvent();
@Override
public boolean onTouchEvent(android.view.MotionEvent motionEvent) {

View File

@ -18,15 +18,6 @@ import org.oscim.event.MotionEvent;
public class AndroidMotionEvent extends MotionEvent {
/**
*
*/
private static final long serialVersionUID = 1L;
public AndroidMotionEvent(Object source) {
super(source);
}
android.view.MotionEvent mEvent;
public void wrap(android.view.MotionEvent e) {

View File

@ -6,12 +6,6 @@ import com.badlogic.gdx.InputProcessor;
public class GdxMotionEvent extends MotionEvent implements InputProcessor {
private static final long serialVersionUID = 1L;
public GdxMotionEvent(Object source) {
super(source);
}
@Override
public int getAction() {
return 0;

View File

@ -1,19 +0,0 @@
package org.oscim.event;
import java.util.ArrayList;
import java.util.List;
public abstract class Dispatcher<T> {
protected List<T> listeners = new ArrayList<T>();
public void addListener(T l) {
if (!listeners.contains(l))
listeners.add(l);
}
public void removeListener(T l) {
listeners.remove(l);
}
public abstract void dispatch();
}

View File

@ -1,8 +0,0 @@
package org.oscim.event;
public interface EventDispatcher {
public void addListener(String type, EventListener listener);
public void removeListener(String type, EventListener listener);
}

View File

@ -1,5 +0,0 @@
package org.oscim.event;
public interface EventListener {
public void handleEvent(MapEvent event);
}

View File

@ -1,5 +0,0 @@
package org.oscim.event;
public interface IListener {
}

View File

@ -1,25 +0,0 @@
/*
* Copyright 2013
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.event;
public class KeyEvent extends MapEvent {
private static final long serialVersionUID = 1L;
public KeyEvent(Object source) {
super(source);
}
}

View File

@ -1,12 +0,0 @@
package org.oscim.event;
import java.util.EventObject;
public class MapEvent extends EventObject {
private static final long serialVersionUID = 1L;
public MapEvent(Object source) {
super(source);
}
}

View File

@ -14,16 +14,10 @@
*/
package org.oscim.event;
public abstract class MotionEvent extends MapEvent {
private static final long serialVersionUID = 1L;
public abstract class MotionEvent {
public static final String TYPE = "MotionEvent";
public MotionEvent(Object source) {
super(source);
}
public static final int ACTION_DOWN = 0;
public static final int ACTION_UP = 1;
public static final int ACTION_MOVE = 2;

View File

@ -15,8 +15,6 @@
package org.oscim.layers;
import org.oscim.core.Tile;
import org.oscim.event.EventListener;
import org.oscim.event.MapEvent;
import org.oscim.event.MotionEvent;
import org.oscim.map.Map;
import org.oscim.map.Viewport;
@ -33,7 +31,7 @@ import org.slf4j.LoggerFactory;
* http://en.wikipedia.org/wiki/Viterbi_algorithm
*/
public class MapEventLayer extends Layer implements EventListener {
public class MapEventLayer extends Layer implements Map.InputListener {
private static final boolean debug = false;
static final Logger log = LoggerFactory.getLogger(MapEventLayer.class);
@ -68,24 +66,15 @@ public class MapEventLayer extends Layer implements EventListener {
public MapEventLayer(Map map) {
super(map);
map.addListener(MotionEvent.TYPE, this);
mMapPosition = map.getViewport();
mTracker = new VelocityTracker();
}
@Override
public void onDetach() {
mMap.removeListener(MotionEvent.TYPE, this);
public void onMotionEvent(MotionEvent event) {
onTouchEvent(event);
}
@Override
public void handleEvent(MapEvent event) {
if (event instanceof MotionEvent)
onTouchEvent((MotionEvent) event);
}
//private long mPrevTime;
private boolean mEnableRotation = true;
private boolean mEnableTilt = true;
private boolean mEnableMove = true;
@ -111,11 +100,8 @@ public class MapEventLayer extends Layer implements EventListener {
mEnableZoom = enable;
}
//@Override
public boolean onTouchEvent(MotionEvent e) {
//mPrevTime = e.getTime();
int action = getAction(e);
if (action == MotionEvent.ACTION_DOWN) {

View File

@ -15,8 +15,6 @@
package org.oscim.layers.tile.vector.labeling;
import org.oscim.core.MapPosition;
import org.oscim.event.EventListener;
import org.oscim.event.MapEvent;
import org.oscim.event.MotionEvent;
import org.oscim.layers.Layer;
import org.oscim.map.Map;
@ -24,7 +22,7 @@ import org.oscim.tiling.TileRenderer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LabelLayer extends Layer implements EventListener, Map.UpdateListener {
public class LabelLayer extends Layer implements Map.InputListener, Map.UpdateListener {
static final Logger log = LoggerFactory.getLogger(LabelLayer.class);
private final TextRenderer mTextRenderer;
@ -33,8 +31,6 @@ public class LabelLayer extends Layer implements EventListener, Map.UpdateListen
public LabelLayer(Map map, TileRenderer tileRenderLayer) {
super(map);
map.addListener(MotionEvent.TYPE, this);
//mTextLayer = new org.oscim.renderer.layers.TextRenderLayer(map, tileRenderLayer);
mTextRenderer = new TextRenderer(map, tileRenderLayer);
mRenderer = mTextRenderer;
@ -42,8 +38,6 @@ public class LabelLayer extends Layer implements EventListener, Map.UpdateListen
@Override
public void onDetach() {
mMap.removeListener(MotionEvent.TYPE, this);
// TODO stop and clear labeling thread
log.debug("DETACH");
mTextRenderer.clearLabels();
@ -52,23 +46,19 @@ public class LabelLayer extends Layer implements EventListener, Map.UpdateListen
}
@Override
public void handleEvent(MapEvent event) {
if (event instanceof MotionEvent) {
MotionEvent e = (MotionEvent) event;
int action = e.getAction() & MotionEvent.ACTION_MASK;
if (action == MotionEvent.ACTION_POINTER_DOWN) {
multi++;
mTextRenderer.hold(true);
} else if (action == MotionEvent.ACTION_POINTER_UP) {
multi--;
if (multi == 0)
mTextRenderer.hold(false);
} else if (action == MotionEvent.ACTION_CANCEL) {
multi = 0;
log.debug("cancel " + multi);
public void onMotionEvent(MotionEvent e) {
int action = e.getAction() & MotionEvent.ACTION_MASK;
if (action == MotionEvent.ACTION_POINTER_DOWN) {
multi++;
mTextRenderer.hold(true);
} else if (action == MotionEvent.ACTION_POINTER_UP) {
multi--;
if (multi == 0)
mTextRenderer.hold(false);
}
} else if (action == MotionEvent.ACTION_CANCEL) {
multi = 0;
log.debug("cancel " + multi);
mTextRenderer.hold(false);
}
}

View File

@ -15,15 +15,12 @@
package org.oscim.map;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import org.oscim.core.BoundingBox;
import org.oscim.core.MapPosition;
import org.oscim.event.Dispatcher;
import org.oscim.event.EventDispatcher;
import org.oscim.event.EventListener;
import org.oscim.event.IListener;
import org.oscim.event.MotionEvent;
import org.oscim.layers.Layer;
import org.oscim.layers.MapEventLayer;
@ -39,10 +36,30 @@ import org.oscim.utils.async.AsyncExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class Map implements EventDispatcher {
public abstract class Map {
static final Logger log = LoggerFactory.getLogger(Map.class);
/**
* Listener interface for map update notifications.
* Layers implementing this interface they will be automatically
* regiseter when the layer is added to the map and unregistered when
* the layer is removed.
*/
public interface UpdateListener {
void onMapUpdate(MapPosition mapPosition, boolean positionChanged, boolean clear);
}
/**
* Listener interface for input events.
* Layers implementing this interface they will be automatically
* regiseter when the layer is added to the map and unregistered when
* the layer is removed.
*/
public interface InputListener {
void onMotionEvent(MotionEvent e);
}
public static final boolean debugTheme = false;
private final Layers mLayers;
@ -57,6 +74,9 @@ public abstract class Map implements EventDispatcher {
private VectorTileLayer mBaseLayer;
private Set<InputListener> mMotionListeners = new LinkedHashSet<InputListener>();
private Set<UpdateListener> mUpdateListeners = new LinkedHashSet<UpdateListener>();
public Map() {
mViewport = new Viewport(this);
@ -183,7 +203,15 @@ public abstract class Map implements EventDispatcher {
* Caution: Do not call directly!
*/
protected void updateLayers() {
mUpdateDispatcher.dispatch();
boolean changed = false;
// get the current MapPosition
changed |= mViewport.getMapPosition(mMapPosition);
for (UpdateListener l : mUpdateListeners)
l.onMapUpdate(mMapPosition, changed, mClearMap);
mClearMap = false;
}
/**
@ -236,64 +264,31 @@ public abstract class Map implements EventDispatcher {
return mAnimator;
}
ArrayList<EventListener> mMotionListeners = new ArrayList<EventListener>();
@Override
public void addListener(String type, EventListener listener) {
if (type == MotionEvent.TYPE)
mMotionListeners.add(listener);
public void bind(InputListener listener) {
mMotionListeners.add(listener);
}
@Override
public void removeListener(String type, EventListener listener) {
if (type == MotionEvent.TYPE)
mMotionListeners.remove(listener);
public void unbind(InputListener listener) {
mMotionListeners.remove(listener);
}
public void handleMotionEvent(MotionEvent e) {
for (EventListener l : mMotionListeners)
l.handleEvent(e);
for (InputListener l : mMotionListeners)
l.onMotionEvent(e);
}
/**
* Listener interface for map update notifications.
* NOTE: Layers implementing this interface they will be automatically
* registered when the layer is added to the map and unresitered when
* the layer is removed.
*/
public interface UpdateListener extends IListener {
void onMapUpdate(MapPosition mapPosition, boolean positionChanged, boolean clear);
}
private class UpdateDispatcher extends Dispatcher<UpdateListener> {
@Override
public void dispatch() {
boolean changed = false;
// get the current MapPosition
changed |= mViewport.getMapPosition(mMapPosition);
for (UpdateListener l : listeners)
l.onMapUpdate(mMapPosition, changed, mClearMap);
mClearMap = false;
}
}
private final UpdateDispatcher mUpdateDispatcher = new UpdateDispatcher();
/**
* Register UpdateListener
*/
public void addUpdateListener(UpdateListener l) {
mUpdateDispatcher.addListener(l);
public void bind(UpdateListener l) {
mUpdateListeners.add(l);
}
/**
* Unregister UpdateListener
*/
public void removeUpdateListener(UpdateListener l) {
mUpdateDispatcher.removeListener(l);
public void unbind(UpdateListener l) {
mUpdateListeners.remove(l);
}
public final class Layers extends AbstractList<Layer> {
@ -320,7 +315,9 @@ public abstract class Map implements EventDispatcher {
throw new IllegalArgumentException("layer added twice");
if (layer instanceof UpdateListener)
addUpdateListener((UpdateListener) layer);
bind((UpdateListener) layer);
if (layer instanceof InputListener)
bind((InputListener) layer);
mLayerList.add(index, layer);
mDirtyLayers = true;
@ -333,7 +330,9 @@ public abstract class Map implements EventDispatcher {
Layer remove = mLayerList.remove(index);
if (remove instanceof UpdateListener)
removeUpdateListener((UpdateListener) remove);
unbind((UpdateListener) remove);
if (remove instanceof InputListener)
unbind((InputListener) remove);
return remove;
}
@ -346,8 +345,11 @@ public abstract class Map implements EventDispatcher {
mDirtyLayers = true;
Layer remove = mLayerList.set(index, layer);
// unbind replaced layer
if (remove instanceof UpdateListener)
removeUpdateListener((UpdateListener) remove);
unbind((UpdateListener) remove);
if (remove instanceof InputListener)
unbind((InputListener) remove);
return remove;
}