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

  1.  
  2.  
  3. #ifndef _controller_h_
  4. #define _controller_h_
  5.  
  6.  
  7.  
  8.  
  9.  
  10. /*
  11.  *
  12.  *          Copyright (C) 1994, M. A. Sridhar
  13.  *  
  14.  *
  15.  *     This software is Copyright M. A. Sridhar, 1994. You are free
  16.  *     to copy, modify or distribute this software  as you see fit,
  17.  *     and to use  it  for  any  purpose, provided   this copyright
  18.  *     notice and the following   disclaimer are included  with all
  19.  *     copies.
  20.  *
  21.  *                        DISCLAIMER
  22.  *
  23.  *     The author makes no warranties, either expressed or implied,
  24.  *     with respect  to  this  software, its  quality, performance,
  25.  *     merchantability, or fitness for any particular purpose. This
  26.  *     software is distributed  AS IS.  The  user of this  software
  27.  *     assumes all risks  as to its quality  and performance. In no
  28.  *     event shall the author be liable for any direct, indirect or
  29.  *     consequential damages, even if the  author has been  advised
  30.  *     as to the possibility of such damages.
  31.  *
  32.  */
  33.  
  34.  
  35.  
  36. // Authors:   M. A. Sridhar
  37. //            N. Bhowmik
  38.  
  39.  
  40. #if defined(__GNUC__)
  41. #pragma interface
  42. #endif
  43.  
  44.  
  45. #include "base/tree.h"
  46. #include "base/objset.h"
  47.  
  48. #include "ui/visualob.h"
  49. #include "ui/rectangl.h"
  50. #include "ui/event.h"
  51. #include "ui/applic.h"
  52. #include "ui/cursor.h"
  53.  
  54. // The Controller   class encapsulates the object  creation/disposal, event
  55. // capturing/dispatching   details of a  YACL    application.  In any  YACL
  56. // application, there    can   be  only   one    instance  of   the   class
  57. // UI_Controller. This class owns and manages the central event queue.  All
  58. // hard events are captured and added to the queue by this class while soft
  59. // events generated  by other YACL objects are also added by it.  All event
  60. // dispatching and disposal is taken care of by this class. In other words,
  61. // any YACL object is free to create an  event and add it  to the queue via
  62. // the controller. The disposal of this event,  after it has been processed
  63. // is the controller's responsibility.  Similarly, all  object  disposal is
  64. // also taken care of by the controller. As documented elsewhere, YACL does
  65. // not allow  static  objects. Nor does  it  allow explicit  deletion.  Any
  66. // object      that  needs  to      be     destroyed must    be    sent  an
  67. // Event_Destroy or Event_Quit. The controller ensures that the object and ALL
  68. // its  children are  then destroyed. It does  so by maintaining  a tree of
  69. // all visual objects in the application.
  70. // 
  71. // In addition to  event and object management,  the controller also  provides
  72. // methods for handling the mouse and keyboard.
  73.  
  74.  
  75.  
  76. class CL_EXPORT UI_MenuItem;
  77.  
  78. class CL_EXPORT UI_Controller: public CL_Object {
  79.  
  80. public:
  81.  
  82.     UI_Controller (UI_Application* appl);
  83.  
  84.     ~UI_Controller ();
  85.  
  86.  
  87.     //
  88.     //----------Controller Services/events provided to a  VisualObject  
  89.     //          
  90.  
  91.     //
  92.     // -------------Mouse Control----------------------------
  93.     //
  94.     
  95.     void GiveMouseTo (const UI_VisualObject& aView);
  96.     // Direct all mouse events to aView irrespective of cursor position.
  97.  
  98.     void ReleaseMouse ();
  99.     // Stop directing all mouse events to a particular view.
  100.  
  101.  
  102.    
  103.  
  104.     //
  105.     //--------------KeyBoard Control-------------------
  106.     //
  107.     
  108.     void GiveFocusTo (const UI_VisualObject& v);
  109.     // Direct all keyboard events to v.
  110.  
  111.     // ----------------------- Cursor display -----------------------
  112.  
  113.     void BeginWait ();
  114.     // Begin a ``wait state'' by displaying the platform-specific wait
  115.     // cursor. Until {\tt EndWait} is called, the mouse cursor will not change.
  116.  
  117.     void EndWait ();
  118.     // End the wait state begun by {\tt BeginWait}.
  119.  
  120.     //
  121.     //----------------Modal Input--------------------------
  122.     //
  123.  
  124.      
  125.     void Beep ();
  126.     // Provide a short beep.
  127.     
  128.     // ----------------- Event methods -------------------
  129.  
  130.     void EventLoop (CL_AbstractBinding* termination = NULL,
  131.                     CL_AbstractBinding* eventFilter = NULL);
  132.     // A  generalized event loop that does the following: retrieve an event,
  133.     // invoke eventFilter on that event, and dispatch the event if
  134.     // eventFilter returns TRUE. Then consult the termination binding with
  135.     // the event as parameter, and stop the loop if it returns TRUE.
  136.     //
  137.     //    The default value of both parameters is NULL; a NULL termination
  138.     // binding is assumed to always return FALSE, while a NULL eventFilter
  139.     // binding is assumed to always return TRUE.
  140.     
  141.     void Run ();
  142.     // The {\tt Run} method is simply a convenient way of running the
  143.     // {\tt EventLoop} until the app gets a Quit event. 
  144.  
  145.     void DispatchPendingEvents ();
  146.     // Dispatch all pending hard events. Must be called periodically when in
  147.     // long processing loops when a progress dialog needs to be maintained.
  148.  
  149.     void AddEvent (UI_Event* );
  150.     // Add an event to the event queue.
  151.  
  152.     // ----------------------- View methods ----------------------
  153.     
  154.     UI_CompositeVObject* Root () {return _root;};
  155.     // Return the root of the view tree.
  156.  
  157.     CL_ObjectSequence ChildrenOf (const UI_VObjCollection& o);
  158.     // Return the children of the given VObjCollection as an
  159.     // ObjectSequence. Each cell in this sequence can be cast down to {\tt
  160.     // UI_VisualObject*}. 
  161.     
  162.     CL_IntegerTree* ViewTree ();
  163.     // Return a pointer to the view tree.
  164.  
  165.     UI_VisualObject* operator[] (UI_ViewHandle); 
  166.     // Return the visual object with the given handle.
  167.  
  168.     UI_VisualObject* VObjUnderMouse() const {return _current;};
  169.     // Return the visual object over which the mouse is currently
  170.     // positioned.
  171.     
  172.     void MakeTopWindow (UI_CompositeVObject* root);
  173.     // Make {\tt root} the main window of the application. Must be called
  174.     // only once, at the beginning of the application.
  175.  
  176.     bool Destroy (UI_VisualObject* aView);
  177.     // Invoke the destructor of the view and those of the subtree rooted
  178.     // at it, if any.
  179.  
  180.     long GetNextWidgetCount ();
  181.  
  182.     UI_VisualObject* Focus () {return _focus;};
  183.     // Return the VisualObject that currently has focus.
  184.     
  185.     
  186. #if defined(__MS_WINDOWS__)
  187.     short Initialize (HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdln,
  188.                       short nCmdShow);
  189.     // [MS/Windows-specific method]
  190.     
  191. #elif defined(__OS2__)
  192.     short Initialize ();
  193.     // [OS/2-specific method]
  194.  
  195. #elif defined(__X_MOTIF__)
  196.     short Initialize (int& argc,char *argv[]);
  197.     // [X-windows-specific method]
  198.  
  199.     struct _WidgetRec* ShellWidget () { return _shell; };
  200.     // [X-windows-specific method] For YACL internal use only.
  201.  
  202.     Display* AppDisplay ();
  203.     // [X-windows-specific method] For YACL internal use only.
  204.  
  205. #endif
  206.  
  207.     const char* ClassName () const { return "UI_Controller";};
  208.  
  209. protected:
  210.  
  211.     // ------- General event methods --------------
  212.  
  213.  
  214.     bool ProcessSoftEvent (UI_Event* e);
  215.  
  216.     bool DispatchEvent (UI_Event* e);
  217.  
  218.  
  219.     bool ProcessNativeEvents ();
  220.     // ProcessNativeEvent: retrieve an event from the underlying window
  221.     // system and process it if the eventFilter allows the processing.
  222.     // Return TRUE if an event was available to 
  223.     // process, and FALSE if not.
  224.  
  225.     void DispatchSoftEvents ();
  226.     
  227.     UI_Event* RemoveEvent ();
  228.     // Remove an event from the queue and return it.
  229.  
  230.  
  231.     //
  232.     // Instance variables:
  233.     //
  234.  
  235.     UI_CompositeVObject* _root; 
  236.     CL_IntegerTree*      _viewTree; // Maintains all views in their proper
  237.                                     // hierarchical order
  238.  
  239.     CL_ObjectSequence*   _eventQueue;  // Queue of events
  240.     UI_VisualObject*     _current;  // Object that is currently under the
  241.                                     // mouse (not necessarily has focus)
  242.     
  243.     CL_IntPtrMap         _visualObjMap;
  244.     UI_VisualObject*     _focus; // The object currently in focus
  245.  
  246.  
  247. #if defined(__MS_WINDOWS__)
  248.     HANDLE hInst;    
  249.     HANDLE hPrevInst;
  250. #elif defined(__X_MOTIF__)
  251.     struct _WidgetRec*   _shell;
  252.     ulong                _grabWindow;
  253.     CL_ObjectSet         _uninitedObjs; // Uninitialized windows
  254.     
  255.     
  256. #endif
  257.     short widgetCount;
  258.  
  259. private:
  260.     void _InitController ();
  261.  
  262.     void FlushEventQueue ();
  263.     // Eat all the pending events that the platform has sent.
  264.     
  265.     bool DisposeNode (const CL_Object&, long);
  266.     // Destroy a view (used for traversing the view tree).
  267.  
  268.     bool RootDestroyed (CL_Object&, long);
  269.     // Are we finished? (The parameters are dummy, needed in order to use
  270.     // this method in a binding.)
  271.  
  272.     bool TranslateNativeEvent (NativeEventStruct& msg, UI_Event& event);
  273.     // Translate the native even into a YACL event. Return TRUE if a knwon
  274.     // event, FALSE otherwise.
  275.  
  276.     bool DispatchNativeEvent (UI_Event& e);
  277.     // Dispatch the event. Return FALSE if default processing must be done
  278.     // after this, TRUE otherwise. Most events require default processing
  279.     // to be done; the one exception is when a window refuses to be closed.
  280.  
  281. #if defined(__MS_WINDOWS__)
  282.     bool _DoOneEvent (NativeEventStruct&, UI_Event&);
  283.     // [MS-Windows-specific, internal use only]
  284.     
  285.     void _MakeWindowsInterface (const UI_Event& e);
  286.     // [MS-Windows-specific, internal use only]
  287.     
  288.     friend long FAR PASCAL YACLWindowProc (HWND ,unsigned, WORD, LONG);
  289.     // [MS-Windows-specific]
  290.     
  291.     friend long FAR PASCAL YACLDialogProc (HWND ,unsigned, WORD, LONG);
  292.     // [MS-Windows-specific]
  293.  
  294.     friend long FAR PASCAL _export YACLBtnGroupProc
  295.         (HWND hwnd, unsigned msg, WORD wParam, LONG lp);
  296.     // [MS-Windows-specific]
  297.     
  298.     long WindowProc (HWND hwnd, unsigned msg, WORD wParam, LONG lp);
  299.     // [MS-Windows-specific]
  300.     
  301.     long DialogProc (HWND hwnd, unsigned msg, WORD wParam, LONG lp);
  302.     // [MS-Windows-specific]
  303.     
  304.     long BtnGroupProc (HWND hwnd, unsigned msg, WORD wParam, LONG lp);
  305.     // [MS-Windows-specific]
  306.  
  307.     CL_PtrIntMap         _menuMap;
  308.     ulong                _buttonFaceBrush;
  309.  
  310. #elif defined(__OS2__)
  311.     HAB  _hab;
  312.     HMQ  _hmq;
  313.     
  314.     void _AbortPMApp (const char* errMsg);
  315.  
  316.     bool _DoOneEvent (NativeEventStruct&);
  317.     // [OS/2-specific, internal use only]
  318.     
  319.     void _MakeOS2Interface (const UI_Event& e);
  320.     // [OS/2-specific, internal use only]
  321.     
  322.     friend MRESULT EXPENTRY YACLWindowProc (HWND hWnd, ULONG msg, MPARAM p1,
  323.                                             MPARAM p2);
  324.     
  325. #elif defined(__X_MOTIF__)
  326.     bool _DoOneEvent (NativeEventStruct&);
  327.     // [X-windows-specific, internal use only]
  328.  
  329.     void _MakeXInterface (const UI_Event& e);
  330.     // [X-Windows-specific, internal use only]
  331.     
  332. #endif
  333.  
  334.     UI_Cursor            _defaultCursor;
  335.     bool                 _inWaitState;
  336.     CL_AbstractBinding*  _eventFilter;
  337.     CL_AbstractBinding*  _termination;
  338.     
  339.  
  340. public:
  341.     void Register (UI_VisualObject* view);
  342.     // [Internal use only]
  343.     // Add a view to the visual object tree  as child of view->Parent(). If
  344.     // parent is NULL, this method assumes that the root is being created,
  345.     // and that the parameter is a composite.
  346.  
  347.     bool SetCurrentCursor (UI_Cursor&);
  348.     // [Internal use only] Set the current cursor being shown. Return TRUE
  349.     // if a cursor was set,  FALSE otherwise.
  350.     
  351. #if defined(__MS_WINDOWS__)
  352.     bool MenuItemCreated   (UI_MenuItem* item);
  353.     // [MS-Windows-specific, for internal use only]
  354.  
  355.     bool MenuItemDestroyed (UI_MenuItem* item);
  356.     // [MS-Windows-specific, for internal use only]
  357.  
  358. #elif defined(__OS2__)
  359.     HAB AnchorBlockHandle () const;
  360.     // [OS/2-specific, for internal use only]
  361.     
  362.     HMQ MessageQueueHandle() const;
  363.     // [OS/2-specific, for internal use only]
  364.     
  365. #elif defined(__X_MOTIF__)
  366.     typedef char* String;
  367.     static void XEventHandler (struct _WidgetRec* w, void *, XEvent* xevent,
  368.                                char *);
  369.     // [X-windows-specific; internal use only]
  370.  
  371.     static void LButtonDouble (struct _WidgetRec*,
  372.                                XEvent*, String*, unsigned int*);
  373.     // [X-windows-specific; internal use only]
  374.     
  375.     static void MButtonDouble (struct _WidgetRec*,
  376.                                XEvent*, String*, unsigned int*);
  377.     // [X-windows-specific; internal use only]
  378.     
  379.     static void RButtonDouble (struct _WidgetRec*,
  380.                                XEvent*, String*, unsigned int*);
  381.     // [X-windows-specific; internal use only]
  382.  
  383.     ulong RegisterTimeOut (long msec, void (*function) (void*, ulong*),
  384.                            void* client_data);
  385.     // [X-windows-specific; internal use only]
  386.  
  387.     void UnregisterTimeOut (ulong);
  388.     // [X-windows-specific; internal use only]
  389.  
  390.  
  391.     
  392. #endif
  393.  
  394. };
  395.  
  396.  
  397. inline CL_IntegerTree* UI_Controller::ViewTree ()
  398. {
  399.     return _viewTree;
  400. }
  401.  
  402.  
  403.  
  404. #if defined(__OS2__)
  405. inline HAB UI_Controller::AnchorBlockHandle () const
  406. {
  407.     return _hab;
  408. }
  409.  
  410. inline HMQ UI_Controller::MessageQueueHandle () const
  411. {
  412.     return _hmq;
  413. }
  414.  
  415. #endif
  416.  
  417. #endif
  418.  
  419.