
#ifndef _composit_h_
#define _composit_h_





/*
 *
 *          Copyright (C) 1995, M. A. Sridhar
 *  
 *
 *     This software is Copyright M. A. Sridhar, 1995. You are free
 *     to copy, modify or distribute this software  as you see fit,
 *     and to use  it  for  any  purpose, provided   this copyright
 *     notice and the following   disclaimer are included  with all
 *     copies.
 *
 *                        DISCLAIMER
 *
 *     The author makes no warranties, either expressed or implied,
 *     with respect  to  this  software, its  quality, performance,
 *     merchantability, or fitness for any particular purpose. This
 *     software is distributed  AS IS.  The  user of this  software
 *     assumes all risks  as to its quality  and performance. In no
 *     event shall the author be liable for any direct, indirect or
 *     consequential damages, even if the  author has been  advised
 *     as to the possibility of such damages.
 *
 */



/*
  Authors:   M. A. Sridhar
             N. Bhowmik
*/


#if defined(__GNUC__)
#pragma interface
#endif



#include "base/intseq.h"


#include "ui/vobjcoll.h"
#include "ui/event.h"


class YACL_UI UI_Menu;
class YACL_UI UI_MenuBar;

// CompositeVObject is an object whose visual representation is a window on
// which other visual objects can be placed. The other objects so placed
// are thought of as children of the Composite. Thus the Composite
// provides the heterogeneous composition mechanism in YACL. Typical
// applications for the Composite are modeless and modal dialogs. The
// CompositeVObject's {\tt operator[]} allows access to its children via
// their view id. The Composite manages the setting of focus on its
// children when the user types the TAB (or SHIFT-TAB) key.
//
// From another viewpoint, a CompositeVObject can be thought of as
// essentially a
// mechanism for accessing its child VisualObjects via their ViewID's.
//
// A CompositeVObject can be a ``sticky'' child of its parent, in which case
// it moves and scrolls with its parent; or it can be ``non-sticky'', in
// which case it can have its own title and menu bar.
//
// The children of a CompositeVObject may be drawn anywhere; however, only
// those that are within its client area (and have not been made invisible by
// the programmer) will be visible.
//
// A Composite can be created with an array of descriptors of its
// children. When so created, the Composite creates all of the children
// described by those descriptors. When the Composite is destroyed, these
// children are all destroyed; in fact, so is the entire subtree of the view
// tree rooted at the Composite being destroyed.
//
// A Composite may have other Composites as its children (although this
// doesn't always seem to work under MS-Windows, possibly because of a
// Windows bug.) 
//
// In response to each event in the windowing
// system, the controller first sends the event to its destination (e.g.,
// when the mouse is clicked on a button, a click event is sent to the
// button) by invoking the destination's {\tt HandleEvent} method.
// Then, the event is sent to the each of the ancestors of the destination
// in the view tree, in order from leaf to root, via their {\tt
// HandleChildEvent} methods. This allows a Composite to inspect events
// that occur in its children by overriding
// the {\tt HandleChildEvent} and taking the necessary action.
//
// If a CompositeVObject is non-sticky, then calling its HideBorder() method
// displays a thin border but hides its sizing border so that the
// CompositeVObject cannot be resized. Note that under
// X/Motif, calling HideBorder or ShowBorder after the Composite has been
// displayed has no effect. You must call it before the window is displayed,
// i.e., either immediately after creating the window or in a derived class
// constructor.


#if defined(__OS2__) && defined(__IBMCPP__)
MRESULT EXPENTRY CallBackFrameProc (HWND hWnd, ULONG msg,
                                    MPARAM p1, MPARAM p2);
#endif

class YACL_UI UI_CompositeVObject: public UI_VObjCollection {

public:

    // ---------------------- Construction ----------------------------

    UI_CompositeVObject (UI_CompositeVObject* parent,
                         const UI_Rectangle& shape, UI_ViewID id = -1);
    // Create a non-sticky CompositeVObject as child of {\tt parent}, with
    // position and size described by {\tt shape} and view id {\tt id}.
    
