home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / yacl-012.zip / ui / visualob.cxx < prev    next >
C/C++ Source or Header  |  1995-04-04  |  30KB  |  1,160 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. #if defined(__GNUC__)
  32. #pragma implementation
  33. #endif
  34.  
  35.  
  36.  
  37. #ifdef __GNUC__
  38. #pragma implementation
  39. #endif
  40.  
  41. // ---------------------- Include files --------------------------
  42.  
  43. #include "base/clntset.h"
  44.  
  45. #include "ui/visualob.h"
  46. #include "ui/cntroler.h"
  47. #include "ui/composit.h"
  48. #include "ui/dsplsurf.h"
  49. // #include "ui/colormap.h"
  50.  
  51. #if defined(__MS_WINDOWS__)
  52.  
  53. #elif defined(__X_MOTIF__)
  54. #include <X11/Intrinsic.h>
  55. #include <X11/StringDefs.h>
  56. #include <Xm/Xm.h>
  57. #include <Xm/Label.h>
  58. #include <Xm/DrawingA.h>
  59. struct _WidgetRec* UI_VisualObject::_shell;
  60.  
  61. #endif
  62.  
  63. #if defined(__GNUC__) && __GNUC_MINOR__ >= 6
  64. template class CL_Binding<UI_VisualObject>;
  65. #endif
  66.  
  67.  
  68. typedef CL_Binding<UI_VisualObject> VObjBind;
  69.  
  70. // --------------- Initializations of static instance variables --------
  71.  
  72. UI_Controller*  UI_VisualObject::_Controller  = NULL;
  73. UI_Application* UI_VisualObject::_Application = NULL;
  74.  
  75.  
  76. //
  77. //  -----------------Constructor---------------------
  78. //
  79.  
  80. UI_VisualObject::UI_VisualObject
  81.     (UI_VObjCollection* parent, 
  82.      const UI_Rectangle& shape, UI_ViewID id, long style)
  83. {
  84.     _shape = shape;
  85. #if defined(__MS_WINDOWS__) || defined(__OS2__)
  86.     _style = style;
  87. #elif defined (__X_MOTIF__)
  88.     _xwidget = NULL;
  89.  
  90. #endif
  91.     _Init (parent, id);
  92. }
  93.  
  94.  
  95.  
  96. #if defined(__MS_WINDOWS__)
  97. UI_VisualObject::UI_VisualObject (UI_VObjCollection* parent,
  98.                                   UI_ViewID id, UI_ViewHandle hndl)
  99. {
  100.     _Init (parent, id);
  101.     _id = id;
  102.     long n = GetWindowTextLength (hndl);
  103.     char* buf = NULL;
  104.     if (n) {
  105.         buf = new char[n+1];
  106.         GetWindowText (hndl, buf, n+1);
  107.         _title = buf;
  108.         delete buf;
  109.     }
  110.     RECT rec;
  111.  
  112.     _handle = hndl;
  113.     _id = GetWindowWord    (_handle,GWW_ID);  
  114.     _style = GetWindowLong (_handle,GWL_STYLE); 
  115.     _visible = (_style & WS_VISIBLE) ? TRUE : FALSE;
  116.     GetWindowRect (_handle, &rec);
  117.     POINT array[2];
  118.     array[0].x = rec.left;
  119.     array[0].y = rec.top;
  120.     array[1].x = rec.right;
  121.     array[1].y = rec.bottom;
  122.     MapWindowPoints (NULL, parent->ViewHandle(), array, 2);
  123.     UI_Point org (array[0].x, array[0].y);
  124.     UI_Rectangle shp (org, array[1].x-array[0].x, array[1].y-array[0].y);
  125.     _SetShapeRectangle (shp);
  126.     
  127. }
  128. #endif
  129.  
  130.  
  131. void UI_VisualObject::_SetShapeRectangle (const UI_Rectangle& r)
  132. {
  133.      VObjBind b (this, &UI_VisualObject::_ShapeRectChanged);
  134.  
  135.     _shape.RemoveDependent (b);
  136.     _shape = r;
  137.     _shape.AddDependent (b, 1);
  138. }
  139.  
  140.  
  141. void UI_VisualObject::_SetTitle (const char* p)
  142. {
  143.      VObjBind b (this, &UI_VisualObject::_TitleChanged);
  144.  
  145.     _title.RemoveDependent (b);
  146.     _title = p;
  147.     _title.AddDependent (b, 1);
  148. }
  149.  
  150.  
  151. void UI_VisualObject::_Init (UI_VObjCollection* prnt, UI_ViewID idnum)
  152. {
  153.     _borderShown = FALSE;
  154.     _model = NULL;
  155.     _displaySurface = NULL;
  156.     _eventDependents = NULL;
  157.     _id = idnum;
  158.     _parent = prnt;
  159.     _isTabStop = TRUE;
  160.  
  161.     VObjBind bind (this, &UI_VisualObject::_TitleChanged);
  162.     _title.AddDependent (bind, 1);
  163.  
  164.     VObjBind b2 (this, &UI_VisualObject::_ShapeRectChanged);
  165.     _shape.AddDependent (b2, 1);
  166.     _ownFont = FALSE;
  167.     _font = NULL;
  168.  
  169.     if (!_parent)
  170.         _font = NULL;
  171.     else
  172.         _font = _parent->_font;
  173.  
  174.     _created = FALSE;
  175.     _enabled = TRUE; // At construction time, we assume it's enabled
  176.  
  177. #if defined(__OS2__)
  178.     _handle = 0;
  179.     _borderHandle = 0;
  180. #endif
  181.     
  182. #if defined(__MS_WINDOWS__)
  183.     _handle = 0;
  184.     _visible = (_style & WS_VISIBLE) ? TRUE : FALSE;
  185.  
  186. #else
  187.     _visible = TRUE; // By default, we're visible
  188.  
  189. #endif
  190.     if (_parent)
  191.         _parent->AddChild (this);
  192.     UI_Event* e1 = new UI_Event (Event_MakeInterface, this, _parent);
  193.     _Controller->AddEvent (e1);
  194. }
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201. UI_VisualObject::~UI_VisualObject () 
  202. {
  203.     if ( _parent )
  204.         _parent->RemoveChild (this);
  205.     if ( _displaySurface )
  206.         delete _displaySurface;
  207.     if ( _ownFont )
  208.         delete _font;
  209.     if (_eventDependents) {
  210.         _eventDependents->DestroyContents();
  211.         delete _eventDependents;
  212.     }
  213. }
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220. //
  221. //  -----------------Query---------------------------
  222. //
  223.  
  224. UI_Rectangle UI_VisualObject::Area() const
  225. {
  226. #if defined(__MS_WINDOWS__)
  227.     RECT msrec;
  228.     GetWindowRect (_handle, &msrec);
  229.     UI_Point p (msrec.left, msrec.top);
  230.     UI_Rectangle rec (p, msrec.right - msrec.left, msrec.bottom - msrec.top);
  231.     return rec;
  232.  
  233. #elif defined(__OS2__)
  234.     return _shape;
  235. #elif defined(__X_MOTIF__)
  236.     return _shape;
  237. #endif
  238. }
  239.  
  240.  
  241.  
  242.  
  243.  
  244. UI_WindowClass UI_VisualObject::WindowClass () const
  245. {
  246.     CL_Error::Warning ("UI_VisualObject::WindowClass: derived class %s"
  247.                        " did not override!", ClassName());
  248. #if defined(__MS_WINDOWS__) || defined(__OS2__)
  249.     return _YACLWindowClassName;
  250. #elif defined(__X_MOTIF__)
  251.     return xmDrawingAreaWidgetClass;
  252. #endif
  253. }
  254.  
  255. UI_DisplaySurface& UI_VisualObject::CreateDisplaySurface ()
  256. {
  257.     if (!_displaySurface)
  258.         _displaySurface = new UI_DisplaySurface (this);
  259.     _displaySurface->SetFont (_font);
  260.     return *_displaySurface;
  261. }
  262.  
  263.  
  264.  
  265. void UI_VisualObject::DestroyDisplaySurface()
  266. {
  267.     if ( _displaySurface ) {
  268.         delete _displaySurface;
  269.         _displaySurface = NULL;
  270.     }
  271. }
  272.  
  273.  
  274. #if defined(__MS_WINDOWS__)
  275.  
  276. bool UI_VisualObject::CreatedViaResource ()
  277. {
  278.     return _parent &&  _parent->CreatedViaResource();
  279. }
  280.  
  281.  
  282. bool UI_VisualObject::Has3DLook () const
  283. {
  284.     return  _parent ? _parent->Has3DLook() : FALSE;
  285. }
  286.  
  287. #endif
  288.  
  289.  
  290. //
  291. //------------------------Event Handling----------------
  292. //
  293.  
  294. bool UI_VisualObject::HandleEvent (UI_Event* e)
  295. {
  296.     return ProcessEvent (e);
  297. }
  298.  
  299.  
  300.  
  301. bool UI_VisualObject::ProcessEvent (UI_Event* e)
  302. {
  303.     switch (e->Type()) {
  304.     case Event_LButtonPress:
  305.         return ButtonDown (e->curPos.Origin(), UIM_Left,
  306.                            e->_shiftKey, e->_ctrlKey);
  307.  
  308.     case Event_LButtonRelease:
  309.         return ButtonUp (e->curPos.Origin(), UIM_Left);
  310.  
  311.     case Event_LButtonDblClk:
  312.         return DoubleClick (e->curPos.Origin(), UIM_Left);
  313.  
  314.     case Event_MButtonPress:
  315.         return ButtonDown (e->curPos.Origin(), UIM_Middle,
  316.                            e->_shiftKey, e->_ctrlKey);
  317.  
  318.     case Event_MButtonRelease:
  319.         return ButtonUp (e->curPos.Origin(), UIM_Middle);
  320.  
  321.     case Event_MButtonDblClk:
  322.         return DoubleClick (e->curPos.Origin(), UIM_Middle);
  323.  
  324.     case Event_RButtonPress:
  325.         return ButtonDown (e->curPos.Origin(), UIM_Right,
  326.                            e->_shiftKey, e->_ctrlKey);
  327.  
  328.     case Event_RButtonRelease:
  329.         return ButtonUp (e->curPos.Origin(), UIM_Right);
  330.  
  331.     case Event_RButtonDblClk:
  332.         return DoubleClick (e->curPos.Origin(), UIM_Right);
  333.  
  334.     case Event_MouseMove:
  335.         return MouseMove (e->curPos.Origin());
  336.  
  337.     case Event_ViewEnter:  
  338.         return ViewEnter (e->curPos.Origin());
  339.  
  340.     case Event_ViewLeave:
  341.         return ViewLeave (e->curPos.Origin());
  342.  
  343.     case Event_GetFocus:
  344.         return GetFocus ();
  345.  
  346.     case Event_LoseFocus:
  347.         return LoseFocus ();
  348.  
  349.     case Event_KeyTyped:
  350.         return KeyTyped (e->key);
  351.  
  352.     case Event_Paint:
  353.         return _created ? Paint(): FALSE;
  354.  
  355.     case Event_Reconfigure:
  356.         return Reconfigure (e->curPos);
  357.  
  358.     case Event_ChildCreated:
  359.         return FALSE;
  360.  
  361.     case Event_Select:
  362.         return Select ();
  363.  
  364.     case Event_Iconify:
  365.         return Iconify ();
  366.  
  367.     case Event_Deiconify:
  368.         return Deiconify ();
  369.  
  370.     case Event_FullScreen:
  371.         return FullScreen ();
  372.  
  373.     case Event_CloseDown:
  374.         CloseDown ();
  375.         return FALSE;
  376.         
  377.     default:
  378.         return FALSE;
  379.     }
  380. }
  381.  
  382.  
  383.  
  384. //
  385. //------------------Mouse Events----------------------
  386. //
  387.  
  388. bool UI_VisualObject::ButtonDown (const UI_Point&, UI_MouseButton, bool, bool)
  389. {
  390.     return FALSE;
  391. }
  392.     
  393.  
  394. bool UI_VisualObject::ButtonUp (const UI_Point&, UI_MouseButton)
  395. {
  396.     return FALSE;
  397. }
  398.  
  399.  
  400. bool UI_VisualObject::DoubleClick (const UI_Point&, UI_MouseButton)
  401. {
  402.     return FALSE;
  403. }
  404.  
  405.  
  406. bool UI_VisualObject::ViewEnter (const UI_Point&)
  407. {
  408.     return FALSE;
  409. }
  410.  
  411.  
  412. bool UI_VisualObject::ViewLeave (const UI_Point&)
  413. {
  414.     return FALSE;
  415. }
  416.  
  417. //
  418. //-------------Key Board Events-----------------
  419. //
  420.  
  421. bool UI_VisualObject::GetFocus()
  422. {
  423.     return FALSE;
  424. }
  425.  
  426.  
  427. bool UI_VisualObject::LoseFocus()
  428. {
  429.     return FALSE;
  430. }
  431.  
  432. bool UI_VisualObject::KeyTyped (char )
  433. {
  434.     return FALSE;
  435. }
  436.  
  437.  
  438. bool UI_VisualObject::MouseMove (const UI_Point& )
  439. {
  440.     return FALSE;
  441. }
  442.  
  443.  
  444. bool UI_VisualObject::Reconfigure (const UI_Rectangle&)
  445. {
  446.     return FALSE;
  447. }
  448.  
  449.  
  450. void UI_VisualObject::CloseDown ()
  451. {
  452.     if (WantToQuit ())
  453.         _Application->Destroy (this);
  454. }
  455.  
  456.  
  457. //
  458. //--------------Display Events---------------------
  459. //
  460.  
  461.  
  462.  
  463. bool UI_VisualObject::_TitleChanged (CL_Object&, long)
  464. {
  465. #if defined(__MS_WINDOWS__)
  466.     if (_handle > 0) {
  467.         SendMessage (_handle, WM_SETTEXT,  0, (long)(const char*)_title);
  468.     }
  469. #elif defined(__OS2__)
  470.     if (_handle > 0) {
  471.         WinSetWindowText (_handle, _title.AsPtr());
  472.     }
  473. #elif defined(__X_MOTIF__)
  474.     if (!_xwidget)
  475.         return TRUE; // Not yet set up
  476.     XmString xmtitle;
  477.     xmtitle = XmStringCreate ((char*)_title.AsPtr(),
  478.                               XmSTRING_DEFAULT_CHARSET);
  479.     XtVaSetValues (_xwidget, XmNlabelString, xmtitle, NULL);
  480.     XmStringFree (xmtitle);
  481.     XmUpdateDisplay (_xwidget);
  482. #endif
  483.     return TRUE;
  484. }
  485.  
  486.  
  487.  
  488. void UI_VisualObject::MakeVisible ()
  489. {
  490.     _visible = TRUE;
  491.  
  492. #if defined(__MS_WINDOWS__)
  493.     if (_handle > 0)
  494.         ShowWindow ((long) _handle, SW_SHOW);
  495.  
  496. #elif defined(__OS2__)
  497.     if (_handle > 0)
  498.         WinShowWindow (_handle, TRUE);
  499. #elif defined(__X_MOTIF__)
  500.     if (_xwidget)
  501.         XtManageChild   (_xwidget);
  502. #endif
  503. }
  504.  
  505.  
  506.  
  507. void UI_VisualObject::MakeInvisible ()
  508. {
  509.     _visible = FALSE;
  510. #if defined(__MS_WINDOWS__)
  511.     if (_handle > 0)
  512.         ShowWindow ((long)_handle, SW_HIDE);
  513. #elif defined(__OS2__)
  514.     if (_handle > 0)
  515.         WinShowWindow (_handle, FALSE);
  516. #elif defined(__X_MOTIF__)
  517.     if (_xwidget)
  518.         XtUnmanageChild (_xwidget); 
  519. #endif
  520. }
  521.  
  522.  
  523.  
  524. bool UI_VisualObject::WantToQuit()
  525. {
  526.     return TRUE;
  527. }
  528.  
  529. //
  530. //---------------other events-----------------
  531. //
  532.  
  533.  
  534.  
  535. bool UI_VisualObject::MakeVisualElement ()
  536. {
  537. #if defined(__MS_WINDOWS__)
  538.     short x = _shape.Left();
  539.     short y = _shape.Top ();
  540.     short w = _shape.Width();
  541.     short h = _shape.Height();
  542.     const char* label = (_title.Length() > 0) ? _title.AsPtr() : NULL;
  543.     const char* class_name = WindowClass ();
  544.     HINSTANCE hInst = (HINSTANCE) _Application->ProcessId();
  545.     if (!_visible)
  546.         _style &= ~WS_VISIBLE;
  547.     HWND parentHandle = _parent ? _parent->ViewHandle() : 0;
  548. //     short lowBits = _style & 0x0f;
  549. //     if (lowBits == BS_AUTORADIOBUTTON || lowBits == BS_AUTOCHECKBOX) {
  550. //         parentHandle = GetParent (parentHandle);
  551. //         if (_parent) {
  552. //             UI_Point topLeft = _parent->ClientArea().Origin();
  553. //             x += topLeft.XCoord();
  554. //             y += topLeft.YCoord();
  555. //         }
  556. //     }
  557.     _handle = CreateWindow (class_name, label, _style, x, y, w, h,
  558.                             parentHandle, _id, (HANDLE) hInst, NULL);
  559.     if (!_handle) {
  560.         CL_Error::Warning
  561.             ("YACL: VisualObject CreateWindow failed:\nClass %s ID %d",
  562.              class_name, _id);
  563.         return FALSE;
  564.     }
  565.     return TRUE;
  566.  
  567. #elif defined(__OS2__)
  568.     long ht = _YACLWindowHeight (_parent ? _parent->ViewHandle()
  569.                                 : HWND_DESKTOP);
  570.     long x = _shape.Left();
  571.     long y = ht - _shape.Top() - _shape.Height();
  572.     long w = _shape.Width();
  573.     long h = _shape.Height();
  574.     const char* label = (_title.Length() > 0) ? _title.AsPtr() : NULL;
  575.     UI_WindowClass class_name = WindowClass ();
  576.     if (!_visible)
  577.         _style &= ~WS_VISIBLE;
  578.     HWND parentHandle = _parent ? _parent->ViewHandle() : HWND_DESKTOP;
  579.     if (class_name == WC_BUTTON) {
  580.         ushort styleBits = _style & BS_PRIMARYSTYLES;
  581.         if (styleBits == BS_AUTORADIOBUTTON ||
  582.             styleBits == BS_AUTOCHECKBOX) {
  583.             UI_WindowClass pClass = _parent ? _parent->WindowClass() : 0;
  584.             if (pClass == WC_STATIC) {
  585.                 // OS/2 PM doesn't like toggle buttons as children of button
  586.                 // groups. So we have yet another hack. Oh well...
  587.                 parentHandle = _parent->_parent ? _parent->_parent->_handle
  588.                     : HWND_DESKTOP;
  589.                 x += _parent->_shape.Left();
  590.                 y += _YACLWindowHeight (parentHandle) -
  591.                     _parent->_shape.Bottom ();
  592.             }
  593.         }
  594.     }
  595.     _handle = WinCreateWindow
  596.         (parentHandle, class_name, label, _style,
  597.          x, y, w, h, parentHandle, HWND_BOTTOM, _id, NULL, NULL);
  598.     if (!_handle) {
  599.         CL_Error::Warning
  600.             ("YACL: VisualObject CreateWindow failed:\nClass %s ID %d",
  601.              class_name, _id);
  602.         return FALSE;
  603.     }
  604.     return TRUE;
  605.  
  606. #elif defined(__X_MOTIF__)
  607.  
  608.     // GNU C seems to have a strange bug, so we work around it. Instead of
  609.     // saying
  610.     //    Widget pw = (Widget) (_parent->ViewHandle());
  611.     // we say
  612.     UI_VisualObject* p = _parent;
  613.     Widget pw = (Widget) p ? p->ViewHandle() : NULL;
  614.  
  615.     CL_String instance_name = InstanceName();
  616.     const char* inst_name = instance_name.AsPtr();
  617.     struct _WidgetClassRec *class_name = WindowClass ();
  618.  
  619.     Arg arg [20];
  620.     short argn = 0;
  621.     _SetupStyle (arg, argn); // Set up the X resources
  622.  
  623.     XmString title = XmStringCreate
  624.         ((char *) _title.AsPtr (), XmSTRING_DEFAULT_CHARSET);    
  625.     XtSetArg (arg [argn], XmNlabelString, title); argn++;
  626.     _xwidget = XtCreateWidget (inst_name, class_name, pw, arg, argn);
  627.     XmStringFree (title);
  628.     XtRealizeWidget (_xwidget);
  629.     return TRUE;
  630.  
  631. #endif
  632. }
  633.  
  634.  
  635. void UI_VisualObject::_PrivateInitialize()
  636. {
  637.     _created = TRUE;
  638.     _Controller->AddEvent (new UI_Event (Event_ChildCreated, this, _parent));
  639. #if defined(__MS_WINDOWS__)
  640.     if (!_enabled)
  641.         EnableWindow   (_handle, FALSE);
  642.     if (!_visible)
  643.         ShowWindow   (_handle, SW_HIDE);
  644. //     if (Has3DLook()) {
  645. //         COLORREF color = GetSysColor (COLOR_BTNFACE);
  646. //         // We're using Ctl3d; otherwise  we would want COLOR_WINDOW
  647. //         _bgColor = UI_Color (GetRValue (color)/((float) UI_MAXCOLORS),
  648. //                              GetGValue (color)/((float) UI_MAXCOLORS),
  649. //                              GetBValue (color)/((float) UI_MAXCOLORS));
  650. //     }
  651. //     else
  652. //         _bgColor = UIColor_White; 
  653.  
  654. #elif defined(__OS2__)
  655.     if (!_enabled)
  656.         WinEnableWindow   (_handle, FALSE);
  657.     if (!_visible)
  658.         WinShowWindow   (_handle, FALSE);
  659.     _DoShowBorder (_borderShown);
  660. #elif defined(__X_MOTIF__)
  661.     if (_visible)
  662.         XtManageChild (_xwidget);
  663.     if (!_enabled)
  664.         XtSetSensitive (_xwidget, FALSE);
  665.     if (_borderShown)
  666.         XtVaSetValues (_xwidget, XmNborderWidth, 2, NULL);
  667. #endif        
  668.         
  669. #if defined(__MS_WINDOWS__)
  670.     CL_String my_name (WindowClass());
  671.     if (my_name(0,4) == "menu")  // Hack to fix menus
  672.         return;
  673.     if (_handle > 0) {
  674.         RECT msrec;
  675.         GetClientRect (_handle, &msrec);
  676.         POINT ms_pt;
  677.         ms_pt.x = ms_pt.y = 0;
  678.         HWND parentHandle = _parent ? _parent->_handle : GetDesktopWindow();
  679.         MapWindowPoints (_handle, parentHandle, &ms_pt, 1);
  680.         UI_Rectangle rec (ms_pt.x, ms_pt.y, msrec.right - msrec.left + 1,
  681.                       msrec.bottom - msrec.top + 1);
  682.         _SetShapeRectangle (rec);
  683.     }
  684. #endif
  685.  
  686.     if (_font) {
  687.         VObjBind b (this, (VObjBind::MethodPtr)
  688.                     &UI_VisualObject::_FontChanged);
  689.         _font->AddDependent (b, 1);
  690.     }
  691. }
  692.  
  693.  
  694.  
  695. bool UI_VisualObject::DestroyVisualElement()
  696. {
  697. #if defined(__MS_WINDOWS__)
  698.     if (_handle > 0 && !_parent->CreatedViaResource()) {
  699.         DestroyWindow (_handle);
  700.         return TRUE;
  701.     }
  702. #elif defined(__X_MOTIF__)
  703.     if ( _xwidget ) {
  704.         XtUnmanageChild (_xwidget);
  705.         XtDestroyWidget (_xwidget);
  706.         return TRUE;
  707.     }
  708. #elif defined(__OS2__)
  709.     WinDestroyWindow (_handle);
  710. #endif
  711.     return TRUE;
  712. }
  713.  
  714.  
  715. bool UI_VisualObject::Enable ()
  716. {
  717.     _enabled = TRUE;
  718. #if defined(__MS_WINDOWS__)
  719.     return _handle ? EnableWindow   (_handle, TRUE) : TRUE;
  720. #elif defined(__OS2__)
  721.     return _handle ? WinEnableWindow   (_handle, TRUE) : TRUE;
  722. #elif defined(__X_MOTIF__)
  723.     if (_xwidget)
  724.         XtSetSensitive (_xwidget, TRUE);
  725.     return TRUE;
  726. #endif
  727.  
  728. }
  729.  
  730.  
  731.  
  732. bool UI_VisualObject::Disable()
  733. {
  734.     _enabled = FALSE;
  735. #if defined(__MS_WINDOWS__)
  736.     return _handle ? EnableWindow (_handle, FALSE) : TRUE;
  737. #elif defined(__OS2__)
  738.     return _handle ? WinEnableWindow   (_handle, FALSE) : TRUE;
  739.  
  740. #elif defined(__X_MOTIF__)
  741.     if (_xwidget)
  742.         XtSetSensitive (_xwidget, FALSE);
  743.     return TRUE;
  744.  
  745. #endif
  746. }
  747.  
  748.  
  749. void UI_VisualObject::Invalidate ()
  750. {
  751. #if defined(__MS_WINDOWS__)
  752.     if (_handle)
  753.         InvalidateRect (_handle, NULL, TRUE);
  754. #elif defined(__OS2__)
  755.     if (_handle) {
  756.         RECTL rect;
  757.         WinQueryWindowRect (_handle, &rect);
  758.         WinInvalidateRect  (_handle, &rect, TRUE);
  759.         WinUpdateWindow    (_handle);
  760.     }
  761. #elif defined(__X_MOTIF__)
  762.     if (_xwidget && XtIsRealized (_xwidget))
  763.         XClearArea (XtDisplay (_xwidget), XtWindow (_xwidget),
  764.                     0, 0, 0, 0, TRUE);
  765. #else
  766.     NotImplemented ("Invalidate");
  767. #endif
  768. }
  769.  
  770.  
  771. #if defined(__X_MOTIF__)
  772. CL_String UI_VisualObject::InstanceName()
  773. {
  774.     if (!_instanceName.Size())
  775.         _instanceName = _Application->InstanceName (this);
  776.     return _instanceName;
  777. }
  778. #endif
  779.  
  780. bool UI_VisualObject::_ShapeRectChanged (CL_Object&, long)
  781. {
  782. #if defined(__MS_WINDOWS__)
  783.     if (_handle <= 0)
  784.         return TRUE;
  785.     RECT rect = _shape.AsMSRect ();
  786.     AdjustWindowRect (&rect, _style, FALSE);
  787.     if (Has3DLook ()) 
  788.         MoveWindow (_handle, rect.left-1, rect.top-1,
  789.                     rect.right-rect.left+3, rect.bottom-rect.top+3, TRUE);
  790.     else
  791.         MoveWindow (_handle, rect.left, rect.top,
  792.                     rect.right-rect.left+1, rect.bottom-rect.top+1, TRUE);
  793.     // Maybe this is because need to correct for Ctl3d problems. I'm not sure
  794.     // why Windows needs co-ordinates fixed up like this.
  795.     return TRUE;
  796.  
  797. #elif defined(__OS2__)
  798.     if (_handle <= 0)
  799.         return TRUE;
  800.     long ht = _YACLWindowHeight (_parent ? _parent->ViewHandle()
  801.                                 : HWND_DESKTOP);
  802.     long y = ht - _shape.Top() - _shape.Height();
  803.     WinSetWindowPos (_handle, HWND_TOP, _shape.Left(), y,
  804.                      _shape.Width(), _shape.Height(),
  805.                      SWP_SIZE | SWP_MOVE);
  806.     if (_borderHandle) {
  807.         WinSetWindowPos
  808.             (_borderHandle, HWND_TOP, _shape.Left() - 1, y - 1,
  809.              _shape.Width()+2, _shape.Height()+2, SWP_MOVE);
  810.         if (_borderShown)
  811.             WinShowWindow (_borderHandle, TRUE);
  812.     }
  813.     return TRUE;
  814. #elif defined(__X_MOTIF__)
  815.     if (!_xwidget)
  816.         return TRUE;
  817.     Position  x = _shape.Origin().XCoord();
  818.     Position  y = _shape.Origin().YCoord();
  819.     Dimension w = _shape.Width();
  820.     Dimension h = _shape.Height();
  821.     XtVaSetValues (_xwidget, XtNx, x, XtNy, y, XtNwidth, w,
  822.                    XtNheight, h, NULL);
  823.     XmUpdateDisplay (_parent ? _parent->_xwidget : _xwidget);
  824.     return TRUE;
  825. #endif
  826. }
  827.  
  828.  
  829. #if defined(__MS_WINDOWS__) || defined(__OS2__)
  830. void UI_VisualObject::TakeFocus ()
  831. {
  832.     _Controller->GiveFocusTo (*this);
  833. }
  834.  
  835. #endif
  836.  
  837.  
  838. UI_Font& UI_VisualObject::Font()
  839. {
  840.     // If someone is asking for our font, we'll assume they're trying to
  841.     // modify our font.
  842.     if (!_ownFont) {
  843.         VObjBind b (this, &UI_VisualObject::_FontChanged);
  844.         if (_font)
  845.             _font->RemoveDependent (b);
  846.         _MakeNewFont ();
  847.         if ( _displaySurface )
  848.             _displaySurface->SetFont ( _font );
  849.         _font->AddDependent (b, 1);
  850.     }
  851.     return *_font;
  852. }
  853.  
  854.  
  855.  
  856. UI_Font* UI_VisualObject::OurFont ()
  857. {
  858.     return _ownFont ? _font : _parent->OurFont();
  859. }
  860.  
  861.  
  862. bool UI_VisualObject::_FontChanged (CL_Object&, long)
  863. {
  864.     return FALSE;
  865. }
  866.  
  867. bool UI_VisualObject::SetFont (UI_Font* f)
  868. {
  869.     if (_ownFont || _font == f)
  870.         return FALSE;
  871.     VObjBind b (this, &UI_VisualObject::_FontChanged);
  872.     if (_font)
  873.         _font->RemoveDependent (b);
  874.     _font = f;
  875.     if (_font)
  876.         _font->AddDependent (b, 1);
  877.     return TRUE;
  878. }
  879.  
  880.  
  881.  
  882.  
  883. void UI_VisualObject::_MakeNewFont ()
  884. {
  885.     if (!_ownFont) {
  886.         if (_parent && _parent->_font)
  887.             _font = new UI_Font (*(_parent->_font));
  888.         else {
  889.             _font = new UI_Font (this);
  890.         }
  891.         SetFont (_font);
  892.         _ownFont = TRUE;
  893.     }
  894. }
  895.  
  896.  
  897.  
  898. void UI_VisualObject::Foreground (const UI_Color& c)
  899. {
  900.     _fgColor = c;
  901. #if defined (__X_MOTIF__)
  902.     if (!ViewHandle())
  903.         return;
  904.     UI_DwgSurfHandle hdc;
  905.     ulong h ;
  906.     XColor xcolor = c.NativeForm ();
  907.     Display *dpy = XtDisplay (_xwidget);
  908.     short screen_num = DefaultScreen (dpy);
  909.     XAllocColor (dpy, DefaultColormap (dpy, screen_num), &xcolor);
  910.     h = xcolor.pixel;
  911.     if (!_displaySurface) {
  912.         XGCValues xvalues;
  913.         hdc = XCreateGC (dpy, XtWindow (_xwidget), 0, &xvalues);
  914.         XSetForeground (XtDisplay (_xwidget), hdc, h);
  915.         XFreeGC (XtDisplay (_xwidget), hdc);
  916.     }
  917.     else {
  918.         hdc = _displaySurface->Handle();
  919.         XSetForeground (XtDisplay (_xwidget), hdc, h);
  920.     }
  921. //    if (!_displaySurface) {
  922. //         XGCValues xvalues;
  923. //         XColor xcolor = c.NativeForm ();
  924. //         Display *dpy = XtDisplay (_xwidget);
  925. //         short screen_num = DefaultScreen (dpy);
  926. //         hdc = XCreateGC (dpy, XtWindow (_xwidget), 0, &xvalues);
  927. //         XAllocColor (dpy, DefaultColormap (dpy, screen_num), &xcolor);
  928. //         h = xcolor.pixel;
  929. //         XSetForeground (XtDisplay (_xwidget), hdc, h);
  930. //         XFreeGC (XtDisplay (_xwidget), hdc);
  931. //     }
  932. //     else {
  933. //         hdc = _displaySurface->Handle();
  934. //         h   = (_displaySurface->ColorMap().Match (c));
  935. //         XSetForeground (XtDisplay (_xwidget), hdc, h);
  936. //     }
  937. #endif
  938. }
  939.  
  940.  
  941.  
  942. void UI_VisualObject::Background (const UI_Color& c)
  943. {
  944.     _bgColor = c;
  945. #if defined (__MS_WINDOWS__)
  946.     if (_displaySurface) {
  947.         HDC hdc = _displaySurface->Handle();
  948.         if (hdc)
  949.             SetBkColor (hdc, c.NativeForm ());
  950.     }
  951.     
  952. #elif defined (__X_MOTIF__)
  953.     ulong h ;
  954.     UI_DwgSurfHandle hdc;
  955.     //    if (_displaySurface == NULL) {
  956.         XGCValues xvalues;
  957.         XColor xcolor = c.NativeForm ();
  958.         Display *dpy = XtDisplay (_xwidget);
  959.         short screen_num = DefaultScreen (dpy);
  960.         hdc = XCreateGC (dpy, XtWindow (_xwidget), 0, &xvalues);
  961.         XAllocColor (dpy, DefaultColormap (dpy, screen_num), &xcolor);
  962.         h = xcolor.pixel;
  963.         XSetBackground (XtDisplay (_xwidget), hdc, h);
  964.         XFreeGC (XtDisplay (_xwidget), hdc);
  965. //     }
  966. //     else {
  967. //         hdc = _displaySurface->Handle();
  968. //         h   = (_displaySurface->ColorMap().Match (c));
  969. //         XSetBackground (XtDisplay (_xwidget), hdc, h);
  970. //     }
  971. #endif
  972. }
  973.  
  974.  
  975.  
  976. #if defined(__X_MOTIF__)
  977. void UI_VisualObject::_SetupStyle (void* p, short& argn)
  978. {
  979.     argn = 0;
  980.     Arg* arg = (Arg*) p;
  981.  
  982.     short x = _shape.Left   ();
  983.     short y = _shape.Top    ();
  984.     short w = _shape.Width  ();
  985.     short h = _shape.Height ();
  986.  
  987.     XtSetArg (arg [ argn ], XtNx,     x); argn++;
  988.     XtSetArg (arg [ argn ], XtNy,     y); argn++;
  989.     XtSetArg (arg [ argn ], XtNheight,h); argn++;
  990.     XtSetArg (arg [ argn ], XtNwidth, w); argn++;
  991.     if (_borderShown)
  992.         XtSetArg (arg [ argn++ ], XmNborderWidth, 2);
  993. }
  994. #endif
  995.  
  996. #if defined (__MS_WINDOWS__)
  997. void UI_VisualObject::SetStyle (ulong style)
  998. {
  999.     _style = style;
  1000. }
  1001. #endif
  1002.  
  1003. bool UI_VisualObject::AddEventDependent
  1004.     (UI_EventType evt, const CL_AbstractBinding& bind, long p)
  1005. {
  1006.     if (!_eventDependents)
  1007.         _eventDependents = new CL_IntPtrMap;
  1008.     if (!_eventDependents)
  1009.         return FALSE; // No memory
  1010.     CL_ClientSet* set = (CL_ClientSet*) (*_eventDependents)[(long) evt];
  1011.     if (!set) {
  1012.         set = new CL_ClientSet;
  1013.         if (!set)
  1014.             return FALSE; // No memory
  1015.         _eventDependents->Add ((long) evt, set);
  1016.     }
  1017.     return set->Add (bind, p);   
  1018. }
  1019.  
  1020.  
  1021.  
  1022. bool UI_VisualObject::RemoveEventDependent
  1023.     (UI_EventType evt, const CL_AbstractBinding& bind)
  1024. {
  1025.     if (!_eventDependents)
  1026.         return FALSE;
  1027.     CL_ClientSet* set = (CL_ClientSet*) (*_eventDependents)[(long) evt];
  1028.     if (!set)
  1029.         return FALSE;
  1030.     return set->Remove (bind);
  1031. }
  1032.  
  1033.  
  1034. bool UI_VisualObject::IsIconified ()
  1035. {
  1036.     return _parent && _parent->IsIconified();
  1037. }
  1038.  
  1039.  
  1040. bool UI_VisualObject::ShowBorder ()
  1041. {
  1042.     return _DoShowBorder (TRUE);
  1043. }
  1044.  
  1045.  
  1046. bool UI_VisualObject::HideBorder ()
  1047. {
  1048.     return _DoShowBorder (FALSE);
  1049. }
  1050.  
  1051. void UI_VisualObject::ScrollView
  1052.     (const UI_Rectangle& scrollArea, short xAmount, short yAmount)
  1053. {
  1054. #if defined(__MS_WINDOWS__)
  1055.     if (_handle) {
  1056.         UpdateWindow (_handle);
  1057.         RECT r = scrollArea.AsMSRect();
  1058.         ScrollWindow (_handle, xAmount, yAmount, &r, NULL);
  1059.     }
  1060. #elif defined(__OS2__)
  1061.     if (_handle) {
  1062.         UI_Rectangle area = ClientArea ();
  1063.         RECTL rect;
  1064.         rect.xLeft    = scrollArea.Left();
  1065.         rect.yBottom  = area.Height() - scrollArea.Bottom () + 1;
  1066.         rect.xRight   = scrollArea.Right();
  1067.         rect.yTop     = area.Height() + 1 - scrollArea.Top ();
  1068.         WinScrollWindow (_handle, xAmount, yAmount, &rect, NULL, NULLHANDLE,
  1069.                          NULL, SW_INVALIDATERGN);
  1070.     }
  1071. #elif defined(__X_MOTIF__)
  1072.     NotImplemented ("ScrollView");
  1073. #endif
  1074. }
  1075.  
  1076.  
  1077. bool UI_VisualObject::_DoShowBorder (bool shown)
  1078. {
  1079.     _borderShown = shown;
  1080. #if defined(__MS_WINDOWS__)
  1081.     if (_handle > 0)
  1082.         _style = GetWindowLong (_handle, GWL_STYLE);
  1083.     _style = shown ? (_style | WS_BORDER) : (_style & ~WS_BORDER);
  1084.     if (_handle > 0) {
  1085.         SetWindowLong (_handle, GWL_STYLE, _style);
  1086.         SetWindowPos  (_handle, NULL, 0, 0, 0, 0, SWP_SHOWWINDOW | 
  1087.                        SWP_NOSIZE | SWP_NOMOVE | 
  1088.                        SWP_NOACTIVATE | SWP_NOZORDER); // Force re-draw
  1089.     }
  1090. #elif defined(__OS2__)
  1091.     if (!shown) {
  1092.         if (_borderHandle)
  1093.             WinShowWindow (_borderHandle, FALSE);
  1094.     }
  1095.     else {
  1096.         if (!_parent)
  1097.             return FALSE; // Don't care about root window
  1098.         HWND parentHandle = _parent->ViewHandle();
  1099.         if (!_borderHandle)
  1100.             _borderHandle = WinCreateWindow
  1101.                 (parentHandle, WC_STATIC, NULL, WS_VISIBLE | SS_FGNDFRAME,
  1102.                  _shape.Left() - 1,
  1103.                  _YACLWindowHeight (parentHandle) - _shape.Bottom() - 2,
  1104.                  _shape.Width()+2, _shape.Height()+2, parentHandle,
  1105.                  HWND_BOTTOM, 0, NULL, NULL);
  1106.         WinShowWindow (_borderHandle, TRUE);
  1107.     }
  1108. #elif defined(__X_MOTIF__)
  1109.     if (_xwidget) {
  1110.         XtVaSetValues (_xwidget, XmNborderWidth, shown ? 2 : 0, NULL);
  1111.     }
  1112. #endif
  1113.     return TRUE;
  1114. }
  1115.  
  1116.  
  1117. bool UI_VisualObject::_PrivateHandleEvent (UI_Event* e)
  1118. {
  1119.     if (e->Type() == Event_Reconfigure) {
  1120.         _SetShapeRectangle (e->curPos);
  1121.     }
  1122.     bool b = HandleEvent (e);
  1123.     bool p = TRUE;
  1124.     if (_eventDependents) {
  1125.         CL_ClientSet* set = (CL_ClientSet*) (*_eventDependents)[e->Type()];
  1126.         if (set)
  1127.             p = set->Permits (*e);
  1128.     }
  1129.     // b will be TRUE if this object itself handled the event. p will be
  1130.     // TRUE if all the event dependents permitted the event to proceed up
  1131.     // the view tree, because none of them handled it.
  1132.     return b || !p; // If none of the dependents handled the event, they
  1133.                     // will all return TRUE, so we return FALSE.
  1134. }
  1135.  
  1136.  
  1137.  
  1138. void UI_VisualObject :: _SetModelValue (const CL_Object& value)
  1139. {
  1140.     CL_Object* model = _model;
  1141.     if ( !model )
  1142.         return;
  1143.     VObjBind bnd (this, &UI_VisualObject::_ModelChanged);
  1144.     model->RemoveDependent (bnd);
  1145.     *model = value;
  1146.     model->AddDependent (bnd, 1);
  1147. }
  1148.  
  1149.  
  1150. #if defined(__OS2__)
  1151. long _YACLWindowHeight (UI_ViewHandle h)
  1152. {
  1153.     RECTL windowRect;
  1154.     if (!WinQueryWindowRect (h, &windowRect))
  1155.         return 0;
  1156.     return windowRect.yTop - windowRect.yBottom + 1;
  1157. }
  1158.  
  1159. #endif
  1160.