home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0040 - 0049 / ibm0040-0049 / ibm0040.tar / ibm0040 / ZINC_5.ZIP / WINSRC.ZIP / MATRIX.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-01  |  11.1 KB  |  358 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 (!object)
  81.             object = First();
  82.         if (ccode == L_PREVIOUS || ccode == L_PGUP || ccode == L_UP)
  83.         {
  84.             sObject = object->Previous();
  85.             while (sObject && FlagSet(sObject->woFlags, WOF_NON_SELECTABLE))
  86.                 sObject = sObject->Previous();
  87.         }
  88.         else
  89.         {
  90.             sObject = object->Next();
  91.             while (sObject && FlagSet(sObject->woFlags, WOF_NON_SELECTABLE))
  92.                 sObject = sObject->Next();
  93.         }
  94.         if (((ccode == L_PREVIOUS || ccode == L_PGUP) && !sObject) ||
  95.             ((ccode == L_NEXT || ccode == L_PGDN) && !sObject) ||
  96.             (ccode == L_UP && (!sObject || object->relative.top == topObject->relative.top)) ||
  97.             (ccode == L_DOWN && (!sObject || object->relative.bottom == bottomObject->relative.bottom)))
  98.             return (S_UNKNOWN);
  99.  
  100.         scrollRecompute = TRUE;
  101.         tcode = UIW_WINDOW::Event(event);
  102.         if (tcode != S_UNKNOWN && tcode != S_ERROR)
  103.             break;
  104.         if (ccode == L_UP || ccode == L_PREVIOUS)
  105.             height = display->cellHeight;
  106.         else if (ccode == L_DOWN || ccode == L_NEXT)
  107.             height = -display->cellHeight;
  108.         else if (ccode == L_PGUP)
  109.             height = ((true.bottom - true.top) / display->cellHeight) * display->cellHeight;
  110.         else
  111.             height = -((true.bottom - true.top) / display->cellHeight) * display->cellHeight;
  112.         // Continue to S_SCROLL_HORIZONTAL and S_SCROLL_VERTICAL.
  113.  
  114.     case S_SCROLL_VERTICAL:
  115.         // Get the delta scroll values.
  116.         if (ccode == S_SCROLL_VERTICAL)
  117.             height = event.scroll.delta * display->cellHeight;
  118.         topObject = bottomObject = First();
  119.         for (object = First(); object; object = object->Next())
  120.         {
  121.             if (object->relative.top < topObject->relative.top)
  122.                 topObject = object;
  123.             if (object->relative.top > bottomObject->relative.top)
  124.                 bottomObject = object;
  125.         }
  126.         if ((height > 0 && FlagSet(topObject->woAdvancedStatus, WOAS_INVALID_REGION | WOAS_TOO_SMALL)) ||
  127.             (height < 0 && FlagSet(bottomObject->woAdvancedStatus, WOAS_INVALID_REGION | WOAS_TOO_SMALL)))
  128.         {
  129.             if (height < 0 &&
  130.                 bottomObject->relative.bottom + height < true.bottom - true.top)
  131.                 height = ((true.bottom - true.top - bottomObject->relative.bottom) /
  132.                     display->cellHeight) * display->cellHeight;
  133.             else if (height > 0 &&
  134.                 topObject->relative.top + height > 0)
  135.                 height = -topObject->relative.top;
  136.             for (object = First(); object; object = object->Next())
  137.             {
  138.                 object->relative.top += height;
  139.                 object->relative.bottom += height;
  140.             }
  141.             tEvent.type = S_SIZE;
  142.             UIW_WINDOW::Event(tEvent);
  143.              UIW_WINDOW::RegionsCompute();
  144.         }
  145.  
  146.         // Change the current field.
  147.         if (!tObject)
  148.             break;
  149.         height = (ccode == S_SCROLL_VERTICAL) ? event.scroll.delta : height / display->cellHeight;
  150.         topObject = tObject;
  151.         for (object = tObject->Previous(); object && height > 0; object = object->Previous())
  152.             if (topObject->relative.top > object->relative.top)
  153.             {
  154.                 topObject = object;
  155.                 height--;
  156.             }
  157.             else if (topObject->relative.top == object->relative.top)
  158.                 topObject = object;
  159.         for (object = topObject->Previous(); object; object = object->Previous())
  160.             if (object->relative.top == topObject->relative.top)
  161.                 topObject = object;
  162.             else
  163.                 break;
  164.         for (object = tObject->Next(); object && height < 0; object = object->Next())
  165.             if (topObject->relative.top < object->relative.top)
  166.             {
  167.                 topObject = object;
  168.                 height++;
  169.             }
  170.         if (topObject)
  171.         {
  172.             object = topObject;
  173.             while (object->relative.top == topObject->relative.top)
  174.                 if (object->relative.left == tObject->relative.left)
  175.                     break;
  176.                 else
  177.                 {
  178.                     topObject = topObject->Next();
  179.                     if (!topObject || topObject->relative.top != object->relative.top)
  180.                         break;
  181.                     object = topObject;
  182.                 }
  183.             tObject->woStatus &= ~WOS_CURRENT;
  184.             if (height > 0)
  185.                 while (object->Next() && FlagSet(object->woFlags, WOF_NON_SELECTABLE))
  186.                     object = object->Next();
  187.             else if (height < 0)
  188.                 while (object->Previous() && FlagSet(object->woFlags, WOF_NON_SELECTABLE))
  189.                     object = object->Previous();
  190.             object->woStatus |= WOS_CURRENT;
  191.  
  192.             scrollRecompute = TRUE;
  193.         }
  194.  
  195.         tEvent.type = S_CURRENT;
  196.         tEvent.region = true;
  197.         ccode = UIW_WINDOW::Event(tEvent);
  198.         break;
  199.  
  200.     case S_CREATE:
  201.         {
  202.         UI_WINDOW_OBJECT::Event(event);
  203.  
  204.         if (!FlagSet(mxFlags, MXF_ROWS_FILL | MXF_COLUMNS_FILL))
  205.         {
  206.             ccode = UIW_WINDOW::Event(event);
  207.             break;
  208.         }
  209.  
  210.         int top = 0;
  211.         int left = 0;
  212.         int count = maxRowsColumns;
  213.         int _cellWidth = (cellWidth > 0) ? cellWidth : 1;
  214.         int _cellHeight = (cellHeight > 0) ? cellHeight : 1;
  215.         for (object = First(); object; object = object->Next())
  216.         {
  217.             object->relative.left = left * _cellWidth;
  218.             object->relative.top = top * _cellHeight;
  219.             object->relative.right = object->relative.left + _cellWidth - 1;
  220.             object->relative.bottom = object->relative.top + _cellHeight - 1;
  221.             object->woStatus &= ~WOS_GRAPHICS;
  222.             if (FlagSet(mxFlags, MXF_ROWS_FILL) && ++top == count)
  223.             {
  224.                 left++;
  225.                 top = 0;
  226.             }
  227.             else if (!FlagSet(mxFlags, MXF_ROWS_FILL) && ++left == count)
  228.             {
  229.                 top++;
  230.                 left = 0;
  231.             }
  232.         }
  233.         }
  234.         // Continue to S_SIZE.
  235.  
  236.     case S_SIZE:
  237.         {
  238.         ccode = UIW_WINDOW::Event(event);
  239.         if (cellWidth < 1)
  240.             for (object = First(); object; object = object->Next())
  241.                 object->true.right = true.right;
  242.         if (cellHeight < 1)
  243.             for (object = First(); object; object = object->Next())
  244.                 object->true.bottom = true.bottom;
  245.         }
  246.         break;
  247.  
  248.     case S_CURRENT:
  249.         if (!First())
  250.         {
  251.             UI_REGION region = true;
  252.             UI_WINDOW_OBJECT::Border(0, region, 0);
  253.             eventManager->DevicePosition(E_CURSOR, region.left, region.top);
  254.             eventManager->DeviceState(E_CURSOR, DC_INSERT);
  255.         }
  256.         // Continue to S_DISPLAY_INACTIVE.
  257.  
  258.     case S_DISPLAY_INACTIVE:
  259.     case S_DISPLAY_ACTIVE:
  260.         scrollRecompute = TRUE;
  261.         // Continue to default.
  262.  
  263.     default:
  264.         ccode = UIW_WINDOW::Event(event);
  265.         object = (UI_WINDOW_OBJECT *)UI_LIST::Get(UIW_WINDOW::FindStatus, &WOS_CURRENT);
  266.         if (ccode != S_CREATE && ccode != S_SIZE && tObject != object)
  267.             scrollRecompute = TRUE;
  268.  
  269.         // Unhighlight the remaining items.
  270.         if (!object || !FlagSet(mxFlags, MXF_SELECT_ONE) ||
  271.             !FlagsSet(object->woStatus, WOS_SELECTED))
  272.             break;
  273.         tEvent.type = S_DISPLAY_ACTIVE;
  274.         for (UI_WINDOW_OBJECT *tObject = First(); tObject; tObject = tObject->Next())
  275.             if (tObject != object && FlagSet(tObject->woStatus, WOS_SELECTED))
  276.             {
  277.                 tObject->woStatus &= ~WOS_SELECTED;
  278.                 tEvent.region = tObject->true;
  279.                 if (!FlagSet(tObject->woAdvancedStatus, WOAS_INVALID_REGION))
  280.                     tObject->Event(tEvent);
  281.             }
  282.         break;
  283.     }
  284.  
  285.     if (scrollRecompute && previous)
  286.     {
  287.         tEvent.type = S_SCROLL_VERTICAL_SET;
  288.         topObject = bottomObject = First();
  289.         for (object = First(); object; object = object->Next())
  290.         {
  291.             if (object->relative.top < topObject->relative.top)
  292.                 topObject = object;
  293.             if (object->relative.top > bottomObject->relative.top)
  294.                 bottomObject = object;
  295.         }
  296.         object = (UI_WINDOW_OBJECT *)UI_LIST::Get(UIW_WINDOW::FindStatus, &WOS_CURRENT);
  297.         if (!object)
  298.             object = First();
  299.         while (object && FlagSet(object->woAdvancedStatus, WOAS_INVALID_REGION | WOAS_TOO_SMALL))
  300.             object = object->Next();
  301.         tEvent.scroll.current = object ? (object->relative.top - topObject->relative.top) / (cellHeight * display->cellHeight) : 0;
  302.         tEvent.scroll.showing = (true.bottom - true.top) / (cellHeight * display->cellHeight);
  303.         tEvent.scroll.maximum = (bottomObject->relative.top - topObject->relative.top) / (cellHeight * display->cellHeight);
  304.         object = Previous();
  305.  
  306.         if (object->Event(tEvent) != S_UNKNOWN)
  307.         {
  308.             tEvent.type = S_DISPLAY_ACTIVE;
  309.             tEvent.region = object->true;
  310.             object->Event(tEvent);
  311.         }
  312.     }
  313.  
  314.     // Return the event control code.
  315.     return (ccode);
  316. }
  317.  
  318. void *UIW_MATRIX::Information(INFORMATION_REQUEST request, void *data)
  319. {
  320.     if (request == GET_NUMBERID_OBJECT || request == GET_STRINGID_OBJECT ||
  321.         request == PRINT_INFORMATION)
  322.         return (UIW_WINDOW::Information(request, data));
  323.     else
  324.         return (UI_WINDOW_OBJECT::Information(request, data));
  325. }
  326.  
  327. #ifdef ZIL_LOAD
  328. UIW_MATRIX::UIW_MATRIX(const char *name, UI_STORAGE *file, USHORT loadFlags) :
  329.     UIW_WINDOW(name, file, loadFlags | L_SUB_LEVEL)
  330. {
  331.     windowID[0] = ID_MATRIX;
  332.     windowID[1] = ID_WINDOW;
  333.  
  334.     if (!file)
  335.         file = _storage;
  336.     file->Load(&mxFlags);
  337.     file->Load(&maxRowsColumns);
  338.     file->Load(&cellWidth);
  339.     file->Load(&cellHeight);
  340.     if (!FlagSet(loadFlags, L_SUB_LEVEL) && FlagSet(file->stStatus, STS_TEMPORARY))
  341.         delete file;
  342. }
  343. #endif
  344.  
  345. #ifdef ZIL_STORE
  346. void UIW_MATRIX::Store(const char *name, UI_STORAGE *file, USHORT storeFlags)
  347. {
  348.     UIW_WINDOW::Store(name, file, storeFlags | S_SUB_LEVEL);
  349.     file->Store(mxFlags);
  350.     file->Store(maxRowsColumns);
  351.     file->Store(cellWidth);
  352.     file->Store(cellHeight);
  353.     if (!FlagSet(storeFlags, S_SUB_LEVEL))
  354.         file->ObjectSize(name, search);
  355. }
  356. #endif
  357.  
  358.