Skip to content

Commit 1cd5185

Browse files
committed
Merge remote-tracking branch 'origin/feature/select-drag-listener' into develop
# Conflicts: # worldwind-examples/src/main/java/gov/nasa/worldwindx/OmnidirectionalSightlineActivity.java # worldwind-examples/src/main/java/gov/nasa/worldwindx/PlacemarksSelectDragActivity.java
2 parents abf8075 + 9153e9f commit 1cd5185

5 files changed

Lines changed: 173 additions & 471 deletions

File tree

worldwind-examples/src/main/java/gov/nasa/worldwindx/OmnidirectionalSightlineActivity.java

Lines changed: 12 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,16 @@
55

66
package gov.nasa.worldwindx;
77

8-
import android.graphics.PointF;
98
import android.os.Bundle;
10-
import android.view.GestureDetector;
11-
import android.view.MotionEvent;
12-
139
import gov.nasa.worldwind.BasicWorldWindowController;
14-
import gov.nasa.worldwind.PickedObject;
15-
import gov.nasa.worldwind.PickedObjectList;
1610
import gov.nasa.worldwind.WorldWind;
17-
import gov.nasa.worldwind.WorldWindow;
18-
import gov.nasa.worldwind.geom.Line;
1911
import gov.nasa.worldwind.geom.LookAt;
2012
import gov.nasa.worldwind.geom.Position;
21-
import gov.nasa.worldwind.geom.Vec3;
22-
import gov.nasa.worldwind.globe.Globe;
13+
import gov.nasa.worldwind.gesture.SelectDragCallback;
2314
import gov.nasa.worldwind.layer.RenderableLayer;
2415
import gov.nasa.worldwind.render.Color;
2516
import gov.nasa.worldwind.render.ImageSource;
17+
import gov.nasa.worldwind.render.Renderable;
2618
import gov.nasa.worldwind.shape.OmnidirectionalSightline;
2719
import gov.nasa.worldwind.shape.Placemark;
2820
import gov.nasa.worldwind.shape.ShapeAttributes;
@@ -45,11 +37,6 @@ public class OmnidirectionalSightlineActivity extends BasicGlobeActivity {
4537
*/
4638
protected Placemark sightlinePlacemark;
4739

48-
/**
49-
* A custom WorldWindowController object that handles the select, drag and navigation gestures.
50-
*/
51-
protected SimpleSelectDragNavigateController controller;
52-
5340
@Override
5441
protected void onCreate(Bundle savedInstanceState) {
5542
super.onCreate(savedInstanceState);
@@ -83,152 +70,22 @@ protected void onCreate(Bundle savedInstanceState) {
8370
sightlineLayer.addRenderable(this.sightlinePlacemark);
8471
this.wwd.getLayers().addLayer(sightlineLayer);
8572

86-
// Override the WorldWindow's built-in navigation behavior with conditional dragging support.
87-
this.controller = new SimpleSelectDragNavigateController(this.wwd);
88-
this.wwd.setWorldWindowController(this.controller);
89-
90-
// And finally, for this demo, position the viewer to look at the sightline position
91-
LookAt lookAt = new LookAt().set(pos.latitude, pos.longitude, pos.altitude, WorldWind.ABSOLUTE, 2e4 /*range*/, 0 /*heading*/, 45 /*tilt*/, 0 /*roll*/);
92-
this.getWorldWindow().cameraFromLookAt(lookAt);
93-
}
94-
95-
/**
96-
* This inner class is based on the controller in the {@link PlacemarksSelectDragActivity} but has been simplified
97-
* for the single Placemark.
98-
*/
99-
public class SimpleSelectDragNavigateController extends BasicWorldWindowController {
100-
101-
protected boolean isDragging = false;
102-
103-
protected boolean isDraggingArmed = false;
104-
105-
private final PointF dragRefPt = new PointF();
106-
107-
/**
108-
* Pre-allocated to avoid memory allocations
109-
*/
110-
private final Line ray = new Line();
111-
112-
/**
113-
* Pre-allocated to avoid memory allocations
114-
*/
115-
private final Vec3 pickPoint = new Vec3();
116-
117-
/**
118-
* Assign a subclassed SimpleOnGestureListener to a GestureDetector to handle the drag gestures.
119-
*/
120-
protected final GestureDetector selectDragDetector = new GestureDetector(getApplicationContext(), new GestureDetector.SimpleOnGestureListener() {
121-
73+
// Add dragging callback
74+
((BasicWorldWindowController) wwd.getWorldWindowController()).setSelectDragCallback(new SelectDragCallback() {
12275
@Override
123-
public boolean onDown(MotionEvent event) {
124-
pick(event); // Pick the object(s) at the tap location
125-
return false; // By not consuming this event, we allow it to pass on to the navigation gesture handlers
76+
public boolean canMoveRenderable(Renderable renderable) {
77+
return renderable == sightlinePlacemark;
12678
}
12779

12880
@Override
129-
public boolean onScroll(MotionEvent downEvent, MotionEvent moveEvent, float distanceX, float distanceY) {
130-
if (isDraggingArmed) {
131-
return drag(distanceX, distanceY);
132-
}
133-
return false;
81+
public void onRenderableMoved(Renderable renderable, Position fromPosition, Position toPosition) {
82+
sightline.setPosition(toPosition);
13483
}
13584
});
13685

137-
public SimpleSelectDragNavigateController(WorldWindow wwd) {
138-
super(wwd);
139-
}
140-
141-
/**
142-
* Delegates events to the select/drag handlers or the native World Wind navigation handlers.
143-
*/
144-
@Override
145-
public boolean onTouchEvent(MotionEvent event) {
146-
// Allow our select and drag handlers to process the event first. They'll set the state flags which will
147-
// either preempt or allow the event to be subsequently processed by the globe's navigation event handlers.
148-
boolean consumed = this.selectDragDetector.onTouchEvent(event);
149-
150-
// Is a dragging operation started or in progress? Any ACTION_UP event cancels a drag operation.
151-
if (this.isDragging && event.getAction() == MotionEvent.ACTION_UP) {
152-
this.isDragging = false;
153-
this.isDraggingArmed = false;
154-
}
155-
// Preempt the globe's pan navigation recognizer if we're dragging
156-
super.panRecognizer.setEnabled(!isDragging);
157-
158-
// Pass on the event on to the default globe navigation handlers
159-
if (!consumed) {
160-
consumed = super.onTouchEvent(event);
161-
}
162-
return consumed;
163-
}
164-
165-
/**
166-
* Moves the selected object to the event's screen position.
167-
*
168-
* @return true if the event was consumed
169-
*/
170-
public boolean drag(float distanceX, float distanceY) {
171-
if (this.isDraggingArmed) {
172-
// Signal that dragging is in progress
173-
this.isDragging = true;
174-
175-
// First we compute the screen coordinates of the position's "ground" point. We'll apply the
176-
// screen X and Y drag distances to this point, from which we'll compute a new position,
177-
// wherein we restore the original position's altitude.
178-
Position position = sightlinePlacemark.getReferencePosition();
179-
double altitude = position.altitude;
180-
if (getWorldWindow().geographicToScreenPoint(position.latitude, position.longitude, 0, this.dragRefPt)) {
181-
// Update the placemark's ground position
182-
if (screenPointToGroundPosition(this.dragRefPt.x - distanceX, this.dragRefPt.y - distanceY, position)) {
183-
// Restore the placemark's original altitude
184-
position.altitude = altitude;
185-
// Move the sightline
186-
sightline.setPosition(position);
187-
// Reflect the change in position on the globe.
188-
getWorldWindow().requestRedraw();
189-
return true;
190-
}
191-
}
192-
// Probably clipped by near/far clipping plane or off the globe. The position was not updated. Stop the drag.
193-
this.isDraggingArmed = false;
194-
return true; // We consumed this event, even if dragging has been stopped.
195-
}
196-
return false;
197-
}
198-
199-
/**
200-
* Performs a pick at the tap location and conditionally arms the dragging flag, so that dragging can occur if
201-
* the next event is an onScroll event.
202-
*/
203-
public void pick(MotionEvent event) {
204-
205-
// Perform the pick at the screen x, y
206-
PickedObjectList pickList = getWorldWindow().pick(event.getX(), event.getY());
207-
208-
// Examine the picked objects for Renderables
209-
PickedObject topPickedObject = pickList.topPickedObject();
210-
// There is only one placemark on the globe and
211-
this.isDraggingArmed = topPickedObject != null && topPickedObject.getUserObject() instanceof Placemark;
212-
}
213-
214-
/**
215-
* Converts a screen point to the geographic coordinates on the globe.
216-
*
217-
* @param screenX X coordinate
218-
* @param screenY Y coordinate
219-
* @param result Pre-allocated Position receives the geographic coordinates
220-
*
221-
* @return true if the screen point could be converted; false if the screen point is not on the globe
222-
*/
223-
public boolean screenPointToGroundPosition(float screenX, float screenY, Position result) {
224-
if (this.wwd.rayThroughScreenPoint(screenX, screenY, ray)) {
225-
Globe globe = wwd.getGlobe();
226-
if (globe.intersect(ray, this.pickPoint)) {
227-
globe.cartesianToGeographic(pickPoint.x, this.pickPoint.y, this.pickPoint.z, result);
228-
return true;
229-
}
230-
}
231-
return false;
232-
}
86+
// And finally, for this demo, position the viewer to look at the sightline position
87+
LookAt lookAt = new LookAt().set(pos.latitude, pos.longitude, pos.altitude, WorldWind.ABSOLUTE, 2e4 /*range*/, 0 /*heading*/, 45 /*tilt*/, 0 /*roll*/);
88+
this.getWorldWindow().cameraFromLookAt(lookAt);
23389
}
90+
23491
}

0 commit comments

Comments
 (0)