home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / yacl-012.zip / ui / toglbtn.cxx < prev    next >
C/C++ Source or Header  |  1995-04-04  |  7KB  |  232 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6. /*
  7.  *
  8.  *          Copyright (C) 1994, M. A. Sridhar
  9.  *  
  10.  *
  11.  *     This software is Copyright M. A. Sridhar, 1994. You are free
  12.  *     to copy, modify or distribute this software  as you see fit,
  13.  *     and to use  it  for  any  purpose, provided   this copyright
  14.  *     notice and the following   disclaimer are included  with all
  15.  *     copies.
  16.  *
  17.  *                        DISCLAIMER
  18.  *
  19.  *     The author makes no warranties, either expressed or implied,
  20.  *     with respect  to  this  software, its  quality, performance,
  21.  *     merchantability, or fitness for any particular purpose. This
  22.  *     software is distributed  AS IS.  The  user of this  software
  23.  *     assumes all risks  as to its quality  and performance. In no
  24.  *     event shall the author be liable for any direct, indirect or
  25.  *     consequential damages, even if the  author has been  advised
  26.  *     as to the possibility of such damages.
  27.  *
  28.  */
  29.  
  30.  
  31.  
  32.  
  33. #if defined(__GNUC__)
  34. #pragma implementation
  35. #endif
  36.  
  37.  
  38.  
  39. #include "ui/toglbtn.h"
  40. #include "ui/cntroler.h"
  41. #include "ui/composit.h"
  42.  
  43. #include "base/integer.h"
  44.  
  45.  
  46. //------------------------------------------------------------------
  47. //                     CLASS TOGGLEBUTTON
  48. //------------------------------------------------------------------
  49.  
  50. #if defined(__MS_WINDOWS__)
  51. #include <windows.h>
  52. #define TOGGLE_BUTTON_STYLE \
  53.     BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP
  54. #elif defined(__OS2__)
  55. #define TOGGLE_BUTTON_STYLE BS_AUTOCHECKBOX | WS_VISIBLE
  56. #elif defined(__X_MOTIF__)
  57. #include <Xm/ToggleB.h>
  58. #endif
  59.  
  60.  
  61. #if defined(__MS_WINDOWS__)
  62. // We have to subclass the button *after* the Ctl3d subclass in order to
  63. // paint its background properly.
  64. #define PROP1 "YACL_BTN_PROP1"
  65. #define PROP2 "YACL_BTN_PROP2"
  66. static long FAR PASCAL _export BtnProc (HWND hWnd, unsigned msg, WORD
  67.                                         wParam, LONG lParam)
  68. {
  69.     int low = GetProp (hWnd, PROP1);
  70.     int hi  = GetProp (hWnd, PROP2);
  71.     if (!low || !hi)
  72.         return DefWindowProc (hWnd, msg, wParam, lParam);
  73.     if (msg == WM_KEYDOWN &&
  74.         (wParam == VK_UP || wParam == VK_DOWN || wParam == VK_LEFT ||
  75.          wParam == VK_RIGHT)) {
  76.         // ----^^^^^^^^------
  77.         // Yet another hack. Windows sends WM_CHAR messages to *both* this
  78.         // subclassing proc and the main event loop in ProcessNativeEvents.
  79.         // But it doesn't send WM_CHAR if an arrow key is typed. So we send
  80.         // the arrow key to the button group parent.
  81.         UI_Controller& ctrl = _TheApplication->Controller();
  82.         UI_VisualObject* v = ctrl[hWnd];
  83.         UI_Event* e = new UI_Event (Event_KeyTyped, v, v);
  84.         e->key = wParam;
  85.         ctrl.AddEvent (e);
  86.     }
  87.     else if (msg == WM_ERASEBKGND) {
  88.         // Catch the ERASEBKGND message *before* it gets to the button, and
  89.         // fill its background with grey:
  90.         RECT rect;
  91.         GetClientRect (hWnd, &rect);
  92.         HBRUSH brush = GetClassWord (GetParent (hWnd), GCW_HBRBACKGROUND);
  93.         FillRect ((HDC) wParam, &rect, brush);
  94.         // Now just call the real proc, pretending that no painting was
  95.         // done, and let it do its thing:
  96.     }
  97.     FARPROC realProc = (FARPROC) MAKELONG (low, hi);
  98.     return CallWindowProc (realProc, hWnd, msg, wParam, lParam);
  99. }
  100.  
  101. static void _SubclassButton (long handle)
  102. {
  103.     FARPROC RealProc = (FARPROC) SetWindowLong (handle, GWL_WNDPROC, (long)
  104.                                                 BtnProc);
  105.     SetProp (handle, PROP1, LOWORD (RealProc));
  106.     SetProp (handle, PROP2, HIWORD (RealProc));
  107. }
  108. #endif
  109.  
  110.  
  111. UI_ToggleButton::UI_ToggleButton
  112.     (UI_VObjCollection* parent, const UI_Rectangle& shape, UI_ViewID id)
  113. : UI_SimpleVObject (parent, shape, id)
  114. {
  115. #if defined(__MS_WINDOWS__) || defined(__OS2__)
  116.     _style = TOGGLE_BUTTON_STYLE;
  117. #endif
  118.     _model = new CL_Integer;
  119.     _borderShown = FALSE;
  120. }
  121.  
  122.  
  123. #if defined(__MS_WINDOWS__)
  124. UI_ToggleButton::UI_ToggleButton (UI_VObjCollection* parent, UI_ViewID
  125.                                   id, UI_ViewHandle h) 
  126. : UI_SimpleVObject (parent, id, h)
  127. {
  128.     _model = new CL_Integer; 
  129.     _borderShown = FALSE;
  130. }
  131. #endif
  132.  
  133.  
  134.  
  135.  
  136. CL_Object& UI_ToggleButton::Model ()
  137. {
  138. #if defined (__MS_WINDOWS__)
  139.     if (_handle > 0)
  140.         _SetModelValue (CL_Integer (SendMessage (_handle,
  141.                                                 BM_GETCHECK, 0, 0L)));
  142. #elif defined(__OS2__)
  143.     if (_handle) {
  144.         long val = (long) WinSendMsg (_handle, BM_QUERYCHECK, 0, 0L);
  145.         _SetModelValue (CL_Integer (val));
  146.     }
  147. #elif defined (__X_MOTIF__)
  148.     if (_xwidget)
  149.         _SetModelValue (CL_Integer (XmToggleButtonGetState (_xwidget)));
  150. #endif
  151.     return *_model;
  152. }
  153.  
  154.  
  155.  
  156.  
  157.  
  158. bool UI_ToggleButton::_ModelChanged (CL_Object&, long)
  159. {
  160. #if defined (__MS_WINDOWS__)
  161.     if (_handle > 0) {
  162.         SendMessage (_handle, BM_SETCHECK,
  163.                      ((CL_Integer*) _model)->Value() > 0 ? 1 : 0, 0L);
  164.     }
  165. #elif defined(__OS2__)
  166.     if (_handle) {
  167.         MPARAM val = MPFROM2SHORT (((CL_Integer *) _model)->Value () > 0
  168.                                  ? TRUE : FALSE, 0);
  169.         WinSendMsg (_handle, BM_SETCHECK, val, NULL);
  170.     }
  171. #elif defined (__X_MOTIF__)
  172.     if (_xwidget)
  173.         XmToggleButtonSetState (_xwidget, ((CL_Integer*) _model)->Value(),
  174.                                 FALSE);
  175. #endif
  176.     return TRUE;
  177. }
  178.  
  179.  
  180.  
  181. bool UI_ToggleButton::MakeVisualElement ()
  182. {
  183.     bool b = UI_SimpleVObject::MakeVisualElement ();
  184. #if defined(__X_MOTIF__)
  185.     XtAddCallback (_xwidget, XmNvalueChangedCallback, 
  186.                    &UI_ToggleButton::SelectionCallback, (XtPointer) this);
  187.     XtVaSetValues (_xwidget, XmNalignment, XmALIGNMENT_BEGINNING, NULL);
  188.     // If we try to set the alignment at creation time (i.e., in
  189.     // _SetupStyle), Motif complains!
  190. #endif
  191.     return b;
  192. }
  193.  
  194.  
  195. void UI_ToggleButton::_PrivateInitialize ()
  196. {
  197.     UI_SimpleVObject::_PrivateInitialize ();
  198.     _ModelChanged (*this, 1); // Dummy call to force initial setting
  199. #if defined(__MS_WINDOWS__)
  200.     _SubclassButton (_handle);
  201. #endif
  202. }
  203.  
  204.  
  205.  
  206. UI_WindowClass UI_ToggleButton::WindowClass () const
  207. {
  208. #if defined(__MS_WINDOWS__)
  209.     return "button";
  210. #elif defined(__OS2__)
  211.     return WC_BUTTON;
  212. #elif defined(__X_MOTIF__)
  213.     return xmToggleButtonWidgetClass;
  214. #endif
  215. }
  216.  
  217.  
  218.  
  219. #if defined (__X_MOTIF__)
  220. void UI_ToggleButton::SelectionCallback (Widget w, void* client, void* call)
  221. {
  222.     UI_ToggleButton* btn = (UI_ToggleButton *) client;
  223.     int value = ((XmToggleButtonCallbackStruct*) call)->set;
  224.     btn->_SetModelValue (CL_Integer(value));
  225.     _Controller->AddEvent (new UI_Event (Event_Select, btn, btn));
  226. }
  227.  
  228. #endif
  229.  
  230.  
  231.  
  232.