
#ifndef _strview_h_
#define _strview_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.
 *
 */





// StringView is a SimpleVObject that displays a sequence of strings. Its
// visual element is the listbox control under MS-Windows and OS/2, and
// the ScrolledList widget under Motif.
//
// StringView is an abstract class that factors out behavior common to
// single-select and multiple-select views; therefore the StringView
// constructors are protected. The two concrete classes
// StringViewSingleSel and StringViewMultiSel derived  from StringView
// provide the versions usable in applications.
//
// The model of a StringView is a {\tt UI_StringSequence}, so you can cast
// down the return value of its {\tt Model} method to a {\tt
// UI_StringSequence}.


#if defined(__GNUC__)
#pragma interface
#endif


#include "base/intset.h"
#include "base/integer.h"

#include "ui/simple.h"
#include "ui/strseq.h"


#if defined(__X_YACL__)
class UI_ScrollBar;
class UI_DrawingSurface;
#endif

class YACL_UI UI_StringView: public UI_SimpleVObject {


public:
    virtual long  TopIndex () const;
    // Return the index of the topmost visible string in the view.

    virtual short VisibleCount () const;
    // Return the number of visible strings.
    
    virtual void  ScrollTo (long index);
    // Scroll the view so that the String at the given index is at the top.

    virtual void MakeInvisible ();
    // Make the StringView invisible. This overrides the inherited method.

    virtual void MakeVisible ();
    // Make the StringView visible. This overrides the inherited method.

    // ---------------- Overridden SimpleVObject methods -------------

    virtual UI_WindowClass WindowClass () const;
    // Return the window class of the StringView. This overrides the
    // inherited method.

    // ---------------- Overridden basic methods ---------------------
    
    const char* ClassName () const { return "UI_StringView";};

protected:

    UI_StringView (UI_VisualObject* parent, UI_StringSequence* model,
                   const UI_Rectangle& shape,
                   bool multiple_select = FALSE,
                   UI_ViewID id = -1, long style = -1);
    // Constructor: create a StringView as a child of {\tt parent}, with
    // the given shape and view id. The parameter {\tt multiple_select}
    // determines whether this is a multiple-select StringView. This
    // constructor creates a StringView that borrows {\tt model} from its
    // caller and uses it as the StringView's model.

    UI_StringView (UI_VisualObject* parent,  
                   const UI_Rectangle& shape, bool multiple_select = FALSE,
                   UI_ViewID id = -1, long style = -1);
    // Constructor: create a StringView as a child of {\tt parent}, with
    // the given shape and view id. The parameter {\tt multiple_select}
    // determines whether this is a multiple-select StringView. This
    // constructor creates a StringView that creates its own model.



#if defined(__MS_WINDOWS__) || defined(__MS_WIN32__)
    UI_StringView (UI_CompositeVObject* parent, UI_ViewID id,
                   UI_ViewHandle h);
    // [MS-Windows-specific, for YACL internal use only] Resource-based
    // construction.

#endif
    

    virtual void _UpdateSelection () = 0;
    // Called by {\tt ItemInserted} and {\tt ItemRemoved} to tell us
    // to update our selection.

    // ---------------- Overridden VisualObject methods --------------

    ~UI_StringView ();
    // Destructor.

    virtual bool MakeVisualElement ();
    // Override the inherited method. Under Windows and OS/2, the
    // implementation  simply forwards the call to the inherited method.
    // Under Motif, the implementation creates a ScrolledList widget.
    
    void _PrivateInitialize ();
    // Override the inherited method. The implementation initializes the
    // view with the initial contents of the model.

    virtual bool _ModelChanged ();
    // Called by the model to tell this object that there was a structural
    // change in it.
    
    virtual void _AddModelStrings ();
    // Includes the platform-dependent code for adding the model strings
    // into the platform's visual element.

    bool _FontChanged ();
    // For YACL internal use only. Overrides the inherited
    // method.
    

#if defined (__X_MOTIF__)

    static void Callback (struct _WidgetRec*, void *, void *);
    // [X-windows-specific, for YACL internal use only] The callback
    // executed when a selection changes.
    
    virtual void _SetupStyle (void* arg, short& argn);
    // [X-windows-specific, YACL internal use only] Called by {\tt
    // MakeVisualElement} to set up Motif resources.

    UI_ViewHandle  _list;

#elif defined(__X_YACL__)
    bool HandleEvent (UI_Event* e);

    bool _ShapeRectChanged ();

    void _DrawClientArea (UI_DrawingSurface& sfc); 

    bool _VertScroll (UI_Event& e);
    
    bool _HorzScroll (UI_Event& e);

    bool _KeyAction (UI_Event& e); //Newly added

    void _Redraw ();

    void _DrawFocus (UI_DisplaySurface&); 

    void _UnFocus (UI_DrawingSurface&); 
    
    void _SetupScrollBar ();

    void _FindMaxStrLength () ;

    virtual void _HighlightSelection (UI_DrawingSurface& s) = 0;

    virtual void _DoSelect (long newSelection) = 0;

    virtual void _EmptySelection () = 0;

    UI_Rectangle _ItemRectangle (long index);

    void _Init ();
    
    long          _topElement;
    short         _charHeight;
    short         _visibleCount;

    long          _leftElement; 
    long          _maxStrWidth; 
    long          _charWidth; 
    long          _currentFocus; 

    UI_ScrollBar* _hBar;
    UI_ScrollBar* _vBar;
#endif

