1 // CircleStartHandler.cpp
3 // Copyright (c) 2007 The Dasher Team
5 // This file is part of Dasher.
7 // Dasher is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
12 // Dasher is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with Dasher; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "../Common/Common.h"
23 #include "CircleStartHandler.h"
24 #include "DefaultFilter.h"
25 #include "DasherInterfaceBase.h"
27 #include "DasherInput.h"
29 using namespace Dasher
;
31 CCircleStartHandler::CCircleStartHandler(CDefaultFilter
*pCreator
)
32 : CStartHandler(pCreator
), CSettingsUserObserver(pCreator
), m_iEnterTime(std::numeric_limits
<long>::max()), m_iScreenRadius(-1), m_pView(NULL
) {
35 CCircleStartHandler::~CCircleStartHandler() {
36 if (m_pView
) m_pView
->Observable
<CDasherView
*>::Unregister(this);
39 CDasherScreen::point
CCircleStartHandler::CircleCenter(CDasherView
*pView
) {
40 if (m_iScreenRadius
!=-1) return m_screenCircleCenter
;
42 m_pView
->Dasher2Screen(CDasherModel::ORIGIN_X
, CDasherModel::ORIGIN_Y
, m_screenCircleCenter
.x
, m_screenCircleCenter
.y
);
43 //compute radius against orientation. It'd be simpler to use
44 // Math.min(screen width, screen height) * LP_CIRCLE_PERCENT / 100
46 screenint iEdgeX
, iEdgeY
;
47 m_pView
->Dasher2Screen(CDasherModel::ORIGIN_X
, CDasherModel::ORIGIN_Y
+ (CDasherModel::MAX_Y
*GetLongParameter(LP_CIRCLE_PERCENT
))/100, iEdgeX
, iEdgeY
);
49 const Opts::ScreenOrientations
iDirection(m_pView
->GetOrientation());
51 if((iDirection
== Opts::TopToBottom
) || (iDirection
== Opts::BottomToTop
)) {
52 m_iScreenRadius
= iEdgeX
- m_screenCircleCenter
.x
;
55 m_iScreenRadius
= iEdgeY
- m_screenCircleCenter
.y
;
57 return m_screenCircleCenter
;
60 bool CCircleStartHandler::DecorateView(CDasherView
*pView
) {
61 if (!m_pView
) (m_pView
=pView
)->Observable
<CDasherView
*>::Register(this);
62 CDasherScreen::point ctr
= CircleCenter(pView
);
64 const bool bAboutToChange
= m_bInCircle
&& m_iEnterTime
!= std::numeric_limits
<long>::max();
65 int fillColor
, lineColor
, lineWidth
;
66 if (m_pFilter
->isPaused()) {
67 lineColor
=2; lineWidth
=1;
68 fillColor
= bAboutToChange
? 241 : 242;
70 lineColor
=240; fillColor
=-1; //don't fill
71 lineWidth
= bAboutToChange
? 3 : 1;
74 pView
->Screen()->DrawCircle(ctr
.x
, ctr
.y
, m_iScreenRadius
, fillColor
, lineColor
, lineWidth
);
79 void CCircleStartHandler::Timer(unsigned long iTime
, dasherint mouseX
, dasherint mouseY
,CDasherView
*pView
) {
80 if (!m_pView
) (m_pView
=pView
)->Observable
<CDasherView
*>::Register(this);
81 CDasherScreen::point ctr
= CircleCenter(pView
);
83 pView
->Dasher2Screen(mouseX
, mouseY
, x
, y
);
84 int dx
=x
-ctr
.x
, dy
=y
-ctr
.y
;
85 const bool inCircleNow
= dx
*dx
+ dy
*dy
<= (m_iScreenRadius
* m_iScreenRadius
) && pView
->Screen()->IsWindowUnderCursor();
89 //still in circle...check they aren't still in there after prev. activation
90 if (m_iEnterTime
!= std::numeric_limits
<long>::max() && iTime
- m_iEnterTime
> 1000) {
92 if (m_pFilter
->isPaused())
93 m_pFilter
->run(iTime
);
96 //note our onPause method will then set
97 // m_iEnterTime = std::numeric_limits<long>::max()
98 // thus preventing us from firing until user leaves circle and enters again
100 } else {// !m_bInCircle
101 //just entered circle
103 m_iEnterTime
= iTime
;
106 //currently outside circle
111 void CCircleStartHandler::HandleEvent(int iParameter
) {
112 if (iParameter
==LP_CIRCLE_PERCENT
)
113 m_iScreenRadius
= -1; //recompute geometry.
116 void CCircleStartHandler::onPause() {
117 m_iEnterTime
= std::numeric_limits
<long>::max();
118 //In one-dimensional mode, we have that (un)pausing can _move_ the circle, thus,
119 // clicking (or using any other start mechanism) can cause the circle to appear
120 // around the mouse. If this happens, you should have to leave and re-enter
121 // the circle before the start handler does anything. The following ensures this.
125 void CCircleStartHandler::onRun(unsigned long iTime
) {
126 //reset things in exactly the same way as when we pause...
130 void CCircleStartHandler::HandleEvent(CDasherView
*pNewView
) {
131 //need to recompute geometry...
132 m_iScreenRadius
= -1; //even if it's the same view
133 if (pNewView
!= m_pView
) {
134 if (m_pView
) m_pView
->Observable
<CDasherView
*>::Unregister(this);
135 (m_pView
=pNewView
)->Observable
<CDasherView
*>::Register(this);