Logo Search packages:      
Sourcecode: dasher version File versions

DasherViewSquare.cpp

// DasherViewSquare.cpp
//
/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2001-2004 David Ward
//
/////////////////////////////////////////////////////////////////////////////

#include "../Common/Common.h"

#include "DasherViewSquare.h"
#include "DasherModel.h"

#include <algorithm>

using namespace Dasher;


/////////////////////////////////////////////////////////////////////////////

CDasherViewSquare::Cymap::Cymap(myint iScale)
{
      double dY1=0.25;    // Amount of acceleration
      double dY2=0.95;    // Accelerate Y movement below this point
      double dY3=0.05;    // Accelerate Y movement above this point

      m_Y2=myint (dY2 * iScale );
      m_Y3=myint (dY3 * iScale );
      m_Y1=myint(1.0/dY1);
}

/////////////////////////////////////////////////////////////////////////////

CDasherViewSquare::CDasherViewSquare(CDasherScreen* DasherScreen, CDasherModel& DasherModel, CLanguageModel* LanguageModel, Dasher::Opts::ScreenOrientations Orientation, bool Colourmode)
  : CDasherView(DasherScreen, DasherModel, LanguageModel, Orientation, Colourmode)
{
      ChangeScreen(DasherScreen);
      
      // tweak these if you know what you are doing
      m_dXmpa=0.2;   // these are for the x non-linearity
      m_dXmpb=0.5;
      m_dXmpc=0.9;
      m_dXmpd=0.5;   // slow X movement when accelerating Y


      KeyControl=false;

      onebutton=-2000;

      m_ymap = Cymap(DasherModel.DasherY());

      CDasherModel::CRange rActive(m_ymap.unmap(0), m_ymap.unmap(DasherModel.DasherY()) );
      DasherModel.SetActive(rActive);
}

/////////////////////////////////////////////////////////////////////////////

int CDasherViewSquare::RenderNode(const symbol Character, const int Color, Opts::ColorSchemes ColorScheme,
      myint y1, myint y2, int& mostleft, bool& force, bool text, std::string displaytext)
{
      // Is this square actually on the screen? Check top
      int top = dashery2screen(y1);
      if (top>CanvasY) {
            return 0;
      }
      if (top<0) { // "highest" legal coordinate to draw is 0.
            top=0;
      }
      
      // Is this square actually on the screen? Check bottom
      int bottom = dashery2screen(y2);
      if (bottom<0) {
            return 0;
      }
      if (bottom>CanvasY)
            bottom=CanvasY;
      
      int height=bottom-top;
      
      if (height==0 && text==true)
            force=false;
      
      if (force || height>1) {
            force=true;

            // horizontal width of the square is controlled by the true size (y2-y1) in Dasher world
            screenint left=dasherx2screen(y2-y1);
            
            // All squares are right-aligned.
            screenint right=CanvasX;
            
            screenint newleft=left, newtop=top, newright=right, newbottom=bottom;
            MapScreen(&newleft, &newtop);
            MapScreen(&newright, &newbottom);
            if( !text ) {
              Screen().DrawRectangle(newleft, newtop, newright, newbottom, Color, ColorScheme);
            }
            else
              {
                if (left<mostleft)
                  left=mostleft;
                
                int Size;
                if (left*Screen().GetFontSize()<CanvasX*19/20) {
                  Size = 20*Screen().GetFontSize();
                } else if (left*Screen().GetFontSize()<CanvasX*159/160) {
                  Size = 14*Screen().GetFontSize();
                } else {
                  Size = 11*Screen().GetFontSize();
                }
                
                screenint TextWidth, TextHeight, OriginX=0, OriginY=0;
                Screen().TextSize(Character, &TextWidth, &TextHeight, Size);
                UnMapScreen(&TextWidth, &TextHeight);
                UnMapScreen(&OriginX, &OriginY);            
                screenint FontHeight = abs(TextHeight-OriginY);         
                screenint FontWidth = abs(TextWidth-OriginX);
                mostleft = left + FontWidth;
                
                screenint newleft2 = left;
                screenint newtop2 = (height-FontHeight)/2 + top;
                screenint newright2 = left + FontWidth;
                screenint newbottom2 = (height+FontHeight)/2 + top;
                MapScreen(&newleft2, &newtop2);
                MapScreen(&newright2, &newbottom2);
                  newleft = std::min(newleft2, newright2);
                  newtop = std::min(newtop2, newbottom2);

//#ifdef DASHER_WIN32
//    #if defined DrawText
      //    #undef DrawText
//    #endif
//#endif
                  if(displaytext!= std::string("") ) {
                  Screen().DrawText(displaytext, newleft, newtop, Size);
                } else {
                  Screen().DrawText(Character, newleft, newtop, Size);
                }
              }
            
            return 1;
      } else 
            return 0;
}

/////////////////////////////////////////////////////////////////////////////

