[dasher] Fix button (menu/direct) modes



commit fcfca356e608720f2655ee624235167add8a9137
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date:   Fri Jul 8 12:54:52 2011 +0100

    Fix button (menu/direct) modes
    
    ButtonMode needed to be SettingsObserver to see changes to LP_R/LP_B;
      tidy SetupBoxes; redraw to see effect immediately on setting change
    
    Fix scanning (used wrong type for Time)
    
    Scan/select if click in top/bottom half of screen in menu mode
      (or just select anywhere, if auto-scanning).

 Src/DasherCore/ButtonMode.cpp    |   83 +++++++++++++++++--------------------
 Src/DasherCore/ButtonMode.h      |    2 +-
 Src/DasherCore/DasherButtons.cpp |    2 +-
 Src/DasherCore/DasherButtons.h   |    2 +-
 4 files changed, 41 insertions(+), 48 deletions(-)
---
diff --git a/Src/DasherCore/ButtonMode.cpp b/Src/DasherCore/ButtonMode.cpp
index 4a55f0c..834675e 100644
--- a/Src/DasherCore/ButtonMode.cpp
+++ b/Src/DasherCore/ButtonMode.cpp
@@ -42,7 +42,7 @@ static SModuleSettings sSettings[] = {
 // FIX iStyle == 0
 
 CButtonMode::CButtonMode(CSettingsUser *pCreator, CDasherInterfaceBase *pInterface, bool bMenu, int iID, const char *szName)
-: CDasherButtons(pCreator, pInterface, bMenu, iID, szName) {}
+: CDasherButtons(pCreator, pInterface, bMenu, iID, szName), CSettingsObserver(pCreator) {}
 
 void CButtonMode::SetupBoxes()
 {
@@ -54,12 +54,9 @@ void CButtonMode::SetupBoxes()
   // Calculate the sizes of non-uniform boxes using standard
   // geometric progression results
 
-  double dRatio;
-  double dNorm;
-
   // FIXME - implement this using DJCM's integer method?
   // See ~mackay/dasher/buttons/
-  dRatio = pow(129/127.0, -static_cast<double>(GetLongParameter(LP_R)));
+  const double dRatio = pow(129/127.0, -static_cast<double>(GetLongParameter(LP_R)));
 
   if(m_bMenu) {
 
@@ -89,24 +86,19 @@ void CButtonMode::SetupBoxes()
 
   }
   else {
-    if(iForwardBoxes == 2+1) { // Special case for two forwards buttons
-      dNorm = 1+dRatio;
+    if(iForwardBoxes == 2) { // Special case for two forwards buttons
+      myint iMid = static_cast<int>(iDasherY / (1.0+dRatio));
 
       m_pBoxes[0].iDisplayTop = 0;
-      m_pBoxes[0].iDisplayBottom = int( (1 / dNorm) * iDasherY );
+      m_pBoxes[0].iDisplayBottom = iMid;
 
-      m_pBoxes[1].iDisplayTop = int( (1 / dNorm) * iDasherY );
+      m_pBoxes[1].iDisplayTop = iMid;
       m_pBoxes[1].iDisplayBottom = iDasherY;
     }
     else {
       bool bEven(iForwardBoxes % 2 == 0);
 
-      int iGeometricTerms;
-
-      if(bEven)
-        iGeometricTerms = iForwardBoxes / 2;
-      else
-        iGeometricTerms = (1+iForwardBoxes) / 2;
+      const int iGeometricTerms = (iForwardBoxes+1)/2; //int div, round down
 
       double dMaxSize;
 
@@ -120,28 +112,14 @@ void CButtonMode::SetupBoxes()
           dMaxSize = iDasherY * (dRatio - 1) / (2 * (pow(dRatio, iGeometricTerms) - 1) - (dRatio - 1));
       }
 
-      double dMin;
-      double dMax;
+      double dMin = (bEven) ? iDasherY/2.0 : (iDasherY-dMaxSize)/2.0;
 
-      if(bEven)
-        dMin = iDasherY / 2;
-      else
-        dMin = (iDasherY - dMaxSize)/2;
+      const int iUpBase = iForwardBoxes/2; //int div, round down if !bEven
+      const int iDownBase = bEven ? iUpBase-1 : iUpBase;
 
-      int iUpBase;
-      int iDownBase;
-
-      if(bEven) {
-        iUpBase = iForwardBoxes / 2;
-        iDownBase = iUpBase - 1;
-      }
-      else {
-        iUpBase = (iForwardBoxes - 1)/ 2;
-        iDownBase = iUpBase;
-      }
 
       for(int i(0); i < iGeometricTerms; ++i) { // One button reserved for backoff
-        dMax = dMin + dMaxSize * pow(dRatio, i);
+        const double dMax = dMin + dMaxSize * pow(dRatio, i);
 
         m_pBoxes[iUpBase + i].iDisplayTop = int(dMin);
         m_pBoxes[iUpBase + i].iDisplayBottom = int(dMax);
@@ -190,21 +168,35 @@ bool CButtonMode::Timer(unsigned long Time, CDasherView *pView, CDasherInput *pI
 
 void CButtonMode::KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, bool bPos, int iX, int iY)
 {
-  if (iId == 100 && !m_bMenu) {
+  if (iId == 100) {
     //Mouse!
-    myint iDasherX, iDasherY;
-    pInput->GetDasherCoords(iDasherX, iDasherY, pView);
-    for (int i = 0; i < m_iNumBoxes; i++)
-    {
-      if (iDasherY < m_pBoxes[i].iDisplayBottom &&
-          iDasherY > m_pBoxes[i].iDisplayTop &&
-          iDasherX < (m_pBoxes[i].iDisplayBottom - m_pBoxes[i].iDisplayTop)) {
-        //user has clicked in box! Simulate press of appropriate (direct-mode) button...
-        CDasherButtons::KeyDown(iTime, (i==m_iNumBoxes-1) ? 1 : i+2, pView, pInput, pModel);
-        return;
+    if (m_bMenu) {
+      bool bScan;
+      if (GetLongParameter(LP_BUTTON_SCAN_TIME))
+        bScan = false; //auto-scan, any click selects
+      else {
+        //top scans, bottom selects
+        screenint iScreenX, iScreenY;
+        pInput->GetScreenCoords(iScreenX, iScreenY, pView);
+        bScan = iScreenY < pView->Screen()->GetHeight()/2;
+      }
+      CDasherButtons::KeyDown(iTime, bScan ? 1 : 2, pView, pInput, pModel);
+      return;
+    } else {
+      myint iDasherX, iDasherY;
+      pInput->GetDasherCoords(iDasherX, iDasherY, pView);
+      //look for a click _in_ a box -> activate box
+      for (int i = 0; i < m_iNumBoxes; i++) {
+        if (iDasherY < m_pBoxes[i].iDisplayBottom &&
+            iDasherY > m_pBoxes[i].iDisplayTop &&
+            iDasherX < (m_pBoxes[i].iDisplayBottom - m_pBoxes[i].iDisplayTop)) {
+          //user has clicked in box! Simulate press of appropriate (direct-mode) button...
+          CDasherButtons::KeyDown(iTime, (i==m_iNumBoxes-1) ? 1 : i+2, pView, pInput, pModel);
+          return;
+        }
       }
+      //not in any box. Fall through, just to be conservative...
     }
-    //not in any box. Fall through, just to be conservative...
   }
   CInputFilter::KeyDown(iTime, iId, pView, pInput, pModel, bPos, iX, iY);
 }
@@ -221,6 +213,7 @@ void CButtonMode::HandleEvent(int iParameter) {
     // Delibarate fallthrough
     delete[] m_pBoxes;
     SetupBoxes();
+    m_pInterface->ScheduleRedraw();
     break;
   }
 }
diff --git a/Src/DasherCore/ButtonMode.h b/Src/DasherCore/ButtonMode.h
index e384ee8..c314619 100644
--- a/Src/DasherCore/ButtonMode.h
+++ b/Src/DasherCore/ButtonMode.h
@@ -18,7 +18,7 @@ namespace Dasher {
 /// \ingroup Input
 /// @{
 /// Handles the "menu mode" and "direct mode" input filters, according to the bMenu constructor parameter.
-class CButtonMode : public CDasherButtons
+class CButtonMode : public CDasherButtons, protected CSettingsObserver
 {
  public:
   CButtonMode(CSettingsUser *pCreator, CDasherInterfaceBase *pInterface, bool bMenu, int iID, const char *szName);
diff --git a/Src/DasherCore/DasherButtons.cpp b/Src/DasherCore/DasherButtons.cpp
index dc89730..e52b9a2 100644
--- a/Src/DasherCore/DasherButtons.cpp
+++ b/Src/DasherCore/DasherButtons.cpp
@@ -36,7 +36,7 @@ void CDasherButtons::Activate() {
   // which depends on it, tho...
   if (!m_pBoxes) SetupBoxes();
 
-  m_iScanTime = std::numeric_limits<int>::min();
+  m_iScanTime = std::numeric_limits<unsigned long>::min();
 }
 
 void CDasherButtons::KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel) {
diff --git a/Src/DasherCore/DasherButtons.h b/Src/DasherCore/DasherButtons.h
index cf2fb6a..cff04ad 100644
--- a/Src/DasherCore/DasherButtons.h
+++ b/Src/DasherCore/DasherButtons.h
@@ -45,7 +45,7 @@ class CDasherButtons : public CInputFilter, protected CSettingsUser
   bool m_bDecorationChanged;
   SBoxInfo *m_pBoxes;
   int m_iNumBoxes, iActiveBox;
-  int m_iScanTime;
+  unsigned long m_iScanTime;
   
   virtual void DirectKeyDown(int iTime, int iId, CDasherView *pView, CDasherModel *pModel);
 };



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]