/******************************************************************************
 JXFLPane.h

    Interface for the JXFLPane class

    Written by John Lindal.
    jafl@micro.caltech.edu (John Lindal)

 ******************************************************************************/

#ifndef _H_JXFLPane
#define _H_JXFLPane

#include <forms.h>

class JXFLPane
{
public:

    JXFLPane(const int type, const FL_Coord x, const FL_Coord y,
             const FL_Coord w, const FL_Coord h, const char* label);

    virtual ~JXFLPane();

    void    Refresh() const;

    void    SetLabel(const char* label);
    void    SetLabelColor(const int color);
    void    SetLabelSize(const int size);
    void    SetLabelStyle(const int style);

    // this is public so jxfl_pane_handler can call it

    FL_OBJECT*  GetXFLObject() const;
    int     HandleXFLEvent(const int event, const FL_Coord mx, const FL_Coord my,
                       const int key, void* xev);

protected:

    enum JMouseButton
    {
        kLeftButton   = 1,
        kMiddleButton = 2,
        kRightButton  = 3
    };

protected:

    void    CanAcceptInput(const int wantInput, const int wantTab);
    void    NeedStep(const int wantStep);

    virtual void    Draw() = 0;
    virtual void    DrawLabel();

    virtual int HandleMouseEnter();
    virtual int HandleMouseHere(const int mx, const int my);
    virtual int HandleMouseLeave();

    virtual int HandleMouseDown(const int mx, const int my,
                                const JMouseButton button);
    virtual int HandleMouseDrag(const int mx, const int my);
    virtual int HandleMouseUp(const int mx, const int my,
                              const JMouseButton button);

    virtual int Activate();
    virtual int HandleKeyPress(const int key);
    virtual int Deactivate();

    virtual int HandleStep();
    virtual int HandleShortcut(const int key);
    virtual int HandleOtherEvent(void* xev);

private:

    FL_OBJECT*  itsXFLObj;

private:

    // not allowed

    JXFLPane(const JXFLPane& source);
    const JXFLPane& operator=(const JXFLPane& source);
};

/******************************************************************************
 Refresh

 ******************************************************************************/

inline void
JXFLPane::Refresh()
    const
{
    // we can only notify XForms that we need to be redrawn

    fl_redraw_object(itsXFLObj);
}

/******************************************************************************
 SetLabel

 ******************************************************************************/

inline void
JXFLPane::SetLabel
    (
    const char* label
    )
{
    fl_set_object_label(itsXFLObj, label);
}

/******************************************************************************
 SetLabelColor

 ******************************************************************************/

inline void
JXFLPane::SetLabelColor
    (
    const int color
    )
{
    fl_set_object_lcol(itsXFLObj, color);
}

/******************************************************************************
 SetLabelSize

 ******************************************************************************/

inline void
JXFLPane::SetLabelSize
    (
    const int size
    )
{
    fl_set_object_lsize(itsXFLObj, size);
}

/******************************************************************************
 SetLabelStyle

 ******************************************************************************/

inline void
JXFLPane::SetLabelStyle
    (
    const int style
    )
{
    fl_set_object_lstyle(itsXFLObj, style);
}

/******************************************************************************
 GetXFLObject

 ******************************************************************************/

inline FL_OBJECT*
JXFLPane::GetXFLObject()
    const
{
    return itsXFLObj;
}

/******************************************************************************
 CanAcceptInput (protected)

 ******************************************************************************/

inline void
JXFLPane::CanAcceptInput
    (
    const int wantInput,
    const int wantTab
    )
{
    itsXFLObj->input = wantInput;
    if (wantTab)
        {
        itsXFLObj->wantkey = FL_KEY_TAB;
        }
    else
        {
        itsXFLObj->wantkey = 0;
        }
}

/******************************************************************************
 NeedStep (protected)

 ******************************************************************************/

inline void
JXFLPane::NeedStep
    (
    const int wantStep
    )
{
    itsXFLObj->automatic = wantStep;
}

#endif





/******************************************************************************
 JXFLPane.cc

    Abstract base class to manage a pane in an XForms window.  This class
    implements the event dispatcher and default event handling (do nothing)
    so derived classes only have to implement handlers for the events that
    they support.  Each event handler returns a value indicating whether
    or not the object should be returned by fl_do_forms and fl_check_forms.

    Draw is a special case.  It is pure virtual because it always has to be
    provided.  It doesn't have a return value because is should never cause
    the object to returned by fl_do_forms or fl_check_forms.

    DrawLabel is also special because its default implementation is to
    draw whatever is stored in obj->label using fl_drw_text_beside().

    Each derived class must also define an fl_add_Pane routine to conform
    to the XForms standard:

    JXFLPane* fl_add_Pane(const FL_Coord x, const FL_Coord y,
                          const FL_Coord w, const FL_Coord h);

    As with any other XForms object, this object should only be created
    during a form definition.

    Implementation notes:

    This object should be destroyed when the associated FL_OBJECT is
    destroyed.  By catching the FL_FREEMEM message, we can insure this
    as long as the object was allocated with new.  Is is fl_add_Pane's
    job to insure this.

    BASE CLASS = none

    Written by John Lindal.

 ******************************************************************************/

#include "JXFLPane.h"

// Private routines