void CDasherViewSquare::CheckForNewRoot()
{
      CDasherNode * const root=DasherModel().Root();
      CDasherNode ** const children=root->Children();


      myint y1=DasherModel().Rootmin();
      myint y2=DasherModel().Rootmax();
      
      // This says that the root node must enclose everything visible.
      // Tiny probability characters near the bottom will cause a problem
      // with forcing to reparent to the previous one.

      if ((y1>myint(0) || y2 < DasherModel().DasherY() || dasherx2screen(y2-y1)>0)) {
        DasherModel().Reparent_root(root->Lbnd(),root->Hbnd());
        return;
      }
          
      if (children==0)
            return;

      int alive=0;
      int theone=0;
      unsigned int i;

      // Find whether there is exactly one alive child; if more, we don't care.
      for (i=1;i<root->ChildCount();i++) {
            if (children[i]->Alive()) {
                  alive++;
                  theone=i;
            if(alive>1) break; 
            }
      }

      if (alive==1) {     
      // We must have zoomed sufficiently that only one child of the root node 
      // is still alive.  Let's make it the root.

        y1=DasherModel().Rootmin();
        y2=DasherModel().Rootmax();
        myint range=y2-y1;
        myint newy1=y1+(range*children[theone]->Lbnd())/DasherModel().Normalization();
        myint newy2=y1+(range*children[theone]->Hbnd())/DasherModel().Normalization();
        if (newy1<myint(0) && newy2> DasherModel().DasherY()) {
          myint left=dasherx2screen(newy2-newy1);
          if (left<myint(0)) {
            DasherModel().Make_root(theone);
            return;
          }
        }
      }
}

/////////////////////////////////////////////////////////////////////////////

// work out the next viewpoint
// move the rectangles accordingly
void CDasherViewSquare::TapOnDisplay(screenint mousex,screenint mousey, unsigned long Time) 
{
      // convert mouse (screen) coords into dasher coords
        int Swapper;

      if (mousex>CanvasX)
            mousex=CanvasX;

      UnMapScreen(&mousex, &mousey);

      if (DasherModel().Dimensions()==true) {
        switch (ScreenOrientation) {
        case (LeftToRight):
          break;
        case (RightToLeft):
          mousex = Screen().GetWidth() - mousex;
          break;
        case (TopToBottom):
          Swapper = ( mousex * Screen().GetHeight()) / Screen().GetWidth();
          mousex = (mousey  * Screen().GetWidth()) / Screen().GetHeight();
          mousey = Swapper;
          break;
        case (BottomToTop):
          // Note rotation by 90 degrees not reversible like others
          Swapper = Screen().GetHeight() - ( mousex * Screen().GetHeight()) / Screen().GetWidth();
          mousex = (mousey  * Screen().GetWidth()) / Screen().GetHeight();
          mousey = Swapper;
          break;
        default:
          break;
        }
      }
      
    bool autocalibrate=1;
    if (autocalibrate) {
        AutoCalibrate(&mousex, &mousey);
    }
      myint idasherx,idashery;
      screen2dasher(mousex,mousey,&idasherx,&idashery);
      DasherModel().Tap_on_display(idasherx,idashery, Time);
      CheckForNewRoot();
}

/////////////////////////////////////////////////////////////////////////////
// move to the specified point

void CDasherViewSquare::GoTo(screenint mousex,screenint mousey) 
{
      // convert mouse (screen) coords into dasher coords
      
      UnMapScreen(&mousex, &mousey);
      myint idasherx,idashery;
      screen2dasher(mousex,mousey,&idasherx,&idashery);
      DasherModel().GoTo(idasherx,idashery);
      CheckForNewRoot();
}

/////////////////////////////////////////////////////////////////////////////

void CDasherViewSquare::DrawGoTo(screenint mousex, screenint mousey)
{
  // Draw a box surrounding the area of the screen that will be zoomed into
  UnMapScreen(&mousex, &mousey);
  myint idasherx,idashery;
  screen2dasher(mousex,mousey,&idasherx,&idashery);
  // So, we have a set of coordinates. We need a bunch of points back.
  myint height=DasherModel().PlotGoTo(idasherx, idashery);
  myint top, bottom, left, right;

  // Convert back to screen coordinates?
  top=mousey-height/2;
  bottom=mousey+height/2;
  left=mousex+height/2;
  right=mousex-height/2;
  top=dashery2screen(top);
  bottom=dashery2screen(bottom);
  left=dasherx2screen(left);
  right=dasherx2screen(right);
  
  // Draw the lines
  Screen().DrawRectangle(left, top+5, right, top-5, 1, Opts::ColorSchemes(Objects));
  Screen().DrawRectangle(left+5, top+5, left, bottom-5, 1, Opts::ColorSchemes(Objects));
  Screen().DrawRectangle(left, bottom+5, right, bottom-5, 1, Opts::ColorSchemes(Objects));
}
  
/////////////////////////////////////////////////////////////////////////////

