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