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

  1. //    Zinc Interface Library - POPUP.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 <mem.h>
  7. #include <ctype.h>
  8. #include <string.h>
  9.  
  10. UIW_POP_UP_MENU::UIW_POP_UP_MENU(int left, int top, USHORT _mnFlags, USHORT _woFlags,
  11.     USHORT _woAdvancedFlags) :
  12.     UIW_WINDOW(left, top, 0, 0, _woFlags, _woAdvancedFlags | WOAF_NORMAL_HOT_KEYS),
  13.     mnFlags(_mnFlags)
  14. {
  15.     /* Initialize the menu information */
  16.     windowID[0] = ID_POP_UP_MENU;
  17.     windowID[1] = ID_MENU;
  18.     windowID[2] = ID_WINDOW;
  19.     search.type = ID_POP_UP_MENU;
  20.  
  21.     if (FlagSet(_mnFlags, MNF_AUTO_SORT))
  22.         compareFunction = UIW_POP_UP_MENU::CompareFunction;
  23. }
  24.  
  25. int UIW_POP_UP_MENU::CompareFunction(void *element1, void *element2)
  26. {
  27.     return (strcmp(((UIW_POP_UP_ITEM *)element1)->DataGet(TRUE), ((UIW_POP_UP_ITEM *)element2)->DataGet(TRUE)));
  28. }
  29.  
  30. UIW_POP_UP_MENU::Event(const UI_EVENT &event)
  31. {
  32.     /* Switch on the event type */
  33.     UI_EVENT tEvent = event;
  34.     int ccode = UI_WINDOW_OBJECT::LogicalEvent(event, ID_MENU);
  35.     int height, width;
  36.     int t_width = 0;
  37.     int t_height = 0;
  38.     int seperatorCount = 0;
  39.     UIW_POP_UP_ITEM *item;
  40.     UIW_POP_UP_ITEM *tItem;
  41.     UI_WINDOW_OBJECT *topWindow = parent;
  42.     while (topWindow->parent)
  43.         topWindow = topWindow->parent;
  44.     switch (ccode)
  45.     {
  46.     case S_CREATE:
  47.         /* Compute the desired height and width */
  48.         char *tHotKey;
  49.         true.right = display->columns - 1;
  50.         true.bottom = display->lines - 1;
  51.         for (item = First(); item; item = item->Next())
  52.         {
  53.             if (!item->userFunction && item->NumberID() > 0xFF00)
  54.                 item->userFunction = UIW_POP_UP_ITEM::PopUpItemUserFunction;
  55.             item->woFlags |= WOF_NON_FIELD_REGION;
  56.             item->woAdvancedFlags |= WOAF_HOT_REGION;
  57.             item->InformationSet(screenID, display, eventManager, windowManager, paletteMapTable, this);
  58.             item->relative.left = item->relative.top = 0;
  59.             item->relative.right = strlen(item->string) - 1;
  60.             item->relative.bottom = display->cellHeight - 1;
  61.             tHotKey = strchr(item->string, '~');
  62.             if (tHotKey)
  63.             {
  64.                 item->hotKey = toupper(tHotKey[1]);
  65.                 item->relative.right -= 1;
  66.             }
  67.             width = (display->isText) ? item->relative.right - 1 :
  68.                 item->relative.right + 1;
  69.             if (width > t_width)
  70.                 t_width = width;
  71.             ++t_height;
  72.             if (FlagSet(item->mniFlags, MNIF_SEPARATOR))
  73.                 seperatorCount++;
  74.         }
  75.         if (t_width == 0 || t_height == 0)
  76.         {
  77.             t_width = 10;
  78.             t_height = 2;
  79.         }
  80.         display->RegionConvert(relative, &woStatus, WOS_GRAPHICS);
  81.         if (display->isText)
  82.         {
  83.             if (FlagSet(woAdvancedFlags, WOAF_TEMPORARY))
  84.                 woFlags |= WOF_BORDER;
  85.             else
  86.                 woFlags &= ~WOF_BORDER;
  87.             relative.right = relative.left + t_width + 1;
  88.             relative.bottom = relative.top + t_height - 1;
  89.             if (FlagSet(woFlags, WOF_BORDER))
  90.             {
  91.                 relative.bottom += 2;
  92.                 relative.right += 2;
  93.             }
  94.         }
  95.         else
  96.         {
  97.             height = display->cellHeight;
  98.             width = display->cellWidth;
  99.             woFlags |= WOF_BORDER;
  100.             relative.right = relative.left + t_width * width - 2;
  101.             relative.bottom = relative.top + t_height * height - seperatorCount * (height / 2) - 2;
  102.             if (!parent || FlagSet(woAdvancedFlags, WOAF_TEMPORARY))
  103.                 relative.bottom += 2;
  104.         }
  105.         /* Continue to S_SIZE */
  106.  
  107.     case S_SIZE:
  108.         UI_WINDOW_OBJECT::RegionMax(TRUE);
  109.         height = display->cellHeight;
  110.         for (item = First(); item; item = item->Next())
  111.         {
  112.             item->RegionMax(TRUE);
  113.             if (FlagSet(woAdvancedStatus, WOAS_TOO_SMALL))
  114.                 item->woAdvancedStatus |= WOAS_TOO_SMALL;
  115.             else
  116.                 item->woAdvancedStatus &= ~WOAS_TOO_SMALL;
  117.             if (display->isText)
  118.             {
  119.                 if (FlagSet(woAdvancedFlags, WOAF_TEMPORARY))
  120.                     item->woFlags &= ~WOF_BORDER;
  121.                 else
  122.                     item->woFlags |= WOF_BORDER;
  123.                 item->true.bottom = item->true.top;
  124.             }
  125.             else
  126.             {
  127.                 item->woFlags &= ~WOF_BORDER;
  128.                 item->true.bottom = (!FlagSet(item->mniFlags, MNIF_SEPARATOR)) ?
  129.                     item->true.top + height - 1 : item->true.top + height / 2;
  130.                 if (item->true.bottom >= true.bottom)
  131.                     item->true.bottom = true.bottom - 1;
  132.                 else if (FlagSet(item->mniFlags, MNIF_SEPARATOR) && !display->isText)
  133.                     item->true.bottom--;
  134.             }
  135.             if (item->mniFlags != 0 && item->mniFlags != MNIF_SEPARATOR)
  136.             {
  137.                 item->woFlags &= ~WOF_NON_SELECTABLE;
  138.                 if ((FlagSet(item->mniFlags, MNIF_RESTORE) && 
  139.                      !FlagSet(topWindow->woAdvancedStatus, WOAS_MINIMIZED | WOAS_MAXIMIZED)) ||
  140.                     (FlagSet(item->mniFlags, MNIF_MINIMIZE | MNIF_MAXIMIZE) && 
  141.                      FlagSet(topWindow->woAdvancedStatus, WOAS_MINIMIZED | WOAS_MAXIMIZED)) ||
  142.                     (FlagSet(item->mniFlags, MNIF_MOVE) && FlagSet(topWindow->woAdvancedFlags, WOAF_NO_MOVE)) ||
  143.                     (FlagSet(item->mniFlags, MNIF_SIZE) && FlagSet(topWindow->woAdvancedFlags, WOAF_NO_SIZE)))
  144.                     item->woFlags |= WOF_NON_SELECTABLE;
  145.             }
  146.         }
  147.          UIW_WINDOW::RegionsCompute();
  148.         break;
  149.  
  150.     case S_CLOSE:
  151.         ccode = UIW_WINDOW::Event(event);
  152.         break;
  153.  
  154.     case L_LEFT:
  155.     case L_RIGHT:
  156.         if ((ccode == L_LEFT && FlagSet(mnFlags, MNF_SELECT_LEFT)) ||
  157.             (ccode == L_RIGHT && FlagSet(mnFlags, MNF_SELECT_RIGHT)))
  158.         {
  159.             tEvent.type = L_SELECT;
  160.             eventManager->Put(tEvent, Q_BEGIN);
  161.             eventManager->Put(event, Q_BEGIN);
  162.             tEvent.type = S_CLOSE_TEMPORARY;
  163.             eventManager->Put(tEvent, Q_BEGIN);
  164.         }
  165.         break;
  166.  
  167.     case L_UP:
  168.     case L_DOWN:
  169.         tEvent.type = (ccode == L_UP) ? L_PREVIOUS : L_NEXT;
  170.         // Continue to L_PREVIOUS and L_NEXT.
  171.  
  172.     case L_PREVIOUS:
  173.     case L_NEXT:
  174.         if (FlagSet(woFlags, WOF_NON_FIELD_REGION))
  175.         {
  176.             UI_WINDOW_OBJECT *tParent = parent;
  177.             parent = NULL;        // Trick the window.
  178.             ccode = UIW_WINDOW::Event(tEvent);
  179.             parent = tParent;
  180.         }
  181.         else
  182.             ccode = UIW_WINDOW::Event(tEvent);
  183.         break;
  184.  
  185.     case L_TOP:
  186.     case L_BOTTOM:
  187.         tEvent.type = (ccode == L_TOP) ? L_FIRST : L_LAST;
  188.         ccode = UIW_WINDOW::Event(tEvent);
  189.         break;
  190.  
  191.     default:
  192.         ccode = UIW_WINDOW::Event(event);
  193.  
  194.         // Check for unknown temporary event (accelerator keys).
  195.         if (ccode == S_UNKNOWN && FlagSet(woAdvancedFlags, WOAF_TEMPORARY) && parent)
  196.         {
  197.             UI_WINDOW_OBJECT *root = parent;
  198.             while (root->parent)
  199.                 root = root->parent;
  200.             ccode = root->Event(event);
  201.             return (ccode);
  202.         }
  203.  
  204.         /* Unhighlight the remaining items */
  205.         item = (UIW_POP_UP_ITEM *)current;
  206.         if (!FlagSet(mnFlags, MNF_SELECT_ONE) || !FlagsSet(item->woStatus, WOS_SELECTED))
  207.             break;
  208.         UI_EVENT tEvent;
  209.         tEvent.type = S_DISPLAY_ACTIVE;
  210.         for (tItem = First(); tItem; tItem = tItem->Next())
  211.             if (tItem != item && FlagSet(tItem->woStatus, WOS_SELECTED))
  212.             {
  213.                 tItem->woStatus &= ~WOS_SELECTED;
  214.                 tEvent.region = tItem->true;
  215.                 tItem->Event(tEvent);
  216.             }
  217.         break;
  218.     }
  219.  
  220.     /* Return the event control code */
  221.     return (ccode);
  222. }
  223.  
  224. void *UIW_POP_UP_MENU::Information(INFORMATION_REQUEST request, void *data)
  225. {
  226.     if (request == GET_NUMBERID_OBJECT || request == GET_STRINGID_OBJECT ||
  227.         request == PRINT_INFORMATION)
  228.         return (UIW_WINDOW::Information(request, data));
  229.     else
  230.         return (UI_WINDOW_OBJECT::Information(request, data));
  231. }
  232.  
  233. #ifdef ZIL_LOAD
  234. UIW_POP_UP_MENU::UIW_POP_UP_MENU(const char *name, UI_STORAGE *file, USHORT loadFlags) :
  235.     UIW_WINDOW(name, file, loadFlags | L_SUB_LEVEL)
  236. {
  237.     windowID[0] = ID_POP_UP_MENU;
  238.     windowID[1] = ID_MENU;
  239.     windowID[2] = ID_WINDOW;
  240.  
  241.     if (!file)
  242.         file = _storage;
  243.     file->Load(&mnFlags);
  244.     if (FlagSet(mnFlags, MNF_AUTO_SORT))
  245.         compareFunction = UIW_POP_UP_MENU::CompareFunction;
  246.     if (!FlagSet(loadFlags, L_SUB_LEVEL) && FlagSet(file->stStatus, STS_TEMPORARY))
  247.         delete file;
  248. }
  249. #endif
  250.  
  251. #ifdef ZIL_STORE
  252. void UIW_POP_UP_MENU::Store(const char *name, UI_STORAGE *file, USHORT storeFlags)
  253. {
  254.     UIW_WINDOW::Store(name, file, storeFlags | S_SUB_LEVEL);
  255.     file->Store(mnFlags);
  256.     if (!FlagSet(storeFlags, S_SUB_LEVEL))
  257.         file->ObjectSize(name, search);
  258. }
  259. #endif
  260.