22
33import android .graphics .RectF ;
44import android .graphics .PointF ;
5+ import android .support .annotation .NonNull ;
56import android .view .*;
67
78import com .androidplot .*;
89import com .androidplot .util .*;
910
11+ import java .io .Serializable ;
1012import java .util .*;
1113
1214/**
@@ -35,6 +37,7 @@ public class PanZoom implements View.OnTouchListener {
3537 // rectangle created by the space between two fingers
3638 protected RectF fingersRect ;
3739 private View .OnTouchListener delegate ;
40+ private State state = new State ();
3841
3942 // Definition of the touch states
4043 protected enum DragState {
@@ -95,29 +98,83 @@ public enum ZoomLimit {
9598 MIN_TICKS
9699 }
97100
98- protected PanZoom (XYPlot plot , Pan pan , Zoom zoom ) {
101+ // TODO: consider making this immutable / threadsafe
102+ public static class State implements Serializable {
103+ private Number domainLowerBoundary ;
104+ private Number domainUpperBoundary ;
105+ private Number rangeLowerBoundary ;
106+ private Number rangeUpperBoundary ;
107+ private BoundaryMode domainBoundaryMode ;
108+ private BoundaryMode rangeBoundaryMode ;
109+
110+ public void setDomainBoundaries (Number lowerBoundary , Number upperBoundary , BoundaryMode mode ) {
111+ this .domainLowerBoundary = lowerBoundary ;
112+ this .domainUpperBoundary = upperBoundary ;
113+ this .domainBoundaryMode = mode ;
114+ }
115+
116+ public void setRangeBoundaries (Number lowerBoundary , Number upperBoundary , BoundaryMode mode ) {
117+ this .rangeLowerBoundary = lowerBoundary ;
118+ this .rangeUpperBoundary = upperBoundary ;
119+ this .rangeBoundaryMode = mode ;
120+ }
121+
122+ public void applyDomainBoundaries (@ NonNull XYPlot plot ) {
123+ plot .setDomainBoundaries (domainLowerBoundary , domainUpperBoundary , domainBoundaryMode );
124+ }
125+
126+ public void applyRangeBoundaries (@ NonNull XYPlot plot ) {
127+ plot .setRangeBoundaries (rangeLowerBoundary , rangeUpperBoundary , rangeBoundaryMode );
128+ }
129+
130+ public void apply (@ NonNull XYPlot plot ) {
131+ applyDomainBoundaries (plot );
132+ applyRangeBoundaries (plot );
133+ }
134+ }
135+
136+ protected PanZoom (@ NonNull XYPlot plot , Pan pan , Zoom zoom ) {
99137 this .plot = plot ;
100138 this .pan = pan ;
101139 this .zoom = zoom ;
102140 this .zoomLimit = ZoomLimit .OUTER ;
103141 }
104142
105143 // additional constructor not to break api
106- protected PanZoom (XYPlot plot , Pan pan , Zoom zoom , ZoomLimit limit ) {
144+ protected PanZoom (@ NonNull XYPlot plot , Pan pan , Zoom zoom , ZoomLimit limit ) {
107145 this .plot = plot ;
108146 this .pan = pan ;
109147 this .zoom = zoom ;
110148 this .zoomLimit = limit ;
111149 }
112150
151+ public State getState () {
152+ return this .state ;
153+ }
154+
155+ public void setState (@ NonNull State state ) {
156+ this .state = state ;
157+ state .apply (plot );
158+ }
159+
160+ protected void adjustRangeBoundary (Number lower , Number upper , BoundaryMode mode ) {
161+ state .setRangeBoundaries (lower , upper , mode );
162+ state .applyRangeBoundaries (plot );
163+ }
164+
165+ protected void adjustDomainBoundary (Number lower , Number upper , BoundaryMode mode ) {
166+ state .setDomainBoundaries (lower , upper , mode );
167+ state .applyDomainBoundaries (plot );
168+ }
169+
113170 /**
114171 * Convenience method for enabling pan/zoom behavior on an instance of {@link XYPlot}, using
115172 * a default behavior of {@link Pan#BOTH} and {@link Zoom#SCALE}.
116173 * Use {@link PanZoom#attach(XYPlot, Pan, Zoom, ZoomLimit)} for finer grain control of this behavior.
117174 * @param plot
118175 * @return
119176 */
120- public static PanZoom attach (XYPlot plot ) {
177+ public static PanZoom attach (@ NonNull XYPlot plot ) {
121178 return attach (plot , Pan .BOTH , Zoom .SCALE );
122179 }
123180
@@ -130,7 +187,7 @@ public static PanZoom attach(XYPlot plot) {
130187 * @param zoom
131188 * @return
132189 */
133- public static PanZoom attach (XYPlot plot , Pan pan , Zoom zoom ) {
190+ public static PanZoom attach (@ NonNull XYPlot plot , @ NonNull Pan pan , @ NonNull Zoom zoom ) {
134191 return attach (plot ,pan ,zoom , ZoomLimit .OUTER );
135192 }
136193
@@ -142,7 +199,7 @@ public static PanZoom attach(XYPlot plot, Pan pan, Zoom zoom) {
142199 * @param limit
143200 * @return
144201 */
145- public static PanZoom attach (XYPlot plot , Pan pan , Zoom zoom , ZoomLimit limit ) {
202+ public static PanZoom attach (@ NonNull XYPlot plot , @ NonNull Pan pan , @ NonNull Zoom zoom , @ NonNull ZoomLimit limit ) {
146203 PanZoom pz = new PanZoom (plot , pan , zoom , limit );
147204 plot .setOnTouchListener (pz );
148205 return pz ;
@@ -237,12 +294,12 @@ protected void pan(final MotionEvent motionEvent) {
237294 if (EnumSet .of (Pan .HORIZONTAL , Pan .BOTH ).contains (pan )) {
238295 Region newBounds = new Region ();
239296 calculatePan (oldFirstFinger , newBounds , true );
240- plot . setDomainBoundaries (newBounds .getMin (), newBounds .getMax (), BoundaryMode .FIXED );
297+ adjustDomainBoundary (newBounds .getMin (), newBounds .getMax (), BoundaryMode .FIXED );
241298 }
242299 if (EnumSet .of (Pan .VERTICAL , Pan .BOTH ).contains (pan )) {
243300 Region newBounds = new Region ();
244301 calculatePan (oldFirstFinger , newBounds , false );
245- plot . setRangeBoundaries (newBounds .getMin (), newBounds .getMax (), BoundaryMode .FIXED );
302+ adjustRangeBoundary (newBounds .getMin (), newBounds .getMax (), BoundaryMode .FIXED );
246303 }
247304
248305 plot .redraw ();
@@ -291,10 +348,9 @@ protected void calculatePan(final PointF oldFirstFinger, Region bounds, final bo
291348 }
292349
293350 protected boolean isValidScale (float scale ) {
294- if (Float .isInfinite (scale ) || Float .isNaN (scale ) || scale > -0.001 && scale < 0.001 ) {
295- return false ;
296- }
297- return true ;
351+ return !Float .isInfinite (scale )
352+ && !Float .isNaN (scale )
353+ && (!(scale > -0.001 ) || !(scale < 0.001 ));
298354 }
299355
300356 protected void zoom (final MotionEvent motionEvent ) {
@@ -349,14 +405,14 @@ protected void zoom(final MotionEvent motionEvent) {
349405 Zoom .STRETCH_BOTH ,
350406 Zoom .SCALE ).contains (zoom )) {
351407 calculateZoom (newRect , scaleX , true );
352- plot . setDomainBoundaries (newRect .left , newRect .right , BoundaryMode .FIXED );
408+ adjustDomainBoundary (newRect .left , newRect .right , BoundaryMode .FIXED );
353409 }
354410 if (EnumSet .of (
355411 Zoom .STRETCH_VERTICAL ,
356412 Zoom .STRETCH_BOTH ,
357413 Zoom .SCALE ).contains (zoom )) {
358414 calculateZoom (newRect , scaleY , false );
359- plot . setRangeBoundaries (newRect .top , newRect .bottom , BoundaryMode .FIXED );
415+ adjustRangeBoundary (newRect .top , newRect .bottom , BoundaryMode .FIXED );
360416 }
361417 plot .redraw ();
362418 }
0 commit comments