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.
- 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.
Pros:
- Very easy to use.
- Configuration and use is very simple.
- Used by pgAdmin right now, not new dependencies needed.
- Good Stability.
- 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.
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
- 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();
}
}
1 comentario:
Excellent article ! Exactly what I was looking for.
And excellent little sample !
Thanks for sharing !
Publicar un comentario