
/*
 *    File drawa.cpp
 *      Demonstrates the use of the DRAWAREA Object
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "mguipp.h"

#include "mguitest.hpp"

class DrawAreaDialog : public CmCallback
{
    CmShell *shell;
public:
    DrawAreaDialog();
    void closeDialog(void) { delete shell; delete this; };
};

class CaDrawArea:public CmDrawArea
{
    public:
    CmLabel * xy_label;
    CmLabel *dim_label;

    CaDrawArea(CmContainer * p, int w, int h);
    void onExpose(MEvent *);
    void onResize(DRAWAREA_PREF * pref);
    void onInput(MEvent * pe);
};

CaDrawArea::CaDrawArea(CmContainer * p, int w, int h)
 : CmDrawArea(p, w, h)
{
    setExposeCallback(this, (EVENT_CB)&CaDrawArea::onExpose);
    setInputCallback(this, (EVENT_CB)&CaDrawArea::onInput);
    setResizeCallback(this, (DRAWAREAPREF_CB)&CaDrawArea::onResize);
}

/*****************************************************
 *	This function draws lines and circles in the
 *	DRAWAREA Object using its current dimensions.
 *****************************************************/
void CaDrawArea::
onExpose(MEvent *)
{
    int hsize, wsize;

    wsize = getWidth();
    hsize = getHeight();

    drawLine(0, 0, wsize, hsize, black);
    drawLine(0, hsize, wsize, 0, white);

    drawFilledCircle(wsize / 2, hsize / 2, wsize / 4, cadetblue);
    drawCircle(wsize / 2, hsize / 2, wsize / 4, black);
}

/*****************************************************
 *	This function handles the resize of the
 *	DRAWAREA, setting a LABEL text to the
 *	new dimensions.
 *****************************************************/
void CaDrawArea::
onResize(DRAWAREA_PREF * pref)
{
    char str[128];

    sprintf(str, "%dx%d", pref->new_w, pref->new_h);
    dim_label->setText(str);
}

/*****************************************************
 *	This function handles the mouse input events
 *	in the Object drawing lines
 *****************************************************/
void CaDrawArea::
onInput(MEvent * pe)
{
    static int x1, y1, x2, y2;
    char buff[128];

    switch (pe->type)
    {
    case E_WINDOW_EXIT:
/*
 * Set the initial coordinates at the mouse
 * button press event
 */
	xy_label->setText("");
	break;
    case E_BUTTON_PRESS:
/*
 * Set the initial coordinates at the mouse
 * button press event
 */
	x1 = x2 = pe->mouse.x;
	y1 = y2 = pe->mouse.y;
	break;
    case E_WINDOW_ENTER:
    case E_MOTION:
	if ((pe->mouse.state & Button1Mask) && x1 > 0)
	{
/*
 * Erase the old line and draw the new one
 * while dragging the mouse (draw in Xor mode)
 */
	    drawXorLine(x1, y1, x2, y2);
	    drawXorLine(x1, y1, pe->mouse.x, pe->mouse.y);
	}
	x2 = pe->mouse.x;
	y2 = pe->mouse.y;
	sprintf(buff, "%3d %3d", x2, y2);
	xy_label->setText(buff);
	break;
    case E_BUTTON_RELEASE:
/*
 * Erase the old line and draw the definitive one
 */
	drawXorLine(x1, y1, x2, y2);
	x2 = pe->mouse.x;
	y2 = pe->mouse.y;
	drawLine(x1, y1, x2, y2, seagreen);
	x1 = -1;
	break;
    case E_GRAB_LOSE:
/*
 * The Object has lost mouse grab, so, clear the line
 */
	drawXorLine(x1, y1, x2, y2);
	x1 = -1;
    }
}

DrawAreaDialog::DrawAreaDialog(void)
{
    CmColForm *cform;
    CmRowForm *rform;
    CmColForm *cf2;
    CmLabel *dim_label;
    CmLabel *xy_label;
    CaDrawArea *drawa;
    CmSFile *sfile;
    CmPushButton *pb;

    shell = new CmShell("Draw Area", SF_MODAL);
	shell->setWMCloseCallback(this, (VOID_CB)&DrawAreaDialog::closeDialog);

    cform = new CmColForm(shell);
    rform = new CmRowForm(cform);
    cf2 = new CmColForm(rform);
/*
 * This LABEL is used to show the current
 * DRAWAREA dimensions
 */
    dim_label = new CmLabel(cf2, "", HELV_MEDIUM);
    xy_label = new CmLabel(cf2, "", SMALL_FONT);

/*
 * Create the DRAWAREA Object of 256x256 pixels wide
 */
    drawa = new CaDrawArea(rform, 256, 256);
    drawa->setCursor(MC_CROSSHAIR);
    drawa->dim_label = dim_label;
    drawa->xy_label = xy_label;
/*
 * Allow the DRAWAREA to resize in Horizontal and Vertical
 * directions
 */
    drawa->setResize(True, True);
/*
 * Create a SFILE Object to show this source file in the dialog
 */
    sfile = new CmSFile(cform, __FILE__, FIXED_MEDIUM, 10, 48);
    sfile->setColor(darkblue, white);
/*
 * This PUSH BUTTON closes the dialog
 */
    pb = new CmPushButton(shell, "Close", TIMES_MEDIUM);
    pb->setCallback(this, (VOID_CB)&DrawAreaDialog::closeDialog);

    shell->realize();
}

/*****************************************************
 *	This function opens the dialog when the
 *	corresponding menu item is selected
 *****************************************************/
void
DrawAreaDemo(void)
{
	new DrawAreaDialog;
}