    UI_CompositeVObject (UI_CompositeVObject* parent,
                         UI_ViewDescriptor* vd, bool sticky = FALSE,
                         const UI_Rectangle& shape = UI_Rectangle (),
                         UI_ViewID id = -1);
    // Descriptor-based construction: the second parameter points to an
    // array of ViewDescriptor structures (see {\tt viewdesc.h}, the last of
    // which has type set to
    // View_None. The data structure pointer to by {\tt vd} is ``borrowed'' for
    // reading by this composite object, and therefore may not be destroyed
    // until the Composite becomes visible. (But the Composite does not
    // write into the {\tt vd} data structure.) The parameter "sticky"
    // indicates whether this composite sticks to its parent's surface, and
    // moves along with the parent; if it is FALSE, the Composite appears as a
    // separate window with its own caption bar. (Composites that stick to
    // parent composites seem to behave erroneously under MS-Windows,
    // perhaps because of a Windows bug?)


#if defined(__MS_WINDOWS__) || defined(__MS_WIN32__)
    UI_CompositeVObject (UI_CompositeVObject* parent,
                         const char* resource_name, UI_ViewID id = -1);
    // Resource-based construction: currently supported only under
    // MS-Windows. This creates a non-sticky composite.

#endif

    // ------------------- View-related methods ---------------

    UI_Rectangle WindowShape () const;
    // Return the view area of this Composite, in screen co-ordinates
    // (measured in pixels), including any window decorations such as border
    // and title bar.  This method functions correctly under MS-Windows and
    // OS/2 but is window-manager-dependent under X windows.
    
    virtual void ShowTitleBar ();
    // Show the title bar. This only works for non-sticky Composites. It
    // must be called before the Composite is displayed, e.g., either
    // immediately after it is constructed or in a derived class
    // constructor. By default, a non-sticky Composite shows its title bar.

    virtual void HideTitleBar ();
    // Hide the title bar. This only works for non-sticky Composites. It
    // must be called before the Composite is displayed, e.g., either
    // immediately after it is constructed or in a derived class constructor.


    virtual bool IsTitleBarShown ();
    // Return TRUE if the title bar is currently shown.
    
    virtual bool IsIconified () {return _iconified;};
    // Return TRUE if this Composite is currently iconified.

    bool SticksToParent () const {return _stickToParent;};
    // Return TRUE if this is a ``sticky'' Composite.

    virtual void MakeInvisible ();
    // Make this Composite and all its descendants invisible. This method
    // overrides the inherited one.

    virtual void MakeVisible ();
    // Make this Composite and all its descendants visible. This method
    // overrides the inherited one.

    void SetMinSize (short width, short height)
        {SetMinWidth (width); SetMinHeight (height);};
    // Set the minimum size of this Composite to {\tt width} pixels by {\tt
    // height} pixels.
    
    void SetMaxSize (short width, short height)
        {SetMaxWidth (width); SetMaxHeight (height);};
    // Set the maximum size of this Composite to {\tt width} pixels by {\tt
    // height} pixels.

    virtual void SetMinWidth (short w);
    // Set the minimum width  to {\tt w} pixels.
    
    virtual void SetMinHeight (short h);
    // Set the minimum height to {\tt h} pixels.
    
    virtual void SetMaxWidth (short w);
    // Set the maximum width  to {\tt w} pixels.
    
    virtual void SetMaxHeight (short h);
    // Set the maximum height to {\tt h} pixels.

    short MinWidth  () const {return _minWidth;}
    // Return the current minimum width in pixels.

    short MinHeight () const {return _minHeight;}
    // Return the current minimum height in pixels.

    short MaxWidth  () const {return _maxWidth;}
    // Return the current maximum width in pixels.

    short MaxHeight () const {return _maxHeight;}
    // Return the current maximum height in pixels.

    
#if defined(__MS_WINDOWS__) || defined(__MS_WIN32__)
    virtual void Set3DLook ();
    // [MS-Windows-specific] Use the Microsoft 3-dimensional look on this
    // Composite  and all its descendants. This method must be called
    // before the Composite is displayed.

    bool Has3DLook () const;
    // [MS-Windows-specific] Does this Composite have a 3-d look?

#endif
    // -------------------- Subview manipulation ---------------------
    
