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 / MATRIX.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-01  |  11.0 KB  |  356 lines

  1. //    Zinc Interface Library - MATRIX.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 <math.h>
  7.  
  8. UIW_MATRIX::UIW_MATRIX(int left, int top, int width, int height,
  9.     int _maxRowsColumns, int _cellWidth, int _cellHeight,
  10.     int (*_compareFunction)(void *element1, void *element2),
  11.     USHORT _mxFlags, USHORT _woFlags, USHORT _woAdvancedFlags) :
  12.     UIW_WINDOW(left, top, width, height, _woFlags, _woAdvancedFlags),
  13.     mxFlags(_mxFlags), maxRowsColumns(_maxRowsColumns), cellWidth(_cellWidth),
  14.     cellHeight(_cellHeight)
  15. {
  16.     // Initialize the matrix information.
  17.     windowID[0] = ID_MATRIX;
  18.     windowID[1] = ID_WINDOW;
  19.     search.type = ID_MATRIX;
  20.  
  21.     compareFunction = _compareFunction;
  22. }
  23.  
  24. UIW_MATRIX::UIW_MATRIX(int left, int top, int width, int height,
  25.     USHORT flagSetting, UI_ITEM *flagItem) :
  26.     UIW_WINDOW(left, top, width, height, WOF_BORDER, WOAF_NO_FLAGS),
  27.     mxFlags(MXF_ROWS_FILL), cellWidth(width), cellHeight(1)
  28. {
  29.     // Initialize the matrix information.
  30.     windowID[0] = ID_MATRIX;
  31.     windowID[1] = ID_WINDOW;
  32.     search.type = ID_MATRIX;
  33.  
  34.     compareFunction = NULL;
  35.     for (int i = 0; flagItem[i].string; i++)
  36.     {
  37.         UIW_POP_UP_ITEM *item = new UIW_POP_UP_ITEM(0, i, width,
  38.             flagItem[i].string, MNIF_NO_FLAGS, BTF_CHECK_MARK, WOF_NO_FLAGS,
  39.             flagItem[i].userFunction);
  40.         item->value = flagItem[i].value;
  41.         if (FlagSet(flagSetting, flagItem[i].value))
  42.             item->woStatus |= WOS_SELECTED;
  43.         *this + item;
  44.     }
  45.     maxRowsColumns = i;
  46. }
  47.  
  48. UIW_MATRIX::Event(const UI_EVENT &event)
  49. {
  50.     // Switch on the event type.
  51.     int height = 0;
  52.     int ccode = UI_WINDOW_OBJECT::LogicalEvent(event, ID_MATRIX);
  53.     UI_WINDOW_OBJECT *object, *sObject;
  54.     UI_EVENT tEvent;
  55.  
  56.     UI_WINDOW_OBJECT *topObject, *bottomObject;
  57.     UI_WINDOW_OBJECT *tObject = (UI_WINDOW_OBJECT *)UI_LIST::Get(UIW_WINDOW::FindStatus, &WOS_CURRENT);
  58.  
  59.     int scrollRecompute = FALSE;
  60.     int tcode;
  61.     switch (ccode)
  62.     {
  63.     case L_PGUP:
  64.     case L_PGDN:
  65.     case L_PREVIOUS:
  66.     case L_NEXT:
  67.     case L_UP:
  68.     case L_DOWN:
  69.         if (!First())
  70.             return (S_UNKNOWN);
  71.         topObject = bottomObject = First();
  72.         for (object = First(); object; object = object->Next())
  73.         {
  74.             if (object->relative.top < topObject->relative.top)
  75.                 topObject = object;
  76.             if (object->relative.top > bottomObject->relative.top)
  77.                 bottomObject = object;
  78.         }
  79.         object = (UI_WINDOW_OBJECT *)UI_LIST::Get(UIW_WINDOW::FindStatus, &WOS_CURRENT);
  80.         if (ccode == L_PREVIOUS || ccode == L_PGUP || ccode == L_UP)
  81.         {
  82.             sObject = object->Previous();
  83.             while (sObject && FlagSet(sObject->woFlags, WOF_NON_SELECTABLE))
  84.                 sObject = sObject->Previous();
  85.         }
  86.         else
  87.         {
  88.             sObject = object->Next();
  89.             while (sObject && FlagSet(sObject->woFlags, WOF_NON_SELECTABLE))
  90.                 sObject = sObject->Next();
  91.         }
  92.         if (((ccode == L_PREVIOUS || ccode == L_PGUP) && !sObject) ||
  93.             ((ccode == L_NEXT || ccode == L_PGDN) && !sObject) ||
  94.             (ccode == L_UP && (!sObject || object->relative.top == topObject->relative.top)) ||
  95.             (ccode == L_DOWN && (!sObject || object->relative.bottom == bottomObject->relative.bottom)))
  96.             return (object->Event(event));
  97.  
  98.         scrollRecompute = TRUE;
  99.         tcode = UIW_WINDOW::Event(event);
  100.         if (tcode != S_UNKNOWN && tcode != S_ERROR)
  101.             break;
  102.         if (ccode == L_UP || ccode == L_PREVIOUS)
  103.             height = display->cellHeight;
  104.         else if (ccode == L_DOWN || ccode == L_NEXT)
  105.             height = -display->cellHeight;
  106.         else if (ccode == L_PGUP)
  107.             height = ((true.bottom - true.top) / display->cellHeight) * display->cellHeight;
  108.         else
  109.             height = -((true.bottom - true.top) / display->cellHeight) * display->cellHeight;
  110.         // Continue to S_SCROLL_HORIZONTAL and S_SCROLL_VERTICAL.
  111.  
  112.     case S_SCROLL_VERTICAL:
  113.         // Get the delta scroll values.
  114.         if (ccode == S_SCROLL_VERTICAL)
  115.             height = event.scroll.delta * display->cellHeight;
  116.         topObject = bottomObject = First();
  117.         for (object = First(); object; object = object->Next())
  118.         {
  119.             if (object->relative.top < topObject->relative.top)
  120.                 topObject = object;
  121.             if (object->relative.top > bottomObject->relative.top)
  122.                 bottomObject = object;
  123.         }
  124.         if ((height > 0 && FlagSet(topObject->woAdvancedStatus, WOAS_INVALID_REGION | WOAS_TOO_SMALL)) ||
  125.             (height < 0 && FlagSet(bottomObject->woAdvancedStatus, WOAS_INVALID_REGION | WOAS_TOO_SMALL)))
  126.         {
  127.             if (height < 0 &&
  128.                 bottomObject->relative.bottom + height < true.bottom - true.top)
  129.                 height = ((true.bottom - true.top - bottomObject->relative.bottom) /
  130.                     display->cellHeight) * display->cellHeight;
  131.             else if (height > 0 &&
  132.                 topObject->relative.top + height > 0)
  133.                 height = -topObject->relative.top;
  134.             for (object = First(); object; object = object->Next())
  135.             {
  136.                 object->relative.top += height;
  137.                 object->relative.bottom += height;
  138.             }
  139.             tEvent.type = S_SIZE;
  140.             UIW_WINDOW::Event(tEvent);
  141.              UIW_WINDOW::RegionsCompute();
  142.         }
  143.  
  144.         // Change the current field.
  145.         if (!tObject)
  146.             break;
  147.         height = (ccode == S_SCROLL_VERTICAL) ? event.scroll.delta : height / display->cellHeight;
  148.         topObject = tObject;
  149.         for (object = tObject->Previous(); object && height > 0; object = object->Previous())
  150.             if (topObject->relative.top > object->relative.top)
  151.             {
  152.                 topObject = object;
  153.                 height--;
  154.             }
  155.             else if (topObject->relative.top == object->relative.top)
  156.                 topObject = object;
  157.         for (object = topObject->Previous(); object; object = object->Previous())
  158.             if (object->relative.top == topObject->relative.top)
  159.                 topObject = object;
  160.             else
  161.                 break;
  162.         for (object = tObject->Next(); object && height < 0; object = object->Next())
  163.             if (topObject->relative.top < object->relative.top)
  164.             {
  165.                 topObject = object;
  166.                 height++;
  167.             }
  168.         if (topObject)
  169.         {
  170.             object = topObject;
  171.             while (object->relative.top == topObject->relative.top)
  172.                 if (object->relative.left == tObject->relative.left)
  173.                     break;
  174.                 else
  175.                 {
  176.                     topObject = topObject->Next();
  177.                     if (!topObject || topObject->relative.top != object->relative.top)
  178.                         break;
  179.                     object = topObject;
  180.                 }
  181.             tObject->woStatus &= ~WOS_CURRENT;
  182.             if (height > 0)
  183.                 while (object->Next() && FlagSet(object->woFlags, WOF_NON_SELECTABLE))
  184.                     object = object->Next();
  185.             else if (height < 0)
  186.                 while (object->Previous() && FlagSet(object->woFlags, WOF_NON_SELECTABLE))
  187.                     object = object->Previous();
  188.             object->woStatus |= WOS_CURRENT;
  189.  
  190.             scrollRecompute = TRUE;
  191.         }
  192.  
  193.         tEvent.type = S_CURRENT;
  194.         tEvent.region = true;
  195.         ccode = UIW_WINDOW::Event(tEvent);
  196.         break;
  197.  
  198.     case S_CREATE:
  199.         {
  200.         UI_WINDOW_OBJECT::Event(event);
  201.  
  202.         if (!FlagSet(mxFlags, MXF_ROWS_FILL | MXF_COLUMNS_FILL))
  203.         {
  204.             ccode = UIW_WINDOW::Event(event);
  205.             break;
  206.         }
  207.  
  208.         int top = 0;
  209.         int left = 0;
  210.         int count = maxRowsColumns;
  211.         int _cellWidth = (cellWidth > 0) ? cellWidth : 1;
  212.         int _cellHeight = (cellHeight > 0) ? cellHeight : 1;
  213.         for (object = First(); object; object = object->Next())
  214.         {
  215.             object->relative.left = left * _cellWidth;
  216.             object->relative.top = top * _cellHeight;
  217.             object->relative.right = object->relative.left + _cellWidth - 1;
  218.             object->relative.bottom = object->relative.top + _cellHeight - 1;
  219.             object->woStatus &= ~WOS_GRAPHICS;
  220.             if (FlagSet(mxFlags, MXF_ROWS_FILL) && ++top == count)
  221.             {
  222.                 left++;
  223.                 top = 0;
  224.             }
  225.             else if (!FlagSet(mxFlags, MXF_ROWS_FILL) && ++left == count)
  226.             {
  227.                 top++;
  228.                 left = 0;
  229.             }
  230.         }
  231.         }
  232.         // Continue to S_SIZE.
  233.  
  234.     case S_SIZE:
  235.         {
  236.         ccode = UIW_WINDOW::Event(event);
  237.         if (cellWidth < 1)
  238.             for (object = First(); object; object = object->Next())
  239.                 object->true.right = true.right;
  240.         if (cellHeight < 1)
  241.             for (object = First(); object; object = object->Next())
  242.                 object->true.bottom = true.bottom;
  243.         }
  244.         break;
  245.  
  246.     case S_CURRENT:
  247.         if (!First())
  248.         {
  249.             UI_REGION region = true;
  250.             UI_WINDOW_OBJECT::Border(0, region, 0);
  251.             eventManager->DevicePosition(E_CURSOR, region.left, region.top);
  252.             eventManager->DeviceState(E_CURSOR, DC_INSERT);
  253.         }
  254.         // Continue to S_DISPLAY_INACTIVE.
  255.  
  256.     case S_DISPLAY_INACTIVE:
  257.     case S_DISPLAY_ACTIVE:
  258.         scrollRecompute = TRUE;
  259.         // Continue to default.
  260.  
  261.     default:
  262.         ccode = UIW_WINDOW::Event(event);
  263.         object = (UI_WINDOW_OBJECT *)UI_LIST::Get(UIW_WINDOW::FindStatus, &WOS_CURRENT);
  264.         if (ccode != S_CREATE && ccode != S_SIZE && tObject != object)
  265.             scrollRecompute = TRUE;
  266.  
  267.         // Unhighlight the remaining items.
  268.         if (!object || !FlagSet(mxFlags, MXF_SELECT_ONE) ||
  269.             !FlagsSet(object->woStatus, WOS_SELECTED))
  270.             break;
  271.         tEvent.type = S_DISPLAY_ACTIVE;
  272.         for (UI_WINDOW_OBJECT *tObject = First(); tObject; tObject = tObject->Next())
  273.             if (tObject != object && FlagSet(tObject->woStatus, WOS_SELECTED))
  274.             {
  275.                 tObject->woStatus &= ~WOS_SELECTED;
  276.                 tEvent.region = tObject->true;
  277.                 if (!FlagSet(tObject->woAdvancedStatus, WOAS_INVALID_REGION))
  278.                     tObject->Event(tEvent);
  279.             }
  280.         break;
  281.     }
  282.  
  283.     if (scrollRecompute && previous)
  284.     {
  285.         tEvent.type = S_SCROLL_VERTICAL_SET;
  286.         topObject = bottomObject = First();
  287.         for (object = First(); object; object = object->Next())
  288.         {
  289.             if (object->relative.top < topObject->relative.top)
  290.                 topObject = object;
  291.             if (object->relative.top > bottomObject->relative.top)
  292.                 bottomObject = object;
  293.         }
  294.         object = (UI_WINDOW_OBJECT *)UI_LIST::Get(UIW_WINDOW::FindStatus, &WOS_CURRENT);
  295.         if (!object)
  296.             object = First();
  297.         while (object && FlagSet(object->woAdvancedStatus, WOAS_INVALID_REGION | WOAS_TOO_SMALL))
  298.             object = object->Next();
  299.         tEvent.scroll.current = object ? (object->relative.top - topObject->relative.top) / (cellHeight * display->cellHeight) : 0;
  300.         tEvent.scroll.showing = (true.bottom - true.top) / (cellHeight * display->cellHeight);
  301.         tEvent.scroll.maximum = (bottomObject->relative.top - topObject->relative.top) / (cellHeight * display->cellHeight);
  302.         object = Previous();
  303.  
  304.         if (object->Event(tEvent) != S_UNKNOWN)
  305.         {
  306.             tEvent.type = S_DISPLAY_ACTIVE;
  307.             tEvent.region = object->true;
  308.             object->Event(tEvent);
  309.         }
  310.     }
  311.  
  312.     // Return the event control code.
  313.     return (ccode);
  314. }
  315.  
  316. void *UIW_MATRIX::Information(INFORMATION_REQUEST request, void *data)
  317. {
  318.     if (request == GET_NUMBERID_OBJECT || request == GET_STRINGID_OBJECT ||
  319.         request == PRINT_INFORMATION)
  320.         return (UIW_WINDOW::Information(request, data));
  321.     else
  322.         return (UI_WINDOW_OBJECT::Information(request, data));
  323. }
  324.  
  325. #ifdef ZIL_LOAD
  326. UIW_MATRIX::UIW_MATRIX(const char *name, UI_STORAGE *file, USHORT loadFlags) :
  327.     UIW_WINDOW(name, file, loadFlags | L_SUB_LEVEL)
  328. {
  329.     windowID[0] = ID_MATRIX;
  330.     windowID[1] = ID_WINDOW;
  331.  
  332.     if (!file)
  333.         file = _storage;
  334.     file->Load(&mxFlags);
  335.     file->Load(&maxRowsColumns);
  336.     file->Load(&cellWidth);
  337.     file->Load(&cellHeight);
  338.     if (!FlagSet(loadFlags, L_SUB_LEVEL) && FlagSet(file->stStatus, STS_TEMPORARY))
  339.         delete file;
  340. }
  341. #endif
  342.  
  343. #ifdef ZIL_STORE
  344. void UIW_MATRIX::Store(const char *name, UI_STORAGE *file, USHORT storeFlags)
  345. {
  346.     UIW_WINDOW::Store(name, file, storeFlags | S_SUB_LEVEL);
  347.     file->Store(mxFlags);
  348.     file->Store(maxRowsColumns);
  349.     file->Store(cellWidth);
  350.     file->Store(cellHeight);
  351.     if (!FlagSet(storeFlags, S_SUB_LEVEL))
  352.         file->ObjectSize(name, search);
  353. }
  354. #endif
  355.  
  356.