home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0040 - 0049 / ibm0040-0049 / ibm0040.tar / ibm0040 / ZINC_6.ZIP / DOSSRC.ZIP / TEXT.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-01  |  11.3 KB  |  543 lines

  1. //    Zinc Interface Library - TEXT.CPP
  2. //    COPYRIGHT (C) 1990, 1991.  All Rights Reserved.
  3. //    Zinc Software Incorporated.  Pleasant Grove, Utah  USA
  4.  
  5. #include "ui_win.hpp"
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10.  
  11. extern char *AdvanceLine(char *ptr, USHORT numLines, int col, USHORT *actual,
  12.     int width);
  13.  
  14. UIW_TEXT::UIW_TEXT(int left, int top, int _width, int _height, char *_text,
  15.     short maxLength, USHORT _txFlags, USHORT woFlags,
  16.     int (*_validate)(void *object, int ccode)) :
  17.     UIW_STRING(left, top, _width, _text, maxLength, STF_NO_FLAGS, woFlags, _validate),
  18.     txFlags(_txFlags)
  19. {
  20.     windowID[0] = ID_TEXT;
  21.     windowID[1] = ID_STRING;
  22.     search.type = ID_TEXT;
  23.  
  24.     relative.bottom = relative.top + _height - 1;
  25.     true.bottom = true.top + _height - 1;
  26.     cellHeight = -1;
  27.     woFlags &= ~(WOF_JUSTIFY_CENTER | WOF_JUSTIFY_RIGHT);
  28. }
  29.  
  30. int _scrollCount;
  31.  
  32. int UIW_TEXT::Event(const UI_EVENT &event)
  33. {
  34.     int viewOnly = FlagSet(woFlags, WOF_VIEW_ONLY) ||
  35.         FlagSet(woAdvancedStatus, WOAS_TOO_SMALL) ? TRUE : FALSE;
  36.     int ccode = UI_WINDOW_OBJECT::LogicalEvent(event, ID_TEXT);
  37.     UI_REGION region;
  38.     char *ptr;
  39.     int row;
  40.     char *nextLine;
  41.     int numLines;
  42.     USHORT key;
  43.     USHORT count;
  44.     UCHAR reDisplay = TRUE;
  45.     UCHAR displayCheckRegion = FALSE;
  46.     _scrollCount = 0;
  47.  
  48.     if (ccode == S_CREATE || ccode == S_SIZE)
  49.     {
  50.         cellHeight = (display->isText) ?
  51.             display->cellHeight : display->cellHeight - 2;
  52.         cellWidth = display->cellWidth;
  53.         if (ccode == S_CREATE)
  54.         {
  55.             markedBlock = NULL;
  56.             screenTop = text;
  57.             cursor = text;
  58.             cursorDesiredCol = -1;
  59.         }
  60.         else
  61.             cursor = screenTop;
  62.  
  63.         // Determine the size of the text field.  We have to do this 
  64.         // twice to make sure both fields are properly initialized.
  65.         UI_WINDOW_OBJECT::Event(event);
  66.         ComputeRegion(0, region, 0);
  67.     }
  68.     else
  69.         ComputeRegion(0, region, 0);
  70.  
  71.     // Switch on the event type.
  72.     switch (ccode)
  73.     {
  74.     case E_KEY:
  75.         key = event.rawCode & 0xFF;
  76.         if ((key == '\b' || key == '\r' || key >= ' ') && !viewOnly)
  77.         {
  78.             if (key == '\b')
  79.                 BackspaceKey();
  80.             else if (key == '\r')
  81.             {
  82.                 SetMark();
  83.                 if (markStart)
  84.                     CopyBlock();
  85.                 else
  86.                     EnterKey();
  87.                 _scrollCount = 0x00FF;
  88.             }
  89.             else
  90.                 RegularKey(event.key.value);
  91.         }
  92.         else
  93.         {
  94.             reDisplay = FALSE;
  95.             ccode = S_UNKNOWN;
  96.         }
  97.         break;
  98.  
  99.     case L_LEFT:
  100.         if (cursor == text)
  101.         {
  102.             ccode = S_UNKNOWN;
  103.             reDisplay = FALSE;
  104.         }
  105.         else
  106.         {
  107.             MoveOperation();
  108.             LeftArrow();
  109.         }
  110.         break;
  111.  
  112.     case L_RIGHT:
  113.         if (*cursor)
  114.         {
  115.             MoveOperation();
  116.             cursor++;
  117.             if (*cursor == '\n' && *(cursor - 1) == '\r')
  118.                 cursor++;
  119.             cursorDesiredCol = -1;
  120.         }
  121.         else
  122.         {
  123.             ccode = S_UNKNOWN;
  124.             reDisplay = FALSE;
  125.         }
  126.         break;
  127.  
  128.     case S_SCROLL_VERTICAL:
  129.         char *tCursor = cursor;
  130.         char *tMark = markedBlock;
  131.         MoveOperation();
  132.         if (event.scroll.delta < 0)
  133.         {
  134.             screenTop = AdvanceLine(screenTop, -event.scroll.delta, 0, 0, width);
  135.             cursor = AdvanceLine(cursor, -event.scroll.delta, 0, 0, width);
  136.         }
  137.         else
  138.         {
  139.             screenTop = PreviousLine(screenTop, event.scroll.delta, 0, text);
  140.             cursor = PreviousLine(cursor, event.scroll.delta, 0, text);
  141.         }
  142.         if (!screenTop)
  143.             screenTop = text;
  144.         if (FlagSet(woFlags, WOF_VIEW_ONLY))
  145.             cursor = screenTop;
  146.         if (Previous())
  147.             Previous()->Event(event);
  148.         reDisplay = TRUE;
  149.         cursor = tCursor;
  150.         markedBlock = tMark;
  151.         break;
  152.  
  153.     case L_UP:
  154.         if (screenTop == text && cursorRow == 0)
  155.         {
  156.             ccode = S_UNKNOWN;
  157.             reDisplay = FALSE;
  158.         }
  159.         else
  160.         {
  161.             MoveOperation();
  162.             MoveUp(viewOnly && cursorRow ? cursorRow + 1 : 1, ccode);
  163.         }
  164.         break;
  165.  
  166.     case L_DOWN:
  167.         if (LastLine())
  168.         {
  169.             ccode = S_UNKNOWN;
  170.             reDisplay = FALSE;
  171.         }
  172.         else
  173.         {
  174.             MoveOperation();
  175.             MoveDown(!viewOnly || (cursorRow == height - 1) ? 1 :
  176.                 height - cursorRow, ccode);
  177.         }
  178.         break;
  179.  
  180.     case L_PGUP:
  181.         if (screenTop == text && cursorRow == 0)
  182.         {
  183.             ccode = S_UNKNOWN;
  184.             reDisplay = FALSE;
  185.         }
  186.         else
  187.         {
  188.             MoveOperation();
  189.             numLines = cursorRow == 0 ?
  190.                 height - 1 : viewOnly ? cursorRow + height - 1 : cursorRow;
  191.             MoveUp(numLines, ccode);
  192.         }
  193.         break;
  194.  
  195.     case L_PGDN:
  196.         if (LastLine())
  197.         {
  198.             ccode = S_UNKNOWN;
  199.             reDisplay = FALSE;
  200.         }
  201.         else
  202.         {
  203.             MoveOperation();
  204.             numLines = cursorRow == height - 1 ?
  205.                 height - 1 : height - 1 - cursorRow +
  206.                 (viewOnly ? height - 1 : 0);
  207.             MoveDown(numLines, ccode);
  208.         }
  209.         break;
  210.  
  211.     case L_TOP:
  212.         MoveOperation();
  213.         screenTop = text;
  214.         cursor = text;
  215.         cursorDesiredCol = 0;
  216.         break;
  217.  
  218.     case L_BOTTOM:
  219.         MoveOperation();
  220.         MoveDown(0xFFFF, ccode);
  221.         while (*cursor)
  222.             cursor++;
  223.         cursorDesiredCol = -1;
  224.         break;
  225.  
  226.     case L_BOL:
  227.         MoveOperation();
  228.         Home();
  229.         break;
  230.  
  231.     case L_EOL:
  232.         if (*cursor)
  233.         {
  234.             MoveOperation();
  235.             cursor = AdvanceLine(cursor, 1, cursorCol, &count, width);
  236.             if (count)
  237.                 LeftArrow();
  238.             cursorDesiredCol = -1;
  239.         }
  240.         break;
  241.  
  242.     case L_WORD_RIGHT:
  243.         if (*cursor)
  244.         {
  245.             MoveOperation();
  246.             nextLine = AdvanceLine(cursor, 1, cursorCol, &count, width);
  247.             while (NonWhiteSpace(*cursor))
  248.                 cursor++;
  249.             while (*cursor && WhiteSpace(*cursor))
  250.                 cursor++;
  251.             row = cursorRow;
  252.             while (count && cursor >= nextLine)
  253.             {
  254.                 row++;
  255.                 if (row >= height)
  256.                 {
  257.                     screenTop = AdvanceLine(screenTop, 1, 0, 0, width);
  258.                     row--;
  259.                 }
  260.                 nextLine = AdvanceLine(nextLine, 1, 0, &count, width);
  261.             }
  262.             cursorDesiredCol = -1;
  263.         }
  264.         break;
  265.  
  266.     case L_WORD_LEFT:
  267.         MoveOperation();
  268.         WordTabLeft();
  269.         break;
  270.  
  271.     case L_INSERT_TOGGLE:
  272.         MoveOperation();
  273.         insertMode = !insertMode;
  274.         break;
  275.  
  276.     case L_DELETE:
  277.         if (!viewOnly)
  278.         {
  279.             SetMark();
  280.             if (markStart)
  281.             {
  282.                 pasteLength = (int)(markTail - markStart);
  283.                 DeleteBlock(markStart, pasteLength);
  284.             }
  285.             else if (*cursor)
  286.                 DeleteBlock(cursor, (*cursor == '\r' && *(cursor + 1) == '\n') ? 2 : 1);
  287.         }
  288.         break;
  289.  
  290.     case L_DELETE_EOL:
  291.         if (!viewOnly)
  292.             DeleteEol();
  293.         break;
  294.  
  295.     case L_DELETE_WORD:
  296.         if (!viewOnly)
  297.             DeleteWord();
  298.         break;
  299.  
  300.     case L_MARK:
  301.         markedBlock = markedBlock ? NULL : cursor;
  302.         break;
  303.  
  304.     case L_VIEW:
  305.         eventManager->DeviceState(event.type, DM_EDIT);
  306.         reDisplay = FALSE;
  307.         break;
  308.  
  309.     case L_CUT:
  310.         if (!viewOnly)
  311.         {
  312.             SetMark();    // Set markStart & markTail according to original cursor.
  313.             MoveOperation();
  314.             if (event.type != E_KEY)
  315.             {
  316.                 ComputeMousePosition((event.position.column - region.left) / cellWidth,
  317.                     (event.position.line - region.top)  / cellHeight);
  318.                 UpdateCursor(region);
  319.             }
  320.             if (markStart)
  321.             {
  322.                 pasteLength = (int)(markTail - markStart);
  323.                 DeleteBlock(markStart, pasteLength);
  324.             }
  325.             _scrollCount = 0x00FF;
  326.             break;
  327.         }
  328.         // If view only, continue to L_COPY_MARK.
  329.  
  330.     case L_COPY_MARK:
  331.         SetMark();
  332.         if (markStart)
  333.             CopyBlock();
  334.         break;
  335.  
  336.     case L_CUT_PASTE:
  337.         SetMark();
  338.         if (markStart)
  339.         {
  340.             if (viewOnly)
  341.                 CopyBlock();
  342.             else
  343.             {
  344.                 pasteLength = (int)(markTail - markStart);
  345.                 DeleteBlock(markStart, pasteLength);
  346.                 _scrollCount = 0x00FF;
  347.             }
  348.             break;
  349.         }
  350.         // Continue to L_PASTE.
  351.  
  352.     case L_PASTE:
  353.         if (!viewOnly)
  354.         {
  355.             if (event.type != E_KEY)
  356.             {
  357.                 ComputeMousePosition((event.position.column - region.left) / cellWidth,
  358.                     (event.position.line   - region.top)  / cellHeight);
  359.                 UpdateCursor(region);
  360.             }
  361.             PasteBlock();
  362.             _scrollCount = 0x00FF;
  363.         }
  364.         break;
  365.  
  366.     case L_END_MARK:
  367.         if (cursor == markedBlock)
  368.             markedBlock = NULL;
  369.         reDisplay = FALSE;
  370.         break;
  371.  
  372.     case L_CONTINUE_MARK:
  373.         if (markedBlock)
  374.         {
  375.             MoveOperation();
  376.             ComputeMousePosition((event.position.column - region.left) / cellWidth,
  377.                 (event.position.line - region.top) / cellHeight);
  378.             UpdateCursor(region);
  379.             break;
  380.         }
  381.         // Continue to L_BEGIN_MARK.
  382.  
  383.     case L_BEGIN_MARK:
  384.         if (ccode == L_BEGIN_MARK && markedBlock)
  385.             markedBlock = NULL;
  386.         SetMark();    // Set markStart & markTail according to original cursor.
  387.         ComputeMousePosition((event.position.column - region.left) / cellWidth,
  388.             (event.position.line - region.top) / cellHeight);
  389.         UpdateCursor(region);
  390.         markedBlock = cursor;        // Throw away possible old mark.
  391.         break;
  392.  
  393.     case S_ERROR_RESPONSE:
  394.         woStatus |= event.rawCode;
  395.         break;
  396.  
  397.     case S_CURRENT:
  398.         if (NeedsValidation())
  399.             (*Validate)(this, ccode);
  400.         // Clear the WOS_UNANSWERED and WOS_NO_AUTO_CLEAR bits
  401.         woStatus &= ~(WOS_UNANSWERED | WOS_NO_AUTO_CLEAR);
  402.         // Continue to S_DISPLAY_ACTIVE.
  403.  
  404.     case S_DISPLAY_ACTIVE:
  405.         displayCheckRegion = TRUE;
  406.         break;
  407.  
  408.     case S_NON_CURRENT:
  409.         if (NeedsValidation() && (*Validate)(this, ccode) != 0)
  410.         {
  411.             ccode = S_ERROR;
  412.             woStatus |= WOS_INVALID;
  413.             break;
  414.         }
  415.         woStatus &= ~WOS_INVALID;
  416.         // Continue to S_DISPLAY_INACTIVE.
  417.  
  418.     case S_DISPLAY_INACTIVE:
  419.         displayCheckRegion = TRUE;
  420.         break;
  421.  
  422.     default:
  423.         ccode = UI_WINDOW_OBJECT::Event(event);
  424.         reDisplay = FALSE;
  425.         break;
  426.     }
  427.  
  428.     if (displayCheckRegion)
  429.     {
  430.         if (!UI_WINDOW_OBJECT::NeedsUpdate(event, ccode))
  431.         {
  432.             if ((ccode == S_NON_CURRENT || ccode == S_DISPLAY_INACTIVE) &&
  433.                  markedBlock)
  434.                 markedBlock = NULL;             // Throw away mark and re-display.
  435.             else
  436.                 reDisplay = FALSE;
  437.         }
  438.         else
  439.         {
  440.             if (ccode == S_NON_CURRENT || ccode == S_DISPLAY_INACTIVE)
  441.                 markedBlock = NULL;
  442.             screenInvalid = TRUE;
  443.             ComputeRegion(ccode, region, lastPalette);
  444.         }
  445.         _scrollCount = 0x00FF;
  446.     }
  447.  
  448.     if (reDisplay)
  449.     {
  450.         /* Compute possible new top of screen. */
  451.         for (;;)
  452.         {
  453.             ptr = screenTop;
  454.             row = 0;
  455.             if (width <= 0)
  456.                 break;
  457.             while (*ptr && row < height)
  458.             {
  459.                 ptr = AdvanceLine(ptr, 1, 0, &count, width);
  460.                 row += count;
  461.             }
  462.             if (row >= height && ptr <= cursor)
  463.             {
  464.                 char *textOrTail = screenTop;
  465.                 textOrTail = AdvanceLine(textOrTail, 1, 0, 0, width);
  466.                 if (strcmp(textOrTail, textTail))
  467.                     screenTop = textOrTail;
  468.                 else
  469.                     break;
  470.             }
  471.             else
  472.                 break;
  473.         }
  474.  
  475.         Redisplay(region, ccode);
  476.     }
  477.     else if (ccode == S_CURRENT)
  478.         UpdateCursor(region);
  479.  
  480.     if (ccode == S_SCROLL_VERTICAL)
  481.         ;
  482.     else if (_scrollCount == 0x00FF)
  483.         ComputeScroll();
  484.     else if (_scrollCount && previous)
  485.     {
  486.         UI_WINDOW_OBJECT *object = Previous();
  487.         UI_EVENT event;
  488.         event.type = S_SCROLL_VERTICAL;
  489.         event.scroll.delta = _scrollCount;
  490.         object->Event(event);
  491.     }
  492.  
  493.     // Return the control code.
  494.     return (ccode);
  495. }
  496.  
  497. void UIW_TEXT::DataSet(char *newText, short maxLength)
  498. {
  499.     if (newText)
  500.     {
  501.         short oldMaxLength = (short)(textTail + 1 - text);
  502.         if (FlagSet(woFlags, WOF_NO_ALLOCATE_DATA))
  503.             text = newText;
  504.         else
  505.         {
  506.             if (maxLength != -1 && maxLength > oldMaxLength)
  507.             {
  508.                 delete text;
  509.                 text = new char[maxLength];
  510.             }
  511.             strcpy(text, newText);
  512.         }
  513.         textTail = (maxLength != -1) ?
  514.             text + maxLength - 1 : text + oldMaxLength - 1;
  515.         screenTop = text;
  516.         cursor = text;
  517.         cursorDesiredCol = -1;
  518.     }
  519.     UI_WINDOW_OBJECT::Redisplay(FALSE);
  520. }
  521.  
  522. #ifdef ZIL_LOAD
  523. UIW_TEXT::UIW_TEXT(const char *name, UI_STORAGE *file, USHORT loadFlags) :
  524.     UIW_STRING(name, file, loadFlags | L_SUB_LEVEL)
  525. {
  526.     windowID[0] = ID_TEXT;
  527.     windowID[1] = ID_STRING;
  528.  
  529.     file->Load(&txFlags);
  530.     cellHeight = -1;
  531. }
  532. #endif
  533.  
  534. #ifdef ZIL_STORE
  535. void UIW_TEXT::Store(const char *name, UI_STORAGE *file, USHORT storeFlags)
  536. {
  537.     UIW_STRING::Store(name, file, storeFlags | S_SUB_LEVEL);
  538.     file->Store(txFlags);
  539.     if (!FlagSet(storeFlags, S_SUB_LEVEL))
  540.         file->ObjectSize(name, search);
  541. }
  542. #endif
  543.