Mostrando entradas con la etiqueta wxogl wxart2d wxdc wxclientdc wxBufferedDC wxwidgets gui programming primitives graphics comparison. Mostrar todas las entradas
Mostrando entradas con la etiqueta wxogl wxart2d wxdc wxclientdc wxBufferedDC wxwidgets gui programming primitives graphics comparison. Mostrar todas las entradas

domingo, 4 de mayo de 2008

WxOGL vs WxDC vs WxArt2D

This Week I was working in the graphical part of the Query Builder and search for all possible options to implement it using wxWidgets, as part of my research I found only three probably options (there are more options but only take in count this by now) where I run and write some test application for evaluation purposes:


1. WxArt2D:
is a graphical library for 2D, the drawing document can be made hierarchical by adding child primitives to a parent primitive, everything that is drawn from within a document, is done by calling drawing methods via a a2dCanvasView through it's device context a2dDrawer2D. A document can have several views open at the same time. And each view can display whatever part of the document. Source: http://wiki.wxwidgets.org/WxArt2d

Pros:
  • It's a multi-document framework.
  • Can draw complex objects in a easy way.
  • Can exists several views of objects in hierarchy.
  • Can save image to svg format.
  • Allow to handled events in graphical objects.
  • It's Highly optimized.
  • Good community support.
Cons:
  • The only way to use it, is downloading directly from CVS.
  • Configuration, Compilation and use can be difficult for begginners because cmake haven't a useful way of explain errors and their solutions (even the simplest).
  • Adds a new level of complexity in a project when the learning curve of understanding of source code grows because use it.
  • If a error related to the library is raised when you use an application (that happens to me with the examples) only have two options: fix by myself (I don't want to do it ) or ask for help (can take long time).
  • I try a demo of electronic parts diagram and I catch a lot of problems and exceptions only testing, without really using it, this don't give me a good advice about stability.
2. WxOGL: it's a good graphical library written when dinosaurs ruled the world :), but in my own words is a very good objects graphical library written in C++ that allow to create some simple and complex objects given to it the possibility of add events & properties.

Pros:
  • Very easy to use.
  • Configuration and use is very simple.
  • Used by pgAdmin right now, not new dependencies needed.
  • Good Stability.
Cons:
  • Poor documented.
  • Doesn't have support of a community.
  • Development status dead.
  • Don't give all control I want from my graphical objects.
  • Library is not good for and architectural pattern like Model View Controller (MVC).
  • Adds an extra overhead for simple graphics needed, forcing to create complex objects that some times are not needed.
  • Use wxDC as their drawing method, not really a cons but an interesting afirmation.
3. WxDC: device context graphic library, allows you to draw stuff manually.

Pros:
  • Have a lot of flavors: wxPaintDC for paint events, wxClientDC can be used outside paint events, wxBufferedDC for flickerless Drawing, Can paint into postscript files with wxPostScriptDC .
  • Give all control to implement the design pattern that I want to use (MVC).
  • It's very stable because their operations are very simple.
  • Allow full control over the way stuff will be painted.
  • Very simple to learn and use.
  • It's integrated with the wxWidgets library not need aditional steps or configurations.
  • Because their simplicity and integration with wx library, it's most probably don't have any issues when compiling source code in different plataforms
  • Very well documented WxWidgets Book Chapter Sample
Cons:
  • It's not as powerful as WxArt2D or WxOGL.
  • All drawing stuff are now responsability of programmer.
  • A bad implementation of drawing maybe can finish with a buggy application.
  • A functional application can take a little more time (not too much) to be completed that using WxOGL or WxArt2D.

My Choice until now it's: WxDC because their simplicity and the full control that give to programmer of doing almost all things needed for a graphical query builder only using graphics primitives (in a pattern like MVC).

I create a very little (and not optimized or good programmed, just functional) hello graphic world proof of concept for a diagram of tables, you can drag and drop tables (just simple squares with text) around application only:

#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#endif

#include "wx/wx.h"

class MyApp: public wxApp
{
virtual bool OnInit();
};


IMPLEMENT_APP(MyApp)



class MyFrame: public wxFrame
{
public:

MyFrame(const wxString& title,
const wxPoint& pos, const wxSize& size);

void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
void MyFrame::OnPaint(wxPaintEvent& event);
void MyFrame::OnMotion(wxMouseEvent& event);
wxRect rectToDraw;
wxRect rectToDraw2;
int xx, xx2;
int yy, yy2;
int pressed;
DECLARE_EVENT_TABLE()
};


bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame( wxT("Hello World"),
wxPoint(50,50), wxSize(800,600) );
frame->Show(TRUE);
SetTopWindow(frame);
frame->xx=10;
frame->yy=10;
frame->xx2=35;
frame->yy2=35;
frame->pressed=0;
return TRUE;
}


