home *** CD-ROM | disk | FTP | other *** search
- // Zinc Interface Library - TEXT.CPP
- // COPYRIGHT (C) 1990, 1991. All Rights Reserved.
- // Zinc Software Incorporated. Pleasant Grove, Utah USA
-
- #include "ui_win.hpp"
- #include <stdio.h>
- #include <ctype.h>
- #include <stdlib.h>
- #include <string.h>
-
- extern char *AdvanceLine(char *ptr, USHORT numLines, int col, USHORT *actual,
- int width);
-
- UIW_TEXT::UIW_TEXT(int left, int top, int _width, int _height, char *_text,
- short maxLength, USHORT _txFlags, USHORT woFlags,
- int (*_validate)(void *object, int ccode)) :
- UIW_STRING(left, top, _width, _text, maxLength, STF_NO_FLAGS, woFlags, _validate),
- txFlags(_txFlags)
- {
- windowID[0] = ID_TEXT;
- windowID[1] = ID_STRING;
- search.type = ID_TEXT;
-
- relative.bottom = relative.top + _height - 1;
- true.bottom = true.top + _height - 1;
- cellHeight = -1;
- woFlags &= ~(WOF_JUSTIFY_CENTER | WOF_JUSTIFY_RIGHT);
- }
-
- int _scrollCount;
-
- int UIW_TEXT::Event(const UI_EVENT &event)
- {
- int viewOnly = FlagSet(woFlags, WOF_VIEW_ONLY) ||
- FlagSet(woAdvancedStatus, WOAS_TOO_SMALL) ? TRUE : FALSE;
- int ccode = UI_WINDOW_OBJECT::LogicalEvent(event, ID_TEXT);
- UI_REGION region;
- char *ptr;
- int row;
- char *nextLine;
- int numLines;
- USHORT key;
- USHORT count;
- UCHAR reDisplay = TRUE;
- UCHAR displayCheckRegion = FALSE;
- _scrollCount = 0;
-
- if (ccode == S_CREATE || ccode == S_SIZE)
- {
- cellHeight = (display->isText) ?
- display->cellHeight : display->cellHeight - 2;
- cellWidth = display->cellWidth;
- if (ccode == S_CREATE)
- {
- markedBlock = NULL;
- screenTop = text;
- cursor = text;
- cursorDesiredCol = -1;
- }
- else
- cursor = screenTop;
-
- // Determine the size of the text field. We have to do this
- // twice to make sure both fields are properly initialized.
- UI_WINDOW_OBJECT::Event(event);
- ComputeRegion(0, region, 0);
- }
- else
- ComputeRegion(0, region, 0);
-
- // Switch on the event type.
- switch (ccode)
- {
- case E_KEY:
- key = event.rawCode & 0xFF;
- if ((key == '\b' || key == '\r' || key >= ' ') && !viewOnly)
- {
- if (key == '\b')
- BackspaceKey();
- else if (key == '\r')
- {
- SetMark();
- if (markStart)
- CopyBlock();
- else
- EnterKey();
- _scrollCount = 0x00FF;
- }
- else
- RegularKey(event.key.value);
- }
- else
- {
- reDisplay = FALSE;
- ccode = S_UNKNOWN;
- }
- break;
-
- case L_LEFT:
- if (cursor == text)
- {
- ccode = S_UNKNOWN;
- reDisplay = FALSE;
- }
- else
- {
- MoveOperation();
- LeftArrow();
- }
- break;
-
- case L_RIGHT:
- if (*cursor)
- {
- MoveOperation();
- cursor++;
- if (*cursor == '\n' && *(cursor - 1) == '\r')
- cursor++;
- cursorDesiredCol = -1;
- }
- else
- {
- ccode = S_UNKNOWN;
- reDisplay = FALSE;
- }
- break;
-
- case S_SCROLL_VERTICAL:
- char *tCursor = cursor;
- char *tMark = markedBlock;
- MoveOperation();
- if (event.scroll.delta < 0)
- {
- screenTop = AdvanceLine(screenTop, -event.scroll.delta, 0, 0, width);
- cursor = AdvanceLine(cursor, -event.scroll.delta, 0, 0, width);
- }
- else
- {
- screenTop = PreviousLine(screenTop, event.scroll.delta, 0, text);
- cursor = PreviousLine(cursor, event.scroll.delta, 0, text);
- }
- if (!screenTop)
- screenTop = text;
- if (FlagSet(woFlags, WOF_VIEW_ONLY))
- cursor = screenTop;
- if (Previous())
- Previous()->Event(event);
- reDisplay = TRUE;
- cursor = tCursor;
- markedBlock = tMark;
- break;
-
- case L_UP:
- if (screenTop == text && cursorRow == 0)
- {
- ccode = S_UNKNOWN;
- reDisplay = FALSE;
- }
- else
- {
- MoveOperation();
- MoveUp(viewOnly && cursorRow ? cursorRow + 1 : 1, ccode);
- }
- break;
-
- case L_DOWN:
- if (LastLine())
- {
- ccode = S_UNKNOWN;
- reDisplay = FALSE;
- }
- else
- {
- MoveOperation();
- MoveDown(!viewOnly || (cursorRow == height - 1) ? 1 :
- height - cursorRow, ccode);
- }
- break;
-
- case L_PGUP:
- if (screenTop == text && cursorRow == 0)
- {
- ccode = S_UNKNOWN;
- reDisplay = FALSE;
- }
- else
- {
- MoveOperation();
- numLines = cursorRow == 0 ?
- height - 1 : viewOnly ? cursorRow + height - 1 : cursorRow;
- MoveUp(numLines, ccode);
- }
- break;
-
- case L_PGDN:
- if (LastLine())
- {
- ccode = S_UNKNOWN;
- reDisplay = FALSE;
- }
- else
- {
- MoveOperation();
- numLines = cursorRow == height - 1 ?
- height - 1 : height - 1 - cursorRow +
- (viewOnly ? height - 1 : 0);
- MoveDown(numLines, ccode);
- }
- break;
-
- case L_TOP:
- MoveOperation();
- screenTop = text;
- cursor = text;
- cursorDesiredCol = 0;
- break;
-
- case L_BOTTOM:
- MoveOperation();
- MoveDown(0xFFFF, ccode);
- while (*cursor)
- cursor++;
- cursorDesiredCol = -1;
- break;
-
- case L_BOL:
- MoveOperation();
- Home();
- break;
-
- case L_EOL:
- if (*cursor)
- {
- MoveOperation();
- cursor = AdvanceLine(cursor, 1, cursorCol, &count, width);
- if (count)
- LeftArrow();
- cursorDesiredCol = -1;
- }
- break;
-
- case L_WORD_RIGHT:
- if (*cursor)
- {
- MoveOperation();
- nextLine = AdvanceLine(cursor, 1, cursorCol, &count, width);
- while (NonWhiteSpace(*cursor))
- cursor++;
- while (*cursor && WhiteSpace(*cursor))
- cursor++;
- row = cursorRow;
- while (count && cursor >= nextLine)
- {
- row++;
- if (row >= height)
- {
- screenTop = AdvanceLine(screenTop, 1, 0, 0, width);
- row--;
- }
- nextLine = AdvanceLine(nextLine, 1, 0, &count, width);
- }
- cursorDesiredCol = -1;
- }
- break;
-
- case L_WORD_LEFT:
- MoveOperation();
- WordTabLeft();
- break;
-
- case L_INSERT_TOGGLE:
- MoveOperation();
- insertMode = !insertMode;
- break;
-
- case L_DELETE:
- if (!viewOnly)
- {
- SetMark();
- if (markStart)
- {
- pasteLength = (int)(markTail - markStart);
- DeleteBlock(markStart, pasteLength);
- }
- else if (*cursor)
- DeleteBlock(cursor, (*cursor == '\r' && *(cursor + 1) == '\n') ? 2 : 1);
- }
- break;
-
- case L_DELETE_EOL:
- if (!viewOnly)
- DeleteEol();
- break;
-
- case L_DELETE_WORD:
- if (!viewOnly)
- DeleteWord();
- break;
-
- case L_MARK:
- markedBlock = markedBlock ? NULL : cursor;
- break;
-
- case L_VIEW:
- eventManager->DeviceState(event.type, DM_EDIT);
- reDisplay = FALSE;
- break;
-
- case L_CUT:
- if (!viewOnly)
- {
- SetMark(); // Set markStart & markTail according to original cursor.
- MoveOperation();
- if (event.type != E_KEY)
- {
- ComputeMousePosition((event.position.column - region.left) / cellWidth,
- (event.position.line - region.top) / cellHeight);
- UpdateCursor(region);
- }
- if (markStart)
- {
- pasteLength = (int)(markTail - markStart);
- DeleteBlock(markStart, pasteLength);
- }
- _scrollCount = 0x00FF;
- break;
- }
- // If view only, continue to L_COPY_MARK.
-
- case L_COPY_MARK:
- SetMark();
- if (markStart)
- CopyBlock();
- break;
-
- case L_CUT_PASTE:
- SetMark();
- if (markStart)
- {
- if (viewOnly)
- CopyBlock();
- else
- {
- pasteLength = (int)(markTail - markStart);
- DeleteBlock(markStart, pasteLength);
- _scrollCount = 0x00FF;
- }
- break;
- }
- // Continue to L_PASTE.
-
- case L_PASTE:
- if (!viewOnly)
- {
- if (event.type != E_KEY)
- {
- ComputeMousePosition((event.position.column - region.left) / cellWidth,
- (event.position.line - region.top) / cellHeight);
- UpdateCursor(region);
- }
- PasteBlock();
- _scrollCount = 0x00FF;
- }
- break;
-
- case L_END_MARK:
- if (cursor == markedBlock)
- markedBlock = NULL;
- reDisplay = FALSE;
- break;
-
- case L_CONTINUE_MARK:
- if (markedBlock)
- {
- MoveOperation();
- ComputeMousePosition((event.position.column - region.left) / cellWidth,
- (event.position.line - region.top) / cellHeight);
- UpdateCursor(region);
- break;
- }
- // Continue to L_BEGIN_MARK.
-
- case L_BEGIN_MARK:
- if (ccode == L_BEGIN_MARK && markedBlock)
- markedBlock = NULL;
- SetMark(); // Set markStart & markTail according to original cursor.
- ComputeMousePosition((event.position.column - region.left) / cellWidth,
- (event.position.line - region.top) / cellHeight);
- UpdateCursor(region);
- markedBlock = cursor; // Throw away possible old mark.
- break;
-
- case S_ERROR_RESPONSE:
- woStatus |= event.rawCode;
- break;
-
- case S_CURRENT:
- if (NeedsValidation())
- (*Validate)(this, ccode);
- // Clear the WOS_UNANSWERED and WOS_NO_AUTO_CLEAR bits
- woStatus &= ~(WOS_UNANSWERED | WOS_NO_AUTO_CLEAR);
- // Continue to S_DISPLAY_ACTIVE.
-
- case S_DISPLAY_ACTIVE:
- displayCheckRegion = TRUE;
- break;
-
- case S_NON_CURRENT:
- if (NeedsValidation() && (*Validate)(this, ccode) != 0)
- {
- ccode = S_ERROR;
- woStatus |= WOS_INVALID;
- break;
- }
- woStatus &= ~WOS_INVALID;
- // Continue to S_DISPLAY_INACTIVE.
-
- case S_DISPLAY_INACTIVE:
- displayCheckRegion = TRUE;
- break;
-
- default:
- ccode = UI_WINDOW_OBJECT::Event(event);
- reDisplay = FALSE;
- break;
- }
-
- if (displayCheckRegion)
- {
- if (!UI_WINDOW_OBJECT::NeedsUpdate(event, ccode))
- {
- if ((ccode == S_NON_CURRENT || ccode == S_DISPLAY_INACTIVE) &&
- markedBlock)
- markedBlock = NULL; // Throw away mark and re-display.
- else
- reDisplay = FALSE;
- }
- else
- {
- if (ccode == S_NON_CURRENT || ccode == S_DISPLAY_INACTIVE)
- markedBlock = NULL;
- screenInvalid = TRUE;
- ComputeRegion(ccode, region, lastPalette);
- }
- _scrollCount = 0x00FF;
- }
-
- if (reDisplay)
- {
- /* Compute possible new top of screen. */
- for (;;)
- {
- ptr = screenTop;
- row = 0;
- if (width <= 0)
- break;
- while (*ptr && row < height)
- {
- ptr = AdvanceLine(ptr, 1, 0, &count, width);
- row += count;
- }
- if (row >= height && ptr <= cursor)
- {
- char *textOrTail = screenTop;
- textOrTail = AdvanceLine(textOrTail, 1, 0, 0, width);
- if (strcmp(textOrTail, textTail))
- screenTop = textOrTail;
- else
- break;
- }
- else
- break;
- }
-
- Redisplay(region, ccode);
- }
- else if (ccode == S_CURRENT)
- UpdateCursor(region);
-
- if (ccode == S_SCROLL_VERTICAL)
- ;
- else if (_scrollCount == 0x00FF)
- ComputeScroll();
- else if (_scrollCount && previous)
- {
- UI_WINDOW_OBJECT *object = Previous();
- UI_EVENT event;
- event.type = S_SCROLL_VERTICAL;
- event.scroll.delta = _scrollCount;
- object->Event(event);
- }
-
- // Return the control code.
- return (ccode);
- }
-
- void UIW_TEXT::DataSet(char *newText, short maxLength)
- {
- if (newText)
- {
- short oldMaxLength = (short)(textTail + 1 - text);
- if (FlagSet(woFlags, WOF_NO_ALLOCATE_DATA))
- text = newText;
- else
- {
- if (maxLength != -1 && maxLength > oldMaxLength)
- {
- delete text;
- text = new char[maxLength];
- }
- strcpy(text, newText);
- }
- textTail = (maxLength != -1) ?
- text + maxLength - 1 : text + oldMaxLength - 1;
- screenTop = text;
- cursor = text;
- cursorDesiredCol = -1;
- }
- UI_WINDOW_OBJECT::Redisplay(FALSE);
- }
-
- #ifdef ZIL_LOAD
- UIW_TEXT::UIW_TEXT(const char *name, UI_STORAGE *file, USHORT loadFlags) :
- UIW_STRING(name, file, loadFlags | L_SUB_LEVEL)
- {
- windowID[0] = ID_TEXT;
- windowID[1] = ID_STRING;
-
- file->Load(&txFlags);
- cellHeight = -1;
- }
- #endif
-
- #ifdef ZIL_STORE
- void UIW_TEXT::Store(const char *name, UI_STORAGE *file, USHORT storeFlags)
- {
- UIW_STRING::Store(name, file, storeFlags | S_SUB_LEVEL);
- file->Store(txFlags);
- if (!FlagSet(storeFlags, S_SUB_LEVEL))
- file->ObjectSize(name, search);
- }
- #endif
-