1 //------------------------------------------------------------------------------
2 // emViewInputFilter.h
3 //
4 // Copyright (C) 2011-2012,2014,2016 Oliver Hamann.
5 //
6 // Homepage: http://eaglemode.sourceforge.net/
7 //
8 // This program is free software: you can redistribute it and/or modify it under
9 // the terms of the GNU General Public License version 3 as published by the
10 // Free Software Foundation.
11 //
12 // This program is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 // FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for
15 // more details.
16 //
17 // You should have received a copy of the GNU General Public License version 3
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 //------------------------------------------------------------------------------
20 
21 #ifndef emViewInputFilter_h
22 #define emViewInputFilter_h
23 
24 #ifndef emViewAnimator_h
25 #include <emCore/emViewAnimator.h>
26 #endif
27 
28 
29 //==============================================================================
30 //============================= emViewInputFilter ==============================
31 //==============================================================================
32 
33 class emViewInputFilter : public emEngine {
34 
35 public:
36 
37 	// Base class for an input event filter of an emView. Each view can have
38 	// a list of filters. Such a filter typically eats certain events for
39 	// zooming and scrolling the view.
40 
41 	emViewInputFilter(emView & view, emViewInputFilter * next=NULL);
42 		// Construct a view input filter and insert it to the list of
43 		// filters of a view.
44 		// Arguments:
45 		//   view - The view.
46 		//   next - The next filter in the list. This filter is
47 		//          inserted before that filter. If next is NULL, this
48 		//          filter is appended to the end of the list.
49 
50 	virtual ~emViewInputFilter();
51 		// Destruct this view input filter. This also removes the filter
52 		// from the list.
53 
54 	emView & GetView() const;
55 		// Get the view.
56 
57 	emViewInputFilter * GetPrev() const;
58 	emViewInputFilter * GetNext() const;
59 		// Get the previous or next filter in the list. NULL means this
60 		// is the first or last filter.
61 
62 	virtual double GetTouchEventPriority(double touchX, double touchY) const;
63 		// Get the maximum touch event priority of this view input
64 		// filter and all its successors and all the panels of the view
65 		// for a certain touch position. The default implementation
66 		// calls GetForwardTouchEventPriority. This should usually also
67 		// be made by overloaded implementations. See the comments on
68 		// emPanel::GetTouchEventPriority for more.
69 		// Arguments:
70 		//   touchX, touchY - Position of a first touch in view
71 		//                    coordinates.
72 
73 protected:
74 
75 	virtual void Input(emInputEvent & event, const emInputState & state);
76 		// Process input form keyboard, mouse, and touch. The default
77 		// implementation calls ForwardInput. This should usually also
78 		// be made by overloaded implementations.
79 		// Arguments:
80 		//   event  - An input event. It may be eaten by calling
81 		//            event.Eat(). The event reference in non-const only
82 		//            for that.
83 		//   state  - The current input state.
84 
85 	virtual bool Cycle();
86 		// emViewInputFilter has been derived from emEngine for
87 		// convenience. This default implementation does nothing and
88 		// returns false.
89 
90 	void ForwardInput(emInputEvent & event, const emInputState & state);
91 		// Forward input to succeeding filters and the panels. Actually
92 		// this calls Input on the next filter, or on the view if this
93 		// is the last filter.
94 		// Arguments:
95 		//   event  - An input event. It may be eaten by calling
96 		//            event.Eat(). The event reference in non-const only
97 		//            for that.
98 		//   state  - The current input state.
99 
100 	double GetForwardTouchEventPriority(double touchX, double touchY) const;
101 		// Get the maximum touch event priority of succeeding filters
102 		// and the panels. Actually this calls GetTouchEventPriority on
103 		// the next filter, or on the view if this is the last filter.
104 		// Arguments:
105 		//   touchX, touchY - Position of a first touch in view
106 		//                    coordinates.
107 
108 private:
109 	friend class emViewPort;
110 	emView & View;
111 	emViewInputFilter * Prev;
112 	emViewInputFilter * Next;
113 };
114 
GetView()115 inline emView & emViewInputFilter::GetView() const
116 {
117 	return View;
118 }
119 
GetPrev()120 inline emViewInputFilter * emViewInputFilter::GetPrev() const
121 {
122 	return Prev;
123 }
124 
GetNext()125 inline emViewInputFilter * emViewInputFilter::GetNext() const
126 {
127 	return Next;
128 }
129 
ForwardInput(emInputEvent & event,const emInputState & state)130 inline void emViewInputFilter::ForwardInput(
131 	emInputEvent & event, const emInputState & state
132 )
133 {
134 	if (!Next) View.Input(event,state);
135 	else Next->Input(event,state);
136 }
137 
GetForwardTouchEventPriority(double touchX,double touchY)138 inline double emViewInputFilter::GetForwardTouchEventPriority(
139 	double touchX, double touchY
140 ) const
141 {
142 	if (!Next) return View.GetTouchEventPriority(touchX,touchY,true);
143 	else return Next->GetTouchEventPriority(touchX,touchY);
144 }
145 
146 
147 //==============================================================================
148 //============================ emMouseZoomScrollVIF ============================
149 //==============================================================================
150 
151 class emMouseZoomScrollVIF : public emViewInputFilter {
152 
153 public:
154 
155 	// This view input filter eats some mouse events for zooming and
156 	// scrolling.
157 
158 	emMouseZoomScrollVIF(emView & view, emViewInputFilter * next=NULL);
159 	virtual ~emMouseZoomScrollVIF();
160 
161 protected:
162 
163 	virtual void Input(emInputEvent & event, const emInputState & state);
164 
165 	virtual bool Cycle();
166 
167 private:
168 
169 	void EmulateMiddleButton(emInputEvent & event, emInputState & state);
170 	bool MoveMousePointerBackIntoView(double * pmx, double * pmy);
171 	void MoveMousePointer(double dx, double dy);
172 	double GetMouseZoomSpeed(bool fine=false) const;
173 	double GetMouseScrollSpeed(bool fine=false) const;
174 	void UpdateWheelZoomSpeed(bool down, bool fine);
175 	void SetMouseAnimParams();
176 	void SetWheelAnimParams();
177 	void InitMagnetismAvoidance();
178 	void UpdateMagnetismAvoidance(double dmx, double dmy);
179 
180 	emSwipingViewAnimator MouseAnim;
181 	emSwipingViewAnimator WheelAnim;
182 	emRef<emCoreConfig> CoreConfig;
183 	double LastMouseX,LastMouseY,ZoomFixX,ZoomFixY;
184 	emUInt64 EmuMidButtonTime;
185 	int EmuMidButtonRepeat;
186 	double WheelZoomSpeed;
187 	emUInt64 WheelZoomTime;
188 	bool MagnetismAvoidance;
189 	double MagAvMouseMoveX,MagAvMouseMoveY;
190 	emUInt64 MagAvTime;
191 };
192 
193 
194 //==============================================================================
195 //========================== emKeyboardZoomScrollVIF ===========================
196 //==============================================================================
197 
198 class emKeyboardZoomScrollVIF : public emViewInputFilter {
199 
200 public:
201 
202 	// This view input filter eats some keyboard events for zooming and
203 	// scrolling.
204 
205 	emKeyboardZoomScrollVIF(emView & view, emViewInputFilter * next=NULL);
206 	virtual ~emKeyboardZoomScrollVIF();
207 
208 protected:
209 
210 	virtual void Input(emInputEvent & event, const emInputState & state);
211 
212 private:
213 
214 	void NavigateByProgram(emInputEvent & event, const emInputState & state);
215 	double GetZoomSpeed(bool fine=false) const;
216 	double GetScrollSpeed(bool fine=false) const;
217 	void SetAnimatorParameters();
218 
219 	emSpeedingViewAnimator Animator;
220 	emRef<emCoreConfig> CoreConfig;
221 	bool Active;
222 	int NavByProgState;
223 };
224 
225 
226 //==============================================================================
227 //================================= emCheatVIF =================================
228 //==============================================================================
229 
230 class emCheatVIF : public emViewInputFilter {
231 
232 public:
233 
234 	// This view input filter implements some chat codes.
235 
236 	emCheatVIF(emView & view, emViewInputFilter * next=NULL);
237 	virtual ~emCheatVIF();
238 
239 protected:
240 
241 	virtual void Input(emInputEvent & event, const emInputState & state);
242 
243 private:
244 
245 	emRef<emCoreConfig> CoreConfig;
246 	char CheatBuffer[64];
247 };
248 
249 
250 //==============================================================================
251 //============================= emDefaultTouchVIF ==============================
252 //==============================================================================
253 
254 class emDefaultTouchVIF : public emViewInputFilter {
255 
256 public:
257 
258 	// This view input filter eats touch events for zooming and scrolling
259 	// and for emulating mouse events.
260 
261 	emDefaultTouchVIF(emView & view, emViewInputFilter * next=NULL);
262 	virtual ~emDefaultTouchVIF();
263 
264 	virtual double GetTouchEventPriority(double touchX, double touchY) const;
265 
266 protected:
267 
268 	virtual void Input(emInputEvent & event, const emInputState & state);
269 
270 	virtual bool Cycle();
271 
272 private:
273 
274 	void DoGesture();
275 	void ResetTouches();
276 	void NextTouches();
277 	void RemoveTouch(int index);
278 	bool IsAnyTouchDown() const;
279 	double GetTouchMoveX(int index) const;
280 	double GetTouchMoveY(int index) const;
281 	double GetTouchMove(int index) const;
282 	double GetTotalTouchMoveX(int index) const;
283 	double GetTotalTouchMoveY(int index) const;
284 	double GetTotalTouchMove(int index) const;
285 
286 	struct Touch {
287 		emUInt64 Id;
288 		int MsTotal;
289 		int MsSincePrev;
290 		bool Down;
291 		double X;
292 		double Y;
293 		bool PrevDown;
294 		double PrevX;
295 		double PrevY;
296 		double DownX;
297 		double DownY;
298 	};
299 
300 	enum { MAX_TOUCH_COUNT=16 };
301 
302 	emInputState InputState;
303 	emInputEvent InputEvent;
304 	Touch Touches[MAX_TOUCH_COUNT];
305 	int TouchCount;
306 	emUInt64 TouchesTime;
307 	int GestureState;
308 };
309 
310 
311 #endif
312