home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / fed0217s.zip / source / cursor.cpp < prev    next >
C/C++ Source or Header  |  2001-04-17  |  9KB  |  378 lines

  1. /*
  2. ** Module   :CURSOR.CPP
  3. ** Abstract :Cursor movement routines
  4. **
  5. ** Copyright (C) Sergey I. Yevtushenko
  6. **
  7. ** Log: Mon  15/03/1998     Created
  8. */
  9.  
  10. #include <buffer.h>
  11. #include <version.h>
  12.  
  13. #define UNDO    1
  14.  
  15. #ifndef max
  16. #define max(a,b) (((a) > (b)) ? (a) : (b))
  17. #define min(a,b) (((a) < (b)) ? (a) : (b))
  18. #endif
  19.  
  20. //----------------------------------------------------------------------
  21. // Cursor movement routines
  22. //
  23. //----------------------------------------------------------------------
  24.  
  25. void Buffer::text_begin(Rect&)
  26. {
  27.     if(cur_row)
  28.         track(opCurRow,(void *)cur_row);
  29.     if(cur_col)
  30.         track(opCurCol,(void *)cur_col);
  31.     if(start_row)
  32.         track(opStartRow,(void *)start_row);
  33.     if(start_col)
  34.         track(opStartCol,(void *)start_col);
  35.  
  36.     cur_row = start_row = cur_col = start_col = 0;
  37. }
  38.  
  39. void Buffer::text_end(Rect& rect)
  40. {
  41.     int _cur_row = cur_row;
  42.     int _cur_col = cur_col;
  43.     int _start_row = start_row;
  44.     int _start_col = start_col;
  45.  
  46.     while(abs_row() < Count() - 1)
  47.     {
  48.         cur_row++;
  49.         if(cur_row + start_row >= Count())
  50.         {
  51.             cur_row = Count() - start_row - 1;
  52.         }
  53.         if(cur_row >= rect.rows)
  54.         {
  55.             start_row += cur_row - rect.rows + 1;
  56.             cur_row   = rect.rows-1;
  57.         }
  58.     }
  59.     line_end(rect);
  60.  
  61.     if(_cur_row != cur_row)
  62.         track(opCurRow,(void *)_cur_row);
  63.     if(_cur_col != cur_col)
  64.         track(opCurCol,(void *)_cur_col);
  65.     if(_start_row != start_row)
  66.         track(opStartRow,(void *)_start_row);
  67.     if(_start_col != start_col)
  68.         track(opStartCol,(void *)_start_col);
  69. }
  70.  
  71. void Buffer::page_up(Rect& rect)
  72. {
  73.     int _cur_row   = cur_row;
  74.     int _start_row = start_row;
  75.  
  76.     for(int i = 0; i < rect.rows - 1; i++)
  77.     {
  78.         start_row--;
  79.         if(start_row < 0)
  80.         {
  81.             start_row = 0;
  82.             cur_row--;
  83.             if(cur_row < 0)
  84.             {
  85.                 cur_row = 0;
  86.                 break;
  87.             }
  88.         }
  89.     }
  90.     if(_cur_row != cur_row)
  91.         track(opCurRow,(void *)_cur_row);
  92.     if(_start_row != start_row)
  93.         track(opStartRow,(void *)_start_row);
  94.  
  95. }
  96.  
  97. void Buffer::page_down(Rect& rect)
  98. {
  99.     int _cur_row   = cur_row;
  100.     int _start_row = start_row;
  101.  
  102.     for(int i = 0; i < rect.rows - 1; i++)
  103.     {
  104.         //cursor_down(rect);
  105.         start_row++;
  106.         if(abs_row() >= Count())
  107.         {
  108.             start_row--;
  109.             cur_row++;
  110.             if(abs_row() >= Count())
  111.             {
  112.                 cur_row--;
  113.                 break;
  114.             }
  115.         }
  116.     }
  117.     if(_cur_row != cur_row)
  118.         track(opCurRow,(void *)_cur_row);
  119.     if(_start_row != start_row)
  120.         track(opStartRow,(void *)_start_row);
  121. }
  122.  
  123. void Buffer::cursor_up(Rect&)
  124. {
  125.     int _cur_row   = cur_row;
  126.     int _start_row = start_row;
  127.  
  128.     cur_row--;
  129.     if(cur_row < 0)
  130.     {
  131.         start_row += cur_row;
  132.         cur_row    = 0;
  133.     }
  134.     if(start_row <0)
  135.         start_row = 0;
  136.  
  137.     if(_cur_row != cur_row)
  138.         track(opCurRow,(void *)_cur_row);
  139.     if(_start_row != start_row)
  140.         track(opStartRow,(void *)_start_row);
  141. }
  142.  
  143. void Buffer::cursor_down(Rect& rect)
  144. {
  145.     int _cur_row   = cur_row;
  146.     int _start_row = start_row;
  147.  
  148.     cur_row++;
  149.  
  150.     if(cur_row + start_row >= Count())
  151.         cur_row = Count() - start_row - 1;
  152.     if(cur_row >= rect.rows)
  153.     {
  154.         start_row += cur_row - rect.rows + 1;
  155.         cur_row   = rect.rows-1;
  156.     }
  157.  
  158.     if(_cur_row != cur_row)
  159.         track(opCurRow,(void *)_cur_row);
  160.     if(_start_row != start_row)
  161.         track(opStartRow,(void *)_start_row);
  162. }
  163.  
  164. void Buffer::line_begin(Rect&)
  165. {
  166.     if(cur_col)
  167.         track(opCurCol,(void *)cur_col);
  168.     if(start_col)
  169.         track(opStartCol,(void *)start_col);
  170.     cur_col = start_col = 0;
  171. }
  172.  
  173. void Buffer::line_end(Rect& rect)
  174. {
  175.     int _cur_col = cur_col;
  176.     int _start_col = start_col;
  177.  
  178.     int slen = abs_line()->len();
  179.  
  180.     //Skip spaces at end of line
  181.     while(slen && __issp(abs_line()->char_at(slen - 1)))
  182.         slen--;
  183.  
  184.     /* Move cursor right */
  185.     while(slen > cur_col + start_col)
  186.     {
  187.         cur_col++;
  188.         if(cur_col >= rect.cols)
  189.         {
  190.             start_col += cur_col - rect.cols + 1;
  191.             cur_col    = rect.cols - 1;
  192.         }
  193.     }
  194.     /* Move cursor left */
  195.     while(slen < cur_col + start_col)
  196.     {
  197.         cur_col--;
  198.         if(cur_col < 0)
  199.         {
  200.             start_col += cur_col;
  201.             cur_col = 0;
  202.         }
  203.         if(start_col < 0)
  204.             start_col = 0;
  205.     }
  206.     if(_cur_col != cur_col)
  207.         track(opCurCol,(void *)_cur_col);
  208.     if(_start_col != start_col)
  209.         track(opStartCol,(void *)_start_col);
  210. }
  211.  
  212. void Buffer::cursor_left(Rect&)
  213. {
  214.     int _cur_col   = cur_col;
  215.     int _start_col = start_col;
  216.  
  217.     cur_col--;
  218.     if(cur_col < 0)
  219.     {
  220.         start_col += cur_col;
  221.         cur_col = 0;
  222.     }
  223.     if(start_col < 0)
  224.         start_col = 0;
  225.  
  226.     if(_cur_col != cur_col)
  227.         track(opCurCol,(void *)_cur_col);
  228.     if(_start_col != start_col)
  229.         track(opStartCol,(void *)_start_col);
  230. }
  231.  
  232. void Buffer::cursor_right(Rect& rect)
  233. {
  234.     int _cur_col   = cur_col;
  235.     int _start_col = start_col;
  236.  
  237.     cur_col++;
  238.     if(cur_col >= rect.cols)
  239.     {
  240.         start_col += cur_col - rect.cols + 1;
  241.         cur_col    = rect.cols - 1;
  242.     }
  243.  
  244.     if(_cur_col != cur_col)
  245.         track(opCurCol,(void *)_cur_col);
  246.     if(_start_col != start_col)
  247.         track(opStartCol,(void *)_start_col);
  248. }
  249.  
  250. void Buffer::word_left(Rect& rect)
  251. {
  252.     int save_col = abs_col();
  253.  
  254.     cursor_left(rect);
  255.     if(abs_col())
  256.     {
  257.         //Skip whitespaces
  258.         while(!is_word_char() && abs_col())
  259.             cursor_left(rect);
  260.  
  261.         int save_col = abs_col();
  262.  
  263.         //Skip word
  264.         while(is_word_char() && abs_col())
  265.             cursor_left(rect);
  266.  
  267.         if(!is_word_char() && abs_col() != save_col)
  268.         {
  269.             cursor_right(rect);
  270.         }
  271.     }
  272.     else
  273.     {
  274.         int save_row = abs_row();
  275.  
  276.         cursor_up(rect);
  277.         if(abs_row() != save_row)
  278.             line_end(rect);
  279.         else
  280.             if(abs_col() != save_col)
  281.                 cursor_right(rect);
  282.     }
  283. }
  284.  
  285. void Buffer::word_right(Rect& rect)
  286. {
  287.     int save_col = abs_col();
  288.  
  289.     cursor_right(rect);
  290.  
  291.     int slen = abs_line()->len();
  292.  
  293.     if(slen)
  294.         slen--;
  295.  
  296.     while(__issp(chr_out(abs_line()->char_at(slen))) && slen > 0)
  297.         slen--;
  298.  
  299.     if(slen > abs_col())
  300.     {
  301.         while(is_word_char() && abs_col() <= slen) //Skip word
  302.             cursor_right(rect);
  303.  
  304.         while(!is_word_char() && abs_col() <= slen) //Skip delimiters
  305.             cursor_right(rect);
  306.     }
  307.     else
  308.     {
  309.         int save_row = abs_row();
  310.  
  311.         cursor_down(rect);
  312.         if(abs_row() != save_row)
  313.             line_begin(rect);
  314.         else
  315.             if(abs_col() != save_col)
  316.                 cursor_left(rect);
  317.     }
  318. }
  319.  
  320. void Buffer::goto_line(Rect& rect, int line_to_go)
  321. {
  322.     if(line_to_go < 0 || line_to_go >= Count())
  323.         return;
  324.  
  325.     track(opCurRow,(void *)cur_row);
  326.  
  327.     //Special case, line already on the screen, we just move cursor to it
  328.  
  329.     if(line_to_go >= start_row && line_to_go < start_row + rect.rows)
  330.     {
  331.         cur_row = line_to_go - start_row;
  332.         return;
  333.     }
  334.  
  335.     //General case
  336.  
  337.     track(opStartRow,(void *)start_row);
  338.  
  339.     //Place this line somewhere around center
  340.     start_row = line_to_go - (rect.rows / 2);
  341.     if(start_row < 0)
  342.         start_row = 0;
  343.     cur_row = line_to_go - start_row;
  344. }
  345.  
  346. void Buffer::goto_col(Rect& rect, int col_to_go)
  347. {
  348.     if(col_to_go < 0)
  349.         return;
  350.  
  351.     track(opCurCol,(void *)cur_col);
  352.     track(opStartCol,(void *)start_col);
  353.  
  354.     start_col = col_to_go - (rect.cols / 2);
  355.     if(start_col < 0)
  356.         start_col = 0;
  357.  
  358.     cur_col = col_to_go - start_col;
  359. }
  360.  
  361. void Buffer::put_mouse(Rect& rect, int new_row, int new_col)
  362. {
  363.     if(new_row < 0 || new_row >= rect.rows)
  364.         return;
  365.  
  366.     if(new_col < 0 || new_col >= rect.cols)
  367.         return;
  368.  
  369.     track(opCurRow,(void *)cur_row);
  370.     track(opCurCol,(void *)cur_col);
  371.  
  372.     cur_col = new_col;
  373.     cur_row = new_row;
  374.  
  375.     if(cur_row + start_row >= Count())
  376.         cur_row = Count() - start_row - 1;
  377. }
  378.