home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Module :CURSOR.CPP
- ** Abstract :Cursor movement routines
- **
- ** Copyright (C) Sergey I. Yevtushenko
- **
- ** Log: Mon 15/03/1998 Created
- */
-
- #include <buffer.h>
- #include <version.h>
-
- #define UNDO 1
-
- #ifndef max
- #define max(a,b) (((a) > (b)) ? (a) : (b))
- #define min(a,b) (((a) < (b)) ? (a) : (b))
- #endif
-
- //----------------------------------------------------------------------
- // Cursor movement routines
- //
- //----------------------------------------------------------------------
-
- void Buffer::text_begin(Rect&)
- {
- if(cur_row)
- track(opCurRow,(void *)cur_row);
- if(cur_col)
- track(opCurCol,(void *)cur_col);
- if(start_row)
- track(opStartRow,(void *)start_row);
- if(start_col)
- track(opStartCol,(void *)start_col);
-
- cur_row = start_row = cur_col = start_col = 0;
- }
-
- void Buffer::text_end(Rect& rect)
- {
- int _cur_row = cur_row;
- int _cur_col = cur_col;
- int _start_row = start_row;
- int _start_col = start_col;
-
- while(abs_row() < Count() - 1)
- {
- cur_row++;
- if(cur_row + start_row >= Count())
- {
- cur_row = Count() - start_row - 1;
- }
- if(cur_row >= rect.rows)
- {
- start_row += cur_row - rect.rows + 1;
- cur_row = rect.rows-1;
- }
- }
- line_end(rect);
-
- if(_cur_row != cur_row)
- track(opCurRow,(void *)_cur_row);
- if(_cur_col != cur_col)
- track(opCurCol,(void *)_cur_col);
- if(_start_row != start_row)
- track(opStartRow,(void *)_start_row);
- if(_start_col != start_col)
- track(opStartCol,(void *)_start_col);
- }
-
- void Buffer::page_up(Rect& rect)
- {
- int _cur_row = cur_row;
- int _start_row = start_row;
-
- for(int i = 0; i < rect.rows - 1; i++)
- {
- start_row--;
- if(start_row < 0)
- {
- start_row = 0;
- cur_row--;
- if(cur_row < 0)
- {
- cur_row = 0;
- break;
- }
- }
- }
- if(_cur_row != cur_row)
- track(opCurRow,(void *)_cur_row);
- if(_start_row != start_row)
- track(opStartRow,(void *)_start_row);
-
- }
-
- void Buffer::page_down(Rect& rect)
- {
- int _cur_row = cur_row;
- int _start_row = start_row;
-
- for(int i = 0; i < rect.rows - 1; i++)
- {
- //cursor_down(rect);
- start_row++;
- if(abs_row() >= Count())
- {
- start_row--;
- cur_row++;
- if(abs_row() >= Count())
- {
- cur_row--;
- break;
- }
- }
- }
- if(_cur_row != cur_row)
- track(opCurRow,(void *)_cur_row);
- if(_start_row != start_row)
- track(opStartRow,(void *)_start_row);
- }
-
- void Buffer::cursor_up(Rect&)
- {
- int _cur_row = cur_row;
- int _start_row = start_row;
-
- cur_row--;
- if(cur_row < 0)
- {
- start_row += cur_row;
- cur_row = 0;
- }
- if(start_row <0)
- start_row = 0;
-
- if(_cur_row != cur_row)
- track(opCurRow,(void *)_cur_row);
- if(_start_row != start_row)
- track(opStartRow,(void *)_start_row);
- }
-
- void Buffer::cursor_down(Rect& rect)
- {
- int _cur_row = cur_row;
- int _start_row = start_row;
-
- cur_row++;
-
- if(cur_row + start_row >= Count())
- cur_row = Count() - start_row - 1;
- if(cur_row >= rect.rows)
- {
- start_row += cur_row - rect.rows + 1;
- cur_row = rect.rows-1;
- }
-
- if(_cur_row != cur_row)
- track(opCurRow,(void *)_cur_row);
- if(_start_row != start_row)
- track(opStartRow,(void *)_start_row);
- }
-
- void Buffer::line_begin(Rect&)
- {
- if(cur_col)
- track(opCurCol,(void *)cur_col);
- if(start_col)
- track(opStartCol,(void *)start_col);
- cur_col = start_col = 0;
- }
-
- void Buffer::line_end(Rect& rect)
- {
- int _cur_col = cur_col;
- int _start_col = start_col;
-
- int slen = abs_line()->len();
-
- //Skip spaces at end of line
- while(slen && __issp(abs_line()->char_at(slen - 1)))
- slen--;
-
- /* Move cursor right */
- while(slen > cur_col + start_col)
- {
- cur_col++;
- if(cur_col >= rect.cols)
- {
- start_col += cur_col - rect.cols + 1;
- cur_col = rect.cols - 1;
- }
- }
- /* Move cursor left */
- while(slen < cur_col + start_col)
- {
- cur_col--;
- if(cur_col < 0)
- {
- start_col += cur_col;
- cur_col = 0;
- }
- if(start_col < 0)
- start_col = 0;
- }
- if(_cur_col != cur_col)
- track(opCurCol,(void *)_cur_col);
- if(_start_col != start_col)
- track(opStartCol,(void *)_start_col);
- }
-
- void Buffer::cursor_left(Rect&)
- {
- int _cur_col = cur_col;
- int _start_col = start_col;
-
- cur_col--;
- if(cur_col < 0)
- {
- start_col += cur_col;
- cur_col = 0;
- }
- if(start_col < 0)
- start_col = 0;
-
- if(_cur_col != cur_col)
- track(opCurCol,(void *)_cur_col);
- if(_start_col != start_col)
- track(opStartCol,(void *)_start_col);
- }
-
- void Buffer::cursor_right(Rect& rect)
- {
- int _cur_col = cur_col;
- int _start_col = start_col;
-
- cur_col++;
- if(cur_col >= rect.cols)
- {
- start_col += cur_col - rect.cols + 1;
- cur_col = rect.cols - 1;
- }
-
- if(_cur_col != cur_col)
- track(opCurCol,(void *)_cur_col);
- if(_start_col != start_col)
- track(opStartCol,(void *)_start_col);
- }
-
- void Buffer::word_left(Rect& rect)
- {
- int save_col = abs_col();
-
- cursor_left(rect);
- if(abs_col())
- {
- //Skip whitespaces
- while(!is_word_char() && abs_col())
- cursor_left(rect);
-
- int save_col = abs_col();
-
- //Skip word
- while(is_word_char() && abs_col())
- cursor_left(rect);
-
- if(!is_word_char() && abs_col() != save_col)
- {
- cursor_right(rect);
- }
- }
- else
- {
- int save_row = abs_row();
-
- cursor_up(rect);
- if(abs_row() != save_row)
- line_end(rect);
- else
- if(abs_col() != save_col)
- cursor_right(rect);
- }
- }
-
- void Buffer::word_right(Rect& rect)
- {
- int save_col = abs_col();
-
- cursor_right(rect);
-
- int slen = abs_line()->len();
-
- if(slen)
- slen--;
-
- while(__issp(chr_out(abs_line()->char_at(slen))) && slen > 0)
- slen--;
-
- if(slen > abs_col())
- {
- while(is_word_char() && abs_col() <= slen) //Skip word
- cursor_right(rect);
-
- while(!is_word_char() && abs_col() <= slen) //Skip delimiters
- cursor_right(rect);
- }
- else
- {
- int save_row = abs_row();
-
- cursor_down(rect);
- if(abs_row() != save_row)
- line_begin(rect);
- else
- if(abs_col() != save_col)
- cursor_left(rect);
- }
- }
-
- void Buffer::goto_line(Rect& rect, int line_to_go)
- {
- if(line_to_go < 0 || line_to_go >= Count())
- return;
-
- track(opCurRow,(void *)cur_row);
-
- //Special case, line already on the screen, we just move cursor to it
-
- if(line_to_go >= start_row && line_to_go < start_row + rect.rows)
- {
- cur_row = line_to_go - start_row;
- return;
- }
-
- //General case
-
- track(opStartRow,(void *)start_row);
-
- //Place this line somewhere around center
- start_row = line_to_go - (rect.rows / 2);
- if(start_row < 0)
- start_row = 0;
- cur_row = line_to_go - start_row;
- }
-
- void Buffer::goto_col(Rect& rect, int col_to_go)
- {
- if(col_to_go < 0)
- return;
-
- track(opCurCol,(void *)cur_col);
- track(opStartCol,(void *)start_col);
-
- start_col = col_to_go - (rect.cols / 2);
- if(start_col < 0)
- start_col = 0;
-
- cur_col = col_to_go - start_col;
- }
-
- void Buffer::put_mouse(Rect& rect, int new_row, int new_col)
- {
- if(new_row < 0 || new_row >= rect.rows)
- return;
-
- if(new_col < 0 || new_col >= rect.cols)
- return;
-
- track(opCurRow,(void *)cur_row);
- track(opCurCol,(void *)cur_col);
-
- cur_col = new_col;
- cur_row = new_row;
-
- if(cur_row + start_row >= Count())
- cur_row = Count() - start_row - 1;
- }
-