The DrawAreaExposeCB() callback receives, as the second argument, a pointer to an Event of type Expose which specifies the portion of the Object area to be redrawn. Before calling this callback the Object automatically sets a clipping area to prevent drawing outside that area. So, the application can decide whether to use or not the received area coordinates to make only useful redrawings. In both cases the output will occurr only in the clipped area. For simplicity the callback in the example simply redraws the entire Object with no care of the actual clipping area to be redrawn. The DrawAreaInputCB() callback handles mouse input events to draw lines. Notice that drawing in this Object is NOT REMEMBERED. The application must take care of storing in some way its drawings in order to be able to redraw them in the Expose callback and/or to save them on disk.
/* C version */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "mgui.h" MTColor black, white, cadetblue, seagreen; void ExitCB(MENU_ITEM item, void *a, void *b) { MShellDestroy((MOBJECT)b); MGUITerm(); exit(0); } void DrawAreaExposeCB(MOBJECT obj, MEvent *pexp, void *a_data) { int hsize, wsize; wsize = MObjectGetWidth(obj); hsize = MObjectGetHeight(obj); MDrawLine(obj, 0, 0, wsize, hsize, black); MDrawLine(obj, 0, hsize, wsize, 0, white); MDrawFilledCircle(obj, wsize/2, hsize/2, wsize/4, cadetblue); MDrawCircle(obj, wsize/2, hsize/2, wsize/4, black); } void DrawAreaResizeCB(MOBJECT obj, DRAWAREA_PREF *pref, void *label) { char str[128]; sprintf(str, "Draw area size: %dx%d", pref->new_w, pref->new_h); MObjectSetText((MOBJECT )label, str); } void DrawAreaInputCB(MOBJECT obj, MEvent *pe, void *a_data) { static int x1, y1, x2, y2; if (pe->type == E_BUTTON_PRESS) { x1 = x2 = pe->mouse.x; y1 = y2 = pe->mouse.y; MDrawXorLine(obj, x1, y1, x2, y2); } else if (pe->type == E_MOTION) { MDrawXorLine(obj, x1, y1, x2, y2); x2 = pe->mouse.x; y2 = pe->mouse.y; MDrawXorLine(obj, x1, y1, x2, y2); } else if (pe->type == E_BUTTON_RELEASE) { MDrawXorLine(obj, x1, y1, x2, y2); x2 = pe->mouse.x; y2 = pe->mouse.y; MDrawLine(obj, x1, y1, x2, y2, seagreen); } } void MGUIMain(int argc, char **argv) { MOBJECT pbutton, shell, label, drawa; black = MBlackColor(); white = MWhiteColor(); cadetblue = MAllocColor(0x60, 0x85, 0x95); seagreen = MAllocColor(0x70, 0xa5, 0xa0); shell = MCreateShell("Sample 9", SF_NO_CLOSE); label = MCreateLabel(shell, "Try and resize the window", HELV_L_FONT); drawa = MCreateDrawArea(shell, 256, 256); MObjectSetCursor(drawa, MC_CROSSHAIR); MObjectSetResize(drawa, True, True); MDrawAreaSetExposeCallback(drawa, DrawAreaExposeCB, NULL); MDrawAreaSetInputCallback(drawa, DrawAreaInputCB, NULL); MDrawAreaSetResizeCallback(drawa, DrawAreaResizeCB, label); pbutton = MCreatePButton(shell, "Close", TIMES_L_FONT); MPButtonSetCallback(pbutton, ExitCB, shell); MShellRealize(shell); MMainLoop(); }
// C++ version #include <stdio.h> #include <string.h> #include "mguipp.h" class CaAppl : public CmAppl { public: void start(int, char **); }; CaAppl appInstance; class CaMainWindow : public CmShell { CmDrawArea *drawa; CmLabel *label; CmSharedColor *seagreen, *cadetblue, *black, *white; int x1, y1, x2, y2; public: CaMainWindow(const char *title, int flags); ~CaMainWindow(); void drawAreaExposeCB(MEvent *); void drawAreaInputCB(MEvent *); void drawAreaResizeCB(DRAWAREA_PREF *); void exitCB(int); }; CaMainWindow::~CaMainWindow() { delete seagreen; delete cadetblue; delete black; delete white; } void CaMainWindow::exitCB(int) { delete this; CmAppl::end(0); } void CaAppl::start(int argc, char **argv) { CaMainWindow *win = new CaMainWindow("Example 9", SF_NO_CLOSE); win->realize(); mainLoop(); } void CaMainWindow::drawAreaExposeCB(MEvent *pexp) { int hsize, wsize; wsize = drawa->getWidth(); hsize = drawa->getHeight(); drawa->drawLine(0, 0, wsize, hsize, black); drawa->drawLine(0, hsize, wsize, 0, white); drawa->drawFilledCircle(wsize/2, hsize/2, wsize/4, cadetblue); drawa->drawCircle(wsize/2, hsize/2, wsize/4, black); } void CaMainWindow::drawAreaResizeCB(DRAWAREA_PREF *pref) { char str[128]; sprintf(str, "Draw area size: %dx%d", pref->new_w, pref->new_h); label->setText(str); } void CaMainWindow::drawAreaInputCB(MEvent *pe) { if (pe->type == E_BUTTON_PRESS) { x1 = x2 = pe->mouse.x; y1 = y2 = pe->mouse.y; drawa->drawXorLine(x1, y1, x2, y2); } else if (pe->type == E_MOTION) { drawa->drawXorLine(x1, y1, x2, y2); x2 = pe->mouse.x; y2 = pe->mouse.y; drawa->drawXorLine(x1, y1, x2, y2); } else if (pe->type == E_BUTTON_RELEASE) { drawa->drawXorLine(x1, y1, x2, y2); x2 = pe->mouse.x; y2 = pe->mouse.y; drawa->drawLine(x1, y1, x2, y2, seagreen); } } CaMainWindow::CaMainWindow(const char *title, int flags) : CmShell(title, flags) { x1 = x2 = y1 = y2 = 0; black = new CmSharedColor(0, 0, 0); white = new CmSharedColor(0xff, 0xff, 0xff); cadetblue = new CmSharedColor(0x60, 0x85, 0x95); seagreen = new CmSharedColor(0x70, 0xa5, 0xa0); label = new CmLabel(this, "Try and resize the window", HELV_MEDIUM); drawa = new CmDrawArea(this, 256, 256); drawa->setExposeCallback(this, (EVENT_CB)drawAreaExposeCB); drawa->setInputCallback(this, (EVENT_CB)drawAreaInputCB); drawa->setResizeCallback(this, (DRAWAREAPREF_CB)drawAreaResizeCB); drawa->setResize(True, True); drawa->setCursor(MC_CROSSHAIR); CmPushButton *pb = new CmPushButton(this, " Ok ", TIMES_MEDIUM); pb->setCallback(this, (VOID_CB)exitCB); }