    bool           _multiple;


public:
    virtual void ItemChanged (long);
    // [YACL internal use only] Called by the model when one of the
    // contained strings changes.

    virtual bool _SelectionChanged () = 0;
    // [YACL internal use only] Called by the selection when it is modified
    // by the application.
    
#if defined (__OS2__)

protected:
    void _UpdateItemCount ();
    // [OS/2-specific, for YACL internal use only] Called to update the
    // count of visible items.

    bool _ShapeRectChanged ();
    // [OS/2-specific, for YACL internal use only] Overrides the inherited
    // method.
    
    short _itemCount;
    
#endif
};




// StringViewSingleSel is derived from StringView, and represents a
// StringView on which the user can select at most one string at a time. The
// selected string is shown (usually) in highlighted form (this is
// dictated by the platform's visual element).
//
// The method {\tt Selection} returns a reference to an Integer containing
// the index of the currently-selected String in the model. (It contains
// $-1$ if there is no current selection.) The application program may
// modify this return value via any of the Integer methods, and this
// modification will be propagated to the visual element.

class YACL_UI UI_StringViewSingleSel: public UI_StringView {

public:
    UI_StringViewSingleSel (UI_VisualObject* parent,  
                            const UI_Rectangle& shape,
                            UI_ViewID id = -1);
    // Constructor: create a StringViewSingleSel as a child of {\tt
    // parent}, with  the given shape and view id. This
    // constructor creates a StringViewSingleSel that creates and owns its
    // model.

    UI_StringViewSingleSel (UI_VisualObject* parent,
                            UI_StringSequence* model,
                            const UI_Rectangle& shape, UI_ViewID id = -1);
    // Constructor: create a StringViewSingleSel as a child of {\tt
    // parent}, with  the given shape and view id. This
    // constructor creates a StringViewSingleSel that borrows {\tt model}
    // from its caller and uses it as the StringViewSingleSel's model.

#if defined(__MS_WINDOWS__) || defined(__MS_WIN32__)
    UI_StringViewSingleSel (UI_CompositeVObject* parent, UI_ViewID id,
                            UI_ViewHandle h);
    // [MS-Windows-specific, for YACL internal use only] Resource-based
    // construction.
    
#endif

    virtual CL_Integer& Selection ();
    // Return the index of the currently selected string. This index is $-1$
    // if no string is currently selected. The return value may be assigned
    // to, thus modifying the selection.
    
protected:
    bool Select ();
    // The Select event handler. The implementation updates the instance
    // variable {\tt _selection}.
    
    bool _SelectionChanged ();
    // This is the method used by StringViewSingleSel as client method for
    // the dependence on the instance variable {\tt _selection}.

    void _UpdateSelection ();
    // This method contains the platform-specific code for changing the
    // visual element when the selection changes.
    
#if defined(__X_YACL__)
    void _HighlightSelection (UI_DrawingSurface& s);

    void _DoSelect (long newSel);

    void _EmptySelection ();
    
#endif

    CL_Integer _selection;
};



// StringViewMultiSel is derived from StringView, and represents a
// StringView on which the user can select one or more strings. The
// selected strings are shown (usually) in highlighted form (this is
// dictated by the platform's visual element).
//
// The method {\tt Selection} returns a reference to an IntegerSet containing
// the indices of the currently-selected Strings in the model. The
// application program may modify this return value via any of the
// IntegerSet methods, and this  modification will be propagated to the
// visual element.

class YACL_UI UI_StringViewMultiSel: public UI_StringView {

public:
    UI_StringViewMultiSel (UI_VisualObject* parent,  
                           const UI_Rectangle& shape,
                           UI_ViewID id = -1);
    // Constructor: create a StringViewMultiSel as a child of {\tt
    // parent}, with  the given shape and view id. This
    // constructor creates a StringViewMultiSel that creates and owns its
    // model.

    UI_StringViewMultiSel (UI_VisualObject* parent,
                           UI_StringSequence* model,
                           const UI_Rectangle& shape, UI_ViewID id = -1);
    // Constructor: create a StringViewMultiSel as a child of {\tt
    // parent}, with  the given shape and view id. This
    // constructor creates a StringViewMultiSel that borrows {\tt model}
    // from its caller and uses it as the StringViewSingleSel's model.


#if defined(__MS_WINDOWS__) || defined(__MS_WIN32__)
    UI_StringViewMultiSel (UI_CompositeVObject* parent, UI_ViewID id,
                           UI_ViewHandle h);
    // [MS-Windows-specific, for YACL internal use only] Resource-based
    // construction.

#endif

    CL_IntegerSet& Selection () {return _selection;};
    // Return the set of indices of strings that are currently selected. The
    // return value may be assigned to or otherwise modified using any of
    // the IntegerSet methods, thus modifying the selection.
    
protected:
    bool Select ();
    // The Select event handler. The implementation updates the instance
    // variable {\tt _selection}.

    bool _SelectionChanged ();
    // This is the method used by StringViewMultiSel as client method for
    // the dependence on the instance variable {\tt _selection}.
    
    void _UpdateSelection ();
    // This method contains the platform-specific code for changing the
    // visual element when the selection changes.
    
#if defined(__X_YACL__)
    void _HighlightSelection (UI_DrawingSurface& s);

    void _DoSelect (long n);
    
    void _EmptySelection ();
    
#endif
    CL_IntegerSet _selection;
};


#endif
