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

  1. //    Zinc Interface Library - BUTTON.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 <ctype.h>
  7. #include <string.h>
  8.  
  9. UIW_BUTTON::UIW_BUTTON(int left, int top, int width, char *_string,
  10.     USHORT _btFlags, USHORT _woFlags, void (*_userFunction)(void *object, UI_EVENT &event),
  11.     USHORT _value) :
  12.     UI_WINDOW_OBJECT(left, top, width, 1, _woFlags, WOAF_NO_FLAGS),
  13.     btFlags(_btFlags), btStatus(BTS_NO_STATUS), userFunction(_userFunction),
  14.     string(NULL), value(_value), getString(NULL), time(0)
  15. {
  16.     // Initialize the button information.
  17.     windowID[0] = ID_BUTTON;
  18.     search.type = ID_BUTTON;
  19.     depth = FlagSet(_btFlags, BTF_NO_3D) ? 0 : 1;
  20.  
  21.     // Match with the appropriate Windows 3.0 flags.
  22.     if (FlagSet(woFlags, WOF_BORDER))
  23.         MSWindowsStyle |= WS_BORDER;
  24.  
  25.     if (!FlagSet(btFlags, BTF_NO_3D))
  26.         MSWindowsStyle |= BS_PUSHBUTTON;
  27.  
  28.     if (!_string)
  29.         return;
  30.     string = FlagSet(_woFlags, WOF_NO_ALLOCATE_DATA) ? _string : ui_strdup(_string);
  31. }
  32.  
  33. UIW_BUTTON::~UIW_BUTTON()
  34. {
  35.     // Destroy the string information.
  36.     if (string && !FlagSet(woFlags, WOF_NO_ALLOCATE_DATA))
  37.         delete string;
  38.     if (getString)
  39.         delete getString;
  40. }
  41.  
  42. void UIW_BUTTON::DataSet(char *_string)
  43. {
  44.     // Reset the button's string information.
  45.     if (_string)
  46.     {
  47.         if (string && !FlagSet(woFlags, WOF_NO_ALLOCATE_DATA))
  48.             delete string;
  49.         string = FlagSet(woFlags, WOF_NO_ALLOCATE_DATA) ? _string : ui_strdup(_string);
  50.  
  51.         if (hWnd)
  52.             SetWindowText(hWnd, string);
  53.     }
  54.     UI_WINDOW_OBJECT::Redisplay(FALSE);
  55. }
  56.  
  57. const char *UIW_BUTTON::DataGet(int stripString)
  58. {
  59.     if (!string || !stripString)
  60.         return (string);
  61.     if (getString)
  62.         delete getString;
  63.     getString = new char[strlen(string)+1];
  64.     int offset = 0;
  65.     while (string[offset] == ' ' || string[offset] == '√')
  66.         offset++;
  67.     strcpy(getString, &string[offset]);
  68.     offset = strlen(getString) - 1;
  69.     while (offset >= 0 && getString[offset] == ' ')
  70.         offset--;
  71.     getString[offset + 1] = '\0';
  72.     return (getString);
  73. }
  74.  
  75. int UIW_BUTTON::Event(const UI_EVENT &event)
  76. {
  77.     // Switch on the event type.
  78.     UI_PALETTE *palette;
  79.     int ccode = UI_WINDOW_OBJECT::LogicalEvent(event, ID_BUTTON);
  80.     int t_depth = (FlagSet(woFlags, WOF_NON_SELECTABLE)) ? 0 : depth;
  81.     if (FlagSet(btFlags, BTF_CHECK_MARK))
  82.         string[0] = (FlagSet(woStatus, WOS_SELECTED)) ? '√' : ' ';
  83.     switch (ccode)
  84.     {
  85.     case S_INITIALIZE:
  86.         {
  87.         // Add item - event.rawCode ID number.
  88.         char *tHotKey = NULL;
  89.         if (string)
  90.             tHotKey = strchr(string, '~');
  91.         if (tHotKey)
  92.             hotKey = toupper(tHotKey[1]);
  93.         if (!FlagSet(btFlags, BTF_NO_3D))
  94.             ui_strrepc(string, '~', '&');
  95.         }
  96.         break;
  97.  
  98.     case S_CREATE:
  99.         depth = FlagSet(btFlags, BTF_NO_3D) ? 0 : 1;
  100.         // Continue to S_SIZE.
  101.  
  102.     case S_SIZE:
  103.         display->RegionConvert(relative, &woStatus, WOS_GRAPHICS);
  104.         if (!display->isText && FlagSet(btFlags, BTF_AUTO_SIZE))
  105.             relative.top = relative.bottom - (display->cellHeight * 3) / 2;
  106.         UI_WINDOW_OBJECT::RegionMax(TRUE);
  107.  
  108.         UI_WINDOW_OBJECT *root = parent;
  109.         while (root->parent && !root->hWnd)
  110.             root = root->parent;
  111.         if (!root->hWnd)
  112.             break;
  113.         POINT client = { 0, 0 };
  114.         ClientToScreen(root->hWnd, &client);
  115.  
  116.         if (!hWnd && !FlagSet(btFlags, BTF_NO_3D))
  117.         {
  118.             hWnd = CreateWindow("Button", string,
  119.                 WS_CHILD | WS_VISIBLE | MSWindowsStyle,
  120.                 true.left - client.x, true.top - client.y,
  121.                 true.right - true.left, true.bottom - true.top,
  122.                 root->hWnd, 1, ((UI_MSWINDOWS_DISPLAY *)display)->hInstance, NULL);
  123.             screenID = hWnd;
  124.         }
  125.         else if (hWnd)
  126.         {
  127.             RECT windowRect;
  128.             GetWindowRect(hWnd, &windowRect);
  129.             if (true.left != windowRect.left || true.top != windowRect.top ||
  130.                 true.right != windowRect.right || true.bottom != windowRect.bottom)
  131.             {
  132.                 MoveWindow(hWnd, true.left - client.x, true.top - client.y,
  133.                     true.right - true.left, true.bottom - true.top, TRUE);
  134.                 SendMessage(hWnd, WM_NCPAINT, 0, 0x0L);
  135.             }
  136.         }
  137.  
  138.         if (hWnd && FlagSet(woAdvancedStatus, WOAS_TOO_SMALL))
  139.         {
  140.             EnableWindow(hWnd, 0);
  141.             SendMessage(hWnd, WM_KILLFOCUS, parent->hWnd, 0L);
  142.         }
  143.         else if (hWnd && !IsWindowEnabled(hWnd))
  144.             EnableWindow(hWnd, 1);
  145.         break;
  146.  
  147.     case S_CURRENT:
  148.     case S_DISPLAY_ACTIVE:
  149.         if (hWnd)
  150.         {
  151.             if (FlagSet(woStatus, WOS_CURRENT) && !FlagSet(woFlags, WOF_VIEW_ONLY))
  152.             {
  153.                 SendMessage(hWnd, WM_KILLFOCUS, parent->hWnd, 0L);
  154.                 SendMessage(hWnd, WM_SETFOCUS, parent->hWnd, 0L);
  155.             }
  156.         }
  157.         else if (ccode == S_CURRENT || UI_WINDOW_OBJECT::NeedsUpdate(event, ccode))
  158.         {
  159.             lastPalette = UI_WINDOW_OBJECT::LogicalPalette(ccode);
  160.             UI_WINDOW_OBJECT::Text(string, t_depth, ccode, lastPalette);
  161.         }
  162.         break;
  163.  
  164.     case S_NON_CURRENT:
  165.         woStatus &= ~WOS_CURRENT;
  166.         btStatus &= ~BTS_DEPRESSED;
  167.         if (hWnd)
  168.             SendMessage(hWnd, WM_KILLFOCUS, parent->hWnd, 0L);
  169.         // Continue on to S_DISPLAY_INACTIVE.
  170.  
  171.     case S_DISPLAY_INACTIVE:
  172.         if (!hWnd && UI_WINDOW_OBJECT::NeedsUpdate(event, ccode))
  173.         {
  174.             lastPalette = UI_WINDOW_OBJECT::LogicalPalette(ccode);
  175.             UI_WINDOW_OBJECT::Text(string, t_depth, ccode, lastPalette);
  176.         }
  177.         break;
  178.  
  179.     case L_VIEW:
  180.         // See if it is an event the button knows how to handle.
  181.         if (event.rawCode == 0)
  182.         {
  183.             UI_WINDOW_OBJECT::Event(event);
  184.             break;
  185.         }
  186.         // Continue to L_BEGIN_SELECT.
  187.  
  188.     case L_BEGIN_SELECT:
  189.     case L_CONTINUE_SELECT:
  190.     case L_END_SELECT:
  191.         // Make sure the button can be selected.
  192.         if (FlagSet(woFlags, WOF_NON_SELECTABLE))
  193.             break;
  194.  
  195.         if (hWnd && ccode == L_BEGIN_SELECT)
  196.                 SendMessage(hWnd, WM_LBUTTONDOWN, 0, 0L);
  197.  
  198.         if (ccode != L_END_SELECT && !FlagSet(btStatus, BTS_DEPRESSED) && 
  199.             UI_WINDOW_OBJECT::Overlap(event.position))
  200.         {
  201.             btStatus |= BTS_DEPRESSED;
  202.             SendMessage(hWnd, BM_SETSTATE, 1, 0L);
  203.         }
  204.         else if (FlagSet(btStatus, BTS_DEPRESSED) &&
  205.             !UI_WINDOW_OBJECT::Overlap(event.position))
  206.         {
  207.             btStatus &= ~BTS_DEPRESSED;
  208.             SendMessage(hWnd, BM_SETSTATE, 0, 0L);
  209.         }
  210.         
  211.         if (ccode == L_BEGIN_SELECT && FlagSet(btFlags, BTF_DOWN_CLICK))
  212.             ccode = L_END_SELECT;
  213.         else if (ccode != L_BEGIN_SELECT && FlagSet(btFlags, BTF_DOWN_CLICK))
  214.             break;
  215.  
  216.         // See if the button is to be selected.
  217.         if (!UI_WINDOW_OBJECT::Overlap(event.position) || ccode != L_END_SELECT ||
  218.             (FlagSet(btFlags, BTF_DOUBLE_CLICK) && ui_time() - time > repeatRate))
  219.         {
  220.             time = ui_time();
  221.             break;
  222.         }
  223.         // Continue to L_SELECT.
  224.  
  225.     case L_SELECT:
  226.         if (!FlagSet(woStatus, WOS_SELECTED) && !FlagSet(btFlags, BTF_NO_TOGGLE))
  227.             woStatus |= WOS_SELECTED;
  228.         else if (!FlagSet(btFlags, BTF_NO_TOGGLE))
  229.             woStatus &= ~WOS_SELECTED;
  230.         btStatus &= ~BTS_DEPRESSED;
  231.         UI_EVENT t_event = event;
  232.         if (hWnd)
  233.         {
  234.             if (ccode == L_SELECT)
  235.             {
  236.                 SendMessage(hWnd, BM_SETSTATE, 1, 0L);
  237.                 WaitMessage();
  238.                 SendMessage(hWnd, BM_SETSTATE, 0, 0L);
  239.             }
  240.             SendMessage(hWnd, WM_KILLFOCUS, parent->hWnd, 0L);
  241.             SendMessage(hWnd, WM_SETFOCUS, parent->hWnd, 0L);
  242.         }
  243.         else
  244.         {
  245.             palette = UI_WINDOW_OBJECT::LogicalPalette(ccode);
  246.             UI_WINDOW_OBJECT::Text(string, t_depth, ccode, palette);
  247.         }
  248.         if (userFunction)
  249.             (*userFunction)(this, t_event);
  250.         woStatus &= ~WOS_UNANSWERED;
  251.         time = ui_time();
  252.         if (FlagSet(btFlags, BTF_CHECK_MARK))
  253.         {
  254.             string[0] = (FlagSet(woStatus, WOS_SELECTED)) ? '√' : ' ';
  255.             if (hWnd)
  256.                 SetWindowText(hWnd, string);
  257.         }
  258.         break;
  259.  
  260.     default:
  261.         ccode = UI_WINDOW_OBJECT::Event(event);
  262.         break;
  263.     }
  264.  
  265.     // Return the control code.
  266.     return (ccode);
  267. }
  268.  
  269. #ifdef ZIL_LOAD
  270. UIW_BUTTON::UIW_BUTTON(const char *name, UI_STORAGE *file, USHORT loadFlags) :
  271.     UI_WINDOW_OBJECT(name, file, loadFlags | L_SUB_LEVEL),
  272.     btStatus(BTS_NO_STATUS), userFunction(NULL), getString(NULL), value(0)
  273. {
  274.     windowID[0] = ID_BUTTON;
  275.  
  276.     if (!file)
  277.         file = _storage;
  278.     file->Load(&btFlags);
  279.     file->Load(&value);
  280.     file->Load(&string);
  281.     if (!string)
  282.         string = ui_strdup("");
  283.     depth = (FlagSet(BTF_NO_3D, btFlags)) ? 0 : 1;
  284.     if (!FlagSet(loadFlags, L_SUB_LEVEL) && FlagSet(file->stStatus, STS_TEMPORARY))
  285.         delete file;
  286. }
  287. #endif
  288.  
  289. #ifdef ZIL_STORE
  290. void UIW_BUTTON::Store(const char *name, UI_STORAGE *file, USHORT storeFlags)
  291. {
  292.     UI_WINDOW_OBJECT::Store(name, file, storeFlags | S_SUB_LEVEL);
  293.     file->Store(btFlags);
  294.     file->Store(value);
  295.     file->Store(string);
  296.     if (!FlagSet(storeFlags, S_SUB_LEVEL))
  297.         file->ObjectSize(name, search);
  298. }
  299. #endif
  300.