[dasher] CDasherModel::ScheduleZoom takes _range_ of Y-coords, _after_ safety margin etc



commit a2258253173ee03ba979568c2d42f20d43172ee0
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date:   Thu Nov 25 13:55:41 2010 +0000

    CDasherModel::ScheduleZoom takes _range_ of Y-coords, _after_ safety margin etc
    
    static CClickFilter::AdjustZoomCoords applies LP_MAXZOOM, (fraction) LP_S, x>=2.
    (virtual) CStylusFilter::ApplyClickTransform calls previous.
    Box modes etc. already implemented LP_S (additively); hence, previously these
    would have had the safety margin applied _twice_, but now only once.

 Src/DasherCore/AlternatingDirectMode.cpp |   38 ++++++++++++++---------------
 Src/DasherCore/ClickFilter.cpp           |   26 ++++++++++++++++----
 Src/DasherCore/ClickFilter.h             |    3 ++
 Src/DasherCore/DasherButtons.cpp         |    4 +-
 Src/DasherCore/DasherModel.cpp           |   33 +++----------------------
 Src/DasherCore/DasherModel.h             |   12 ++++++---
 Src/DasherCore/OneButtonFilter.cpp       |    6 +++-
 Src/DasherCore/StylusFilter.cpp          |    9 +++++-
 Src/DasherCore/StylusFilter.h            |    5 ++++
 9 files changed, 72 insertions(+), 64 deletions(-)