static int jxfl_pane_handler(FL_OBJECT* obj, int event, FL_Coord mx, FL_Coord my,
                             int key, void* xev);

/******************************************************************************
 Constructor

    The secondary object type is zero because you should use inheritance.

 ******************************************************************************/

JXFLPane::JXFLPane
    (
    const int       type,
    const FL_Coord  x,
    const FL_Coord  y,
    const FL_Coord  w,
    const FL_Coord  h,
    const char*     label
    )
{
    itsXFLObj = fl_make_object(type, 0, x,y, w,h, label, jxfl_pane_handler);
    itsXFLObj->spec = NULL;
    itsXFLObj->u_vdata = this;
}

/******************************************************************************
 Destructor

 ******************************************************************************/

JXFLPane::~JXFLPane()
{
}

/******************************************************************************
 XForms object handler

 ******************************************************************************/

static int
jxfl_pane_handler
    (
    FL_OBJECT*  obj,
    int         event,
    FL_Coord    mx,
    FL_Coord    my,
    int         key,
    void*       xev
    )
{
    JXFLPane* pane = (JXFLPane*) obj->u_vdata;
    return pane->HandleXFLEvent(event, mx, my, key, xev);
}

/******************************************************************************
 HandleXFLEvent

 ******************************************************************************/

int
JXFLPane::HandleXFLEvent
    (
    const int       event,
    const FL_Coord  mx,
    const FL_Coord  my,
    const int       key,
    void*       xev
    )
{
    if (event == FL_DRAW)
        {
        Draw();
        return 0;
        }
    if (event == FL_DRAWLABEL)
        {
        DrawLabel();
        return 0;
        }

    else if (event == FL_ENTER)
        {
        return HandleMouseEnter();
        }
    else if (event == FL_MOTION)
        {
        return HandleMouseHere(mx, my);
        }
    else if (event == FL_LEAVE)
        {
        return HandleMouseLeave();
        }

    else if (event == FL_PUSH)
        {
        return HandleMouseDown(mx, my, (JMouseButton) key);
        }
    else if (event == FL_MOUSE)
        {
        return HandleMouseDrag(mx, my);
        }
    else if (event == FL_RELEASE)
        {
        return HandleMouseUp(mx, my, (JMouseButton) key);
        }

    else if (event == FL_FOCUS)
        {
        return Activate();
        }
    else if (event == FL_KEYBOARD)
        {
        return HandleKeyPress(key);
        }
    else if (event == FL_UNFOCUS)
        {
        return Deactivate();
        }

    else if (event == FL_STEP)
        {
        return HandleStep();
        }

    else if (event == FL_SHORTCUT)
        {
        return HandleShortcut(key);
        }

    else if (event == FL_OTHER)
        {
        return HandleOtherEvent(xev);
        }

    else if (event == FL_FREEMEM)
        {
        delete this;
        return 0;
        }
    else
        {
        return 0;
        }
}

/******************************************************************************
 DrawLabel

 ******************************************************************************/

void
JXFLPane::DrawLabel()
{
    fl_drw_text_beside(itsXFLObj->align, itsXFLObj->x, itsXFLObj->y,
                       itsXFLObj->w, itsXFLObj->h, itsXFLObj->lcol,
                       itsXFLObj->lsize, itsXFLObj->lstyle, itsXFLObj->label);
}

/******************************************************************************
 HandleMouseEnter

 ******************************************************************************/

int
JXFLPane::HandleMouseEnter()
{
    return 0;
}

/******************************************************************************
 HandleMouseHere

 ******************************************************************************/

int
JXFLPane::HandleMouseHere
    (
    const int mx,
    const int my
    )
{
    return 0;
}

/******************************************************************************
 HandleMouseLeave

 ******************************************************************************/

int
JXFLPane::HandleMouseLeave()
{
    return 0;
}

/******************************************************************************
 HandleMouseDown

 ******************************************************************************/

int
JXFLPane::HandleMouseDown
    (
    const int           mx,
    const int           my,
    const JMouseButton  button
    )
{
    return 0;
}

/******************************************************************************
 HandleMouseDrag

 ******************************************************************************/

int
JXFLPane::HandleMouseDrag
    (
    const int mx,
    const int my
    )
{
    return 0;
}

/******************************************************************************
 HandleMouseUp

 ******************************************************************************/

int
JXFLPane::HandleMouseUp
    (
    const int           mx,
    const int           my,
    const JMouseButton  button
    )
{
    return 0;
}

/******************************************************************************
 Activate

 ******************************************************************************/

int
JXFLPane::Activate()
{
    return 0;
}

/******************************************************************************
 HandleKeyPress

 ******************************************************************************/

int
JXFLPane::HandleKeyPress
    (
    const int key
    )
{
    return 0;
}

/******************************************************************************
 Deactivate

 ******************************************************************************/

int
JXFLPane::Deactivate()
{
    return 0;
}

/******************************************************************************
 HandleStep

 ******************************************************************************/

int
JXFLPane::HandleStep()
{
    return 0;
}

/******************************************************************************
 HandleShortcut

 ******************************************************************************/

int
JXFLPane::HandleShortcut
    (
    const int key
    )
{
    return 0;
}

/******************************************************************************
 HandleOtherEvent

 ******************************************************************************/

int
JXFLPane::HandleOtherEvent
    (
    void* xev
    )
{
    return 0;
}

