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