void CDasherViewSquare::DrawMouse(screenint mousex, screenint mousey)
{
        if (DasherModel().Dimensions()==true || DasherModel().Eyetracker()==true) {
  
        int Swapper;
      
        myint dasherx,dashery;
        screen2dasher(mousex,mousey,&dasherx,&dashery);
        mousex=dasherx2screen(dasherx);
        mousey=dashery2screen(dashery);
        switch (ScreenOrientation) {
        case (LeftToRight):
          break;
        case (RightToLeft):
          mousex = Screen().GetWidth() - mousex;
          break;
        case (TopToBottom):
          Swapper = ( mousex * Screen().GetHeight()) / Screen().GetWidth();
          mousex = (mousey  * Screen().GetWidth()) / Screen().GetHeight();
          mousey = Swapper;
          break;
        case (BottomToTop):
          // Note rotation by 90 degrees not reversible like others
          Swapper = Screen().GetHeight() - ( mousex * Screen().GetHeight()) / Screen().GetWidth();
          mousex = (mousey  * Screen().GetWidth()) / Screen().GetHeight();
          mousey = Swapper;
          break;
        default:
          break;
        }
      }

      if (ColourMode==true) {
        Screen().DrawRectangle(mousex-5, mousey-5, mousex+5, mousey+5, 2, Opts::ColorSchemes(Objects));
      } else {
        Screen().DrawRectangle(mousex-5, mousey-5, mousex+5, mousey+5, 1, Opts::ColorSchemes(Objects));
      }
}

/////////////////////////////////////////////////////////////////////////////

void CDasherViewSquare::DrawMouseLine(screenint mousex, screenint mousey)
{
        if (DasherModel().Dimensions()==true || DasherModel().Eyetracker()==true) {
  
        screenint Swapper;
      
        myint dasherx,dashery;
        screen2dasher(mousex,mousey,&dasherx,&dashery);
        mousex=dasherx2screen(dasherx);
        mousey=dashery2screen(dashery);
        switch (ScreenOrientation) {
        case (LeftToRight):
          break;
        case (RightToLeft):
          mousex = Screen().GetWidth() - mousex;
          break;
        case (TopToBottom):
          Swapper = ( mousex * Screen().GetHeight()) / Screen().GetWidth();
          mousex = (mousey  * Screen().GetWidth()) / Screen().GetHeight();
          mousey = Swapper;
          break;
        case (BottomToTop):
          // Note rotation by 90 degrees not reversible like others
          Swapper = Screen().GetHeight() - ( mousex * Screen().GetHeight()) / Screen().GetWidth();
          mousex = (mousey  * Screen().GetWidth()) / Screen().GetHeight();
          mousey = Swapper;
          break;
        default:
          break;
        }
      }

      CDasherScreen::point mouseline[2];

      mouseline[0].x=dasherx2screen(DasherModel().DasherOX());
      mouseline[0].y=CanvasY/2;
      mouseline[1].x=mousex;
      mouseline[1].y=mousey;        

      if (ColourMode==true) {
        Screen().Polyline(mouseline,2,1);
      } else {
        Screen().Polyline(mouseline,2);
      }
}

/////////////////////////////////////////////////////////////////////////////

void CDasherViewSquare::DrawKeyboard()
{
  CDasherScreen::point line[2];
  line[0].x = 200;
  line[0].y = 0;
  line[1].x = 200;
  line[1].y = CanvasY/2;
  
  if (ColourMode==true) {
    Screen().Polyline(line,2,6);
  } else {
    Screen().Polyline(line,2);
  }

  line[0].x = 200;
  line[0].y = CanvasY/2;
  line[1].x = 0;
  line[1].y = CanvasY/2;

  if (ColourMode==true) {
    Screen().Polyline(line,2,6);
  } else {
    Screen().Polyline(line,2);
  }

  line[0].x = 200;
  line[0].y = CanvasY/2;
  line[1].x = 200;
  line[1].y = CanvasY;

  if (ColourMode==true) {
    Screen().Polyline(line,2,6);
  } else {
    Screen().Polyline(line,2);
  }
}

/////////////////////////////////////////////////////////////////////////////

void CDasherViewSquare::ChangeScreen(CDasherScreen* NewScreen)
{
      CDasherView::ChangeScreen(NewScreen);
      screenint Width = Screen().GetWidth();
      screenint Height = Screen().GetHeight();
      CanvasX=9*Width/10;
      CanvasBorder=Width-CanvasX;
      CanvasY=Height;
}

/////////////////////////////////////////////////////////////////////////////

int CDasherView::GetAutoOffset() {
       return CDasherView::yAutoOffset;
}

/////////////////////////////////////////////////////////////////////////////

int CDasherView::GetOneButton() const {
     return onebutton;
}

/////////////////////////////////////////////////////////////////////////////

void CDasherView::SetOneButton(int Value) {
       if (onebutton < -5000) 
               onebutton=-5000;
       if (onebutton > 7000)
               onebutton=7000;
 
       onebutton += Value;
}

/////////////////////////////////////////////////////////////////////////////


Generated by  Doxygen 1.6.0   Back to index