![]() |
PortableGUI |
Hosted by SourceForge Project page |
// Import all PortableGUI include files
#include <portablegui.h>
// Selection modes
#define MOUSE_MODE_CLICK 0
#define MOUSE_MODE_LINE 1
#define MOUSE_MODE_RECT 2
// Drawing object types
#define DRAW_TYPE_LINE 0
#define DRAW_TYPE_ARC 1
#define DRAW_TYPE_ROUNDRECT 2
#define DRAW_TYPE_STAR 3
#define DRAW_TYPE_LOGO 4
#define DRAW_TYPE_TEXT 5
// Forward declaration
class MyCanvas;
// Main frame window
PGFrame* g_hMainFrame;
// Status bar
PGPanel* g_hStatus;
// PortableGUI Logo
PGImage* g_hLogo;
// For drawing
MyCanvas* g_hMyCanvas;
// Object array
PGVector* g_hObjects;
// Size for lines
PGIntegerField* g_hLineSize;
// Radion button groups
PGButtonGroup* m_hGroup1;
PGButtonGroup* m_hGroup2;
// Mouse rectangle position
int g_iStartX, g_iStartY;
int g_iPrevX, g_iPrevY;
// Mode for selection
int g_iMode = MOUSE_MODE_LINE;
// Colors for drawing objects
PGColor* g_hColors[] = {
PGCOLOR_BLACK, PGCOLOR_BLUE, PGCOLOR_GRAY, PGCOLOR_GREEN,
PGCOLOR_ORANGE, PGCOLOR_RED, PGCOLOR_WHITE, PGCOLOR_YELLOW
};
// An object that can be drawn on our canvas
class MyDrawObject : public PGObject {
protected:
int m_iX1, m_iY1;
int m_iColor;
public:
// Construct a new drawable object
MyDrawObject(int x, int y, int color) {
m_iX1 = x;
m_iY1 = y;
m_iColor = color;
}
// Draw the object on screen
virtual void draw(PGGraphics* graph) {
graph->setColor(g_hColors[m_iColor]);
graph->setLineWidth(1);
}
};
// A line that can be drawn on our canvas
class MyDrawObjectLine : public MyDrawObject {
protected:
int m_iX2, m_iY2, m_iSize;
public:
// Construct a new drawable line
MyDrawObjectLine(int x1, int y1, int x2, int y2, int siz, int col) : MyDrawObject(x1, y1, col) {
m_iX2 = x2;
m_iY2 = y2;
m_iSize = siz;
}
// Draw the line on screen
virtual void draw(PGGraphics* graph) {
MyDrawObject::draw(graph);
graph->setLineWidth(m_iSize);
graph->drawLine(m_iX1, m_iY1, m_iX2, m_iY2);
}
};
// An arc that can be drawn on our canvas
class MyDrawObjectArc : public MyDrawObject {
protected:
int m_iWidth, m_iHeight;
public:
// Construct a new drawable arc
MyDrawObjectArc(int x1, int y1, int wd, int hi, int col) : MyDrawObject(x1, y1, col) {
m_iWidth = wd;
m_iHeight = hi;
}
// Draw the arc on screen
virtual void draw(PGGraphics* graph) {
MyDrawObject::draw(graph);
graph->fillArc(m_iX1, m_iY1, m_iWidth, m_iHeight, 45, 315);
}
};
// A rectangle with rounded corners that can be drawn on our canvas
class MyDrawObjectRoundRect : public MyDrawObject {
protected:
int m_iWidth, m_iHeight;
public:
// Construct a new drawable rounded rectanlge
MyDrawObjectRoundRect(int x1, int y1, int wd, int hi, int col) : MyDrawObject(x1, y1, col) {
m_iWidth = wd;
m_iHeight = hi;
}
// Draw the rounded rectangle on screen
virtual void draw(PGGraphics* graph) {
MyDrawObject::draw(graph);
graph->fillRoundRect(m_iX1, m_iY1, m_iWidth, m_iHeight, 20, 20);
}
};
// A star that can be drawn on our canvas
class MyDrawObjectStar : public MyDrawObject {
protected:
PGPolygon* m_hPoly;
public:
// Construct a new drawable star
MyDrawObjectStar(int x1, int y1, int wd, int hi, int col) : MyDrawObject(x1, y1, col) {
m_hPoly = makeStar(x1, y1, wd, hi);
PGINCREF(m_hPoly);
}
// Terminate object
virtual ~MyDrawObjectStar() {
PGDECREF(m_hPoly);
}
// Create a polygon in the shape of a star
PGPolygon* makeStar(int x, int y, int xl, int yl) {
PGPolygon* poly = new PGPolygon(10);
poly->addPoint(x+xl/2,y); /*1*/
poly->addPoint(x+xl*100/155,y+yl*45/150); /*2*/
poly->addPoint(x+xl,y+yl*45/150); /*3*/
poly->addPoint(x+xl*115/155,y+yl*75/150); /*4*/
poly->addPoint(x+xl,y+yl); /*5*/
poly->addPoint(x+xl/2,y+yl*10/15); /*6*/
poly->addPoint(x,y+yl); /*7*/
poly->addPoint(x+xl*40/155,y+yl*75/150); /*8*/
poly->addPoint(x,y+yl*45/150); /*9*/
poly->addPoint(x+xl*55/155,y+yl*45/150); /*A*/
return poly;
}
// Draw the star on screen
virtual void draw(PGGraphics* graph) {
MyDrawObject::draw(graph);
graph->fillPolygon(m_hPoly);
}
};
// PortableGUI logo that can be drawn on our canvas
class MyDrawObjectLogo : public MyDrawObject {
public:
// Construct a new drawable PortableGUI logo
MyDrawObjectLogo(int x1, int y1, int col) : MyDrawObject(x1, y1, col) {
}
// Draw the PortableGUI logo on screen
virtual void draw(PGGraphics* graph) {
MyDrawObject::draw(graph);
graph->drawImage(g_hLogo, m_iX1, m_iY1);
}
};
// The text 'PortableGUI' that can be drawn on our canvas
class MyDrawObjectText : public MyDrawObject {
protected:
PGFont* m_hFont;
public:
// Construct a new drawable text
MyDrawObjectText(int x1, int y1, int wd, int hi, int col) : MyDrawObject(x1, y1, col) {
m_hFont = makeFont(wd, hi);
PGINCREF(m_hFont);
}
// Terminate object
virtual ~MyDrawObjectText() {
PGDECREF(m_hFont);
}
// Create the font depending on the width and height
PGFont* makeFont(int w, int h) {
int size = PGMathMin(w/15, h/4)*2;
size = PGMathMax(size, 8);
size = PGMathMin(size, 40);
return new PGFont("Times", PGFONT_BOLD, size);
}
// Draw the text on screen
virtual void draw(PGGraphics* graph) {
MyDrawObject::draw(graph);
graph->setFont((PGNormalComponent*)g_hMyCanvas, m_hFont);
graph->drawString("PortableGUI", m_iX1, m_iY1);
}
};
// Canvas for drawing the picture
class MyCanvas : public PGDoubleBufferCanvas {
public:
// Return the preferred size for this component
virtual void getPreferredSize(PGDimension* dimension, BOOL recalc) {
dimension->width = 500;
dimension->height = 400;
}
// Paint all objects
virtual void draw(PGGraphics* graph) {
// Get size
PGDimension dim;
getSize(&dim);
// Draw background
graph->setColor(PGCOLOR_DARKGRAY);
graph->fillRect(0, 0, dim.width, dim.height);
// Draw objects
for (int ctr = 0; ctr < g_hObjects->getSize(); ctr++) {
MyDrawObject* obj = (MyDrawObject*)g_hObjects->getElementAt(ctr);
obj->draw(graph);
}
}
// Redraw region painted when mouse-drags
void redrawDragRegion() {
PGRectangle rect;
updateDragRegion(&rect);
drawDragRegion(&rect);
}
// Update region painted when mouse-drags
PGGraphics* updateDragRegion(PGRectangle* rect) {
// Get buffer graphics
PGGraphics* bufGrp = getBufferGraphics();
// Set right clip
rect->fromPoints(g_iStartX, g_iStartY, g_iPrevX, g_iPrevY);
bufGrp->setClip(rect->x-2, rect->y-2, rect->width+4, rect->height+4);
draw(bufGrp);
return bufGrp;
}
// Draw region painted when mouse-drags
void drawDragRegion(PGRectangle* rect) {
PGGraphics graph;
getGraphics(&graph);
rect->fromPoints(g_iStartX, g_iStartY, g_iPrevX, g_iPrevY);
redraw(rect->x-2, rect->y-2, rect->width+4, rect->height+4, &graph);
}
};
// Canvas for the color chooser
class MyColorCanvas : public PGCanvas {
private:
PGColor* m_Color;
public:
// Create a new color chooser canvas
MyColorCanvas(PGColor* color) {
m_Color = color;
}
// Return the preferred size for this component
virtual void getPreferredSize(PGDimension* dimension, BOOL recalc) {
dimension->width = 30;
dimension->height = 15;
}
// Paint the color in a dark gray rectangle
virtual void paint(PGGraphics* graph) {
PGDimension dim;
getSize(&dim);
graph->setColor(m_Color);
graph->fillRect(0, 0, dim.width, dim.height);
graph->setColor(PGCOLOR_DARKGRAY);
graph->drawRect(0, 0, dim.width, dim.height);
}
};
// Called when user tries to close the main window
class MyWindowListener : public PGWindowListener {
// Exit the application
virtual void windowClosing(PGWindow* wnd) {
getPGApplication()->exit(0);
}
};
// Called when the user chooses another tool
class MyToolListener : public PGActionListener {
private:
char* m_sStatus;
int m_iMode;
public:
// Create a listener for a tool radio-button
MyToolListener(const char* status, int mode) {
m_sStatus = (char*)status;
m_iMode = mode;
}
// Update status-bar and change drag mode
virtual void actionPerformed(PGActionListenerParent* from) {
g_iMode = m_iMode;
g_hMainFrame->setStatus(m_sStatus);
}
};
// Respond to mouse events
class MyMouseListener : public PGMouseListener {
// Add an object to the canvas
void addObject(int x, int y, int w, int h) {
BOOL update = FALSE;
// Get type and color from radio button groups
int type = m_hGroup1->getSelectedIndex();
int col = m_hGroup2->getSelectedIndex();
// Create the drawable object
MyDrawObject* obj = (MyDrawObject*)NULL;
switch (type) {
case DRAW_TYPE_LINE:
obj = new MyDrawObjectLine(x, y, w, h, g_hLineSize->getValue(), col);
update = TRUE;
break;
case DRAW_TYPE_ARC:
obj = new MyDrawObjectArc(x, y, w, h, col);
break;
case DRAW_TYPE_ROUNDRECT:
obj = new MyDrawObjectRoundRect(x, y, w, h, col);
break;
case DRAW_TYPE_STAR:
obj = new MyDrawObjectStar(x, y, w, h, col);
break;
case DRAW_TYPE_LOGO:
obj = new MyDrawObjectLogo(x, y, col);
update = TRUE;
break;
case DRAW_TYPE_TEXT:
obj = new MyDrawObjectText(x, y, w, h, col);
update = TRUE;
break;
}
// Add the object
g_hObjects->addElement(obj);
if (update) {
g_hMyCanvas->repaint();
} else {
g_hMyCanvas->redrawDragRegion();
}
}
// Select origin
virtual void mousePressed(PGMouseEvent* e) {
g_iStartX = e->getX();
g_iStartY = e->getY();
g_iPrevX = g_iStartX;
g_iPrevY = g_iStartY;
if (g_iMode == MOUSE_MODE_CLICK)
addObject(g_iStartX, g_iStartY, 0, 0);
}
// Draw object
virtual void mouseReleased(PGMouseEvent* e) {
if (g_iMode != MOUSE_MODE_CLICK) {
PGRectangle rect;
if (g_iMode == MOUSE_MODE_RECT) {
// Rectangle drawing mode
rect.fromPoints(g_iStartX, g_iStartY, g_iPrevX, g_iPrevY);
} else {
// Line drawing mode
rect.x = g_iStartX;
rect.y = g_iStartY;
rect.width = g_iPrevX;
rect.height = g_iPrevY;
}
addObject(rect.x, rect.y, rect.width, rect.height);
}
}
// FIXME: The mouseExit message is not available yet
virtual void mouseExited(PGMouseEvent* e) {
getPGApplication()->println("Exit rgn");
if (g_iMode != MOUSE_MODE_CLICK) g_hMyCanvas->redrawDragRegion();
}
};
// Respond to mouse motion events
class MyMouseMotionListener : public PGMouseMotionListener {
// Mouse is dragged
virtual void mouseDragged(PGMouseEvent* e) {
if (g_iMode != MOUSE_MODE_CLICK) {
PGRectangle rect;
PGGraphics* graph = g_hMyCanvas->updateDragRegion(&rect);
// Draw rect or line in white
graph->setColor(PGCOLOR_WHITE);
graph->setLineWidth(1);
if (g_iMode == MOUSE_MODE_RECT) {
PGRectangle rect;
rect.fromPoints(g_iStartX, g_iStartY, e->getX(), e->getY());
graph->drawRect(rect.x, rect.y, rect.width, rect.height);
} else {
graph->drawLine(g_iStartX, g_iStartY, e->getX(), e->getY());
}
g_hMyCanvas->drawDragRegion(&rect);
// Remember previous point
g_iPrevX = e->getX();
g_iPrevY = e->getY();
}
}
};
// Create panel with radio-buttons
PGPanel* makeLeftPanel() {
// Create a buttongroup for the radio buttons
PGRadioButton* rdbutton;
m_hGroup1 = new PGButtonGroup();
m_hGroup2 = new PGButtonGroup();
// Create panel
PGPanel* panel = new PGPanel();
panel->setLayout(new PGPercentLayout("p p p p p p 10%d p 90%d p p p p p p p p", 4, 0, TRUE));
// Add tool buttons
panel->add(rdbutton = new PGRadioButton("Line"));
rdbutton->setToolTipText("Draw a line");
rdbutton->addActionListener(new MyToolListener("Drag to draw a line", MOUSE_MODE_LINE));
m_hGroup1->add(rdbutton);
panel->add(rdbutton = new PGRadioButton("Arc"));
rdbutton->setToolTipText("Draw a an arc");
rdbutton->addActionListener(new MyToolListener("Drag to draw an arc", MOUSE_MODE_RECT));
m_hGroup1->add(rdbutton);
panel->add(rdbutton = new PGRadioButton("RoundRect"));
rdbutton->setToolTipText("Draw a rectangle with rounded corners");
rdbutton->addActionListener(new MyToolListener("Drag to draw a rectangle with rounded corners", MOUSE_MODE_RECT));
m_hGroup1->add(rdbutton);
panel->add(rdbutton = new PGRadioButton("Star"));
rdbutton->setToolTipText("Draw a star");
rdbutton->addActionListener(new MyToolListener("Drag to draw a star", MOUSE_MODE_RECT));
m_hGroup1->add(rdbutton);
panel->add(rdbutton = new PGRadioButton("Logo"));
rdbutton->setToolTipText("Draw the PortableGUI logo");
rdbutton->addActionListener(new MyToolListener("Click to draw the PortableGUI logo", MOUSE_MODE_CLICK));
m_hGroup1->add(rdbutton);
panel->add(rdbutton = new PGRadioButton("PortableGUI"));
rdbutton->setToolTipText("Draw the text 'PortableGUI'");
rdbutton->addActionListener(new MyToolListener("Drag to draw the text 'PortableGUI'", MOUSE_MODE_RECT));
m_hGroup1->add(rdbutton);
// Add the line size button
PGPanel *entries = new PGPanel();
entries->setLayout(new PGBorderLayout(3, 3));
g_hLineSize = new PGIntegerField(1);
g_hLineSize->setToolTipText("Set the width for drawing lines");
entries->add(g_hLineSize, PGBORDERLAYOUT_CENTER);
entries->add(new PGUpDown(g_hLineSize, 1, 4, 1), PGBORDERLAYOUT_EAST);
panel->add(entries);
// Add color buttons
for (int color = 0; color < 8; color++) {
PGPanel* subpanel = new PGPanel();
subpanel->setLayout(new PGBorderLayout(0, 0));
subpanel->add(rdbutton = new PGRadioButton(), PGBORDERLAYOUT_WEST);
m_hGroup2->add(rdbutton);
subpanel->add(new MyColorCanvas(g_hColors[color]), PGBORDERLAYOUT_CENTER);
panel->add(subpanel);
}
return panel;
}
// Make the panel with the status bar
PGPanel* makeStatus(PGFrame* frame, PGImage* file) {
// Create style for status line
PGStyle* style = new PGStyle();
style->setFont(new PGFont("Dialog", PGFONT_PLAIN, 8));
// Create panel
PGPanel* panel = new PGPanel();
panel->setLayout(new PGBorderLayout(3, 3));
// Create and add status line
PGLabel* status = new PGLabel("Graphics", PGLABEL_SUNKEN);
status->setStyle(style);
panel->add(status, PGBORDERLAYOUT_CENTER);
// Add icon
panel->add(new PGImageViewer(file), PGBORDERLAYOUT_EAST);
// Add panel to main frame
frame->add(panel, PGBORDERLAYOUT_SOUTH);
frame->setStatusDisplay(status);
return panel;
}
// Mainproc is different for Windows and GTK
PGMAINPROC {
PGApplication app;
// Initialize the app using Mainproc args
PGINIT(app);
app.setConsoleEnabled(TRUE);
// Create array for objects
g_hObjects = new PGVector();
PGINCREF(g_hObjects);
// Create main frame window
g_hMainFrame = new PGFrame("PGGraphics");
PGINCREF(g_hMainFrame);
// Load icon for main window
PGColor background(178,178,180);
PGImage* file = new PGImage("../../images/file.bmp", &background, g_hMainFrame);
g_hMainFrame->setIconImage(new PGIcon(file));
// Load PortableGUI logo
g_hLogo = new PGImage("../../images/logo.bmp", PGCOLOR_YELLOW, g_hMainFrame);
PGINCREF(g_hLogo);
// Add window listener to frame
g_hMainFrame->addWindowListener(new MyWindowListener());
// Use simple layoutmanager for the edit control
g_hMainFrame->setLayout(new PGBorderLayout(1,1,3,3));
// Add the panel with the radio-buttons
g_hMainFrame->add(makeLeftPanel(), PGBORDERLAYOUT_WEST);
// Add the drawing canvas
g_hMyCanvas = new MyCanvas();
g_hMyCanvas->addMouseListener(new MyMouseListener());
g_hMyCanvas->addMouseMotionListener(new MyMouseMotionListener());
g_hMainFrame->add(g_hMyCanvas, PGBORDERLAYOUT_CENTER);
// Make and add status bar
g_hStatus = makeStatus(g_hMainFrame, new PGImage("../../images/resize.bmp", &background, g_hMainFrame));
PGINCREF(g_hStatus);
// Pack and show the frame
g_hMainFrame->pack();
g_hMainFrame->setVisible(TRUE);
// Run the main event loop
PGEXITCODE exitCode = app.run();
// Free global references
PGDECREF(g_hObjects);
PGDECREF(g_hMainFrame);
PGDECREF(g_hLogo);
PGDECREF(g_hStatus);
return exitCode;
}
| Syntax highlighted by Code2HTML, v. 0.9 |
Back to PortableGUI