home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware 1 2 the Maxx
/
sw_1.zip
/
sw_1
/
PROGRAM
/
AEWIN100.ZIP
/
CONTRIB
/
WINDOWS
/
SRC
/
BASEWIN.CC
next >
Wrap
C/C++ Source or Header
|
1991-10-27
|
6KB
|
285 lines
/**********************************************************************
*
* NAME: basewin.cpp
*
* DESCRIPTION:
*
* copyright (c) 1990 J. Alan Eldridge
*
* M O D I F I C A T I O N H I S T O R Y
*
* when who what
* -------------------------------------------------------------------
* 11/??/90 J. Alan Eldridge created
*
*********************************************************************/
#include "w.h"
// local defines
#define PRINTF_MAX 512 // size of string buffer for printf()
// Unix Curses clears to end of line on newline ...
// set NL_DOES_CLREOL to 0 if you do not want this behavior
#define NL_DOES_CLREOL 1
// destructor
basewin::~basewin()
{
if (state == OK) {
delete xdirty;
state = ERR;
}
}
// constructor
basewin::basewin(
int yul, int xul,
int ylr, int xlr):
vidbuf(yul, xul, ylr, xlr),
viewport(0, 0, ylr - yul, xlr - xul)
{
if (state == OK) {
if (!(xdirty = new int [ ylr - yul ][ 2 ]))
state = ERR;
}
if (state == OK) {
zflags();
unmark();
att = vid_defaultatt;
clear();
}
}
// clear current port
basewin &
basewin::clear(uchar ch)
{
setpos(0,0);
vidbuf::clear(yUL,xUL,yLR,xLR,ch,att);
touch();
return *this;
}
// clear to end of line
basewin &
basewin::clreol(uchar ch)
{
if (xCur <= xLR) {
mark(yCur);
markline(yCur, xCur);
markline(yCur, xLR);
clrline(yCur, xCur, xLR, ch, att);
}
return *this;
}
// newline (implies carriage return)
basewin &
basewin::NL()
{
#if NL_DOES_CLREOL
clreol();
#endif
CR();
if (yCur < yLR) {
yCur++;
} else if (fScroll) {
scroll();
}
return *this;
}
// carriage return
basewin &
basewin::CR()
{
xCur = xUL;
return *this;
}
// non-destructive backspace
basewin &
basewin::BS()
{
if (xCur > xUL) {
xCur--;
} else if (yCur > yUL) {
yCur--;
xCur = xLR;
}
return *this;
}
// put a single character
basewin &
basewin::put(uchar ch)
{
if (ch == '\r')
return CR();
else if (ch == '\n')
return NL();
else if (ch == '\b')
return BS();
else if (xCur <= xLR) {
mark(yCur);
markline(yCur, xCur);
putchr(yCur, xCur++, ch, att);
if (xCur > xLR && fWrap) {
NL();
}
}
return *this;
}
// put a string
basewin &
basewin::put(uchar *s)
{
while (*s) {
put(*s++);
}
return *this;
}
basewin &
basewin::center(int line, uchar *s)
{
int skip = (cols - strlen(s))/2;
if (skip < 0)
skip = 0;
setpos(line, 0);
clreol();
setpos(yCur, skip);
return put(s);
}
// printf to current position
basewin &
basewin::printf(uchar *fmt, ...)
{
uchar buf[PRINTF_MAX];
va_list ap;
va_start(ap, fmt);
vsprintf(buf, fmt, ap);
va_end(ap);
return put(buf);
}
// mark row as dirty (does NOT set line dirty markers)
void
basewin::mark(int row)
{
if (row < ydirty[0]) ydirty[0] = row;
if (row > ydirty[1]) ydirty[1] = row;
}
// mark position on line as dirty
void
basewin::markline(int row, int col)
{
if (col < xdirty[row][0]) xdirty[row][0] = col;
if (col > xdirty[row][1]) xdirty[row][1] = col;
}
// unmark everything (nothing to redraw)
void
basewin::unmark()
{
ydirty[0] = INT_MAX; ydirty[1] = 0;
for (int y = 0; y < rows; y++) {
xdirty[y][0] = INT_MAX; xdirty[y][1] = 0;
}
}
// mark a region as dirty
void
basewin::touch(
int yul,
int xul,
int ylr,
int xlr)
{
mark(yul);
mark(ylr);
for (int y = yul; y <= ylr; y++) {
markline(y, xul);
markline(y, xlr);
}
}
// update to display screen
void
basewin::refresh(int vflag)
{
if (state != OK)
return;
for (int y = ydirty[0], ylim = ydirty[1]; y <= ylim; y++) {
int x = xdirty[y][0], xlim = xdirty[y][1];
if (x <= xlim)
display(y, x, xlim - x + 1, vflag);
}
unmark();
setcursor(vflag);
}
// scroll a section of a window
void
basewin::scroll(
int yul,
int xul,
int ylr,
int xlr,
int nLines)
{
if (nLines) {
int absLines = abs(nLines);
// 3 choices here: clear it, scroll up, or scroll down
if (absLines > ylr - yul) {
vidbuf::clear(yul, xul, ylr, xlr, ' ', att);
} else {
int rows = ylr - yul + 1 - absLines;
int bytes = (xlr - xul + 1) * sizeof(vidchr);
if (nLines > 0) {
// scroll up
for (int r = yul; rows-- > 0; r++) {
memcpy(vidptr(r, xul), vidptr(r + nLines, xul), bytes);
}
vidbuf::clear(r, xul, ylr, xlr, ' ', att);
} else {
// scroll down
for (int r = ylr; rows-- > 0; r--) {
memcpy(vidptr(r, xul), vidptr(r + nLines, xul), bytes);
}
vidbuf::clear(yul, xul, r, xlr, ' ', att);
}
touch(yul, xul, ylr, xlr);
}
}
}