

#ifndef _stred_h_
#define _stred_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.
 *
 */





// This SimpleVObject is  designed to support the  editing of a single line
// of text  contained in its model, which  is a {\small\tt  CL_String}. The
// selection on the model is a {\small\tt CL_Interval}, i.e., the positions
// of the left and right ends of the substring currently selected.
//
// Under X_YACL, there is minimal support for this class. Its key bindings
// are Windows-ish, with significance attached to the delete, home, end and
// arrow keys.

#if defined(__GNUC__)
#pragma interface
#endif


#include "ui/simple.h"
#include "ui/interval.h"
#include "base/integer.h"

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

class YACL_UI UI_StringEditor: public UI_SimpleVObject {

public:

    //
    // Construction:
    //

    UI_StringEditor (UI_VisualObject* parent, const UI_Rectangle& shape,
                     UI_ViewID id);
    // Constructor: create  a StringEditor as child of {\tt parent}, with
    // the given shape and view id. The StringEditor owns its model.

    UI_StringEditor (UI_VisualObject* parent, CL_String* model,
                     const UI_Rectangle& shape, UI_ViewID id);
    // Constructor: create  a StringEditor as child of {\tt parent}, with
    // the given shape and view id. The StringEditor borrows {\tt model}
    // from the caller and uses it as model.


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

#endif

    CL_Object& Model ();
    // Override the inherited method. The returned reference is to a {\tt
    // CL_String}. Applications should not remember the
    // pointer returned by this method; instead, they should call this
    // method explicitly just before the data is needed, even if the
    // application owns the model.
    
    CL_Integer&  InsertionPosition ();
    // Return the current position of insertion. The returned object
    // contains the position of the character to the left of which the caret
    // is currently located. Assigning to the return value modifies this
    // position.
    //
    // Modifying this return value does not seem to work correctly under
    // Motif 1.1.
    
    
    virtual CL_Interval& Selection ();
    // Return a {\tt CL_Interval} containing the range of positions currently
    // selected. Modifying the return value causes a corresponding setting
    // of selection in the displayed string.
    
    virtual bool SetLengthLimit (long n);
    // Make the StringEditor enforce a  limit user type-in to $n$
    // characters.

    virtual long LengthLimit () const;
    // Return the current length limit. Returns $-1$ if there is no explicit
    // limit.

    
    const char* ClassName() const {return "UI_StringEditor";};



    virtual UI_WindowClass WindowClass () const;
    
protected:

    virtual bool FilterChar (short& /* key */) {return TRUE;};
    // This is a hook function provided for derived classes. When the user
    // types a key, YACL's Controller calls this function just before the
    // corresponding character is sent to this StringEditor's window. The
    // parameter is the key typed. {\tt FilterChar} may modify the
    // parameter. If {\tt FilterChar} returns TRUE, the (possibly modified)
    // key is sent to the window, otherwise it is not.
    //
    // The default implementation returns TRUE unconditionally. Derived
    // classes may use other criteria; for example, a number editor can
    // insist that the typed-in character be a number or an editing key.

    virtual void Update () {};
    // This is a hook function for use by derived classes. YACL's Controller
    // calls this function just after the user has taken an action that
    // might have altered the StringEditor's contents. The
    // default implementation does nothing.


    virtual bool PermitDelete () {return TRUE;};
    // This is a hook function for use by derived classes. YACL's Controller
    // calls this function when the user types the delete key when this
    // StringEditor has focus. If {\tt PermitDelete} returns TRUE, the
    // delete character is sent to the StringEditor's window, otherwise it
    // is not. The default implementation returns TRUE unconditionally.

    
    void _PrivateInitialize ();
    // For YACL internal use only.
  
    bool _ModelChanged ();
    // For YACL internal use only.
  
    bool _TitleChanged () {return TRUE;};
    // String editors don't have titles. If we don't override it this way,
    // things don't work right under OS/2.
    
    virtual bool _InsertPosChanged ();
    // Called by _insertPos.

    //  Instance Variables:

    CL_Interval _selection;
    long        _limit;
    CL_Integer  _insertPos;
    bool        _readOnly;

#if defined(__X_YACL__)
    bool MakeVisualElement ();

    void _DoFocusEmphasis ();
    // Override the inherited method.
  
    ~UI_StringEditor ();

    
    friend class YVE_StringEditorEventHandler;
    YVE_StringEditorEventHandler* _handler;
    
#elif defined(__X_MOTIF__)
    bool MakeVisualElement();

    void _SetupStyle (void* arg, short& argn);
    // Motif-specific; for YACL internal use only.

    bool _FontChanged ();
    // Motif-specific; for YACL internal use only. Overrides the inherited
    // method.

    static void ModifyCallback (struct _WidgetRec*, void *, void *);
    // [X-windows-specific, for internal use only] The callback executed
    // when the user attempts to modify the value.

    bool _callbackActive; // Workaround for Motif problems
    
    UI_ViewHandle  _text;
#endif

    friend UI_Controller;

private:
    virtual bool _SelectionChanged ();
    // Called when the application modifies the return value of the
    // Selection() method.
    
#if defined(__OS2__)
#   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 StrEditProc (HWND hWnd, ULONG msg,
                                MPARAM p1, MPARAM p2);

    friend MRESULT EXPENTRY CallBackStrEditProc(HWND hWnd, ULONG msg,
                                                MPARAM p1, MPARAM p2);
    
#   else
    static MRESULT EXPENTRY StrEditProc (HWND hWnd, ULONG msg,
                                         MPARAM p1, MPARAM p2);
#   endif

    void _SubclassEditor ();
    
    PFNWP _oldEditProc;


#endif
};




inline long UI_StringEditor::LengthLimit () const
{
    return _limit;
}


#endif