enum
{
ID_Quit = 1,
ID_About = 0,

};

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(ID_Quit, MyFrame::OnQuit)
EVT_MENU(ID_About, MyFrame::OnAbout)
EVT_PAINT(MyFrame::OnPaint)
EVT_MOTION(MyFrame::OnMotion)
EVT_LEFT_DOWN(MyFrame::OnMotion)
EVT_LEFT_UP(MyFrame::OnMotion)
END_EVENT_TABLE()



void MyFrame::OnPaint(wxPaintEvent& event)
{
wxPaintDC dc(this);
dc.SetPen(*wxBLACK_PEN);

wxRect tmp(wxPoint(xx, yy), wxSize(70,70));
rectToDraw = tmp;

wxRect tmp2(wxPoint(xx2, yy2), wxSize(70,70));
rectToDraw2 = tmp2;
//Do not draw if not exposed
if (IsExposed(rectToDraw)){
//draw object 1
dc.SetBrush(*wxBLUE_BRUSH);
dc.DrawRectangle(rectToDraw);
dc.DrawText(wxT("Table 1"),xx,yy);
dc.DrawText(wxT("Col1"),xx,yy+12); //use font metrics here
//draw object 2
dc.SetBrush(*wxWHITE_BRUSH);
dc.DrawRectangle(rectToDraw2);
dc.DrawText(wxT("Table 2"),xx2,yy2);
dc.DrawText(wxT("Col1"),xx2,yy2+12);
}
}


MyFrame::MyFrame(const wxString& title,
const wxPoint& pos, const wxSize& size)
: wxFrame((wxFrame *)NULL, -1, title, pos, size)
{
wxMenu *menuFile = new wxMenu;
menuFile->Append( ID_About, wxT("&About..." ));
menuFile->AppendSeparator();
menuFile->Append( ID_Quit, wxT("E&xit" ));

wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append( menuFile, wxT("&File") );

SetMenuBar( menuBar );

CreateStatusBar();
SetStatusText( wxT("Proof of Concept drawing moving objects, just click one and drag & drop [flicker can be eliminated with buffering]") );
}


void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close(TRUE);
}

void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{

wxMessageBox(wxT("This is a Hello Direct Contex Application in wxWidgets"),
wxT("About Hello DC"), wxOK | wxICON_INFORMATION, this);
}


//Change position of objects when mouse is dragged & refresh painting
void MyFrame::OnMotion(wxMouseEvent& event)
{
if(event.ButtonDown()&&pressed==0){
pressed=1;
}
if(event.ButtonUp()){
pressed=0;
}

if (event.Dragging())
{
wxClientDC dc(this);
wxPen pen(*wxRED, 1); // red pen of width 1
dc.SetPen(pen);
dc.DrawPoint(event.GetPosition());
dc.SetPen(wxNullPen);
int posx=event.GetPosition().x;
int posy=event.GetPosition().y;
if(pressed==1 &&( posx-xx>0 && xx+50>posx ) && (posy-yy>0 && yy+50>posy)){
pressed=2;
}else if(pressed==1 &&( posx-xx2>0 && xx2+50>posx ) && (posy-yy2>0 && yy2+50>posy)){
pressed=3;
}

if(pressed==2){
xx=posx-25;
yy=posy-25;
}else if (pressed==3){
xx2=posx-25;
yy2=posy-25;
}

this->Refresh();
}
}