[dasher] In two-button dynamic mode, add option to invert the sense of a
- From: Patrick Welche <pwelche src gnome org>
- To: svn-commits-list gnome org
- Subject: [dasher] In two-button dynamic mode, add option to invert the sense of a
- Date: Thu, 2 Jul 2009 12:33:13 +0000 (UTC)
commit 7ef84213b013eb2f18ce344179488a32b1d8d15c
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date: Thu Jul 2 13:32:38 2009 +0100
In two-button dynamic mode, add option to invert the sense of a
double-click. (Includes partial implementation of RevertPresses)
ChangeLog | 2 +
Src/DasherCore/ButtonMultiPress.cpp | 46 ++++++++++++-------------
Src/DasherCore/ButtonMultiPress.h | 1 +
Src/DasherCore/DynamicFilter.cpp | 3 +-
Src/DasherCore/DynamicFilter.h | 2 +-
Src/DasherCore/OneButtonDynamicFilter.cpp | 6 +--
Src/DasherCore/OneButtonDynamicFilter.h | 1 +
Src/DasherCore/Parameters.h | 8 ++--
Src/DasherCore/TwoButtonDynamicFilter.cpp | 53 +++++++++++++++++++++++-----
Src/DasherCore/TwoButtonDynamicFilter.h | 8 ++++
10 files changed, 85 insertions(+), 45 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 974263c..7ba826c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,8 @@
* Remove NodeManagerFactory class.
* Remove CControlManagerFactory class.
* Rename BP_DELAY_VIEW to BP_SMOOTH_OFFSET and tidy its handling.
+ * In two-button dynamic mode, add option to invert the sense of a
+ double-click.
2009-07-02 Patrick Welche <prlw1 cam ac uk>
diff --git a/Src/DasherCore/ButtonMultiPress.cpp b/Src/DasherCore/ButtonMultiPress.cpp
index 0f777ae..ace0652 100644
--- a/Src/DasherCore/ButtonMultiPress.cpp
+++ b/Src/DasherCore/ButtonMultiPress.cpp
@@ -30,34 +30,32 @@ void CButtonMultiPress::KeyDown(int iTime, int iId, CDasherView *pView, CDasherM
if (m_bKeyDown) return;
// Check for multiple clicks
- if(iId == m_iQueueId) {
- while((m_deQueueTimes.size() > 0) && (iTime - m_deQueueTimes.front()) > GetLongParameter(LP_MULTIPRESS_TIME))
- m_deQueueTimes.pop_front();
-
- //if that's the final press...
- if(m_deQueueTimes.size() == static_cast<unsigned int>(GetLongParameter(LP_MULTIPRESS_COUNT) - 1)) {
- //undo the preceding ones...
- RevertPresses(GetLongParameter(LP_MULTIPRESS_COUNT) - 1);
- //execute the event
- Event(iTime, iId, 2, pModel, pUserLog);
- m_deQueueTimes.clear();
- }
- else {
- //not the final press; so record...
- m_deQueueTimes.push_back(iTime);
- //and process normally
- //(this may clear the queue if it changes the state)
- CDynamicFilter::KeyDown(iTime, iId, pView, pModel, pUserLog);
+ if(iId == m_iQueueId && m_deQueueTimes.size()) {
+ if ( (iTime - m_deQueueTimes.back()) > GetLongParameter(LP_MULTIPRESS_TIME) )
+ m_deQueueTimes.clear(); //and fall through to record+process normally, below
+ else
+ {
+ //previous presses should not be treated as such....
+ RevertPresses(m_deQueueTimes.size());
+ //...but should be combined with this one into a new event (type = #presses)
+ Event(iTime, iId, m_deQueueTimes.size()+1, pModel, pUserLog);
+ if (m_deQueueTimes.size() >= maxClickCount() - 1)
+ m_deQueueTimes.clear(); //final press
+ else //may still be more presses to come
+ m_deQueueTimes.push_back(iTime);
+ return; //we've called Event ourselves, so finished.
}
}
- else {
- //record as first press...
- m_deQueueTimes.clear();
- m_deQueueTimes.push_back(iTime);
+ else
+ {
+ m_deQueueTimes.clear(); //clear record of previous, different, button
m_iQueueId = iId;
- //...and process normally; if it changes the state, pause()/reverse()'ll clear the queue
- CDynamicFilter::KeyDown(iTime, iId, pView, pModel, pUserLog);
}
+
+ //record press...
+ m_deQueueTimes.push_back(iTime);
+ //...and process normally; if it changes the state, pause()/reverse()'ll clear the queue
+ CDynamicFilter::KeyDown(iTime, iId, pView, pModel, pUserLog);
}
void CButtonMultiPress::pause()
diff --git a/Src/DasherCore/ButtonMultiPress.h b/Src/DasherCore/ButtonMultiPress.h
index cb172c8..faf4026 100644
--- a/Src/DasherCore/ButtonMultiPress.h
+++ b/Src/DasherCore/ButtonMultiPress.h
@@ -33,6 +33,7 @@ class CButtonMultiPress : public CDynamicFilter {
virtual void KeyDown(int iTime, int iId, CDasherView *pView, CDasherModel *pModel, CUserLogBase *pUserLog);
protected:
+ virtual unsigned int maxClickCount()=0;
virtual void reverse();
virtual void pause();
virtual void run(int iSubclassState);
diff --git a/Src/DasherCore/DynamicFilter.cpp b/Src/DasherCore/DynamicFilter.cpp
index 8c1416f..d83e449 100644
--- a/Src/DasherCore/DynamicFilter.cpp
+++ b/Src/DasherCore/DynamicFilter.cpp
@@ -120,8 +120,7 @@ void CDynamicFilter::Event(int iTime, int iButton, int iType, CDasherModel *pMod
ActionButton(iTime, iButton, iType, pModel, pUserLog);
}
break;
- case 1: // Delibarate fallthrough
- case 2:
+ default: // _Any_ other kind of event - long, double, triple, ...
if((iButton >= 2) && (iButton <= 4)) {
if(pUserLog)
pUserLog->KeyDown(iButton, iType, 6);
diff --git a/Src/DasherCore/DynamicFilter.h b/Src/DasherCore/DynamicFilter.h
index e9a4646..db702b5 100644
--- a/Src/DasherCore/DynamicFilter.h
+++ b/Src/DasherCore/DynamicFilter.h
@@ -40,7 +40,7 @@ class CDynamicFilter : public CInputFilter {
protected:
virtual void ActionButton(int iTime, int iButton, int iType, CDasherModel *pModel, CUserLogBase *pUserLog) = 0;
- void Event(int iTime, int iButton, int iType, CDasherModel *pModel, CUserLogBase *pUserLog);
+ virtual void Event(int iTime, int iButton, int iType, CDasherModel *pModel, CUserLogBase *pUserLog);
bool m_bKeyDown;
bool m_bKeyHandled;
diff --git a/Src/DasherCore/OneButtonDynamicFilter.cpp b/Src/DasherCore/OneButtonDynamicFilter.cpp
index 7911747..b187c6a 100644
--- a/Src/DasherCore/OneButtonDynamicFilter.cpp
+++ b/Src/DasherCore/OneButtonDynamicFilter.cpp
@@ -27,10 +27,8 @@
static SModuleSettings sSettings[] = {
/* 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: Multiple button presses are special (like a generalisation on double clicks) in some situations. This is the time in which the button must be pressed multiple times to count.*/
- {LP_MULTIPRESS_TIME, T_LONG, 100, 10000, 1000, 100, _("Multiple press time")},
- /* TRANSLATORS: Multiple button presses are special (like a generalisation on double clicks) in some situations. This is the number of times a button must be pressed to count as a multiple press.*/
- {LP_MULTIPRESS_COUNT,T_LONG, 2, 10, 1, 1, _("Multiple press count")},
+ /* TRANSLATORS: Double-clicks are special in some situations (they cause us to start reversing). This is the time in which the button must be pressed twice to count.*/
+ {LP_MULTIPRESS_TIME, T_LONG, 100, 10000, 1000, 100, _("Double-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.*/
{BP_BACKOFF_BUTTON,T_BOOL, -1, -1, -1, -1, _("Enable backoff button")},
{BP_SLOW_START,T_BOOL, -1, -1, -1, -1, _("Slow startup")},
diff --git a/Src/DasherCore/OneButtonDynamicFilter.h b/Src/DasherCore/OneButtonDynamicFilter.h
index f79bcd9..4d43410 100644
--- a/Src/DasherCore/OneButtonDynamicFilter.h
+++ b/Src/DasherCore/OneButtonDynamicFilter.h
@@ -35,6 +35,7 @@ class COneButtonDynamicFilter : public CButtonMultiPress {
virtual bool GetSettings(SModuleSettings **pSettings, int *iCount);
private:
+ unsigned int maxClickCount() {return 2;} //double-click to reverse
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);
diff --git a/Src/DasherCore/Parameters.h b/Src/DasherCore/Parameters.h
index 68df370..ed0358d 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_SMOOTH_OFFSET, BP_CONVERSION_MODE, BP_PAUSE_OUTSIDE, BP_BACKOFF_BUTTON,
- BP_TWOBUTTON_REVERSE, BP_SLOW_START, BP_FIXED_MARKERS, END_OF_BPS
+ BP_TWOBUTTON_REVERSE, BP_2B_INVERT_DOUBLE, BP_SLOW_START, BP_FIXED_MARKERS, END_OF_BPS
};
enum {
@@ -58,7 +58,7 @@ enum {
LP_ZOOMSTEPS, LP_B, LP_S, LP_Z, LP_R, LP_RIGHTZOOM,
LP_BOOSTFACTOR, LP_AUTOSPEED_SENSITIVITY, LP_SOCKET_PORT, LP_SOCKET_INPUT_X_MIN, LP_SOCKET_INPUT_X_MAX,
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_CIRCLE_PERCENT, LP_TWO_BUTTON_OFFSET, LP_HOLD_TIME, LP_MULTIPRESS_TIME,
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,
@@ -157,11 +157,12 @@ static bp_table boolparamtable[] = {
{BP_OLD_STYLE_PUSH, "OldStylePush", PERS, false, "Old style node pushing algorithm"},
{BP_CIRCLE_START, "CircleStart", PERS, false, "Start on circle mode"},
{BP_GLOBAL_KEYBOARD, "GlobalKeyboard", PERS, false, "Whether to assume global control of the keyboard"},
- {BP_SMOOTH_OFFSET, "DelayView", !PERS, false, "Smooth dynamic button mode jumps over several frames"},
+ {BP_SMOOTH_OFFSET, "DelayView", !PERS, false, "Smooth dynamic-button-mode jumps over several frames"},
{BP_CONVERSION_MODE, "ConversionMode", !PERS, false, "Whether Dasher is operating in conversion (eg Japanese) mode"},
{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_2B_INVERT_DOUBLE, "TwoButtonInvertDouble", PERS, false, "Double-press acts as opposite button in two-button mode"},
{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"},
};
@@ -212,7 +213,6 @@ static lp_table longparamtable[] = {
{LP_TWO_BUTTON_OFFSET, "TwoButtonOffset", PERS, 1638, "Offset for two button dynamic mode"},
{LP_HOLD_TIME, "HoldTime", PERS, 1000, "Time for which buttons must be held to count as long presses, in ms"},
{LP_MULTIPRESS_TIME, "MultipressTime", PERS, 1000, "Time in which multiple presses must occur, in ms"},
- {LP_MULTIPRESS_COUNT, "MultipressCount", PERS, 2, "Time in which multiple presses must occur to count"},
{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"},
diff --git a/Src/DasherCore/TwoButtonDynamicFilter.cpp b/Src/DasherCore/TwoButtonDynamicFilter.cpp
index 8802f41..19beeb8 100644
--- a/Src/DasherCore/TwoButtonDynamicFilter.cpp
+++ b/Src/DasherCore/TwoButtonDynamicFilter.cpp
@@ -28,14 +28,16 @@ static SModuleSettings sSettings[] = {
{LP_TWO_BUTTON_OFFSET, T_LONG, 1024, 2048, 2048, 100, _("Button offset")},
/* 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: Multiple button presses are special (like a generalisation on double clicks) in some situations. This is the time in which the button must be pressed multiple times to count.*/
- {LP_MULTIPRESS_TIME, T_LONG, 100, 10000, 1000, 100, _("Multiple press time")},
- /* TRANSLATORS: Multiple button presses are special (like a generalisation on double clicks) in some situations. This is the number of times a button must be pressed to count as a multiple press.*/
- {LP_MULTIPRESS_COUNT,T_LONG, 2, 10, 1, 1, _("Multiple press count")},
+ /* TRANSLATORS: Multiple button presses are special (like a generalisation on double clicks) in some situations. This is the maximum time between two presses to count as _part_of_ a multi-press gesture
+ (potentially more than two presses). */
+ {LP_MULTIPRESS_TIME, T_LONG, 100, 10000, 1000, 100, _("Multiple press interval")},
/* 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")},
/* TRANSLATORS: What is normally the up button becomes the down button etc. */
{BP_TWOBUTTON_REVERSE,T_BOOL, -1, -1, -1, -1, _("Reverse up and down buttons")},
+ /* TRANSLATORS: Pushing the up/down button twice quickly has the same effect as pushing the other
+ button once; in this case, one must push three times (or push-and-hold) to reverse. */
+ {BP_2B_INVERT_DOUBLE, T_BOOL, -1, -1, -1, -1, _("Double-click is opposite up/down - triple to reverse")},
{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)")},
@@ -45,7 +47,7 @@ static SModuleSettings sSettings[] = {
};
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")), m_dMulSinceFirstPush(1.0)
{
//ensure that m_dLagMul is properly initialised
Dasher::CParameterNotificationEvent oEvent(LP_DYNAMIC_BUTTON_LAG);
@@ -103,19 +105,50 @@ void CTwoButtonDynamicFilter::Deactivate() {
void CTwoButtonDynamicFilter::run(int iState) {
SetBoolParameter(BP_SMOOTH_OFFSET, true);
- CDynamicFilter::run(iState);
+ CButtonMultiPress::run(iState);
}
void CTwoButtonDynamicFilter::pause() {
SetBoolParameter(BP_SMOOTH_OFFSET, false);
- CDynamicFilter::pause();
+ CButtonMultiPress::pause();
}
void CTwoButtonDynamicFilter::reverse() {
//hmmmm. If we ever actually did Offset() while reversing,
// we might want BP_SMOOTH_OFFSET on....
SetBoolParameter(BP_SMOOTH_OFFSET, false);
- CDynamicFilter::reverse();
+ CButtonMultiPress::reverse();
+}
+
+void CTwoButtonDynamicFilter::Event(int iTime, int iButton, int iType, CDasherModel *pModel, CUserLogBase *pUserLog)
+{
+ if (GetBoolParameter(BP_2B_INVERT_DOUBLE) && iType == 2 && iButton>=2 && iButton<=4)
+ { //double-press - treat as single-press of the other button....
+ iType = 0; //0=normal, 1=long press
+ iButton = (iButton == 2) ? 3 : 2;
+ m_dMulSinceFirstPush = exp(pModel->GetNats());
+ }
+ CDynamicFilter::Event(iTime, iButton, iType, pModel, pUserLog);
+}
+
+void CTwoButtonDynamicFilter::ApplyOffset(CDasherModel *pModel, long lOffset)
+{
+ lOffset *= m_dMulSinceFirstPush; m_dMulSinceFirstPush = 1.0;
+ pModel->Offset(lOffset);
+ m_pModel = pModel;
+ m_lOffsetApplied = lOffset;
+ pModel->ResetNats();
+}
+
+void CTwoButtonDynamicFilter::RevertPresses(int iCount)
+{
+ //invert the *last* invocation of ApplyOffset.
+ //this'll handle reverting single clicks and (if BP_2B_INVERT_DOUBLE is on) double-clicks,
+ //but we'll get into trouble if the user e.g. double-presses the reverse button!
+
+ //correct for expansion since the first click, if any (if we've rendered any frames!)
+ m_pModel->Offset(-m_lOffsetApplied * exp(m_pModel->GetNats()));
+ m_lOffsetApplied = 0;
}
void CTwoButtonDynamicFilter::ActionButton(int iTime, int iButton, int iType, CDasherModel *pModel, CUserLogBase *pUserLog) {
@@ -125,12 +158,12 @@ void CTwoButtonDynamicFilter::ActionButton(int iTime, int iButton, int iType, CD
iFactor = -1;
if(iButton == 2) {
- pModel->Offset(iFactor * GetLongParameter(LP_TWO_BUTTON_OFFSET) * m_dLagMul);
+ ApplyOffset(pModel, 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) * m_dLagMul);
+ ApplyOffset(pModel, iFactor * -GetLongParameter(LP_TWO_BUTTON_OFFSET) * m_dLagMul);
if(pUserLog)
pUserLog->KeyDown(iButton, iType, 4);
}
diff --git a/Src/DasherCore/TwoButtonDynamicFilter.h b/Src/DasherCore/TwoButtonDynamicFilter.h
index 1362926..a1b818b 100644
--- a/Src/DasherCore/TwoButtonDynamicFilter.h
+++ b/Src/DasherCore/TwoButtonDynamicFilter.h
@@ -44,14 +44,22 @@ class CTwoButtonDynamicFilter : public CButtonMultiPress {
virtual void HandleEvent(Dasher::CEvent *pEvent);
protected:
+ void Event(int iTime, int iButton, int iType, CDasherModel *pModel, CUserLogBase *pUserLog);
virtual void run(int iState);
virtual void pause();
virtual void reverse();
private:
+ unsigned int maxClickCount() {return GetBoolParameter(BP_2B_INVERT_DOUBLE) ? 3 : 2;}
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;
+
+ void RevertPresses(int iCount);
+ void ApplyOffset(CDasherModel *pModel, long lOffset);
+ CDasherModel *m_pModel;
+ long m_lOffsetApplied;
+ double m_dMulSinceFirstPush;
};
/// @}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]