home *** CD-ROM | disk | FTP | other *** search
- /*
-
- eb2.cpp
- 8-10-91
- Electronic Book
-
-
- Copyright 1991
- John W. Small
- All rights reserved
-
- Licensed users of FlexList may use and modify this
- tool for use in their programs.
-
-
- PSW / Power SoftWare
- P.O. Box 10072
- McLean, Virginia 22102 8072 USA
-
- Voice: (703) 759-3838
- CIS: 73757,2233
-
-
- Notes: The Electronic Book was coded to demonstrate
- the various uses of FlexList.
-
-
- */
-
- #include <ctype.h>
- #include <dos.h>
-
- #include <eb1.hpp>
- #include <eb2.hpp>
- #include <pckey.hpp>
- #include <pcput2.hpp>
- #include <pcframe.hpp>
-
-
-
- HyperLaunch::HyperLaunch(int imageX, int imageY,
- const char *launch)
- {
- ix = imageX;
- iy = imageY;
- this->launch = launch;
- ilen = 0;
- if (!launch)
- return;
- for (/* no init */; ilen < MAX_HYPER_LINE &&
- launch[ilen]; ilen++)
- if (launch[ilen] == HYPER_LAUNCH_DELIMIT)
- break;
- }
-
- void HyperLaunch::hilite(int winleft, int wintop,
- int winwidth, int winheight, int attr)
- {
- int x, y, i, l;
-
- if (iy < wintop)
- return;
- if ((y = iy - wintop + 1) > winheight)
- return;
- if (ix < winleft)
- if (ix + ilen <= winleft)
- return; // launch left of window
- else {
- x = 1;
- i = winleft - ix;
- if ((l = ilen - i) > winwidth)
- l = winwidth;
- }
- else if ((x = ix - winleft + 1) > winwidth)
- return; // launch right of window
- else {
- i = 0;
- if (x + ilen >= winwidth)
- l = winwidth - x + 1;
- else
- l = ilen;
- }
- gotoxy(x,y);
- textattr(attr);
- cprintf("%.*s",l,&launch[i]);
- }
-
- int HyperLaunch::match(const char *prefix, int pfLen)
- {
- if (pfLen <= ilen)
- if (!strncmpi(prefix,launch,pfLen))
- return ix+pfLen-1;
- return 0;
- }
-
-
- Palette HyperContext::defaultP = {
-
- 0, /* monochrome or color */
-
- svideo(BLACK,LIGHTGRAY), svideo(WHITE,BLUE),
- svideo(DARKGRAY,LIGHTGRAY), svideo(LIGHTRED,BLUE),
- svideo(WHITE,BLACK), svideo(BLUE,LIGHTGRAY)
- };
-
- int HyperContext::defaultTabSpacing = 8;
-
- void HyperContext::findLinesAndLaunches()
- {
- int x, y, l;
- unsigned inLaunch, i;
- char *nline;
- HyperLauncH HL;
-
- if ((nline = context) == (char *)0)
- return;
- for (x = y = 1, inLaunch = i = 0; i < clen; i++) {
- if (nline) {
- lines.insQD(&nline);
- nline = (char *)0;
- }
- switch(context[i]) {
- case HYPER_LAUNCH_DELIMIT:
- if (context[i+1] ==
- HYPER_LAUNCH_DELIMIT) {
- i++;
- x++;
- continue;
- }
- if (inLaunch)
- inLaunch = !inLaunch;
- else if ((HL = new(launches.insQD())
- HyperLaunch(x,y,
- &context[++i]))
- != HyperLauncH0) {
- l = HL->len();
- i += l;
- x += l;
- }
- else
- inLaunch = !inLaunch;
- break;
- case '\r':
- if (context[i+1] == '\n')
- i++;
- case '\n':
- x = 1;
- y++;
- nline = &context[i+1];
- break;
- case TAB:
- while (x++ % tabSpacing)
- /* null stmt */;
- break;
- default:
- x++;
- break;
- }
- }
- }
-
- HyperContext::HyperContext(char *context, unsigned clen,
- const char *inlinks, const char *outlinks,
- unsigned startRow, unsigned startColumn,
- unsigned cursorRow, unsigned cursorColumn,
- unsigned topicNum)
- : lines(sizeof(char *)),
- launches(sizeof(HyperLaunch))
- {
- this ->context = context;
- this->inlinks = strdup(inlinks);
- this->outlinks = strdup(outlinks);
- this->clen = clen;
- choice = 0;
- setPalette();
- this->startRow = startRow;
- this->startColumn = startColumn;
- this->cursorRow = cursorRow;
- this->cursorColumn = cursorColumn;
- this->topicNum = topicNum;
- tabSpacing = defaultTabSpacing;
- prefix[pfLen=0] = '\0';
- lines.setMaxNodes(MAX_HYPER_TOPIC_LINES);
- launches.setMaxNodes(MAX_HYPER_TOPIC_LAUNCHES);
- findLinesAndLaunches();
- }
-
- HC_ACTIONS HyperContext::view()
- {
- struct text_info ti;
- ScrLnBuf scrbuf;
- char *nline;
- int x, y, i;
- unsigned pgHeight, winHeight;
- unsigned oldStartColumn, oldStartRow;
- unsigned char scrollAttr;
- unsigned scrollTopLeft, scrollBottomRight;
- unsigned oldChoice;
- HyperLauncH HL;
-
- PCF.reset();
- gettextinfo(&ti);
- mappalette(P);
- mapvideo(NORMAL,P);
- winHeight = ti.winbottom - ti.wintop + 1;
- pgHeight = winHeight - 1;
- scrbuf.set(mapattr(NORMAL,P),mapattr(HILITE,P),
- ti.winright-ti.winleft+1,startColumn,1,'\r',
- HYPER_LAUNCH_DELIMIT,tabSpacing);
- if (cursorRow >= startRow + winHeight)
- startRow = cursorRow - winHeight + 1;
- else if (cursorRow < startRow)
- startRow = cursorRow;
- oldStartColumn = oldStartRow = 0;
- scrollAttr = mapattr(NORMAL,P);
- scrollBottomRight = ((ti.winbottom-1) << 8)
- | (ti.winright-1);
- scrollTopLeft = ((ti.wintop-1) << 8)
- | (ti.winleft-1);
-
- prefix[pfLen = 0] = '\0';
- oldChoice = choice = 0;
-
-
- while (1) {
- if (pfLen) { // find typed in hyper link
- choice = 0;
- for (launches.mkcur(); (HL = (HyperLauncH)
- launches.nextD()) != HyperLauncH0;
- /* no reinit */) {
- if ((x = HL->match(prefix,pfLen)) != 0) {
- cursorColumn = x + 1;
- choice = launches.CurNum();
- cursorRow = HL->IY();
- break;
- }
- }
- if (!choice)
- prefix[pfLen = 0] = '\0';
- }
- else if (oldChoice != choice) // find tabbed to hyper link
- if ((HL = (HyperLauncH) launches.mkcur(choice))
- != HyperLauncH0) {
- cursorRow = HL->IY();
- cursorColumn = HL->IX();
- }
- if (cursorRow < startRow)
- startRow = cursorRow;
- else if (cursorRow >= startRow + winHeight)
- startRow = cursorRow - winHeight + 1;
- if (cursorColumn < scrbuf.startColumn)
- scrbuf.startColumn = cursorColumn;
- else if (cursorColumn >= scrbuf.startColumn
- + scrbuf.pgWidth)
- scrbuf.startColumn = cursorColumn
- - scrbuf.pgWidth + 1;
- if (oldStartColumn != scrbuf.startColumn ||
- oldStartRow != startRow) {
- if (oldStartColumn == scrbuf.startColumn &&
- oldStartRow &&
- ((((y = oldStartRow-startRow) > 0)?
- y : -y) <= 1)) {
- // scroll up/down and insert line.
- _DX = scrollBottomRight;
- _CX = scrollTopLeft;
- _BH = scrollAttr;
- _AX = (y > 0)? 0x0701 : 0x0601;
- geninterrupt(0x10);
- y = (( y > 0)? startRow : startRow
- + winHeight - 1);
- if (lines.recallD(&nline,y))
- scrbuf.put(nline,ti.winleft,
- ti.wintop+y-startRow);
- }
- else {
- lines.mkcur(startRow-1);
- for (y = 0; y < winHeight &&
- lines.nextD(&nline); y++) {
- scrbuf.put(nline,
- ti.winleft,ti.wintop+y);
- }
- while (y < winHeight)
- scrbuf.put((char *)0,
- ti.winleft,ti.wintop+y++);
- }
- oldStartColumn = scrbuf.startColumn;
- oldStartRow = startRow;
- }
- if (!pfLen) { // find cursor moved over hyper link
- choice = 0;
- for (launches.mkcur(); (HL = (HyperLauncH)
- launches.nextD()) != HyperLauncH0;
- /* no reinit */)
- if (HL->onLaunchPad(cursorColumn,cursorRow)) {
- choice = launches.CurNum();
- break;
- }
- }
- if (oldChoice != choice) { // New hyper link to hilite
- if ((HL = (HyperLauncH) launches.mkcur(oldChoice))
- != HyperLauncH0)
- HL->hilite(scrbuf.startColumn,startRow,
- scrbuf.pgWidth,winHeight,
- mapattr(HILITE,P));
- if ((HL = (HyperLauncH) launches.mkcur(choice))
- != HyperLauncH0)
- HL->hilite(scrbuf.startColumn,startRow,
- scrbuf.pgWidth,winHeight,
- mapattr(SELECT,P));
- oldChoice = choice;
- }
- startColumn = scrbuf.startColumn; // save for hyperstack
- gotoxy(cursorColumn-startColumn+1,
- cursorRow-startRow+1);
- pfLen = 0; // get ready to erase prefix if not added to
- switch (PCK.getkey()) {
- case -Home:
- cursorColumn = scrbuf.startColumn = 1;
- break;
- case -EndKey:
- // compute line length;
- if (lines.recallD(&nline,cursorRow)) {
- scrbuf.writebuf(nline);
- cursorColumn = scrbuf.eolColumn;
- }
- else
- cursorColumn = 1;
- if (cursorColumn < scrbuf.startColumn)
- scrbuf.startColumn = cursorColumn;
- else if (cursorColumn >=
- scrbuf.startColumn + scrbuf.pgWidth)
- scrbuf.startColumn = cursorColumn
- - scrbuf.pgWidth + 1;
- break;
- case CtrlS:
- case -LArr:
- if (cursorColumn > 1)
- if (--cursorColumn < scrbuf.startColumn)
- scrbuf.startColumn = cursorColumn;
- break;
- case CtrlD:
- case -RArr:
- if (cursorColumn < MAX_HYPER_LINE)
- if (++cursorColumn >=
- scrbuf.startColumn + scrbuf.pgWidth)
- scrbuf.startColumn = cursorColumn
- - scrbuf.pgWidth + 1;
- break;
- case -UpArr:
- if (cursorRow > 1)
- if (--cursorRow < startRow)
- startRow = cursorRow;
- break;
- case -DnArr:
- if (cursorRow < lines.Nodes()) {
- if (++cursorRow >= startRow + winHeight)
- startRow = cursorRow - winHeight + 1;
- }
- else if (startRow < cursorRow)
- startRow++;
- break;
- case CtrlA:
- case -CtrlLArr:
- if (lines.recallD(&nline,cursorRow)) {
- scrbuf.writebuf(nline);
- if (cursorColumn > scrbuf.eolColumn)
- i = scrbuf.eolColumn - 1;
- else
- i = cursorColumn - 1;
- while (i && !isalnum((char)scrbuf.buf[i-1]))
- i--;
- if (!i) {
- if (cursorRow == 1)
- break;
- if (lines.recallD(&nline,cursorRow-1)) {
- cursorRow--;
- scrbuf.writebuf(nline);
- cursorColumn = scrbuf.eolColumn;
- }
- break;
- }
- while (i && isalnum((char)scrbuf.buf[i-1]))
- i--;
- cursorColumn = i + 1;
- }
- break;
- case CtrlF:
- case -CtrlRArr:
- lines.mkcur(cursorRow-1);
- for (i = cursorColumn - 1; lines.nextD(&nline);
- i = 0) {
- scrbuf.writebuf(nline);
- x = scrbuf.eolColumn - 1;
- if (i >= x)
- continue;
- while (i < x && isalnum((char)scrbuf.buf[i])) i++;
- if (i >= x)
- break;
- while (i < x && !isalnum((char)scrbuf.buf[i])) i++;
- if (i < x)
- break;
- }
- if (lines.CurNum()) {
- cursorRow = lines.CurNum();
- cursorColumn = i + 1;
- }
- break;
- case -CtrlHome:
- cursorRow = startRow;
- break;
- case -CtrlEnd:
- if (startRow + winHeight - 1 > lines.Nodes())
- cursorRow = lines.Nodes();
- else
- cursorRow = startRow + winHeight - 1;
- break;
- case -PgDn:
- cursorRow += pgHeight;
- if (cursorRow >= lines.Nodes()) {
- cursorRow = lines.Nodes();
- if (startRow + pgHeight > cursorRow)
- break;
- }
- startRow += pgHeight;
- if (startRow > cursorRow)
- startRow = cursorRow;
- break;
- case -PgUp:
- if (cursorRow > pgHeight)
- cursorRow -= pgHeight;
- else
- cursorRow = 1;
- if (startRow > pgHeight)
- startRow -= pgHeight;
- else
- startRow = 1;
- break;
- case -CtrlPgUp:
- startRow = cursorRow = 1;
- break;
- case -CtrlPgDn:
- cursorRow = lines.Nodes();
- if (cursorRow >= startRow + winHeight)
- if (cursorRow > winHeight/2)
- startRow = cursorRow
- - winHeight/2;
- else
- startRow = 1;
- break;
- case CtrlZ: // pan down
- if (startRow < lines.Nodes())
- if (++startRow > cursorRow)
- cursorRow = startRow;
- break;
- case CtrlW: // pan up
- if (startRow > 1)
- if (--startRow + winHeight <= cursorRow)
- cursorRow = startRow + winHeight - 1;
- break;
- case -F1:
- return HELP;
- case -F3:
- return LOAD;
- case -F10:
- case -AltT:
- return TABLE_OF_CONTENTS;
- case -AltF10:
- case -AltI:
- return INDEX;
- case CR:
- choice = 0;
- for (launches.mkcur(); (HL = (HyperLauncH)
- launches.nextD()) != HyperLauncH0;
- /* no reinit */)
- if (HL->onLaunchPad(cursorColumn,cursorRow)) {
- choice = launches.CurNum();
- return LAUNCH;
- }
- break;
- case -AltF1:
- case BACKSP:
- return BACKUP;
- case -ShiftF6:
- return ATTR_TOGGLE;
- case -F6:
- return RES_TOGGLE;
- case -AltX:
- return EXIT;
- case TAB:
- if (!choice) { // find closest launch to cursor
- for (launches.mkcur(); (HL = (HyperLauncH)
- launches.nextD()) != HyperLauncH0;
- /* no reinit */)
- if ((HL->IY() > cursorRow) ||
- ((HL->IY() == cursorRow) &&
- ((HL->IX() + HL->len())
- > cursorColumn)))
- break;
- if ((choice = launches.CurNum()) == 0)
- choice = 1;
- }
- else if (choice < launches.Nodes())
- choice++;
- else
- choice = 1;
- break;
- case -ShiftTab:
- if (!choice) { // find closest launch to cursor
- for (launches.mkcur(); (HL = (HyperLauncH)
- launches.prevD()) != HyperLauncH0;
- /* no reinit */)
- if ((HL->IY() < cursorRow) ||
- ((HL->IY() == cursorRow) &&
- (HL->IX() < cursorColumn)))
- break;
- if ((choice = launches.CurNum()) == 0)
- choice = launches.Nodes();
- }
- else if (choice > 1)
- choice--;
- else
- choice = launches.Nodes();
- break;
- default:
- if ((pfLen = strlen(prefix)) >= MAX_HC_PREFIX - 1)
- continue;
- if (!isprint(PCK.ascii()))
- continue;
- prefix[pfLen++] = toupper(PCK.ascii());
- break;
- }
- prefix[pfLen] = '\0';
- }
- return EXIT;
- }
-
- char * HyperContext::newTarget()
- {
- char *t;
-
- if (!choice) return (char *)0;
- t = parseLinks(outlinks);
- for (unsigned i = 1; i < choice; i++)
- t = parseLinks();
- return t;
- }
-
- HyperContext::~HyperContext()
- {
- delete context;
- lines.clear();
- launches.clear();
- delete inlinks;
- delete outlinks;
- }
-