[dasher] LP_GEOMETRY switches between styles for handling tall-thin screens (0=~=old way)



commit 97b5d62cbafed611e1966c5969ec06f230c0eaf4
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date:   Mon Dec 13 17:45:16 2010 +0000

    LP_GEOMETRY switches between styles for handling tall-thin screens (0=~=old way)
    
    LP_GEOMETRY==1 => crosshair may be offscreen; in this mode,
      DefaultFilter remaps coords inc. reversing if mouse close to ctr of LHS.
    
    Added both LP_GEOMETRY and LP_SHAPE_TYPE to DefaultFilter module settings.
    Not the right place so yes, a temporary hack...

 Src/DasherCore/DasherInterfaceBase.cpp |    1 +
 Src/DasherCore/DasherViewSquare.cpp    |   65 +++++++++++++++++++++++--------
 Src/DasherCore/DefaultFilter.cpp       |   16 ++++++++
 Src/DasherCore/Parameters.h            |    3 +-
 4 files changed, 67 insertions(+), 18 deletions(-)
---
diff --git a/Src/DasherCore/DasherInterfaceBase.cpp b/Src/DasherCore/DasherInterfaceBase.cpp
index e8da093..1c4ae11 100644
--- a/Src/DasherCore/DasherInterfaceBase.cpp
+++ b/Src/DasherCore/DasherInterfaceBase.cpp
@@ -326,6 +326,7 @@ void CDasherInterfaceBase::InterfaceEventHandler(Dasher::CEvent *pEvent) {
     case LP_MARGIN_WIDTH:
     case BP_NONLINEAR_Y:
     case LP_NONLINEAR_X:
+    case LP_GEOMETRY:
         ScheduleRedraw();
         break;
     case LP_NODE_BUDGET:
diff --git a/Src/DasherCore/DasherViewSquare.cpp b/Src/DasherCore/DasherViewSquare.cpp
index 953e9d8..2a3b6cd 100644
--- a/Src/DasherCore/DasherViewSquare.cpp
+++ b/Src/DasherCore/DasherViewSquare.cpp
@@ -86,6 +86,7 @@ void CDasherViewSquare::HandleEvent(Dasher::CEvent *pEvent) {
     case LP_MARGIN_WIDTH:
     case BP_NONLINEAR_Y:
     case LP_NONLINEAR_X:
+    case LP_GEOMETRY:
       m_bVisibleRegionValid = false;
       SetScaleFactor();
       break;
@@ -860,32 +861,62 @@ void CDasherViewSquare::SetScaleFactor( void )
   const double dPixelsX(bHoriz ? iScreenWidth : iScreenHeight), dPixelsY(bHoriz ? iScreenHeight : iScreenWidth);
   
   const myint lpMaxY(GetLongParameter(LP_MAX_Y));
-  iMarginWidth = GetLongParameter(LP_MARGIN_WIDTH); //different schemes will alter this later...
   
+  //Defaults/starting values, will be modified later according to scheme in use...
+  iMarginWidth = GetLongParameter(LP_MARGIN_WIDTH);
   double dScaleFactorY(dPixelsY / lpMaxY );
   double dScaleFactorX(dPixelsX / static_cast<double>(lpMaxY + iMarginWidth) );
       
-  if (dScaleFactorX < dScaleFactorY) {
-    //fewer (pixels per dasher coord) in X direction - i.e., X is more compressed.
-    //So, use X scale for Y too...except first, we'll _try_ to reduce the difference
-    // by changing the relative scaling of X and Y (by at most 20%):
-    double dMul = max(0.8, dScaleFactorX / dScaleFactorY);
-    dScaleFactorY = std::max(dScaleFactorX/dMul, dScaleFactorY / 4.0);
-    dScaleFactorX *= 0.9;
-    iMarginWidth = (lpMaxY/20.0 + iMarginWidth*0.95)/0.9;
-  } else {
-    //X has more room; use Y scale for both -> will get lots history
-    // however, "compensate" by relaxing the default "relative scaling" of X
-    // (normally only 90% of Y) towards 1...
-    double dXmpc = std::min(1.0,0.9 * dScaleFactorX / dScaleFactorY);
-    dScaleFactorX = max(dScaleFactorY, dScaleFactorX / 4.0)*dXmpc;
-    iMarginWidth = (iMarginWidth + dPixelsX/dScaleFactorX - lpMaxY)/2;
+  switch (GetLongParameter(LP_GEOMETRY)) {
+    case 0: {
+      //old style
+      if (dScaleFactorX < dScaleFactorY) {
+        //fewer (pixels per dasher coord) in X direction - i.e., X is more compressed.
+        //So, use X scale for Y too...except first, we'll _try_ to reduce the difference
+        // by changing the relative scaling of X and Y (by at most 20%):
+        double dMul = max(0.8, dScaleFactorX / dScaleFactorY);
+        dScaleFactorY = std::max(dScaleFactorX/dMul, dScaleFactorY / 4.0);
+        dScaleFactorX *= 0.9;
+        iMarginWidth = (lpMaxY/20.0 + iMarginWidth*0.95)/0.9;
+      } else {
+        //X has more room; use Y scale for both -> will get lots history
+        // however, "compensate" by relaxing the default "relative scaling" of X
+        // (normally only 90% of Y) towards 1...
+        double dXmpc = std::min(1.0,0.9 * dScaleFactorX / dScaleFactorY);
+        dScaleFactorX = max(dScaleFactorY, dScaleFactorX / 4.0)*dXmpc;
+        iMarginWidth = (iMarginWidth + dPixelsX/dScaleFactorX - lpMaxY)/2;
+      }
+      break;
+    }
+    //all new styles fix the y axis the way we want it (i.e. leave as above),
+    // and just do different things with x...
+    case 1:
+      //square with x-hair possibly offscreen
+      dScaleFactorX = dScaleFactorY;
+      break;
+    case 2:
+    case 3: {
+      //2 or 3 => squish x (so xhair always visible)
+      const double dDesiredXPerPixel( (lpMaxY + iMarginWidth) / dPixelsX), dMinXPerPixel((GetLongParameter(LP_OX)+iMarginWidth)/dPixelsX);
+      const double dAspect(1.0/dScaleFactorY/dDesiredXPerPixel);
+      double dDasherXPerPixel( (dAspect<1.0)
+                              ? (dMinXPerPixel+pow(dAspect,3.0)*(dDesiredXPerPixel-dMinXPerPixel)) //tall+thin
+                              : (1.0/dScaleFactorY)); //square or wide+low
+      iMarginWidth /= 0.9; //this comes from the old scaling by m_dXmpc=0.9. Drop in new scheme?
+      if (GetLongParameter(LP_GEOMETRY)==3) {
+        //make whole screen logarithmic (but keep xhair in same place)
+        myint crosshair(xmap(2048)); //should be 2048...
+        m_iXlogThres=0;
+        dDasherXPerPixel *= xmap(2048)/static_cast<double>(crosshair);
+      }
+      dScaleFactorX = 0.9 / dDasherXPerPixel;
+    }
   }
   iScaleFactorX = myint(dScaleFactorX * m_iScalingFactor);
   iScaleFactorY = myint(dScaleFactorY * m_iScalingFactor);
 
 #ifdef DEBUG
-  //now test Dasher2Screen & Screen2Dasher are inverses...
+  //test...
   for (screenint x=0; x<iScreenWidth; x++) {
     dasherint dx, dy;
     Screen2Dasher(x, 0, dx, dy);
diff --git a/Src/DasherCore/DefaultFilter.cpp b/Src/DasherCore/DefaultFilter.cpp
index 6f931b3..82cff35 100644
--- a/Src/DasherCore/DefaultFilter.cpp
+++ b/Src/DasherCore/DefaultFilter.cpp
@@ -14,6 +14,8 @@ static SModuleSettings sSettings[] = {
   {LP_TARGET_OFFSET, T_LONG, -100, 100, 400, 1, _("Vertical distance from mouse/gaze to target (400=screen height)")},
   {BP_AUTOCALIBRATE, T_BOOL, -1, -1, -1, -1, _("Learn offset (previous) automatically, e.g. gazetrackers")},
   {BP_REMAP_XTREME, T_BOOL, -1, -1, -1, -1, _("At top and bottom, scroll more and translate less (makes error-correcting easier)")},
+  {LP_GEOMETRY, T_LONG, 0, 3, 1, 1, _("Screen geometry (mostly for tall thin screens) - 0=old-style, 1=square no-xhair, 2=squish, 3=squish+log")},
+  {LP_SHAPE_TYPE, T_LONG, 0, 5, 1, 1, _("Shape type: 0=disjoint rects, 1=overlapping, 2=triangles, 3=trunc-tris, 4=quadrics, 5=circles")},
 };
 
 bool CDefaultFilter::GetSettings(SModuleSettings **sets, int *iCount) {
@@ -213,6 +215,20 @@ double xmax(double y) {
 
 void CDefaultFilter::ApplyTransform(myint &iDasherX, myint &iDasherY, CDasherView *pView) {
   ApplyOffset(iDasherX, iDasherY);
+  if (GetLongParameter(LP_GEOMETRY)==1) {
+    //crosshair may be offscreen; so do something to allow us to navigate
+    // up/down and reverse
+    myint iDasherMaxX,temp;
+    pView->VisibleRegion(temp, temp, iDasherMaxX, temp);
+    const myint xd(iDasherX - iDasherMaxX),yd(iDasherY-GetLongParameter(LP_OY));
+    const myint dist(xd*xd + yd*yd); //squared distance from closest point onscreen to crosshair
+    if (iDasherMaxX < GetLongParameter(LP_OX)) {
+      //crosshair actually offscreen; rescale so left edge of screen = translate
+      iDasherX = (iDasherX * GetLongParameter(LP_OX))/iDasherMaxX;
+    }
+    //boost reversing if near centerpoint of LHS (even if xhair onscreen)
+    iDasherX += (2*GetLongParameter(LP_OY)*GetLongParameter(LP_OY))/(dist+50); //and close to centerpoint = reverse
+  }
   if (GetBoolParameter(BP_REMAP_XTREME)) {
     // Y co-ordinate...
     myint dasherOY=(myint)GetLongParameter(LP_OY); 
diff --git a/Src/DasherCore/Parameters.h b/Src/DasherCore/Parameters.h
index 4e5ee35..6e2cf17 100644
--- a/Src/DasherCore/Parameters.h
+++ b/Src/DasherCore/Parameters.h
@@ -56,7 +56,7 @@ enum {
   LP_UNIFORM, LP_YSCALE, LP_MOUSEPOSDIST, LP_STOP_IDLETIME,
   LP_LM_MAX_ORDER, LP_LM_EXCLUSION,
   LP_LM_UPDATE_EXCLUSION, LP_LM_ALPHA, LP_LM_BETA,
-  LP_LM_MIXTURE, LP_NORMALIZATION, LP_LINE_WIDTH, 
+  LP_LM_MIXTURE, LP_NORMALIZATION, LP_LINE_WIDTH, LP_GEOMETRY,
   LP_LM_WORD_ALPHA, LP_USER_LOG_LEVEL_MASK, 
   LP_ZOOMSTEPS, LP_B, LP_S, LP_BUTTON_SCAN_TIME, LP_R, LP_RIGHTZOOM,
   LP_NODE_BUDGET, LP_OUTLINE_WIDTH, LP_MIN_NODE_SIZE, LP_NONLINEAR_X,
@@ -208,6 +208,7 @@ static lp_table longparamtable[] = {
   {LP_LM_MIXTURE, "LMMixture", PERS, 50, "LMMixture"},
   {LP_NORMALIZATION, "Normalization", !PERS, 1 << 16, "Interval for child nodes"},
   {LP_LINE_WIDTH, "LineWidth", PERS, 1, "Width to draw crosshair and mouse line"},
+  {LP_GEOMETRY, "Geometry", PERS, 0, "Screen geometry (mostly for tall thin screens) - 0=old-style, 1=square no-xhair, 2=squish, 3=squish+log"},
   {LP_LM_WORD_ALPHA, "WordAlpha", PERS, 50, "Alpha value for word-based model"},
   {LP_USER_LOG_LEVEL_MASK, "UserLogLevelMask", PERS, 0, "Controls level of user logging, 0 = none, 1 = short, 2 = detailed, 3 = both"},
   {LP_ZOOMSTEPS, "Zoomsteps", PERS, 32, "Integerised ratio of zoom size for click/button mode, denom 64."},



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