Added wxCanvasLine, Freeze() and Thaw() and mouse events (untested)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8241 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -34,6 +34,8 @@ public:
|
|||||||
wxCanvasObject( int x, int y, int width, int height );
|
wxCanvasObject( int x, int y, int width, int height );
|
||||||
|
|
||||||
virtual void Move( int x, int y );
|
virtual void Move( int x, int y );
|
||||||
|
virtual bool IsHit( int x, int y, int margin = 0 );
|
||||||
|
|
||||||
virtual void Render( int clip_x, int clip_y, int clip_width, int clip_height );
|
virtual void Render( int clip_x, int clip_y, int clip_width, int clip_height );
|
||||||
virtual void WriteSVG( wxTextOutputStream &stream );
|
virtual void WriteSVG( wxTextOutputStream &stream );
|
||||||
|
|
||||||
@@ -76,6 +78,24 @@ private:
|
|||||||
unsigned char m_blue;
|
unsigned char m_blue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// wxCanvasLine
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class wxCanvasLine: public wxCanvasObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxCanvasLine( int x, int y, int w, int h, unsigned char red, unsigned char green, unsigned char blue );
|
||||||
|
|
||||||
|
virtual void Render( int clip_x, int clip_y, int clip_width, int clip_height );
|
||||||
|
virtual void WriteSVG( wxTextOutputStream &stream );
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned char m_red;
|
||||||
|
unsigned char m_green;
|
||||||
|
unsigned char m_blue;
|
||||||
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// wxCanvasImage
|
// wxCanvasImage
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -125,6 +145,7 @@ public:
|
|||||||
void CreateBuffer();
|
void CreateBuffer();
|
||||||
void SetRGB( unsigned char red, unsigned char green, unsigned char blue );
|
void SetRGB( unsigned char red, unsigned char green, unsigned char blue );
|
||||||
void SetFlag( int flag );
|
void SetFlag( int flag );
|
||||||
|
int GetFlag() { return m_flag; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wxString m_text;
|
wxString m_text;
|
||||||
@@ -157,6 +178,9 @@ public:
|
|||||||
virtual void Update( int x, int y, int width, int height );
|
virtual void Update( int x, int y, int width, int height );
|
||||||
virtual void UpdateNow();
|
virtual void UpdateNow();
|
||||||
|
|
||||||
|
virtual void Freeze();
|
||||||
|
virtual void Thaw();
|
||||||
|
|
||||||
virtual void Prepend( wxCanvasObject* obj );
|
virtual void Prepend( wxCanvasObject* obj );
|
||||||
virtual void Append( wxCanvasObject* obj );
|
virtual void Append( wxCanvasObject* obj );
|
||||||
virtual void Insert( size_t before, wxCanvasObject* obj );
|
virtual void Insert( size_t before, wxCanvasObject* obj );
|
||||||
@@ -173,6 +197,9 @@ private:
|
|||||||
wxList m_updateRects;
|
wxList m_updateRects;
|
||||||
wxList m_objects;
|
wxList m_objects;
|
||||||
unsigned char m_green,m_red,m_blue;
|
unsigned char m_green,m_red,m_blue;
|
||||||
|
bool m_frozen;
|
||||||
|
wxCanvasObject *m_lastMouse;
|
||||||
|
|
||||||
|
|
||||||
friend class wxCanvasObject;
|
friend class wxCanvasObject;
|
||||||
|
|
||||||
|
@@ -20,6 +20,8 @@
|
|||||||
#include <wx/image.h>
|
#include <wx/image.h>
|
||||||
#include <wx/file.h>
|
#include <wx/file.h>
|
||||||
#include <wx/timer.h>
|
#include <wx/timer.h>
|
||||||
|
#include <wx/log.h>
|
||||||
|
|
||||||
|
|
||||||
#include "smile.xpm"
|
#include "smile.xpm"
|
||||||
|
|
||||||
@@ -46,7 +48,10 @@ public:
|
|||||||
wxCanvas *m_canvas;
|
wxCanvas *m_canvas;
|
||||||
wxCanvasObject *m_sm1;
|
wxCanvasObject *m_sm1;
|
||||||
wxCanvasObject *m_sm2;
|
wxCanvasObject *m_sm2;
|
||||||
|
wxCanvasObject *m_sm3;
|
||||||
|
wxCanvasObject *m_sm4;
|
||||||
wxTimer *m_timer;
|
wxTimer *m_timer;
|
||||||
|
wxTextCtrl *m_log;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DECLARE_DYNAMIC_CLASS(MyFrame)
|
DECLARE_DYNAMIC_CLASS(MyFrame)
|
||||||
@@ -85,7 +90,7 @@ END_EVENT_TABLE()
|
|||||||
|
|
||||||
MyFrame::MyFrame()
|
MyFrame::MyFrame()
|
||||||
: wxFrame( (wxFrame *)NULL, -1, "wxCanvas sample",
|
: wxFrame( (wxFrame *)NULL, -1, "wxCanvas sample",
|
||||||
wxPoint(20,20), wxSize(470,360) )
|
wxPoint(20,20), wxSize(470,460) )
|
||||||
{
|
{
|
||||||
wxMenu *file_menu = new wxMenu();
|
wxMenu *file_menu = new wxMenu();
|
||||||
file_menu->Append( ID_ABOUT, "&About...");
|
file_menu->Append( ID_ABOUT, "&About...");
|
||||||
@@ -103,6 +108,8 @@ MyFrame::MyFrame()
|
|||||||
|
|
||||||
m_canvas = new wxCanvas( this, -1, wxPoint(0,0), wxSize(10,10) );
|
m_canvas = new wxCanvas( this, -1, wxPoint(0,0), wxSize(10,10) );
|
||||||
|
|
||||||
|
m_canvas->Freeze();
|
||||||
|
|
||||||
m_canvas->SetArea( 400, 600 );
|
m_canvas->SetArea( 400, 600 );
|
||||||
m_canvas->SetColour( 255, 255, 255 );
|
m_canvas->SetColour( 255, 255, 255 );
|
||||||
|
|
||||||
@@ -128,6 +135,29 @@ MyFrame::MyFrame()
|
|||||||
m_canvas->Append( new wxCanvasText( "Hello", 180, 50,
|
m_canvas->Append( new wxCanvasText( "Hello", 180, 50,
|
||||||
wxGetApp().GetFontPath() + "/times.ttf", 20 ) );
|
wxGetApp().GetFontPath() + "/times.ttf", 20 ) );
|
||||||
|
|
||||||
|
m_sm3 = new wxCanvasImage( image, 0, 210 );
|
||||||
|
m_canvas->Append( m_sm3 );
|
||||||
|
|
||||||
|
for (i = 10; i < 300; i+=10)
|
||||||
|
m_canvas->Append( new wxCanvasLine( 10,150,i,200, 0,255,0 ) );
|
||||||
|
|
||||||
|
m_sm4 = new wxCanvasImage( image, 0, 270 );
|
||||||
|
m_canvas->Append( m_sm4 );
|
||||||
|
|
||||||
|
m_canvas->Thaw();
|
||||||
|
|
||||||
|
m_log = new wxTextCtrl( this, -1, "", wxPoint(0,0), wxSize(100,100), wxTE_MULTILINE );
|
||||||
|
wxLog *old_log = wxLog::SetActiveTarget( new wxLogTextCtrl( m_log ) );
|
||||||
|
delete old_log;
|
||||||
|
|
||||||
|
wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
|
||||||
|
|
||||||
|
topsizer->Add( m_canvas, 1, wxEXPAND );
|
||||||
|
topsizer->Add( m_log, 0, wxEXPAND );
|
||||||
|
|
||||||
|
SetAutoLayout( TRUE );
|
||||||
|
SetSizer( topsizer );
|
||||||
|
|
||||||
m_timer = new wxTimer( this );
|
m_timer = new wxTimer( this );
|
||||||
m_timer->Start( 100, FALSE );
|
m_timer->Start( 100, FALSE );
|
||||||
}
|
}
|
||||||
@@ -146,6 +176,8 @@ void MyFrame::OnTimer( wxTimerEvent &WXUNUSED(event) )
|
|||||||
{
|
{
|
||||||
m_sm1->Move( m_sm1->GetX()+1, m_sm1->GetY() );
|
m_sm1->Move( m_sm1->GetX()+1, m_sm1->GetY() );
|
||||||
m_sm2->Move( m_sm2->GetX()+1, m_sm2->GetY() );
|
m_sm2->Move( m_sm2->GetX()+1, m_sm2->GetY() );
|
||||||
|
m_sm3->Move( m_sm3->GetX()+1, m_sm3->GetY() );
|
||||||
|
m_sm4->Move( m_sm4->GetX()+1, m_sm4->GetY() );
|
||||||
wxWakeUpIdle();
|
wxWakeUpIdle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -72,6 +72,14 @@ void wxCanvasObject::Move( int x, int y )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxCanvasObject::IsHit( int x, int y, int margin )
|
||||||
|
{
|
||||||
|
return ((x >= m_area.x-margin) &&
|
||||||
|
(x <= m_area.x+m_area.width+margin) &&
|
||||||
|
(y >= m_area.y-margin) &&
|
||||||
|
(y <= m_area.y+m_area.height+margin));
|
||||||
|
}
|
||||||
|
|
||||||
void wxCanvasObject::WriteSVG( wxTextOutputStream &stream )
|
void wxCanvasObject::WriteSVG( wxTextOutputStream &stream )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -105,6 +113,93 @@ void wxCanvasRect::WriteSVG( wxTextOutputStream &stream )
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// wxCanvasLine
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxCanvasLine::wxCanvasLine( int x, int y, int w, int h, unsigned char red, unsigned char green, unsigned char blue )
|
||||||
|
: wxCanvasObject( x, y, w, h )
|
||||||
|
{
|
||||||
|
m_red = red;
|
||||||
|
m_green = green;
|
||||||
|
m_blue = blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCanvasLine::Render( int clip_x, int clip_y, int clip_width, int clip_height )
|
||||||
|
{
|
||||||
|
wxImage *image = m_owner->GetBuffer();
|
||||||
|
|
||||||
|
if ((m_area.width == 0) && (m_area.height == 0))
|
||||||
|
{
|
||||||
|
image->SetRGB( m_area.x, m_area.y, m_red, m_green, m_blue );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int x1 = m_area.x;
|
||||||
|
int y1 = m_area.y;
|
||||||
|
int x2 = m_area.x+m_area.width;
|
||||||
|
int y2 = m_area.y+m_area.height;
|
||||||
|
|
||||||
|
wxInt32 d, ii, jj, di, ai, si, dj, aj, sj;
|
||||||
|
di = x1 - x2;
|
||||||
|
ai = abs(di) << 1;
|
||||||
|
si = (di < 0)? -1 : 1;
|
||||||
|
dj = y1 - y2;
|
||||||
|
aj = abs(dj) << 1;
|
||||||
|
sj = (dj < 0)? -1 : 1;
|
||||||
|
|
||||||
|
ii = x2;
|
||||||
|
jj = y2;
|
||||||
|
|
||||||
|
if (ai > aj)
|
||||||
|
{
|
||||||
|
// iterate over i
|
||||||
|
d = aj - (ai >> 1);
|
||||||
|
|
||||||
|
while (ii != x1)
|
||||||
|
{
|
||||||
|
if ((ii >= clip_x) && (ii <= clip_x+clip_width) &&
|
||||||
|
(jj >= clip_y) && (jj <= clip_y+clip_height))
|
||||||
|
{
|
||||||
|
image->SetRGB( ii, jj, m_red, m_blue, m_green );
|
||||||
|
}
|
||||||
|
if (d >= 0)
|
||||||
|
{
|
||||||
|
jj += sj;
|
||||||
|
d -= ai;
|
||||||
|
}
|
||||||
|
ii += si;
|
||||||
|
d += aj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// iterate over j
|
||||||
|
d = ai - (aj >> 1);
|
||||||
|
|
||||||
|
while (jj != y1)
|
||||||
|
{
|
||||||
|
if ((ii >= clip_x) && (ii <= clip_x+clip_width) &&
|
||||||
|
(jj >= clip_y) && (jj <= clip_y+clip_height))
|
||||||
|
{
|
||||||
|
image->SetRGB( ii, jj, m_red, m_blue, m_green );
|
||||||
|
}
|
||||||
|
if (d >= 0)
|
||||||
|
{
|
||||||
|
ii += si;
|
||||||
|
d -= aj;
|
||||||
|
}
|
||||||
|
jj += sj;
|
||||||
|
d += ai;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCanvasLine::WriteSVG( wxTextOutputStream &stream )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// wxCanvasImage
|
// wxCanvasImage
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -349,6 +444,8 @@ wxCanvas::wxCanvas( wxWindow *parent, wxWindowID id,
|
|||||||
m_red = 0;
|
m_red = 0;
|
||||||
m_green = 0;
|
m_green = 0;
|
||||||
m_blue = 0;
|
m_blue = 0;
|
||||||
|
m_lastMouse = (wxCanvasObject*)NULL;
|
||||||
|
m_frozen = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCanvas::~wxCanvas()
|
wxCanvas::~wxCanvas()
|
||||||
@@ -375,6 +472,8 @@ void wxCanvas::SetColour( unsigned char red, unsigned char green, unsigned char
|
|||||||
m_green = green;
|
m_green = green;
|
||||||
m_blue = blue;
|
m_blue = blue;
|
||||||
|
|
||||||
|
if (m_frozen) return;
|
||||||
|
|
||||||
unsigned char *data = m_buffer.GetData();
|
unsigned char *data = m_buffer.GetData();
|
||||||
|
|
||||||
for (int y = 0; y < m_buffer.GetHeight(); y++)
|
for (int y = 0; y < m_buffer.GetHeight(); y++)
|
||||||
@@ -389,8 +488,31 @@ void wxCanvas::SetColour( unsigned char red, unsigned char green, unsigned char
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxCanvas::Freeze()
|
||||||
|
{
|
||||||
|
m_frozen = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCanvas::Thaw()
|
||||||
|
{
|
||||||
|
wxNode *node = m_updateRects.First();
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
wxRect *rect = (wxRect*) node->Data();
|
||||||
|
delete rect;
|
||||||
|
m_updateRects.DeleteNode( node );
|
||||||
|
node = m_updateRects.First();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_frozen = FALSE;
|
||||||
|
|
||||||
|
Update( 0, 0, m_buffer.GetWidth(), m_buffer.GetHeight() );
|
||||||
|
}
|
||||||
|
|
||||||
void wxCanvas::Update( int x, int y, int width, int height )
|
void wxCanvas::Update( int x, int y, int width, int height )
|
||||||
{
|
{
|
||||||
|
if (m_frozen) return;
|
||||||
|
|
||||||
// clip to buffer
|
// clip to buffer
|
||||||
if (x < 0)
|
if (x < 0)
|
||||||
{
|
{
|
||||||
@@ -620,7 +742,79 @@ void wxCanvas::OnPaint(wxPaintEvent &event)
|
|||||||
|
|
||||||
void wxCanvas::OnMouse(wxMouseEvent &event)
|
void wxCanvas::OnMouse(wxMouseEvent &event)
|
||||||
{
|
{
|
||||||
// Propagate to objects here
|
// should we implement mouse capture ?
|
||||||
|
|
||||||
|
int x = event.GetX();
|
||||||
|
int y = event.GetY();
|
||||||
|
CalcUnscrolledPosition( x, y, &x, &y );
|
||||||
|
|
||||||
|
if (event.GetEventType() == wxEVT_MOTION)
|
||||||
|
{
|
||||||
|
wxNode *node = m_objects.First();
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
wxCanvasObject *obj = (wxCanvasObject*) node->Data();
|
||||||
|
|
||||||
|
if (!obj->IsControl())
|
||||||
|
{
|
||||||
|
if (obj->IsHit(x,y))
|
||||||
|
{
|
||||||
|
wxMouseEvent child_event( wxEVT_MOTION );
|
||||||
|
child_event.SetEventObject( obj );
|
||||||
|
child_event.m_x = x + obj->GetX();
|
||||||
|
child_event.m_y = y + obj->GetY();
|
||||||
|
child_event.m_leftDown = event.m_leftDown;
|
||||||
|
child_event.m_rightDown = event.m_rightDown;
|
||||||
|
child_event.m_middleDown = event.m_middleDown;
|
||||||
|
child_event.m_controlDown = event.m_controlDown;
|
||||||
|
child_event.m_shiftDown = event.m_shiftDown;
|
||||||
|
child_event.m_altDown = event.m_altDown;
|
||||||
|
child_event.m_metaDown = event.m_metaDown;
|
||||||
|
|
||||||
|
if ((obj != m_lastMouse) && (m_lastMouse != NULL))
|
||||||
|
{
|
||||||
|
child_event.SetEventType( wxEVT_LEAVE_WINDOW );
|
||||||
|
child_event.SetEventObject( m_lastMouse );
|
||||||
|
child_event.m_x = x + m_lastMouse->GetX();
|
||||||
|
child_event.m_y = y + m_lastMouse->GetY();
|
||||||
|
m_lastMouse->ProcessEvent( child_event );
|
||||||
|
|
||||||
|
m_lastMouse = obj;
|
||||||
|
child_event.SetEventType( wxEVT_ENTER_WINDOW );
|
||||||
|
child_event.SetEventObject( m_lastMouse );
|
||||||
|
child_event.m_x = x + m_lastMouse->GetX();
|
||||||
|
child_event.m_y = y + m_lastMouse->GetY();
|
||||||
|
m_lastMouse->ProcessEvent( child_event );
|
||||||
|
|
||||||
|
child_event.SetEventType( wxEVT_MOTION );
|
||||||
|
child_event.SetEventObject( obj );
|
||||||
|
}
|
||||||
|
obj->ProcessEvent( child_event );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node = node->Next();
|
||||||
|
}
|
||||||
|
if (m_lastMouse)
|
||||||
|
{
|
||||||
|
wxMouseEvent child_event( wxEVT_LEAVE_WINDOW );
|
||||||
|
child_event.SetEventObject( m_lastMouse );
|
||||||
|
child_event.m_x = x + m_lastMouse->GetX();
|
||||||
|
child_event.m_y = y + m_lastMouse->GetY();
|
||||||
|
child_event.m_leftDown = event.m_leftDown;
|
||||||
|
child_event.m_rightDown = event.m_rightDown;
|
||||||
|
child_event.m_middleDown = event.m_middleDown;
|
||||||
|
child_event.m_controlDown = event.m_controlDown;
|
||||||
|
child_event.m_shiftDown = event.m_shiftDown;
|
||||||
|
child_event.m_altDown = event.m_altDown;
|
||||||
|
child_event.m_metaDown = event.m_metaDown;
|
||||||
|
m_lastMouse->ProcessEvent( child_event );
|
||||||
|
|
||||||
|
m_lastMouse = (wxCanvasObject*) NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxCanvas::OnSize(wxSizeEvent &event)
|
void wxCanvas::OnSize(wxSizeEvent &event)
|
||||||
|
Reference in New Issue
Block a user