    virtual UI_VisualObject*  CreateChild (const UI_ViewDescriptor& vd);
    //  Create a child with given descriptor, and return a pointer to it.
    //  This array cannot include any ExOrToggleButton descriptors.
    
    virtual UI_VisualObject* RemoveChild (UI_VisualObject* view);
    // Remove the given VisualObject from the Composite and
    // return it. The caller must destroy the returned object via the
    // Application's Destroy method.

    // ------------------ Convenience methods ----------------------

    CL_Object& Model ();
    // The returned model is an IntPtrMap whose keys are the view id's of
    // the children, and whose values are pointers to the corresponding
    // model objects.
    
#if defined(__MS_WINDOWS__) || defined(__MS_WIN32__)
    bool CreatedViaResource () {return _rname.Size() > 0;};
    // [MS-Windows-specific] Return TRUE if this object was created using a
    // resource name.

#endif
    // --------------------- Menu methods ---------------------------
    
    UI_MenuBar* MenuBar () const;
    // Return the menu used by this composite. Return NULL if there is no
    // associated menu.

    
    // ---------------------- Basic methods -----------------------

    virtual UI_WindowClass WindowClass () const;
    
    const char* ClassName() const { return "UI_CompositeVObject";};


protected:
    

    ~UI_CompositeVObject();
    // Destructor: clean up all local data structures. SHould never be
    // called directly, since the COntroller takes care of destroying visual
    // objects. 

    virtual bool MakeVisualElement ();
    // Overrides the inherited method.
    
    // 
    // Composite method for child event inspection:
    // 

    virtual bool HandleChildEvent (const UI_Event& e);
    // This is a hook for inspecting and processing any event originating
    // in any of the children and passed up to this
    // Composite. The default implementation does nothing and
    // returns FALSE.

    
    bool DestroyVisualElement ();
    // Destroy the visual element for this Composite. This overrides the
    // inherited method.

    void initSimple (UI_VisualObject*);

    void _PrivateInitialize();
    // Internal use only.



#if defined(__X_MOTIF__)
    _WidgetRec* _mainWindow;
    _WidgetRec* _shell;
    static void DeleteWindowCallback (struct _WidgetRec* w,
                                      void* client, void* call);
    // [X-windows-specific, for YACL internal use only]
    
    virtual bool _CursorChanged();
    // [X-Motif-specific, YACL internal use only] Called when the
    // application changes this VisualObject's cursor.
    
#endif
    
public:

    // -------------- For YACL internal use only -----------------
    
#if defined(__X_MOTIF__)
    UI_ViewHandle MainWindowHandle () { return _mainWindow;};
    // [X-windows-specific, YACL internal use only]
    
    UI_ViewHandle ShellHandle () { return _shell;};
    // [X-windows-specific, YACL internal use only]

    virtual void Realized ();
    // [X-windows-specific, YACL internal use only] Called by the Controller
    // when this Composite has a shell that has been realized.

#endif
    
#if defined(__MS_WINDOWS__) || defined(__MS_WIN32__)
    bool CreateResourceChild (UI_ViewHandle, const CL_String& name);
    //  [YACL internal use only] MS-Windows-specific: Create a child if
    //  instantiated from a resource file.

    virtual ulong ExtendedStyle () const;
    //  [YACL internal use only] MS-Windows-specific: Return the extended
    //  style parameters with which this window must be created. This
    //  method is called by the MakeVisualElement method.
    
#endif
    void AddChild (UI_VisualObject* child);
    // [YACL internal use only]
    
    virtual bool MenuBarCreated  ();
    // [YACL internal use only] Called by this object's MenuBar to let it
    // know that the MenuBar's visual element has been created.

    virtual void SetMenuBar (UI_MenuBar* menu);
    // [YACL internal use only]
    
    virtual bool PropagateFontChange (UI_VisualObject*);
    // [YACL Internal use only]

#if defined(__MS_WINDOWS__) || defined(__MS_WIN32__) || defined(__OS2__) \
    || defined(__X_YACL__)
    bool TakeFocus ();
    // [Specific to OS/2 and Windows. YACL internal use only.]

    virtual void MoveFocusTo (UI_VisualObject* child);
    // [Specific to OS/2 and Windows. YACL internal use only.] This method
    // moves the focus to the specified child. 

