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

  1. //    Zinc Interface Library - ICON.CPP
  2. //    COPYRIGHT (C) 1990, 1991.  All Rights Reserved.
  3. //    Zinc Software Incorporated.  Pleasant Grove, Utah  USA
  4.  
  5. #define USE_RAW_KEYS
  6. #include "ui_win.hpp"
  7. #include <string.h>
  8.  
  9. static UI_PALETTE _colorMap[16] =
  10. {
  11.     { HS_NONE, BLACK, BLACK },
  12.     { HS_NONE, BLUE, BLUE },
  13.     { HS_NONE, GREEN, GREEN },
  14.     { HS_NONE, CYAN, CYAN },
  15.     { HS_NONE, RED, RED },
  16.     { HS_NONE, MAGENTA, MAGENTA },
  17.     { HS_NONE, BROWN, BROWN },
  18.     { HS_NONE, LIGHTGRAY, LIGHTGRAY },
  19.     { HS_NONE, DARKGRAY, DARKGRAY },
  20.     { HS_NONE, LIGHTBLUE, LIGHTBLUE },
  21.     { HS_NONE, LIGHTGREEN, LIGHTGREEN  },
  22.     { HS_NONE, LIGHTCYAN, LIGHTCYAN },
  23.     { HS_NONE, LIGHTRED, LIGHTRED },
  24.     { HS_NONE, LIGHTMAGENTA, LIGHTMAGENTA },
  25.     { HS_NONE, YELLOW, YELLOW },
  26.     { HS_NONE, WHITE, WHITE }
  27. };
  28.  
  29. UIW_ICON::UIW_ICON(int left, int top, int _bitmapWidth, int _bitmapHeight,
  30.     UCHAR *_bitmapArray, char *_string, USHORT _icFlags, USHORT _woFlags,
  31.     void (*_userFunction)(void *object, UI_EVENT &event), int _ratioWidth,
  32.     int _ratioHeight) :
  33.     UI_WINDOW_OBJECT(left, top, 1, 1, _woFlags, WOAF_NO_SIZE | WOAF_MULTIPLE_REGIONS),
  34.     icFlags(_icFlags), bitmapWidth(_bitmapWidth), bitmapHeight(_bitmapHeight),
  35.     bitmapArray(_bitmapArray), userFunction(_userFunction), lastTime(0),
  36.     window(0), ratioWidth(_ratioWidth), ratioHeight(_ratioHeight)
  37. {
  38.     // Initialize the basic icon information.
  39.     windowID[0] = ID_ICON;
  40.     search.type = ID_ICON;
  41.  
  42.     if (FlagSet(_icFlags, ICF_READ | ICF_WRITE | ICF_AUTO_SELECT | ICF_AUTO_ESCAPE | ICF_END))
  43.         woAdvancedFlags |= WOAF_NON_CURRENT;
  44.     string = ui_strdup(_string);
  45.     if (FlagSet(woFlags, WOF_NO_ALLOCATE_DATA))
  46.         bitmapArray = _bitmapArray;
  47.     else
  48.     {
  49.         bitmapArray = new UCHAR[_bitmapWidth * _bitmapHeight];
  50.         if (!_bitmapArray)
  51.             memset(bitmapArray, LIGHTGRAY, _bitmapWidth * _bitmapHeight);
  52.         else
  53.             memcpy(bitmapArray, _bitmapArray, _bitmapWidth * _bitmapHeight);
  54.     }
  55. }
  56.  
  57. void UIW_ICON::DataSet(int _bitmapWidth, int _bitmapHeight, UCHAR *_bitmapArray)
  58. {
  59.     if (_bitmapArray)
  60.     {
  61.         bitmapWidth = _bitmapWidth;
  62.         bitmapHeight = _bitmapHeight;
  63.         delete bitmapArray;
  64.         bitmapArray = _bitmapArray;
  65.     }
  66.     UI_WINDOW_OBJECT::Redisplay(FALSE);
  67. }
  68.  
  69. UIW_ICON::Event(const UI_EVENT &event)
  70. {
  71.     // Switch on the event type.
  72.     int redisplay = FALSE;
  73.     int border = FlagSet(woFlags, WOF_BORDER) ? 1 : 0;
  74.     int ccode = UI_WINDOW_OBJECT::LogicalEvent(event, ID_ICON);
  75.     switch (ccode)
  76.     {
  77.     case S_DEFINE_REGION:
  78.         if (!parent)
  79.         {
  80.             if (!display->isText)
  81.                 display->RegionDefine(screenID, iconRegion);
  82.             if (string)
  83.                 display->RegionDefine(screenID, stringRegion);
  84.         }
  85.         break;
  86.  
  87.     case S_CREATE:
  88.     case S_SIZE:
  89.         if (display->isText)
  90.         {
  91.             relative.right = relative.left + display->TextWidth(string) + 1;
  92.             relative.bottom = relative.top + 2;
  93.         }
  94.         else
  95.         {
  96.             display->RegionConvert(relative, &woStatus, WOS_GRAPHICS);
  97.             relative.right = relative.left + bitmapWidth * ratioWidth - 1;
  98.             relative.bottom = relative.top + bitmapHeight * ratioHeight - 1;
  99.             if (FlagSet(woFlags, WOF_BORDER))
  100.             {
  101.                 relative.right += bitmapWidth + 1;
  102.                 relative.bottom += bitmapHeight + 1;
  103.             }
  104.             if (FlagSet(icFlags, ICF_AUTO_SELECT))
  105.                 memset(bitmapArray, leftColor, bitmapWidth * bitmapHeight);
  106.             else if (FlagSet(icFlags, ICF_AUTO_ESCAPE))
  107.                 memset(bitmapArray, rightColor, bitmapWidth * bitmapHeight);
  108.             if (string)
  109.             {
  110.                 if (relative.right - relative.left < display->TextWidth(string))
  111.                     relative.right = relative.left + display->TextWidth(string) - 1;
  112.                 relative.bottom += display->TextHeight(string) + 5;
  113.             }
  114.         }
  115.         // Continue to S_MOVE.
  116.  
  117.     case S_MOVE:
  118.         if (display->isText)
  119.         {
  120.             ccode = UI_WINDOW_OBJECT::Event(event);
  121.             iconRegion = stringRegion = true;
  122.             break;
  123.         }
  124.         int delta = FlagSet(woFlags, WOF_BORDER) ? bitmapWidth : 0;
  125.         delta = display->isText ? 0 : (relative.right - relative.left - bitmapWidth * ratioWidth - delta) / 2;
  126.         ccode = UI_WINDOW_OBJECT::Event(event);
  127.  
  128.         iconRegion = true;
  129.         stringRegion = true;
  130.         if (!display->isText)
  131.         {
  132.             iconRegion.left = true.left + delta;
  133.             iconRegion.right = iconRegion.left + bitmapWidth * ratioWidth - 1;
  134.             iconRegion.bottom = iconRegion.top + bitmapHeight * ratioHeight - 1;
  135.             if (FlagSet(woFlags, WOF_BORDER))
  136.             {
  137.                 iconRegion.right += bitmapWidth + 1;
  138.                 iconRegion.bottom += bitmapHeight + 1;
  139.             }
  140.             if (iconRegion.right > true.right)
  141.                 iconRegion.right = true.right;
  142.             if (iconRegion.bottom > true.bottom)
  143.                 iconRegion.bottom = true.bottom;
  144.             if (string)
  145.             {
  146.                 if (iconRegion.bottom < true.bottom)
  147.                     stringRegion.top = iconRegion.bottom + 4;
  148.                 int length = true.right - true.left - display->TextWidth(string);
  149.                 if (length > 0)
  150.                 {
  151.                     stringRegion.left = true.left + length / 2;
  152.                     stringRegion.right = stringRegion.left + length - 1;
  153.                 }
  154.             }
  155.         }
  156.         break;
  157.  
  158.     case L_FLOOD_COLOR:
  159.         redisplay = TRUE;
  160.         if (FlagSet(event.rawCode, M_LEFT_CHANGE) && FlagSet(icFlags, ICF_AUTO_SELECT | ICF_READ))
  161.             memset(bitmapArray, leftColor, bitmapWidth * bitmapHeight);
  162.         else if (FlagSet(event.rawCode, M_RIGHT_CHANGE) && FlagSet(icFlags, ICF_AUTO_ESCAPE | ICF_READ))
  163.             memset(bitmapArray, rightColor, bitmapWidth * bitmapHeight);
  164.         else
  165.             redisplay = FALSE;
  166.         if (next)
  167.         {
  168.             UI_WINDOW_OBJECT *object = Next();
  169.             if (object)
  170.                 object->Event(event);
  171.         }
  172.         break;
  173.  
  174.     case L_CHECK_COLOR:
  175.         redisplay = TRUE;
  176.         if (FlagSet(event.rawCode, M_LEFT_CHANGE) && FlagSet(icFlags, ICF_AUTO_SELECT))
  177.             bitmapArray[0] = leftColor;
  178.         else if (FlagSet(event.rawCode, M_RIGHT_CHANGE) && FlagSet(icFlags, ICF_AUTO_ESCAPE))
  179.             bitmapArray[0] = rightColor;
  180.         else
  181.         {
  182.             UI_WINDOW_OBJECT *object = Next();
  183.             if (object)
  184.                 object->Event(event);
  185.             redisplay = FALSE;
  186.         }
  187.         break;
  188.  
  189.     case L_SELECT:
  190.         if (userFunction)
  191.         {
  192.             UI_EVENT tEvent = event;
  193.             (*userFunction)(this, tEvent);
  194.             lastTime = 0;
  195.         }
  196.         if (window)
  197.         {
  198.             UI_WINDOW_MANAGER *tWindowManager = windowManager;
  199.             *tWindowManager - this;
  200.             *tWindowManager + window;
  201.         }
  202.         break;
  203.  
  204.     case L_BEGIN_SELECT:
  205.     case L_CONTINUE_SELECT:
  206.     case L_END_SELECT:
  207.         int column = (event.position.column - true.left) / (ratioWidth + border);
  208.         int line = (event.position.line - true.top) / (ratioHeight + border);
  209.         int currentColor = FlagSet(event.rawCode, M_LEFT | M_LEFT_CHANGE) ? leftColor : rightColor;
  210.         if ((icFlags == ICF_NO_FLAGS || icFlags == ICF_SINGLE_CLICK) &&
  211.             UI_WINDOW_OBJECT::Overlap(event.position))
  212.         {
  213.             UI_REGION region = true;
  214.             true = iconRegion;
  215.             int move = UI_WINDOW_OBJECT::Overlap(event.position);
  216.             true = stringRegion;
  217.             if (!move)
  218.                 move = UI_WINDOW_OBJECT::Overlap(event.position);
  219.             true = region;
  220.             if (!move)
  221.                 break;
  222.             if (icFlags == ICF_SINGLE_CLICK || ui_time() - lastTime < 12)
  223.             {
  224.                 if (userFunction)
  225.                 {
  226.                     UI_EVENT tEvent = event;
  227.                     (*userFunction)(this, tEvent);
  228.                     lastTime = 0;
  229.                 }
  230.                 if (window)
  231.                 {
  232.                     UI_WINDOW_MANAGER *tWindowManager = windowManager;
  233.                     *tWindowManager - this;
  234.                     *tWindowManager + window;
  235.                 }
  236.                 break;
  237.             }
  238.             else
  239.                 lastTime = ui_time();
  240.             UI_EVENT tEvent = event;
  241.             tEvent.rawCode = DM_MOVE;
  242.             eventManager->Event(tEvent);
  243.             if (ccode == L_BEGIN_SELECT)
  244.             {
  245.                 tEvent.type = S_MOVE;
  246.                 eventManager->Put(tEvent, Q_BEGIN);
  247.             }
  248.             break;
  249.         }
  250.         else if (column < 0 || column >= bitmapWidth || line < 0 || line >= bitmapHeight)
  251.             break;
  252.         else if (FlagSet(icFlags, ICF_WRITE) &&
  253.             bitmapArray[line * bitmapWidth + column] == currentColor)
  254.         {
  255.             if (ccode == L_END_SELECT && ui_time() - lastTime < repeatRate && next)
  256.             {
  257.                 UI_EVENT tEvent = event;
  258.                 tEvent.type = L_FLOOD_COLOR;
  259.                 UI_WINDOW_OBJECT *object = Next();
  260.                 object->Event(tEvent);
  261.                 lastTime = 0;
  262.             }
  263.             else if (ccode == L_END_SELECT)
  264.                 lastTime = ui_time();
  265.         }
  266.         else if (FlagSet(icFlags, ICF_READ) &&
  267.             bitmapArray[line * bitmapWidth + column] != currentColor)
  268.         {
  269.             UI_REGION region;
  270.             region.left = iconRegion.left + (ratioWidth + border) * column + border;
  271.             region.right = region.left + ratioWidth - 1;
  272.             region.top = iconRegion.top + (ratioHeight + border) * line + border;
  273.             region.bottom = region.top + ratioHeight - 1;
  274.             display->Rectangle(screenID, region, &_colorMap[currentColor], 0, TRUE);
  275.             bitmapArray[line * bitmapWidth + column] = currentColor;
  276.             if (next && !FlagSet(icFlags, ICF_END))
  277.             {
  278.                 UI_WINDOW_OBJECT *object = Next();
  279.                 UI_EVENT tEvent = event;
  280.                 tEvent.position.column = object->true.left + column;
  281.                 tEvent.position.line = object->true.top + line;
  282.                 object->Event(tEvent);
  283.             }
  284.         }
  285.         else if (FlagSet(icFlags, ICF_WRITE) &&
  286.             bitmapArray[line * bitmapWidth + column] != currentColor &&
  287.             ccode == L_END_SELECT)
  288.         {
  289.             if (FlagSet(event.rawCode, M_LEFT_CHANGE))
  290.                 leftColor = bitmapArray[line * bitmapWidth + column];
  291.             else
  292.                 rightColor = bitmapArray[line * bitmapWidth + column];
  293.             if (next && !FlagSet(icFlags, ICF_END))
  294.             {
  295.                 UI_WINDOW_OBJECT *object = Next();
  296.                 UI_EVENT tEvent = event;
  297.                 tEvent.type = L_CHECK_COLOR;
  298.                 object->Event(tEvent);
  299.             }
  300.             lastTime = ui_time();
  301.         }
  302.         break;
  303.  
  304.     case S_CURRENT:
  305.     case S_DISPLAY_ACTIVE:
  306.     case S_DISPLAY_INACTIVE:
  307.     case S_NON_CURRENT:
  308.         if (string && UI_WINDOW_OBJECT::NeedsUpdate(event, ccode))
  309.         {
  310.             UI_REGION region = true;
  311.             true = stringRegion;
  312.             woFlags |= WOF_JUSTIFY_CENTER;
  313.             Text(string, 0, ccode, lastPalette);
  314.             true = region;
  315.         }
  316.         if (ccode != S_NON_CURRENT &&
  317.             !FlagSet(woAdvancedStatus, WOAS_INVALID_REGION) &&
  318.             UI_WINDOW_OBJECT::Overlap(event.region))
  319.             redisplay = TRUE;
  320.         break;
  321.  
  322.     default:
  323.         ccode = UI_WINDOW_OBJECT::Event(event);
  324.         break;
  325.     }
  326.  
  327.     // Redisplay the object information.
  328.     if (redisplay && ratioWidth == 1 && ratioWidth == 1 && !display->isText)
  329.         display->Bitmap(screenID, iconRegion.left, iconRegion.top,
  330.             bitmapWidth, bitmapHeight, bitmapArray, NULL, &iconRegion);
  331.     else if (redisplay && !display->isText)
  332.     {
  333.         int k = 0;
  334.         UI_REGION region;
  335.         region.top = iconRegion.top + border;
  336.         for (int i = 0; i < bitmapHeight; i++)
  337.         {
  338.             region.bottom = region.top + ratioHeight - 1;
  339.             region.left = iconRegion.left + border;
  340.             for (int j = 0; j < bitmapWidth; j++, k++)
  341.             {
  342.                 region.right = region.left + ratioWidth - 1;
  343.                 display->Rectangle(screenID, region, &_colorMap[bitmapArray[k]], 0, TRUE);
  344.                 if (i == 0 && border)
  345.                     display->Line(screenID, region.right + 1, iconRegion.top,
  346.                         region.right + 1, iconRegion.bottom, &_colorMap[DARKGRAY]);
  347.                 if (j == 0 && border)
  348.                     display->Line(screenID, iconRegion.left, region.bottom + 1,
  349.                         iconRegion.right, region.bottom + 1, &_colorMap[DARKGRAY]);
  350.                 region.left += ratioWidth + border;
  351.             }
  352.             region.top += ratioHeight + border;
  353.         }
  354.         if (border)
  355.             display->Rectangle(screenID, iconRegion, &_colorMap[DARKGRAY]);
  356.     }
  357.  
  358.     // Return the control code.
  359.     return (ccode);
  360. }
  361.  
  362. #ifdef ZIL_LOAD
  363. UIW_ICON::UIW_ICON(const char *name, UI_STORAGE *file, USHORT loadFlags) :
  364.     UI_WINDOW_OBJECT(name, file, loadFlags | L_SUB_LEVEL),
  365.     userFunction(NULL), lastTime(0), ratioWidth(1), ratioHeight(1)
  366. {
  367.     windowID[0] = ID_ICON;
  368.  
  369.     lastTime = 0;
  370.     if (!file)
  371.         file = _storage;
  372.     file->Load(&icFlags);
  373.     file->Load(&bitmapWidth);
  374.     file->Load(&bitmapHeight);
  375.     short size = bitmapWidth * bitmapHeight;
  376.     bitmapArray = new UCHAR[size];
  377.     file->Load(bitmapArray, size);
  378.     file->Load(&string);
  379.     if (!FlagSet(loadFlags, L_SUB_LEVEL) && FlagSet(file->stStatus, STS_TEMPORARY))
  380.         delete file;
  381. }
  382. #endif
  383.  
  384. #ifdef ZIL_STORE
  385. void UIW_ICON::Store(const char *name, UI_STORAGE *file, USHORT storeFlags)
  386. {
  387.     UI_WINDOW_OBJECT::Store(name, file, storeFlags | S_SUB_LEVEL);
  388.  
  389.     file->Store(icFlags);
  390.     file->Store(bitmapWidth);
  391.     file->Store(bitmapHeight);
  392.     short size = bitmapWidth * bitmapHeight;
  393.     file->Store(bitmapArray, size);
  394.     file->Store(string);
  395.     if (!FlagSet(storeFlags, S_SUB_LEVEL))
  396.         file->ObjectSize(name, search);
  397. }
  398. #endif
  399.