create changelog entry
[debian/openrocket] / android-libraries / achartengine / src / org / achartengine / tools / Pan.java
1 /**\r
2  * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL\r
3  * \r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  * \r
8  *      http://www.apache.org/licenses/LICENSE-2.0\r
9  * \r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 package org.achartengine.tools;\r
17 \r
18 import java.util.ArrayList;\r
19 import java.util.List;\r
20 \r
21 import org.achartengine.chart.AbstractChart;\r
22 import org.achartengine.chart.RoundChart;\r
23 import org.achartengine.chart.XYChart;\r
24 \r
25 /**\r
26  * The pan tool.\r
27  */\r
28 public class Pan extends AbstractTool {\r
29   /** The pan listeners. */\r
30   private List<PanListener> mPanListeners = new ArrayList<PanListener>();\r
31   /** Pan limits reached on the X axis. */\r
32   private boolean limitsReachedX = false;\r
33   /** Pan limits reached on the X axis. */\r
34   private boolean limitsReachedY = false;\r
35 \r
36   /**\r
37    * Builds and instance of the pan tool.\r
38    * \r
39    * @param chart the XY chart\r
40    */\r
41   public Pan(AbstractChart chart) {\r
42     super(chart);\r
43   }\r
44 \r
45   /**\r
46    * Apply the tool.\r
47    * \r
48    * @param oldX the previous location on X axis\r
49    * @param oldY the previous location on Y axis\r
50    * @param newX the current location on X axis\r
51    * @param newY the current location on the Y axis\r
52    */\r
53   public void apply(float oldX, float oldY, float newX, float newY) {\r
54     boolean notLimitedUp = true;\r
55     boolean notLimitedBottom = true;\r
56     boolean notLimitedLeft = true;\r
57     boolean notLimitedRight = true;\r
58     if (mChart instanceof XYChart) {\r
59       int scales = mRenderer.getScalesCount();\r
60       double[] limits = mRenderer.getPanLimits();\r
61       boolean limited = limits != null && limits.length == 4;\r
62       XYChart chart = (XYChart) mChart;\r
63       for (int i = 0; i < scales; i++) {\r
64         double[] range = getRange(i);\r
65         double[] calcRange = chart.getCalcRange(i);\r
66         if (limitsReachedX\r
67             && limitsReachedY\r
68             && (range[0] == range[1] && calcRange[0] == calcRange[1] || range[2] == range[3]\r
69                 && calcRange[2] == calcRange[3])) {\r
70           return;\r
71         }\r
72         checkRange(range, i);\r
73 \r
74         double[] realPoint = chart.toRealPoint(oldX, oldY, i);\r
75         double[] realPoint2 = chart.toRealPoint(newX, newY, i);\r
76         double deltaX = realPoint[0] - realPoint2[0];\r
77         double deltaY = realPoint[1] - realPoint2[1];\r
78         double ratio = getAxisRatio(range);\r
79         if (chart.isVertical(mRenderer)) {\r
80           double newDeltaX = -deltaY * ratio;\r
81           double newDeltaY = deltaX / ratio;\r
82           deltaX = newDeltaX;\r
83           deltaY = newDeltaY;\r
84         }\r
85         if (mRenderer.isPanXEnabled()) {\r
86           if (limits != null) {\r
87             if (notLimitedLeft) {\r
88               notLimitedLeft = limits[0] <= range[0] + deltaX;\r
89             }\r
90             if (notLimitedRight) {\r
91               notLimitedRight = limits[1] >= range[1] + deltaX;\r
92             }\r
93           }\r
94           if (!limited || (notLimitedLeft && notLimitedRight)) {\r
95             setXRange(range[0] + deltaX, range[1] + deltaX, i);\r
96             limitsReachedX = false;\r
97           } else {\r
98             limitsReachedX = true;\r
99           }\r
100         }\r
101         if (mRenderer.isPanYEnabled()) {\r
102           if (limits != null) {\r
103             if (notLimitedBottom) {\r
104               notLimitedBottom = limits[2] <= range[2] + deltaY;\r
105             }\r
106             if (notLimitedUp) {\r
107               notLimitedUp = limits[3] >= range[3] + deltaY;\r
108             }\r
109           }\r
110           if (!limited || (notLimitedBottom && notLimitedUp)) {\r
111             setYRange(range[2] + deltaY, range[3] + deltaY, i);\r
112             limitsReachedY = false;\r
113           } else {\r
114             limitsReachedY = true;\r
115           }\r
116         }\r
117       }\r
118     } else {\r
119       RoundChart chart = (RoundChart) mChart;\r
120       chart.setCenterX(chart.getCenterX() + (int) (newX - oldX));\r
121       chart.setCenterY(chart.getCenterY() + (int) (newY - oldY));\r
122     }\r
123     notifyPanListeners();\r
124   }\r
125 \r
126   /**\r
127    * Return the X / Y axis range ratio.\r
128    * \r
129    * @param range the axis range\r
130    * @return the ratio\r
131    */\r
132   private double getAxisRatio(double[] range) {\r
133     return Math.abs(range[1] - range[0]) / Math.abs(range[3] - range[2]);\r
134   }\r
135 \r
136   /**\r
137    * Notify the pan listeners about a pan.\r
138    */\r
139   private synchronized void notifyPanListeners() {\r
140     for (PanListener listener : mPanListeners) {\r
141       listener.panApplied();\r
142     }\r
143   }\r
144 \r
145   /**\r
146    * Adds a new pan listener.\r
147    * \r
148    * @param listener pan listener\r
149    */\r
150   public synchronized void addPanListener(PanListener listener) {\r
151     mPanListeners.add(listener);\r
152   }\r
153 \r
154   /**\r
155    * Removes a pan listener.\r
156    * \r
157    * @param listener pan listener\r
158    */\r
159   public synchronized void removePanListener(PanListener listener) {\r
160     mPanListeners.add(listener);\r
161   }\r
162 \r
163 }\r