    virtual bool AdvanceFocus (short n);
    // [Specific to OS/2 and Windows. YACL internal use only.] This method
    // advances focus to the next child if n is +1, and to the previous
    // child if n is -1. Returns TRUE on success, FALSE if it hits the ends
    // of the tab sequence.

#ifndef __X_YACL__
    virtual void SetStyle ();
    // [Specific to OS/2 and Windows. YACL internal use only.] Set up the
    // style parameters for this Composite. This method is called by the
    // default implementation of {\tt MakeVisualElement} just before the
    // visual element is created. Under Windows, this sets the {\tt _style}
    // instance variable. Under OS/2, it sets the instance variables {\tt
    // _style} (which is the client window style), {\tt _frameCreationFlags}
    // and {\tt _frameStyle}.
    
protected:
    void _SetFocusTo (short i);
    // [Specific to OS/2 and Windows. YACL internal use only.] Set the focus
    // to child $i$ in the tab sequence.

#endif
#endif


#if defined(__OS2__)
    virtual HWND ParentHandle () const;
    // [Specific to OS/2 and Windows. YACL internal use only.] Return the
    // handle of the parent of this object. This method is called by the
    // MakeVisualElement method.

    virtual void _ComputeWindowShape (RECTL& );
    // [Specific to OS/2 and Windows. YACL internal use only.] Return the
    // rectangle containing the desired shape. THis method is called by
    // the MakeVisualElement method.
    
#if defined(__IBMCPP__) // IBMCPP only allows _OptLink calling convention
                        // for member functions.  the work around is to
                        // make a global function that is used to call the
                        // class static function...
    static MRESULT FrameProc (HWND hWnd, ULONG msg, MPARAM p1, MPARAM p2);
    // [OS/2- and IBM C++-specific, YACL Internal use only]
    
    friend MRESULT EXPENTRY CallBackFrameProc(HWND hWnd, ULONG msg,
                                              MPARAM p1, MPARAM p2);
    // [OS/2- and IBM C++-specific, YACL Internal use only]
    
#else
    static MRESULT EXPENTRY FrameProc (HWND hWnd, ULONG msg, MPARAM p1,
                                       MPARAM p2);
    // [OS/2-specific, YACL Internal use only]

#endif

    PFNWP _oldFrameProc;

#endif
    
protected:
    // 
    // Instance Variables:
    // 

    UI_MenuBar*        _menuBar;
    bool               _stickToParent; // Do we stick to our parent's
                                       // surface?
    short              _currentChild;  // Index of current child in map
    CL_ObjectSequence  _tabSequence;   // The sequence of children in
                                       // tabbing order
    bool               _titleBarShown; // Is the title bar currently shown?
    bool               _iconified;     // Are we currently iconified?
    short              _minWidth;
    short              _minHeight;
    short              _maxWidth;
    short              _maxHeight;
#if defined(__OS2__)
    UI_ViewHandle      _frameHandle;
    ulong              _frameStyle;
    ulong              _frameCreationFlags;
    UI_ViewHandle      _sysMenu;
    UI_ViewHandle      _titleBar;
    UI_ViewHandle      _minMax;

    void _SetTitleBarVisibility (bool);
    // [OS/2-specific, for YACL internal use only]
    
#endif
    
protected:

    bool  _ShapeRectChanged ();
    // Override VisualObject's method

    bool _TitleChanged ();
    // Override VisualObject's method

    bool _DoShowBorder (bool);
    // Override VisualObject's method
    
#if defined(__X_MOTIF__)
#endif

#if defined(__MS_WINDOWS__) || defined(__MS_WIN32__)
    bool               _3dLook;
    CL_String          _rname;         // Resource  name
                                       // (used only under MS-Windows)
#endif

    virtual bool _EventOccurred (UI_Event& o);
    // [YACL internal use only.] This method is meant for handling tab
    // sequences. The Composite sets up an event dependence on itself,
    // designating this method in the bindings. The events that cause this
    // methods to be called are KeyTyped, LButtonRelease,
    // ChildCreated, Iconify and Deiconify.

private:
    void _Init ();
    // [Internal use only]
    
};




#endif
