[dasher] Implement new two-push dynamic mode which reduces the up-and-down motion
- From: Patrick Welche <pwelche src gnome org>
- To: svn-commits-list gnome org
- Subject: [dasher] Implement new two-push dynamic mode which reduces the up-and-down motion
- Date: Wed, 17 Jun 2009 14:29:15 -0400 (EDT)
commit 07ca9fd0bedceb489f8a774b9536a8d5676ffbae
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date: Wed Jun 17 19:20:13 2009 +0100
Implement new two-push dynamic mode which reduces the up-and-down motion
of one button dynamic mode by measuring between-click times.
Also added dynamic button lag to two-button dynamic mode.
ChangeLog | 5 +
NEWS | 6 +
Src/DasherCore/DasherInterfaceBase.cpp | 2 +
Src/DasherCore/DasherModel.cpp | 3 +-
Src/DasherCore/DasherModel.h | 9 -
Src/DasherCore/Makefile.am | 2 +
Src/DasherCore/OneButtonDynamicFilter.h | 4 +-
Src/DasherCore/Parameters.h | 16 ++-
Src/DasherCore/TwoButtonDynamicFilter.cpp | 30 +++-
Src/DasherCore/TwoButtonDynamicFilter.h | 3 +
Src/DasherCore/TwoPushDynamicFilter.cpp | 263 +++++++++++++++++++++++++++++
Src/DasherCore/TwoPushDynamicFilter.h | 56 ++++++
12 files changed, 380 insertions(+), 19 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index bf8a90b..af3eb1f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2009-06-17 Alan Lawrence <acl33 inf phy cam ac uk>
+ * Implement new two-push dynamic mode (TwoPushDynamicFilter.{h,cpp}).
+ Also added dynamic button lag to two-button dynamic mode.
+
+2009-06-17 Alan Lawrence <acl33 inf phy cam ac uk>
+
* Re-implement dynamic mode speed control:
Periodically increase speed as long as in a 'running' state;
decrease every time we start to reverse.
diff --git a/NEWS b/NEWS
index 330726c..f390983 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,9 @@
+==========
+Dasher 5.0
+==========
+ * New two-push, one button, dynamic mode (which reduces
+ the up-and-down motion of one button dynamic mode).
+
=============
Dasher 4.10.2
=============
diff --git a/Src/DasherCore/DasherInterfaceBase.cpp b/Src/DasherCore/DasherInterfaceBase.cpp
index dde675c..f5c99bc 100644
--- a/Src/DasherCore/DasherInterfaceBase.cpp
+++ b/Src/DasherCore/DasherInterfaceBase.cpp
@@ -48,6 +48,7 @@
#include "OneDimensionalFilter.h"
#include "StylusFilter.h"
#include "TwoButtonDynamicFilter.h"
+#include "TwoPushDynamicFilter.h"
// STL headers
#include <cstdio>
@@ -946,6 +947,7 @@ void CDasherInterfaceBase::CreateModules() {
#endif
RegisterModule(new COneButtonDynamicFilter(m_pEventHandler, m_pSettingsStore, this));
RegisterModule(new CTwoButtonDynamicFilter(m_pEventHandler, m_pSettingsStore, this));
+ RegisterModule(new CTwoPushDynamicFilter(m_pEventHandler, m_pSettingsStore, this));
// TODO: specialist factory for button mode
RegisterModule(new CDasherButtons(m_pEventHandler, m_pSettingsStore, this, 5, 1, true,8, _("Menu Mode")));
RegisterModule(new CDasherButtons(m_pEventHandler, m_pSettingsStore, this, 3, 0, false,10, _("Direct Mode")));
diff --git a/Src/DasherCore/DasherModel.cpp b/Src/DasherCore/DasherModel.cpp
index b64ef23..41d66df 100644
--- a/Src/DasherCore/DasherModel.cpp
+++ b/Src/DasherCore/DasherModel.cpp
@@ -380,7 +380,8 @@ void CDasherModel::Get_new_root_coords(dasherint X, dasherint Y, dasherint &r1,
double dFactor;
- if(IsSlowdown(iTime))
+ if(GetBoolParameter(BP_SLOW_START) &&
+ ((iTime - m_iStartTime) < GetLongParameter(LP_SLOW_START_TIME)))
dFactor = 0.1 * (1 + 9 * ((iTime - m_iStartTime) / static_cast<double>(GetLongParameter(LP_SLOW_START_TIME))));
else
dFactor = 1.0;
diff --git a/Src/DasherCore/DasherModel.h b/Src/DasherCore/DasherModel.h
index f5c0e03..74c0618 100644
--- a/Src/DasherCore/DasherModel.h
+++ b/Src/DasherCore/DasherModel.h
@@ -166,15 +166,6 @@ class Dasher::CDasherModel:public CFrameRate, private NoClones
};
///
- /// Return whether Dasher is currently being temporarily slowed or
- /// not.
- ///
-
- bool IsSlowdown(unsigned long iTime) {
- return ((iTime - m_iStartTime) < static_cast<unsigned long>(GetLongParameter(LP_SLOW_START_TIME)));
- };
-
- ///
/// Check whether a change of root node is needed, and perform the
/// update if so
/// TODO: Could be done in UpdateBounds?
diff --git a/Src/DasherCore/Makefile.am b/Src/DasherCore/Makefile.am
index 5266d78..547d4a5 100644
--- a/Src/DasherCore/Makefile.am
+++ b/Src/DasherCore/Makefile.am
@@ -119,6 +119,8 @@ libdashercore_a_SOURCES = \
TwoBoxStartHandler.h \
TwoButtonDynamicFilter.cpp \
TwoButtonDynamicFilter.h \
+ TwoPushDynamicFilter.cpp \
+ TwoPushDynamicFilter.h \
UserButton.cpp \
UserButton.h \
UserLocation.cpp \
diff --git a/Src/DasherCore/OneButtonDynamicFilter.h b/Src/DasherCore/OneButtonDynamicFilter.h
index 6c7a3fb..f79bcd9 100644
--- a/Src/DasherCore/OneButtonDynamicFilter.h
+++ b/Src/DasherCore/OneButtonDynamicFilter.h
@@ -18,8 +18,8 @@
// along with Dasher; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-#ifndef __DYNAMIC_FILTER_H__
-#define __DYNAMIC_FILTER_H__
+#ifndef __ONE_BUTTON_DYNAMIC_FILTER_H__
+#define __ONE_BUTTON_DYNAMIC_FILTER_H__
#include "ButtonMultiPress.h"
diff --git a/Src/DasherCore/Parameters.h b/Src/DasherCore/Parameters.h
index 9bc5a34..ce2965c 100644
--- a/Src/DasherCore/Parameters.h
+++ b/Src/DasherCore/Parameters.h
@@ -44,7 +44,7 @@ enum {
BP_COMPASSMODE, BP_SOCKET_INPUT_ENABLE, BP_SOCKET_DEBUG,
BP_OLD_STYLE_PUSH, BP_CIRCLE_START, BP_GLOBAL_KEYBOARD,
BP_DELAY_VIEW, BP_CONVERSION_MODE, BP_PAUSE_OUTSIDE, BP_BACKOFF_BUTTON,
- BP_TWOBUTTON_REVERSE, BP_SLOW_START, END_OF_BPS
+ BP_TWOBUTTON_REVERSE, BP_SLOW_START, BP_FIXED_MARKERS, END_OF_BPS
};
enum {
@@ -60,6 +60,8 @@ enum {
LP_SOCKET_INPUT_Y_MIN, LP_SOCKET_INPUT_Y_MAX, LP_OX, LP_OY, LP_MAX_Y, LP_INPUT_FILTER,
LP_CIRCLE_PERCENT, LP_TWO_BUTTON_OFFSET, LP_HOLD_TIME, LP_MULTIPRESS_TIME, LP_MULTIPRESS_COUNT,
LP_SLOW_START_TIME, LP_CONVERSION_ORDER, LP_CONVERSION_TYPE,
+ LP_TWO_PUSH_OUTER, LP_TWO_PUSH_UP, LP_TWO_PUSH_DOWN, LP_TWO_PUSH_TOLERANCE,
+ LP_DYNAMIC_BUTTON_LAG,
LP_DEMO_SPRING, LP_DEMO_NOISE_MEM, LP_DEMO_NOISE_MAG, LP_MAXZOOM,
LP_DYNAMIC_SPEED_INC, LP_DYNAMIC_SPEED_FREQ, LP_DYNAMIC_SPEED_DEC, END_OF_LPS
};
@@ -160,7 +162,8 @@ static bp_table boolparamtable[] = {
{BP_PAUSE_OUTSIDE, "PauseOutside", PERS, false, "Whether to pause when pointer leaves canvas area"},
{BP_BACKOFF_BUTTON, "BackoffButton", PERS, true, "Whether to enable the extra backoff button in dynamic mode"},
{BP_TWOBUTTON_REVERSE, "TwoButtonReverse", PERS, false, "Reverse the up/down buttons in two button mode"},
- {BP_SLOW_START, "SlowStart", PERS, false, "Start at low speed and insrease"},
+ {BP_SLOW_START, "SlowStart", PERS, false, "Start at low speed and increase"},
+ {BP_FIXED_MARKERS, "TwoPushMarkersFixed", PERS, false, "Two-push Dynamic Mode markers fixed to canvas"},
};
static lp_table longparamtable[] = {
@@ -213,13 +216,18 @@ static lp_table longparamtable[] = {
{LP_SLOW_START_TIME, "SlowStartTime", PERS, 1000, "Time over which slow start occurs"},
{LP_CONVERSION_ORDER, "ConversionOrder", PERS, 0, "Conversion ordering"},
{LP_CONVERSION_TYPE, "ConversionType", PERS, 0, "Conversion type"},
+ {LP_TWO_PUSH_OUTER, "TwoPushOuter", PERS, 1792, "Offset for one button dynamic mode outer marker"},
+ {LP_TWO_PUSH_UP, "TwoPushUp", PERS, 1536, "Offset to up marker in one button dynamic"},
+ {LP_TWO_PUSH_DOWN, "TwoPushDown", PERS, 1280, "Offset to down marker in one button dynamic"},
+ {LP_TWO_PUSH_TOLERANCE, "TwoPushTolerance", PERS, 100, "Tolerance of two-push-mode pushes, in ms"},
+ {LP_DYNAMIC_BUTTON_LAG, "DynamicButtonLag", PERS, 50, "Lag of pushes in dynamic button mode (ms)"},
{LP_DEMO_SPRING, "DemoSpring", PERS, 100, "Springyness in Demo-mode"},
{LP_DEMO_NOISE_MEM, "DemoNoiseMem", PERS, 100, "Memory parameter for noise in Demo-mode"},
{LP_DEMO_NOISE_MAG, "DemoNoiseMag", PERS, 325, "Magnitude of noise in Demo-mode"},
{LP_MAXZOOM, "ClickMaxZoom", PERS, 200, "Maximum zoom possible in click mode (times 10)"},
- {LP_DYNAMIC_SPEED_INC, "DynamicSpeedInc", PERS, 1, "%age by which dynamic mode auto speed control increases speed"},
+ {LP_DYNAMIC_SPEED_INC, "DynamicSpeedInc", PERS, 3, "%age by which dynamic mode auto speed control increases speed"},
{LP_DYNAMIC_SPEED_FREQ, "DynamicSpeedFreq", PERS, 10, "Seconds after which dynamic mode auto speed control increases speed"},
- {LP_DYNAMIC_SPEED_DEC, "DynamicSpeedDec", PERS, 10, "%age by which dynamic mode auto speed control decreases speed on reverse"},
+ {LP_DYNAMIC_SPEED_DEC, "DynamicSpeedDec", PERS, 8, "%age by which dynamic mode auto speed control decreases speed on reverse"},
};
static sp_table stringparamtable[] = {
diff --git a/Src/DasherCore/TwoButtonDynamicFilter.cpp b/Src/DasherCore/TwoButtonDynamicFilter.cpp
index a7d490f..beee743 100644
--- a/Src/DasherCore/TwoButtonDynamicFilter.cpp
+++ b/Src/DasherCore/TwoButtonDynamicFilter.cpp
@@ -38,13 +38,19 @@ static SModuleSettings sSettings[] = {
{BP_TWOBUTTON_REVERSE,T_BOOL, -1, -1, -1, -1, _("Reverse up and down buttons")},
{BP_SLOW_START,T_BOOL, -1, -1, -1, -1, _("Slow startup")},
{LP_SLOW_START_TIME, T_LONG, 0, 10000, 1000, 100, _("Startup time")},
+ {LP_DYNAMIC_BUTTON_LAG, T_LONG, 0, 1000, 1, 25, _("Lag before user actually pushes button (ms)")},
{LP_DYNAMIC_SPEED_INC, T_LONG, 1, 100, 1, 1, _("%age by which to automatically increase speed")},
{LP_DYNAMIC_SPEED_FREQ, T_LONG, 1, 1000, 1, 1, _("Time after which to automatically increase speed (secs)")},
{LP_DYNAMIC_SPEED_DEC, T_LONG, 1, 99, 1, 1, _("%age by which to decrease speed upon reverse")}
};
CTwoButtonDynamicFilter::CTwoButtonDynamicFilter(Dasher::CEventHandler * pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface)
- : CButtonMultiPress(pEventHandler, pSettingsStore, pInterface, 14, 1, _("Two Button Dynamic Mode")) { }
+ : CButtonMultiPress(pEventHandler, pSettingsStore, pInterface, 14, 1, _("Two Button Dynamic Mode"))
+{
+ //ensure that m_dLagMul is properly initialised
+ Dasher::CParameterNotificationEvent oEvent(LP_DYNAMIC_BUTTON_LAG);
+ HandleEvent(&oEvent);
+}
bool CTwoButtonDynamicFilter::DecorateView(CDasherView *pView) {
CDasherScreen *pScreen(pView->Screen());
@@ -102,12 +108,12 @@ void CTwoButtonDynamicFilter::ActionButton(int iTime, int iButton, int iType, CD
iFactor = -1;
if(iButton == 2) {
- pModel->Offset(iFactor * GetLongParameter(LP_TWO_BUTTON_OFFSET));
+ pModel->Offset(iFactor * GetLongParameter(LP_TWO_BUTTON_OFFSET) * m_dLagMul);
if(pUserLog)
pUserLog->KeyDown(iButton, iType, 3);
}
else if((iButton == 3) || (iButton == 4)) {
- pModel->Offset(iFactor * -GetLongParameter(LP_TWO_BUTTON_OFFSET));
+ pModel->Offset(iFactor * -GetLongParameter(LP_TWO_BUTTON_OFFSET) * m_dLagMul);
if(pUserLog)
pUserLog->KeyDown(iButton, iType, 4);
}
@@ -128,3 +134,21 @@ bool CTwoButtonDynamicFilter::GetMinWidth(int &iMinWidth) {
iMinWidth = 1024;
return true;
}
+
+void CTwoButtonDynamicFilter::HandleEvent(Dasher::CEvent *pEvent)
+{
+ if (pEvent->m_iEventType == EV_PARAM_NOTIFY)
+ {
+ Dasher::CParameterNotificationEvent *pEvt = static_cast<Dasher::CParameterNotificationEvent *>(pEvent);
+ switch (pEvt->m_iParameter)
+ {
+ case LP_MAX_BITRATE:
+ case LP_BOOSTFACTOR: // Deliberate fallthrough
+ case LP_DYNAMIC_BUTTON_LAG:
+ {
+ double dMaxRate = GetLongParameter(LP_MAX_BITRATE) * GetLongParameter(LP_BOOSTFACTOR) / 10000.0;
+ m_dLagMul = exp(dMaxRate * GetLongParameter(LP_DYNAMIC_BUTTON_LAG)/1000.0);
+ }
+ }
+ }
+}
diff --git a/Src/DasherCore/TwoButtonDynamicFilter.h b/Src/DasherCore/TwoButtonDynamicFilter.h
index 5219657..3c7cb8d 100644
--- a/Src/DasherCore/TwoButtonDynamicFilter.h
+++ b/Src/DasherCore/TwoButtonDynamicFilter.h
@@ -40,10 +40,13 @@ class CTwoButtonDynamicFilter : public CButtonMultiPress {
virtual bool GetSettings(SModuleSettings **pSettings, int *iCount);
virtual bool GetMinWidth(int &iMinWidth);
+
+ virtual void HandleEvent(Dasher::CEvent *pEvent);
private:
virtual bool TimerImpl(int Time, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted);
virtual void ActionButton(int iTime, int iButton, int iType, CDasherModel *pModel, CUserLogBase *pUserLog);
+ double m_dLagMul;
};
/// @}
diff --git a/Src/DasherCore/TwoPushDynamicFilter.cpp b/Src/DasherCore/TwoPushDynamicFilter.cpp
new file mode 100644
index 0000000..df30642
--- /dev/null
+++ b/Src/DasherCore/TwoPushDynamicFilter.cpp
@@ -0,0 +1,263 @@
+// TwoPushDynamicFilter.cpp
+//
+// Copyright (c) 2007 The Dasher Team
+//
+// This file is part of Dasher.
+//
+// Dasher is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// Dasher is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Dasher; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "../Common/Common.h"
+
+#include "TwoPushDynamicFilter.h"
+#include "DasherInterfaceBase.h"
+#include "Event.h"
+
+static SModuleSettings sSettings[] = {
+ {LP_TWO_PUSH_OUTER, T_LONG, 1024, 2048, 2048, 128, _("Offset for outer (second) button")},
+ {LP_TWO_PUSH_UP, T_LONG, 256, 2048, 2048/*divisor*/, 128/*step*/, _("Distance for 1st button UP")},
+ {LP_TWO_PUSH_DOWN, T_LONG, 256, 2048, 2048, 128, _("Distance for 1st button DOWN")},
+ {LP_TWO_PUSH_TOLERANCE, T_LONG, 50, 1000, 1, 10, _("Tolerance for inaccurate timing of button pushes (in ms)")},
+ /* TRANSLATORS: The time for which a button must be held before it counts as a 'long' (rather than short) press. */
+ {LP_HOLD_TIME, T_LONG, 100, 10000, 1000, 100, _("Long press time")},
+ /* TRANSLATORS: Backoff = reversing in Dasher to correct mistakes. This allows a single button to be dedicated to activating backoff, rather than using multiple presses of other buttons, and another to be dedicated to starting and stopping. 'Button' in this context is a physical hardware device, not a UI element.*/
+ {BP_BACKOFF_BUTTON,T_BOOL, -1, -1, -1, -1, _("Enable backoff and start/stop buttons")},
+ {BP_FIXED_MARKERS, T_BOOL, -1, -1, -1, -1, _("Markers fixed to canvas")},
+ {BP_SLOW_START,T_BOOL, -1, -1, -1, -1, _("Slow startup")},
+ {LP_SLOW_START_TIME, T_LONG, 0, 10000, 1000, 100, _("Slow startup time")},
+ {LP_DYNAMIC_SPEED_INC, T_LONG, 1, 100, 1, 1, _("%age by which to automatically increase speed")},
+ {LP_DYNAMIC_SPEED_FREQ, T_LONG, 1, 1000, 1, 1, _("Time after which to automatically increase speed (secs)")},
+ {LP_DYNAMIC_SPEED_DEC, T_LONG, 1, 99, 1, 1, _("%age by which to decrease speed upon reverse")},
+ {LP_DYNAMIC_BUTTON_LAG, T_LONG, 0, 1000, 1, 25, _("Lag before user actually pushes button (ms)")},
+};
+
+CTwoPushDynamicFilter::CTwoPushDynamicFilter(Dasher::CEventHandler * pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface)
+ : CDynamicFilter(pEventHandler, pSettingsStore, pInterface, 14, 1, _("Two-push Dynamic Mode (New One Button)")) {
+
+ Dasher::CParameterNotificationEvent oEvent(LP_TWO_PUSH_OUTER);//and all the others too!
+ HandleEvent(&oEvent);
+}
+
+void GuideLine(CDasherView *pView, const myint iDasherY, const int iColour)
+{
+ myint iDasherX = -100;
+ CDasherScreen::point p[2];
+ CDasherScreen *pScreen(pView->Screen());
+
+ pView->Dasher2Screen(iDasherX, iDasherY, p[0].x, p[0].y);
+
+ iDasherX = -1000;
+
+ pView->Dasher2Screen(iDasherX, iDasherY, p[1].x, p[1].y);
+
+ pScreen->Polyline(p, 2, 3, iColour);
+}
+
+bool CTwoPushDynamicFilter::DecorateView(CDasherView *pView)
+{
+ //outer guides (yellow rects)
+ for (int i=0; i<2; i++)
+ {
+ screenint x1, y1, x2, y2;
+ CDasherScreen *pScreen(pView->Screen());
+
+ pView->Dasher2Screen(-100, m_aaiGuideAreas[i][0], x1, y1);
+ pView->Dasher2Screen(-1000, m_aaiGuideAreas[i][1], x2, y2);
+
+ pScreen->DrawRectangle(x1, y1, x2, y2, 62/*pale yellow*/, -1, Opts::Nodes1, false, true, 0);
+ }
+
+ //inner guides (red lines)
+ GuideLine(pView, 2048 - GetLongParameter(LP_TWO_PUSH_UP), 1);
+ GuideLine(pView, 2048 + GetLongParameter(LP_TWO_PUSH_DOWN), 1);
+
+ if (GetBoolParameter(BP_FIXED_MARKERS))
+ { //outer guides (at center of rects) - red lines
+ GuideLine(pView, 2048 - GetLongParameter(LP_TWO_PUSH_OUTER), 1);
+ GuideLine(pView, 2048 + GetLongParameter(LP_TWO_PUSH_OUTER), 1);
+ }
+
+ //moving markers - green if active, else yellow
+ int myState;
+ if (m_bDecorationChanged && isRunning(myState) && myState == 1)
+ {
+ for (int i = 0; i < 2; i++)
+ {
+ GuideLine(pView, m_aiMarker[i], (i == m_iActiveMarker) ? 240 : 61/*orange*/);
+ }
+ }
+ bool bRV(m_bDecorationChanged);
+ m_bDecorationChanged = false;
+ return bRV;
+}
+
+void CTwoPushDynamicFilter::HandleEvent(Dasher::CEvent * pEvent)
+{
+ if(pEvent->m_iEventType == EV_PARAM_NOTIFY)
+ {
+ Dasher::CParameterNotificationEvent * pEvt(static_cast < Dasher::CParameterNotificationEvent * >(pEvent));
+ switch (pEvt->m_iParameter)
+ {
+ case LP_TWO_PUSH_OUTER: //deliberate fallthrough
+ case LP_TWO_PUSH_UP: //deliberate fallthrough
+ case LP_TWO_PUSH_DOWN:
+ {
+//cout << "Initializing - outer " << GetLongParameter(LP_TWO_PUSH_OUTER) << " up " << GetLongParameter(LP_TWO_PUSH_UP) << " down " << GetLongParameter(LP_TWO_PUSH_DOWN) << "\n";
+ DASHER_ASSERT (GetLongParameter(LP_TWO_PUSH_UP) < GetLongParameter(LP_TWO_PUSH_OUTER));
+ DASHER_ASSERT (GetLongParameter(LP_TWO_PUSH_DOWN) < GetLongParameter(LP_TWO_PUSH_OUTER));
+ DASHER_ASSERT (GetLongParameter(LP_TWO_PUSH_UP) > GetLongParameter(LP_TWO_PUSH_DOWN));
+ //TODO, that means short gap at the top - allow other way around also?
+
+ double dOuter = GetLongParameter(LP_TWO_PUSH_OUTER);
+ m_dLogUpMul = log(dOuter / (double)GetLongParameter(LP_TWO_PUSH_UP));
+ m_dLogDownMul = log(dOuter / (double)GetLongParameter(LP_TWO_PUSH_DOWN));
+ m_dSqrtUpDist = exp(m_dLogUpMul / 2.0);
+ m_dSqrtDownDist = exp(m_dLogDownMul / 2.0);
+//cout << "bitsUp " << m_dLogUpMul << " bitsDown " << m_dLogDownMul << " upDist " << m_dSqrtUpDist << " downDist " << m_dSqrtDownDist << "\n";
+ } //and fallthrough
+ case LP_TWO_PUSH_TOLERANCE:
+ case LP_MAX_BITRATE:
+ case LP_BOOSTFACTOR: // Deliberate fallthrough
+ {
+ double dMaxRate = GetLongParameter(LP_MAX_BITRATE) * GetLongParameter(LP_BOOSTFACTOR) / 10000.0;
+ double dPressBits = dMaxRate * (double) GetLongParameter(LP_TWO_PUSH_TOLERANCE) / 1000.0;
+//cout << "Max Bitrate changed - now " << dMaxRate << " user accuracy " << dPressBits;
+ m_dMinShortTwoPushTime = m_dLogUpMul - dPressBits;
+//cout << "bits; minShort " << m_dMinShortTwoPushTime;
+ m_dMaxShortTwoPushTime = m_dLogUpMul + dPressBits;
+ m_dMinLongTwoPushTime = m_dLogDownMul - dPressBits;
+ if (m_dMaxShortTwoPushTime > m_dMinLongTwoPushTime)
+ m_dMaxShortTwoPushTime = m_dMinLongTwoPushTime = (m_dLogUpMul + m_dLogDownMul)/2.0;
+ m_dMaxLongTwoPushTime = m_dLogDownMul + dPressBits;
+//TODO, what requirements do we actually need to make to ensure sanity (specifically, that computed m_aiTarget's are in range)?
+//cout << " maxShort " << m_dMaxShortTwoPushTime << " minLong " << m_dMinLongTwoPushTime << " maxLong " << m_dMaxLongTwoPushTime << "\n";
+ m_bDecorationChanged = true;
+ } //and fallthrough again
+ case LP_DYNAMIC_BUTTON_LAG:
+ {
+ double dMaxRate = GetLongParameter(LP_MAX_BITRATE) * GetLongParameter(LP_BOOSTFACTOR) / 10000.0;
+ m_dLagBits = dMaxRate * GetLongParameter(LP_DYNAMIC_BUTTON_LAG)/1000.0;
+ //cout << " lag (" << m_dLagBits[0] << ", " << m_dLagBits[1] << ", " << m_dLagBits[2] << ", " << m_dLagBits[3] << ")";
+ } //and fallthrough
+ case BP_FIXED_MARKERS:
+ if (GetBoolParameter(BP_FIXED_MARKERS))
+ {
+ m_aaiGuideAreas[0][0] = 2048 - GetLongParameter(LP_TWO_PUSH_UP)*exp(m_dMaxShortTwoPushTime);
+ m_aaiGuideAreas[0][1] = 2048 - GetLongParameter(LP_TWO_PUSH_UP)*exp(m_dMinShortTwoPushTime);
+ m_aaiGuideAreas[1][0] = 2048 + GetLongParameter(LP_TWO_PUSH_DOWN)*exp(m_dMinLongTwoPushTime);
+ m_aaiGuideAreas[1][1] = 2048 + GetLongParameter(LP_TWO_PUSH_DOWN)*exp(m_dMaxLongTwoPushTime);
+ }
+ else
+ {
+ m_aaiGuideAreas[0][0] = 2048 - GetLongParameter(LP_TWO_PUSH_UP) * exp(m_dMaxShortTwoPushTime / 2.0) * m_dSqrtUpDist;
+ m_aaiGuideAreas[0][1] = 2048 - GetLongParameter(LP_TWO_PUSH_UP) * exp(m_dMinShortTwoPushTime / 2.0) * m_dSqrtUpDist;
+ m_aaiGuideAreas[1][0] = 2048 + GetLongParameter(LP_TWO_PUSH_DOWN) * exp(m_dMinLongTwoPushTime / 2.0) * m_dSqrtDownDist;
+ m_aaiGuideAreas[1][1] = 2048 + GetLongParameter(LP_TWO_PUSH_DOWN) * exp(m_dMaxLongTwoPushTime / 2.0) * m_dSqrtDownDist;
+ }
+ break;
+ }
+ }
+
+};
+
+void CTwoPushDynamicFilter::ActionButton(int iTime, int iButton, int iType, CDasherModel *pModel, CUserLogBase *pUserLog) {
+ // Types:
+ // 0 = ordinary click
+ // 1 = long click
+ int myState;
+ if (!isRunning(myState)) DASHER_ASSERT(false);
+
+ if (myState == 0) //no button pushed (recently)
+ {
+//cout << "First push - event type " << iType << " \n";
+ pModel->GetNats();
+ run(1);
+ pModel->ResetNats();
+ }
+ else
+ {
+ DASHER_ASSERT (myState == 1);
+//cout << "Second push - event type " << iType << " logGrowth " << pModel->GetNats() << "\n";
+ if (m_iActiveMarker == -1)
+ reverse();
+ else
+ {
+ pModel->Offset(m_aiTarget[m_iActiveMarker]);
+ pModel->ResetNats();
+ run(0);
+ }
+ }
+}
+bool doSet(int &var, const int val)
+{
+ if (var == val) return false;
+ var = val;
+ return true;
+}
+
+bool CTwoPushDynamicFilter::TimerImpl(int iTime, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted)
+{
+ int myState;
+ if (!isRunning(myState)) DASHER_ASSERT(false);
+ if (myState == 1) // button pushed
+ {
+ double dLogGrowth(m_pDasherModel->GetNats());
+ double dUpDist = exp(dLogGrowth/2.0) * m_dSqrtUpDist * GetLongParameter(LP_TWO_PUSH_UP);
+ double dDownDist = exp(dLogGrowth/2.0)*m_dSqrtDownDist*GetLongParameter(LP_TWO_PUSH_DOWN);
+ m_aiTarget[0] = dUpDist * exp(m_dLagBits);
+ m_aiTarget[1] = -dDownDist * exp(m_dLagBits);
+ if (GetBoolParameter(BP_FIXED_MARKERS))
+ {
+ m_bDecorationChanged |= doSet(m_aiMarker[0], 2048 - GetLongParameter(LP_TWO_PUSH_UP)*exp(m_dLagBits + dLogGrowth));
+ m_bDecorationChanged |= doSet(m_aiMarker[1], 2048 + GetLongParameter(LP_TWO_PUSH_DOWN)*exp(m_dLagBits + dLogGrowth));
+ }
+ else
+ {
+ m_bDecorationChanged |= doSet(m_aiMarker[0], 2048 - dUpDist * exp(m_dLagBits/2.0));
+ m_bDecorationChanged |= doSet(m_aiMarker[1], 2048 + dDownDist * exp(m_dLagBits/2.0));
+ }
+ if (dLogGrowth > m_dMaxLongTwoPushTime)
+ {
+//cout << " growth " << dLogGrowth << " - reversing\n";
+ //button pushed, but then waited too long.
+ reverse();
+ }
+ else if (dLogGrowth >= m_dMinShortTwoPushTime && dLogGrowth <= m_dMaxShortTwoPushTime)
+ m_bDecorationChanged |= doSet(m_iActiveMarker, 0 /*up*/);
+ else if (dLogGrowth >= m_dMinLongTwoPushTime)
+ m_bDecorationChanged |= doSet(m_iActiveMarker, 1 /*down*/);
+ else m_bDecorationChanged |= doSet(m_iActiveMarker, -1 /*in middle (neither/both) or too short*/);
+ }
+ m_pDasherModel->OneStepTowards(100, 2048, iTime, pAdded, pNumDeleted);
+}
+
+void CTwoPushDynamicFilter::Activate() {
+ SetBoolParameter(BP_DELAY_VIEW, true);
+}
+
+void CTwoPushDynamicFilter::Deactivate() {
+ SetBoolParameter(BP_DELAY_VIEW, false);
+}
+
+bool CTwoPushDynamicFilter::GetSettings(SModuleSettings **pSettings, int *iCount) {
+ *pSettings = sSettings;
+ *iCount = sizeof(sSettings) / sizeof(SModuleSettings);
+
+ return true;
+};
+
+bool CTwoPushDynamicFilter::GetMinWidth(int &iMinWidth) {
+ iMinWidth = 1024;
+ return true;
+}
diff --git a/Src/DasherCore/TwoPushDynamicFilter.h b/Src/DasherCore/TwoPushDynamicFilter.h
new file mode 100644
index 0000000..38b027c
--- /dev/null
+++ b/Src/DasherCore/TwoPushDynamicFilter.h
@@ -0,0 +1,56 @@
+// TwoPushDynamicFilter.h
+//
+// Copyright (c) 2007 The Dasher Team
+//
+// This file is part of Dasher.
+//
+// Dasher is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// Dasher is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Dasher; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef __TWO_PUSH_DYNAMIC_FILTER_H__
+#define __TWO_PUSH_DYNAMIC_FILTER_H__
+
+#include "DynamicFilter.h"
+
+/// \ingroup InputFilter
+/// @{
+class CTwoPushDynamicFilter : public CDynamicFilter /*long push, but do our own "multi-push" detection*/ {
+ public:
+ CTwoPushDynamicFilter(Dasher::CEventHandler * pEventHandler, CSettingsStore *pSettingsStore, CDasherInterfaceBase *pInterface);
+
+ // Inherited methods
+ virtual bool DecorateView(CDasherView *pView);
+
+ virtual void Activate();
+ virtual void Deactivate();
+ virtual bool GetMinWidth(int &iMinWidth);
+ virtual bool GetSettings(SModuleSettings **pSettings, int *iCount);
+ protected:
+ virtual bool TimerImpl(int Time, CDasherView *m_pDasherView, CDasherModel *m_pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted);
+ virtual void ActionButton(int iTime, int iButton, int iType, CDasherModel *pModel, CUserLogBase *pUserLog);
+
+ virtual void HandleEvent(Dasher::CEvent * pEvent);
+
+ private:
+ double m_dLogUpMul, m_dLogDownMul, m_dSqrtUpDist, m_dSqrtDownDist, m_dLagBits;
+ double m_dMinShortTwoPushTime, m_dMaxShortTwoPushTime,
+ m_dMinLongTwoPushTime, m_dMaxLongTwoPushTime;
+ int m_aiMarker[2];
+ int m_iActiveMarker;
+ int m_aiTarget[2];
+ int m_aaiGuideAreas[2][2];
+};
+/// @}
+
+#endif
\ No newline at end of file
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]