home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / yacl-012.zip / ui / btngroup.cxx < prev    next >
C/C++ Source or Header  |  1995-04-04  |  10KB  |  356 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. #if defined(__GNUC__)
  33. #pragma implementation
  34. #endif
  35.  
  36.  
  37. #include "ui/btngroup.h"
  38. #include "ui/cntroler.h"
  39. #include "ui/simple.h"
  40. #include "ui/applic.h"
  41.  
  42. #if defined (__MS_WINDOWS__)
  43. #include <windows.h>
  44. #include <ctl3d.h>
  45. #define DEFAULT_STYLE BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS
  46.  
  47. #elif defined(__OS2__)
  48. #define DEFAULT_STYLE  SS_GROUPBOX | WS_VISIBLE | WS_GROUP
  49.  
  50. #elif defined (__X_MOTIF__)
  51. #include <Xm/BulletinB.h>
  52. #include <Xm/Frame.h>
  53. #include <Xm/Label.h>
  54. #endif
  55.  
  56. typedef CL_Binding<UI_ButtonGroup> BtnGroupBind;
  57.  
  58. #if defined(__GNUC__)
  59. template class CL_Binding<UI_ButtonGroup>;
  60. #endif
  61.  
  62.  
  63. UI_ButtonGroup::UI_ButtonGroup
  64.     (UI_VObjCollection* parent, const UI_Rectangle& r,  UI_ViewID id)
  65. : UI_VObjCollection (parent, r, id)
  66. {
  67.     if (!_parent)
  68.         CL_Error::Warning ("ButtonGroup constructor: id %d: NULL parent!",
  69.                            id);
  70. #if defined (__MS_WINDOWS__) || defined(__OS2__)
  71.     _style = DEFAULT_STYLE;
  72.     BtnGroupBind bind (this, &UI_ButtonGroup::_GetFocus);
  73.     AddEventDependent (Event_KeyTyped, bind, 1);
  74. #endif
  75. }
  76.  
  77.  
  78.  
  79. #if defined(__MS_WINDOWS__)
  80. // For resource-based construction (only under MS-Windows):
  81.  
  82. UI_ButtonGroup::UI_ButtonGroup
  83.     (UI_VObjCollection* parent, UI_ViewID id, UI_ViewHandle h)
  84. : UI_VObjCollection (parent, UI_Rectangle(), id)
  85. {
  86.     _id = id;
  87.     _handle = h;
  88. #if defined (__MS_WINDOWS__) || defined(__OS2__)
  89.     BtnGroupBind bind (this, &UI_ButtonGroup::_GetFocus);
  90.     AddEventDependent (Event_KeyTyped, bind, 1);
  91. #endif
  92. }
  93.  
  94. #endif
  95.  
  96.  
  97.  
  98. UI_ButtonGroup::~UI_ButtonGroup ()
  99. {
  100. }
  101.  
  102.  
  103.  
  104. bool UI_ButtonGroup::MakeVisualElement ()
  105. {
  106. #if defined(__MS_WINDOWS__)
  107.     if (!UI_VObjCollection::MakeVisualElement())
  108.         return FALSE;
  109.     if (Has3DLook())
  110.         Ctl3dSubclassCtl (_handle);
  111.     return TRUE;
  112. #elif defined(__OS2__)
  113.     bool b = UI_VObjCollection::MakeVisualElement();
  114.     // And, just like under Windows, we need to subclass the button group,
  115.     // otherwise it doesn't repaint itself right.
  116.     // _Subclass ();
  117.     BtnGroupBind bind (this, &UI_ButtonGroup::_GetFocus);
  118.     AddEventDependent (Event_KeyTyped, bind, 1);
  119.     return b;
  120. #elif defined(__X_MOTIF__)
  121.     // GNU C seems to have a strange bug, so we work around it. Instead of
  122.     // saying
  123.     //    Widget pw = (Widget) (_parent->ViewHandle());
  124.     // we say
  125.     UI_VisualObject* p = _parent;
  126.     Widget pw = (Widget) p->ViewHandle();
  127.  
  128.     // First, we'll create a Frame widget
  129.     CL_String instance_name = InstanceName();
  130.     CL_String frame_name    = instance_name  + "_frame";
  131.  
  132.     Arg arg [20];
  133.     short argn = 0;
  134.     _SetupStyle (arg, argn); // Set up the X resources
  135.     XtSetArg (arg[argn ], XmNshadowType, XmSHADOW_ETCHED_OUT); argn++;
  136.     XtSetArg (arg [argn], XmNmarginWidth,  0);     argn++;
  137.     XtSetArg (arg [argn], XmNmarginHeight, 0);     argn++;
  138.     _frameWidget = XtCreateWidget (frame_name.AsPtr(), xmFrameWidgetClass,
  139.                                    pw, arg, argn);
  140.  
  141.     // Next, create a label child of the frame
  142.     CL_String label_name = instance_name + "_label";
  143.     argn = 0;
  144.     XmString title = XmStringCreate
  145.         ((char *) _title.AsPtr (), XmSTRING_DEFAULT_CHARSET);    
  146.     XtSetArg (arg [argn], XmNlabelString, title); argn++;
  147.     XtSetArg (arg [argn], XmNchildType, XmFRAME_TITLE_CHILD); argn++;
  148.     _frameLabel = XtCreateWidget
  149.         (label_name.AsPtr(), xmLabelWidgetClass, _frameWidget, arg, argn);
  150.  
  151.     // Finally, create the bulletin board widget
  152.     const char* inst_name = instance_name.AsPtr();
  153.     struct _WidgetClassRec *class_name = WindowClass ();
  154.     argn = 0;
  155. //     XtSetArg (arg [argn], XmNmarginWidth,  0);     argn++;
  156. //     XtSetArg (arg [argn], XmNmarginHeight, 0);     argn++;
  157.     _xwidget = XtCreateWidget (inst_name, class_name, _frameWidget, arg,
  158.                                argn);
  159.     // Clean up
  160.     XtRealizeWidget (_frameWidget);
  161.     XtRealizeWidget (_xwidget);
  162.     XmStringFree (title);
  163.  
  164.     return TRUE;
  165. #endif
  166. }
  167.  
  168.  
  169. void UI_ButtonGroup::_PrivateInitialize ()
  170. {
  171.     UI_VObjCollection::_PrivateInitialize ();
  172. #if defined(__MS_WINDOWS__)
  173.     UI_ResourceHandle h = _font ? _font->Handle() : 0;
  174.     if (h && !_parent->CreatedViaResource()) {
  175.         SendMessage (_handle, WM_SETFONT, h, TRUE);
  176.     }
  177.  
  178.     // We must subclass the GroupBox to ensure that group boxes get
  179.     // correctly repainted under Windows. This is not necessary for
  180.     // resource-based dialogs, however.
  181.     if (!CreatedViaResource()) {
  182.         WNDPROC realProc = (WNDPROC) SetWindowLong
  183.             (_handle, GWL_WNDPROC, (long) YACLBtnGroupProc);
  184.         // Set the property to our address
  185.         SetProp (_handle, BTNGROUP_PROPERTY1, LOWORD (realProc));
  186.         SetProp (_handle, BTNGROUP_PROPERTY2, HIWORD (realProc));
  187.     }
  188. #elif defined(__X_MOTIF__)
  189.     if (_visible) {
  190.         XtManageChild (_frameWidget);
  191.         XtManageChild (_frameLabel);
  192.     }
  193. #endif
  194. }
  195.  
  196.  
  197. void UI_ButtonGroup::MakeInvisible ()
  198. {
  199.     UI_VObjCollection::MakeInvisible ();
  200. #if defined(__X_MOTIF__)
  201.     if (_frameWidget)   // We've been created
  202.         XtUnmanageChild (_frameWidget);
  203. #endif
  204. }
  205.  
  206.  
  207. void UI_ButtonGroup::MakeVisible ()
  208. {
  209.     UI_VObjCollection::MakeVisible ();
  210. #if defined(__X_MOTIF__)
  211.     if (_frameWidget) {   // We've been created
  212.         XtManageChild (_frameWidget);
  213.         XtManageChild (_frameLabel);
  214.     }
  215. #endif
  216. }
  217.  
  218.  
  219. #if defined(__MS_WINDOWS__) || defined(__OS2__)
  220. bool UI_ButtonGroup::_GetFocus (CL_Object& obj, long)
  221. {
  222.     UI_Event& e = (UI_Event&) obj;
  223. #if defined(__OS2__)
  224.     ushort virtKey = SHORT2FROMMP (((QMSG*) e._nativeEvent)->mp2);
  225. #else
  226.     ushort virtKey = e.key;
  227. #endif
  228.     if (virtKey != VK_UP && virtKey != VK_DOWN)
  229.         return TRUE;
  230.     CL_ObjectSequence seq = _Controller->ChildrenOf (*this);
  231.     short n = seq.Size();
  232.     if (n > 0) {
  233.         long index = seq.LinearSearch (e.Origin());
  234.         if (index >= 0) {
  235.             short next = virtKey == VK_UP ? index-1 : (index+1) % n;
  236.             if (next == -1)
  237.                 next += n;
  238.             _Controller->GiveFocusTo (*(UI_VisualObject*) seq[next]);
  239.         }
  240.     }
  241.     return TRUE;
  242. }
  243.  
  244. void UI_ButtonGroup::TakeFocus ()
  245. {
  246.     CL_ObjectSequence seq = _Controller->ChildrenOf (*this);
  247.     short n = seq.Size();
  248.     if (n > 0)
  249.         _Controller->GiveFocusTo (*(UI_VisualObject*) seq[0]);
  250. }
  251.  
  252. #endif
  253.  
  254.  
  255. UI_WindowClass UI_ButtonGroup::WindowClass () const
  256. {
  257. #if defined(__MS_WINDOWS__)
  258.     return  "button";
  259. #elif defined(__OS2__)
  260.     return WC_STATIC;
  261. #elif defined(__X_MOTIF__)
  262.     return xmBulletinBoardWidgetClass;
  263. #endif
  264. }
  265.  
  266.  
  267.  
  268.  
  269.  
  270. bool UI_ButtonGroup::_TitleChanged (CL_Object& o, long l)
  271. {
  272. #if defined(__MS_WINDOWS__)
  273.     return UI_VObjCollection::_TitleChanged (o, l);
  274.  
  275. #elif defined(__OS2__)
  276.     return UI_VObjCollection::_TitleChanged (o, l);
  277.  
  278. #elif defined(__X_MOTIF__)
  279.     if (!_xwidget)
  280.         return TRUE; // Not yet set up
  281.     XmString xmtitle;
  282.     xmtitle = XmStringCreate ((char*)_title.AsPtr(),
  283.                               XmSTRING_DEFAULT_CHARSET);
  284.     XtVaSetValues (_frameWidget, XmNlabelString, xmtitle, NULL);
  285.     XmStringFree (xmtitle);
  286.     XmUpdateDisplay (_xwidget);
  287.     return TRUE;
  288. #endif
  289. }
  290.  
  291.  
  292. bool UI_ButtonGroup :: _FontChanged (CL_Object& o, long l)
  293. {
  294. #if defined (__X_MOTIF__)
  295.     UI_ResourceHandle h = _font ? _font->Handle() : 0;
  296.     
  297.     if (h <= 0 || !_frameLabel)
  298.         return FALSE;
  299.  
  300.     Display *dpy = XtDisplay (_frameLabel);
  301.     XmFontList f = XmFontListCreate (XQueryFont (dpy, h),
  302.                                      XmSTRING_DEFAULT_CHARSET);
  303.     Arg arg [1];
  304.     XtSetArg       (arg [0], XmNfontList,  f);
  305.     XtSetValues    (_frameLabel, arg, 1);
  306.     XmFontListFree (f);
  307. #endif
  308.     return UI_VObjCollection::_FontChanged (o, l);
  309. }
  310.  
  311.  
  312. #if defined(__OS2__)
  313.  
  314. MRESULT EXPENTRY UI_ButtonGroup::ButtonGroupProc
  315.     (HWND hWnd, ULONG msg, MPARAM p1, MPARAM p2)
  316. {
  317.     UI_ButtonGroup* grp = (UI_ButtonGroup*) (*_Controller)[hWnd];
  318.     switch (msg) {
  319.     case WM_ERASEBACKGROUND:
  320.         CL_Error::Warning ("ButtonGroup erase: hwnd %d\n", hWnd);
  321.         break;
  322.         
  323.     case WM_PAINT: {
  324.         if (grp) {
  325.             CL_Error::Warning ("ButtonGroup paint: hwnd %d\n", hWnd);
  326.         }
  327.         break;
  328.     }
  329.         
  330. //         HPS hps = WinGetPS (hWnd);
  331. //         RECTL rect;
  332. //         WinQueryWindowRect (hWnd, &rect);
  333. //         HRGN hrgn = GpiCreateRegion (hps, 1, &rect);
  334. //         GpiSetClipRegion (hps, hrgn, NULL);
  335. //         GpiErase (hps);
  336. //         GpiDestroyRegion (hps, hrgn);
  337. //         WinReleasePS (hps);
  338.  
  339.     default:
  340.         break;
  341.     }
  342.     if (grp)
  343.         return (*(grp->_oldProc))(hWnd, msg, p1, p2);
  344.     return WinDefWindowProc (hWnd, msg, p1, p2);
  345.     
  346. }
  347.  
  348. void UI_ButtonGroup::_Subclass ()
  349. {
  350.     _oldProc = WinSubclassWindow (_handle, UI_ButtonGroup::ButtonGroupProc);
  351. }
  352.  
  353. #endif
  354.  
  355.  
  356.