---
diff --git a/Src/DasherCore/AlternatingDirectMode.cpp b/Src/DasherCore/AlternatingDirectMode.cpp
index 0aa0117..b736763 100644
--- a/Src/DasherCore/AlternatingDirectMode.cpp
+++ b/Src/DasherCore/AlternatingDirectMode.cpp
@@ -91,28 +91,26 @@ bool CAlternatingDirectMode::DecorateView(CDasherView *pView, CDasherInput *pInp
 
 
 void CAlternatingDirectMode::DirectKeyDown(int iTime, int iId, CDasherView *pView, CDasherModel *pModel, CUserLogBase *pUserLog) {
-
+  int iTargetBox;
   switch(iId) {
-  case 2:
-    if(m_iLastBox == 1)
-      pModel->ScheduleZoom(iTime, (m_pBoxes[2].iBottom - m_pBoxes[2].iTop)/2, (m_pBoxes[2].iBottom + m_pBoxes[2].iTop)/2);
-    else
-      pModel->ScheduleZoom(iTime, (m_pBoxes[0].iBottom - m_pBoxes[0].iTop)/2, (m_pBoxes[0].iBottom + m_pBoxes[0].iTop)/2);
-    m_iLastBox = 1;
-    break;
-  case 3:
-  case 4:
-    if(m_iLastBox == 2)
-      pModel->ScheduleZoom(iTime, (m_pBoxes[3].iBottom - m_pBoxes[3].iTop)/2, (m_pBoxes[3].iBottom + m_pBoxes[3].iTop)/2);
-    else
-      pModel->ScheduleZoom(iTime, (m_pBoxes[1].iBottom - m_pBoxes[1].iTop)/2, (m_pBoxes[1].iBottom + m_pBoxes[1].iTop)/2);
-    m_iLastBox = 2;
-    break;
-  case 1:
-    pModel->ScheduleZoom(iTime, (m_pBoxes[4].iBottom - m_pBoxes[4].iTop)/2, (m_pBoxes[4].iBottom + m_pBoxes[4].iTop)/2);
-    break;
+    case 2:
+      iTargetBox = (m_iLastBox == 1) ? 2 : 0;
+      m_iLastBox = 1;
+      break;
+    case 3:
+    case 4:
+      iTargetBox = (m_iLastBox==2) ? 3 : 1;
+      m_iLastBox = 2;
+      break;
+    case 1:
+      iTargetBox = 4;
+      break;
+    default:
+      //unknown button...do nothing (?)
+      return;
   }
-
+  //iTargetBox now indicates the box into which to zoom
+  pModel->ScheduleZoom(iTime, m_pBoxes[iTargetBox].iTop,  m_pBoxes[iTargetBox].iBottom);
 }
 
 bool CAlternatingDirectMode::GetSettings(SModuleSettings **pSettings, int *iCount) {
diff --git a/Src/DasherCore/ClickFilter.cpp b/Src/DasherCore/ClickFilter.cpp
index 69aef54..6e71287 100644
--- a/Src/DasherCore/ClickFilter.cpp
+++ b/Src/DasherCore/ClickFilter.cpp
@@ -24,9 +24,7 @@ bool CClickFilter::DecorateView(CDasherView *pView, CDasherInput *pInput) {
   if (GetBoolParameter(BP_DRAW_MOUSE_LINE)) {
     myint mouseX, mouseY;
     pInput->GetDasherCoords(mouseX, mouseY, pView);
-    //unfortunately we have to copy the limit set by DasherModel::ScheduleZoom here
-    // ....call for a refactor? but of some/what sort?
-    if (mouseX<2) mouseX=2;
+    AdjustZoomCoords(mouseX,mouseY,pView);
     if (m_iLastX != mouseX || m_iLastY != mouseY) {
       bChanged = true;
       m_iLastX = mouseX; m_iLastY = mouseY;
@@ -60,6 +58,24 @@ bool CClickFilter::DecorateView(CDasherView *pView, CDasherInput *pInput) {
   return bChanged;
 }
 
+void CClickFilter::AdjustZoomCoords(myint &iDasherX, myint &iDasherY, CDasherView *pView) {
+  const myint ox(pView->GetLongParameter(LP_OX)), safety(pView->GetLongParameter(LP_S));
+  //safety param. Used to be just added onto DasherX,
+  // but comments suggested should be interpreted as a fraction. Hence...
+  myint iNewDasherX = (iDasherX*1024 + ox*safety) / (1024+safety);
+  
+  //max zoom parameter...
+  iNewDasherX = std::max(ox/pView->GetLongParameter(LP_MAXZOOM),iNewDasherX);
+  //force x>=2 (what's wrong with x==1?)
+  if (iNewDasherX<2) iNewDasherX=2;
+  if (iNewDasherX != iDasherX) {
+    //compute new dasher y to keep centre of expansion in same place...
+    const myint oy(pView->GetLongParameter(LP_OY));
+    myint iNewDasherY = oy + ((ox-iNewDasherX) * (iDasherY-oy))/(ox-iDasherX);
+    iDasherX = iNewDasherX; iDasherY = iNewDasherY;
+  }
+}
+
 bool CClickFilter::Timer(int Time, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol) {
   return pModel->NextScheduledStep(Time, pAdded, pNumDeleted);
 }
@@ -72,8 +88,8 @@ void CClickFilter::KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput
       myint iDasherY;
 
       pInput->GetDasherCoords(iDasherX, iDasherY, pView);
-
-      pModel->ScheduleZoom(iTime, iDasherX,iDasherY, GetLongParameter(LP_MAXZOOM));
+      AdjustZoomCoords(iDasherX, iDasherY, pView);
+      pModel->ScheduleZoom(iTime, iDasherY-iDasherX, iDasherY+iDasherX);
     }
     break;
   default:
diff --git a/Src/DasherCore/ClickFilter.h b/Src/DasherCore/ClickFilter.h
index e191e11..7e63fca 100644
--- a/Src/DasherCore/ClickFilter.h
+++ b/Src/DasherCore/ClickFilter.h
@@ -15,6 +15,9 @@ class CClickFilter : public CInputFilter {
   virtual bool Timer(int Time, CDasherView *pView, CDasherInput *pInput, CDasherModel *pDasherModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
   virtual void KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog, bool bPos, int iX, int iY);
   virtual bool GetSettings(SModuleSettings **pSettings, int *iCount);
+  
+  static void AdjustZoomCoords(myint &iDasherX, myint &iDasherY, CDasherView *comp);
+  
  private:
   //for mouse lines
   myint m_iLastX, m_iLastY;
diff --git a/Src/DasherCore/DasherButtons.cpp b/Src/DasherCore/DasherButtons.cpp
index 6a9aaa3..05aed43 100644
--- a/Src/DasherCore/DasherButtons.cpp
+++ b/Src/DasherCore/DasherButtons.cpp
@@ -56,7 +56,7 @@ void CDasherButtons::KeyDown(int iTime, int iId, CDasherView *pView, CDasherInpu
     case 3:
     case 100:
       m_bDecorationChanged = true;
-      pModel->ScheduleZoom(iTime, (m_pBoxes[iActiveBox].iBottom - m_pBoxes[iActiveBox].iTop)/2, (m_pBoxes[iActiveBox].iBottom + m_pBoxes[iActiveBox].iTop)/2);
+      pModel->ScheduleZoom(iTime, m_pBoxes[iActiveBox].iTop, m_pBoxes[iActiveBox].iBottom);
       if(iActiveBox != m_iNumBoxes-1)
         iActiveBox = 0;
       break;
@@ -78,7 +78,7 @@ void CDasherButtons::DirectKeyDown(int iTime, int iId, CDasherView *pView, CDash
   else
   iActiveBox = m_iNumBoxes-2;
 
-  pModel->ScheduleZoom(iTime, (m_pBoxes[iActiveBox].iBottom - m_pBoxes[iActiveBox].iTop)/2, (m_pBoxes[iActiveBox].iBottom + m_pBoxes[iActiveBox].iTop)/2);
+  pModel->ScheduleZoom(iTime, m_pBoxes[iActiveBox].iTop,m_pBoxes[iActiveBox].iBottom);
 }
 
 bool CDasherButtons::Timer(int Time, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol) {
diff --git a/Src/DasherCore/DasherModel.cpp b/Src/DasherCore/DasherModel.cpp
index 9e030ea..2265bf2 100644
--- a/Src/DasherCore/DasherModel.cpp
+++ b/Src/DasherCore/DasherModel.cpp
@@ -614,36 +614,15 @@ void CDasherModel::RenderToView(CDasherView *pView, CExpansionPolicy &policy) {
   
 }
 
-void CDasherModel::ScheduleZoom(long time, dasherint X, dasherint Y, int iMaxZoom)
-{
-  // 1 = min, 2 = max. y1, y2 is the length we select from Y1, Y2. With
-  // that ratio we calculate the new root{min,max} r1, r2 from current R1, R2.
-  const int nsteps = GetLongParameter(LP_ZOOMSTEPS);
-  const int safety = GetLongParameter(LP_S); // over safety_denom gives %
-  const int safety_denom = 1024;
-  const int ymax = GetLongParameter(LP_MAX_Y);
-  const int scale = ymax; // (0,1) -> (ymin=0,ymax)
-
-  // (X,Y) is mouse position in dasher coordinates
-  // Prevent clicking too far to the right => y1 <> y2 see below
-  if (X < 2) X = 2;
-
-  // Lines with gradient +/- 1 passing through (X,Y) intersect y-axis at
-  dasherint y1 = Y - X;     // y =  x + (Y - X)
-  dasherint y2 = Y + X;     // y = -x + (Y + X)
+void CDasherModel::ScheduleZoom(long time, dasherint y1, dasherint y2) {
+  DASHER_ASSERT(y2>y1);
 
   // Rename for readability.
   const dasherint Y1 = 0;
-  const dasherint Y2 = ymax;
+  const dasherint Y2 = GetLongParameter(LP_MAX_Y);
   const dasherint R1 = m_Rootmin;
   const dasherint R2 = m_Rootmax;
 
-  // So, want to zoom (y1 - safety/2, y2 + safety/2) -> (Y1, Y2)
-  // Adjust y1, y2 for safety margin
-  dasherint ds = (safety * scale) / (2 * safety_denom);
-  y1 -= ds;
-  y2 += ds;
-
   dasherint C, r1, r2;
 
   // If |(y1,y2)| = |(Y1,Y2)|, the "zoom factor" is 1, so we just translate.
@@ -667,15 +646,11 @@ void CDasherModel::ScheduleZoom(long time, dasherint X, dasherint Y, int iMaxZoo
       } else { // implies y1 = y2
           std::cerr << "Impossible geometry in CDasherModel::ScheduleZoom\n";
       }
-  // iMaxZoom seems to be in tenths
-      if (iMaxZoom != 0 && 10 * (r2 - r1) > iMaxZoom * (R2 - R1)) {
-          r1 = ((R1 - C) * iMaxZoom) / 10 + C;
-          r2 = ((R2 - C) * iMaxZoom) / 10 + C;
-      }
   }
 
   // sNewItem seems to contain a list of root{min,max} for the frames of the
   // zoom, so split r -> R into n steps, with accurate R
+  const int nsteps = GetLongParameter(LP_ZOOMSTEPS);
   m_deGotoQueue.clear();
   for (int s = nsteps - 1; s >= 0; --s) {
       SGotoItem sNewItem;
diff --git a/Src/DasherCore/DasherModel.h b/Src/DasherCore/DasherModel.h
index 1a78dab..17eeb39 100644
--- a/Src/DasherCore/DasherModel.h
+++ b/Src/DasherCore/DasherModel.h
@@ -135,10 +135,14 @@ class Dasher::CDasherModel:public Dasher::CFrameRate, private NoClones
   /// @{
 
   ///
-  /// Schedule zoom to a given Dasher coordinate (used in click mode,
-  /// button mode etc.)
-  ///
-  void ScheduleZoom(long time, dasherint iDasherX, dasherint iDasherY, int iMaxZoom = 0);
+  /// Schedule a zoom such that the given range of Dasher coordinates
+  /// will fill the Y-axis. (used in click mode, button mode etc.)
+  /// Note that safety margin, max-zoom, etc., as desired, are the responsibility
+  /// of the caller; this method requires only that y2 > y1.
+  /// \param y1 Minimum Y-coordinate (will be moved to dasher-y of 0)
+  /// \param y2 Maximum Y-coordinate (will be moved to dasher-y of 4096)
+  ///
+  void ScheduleZoom(long time, dasherint y1, dasherint y2);
 
   void ClearScheduledSteps();
   
diff --git a/Src/DasherCore/OneButtonFilter.cpp b/Src/DasherCore/OneButtonFilter.cpp
index cf72295..8bfadf9 100644
--- a/Src/DasherCore/OneButtonFilter.cpp
+++ b/Src/DasherCore/OneButtonFilter.cpp
@@ -74,11 +74,13 @@ void COneButtonFilter::KeyDown(int iTime, int iId, CDasherView *pView, CDasherIn
   if (bStarted) {
     if (iLocation == 0) {
       //back up by one zoom step.
-      pModel->ScheduleZoom(iTime, GetLongParameter(LP_STATIC1B_ZOOM) * 2048, 2048, 0);
+      const myint x(GetLongParameter(LP_STATIC1B_ZOOM)*2048);
+      pModel->ScheduleZoom(iTime, 2048-x, 2048+x);
     } else {
       iLocation -= (GetLongParameter(LP_DYNAMIC_BUTTON_LAG)*4096) / GetLongParameter(LP_STATIC1B_TIME);
       if (iLocation>4096) iLocation =8192-iLocation;
-      pModel->ScheduleZoom(iTime, 2048/GetLongParameter(LP_STATIC1B_ZOOM), iLocation, 0);
+      const myint x(2048/GetLongParameter(LP_STATIC1B_ZOOM));
+      pModel->ScheduleZoom(iTime, 2048-x, 2048+x);
     }
     bStarted = false;
   } else {
diff --git a/Src/DasherCore/StylusFilter.cpp b/Src/DasherCore/StylusFilter.cpp
index 7dad760..8e54a0f 100644
--- a/Src/DasherCore/StylusFilter.cpp
+++ b/Src/DasherCore/StylusFilter.cpp
@@ -2,6 +2,7 @@
 #include "StylusFilter.h"
 #include "DasherInterfaceBase.h"
 #include "Event.h"
+#include "ClickFilter.h"
 
 using namespace Dasher;
 
@@ -33,10 +34,14 @@ void CStylusFilter::KeyUp(int iTime, int iId, CDasherView *pView, CDasherInput *
   if(iId == 100) {
     if (iTime - m_iKeyDownTime < GetLongParameter(LP_TAP_TIME)) {
       pInput->GetDasherCoords(m_iLastX, m_iLastY, pView);
-      //Do not apply transform. (Could add extra virtual method, ApplyClickTransform?)
-      pModel->ScheduleZoom(iTime, m_iLastX, m_iLastY, GetLongParameter(LP_MAXZOOM));
+      ApplyClickTransform(m_iLastX, m_iLastY, pView);
+      pModel->ScheduleZoom(iTime, m_iLastX, m_iLastY);
     } else {
       m_pInterface->Stop();
     }
   }
 }
+
+void CStylusFilter::ApplyClickTransform(myint &iDasherX, myint &iDasherY, CDasherView *pView) {
+  CClickFilter::AdjustZoomCoords(iDasherX, iDasherY, pView);
+}
diff --git a/Src/DasherCore/StylusFilter.h b/Src/DasherCore/StylusFilter.h
index 905299f..521d013 100644
--- a/Src/DasherCore/StylusFilter.h
+++ b/Src/DasherCore/StylusFilter.h
@@ -15,6 +15,11 @@ class CStylusFilter : public CDefaultFilter {
   virtual bool Timer(int Time, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, Dasher::VECTOR_SYMBOL_PROB *pAdded, int *pNumDeleted, CExpansionPolicy **pol);
   virtual void KeyDown(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel, CUserLogBase *pUserLog);
   virtual void KeyUp(int iTime, int iId, CDasherView *pView, CDasherInput *pInput, CDasherModel *pModel);
+  ///Transform coordinates of a click, to get location to zoom into.
+  /// Default is to call CClickFilter::AdjustZoomCoords, which adds
+  /// a safety margin according to LP_S, checks we don't exceed the
+  /// zoom factor given by LP_MAXZOOM, and ensures x>=2.
+  virtual void ApplyClickTransform(myint &iDasherX, myint &iDasherY, CDasherView *pView);
  private:
   int m_iKeyDownTime;
 };



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