#include "wx/wxprec.h"
#define MAXRECTANGLES 10
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#endif
#include "wx/wx.h"
#include "wx/dcbuffer.h"
enum MenuItems
{
ID_Add = 2,
ID_Quit = 1,
ID_About = 0,
};
class MyApp: public wxApp
{
virtual bool OnInit();
};
IMPLEMENT_APP(MyApp)
class MyCanvas; //Just a prototype
class MyFrame: public wxFrame
{
public:
MyFrame(const wxString& title,
const wxPoint& pos, const wxSize& size);
//Menu Events
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
void OnAddRectangle(wxCommandEvent& event);
//Global Class Variables
MyCanvas *paintArea;
DECLARE_EVENT_TABLE()
};
class MyCanvas: public wxScrolledWindow
{
public:
MyCanvas::MyCanvas(MyFrame *parent, wxSize size);
//MyCanvas Functions
void MyCanvas::DrawAll(wxBufferedDC& bdc);
int MyCanvas::GetIndexSelected();
//MyCanvas Events
void MyCanvas::OnPaint(wxPaintEvent& event);
void MyCanvas::OnMotion(wxMouseEvent& event);
void MyCanvas::OnErase(wxEraseEvent& event);
void MyCanvas::OnEraseBackGround(wxEraseEvent& event);
//Global Class Variables
int rts[MAXRECTANGLES][2];
int rts_Size;
int pressed,posx,posy,selected;
wxSize c_size;
private:
MyFrame *m_owner;
DECLARE_EVENT_TABLE()
};
//**********************Begin implementations
bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame( wxT("Hello World Drawing in 2D"),
wxPoint(50,50), wxSize(800,600) );
frame->Show(TRUE);
SetTopWindow(frame);
//frame->SetScrollbar(wxVERTICAL,0,16,50);
//initialize values
frame->paintArea->rts_Size=0;
for(int i=0;i<MAXRECTANGLES;i++){
frame->paintArea->rts[i][0]=-1;
frame->paintArea->rts[i][1]=-1;
}
frame->paintArea->pressed=-1; //No rectangle selected
return TRUE;
}
//MyFrame Constructor
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_Add, wxT("&Add new Rectangle..." ));
menuFile->Append( ID_About, wxT("A&bout..." ));
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") );
paintArea = new MyCanvas(this,wxSize(800,600));
paintArea->SetScrollbars( 10, 10, 100, 240 );
}
//MyCanvas Constructor
MyCanvas::MyCanvas(MyFrame *parent, wxSize size)
: wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, size,
wxHSCROLL | wxVSCROLL | wxBORDER | wxRETAINED)
{
m_owner = parent;
c_size = size;
}
//Events Table Macros
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(ID_Quit, MyFrame::OnQuit)
EVT_MENU(ID_About, MyFrame::OnAbout)
EVT_MENU(ID_Add, MyFrame::OnAddRectangle)
END_EVENT_TABLE()
BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
EVT_PAINT(MyCanvas::OnPaint)
EVT_MOTION(MyCanvas::OnMotion)
EVT_LEFT_DOWN(MyCanvas::OnMotion)
EVT_LEFT_UP(MyCanvas::OnMotion)
EVT_ERASE_BACKGROUND(MyCanvas::OnEraseBackGround)
//This erase flicker create by wxStaticText when erasing background but this is not needed
END_EVENT_TABLE()
//Events **************************
//Overwrite and disable onEraseBackground Event to avoid Flicker
void MyCanvas::OnEraseBackGround(wxEraseEvent& event) {};
void MyCanvas::OnPaint(wxPaintEvent& event)
{
//Prepare Context for Buffered Draw
wxPaintDC dcc(this);
wxBufferedDC dc(&dcc, c_size );
DrawAll(dc);
}
void MyCanvas::OnMotion(wxMouseEvent& event)
{
posx=event.GetPosition().x;
posy=event.GetPosition().y;
this->CalcUnscrolledPosition(posx,posy,&posx,&posy);
if(event.ButtonDown()&&pressed==-1){
pressed=GetIndexSelected();
selected=pressed;
}
if(event.ButtonUp()){
pressed=-1;
}
if (event.Dragging()&&pressed!=-1)
{
rts[pressed][0]=posx-25;
rts[pressed][1]=posy-25;
}
this->Refresh();
}
//**************************Functions
int MyCanvas::GetIndexSelected(){
int index=-1;
for(int i=0;i<rts_Size;i++){
int x=rts[i][0];
int y=rts[i][1];
if( ((posx-x>0)&&(x+70>posx)) && ((posy-y>0)&&(y+70>posy)) ){
return i;
break;
}
}
return index;
}
void MyCanvas::DrawAll(wxBufferedDC& bdc){
bdc.SetBackground(*wxBLACK_BRUSH);
wxFont f = wxFont(8, wxFONTFAMILY_ROMAN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
wxFont f2 = wxFont(10, wxFONTFAMILY_ROMAN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD);
bdc.Clear();
bdc.SetBrush(*wxWHITE_BRUSH);
for(int i=(rts_Size-1);i>=0;i--){ //i-- to draw in order
int x=rts[i][0];
int y=rts[i][1];
this->CalcScrolledPosition(x,y,&x,&y);
if(x!=-1 && y!=-1){
if(selected==i){
bdc.SetPen(*wxRED_PEN);
}else{
bdc.SetPen(*wxBLACK_PEN);
}
bdc.DrawRectangle(wxRect(wxPoint(x,y), wxSize(70,70)));
bdc.SetFont(f2);
bdc.DrawText(wxT("TName"),x+5,y);
bdc.SetFont(f);
bdc.DrawText(wxT("CName 1"),x+10,y+12); //use font metrics here
bdc.DrawText(wxT("CName 2"),x+10,y+24); //use font metrics here
bdc.DrawText(wxT("CName 3"),x+10,y+36); //use font metrics here
bdc.DrawText(wxT("CName ..."),x+10,y+36); //use font metrics here
}
else{
break;
}
}
}
//**************************Menu Events
void MyFrame::OnAddRectangle(wxCommandEvent& WXUNUSED(event))
{
if(paintArea->rts_Size < MAXRECTANGLES){
paintArea->rts[paintArea->rts_Size][0]= paintArea->rts_Size*10+10;
paintArea->rts[paintArea->rts_Size][1]= paintArea->rts_Size*10+10;
paintArea->rts_Size++;
}
}
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);
}