1 //------------------------------------------------------------------------------
2 // emView.h
3 //
4 // Copyright (C) 2004-2012,2014,2016-2017 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 emView_h
22 #define emView_h
23 
24 #ifndef emCursor_h
25 #include <emCore/emCursor.h>
26 #endif
27 
28 #ifndef emInput_h
29 #include <emCore/emInput.h>
30 #endif
31 
32 #ifndef emPainter_h
33 #include <emCore/emPainter.h>
34 #endif
35 
36 #ifndef emCoreConfig_h
37 #include <emCore/emCoreConfig.h>
38 #endif
39 
40 class emPanel;
41 class emViewPort;
42 class emWindow;
43 class emScreen;
44 class emViewAnimator;
45 class emMagneticViewAnimator;
46 class emVisitingViewAnimator;
47 class emViewInputFilter;
48 class emCheatVIF;
49 
50 
51 //==============================================================================
52 //=================================== emView ===================================
53 //==============================================================================
54 
55 class emView : public emContext {
56 
57 public:
58 
59 	// An emView is a rectangle on the screen in which the user can see a
60 	// tree of panels (see class emPanel). If not disabled by a feature
61 	// flag, the user can navigate through the panels by zooming, scrolling
62 	// and moving the focus.
63 	//
64 	// After constructing an emView, an appropriate emViewPort should be
65 	// created on it. Otherwise the view is not connected to any screen or
66 	// input device (it uses an internal dummy emViewPort then). See the
67 	// derived class emWindow - it solves the problem of connecting the
68 	// view. Another solution is the class emSubViewPanel.
69 	//
70 	// Even, emView does not create any panels. This should also be done by
71 	// the caller.
72 	//
73 	// emView has been derived from emContext so that it is easy to define
74 	// custom view settings as models of that context.
75 
76 	typedef int ViewFlags;
77 		// Data type for the feature flags of a view. Possible flags
78 		// are:
79 	enum {
80 		VF_POPUP_ZOOM         =(1<<0),
81 			// The view pops up whenever the view is zoomed. For
82 			// this feature to work, an emScreen must be in the path
83 			// of contexts, so that the view is able to create a
84 			// private emWindow as the popup.
85 		VF_ROOT_SAME_TALLNESS =(1<<1),
86 			// The root panel always has the same tallness as the
87 			// view. This is highly recommended when using
88 			// VF_POPUP_ZOOM.
89 		VF_NO_ZOOM            =(1<<2),
90 			// The view is always zoomed out. This implies having
91 			// VF_NO_USER_NAVIGATION and not having VF_POPUP_ZOOM
92 			// and not having VF_EGO_MODE.
93 		VF_NO_USER_NAVIGATION =(1<<3),
94 			// The user cannot navigate in the view.
95 		VF_NO_FOCUS_HIGHLIGHT =(1<<4),
96 			// The view does not show any focus highlight.
97 		VF_NO_ACTIVE_HIGHLIGHT=(1<<5),
98 			// The view does not show any active highlight.
99 		VF_EGO_MODE           =(1<<6),
100 			// This is a special mode of user interaction. The mouse
101 			// pointer is degenerated to a cross-hair in the center
102 			// of the view, and each mouse movement scrolls the
103 			// view. This mode should not be used when there are
104 			// multiple windows or views on the screen, because the
105 			// mouse pointer cannot be moved. The name "ego mode"
106 			// has been chosen because it is somehow similar to the
107 			// mouse control in ego shooter games.
108 		VF_STRESS_TEST        =(1<<7)
109 			// This repaints the view on every time slice and shows
110 			// the frame rate in the upper-left corner. This feature
111 			// exists for use by developers.
112 	};
113 
114 	emView(emContext & parentContext, ViewFlags viewFlags=0);
115 		// Constructor.
116 		// Arguments:
117 		//   parentContext - Parent context for this new context.
118 		//   viewFlags     - Initial feature flags.
119 
120 	virtual ~emView();
121 		// Destructor. If a real view port has been created for this
122 		// view, it must be deleted before destructing the view. In
123 		// addition, it is always a good idea to delete the root panel
124 		// by destructors of derived classes, just because a panel could
125 		// depend on the properties of the derivative. For example,
126 		// emPanel::GetWindow() must not be used after destructing the
127 		// emWindow, and therefore the destructor of emWindow deletes
128 		// the panels itself.
129 
130 	void LinkCrossPtr(emCrossPtrPrivate & crossPtr);
131 		// This means emCrossPtr<emView> is possible.
132 
133 	ViewFlags GetViewFlags() const;
134 	void SetViewFlags(ViewFlags viewFlags);
135 		// Get or set the features of this view.
136 
137 	const emSignal & GetViewFlagsSignal() const;
138 		// This signal is signaled when the features of this view have
139 		// changed.
140 
141 	emColor GetBackgroundColor() const;
142 	void SetBackgroundColor(emColor c);
143 		// Get or set the background color of this view. This color is
144 		// used for areas which are not covered by the panels, or where
145 		// the panels are transparent. The default is some grey.
146 
147 	virtual emString GetTitle() const;
148 		// Get the title to be shown for this view. The default
149 		// implementation returns the title of the active panel (not
150 		// directly, but updated through an engine). See also:
151 		// InvalidateTitle()
152 
153 	const emSignal & GetTitleSignal() const;
154 		// This signal is signaled when the title has changed.
155 
156 	emPanel * CreateControlPanel(emPanel & parent, const emString & name);
157 		// If this is a content view, this method may be called to
158 		// create a control panel in a control view. The call is
159 		// forwarded to the active panel. The result can be NULL which
160 		// means to have no control panel. The caller should delete the
161 		// control panel before calling CreateControlPanel again, and
162 		// before destructing this view.
163 
164 	const emSignal & GetControlPanelSignal() const;
165 		// This signal is signaled when the control panel should be
166 		// recreated.
167 
168 	bool IsFocused() const;
169 		// Whether this view has the focus.
170 
171 	const emSignal & GetFocusSignal() const;
172 		// This signal is signaled when the focus of this view has
173 		// changed.
174 
175 	void Focus();
176 		// Make that this view has the focus, if possible by the
177 		// emViewPort implementation. Hint: If this is an emWindow, you
178 		// may want to call Raise() before.
179 
180 	emWindow * GetWindow() const;
181 		// Get the window of this view. It returns the nearest window
182 		// within the path of contexts to this view. If this view itself
183 		// is a window, that window is returned. If no window can be
184 		// found, NULL is returned. The result is cached internally.
185 
186 	emScreen * GetScreen() const;
187 		// Get the screen of this view. If GetWindow() returns non-NULL,
188 		// the screen of that window is returned. Otherwise the call is
189 		// forwarded to emScreen::LookupInherited(*this). The result is
190 		// cached internally.
191 
192 	double GetHomeX() const;
193 	double GetHomeY() const;
194 	double GetHomeWidth() const;
195 	double GetHomeHeight() const;
196 	double GetHomePixelTallness() const;
197 	double GetHomeTallness() const;
198 		// Get the home geometry of this view on the screen. "Home"
199 		// means the state where the view is not popped up by the
200 		// popup-zoom feature. X, Y, Width and Height are the
201 		// coordinates of the view rectangle, measured in pixels on the
202 		// screen. PixelTallness is the height/width ratio of the pixels
203 		// on the monitor (as far as known by the implementation of
204 		// emViewPort). And Tallness is the height/width ration of the
205 		// view on the monitor. It is equal to
206 		// Height/Width*PixelTallness.
207 
208 	double GetCurrentX() const;
209 	double GetCurrentY() const;
210 	double GetCurrentWidth() const;
211 	double GetCurrentHeight() const;
212 	double GetCurrentPixelTallness() const;
213 	double GetCurrentTallness() const;
214 		// Get the current geometry of this view on the screen. This is
215 		// like GetHomeX(), GetHomeY() and so on, but if the view is
216 		// currently popped up by the popup-zoom feature, the geometry
217 		// of the popup is returned (should not make any difference for
218 		// PixelTallness).
219 
220 	const emSignal & GetGeometrySignal() const;
221 		// This signal is signaled when the home geometry or the current
222 		// geometry of this view has changed.
223 
224 	void GetMaxPopupViewRect(double * pX, double * pY,
225 	                         double * pW, double * pH) const;
226 		// Get the pixel coordinates of the maximum visible rectangle of
227 		// a popup. This is the bounding rectangle of all display
228 		// monitors, which intersect the home rectangle of the view. The
229 		// given pointers are for returning the rectangle coordinates
230 		// (x,y,w,h). NULL pointers are allowed.
231 
232 	emViewInputFilter * GetFirstVIF() const;
233 	emViewInputFilter * GetLastVIF() const;
234 		// Get the first or last view input filter (VIF) in the chain of
235 		// the VIFs of this view. The default chain (after constructing
236 		// the view) contains emDefaultTouchVIF, emCheatVIF,
237 		// emKeyboardZoomScrollVIF, and emMouseZoomScrollVIF in that
238 		// order. This could change in future versions. You can modify
239 		// the chain simply by deleting and creating VIFs as you like.
240 		// See emViewInputFilter for more details. Note that the
241 		// zoom/scroll VIFs have no effect when VF_NO_USER_NAVIGATION is
242 		// set in the view flags. Also, never forget about the
243 		// possibility of parent and child views (=>emSubViewPanel).
244 		// Parent views should always have VF_NO_ZOOM.
245 
246 	emPanel * GetRootPanel() const;
247 		// Get the root panel of this view. Returns NULL when this view
248 		// has no panels.
249 
250 	emPanel * GetSupremeViewedPanel() const;
251 		// Get the supreme viewed panel. It is the upper-most panel in
252 		// the panel tree which has IsViewed()==true. Returns NULL when
253 		// this view has no panels. The supreme viewed panel is always
254 		// chosen automatically by the view, depending on the visit
255 		// state.
256 
257 	emPanel * GetActivePanel() const;
258 		// Get the active panel. The active panel is the panel which is
259 		// focused when the view is focused. Returns NULL when this view
260 		// has no panels.
261 
262 	bool IsActivationAdherent() const;
263 		// Whether the panel activation is adherent. It usually means
264 		// that the activation has been made by the user.
265 
266 	void SetActivePanel(emPanel * panel, bool adherent=true);
267 		// Make the given Panel the active panel, or if it is not
268 		// focusable, make the nearest focusable ancestor active.
269 		// The location of the view is not changed.
270 
271 	void SetActivePanelBestPossible();
272 		// Search for a viewed panel whose position in the view is best
273 		// for being the active panel, and activate it. But if the old
274 		// activation is adherent, the activation is changed only if it
275 		// is really too bad.
276 
277 	emPanel * GetPanelByIdentity(const char * identity) const;
278 		// Search for a panel by identity (see emPanel::GetIdentity()).
279 		// Returns NULL if not found.
280 
281 	emPanel * GetPanelAt(double x, double y) const;
282 		// Get the uppermost panel at the given point.
283 
284 	emPanel * GetFocusablePanelAt(double x, double y,
285 	                              bool checkSubstance) const;
286 		// Get the uppermost focusable panel at the given point. If
287 		// checkSubstance is true, the substance rectangles of the
288 		// panels are checked. Otherwise the whole panel rectangles are
289 		// checked.
290 
291 	emPanel * GetVisitedPanel(double * pRelX=NULL, double * pRelY=NULL,
292 	                          double * pRelA=NULL) const;
293 		// Get the visited panel and optionally relative coordinates.
294 		// The visited panel is the one on which the view is currently
295 		// anchored. That means, if any panel layout is changed, the
296 		// visited panel keeps its position and size in the view.
297 		// Normally, the visited panel is the active panel. But if the
298 		// active panel is not viewed, the visited panel is the viewed
299 		// panel which is (in the tree of panels) nearest to the active
300 		// panel.
301 		// Arguments:
302 		//   pRelX, pRelY - Pointers for returning the distance vector
303 		//                  between the center of the view and the
304 		//                  center of the panel, measured in view widths
305 		//                  and heights.
306 		//   pRelA        - Pointer for returning the area size of the
307 		//                  view relative to the area size of the panel.
308 		// Returns:
309 		//   The visited panel, or NULL if this view has no panels.
310 
311 	void Visit(emPanel * panel, double relX, double relY, double relA,
312 	           bool adherent);
313 	void Visit(const char * identity, double relX, double relY, double relA,
314 	           bool adherent, const char * subject=NULL);
315 		// Start to visit a panel. This means to position the view
316 		// relative to the given panel and make that panel the active
317 		// panel. The operation is animated and may take a long time.
318 		// Arguments:
319 		//   panel     - The panel to be visited.
320 		//   identity  - Identity of the panel to be visited.
321 		//   relX,relY - Desired distance vector between the center of
322 		//               the view and the center of the panel, measured
323 		//               in view widths and heights.
324 		//   relA      - Desired area size of the view relative to the
325 		//               area size of the panel.
326 		//   adherent  - Whether the activation shall be adherent.
327 		//   subject   - A subject text to be shown in an info box
328 		//               for the case the operation takes much time.
329 		//               Best is to give the title of the panel.
330 
331 	void Visit(emPanel * panel, bool adherent);
332 	void Visit(const char * identity, bool adherent,
333 	           const char * subject=NULL);
334 		// Like the Visit methods above, but automatically
335 		// choose a good position for the panel in the view.
336 
337 	void VisitFullsized(emPanel * panel, bool adherent,
338 	                    bool utilizeView=false);
339 	void VisitFullsized(const char * identity, bool adherent,
340 	                    bool utilizeView=false, const char * subject=NULL);
341 		// Like the Visit methods above, but position the view so that
342 		// the panel is shown full-sized.
343 
344 	void RawVisit(emPanel * panel, double relX, double relY, double relA);
345 	void RawVisit(emPanel * panel);
346 	void RawVisitFullsized(emPanel * panel, bool utilizeView=false);
347 		// Like the Visit methods above, but without animation (these
348 		// methods act immediately), without aborting any active
349 		// animation, and without changing the active panel.
350 
351 	void VisitNext();
352 	void VisitPrev();
353 	void VisitFirst();
354 	void VisitLast();
355 	void VisitLeft();
356 	void VisitRight();
357 	void VisitUp();
358 	void VisitDown();
359 	void VisitNeighbour(int direction);
360 	void VisitIn();
361 	void VisitOut();
362 		// Start to visit a sister, parent or child of the active panel.
363 		// This walks the tree of focusable panels only.
364 		// VisitNeighbour(0) is like VisitRight(), 1 like Down, 2 like
365 		// Left and 3 like Up.
366 
367 	void Scroll(double deltaX, double deltaY);
368 		// Scroll the view. This aborts any active animation and
369 		// performs immediately without animation. The active panel is
370 		// adapted.
371 		// Arguments:
372 		//   deltaX     - How many pixels to scroll in X direction.
373 		//                A positive value means to scroll right.
374 		//   deltaY     - How many pixels to scroll in Y direction.
375 		//                A positive value means to scroll down.
376 
377 	void Zoom(double fixX, double fixY, double factor);
378 		// Zoom the view. This aborts any active animation and performs
379 		// immediately without animation. The active panel is adapted.
380 		// Arguments:
381 		//   fixX, fixY - Fix point for the zooming.
382 		//   factor     - Zoom factor. A value less than 1.0 means to
383 		//                zoom out, and a value greater than 1.0 means
384 		//                to zoom in.
385 
386 	void RawScrollAndZoom(
387 		double fixX, double fixY,
388 		double deltaX, double deltaY, double deltaZ,
389 		emPanel * panel=NULL, double * pDeltaXDone=NULL,
390 		double * pDeltaYDone=NULL, double * pDeltaZDone=NULL
391 	);
392 		// Scroll and zoom the view without aborting animations and
393 		// without changing the active panel. The scrolling is performed
394 		// before the zooming.
395 		// Arguments:
396 		//   fixX, fixY  - Fix point for the zooming.
397 		//   deltaX      - How many pixels to scroll in X direction.
398 		//                 A positive value means to scroll right.
399 		//   deltaY      - How many pixels to scroll in Y direction.
400 		//                 A positive value means to scroll down.
401 		//   deltaZ      - How many pixels to zoom. The zoom factor is:
402 		//                 exp(deltaZ * GetZoomFactorLogarithmPerPixel())
403 		//   panel       - A panel to be used for the calculations.
404 		//                 It should be a panel which is also viewed
405 		//                 after the operation. If NULL or not viewed,
406 		//                 the visited panel is used.
407 		//   pDeltaXDone - Pointer for returning the number of pixels by
408 		//                 which the view actually has been scrolled in
409 		//                 X.
410 		//   pDeltaYDone - Pointer for returning the number of pixels by
411 		//                 which the view actually has been scrolled in
412 		//                 Y.
413 		//   pDeltaZDone - Pointer for returning the number of pixels by
414 		//                 which the view actually has been zoomed.
415 
416 	double GetZoomFactorLogarithmPerPixel() const;
417 		// How much zooming feels the same amount of motion to the user
418 		// as scrolling one pixel, returned as natural logarithm of zoom
419 		// factor.
420 
421 	void ZoomOut();
422 		// Zoom out the view completely. This aborts any active
423 		// animation and performs immediately without animation. The
424 		// active panel is adapted.
425 
426 	void RawZoomOut();
427 		// Like ZoomOut(), but without aborting animations and without
428 		// changing the active panel.
429 
430 	bool IsZoomedOut() const;
431 		// Whether the view is currently zoomed out completely.
432 
433 	bool IsPoppedUp() const;
434 		// Whether the view is in popped up state.
435 
436 	void SignalEOIDelayed();
437 		// After calling this, the End-Of-Interaction signal will be
438 		// signaled, but with a delay of some time slices.
439 
440 	const emSignal & GetEOISignal() const;
441 		// Get the End-Of-Interaction signal. This signal indicates an
442 		// end of a temporary user interaction. It has been invented for
443 		// emButton (see emButton::IsNoEOI()). If the view has
444 		// VF_POPUP_ZOOM set, the application should call ZoomOut() when
445 		// an EOI has been signaled.
446 
447 	bool IsSoftKeyboardShown() const;
448 	void ShowSoftKeyboard(bool show);
449 		// Get and set whether to show a software keyboard (if there is
450 		// no hardware keyboard).
451 
452 	emUInt64 GetInputClockMS() const;
453 		// Get the time of the currently handled input event and input
454 		// state, or the current time if all events are handled. The
455 		// time is measured in milliseconds and starts anywhere, but it
456 		// should never overflow.
457 
458 	virtual double GetTouchEventPriority(
459 		double touchX, double touchY, bool afterVIFs=false
460 	) const;
461 		// Get the touch event priority of this view for a certain touch
462 		// position. (See emPanel::GetTouchEventPriority).
463 		// Arguments:
464 		//   touchX, touchY - Position of a first touch in view
465 		//                    coordinates.
466 		//   afterVIFs      - Whether to leave out the view input filters
467 		//                    in the calculation.
468 
469 	emViewAnimator * GetActiveAnimator() const;
470 		// Get the active view animator, or NULL if none is active.
471 
472 	void ActivateMagneticViewAnimator();
473 		// Activate the magnetic view animator.
474 
475 	void AbortActiveAnimator();
476 		// Abort any activate view animator.
477 
478 protected:
479 
480 	virtual void Input(emInputEvent & event, const emInputState & state);
481 		// Process input form keyboard, mouse, and touch after filtering
482 		// it by the view input filters. The default implementation
483 		// forwards to the panels.
484 		// Arguments:
485 		//   event  - An input event. It may be eaten by calling
486 		//            event.Eat(). The event reference in non-const only
487 		//            for that.
488 		//   state  - The current input state.
489 
490 	virtual emCursor GetCursor() const;
491 		// Get the mouse cursor to be shown for this view. The default
492 		// implementation returns the cursor of the panel where the
493 		// mouse is. See also: InvalidateCursor()
494 
495 	virtual void Paint(
496 		const emPainter & painter, emColor canvasColor
497 	) const;
498 		// Paint this view. The default implementation paints the
499 		// panels, the focus and an info box when seeking.
500 		// Arguments:
501 		//   painter     - A painter for painting the view to the
502 		//                 screen. Origin and scaling of this painter
503 		//                 are prepared for having the coordinate system
504 		//                 of the screen.
505 		//   canvasColor - Color of the canvas.
506 		// See also: InvalidatePainting()
507 
508 	virtual void InvalidateTitle();
509 		// Indicate a change in the results of GetTitle(). The default
510 		// implementation simply signals the title signal (see
511 		// GetTitleSignal()).
512 
513 	void InvalidateCursor();
514 		// Indicate a change in the results of GetCursor(). After
515 		// calling this, showings of the cursor will be updated.
516 
517 	void InvalidatePainting();
518 	void InvalidatePainting(double x, double y, double w, double h);
519 		// Indicate a change in the results of Paint(). After calling
520 		// this, the view will be re-painted. The second version of the
521 		// method allows to invalidate just a rectangular area instead
522 		// of the whole view.
523 		// Arguments:
524 		//   x,y,w,h - Upper-left corner and size of the rectangle.
525 
526 	virtual void DoCustomCheat(const char * func);
527 		// This method could be overloaded for implementing custom cheat
528 		// codes. For example, if the user enters "chEat:abc!", this
529 		// method is called with func="abc". The default implementation
530 		// calls the ancestor view, if there. For the cheat codes
531 		// implemented by default, see the implementation of
532 		// emCheatVIF::Input.
533 
534 	// - - - - - - - - - - Depreciated methods - - - - - - - - - - - - - - -
535 	// The following virtual non-const methods have been replaced by const
536 	// methods (see above). The old versions still exist here with the
537 	// "final" keyword added, so that old overridings will fail to compile.
538 	// If you run into this, please adapt your overridings by adding "const".
539 public:
540 	virtual emString GetTitle() final;
541 	virtual double GetTouchEventPriority(
542 		double touchX, double touchY, bool afterVIFs=false
543 	) final;
544 protected:
545 	virtual emCursor GetCursor() final;
546 	virtual void Paint(const emPainter & painter, emColor canvasColor) final;
547 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
548 
549 private:
550 	friend class emViewPort;
551 	friend class emViewAnimator;
552 	friend class emVisitingViewAnimator;
553 	friend class emViewInputFilter;
554 	friend class emCheatVIF;
555 	friend class emPanel;
556 	friend class emSubViewPanel;
557 	friend class emWindow;
558 
559 	struct PanelRingNode {
560 		PanelRingNode * Prev;
561 		PanelRingNode * Next;
562 	};
563 
564 	void SetWindowAndScreen(emWindow * window=NULL);
565 
566 	void SetFocused(bool focused);
567 	void SetGeometry(double x, double y, double width, double height,
568 	                 double pixelTallness);
569 
570 	void AddToNoticeList(PanelRingNode * node);
571 
572 	void Update();
573 
574 	void CalcVisitCoords(const emPanel * panel, double * pRelX,
575 	                     double * pRelY, double * pRelA) const;
576 
577 	void CalcVisitFullsizedCoords(const emPanel * panel, double * pRelX,
578 	                              double * pRelY, double * pRelA,
579 	                              bool utilizeView=false) const;
580 
581 	void RawVisit(emPanel * panel, double relX, double relY, double relA,
582 	              bool forceViewingUpdate);
583 	void RawVisitAbs(emPanel * panel, double vx, double vy, double vw,
584 	                 bool forceViewingUpdate);
585 	void RawZoomOut(bool forceViewingUpdate);
586 
587 	void FindBestSVP(emPanel * * pPanel, double * pVx, double * pVy,
588 	                 double * pVw) const;
589 	bool FindBestSVPInTree(emPanel * * pPanel, double * pVx, double * pVy,
590 	                       double * pVw, bool covering) const;
591 
592 	void SwapViewPorts(bool swapFocus);
593 
594 	void RecurseInput(emInputEvent & event,
595 	                  const emInputState & state);
596 	void RecurseInput(emPanel * parent, emInputEvent & event,
597 	                  const emInputState & state);
598 
599 	void InvalidateHighlight();
600 	void PaintHighlight(const emPainter & painter) const;
601 	void PaintHighlightArrowsOnLine(
602 		const emPainter & painter, double x, double y,
603 		double dx, double dy, double pos, double delta,
604 		int count, double goalX, double goalY, double arrowSize,
605 		emColor shadowColor, emColor arrowColor
606 	) const;
607 	void PaintHighlightArrowsOnBow(
608 		const emPainter & painter, double x, double y, double radius,
609 		int quadrant, double pos, double delta, int count,
610 		double goalX, double goalY, double arrowSize,
611 		emColor shadowColor, emColor arrowColor
612 	) const;
613 	void PaintHighlightArrow(
614 		const emPainter & painter, double x, double y,
615 		double goalX, double goalY, double arrowSize,
616 		emColor shadowColor, emColor arrowColor
617 	) const;
618 
619 	void SetSeekPos(emPanel * panel, const char * childName);
620 	bool IsHopeForSeeking() const;
621 
622 	class UpdateEngineClass : public emEngine {
623 	public:
624 		UpdateEngineClass(emView & view);
625 	protected:
626 		virtual bool Cycle();
627 	private:
628 		emView & View;
629 	};
630 	friend class UpdateEngineClass;
631 
632 	class EOIEngineClass : public emEngine {
633 	public:
634 		EOIEngineClass(emView & view);
635 	protected:
636 		virtual bool Cycle();
637 	private:
638 		emView & View;
639 		int CountDown;
640 	};
641 	friend class EOIEngineClass;
642 
643 	class StressTestClass : public emEngine {
644 	public:
645 		StressTestClass(emView & view);
646 		virtual ~StressTestClass();
647 		void PaintInfo(const emPainter & painter);
648 	protected:
649 		virtual bool Cycle();
650 	private:
651 		emView & View;
652 		int TCnt,TPos,TValid;
653 		emUInt64 * T;
654 		double FrameRate;
655 		emUInt64 FRUpdate;
656 	};
657 	friend class StressTestClass;
658 
659 	emCrossPtrList CrossPtrList;
660 	emRef<emCoreConfig> CoreConfig;
661 	emViewPort * DummyViewPort;
662 	emViewPort * HomeViewPort;
663 	emViewPort * CurrentViewPort;
664 	emWindow * Window;
665 	emRef<emModel> ScreenRef;
666 	emWindow * PopupWindow;
667 	emViewInputFilter * FirstVIF;
668 	emViewInputFilter * LastVIF;
669 	emViewAnimator * ActiveAnimator;
670 	emMagneticViewAnimator * MagneticVA;
671 	emVisitingViewAnimator * VisitingVA;
672 	emPanel * RootPanel;
673 	emPanel * SupremeViewedPanel;
674 	emPanel * MinSVP, * MaxSVP;
675 	emPanel * ActivePanel;
676 	emSignal ViewFlagsSignal;
677 	emSignal TitleSignal;
678 	emSignal ControlPanelSignal;
679 	emSignal FocusSignal;
680 	emSignal GeometrySignal;
681 	emSignal EOISignal;
682 	double HomeX,HomeY,HomeWidth,HomeHeight,HomePixelTallness;
683 	double CurrentX,CurrentY,CurrentWidth,CurrentHeight,
684 	       CurrentPixelTallness;
685 	double LastMouseX,LastMouseY;
686 	emString Title;
687 	emCursor Cursor;
688 	emColor BackgroundColor;
689 	ViewFlags VFlags;
690 	bool Focused;
691 	bool ActivationAdherent;
692 	bool ZoomScrollInAction;
693 	bool TitleInvalid;
694 	bool CursorInvalid;
695 	bool SVPChoiceInvalid;
696 	bool SVPChoiceByOpacityInvalid;
697 	bool GotPopupWindowCloseSignal;
698 	bool RestartInputRecursion;
699 	bool ZoomedOutBeforeSG;
700 	int SettingGeometry;
701 	int SVPUpdCount;
702 	emUInt64 SVPUpdSlice;
703 	emInputEvent NoEvent;
704 	PanelRingNode NoticeList;
705 	UpdateEngineClass * UpdateEngine;
706 	EOIEngineClass * EOIEngine;
707 	emPanel * SeekPosPanel;
708 	emString SeekPosChildName;
709 	StressTestClass * StressTest;
710 
711 	static const double MaxSVPSize;
712 	static const double MaxSVPSearchSize;
713 };
714 
715 
716 //==============================================================================
717 //================================= emViewPort =================================
718 //==============================================================================
719 
720 class emViewPort : public emUncopyable {
721 
722 public:
723 
724 	// Base class for the connection between an emView and the operating
725 	// system or the hardware or whatever. The default implementation
726 	// connects the view to nothing. When a view is constructed, it creates
727 	// such a dummy view port just to have a view port at all. A real view
728 	// port should be created on the view afterwards. For example, this is
729 	// solved in emWindow by creating an emWindowPort, which is a derivative
730 	// of emViewPort.
731 	//
732 	// Note that emView implements some tricks for solving the popup-zoom
733 	// feature. When popping up, the view creates a private emWindow and
734 	// exchanges the view port of that window for its own view port
735 	// temporarily. A view port derivative must come clear with such an
736 	// exchange (do not store any references to the view in it).
737 	//
738 	// The title is not interfaced through emViewPort (but through
739 	// emWindowPort) because it must not be exchanged when the view pops up.
740 	//
741 	// The popup-zoom feature is even the reason why all views must share
742 	// the same coordinate system. It should be the coordinate system of
743 	// screen.
744 
745 	emViewPort(emView & homeView);
746 
747 	virtual ~emViewPort();
748 
749 	double GetViewX() const;
750 	double GetViewY() const;
751 	double GetViewWidth() const;
752 	double GetViewHeight() const;
753 
754 	emCursor GetViewCursor() const;
755 
756 	void PaintView(const emPainter & painter, emColor canvasColor) const;
757 
758 protected:
759 
760 	void SetViewGeometry(double x, double y, double w, double h,
761 	                     double pixelTallness);
762 
763 	void SetViewFocused(bool focused);
764 	virtual void RequestFocus();
765 
766 	virtual bool IsSoftKeyboardShown() const;
767 	virtual void ShowSoftKeyboard(bool show);
768 
769 	virtual emUInt64 GetInputClockMS() const;
770 
771 	void InputToView(emInputEvent & event, const emInputState & state);
772 
773 	virtual void InvalidateCursor();
774 
775 	virtual void InvalidatePainting(double x, double y, double w, double h);
776 
777 	// - - - - - - - - - - Depreciated methods - - - - - - - - - - - - - - -
778 	// The following virtual non-const methods have been replaced by const
779 	// methods (see above). The old versions still exist here with the
780 	// "final" keyword added, so that old overridings will fail to compile.
781 	// If you run into this, please adapt your overridings by adding "const".
782 	virtual bool IsSoftKeyboardShown() final;
783 	virtual emUInt64 GetInputClockMS() final;
784 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
785 
786 private:
787 	friend class emView;
788 	emViewPort();
789 	emView * HomeView;
790 	emView * CurrentView;
791 };
792 
793 
794 //==============================================================================
795 //============================== Implementations ===============================
796 //==============================================================================
797 
798 //----------------------------------- emView -----------------------------------
799 
LinkCrossPtr(emCrossPtrPrivate & crossPtr)800 inline void emView::LinkCrossPtr(emCrossPtrPrivate & crossPtr)
801 {
802 	CrossPtrList.LinkCrossPtr(crossPtr);
803 }
804 
GetViewFlags()805 inline emView::ViewFlags emView::GetViewFlags() const
806 {
807 	return VFlags;
808 }
809 
GetViewFlagsSignal()810 inline const emSignal & emView::GetViewFlagsSignal() const
811 {
812 	return ViewFlagsSignal;
813 }
814 
GetBackgroundColor()815 inline emColor emView::GetBackgroundColor() const
816 {
817 	return BackgroundColor;
818 }
819 
GetTitleSignal()820 inline const emSignal & emView::GetTitleSignal() const
821 {
822 	return TitleSignal;
823 }
824 
GetControlPanelSignal()825 inline const emSignal & emView::GetControlPanelSignal() const
826 {
827 	return ControlPanelSignal;
828 }
829 
IsFocused()830 inline bool emView::IsFocused() const
831 {
832 	return Focused;
833 }
834 
GetFocusSignal()835 inline const emSignal & emView::GetFocusSignal() const
836 {
837 	return FocusSignal;
838 }
839 
GetWindow()840 inline emWindow * emView::GetWindow() const
841 {
842 	return Window;
843 }
844 
GetHomeX()845 inline double emView::GetHomeX() const
846 {
847 	return HomeX;
848 }
849 
GetHomeY()850 inline double emView::GetHomeY() const
851 {
852 	return HomeY;
853 }
854 
GetHomeWidth()855 inline double emView::GetHomeWidth() const
856 {
857 	return HomeWidth;
858 }
859 
GetHomeHeight()860 inline double emView::GetHomeHeight() const
861 {
862 	return HomeHeight;
863 }
864 
GetHomePixelTallness()865 inline double emView::GetHomePixelTallness() const
866 {
867 	return HomePixelTallness;
868 }
869 
GetHomeTallness()870 inline double emView::GetHomeTallness() const
871 {
872 	return HomeHeight/HomeWidth*HomePixelTallness;
873 }
874 
GetCurrentX()875 inline double emView::GetCurrentX() const
876 {
877 	return CurrentX;
878 }
879 
GetCurrentY()880 inline double emView::GetCurrentY() const
881 {
882 	return CurrentY;
883 }
884 
GetCurrentWidth()885 inline double emView::GetCurrentWidth() const
886 {
887 	return CurrentWidth;
888 }
889 
GetCurrentHeight()890 inline double emView::GetCurrentHeight() const
891 {
892 	return CurrentHeight;
893 }
894 
GetCurrentPixelTallness()895 inline double emView::GetCurrentPixelTallness() const
896 {
897 	return CurrentPixelTallness;
898 }
899 
GetCurrentTallness()900 inline double emView::GetCurrentTallness() const
901 {
902 	return CurrentHeight/CurrentWidth*CurrentPixelTallness;
903 }
904 
GetGeometrySignal()905 inline const emSignal & emView::GetGeometrySignal() const
906 {
907 	return GeometrySignal;
908 }
909 
GetFirstVIF()910 inline emViewInputFilter * emView::GetFirstVIF() const
911 {
912 	return FirstVIF;
913 }
914 
GetLastVIF()915 inline emViewInputFilter * emView::GetLastVIF() const
916 {
917 	return LastVIF;
918 }
919 
GetRootPanel()920 inline emPanel * emView::GetRootPanel() const
921 {
922 	return RootPanel;
923 }
924 
GetSupremeViewedPanel()925 inline emPanel * emView::GetSupremeViewedPanel() const
926 {
927 	return SupremeViewedPanel;
928 }
929 
GetActivePanel()930 inline emPanel * emView::GetActivePanel() const
931 {
932 	return ActivePanel;
933 }
934 
IsActivationAdherent()935 inline bool emView::IsActivationAdherent() const
936 {
937 	return ActivationAdherent;
938 }
939 
IsPoppedUp()940 inline bool emView::IsPoppedUp() const
941 {
942 	return PopupWindow!=NULL;
943 }
944 
GetEOISignal()945 inline const emSignal & emView::GetEOISignal() const
946 {
947 	return EOISignal;
948 }
949 
IsSoftKeyboardShown()950 inline bool emView::IsSoftKeyboardShown() const
951 {
952 	return CurrentViewPort->IsSoftKeyboardShown();
953 }
954 
ShowSoftKeyboard(bool show)955 inline void emView::ShowSoftKeyboard(bool show)
956 {
957 	CurrentViewPort->ShowSoftKeyboard(show);
958 }
959 
GetInputClockMS()960 inline emUInt64 emView::GetInputClockMS() const
961 {
962 	return CurrentViewPort->GetInputClockMS();
963 }
964 
GetActiveAnimator()965 inline emViewAnimator * emView::GetActiveAnimator() const
966 {
967 	return ActiveAnimator;
968 }
969 
InvalidateCursor()970 inline void emView::InvalidateCursor()
971 {
972 	CurrentViewPort->InvalidateCursor();
973 }
974 
InvalidatePainting()975 inline void emView::InvalidatePainting()
976 {
977 	CurrentViewPort->InvalidatePainting(
978 		CurrentX,CurrentY,CurrentWidth,CurrentHeight
979 	);
980 }
981 
InvalidatePainting(double x,double y,double w,double h)982 inline void emView::InvalidatePainting(double x, double y, double w, double h)
983 {
984 	CurrentViewPort->InvalidatePainting(x,y,w,h);
985 }
986 
987 
988 //--------------------------------- emViewPort ---------------------------------
989 
GetViewX()990 inline double emViewPort::GetViewX() const
991 {
992 	return CurrentView->GetCurrentX();
993 }
994 
GetViewY()995 inline double emViewPort::GetViewY() const
996 {
997 	return CurrentView->GetCurrentY();
998 }
999 
GetViewWidth()1000 inline double emViewPort::GetViewWidth() const
1001 {
1002 	return CurrentView->GetCurrentWidth();
1003 }
1004 
GetViewHeight()1005 inline double emViewPort::GetViewHeight() const
1006 {
1007 	return CurrentView->GetCurrentHeight();
1008 }
1009 
GetViewCursor()1010 inline emCursor emViewPort::GetViewCursor() const
1011 {
1012 	return CurrentView->GetCursor();
1013 }
1014 
PaintView(const emPainter & painter,emColor canvasColor)1015 inline void emViewPort::PaintView(
1016 	const emPainter & painter, emColor canvasColor
1017 ) const
1018 {
1019 	CurrentView->Paint(painter,canvasColor);
1020 }
1021 
SetViewGeometry(double x,double y,double w,double h,double pixelTallness)1022 inline void emViewPort::SetViewGeometry(
1023 	double x, double y, double w, double h, double pixelTallness
1024 )
1025 {
1026 	CurrentView->SetGeometry(x,y,w,h,pixelTallness);
1027 }
1028 
SetViewFocused(bool focused)1029 inline void emViewPort::SetViewFocused(bool focused)
1030 {
1031 	CurrentView->SetFocused(focused);
1032 }
1033 
1034 
1035 #endif
1036