55
66package gov .nasa .worldwindx ;
77
8- import android .graphics .PointF ;
98import android .os .Bundle ;
10- import android .view .GestureDetector ;
11- import android .view .MotionEvent ;
12-
139import gov .nasa .worldwind .BasicWorldWindowController ;
14- import gov .nasa .worldwind .PickedObject ;
15- import gov .nasa .worldwind .PickedObjectList ;
1610import gov .nasa .worldwind .WorldWind ;
17- import gov .nasa .worldwind .WorldWindow ;
18- import gov .nasa .worldwind .geom .Line ;
1911import gov .nasa .worldwind .geom .LookAt ;
2012import 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 ;
2314import gov .nasa .worldwind .layer .RenderableLayer ;
2415import gov .nasa .worldwind .render .Color ;
2516import gov .nasa .worldwind .render .ImageSource ;
17+ import gov .nasa .worldwind .render .Renderable ;
2618import gov .nasa .worldwind .shape .OmnidirectionalSightline ;
2719import gov .nasa .worldwind .shape .Placemark ;
2820import 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