added groups of canvasobject and references to groups
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8307 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
afdefa8e84
commit
fcbb6b37bf
@ -41,7 +41,7 @@ public:
|
|||||||
// These are for screen output only therefore use
|
// These are for screen output only therefore use
|
||||||
// int as coordinates.
|
// int as coordinates.
|
||||||
virtual bool IsHit( int x, int y, int margin = 0 );
|
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 xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height );
|
||||||
|
|
||||||
// use doubles later
|
// use doubles later
|
||||||
virtual void Move( int x, int y );
|
virtual void Move( int x, int y );
|
||||||
@ -55,7 +55,7 @@ public:
|
|||||||
virtual void WriteSVG( wxTextOutputStream &stream );
|
virtual void WriteSVG( wxTextOutputStream &stream );
|
||||||
|
|
||||||
wxCanvas *GetOwner() { return m_owner; }
|
wxCanvas *GetOwner() { return m_owner; }
|
||||||
void SetOwner( wxCanvas *owner ) { m_owner = owner; }
|
virtual void SetOwner( wxCanvas *owner ) { m_owner = owner; }
|
||||||
|
|
||||||
bool IsControl() { return m_isControl; }
|
bool IsControl() { return m_isControl; }
|
||||||
bool IsVector() { return m_isVector; }
|
bool IsVector() { return m_isVector; }
|
||||||
@ -74,11 +74,99 @@ protected:
|
|||||||
bool m_isControl;
|
bool m_isControl;
|
||||||
bool m_isVector;
|
bool m_isVector;
|
||||||
bool m_isImage;
|
bool m_isImage;
|
||||||
|
|
||||||
|
//relative boundingbox in parent in pixels
|
||||||
wxRect m_area;
|
wxRect m_area;
|
||||||
|
|
||||||
friend class wxCanvas;
|
friend class wxCanvas;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// wxCanvasObjectGroup
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class wxCanvasObjectGroup
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxCanvasObjectGroup();
|
||||||
|
|
||||||
|
void SetOwner(wxCanvas* canvas);
|
||||||
|
wxCanvas *GetOwner() { return m_owner; }
|
||||||
|
|
||||||
|
virtual void Prepend( wxCanvasObject* obj );
|
||||||
|
virtual void Append( wxCanvasObject* obj );
|
||||||
|
virtual void Insert( size_t before, wxCanvasObject* obj );
|
||||||
|
virtual void Remove( wxCanvasObject* obj );
|
||||||
|
|
||||||
|
virtual void Recreate();
|
||||||
|
void DeleteContents( bool );
|
||||||
|
virtual void Render(int xabs, int yabs,int x, int y, int width, int height );
|
||||||
|
virtual void WriteSVG( wxTextOutputStream &stream );
|
||||||
|
virtual bool IsHit( int x, int y, int margin );
|
||||||
|
virtual wxCanvasObject* IsHitObject( int x, int y, int margin );
|
||||||
|
|
||||||
|
void ExtendArea(int x, int y);
|
||||||
|
|
||||||
|
inline int GetXMin() { return m_minx; }
|
||||||
|
inline int GetYMin() { return m_miny; }
|
||||||
|
inline int GetXMax() { return m_maxx; }
|
||||||
|
inline int GetYMax() { return m_maxy; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
wxCanvas *m_owner;
|
||||||
|
|
||||||
|
//bounding box
|
||||||
|
double m_minx;
|
||||||
|
double m_miny;
|
||||||
|
double m_maxx;
|
||||||
|
double m_maxy;
|
||||||
|
bool m_validbounds;
|
||||||
|
|
||||||
|
wxList m_objects;
|
||||||
|
|
||||||
|
friend class wxCanvas;
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// wxCanvasObjectGroupRef
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class wxCanvasObjectGroupRef: public wxCanvasObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxCanvasObjectGroupRef(double x, double y,wxCanvasObjectGroup* group);
|
||||||
|
|
||||||
|
void SetOwner(wxCanvas* canvas);
|
||||||
|
|
||||||
|
virtual void Recreate();
|
||||||
|
virtual void Render(int xabs, int yabs,int x, int y, int width, int height );
|
||||||
|
virtual void WriteSVG( wxTextOutputStream &stream );
|
||||||
|
virtual bool IsHit( int x, int y, int margin );
|
||||||
|
void Move( int x, int y );
|
||||||
|
|
||||||
|
inline int GetPosX() { return m_x; }
|
||||||
|
inline int GetPosY() { return m_y; }
|
||||||
|
|
||||||
|
void ExtendArea(int x, int y);
|
||||||
|
virtual wxCanvasObject* IsHitObject( int x, int y, int margin );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
//position of the group
|
||||||
|
double m_x;
|
||||||
|
double m_y;
|
||||||
|
|
||||||
|
//reference to the group
|
||||||
|
wxCanvasObjectGroup* m_group;
|
||||||
|
|
||||||
|
//bounding box
|
||||||
|
double m_minx;
|
||||||
|
double m_miny;
|
||||||
|
double m_maxx;
|
||||||
|
double m_maxy;
|
||||||
|
bool m_validbounds;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// wxCanvasRect
|
// wxCanvasRect
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -91,7 +179,7 @@ public:
|
|||||||
|
|
||||||
virtual void Recreate();
|
virtual void Recreate();
|
||||||
|
|
||||||
virtual void Render( int clip_x, int clip_y, int clip_width, int clip_height );
|
virtual void Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height );
|
||||||
virtual void WriteSVG( wxTextOutputStream &stream );
|
virtual void WriteSVG( wxTextOutputStream &stream );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -117,7 +205,7 @@ public:
|
|||||||
|
|
||||||
virtual void Recreate();
|
virtual void Recreate();
|
||||||
|
|
||||||
virtual void Render( int clip_x, int clip_y, int clip_width, int clip_height );
|
virtual void Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height );
|
||||||
virtual void WriteSVG( wxTextOutputStream &stream );
|
virtual void WriteSVG( wxTextOutputStream &stream );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -142,7 +230,7 @@ public:
|
|||||||
|
|
||||||
virtual void Recreate();
|
virtual void Recreate();
|
||||||
|
|
||||||
virtual void Render( int clip_x, int clip_y, int clip_width, int clip_height );
|
virtual void Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height );
|
||||||
virtual void WriteSVG( wxTextOutputStream &stream );
|
virtual void WriteSVG( wxTextOutputStream &stream );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -185,7 +273,7 @@ public:
|
|||||||
|
|
||||||
void Recreate();
|
void Recreate();
|
||||||
|
|
||||||
virtual void Render( int clip_x, int clip_y, int clip_width, int clip_height );
|
virtual void Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height );
|
||||||
virtual void WriteSVG( wxTextOutputStream &stream );
|
virtual void WriteSVG( wxTextOutputStream &stream );
|
||||||
|
|
||||||
void SetRGB( unsigned char red, unsigned char green, unsigned char blue );
|
void SetRGB( unsigned char red, unsigned char green, unsigned char blue );
|
||||||
@ -264,7 +352,8 @@ private:
|
|||||||
int m_bufferY;
|
int m_bufferY;
|
||||||
bool m_needUpdate;
|
bool m_needUpdate;
|
||||||
wxList m_updateRects;
|
wxList m_updateRects;
|
||||||
wxList m_objects;
|
wxCanvasObjectGroup* m_root;
|
||||||
|
|
||||||
unsigned char m_green,m_red,m_blue;
|
unsigned char m_green,m_red,m_blue;
|
||||||
bool m_frozen;
|
bool m_frozen;
|
||||||
bool m_requestNewBuffer;
|
bool m_requestNewBuffer;
|
||||||
|
@ -76,6 +76,53 @@ void MywxCanvasImage::OnMouse(wxMouseEvent &event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MywxCanvasObjectGroupRef: public wxCanvasObjectGroupRef
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MywxCanvasObjectGroupRef(double x, double y, wxCanvasObjectGroup* group);
|
||||||
|
|
||||||
|
void OnMouse(wxMouseEvent &event);
|
||||||
|
|
||||||
|
DECLARE_EVENT_TABLE()
|
||||||
|
};
|
||||||
|
|
||||||
|
BEGIN_EVENT_TABLE(MywxCanvasObjectGroupRef,wxCanvasObjectGroupRef)
|
||||||
|
EVT_MOUSE_EVENTS( MywxCanvasObjectGroupRef::OnMouse )
|
||||||
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
MywxCanvasObjectGroupRef::MywxCanvasObjectGroupRef(double x, double y,wxCanvasObjectGroup* group)
|
||||||
|
:wxCanvasObjectGroupRef(x,y,group)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MywxCanvasObjectGroupRef::OnMouse(wxMouseEvent &event)
|
||||||
|
{
|
||||||
|
static bool first=false;
|
||||||
|
static dx=0;
|
||||||
|
static dy=0;
|
||||||
|
|
||||||
|
//new position of object
|
||||||
|
int x = m_owner->GetDeviceX( event.GetX());
|
||||||
|
int y = m_owner->GetDeviceY( event.GetY());
|
||||||
|
|
||||||
|
if (event.m_leftDown)
|
||||||
|
{ if (!first)
|
||||||
|
{
|
||||||
|
first=true;
|
||||||
|
dx=x;
|
||||||
|
dy=y;
|
||||||
|
}
|
||||||
|
Move(m_x+x-dx,m_y+y-dy);
|
||||||
|
CaptureMouse();
|
||||||
|
}
|
||||||
|
else if (IsCapturedMouse())
|
||||||
|
{
|
||||||
|
ReleaseMouse();
|
||||||
|
first=false;
|
||||||
|
dx=0;dy=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class MyFrame;
|
class MyFrame;
|
||||||
class MyApp;
|
class MyApp;
|
||||||
|
|
||||||
@ -97,6 +144,10 @@ public:
|
|||||||
wxCanvasObject *m_sm2;
|
wxCanvasObject *m_sm2;
|
||||||
wxCanvasObject *m_sm3;
|
wxCanvasObject *m_sm3;
|
||||||
wxCanvasObject *m_sm4;
|
wxCanvasObject *m_sm4;
|
||||||
|
|
||||||
|
MywxCanvasObjectGroupRef *m_ref;
|
||||||
|
MywxCanvasObjectGroupRef *m_ref2;
|
||||||
|
|
||||||
wxTimer *m_timer;
|
wxTimer *m_timer;
|
||||||
wxTextCtrl *m_log;
|
wxTextCtrl *m_log;
|
||||||
|
|
||||||
@ -137,7 +188,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,460) )
|
wxPoint(20,20), wxSize(470,860) )
|
||||||
{
|
{
|
||||||
wxMenu *file_menu = new wxMenu();
|
wxMenu *file_menu = new wxMenu();
|
||||||
file_menu->Append( ID_ABOUT, "&About...");
|
file_menu->Append( ID_ABOUT, "&About...");
|
||||||
@ -158,12 +209,13 @@ MyFrame::MyFrame()
|
|||||||
m_canvas->SetArea( 1400, 600 );
|
m_canvas->SetArea( 1400, 600 );
|
||||||
m_canvas->SetColour( 255, 255, 255 );
|
m_canvas->SetColour( 255, 255, 255 );
|
||||||
|
|
||||||
|
|
||||||
wxBitmap bitmap( smile_xpm );
|
wxBitmap bitmap( smile_xpm );
|
||||||
wxImage image( bitmap );
|
wxImage image( bitmap );
|
||||||
|
|
||||||
m_sm1 = new wxCanvasImage( image, 0,70,16,16 );
|
m_sm1 = new wxCanvasImage( image, 0,70,16,16 );
|
||||||
m_canvas->Append( m_sm1 );
|
m_canvas->Append( m_sm1 );
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 10; i < 300; i+=10)
|
for (i = 10; i < 300; i+=10)
|
||||||
m_canvas->Append( new wxCanvasRect( i,50,3,140, 255,0,0 ) );
|
m_canvas->Append( new wxCanvasRect( i,50,3,140, 255,0,0 ) );
|
||||||
@ -189,9 +241,35 @@ MyFrame::MyFrame()
|
|||||||
m_sm4 = new MywxCanvasImage( image, 0,270,64,32 );
|
m_sm4 = new MywxCanvasImage( image, 0,270,64,32 );
|
||||||
m_canvas->Append( m_sm4 );
|
m_canvas->Append( m_sm4 );
|
||||||
|
|
||||||
|
|
||||||
// m_canvas->Append( new wxCanvasLine( 10,-1500e6,50,300000e6, 0,255,0 ) );
|
// m_canvas->Append( new wxCanvasLine( 10,-1500e6,50,300000e6, 0,255,0 ) );
|
||||||
// m_canvas->Append( new wxCanvasLine( 10,-150000,50,300000, 0,255,0 ) );
|
// m_canvas->Append( new wxCanvasLine( 10,-150000,50,300000, 0,255,0 ) );
|
||||||
|
|
||||||
|
//make a group of wxCanvasObjects
|
||||||
|
wxCanvasObjectGroup* group1 = new wxCanvasObjectGroup();
|
||||||
|
group1->Prepend( new wxCanvasLine( 10,-35,50,190,100,255,0 ) );
|
||||||
|
group1->Prepend( new wxCanvasImage( image, 4,38,32,32 ) );
|
||||||
|
group1->Prepend( new wxCanvasRect(20,-20,50,170,0,20,240 ) );
|
||||||
|
group1->Prepend( new wxCanvasRect(10,20,104,52,0,240,240 ) );
|
||||||
|
|
||||||
|
|
||||||
|
//make another group of wxCanvasObjects
|
||||||
|
wxCanvasObjectGroup* group2 = new wxCanvasObjectGroup();
|
||||||
|
group2->Prepend( new wxCanvasImage( image, 60,38,52,32 ) );
|
||||||
|
group2->Prepend( new wxCanvasRect(10,20,104,52,10,40,10 ) );
|
||||||
|
|
||||||
|
//this a reference to group2 put into group1
|
||||||
|
wxCanvasObjectGroupRef* m_subref = new wxCanvasObjectGroupRef(60,50, group2);
|
||||||
|
group1->Prepend( m_subref );
|
||||||
|
|
||||||
|
//now make two refrences to group1 into root group of the canvas
|
||||||
|
m_ref = new MywxCanvasObjectGroupRef(40,200, group1);
|
||||||
|
m_canvas->Prepend( m_ref );
|
||||||
|
|
||||||
|
m_ref2 = new MywxCanvasObjectGroupRef(80,350, group1);
|
||||||
|
m_canvas->Prepend( m_ref2 );
|
||||||
|
|
||||||
|
|
||||||
m_log = new wxTextCtrl( this, -1, "", wxPoint(0,0), wxSize(100,100), wxTE_MULTILINE );
|
m_log = new wxTextCtrl( this, -1, "", wxPoint(0,0), wxSize(100,100), wxTE_MULTILINE );
|
||||||
wxLog *old_log = wxLog::SetActiveTarget( new wxLogTextCtrl( m_log ) );
|
wxLog *old_log = wxLog::SetActiveTarget( new wxLogTextCtrl( m_log ) );
|
||||||
delete old_log;
|
delete old_log;
|
||||||
@ -220,11 +298,13 @@ void MyFrame::OnQuit( wxCommandEvent &WXUNUSED(event) )
|
|||||||
|
|
||||||
void MyFrame::OnTimer( wxTimerEvent &WXUNUSED(event) )
|
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_sm3->Move( m_sm3->GetX()+1, m_sm3->GetY() );
|
||||||
m_sm4->Move( m_sm4->GetX()+1, m_sm4->GetY() );
|
m_sm4->Move( m_sm4->GetX()+2, m_sm4->GetY() );
|
||||||
|
m_ref->Move( m_ref->GetPosX()+1, m_ref->GetPosY() );
|
||||||
|
m_ref2->Move( m_ref2->GetPosX()+2, m_ref2->GetPosY() );
|
||||||
|
|
||||||
wxWakeUpIdle();
|
wxWakeUpIdle();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,6 +322,7 @@ void MyFrame::OnAbout( wxCommandEvent &WXUNUSED(event) )
|
|||||||
bool MyApp::OnInit()
|
bool MyApp::OnInit()
|
||||||
{
|
{
|
||||||
m_fontpath = getenv("TRUETYPE");
|
m_fontpath = getenv("TRUETYPE");
|
||||||
|
m_fontpath = "c:\WINNT\Fonts\times.ttf";
|
||||||
if ( !m_fontpath )
|
if ( !m_fontpath )
|
||||||
{
|
{
|
||||||
wxLogError("Please set env var TRUETYPE to the path where times.ttf lives.");
|
wxLogError("Please set env var TRUETYPE to the path where times.ttf lives.");
|
||||||
|
@ -114,7 +114,7 @@ bool wxCanvasObject::IsCapturedMouse()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void wxCanvasObject::Render( int clip_x, int clip_y, int clip_width, int clip_height )
|
void wxCanvasObject::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,6 +126,322 @@ void wxCanvasObject::WriteSVG( wxTextOutputStream &stream )
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// wxCanvasObjectGroup
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxCanvasObjectGroup::wxCanvasObjectGroup()
|
||||||
|
{
|
||||||
|
m_validbounds=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCanvasObjectGroup::SetOwner(wxCanvas* canvas)
|
||||||
|
{
|
||||||
|
m_owner=canvas;
|
||||||
|
wxNode *node = m_objects.First();
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
wxCanvasObject *obj = (wxCanvasObject*) node->Data();
|
||||||
|
|
||||||
|
obj->SetOwner(canvas);
|
||||||
|
|
||||||
|
node = node->Next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCanvasObjectGroup::ExtendArea(int x, int y)
|
||||||
|
{
|
||||||
|
if (m_validbounds)
|
||||||
|
{
|
||||||
|
if ( x < m_minx ) m_minx = x;
|
||||||
|
if ( y < m_miny ) m_miny = y;
|
||||||
|
if ( x > m_maxx ) m_maxx = x;
|
||||||
|
if ( y > m_maxy ) m_maxy = y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_validbounds = true;
|
||||||
|
|
||||||
|
m_minx = x;
|
||||||
|
m_miny = y;
|
||||||
|
m_maxx = x;
|
||||||
|
m_maxy = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void wxCanvasObjectGroup::DeleteContents( bool flag)
|
||||||
|
{
|
||||||
|
m_objects.DeleteContents( flag );
|
||||||
|
m_validbounds=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void wxCanvasObjectGroup::Prepend( wxCanvasObject* obj )
|
||||||
|
{
|
||||||
|
m_objects.Insert( obj );
|
||||||
|
m_validbounds=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCanvasObjectGroup::Append( wxCanvasObject* obj )
|
||||||
|
{
|
||||||
|
m_objects.Append( obj );
|
||||||
|
m_validbounds=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCanvasObjectGroup::Insert( size_t before, wxCanvasObject* obj )
|
||||||
|
{
|
||||||
|
m_objects.Insert( before, obj );
|
||||||
|
m_validbounds=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCanvasObjectGroup::Remove( wxCanvasObject* obj )
|
||||||
|
{
|
||||||
|
m_objects.DeleteObject( obj );
|
||||||
|
m_validbounds=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCanvasObjectGroup::Recreate()
|
||||||
|
{
|
||||||
|
m_validbounds=false;
|
||||||
|
wxNode *node = m_objects.First();
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
wxCanvasObject *obj = (wxCanvasObject*) node->Data();
|
||||||
|
|
||||||
|
obj->Recreate();
|
||||||
|
ExtendArea(obj->GetX(),obj->GetY());
|
||||||
|
ExtendArea(obj->GetX()+obj->GetWidth(),obj->GetY()+obj->GetHeight());
|
||||||
|
|
||||||
|
node = node->Next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCanvasObjectGroup::Render(int xabs, int yabs, int x, int y, int width, int height )
|
||||||
|
{
|
||||||
|
wxImage *image = m_owner->GetBuffer();
|
||||||
|
// cycle through all objects
|
||||||
|
wxNode *node = m_objects.First();
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
wxCanvasObject *obj = (wxCanvasObject*) node->Data();
|
||||||
|
|
||||||
|
if (!obj->IsControl())
|
||||||
|
{
|
||||||
|
// If we have 10.000 objects, we will go through
|
||||||
|
// this 10.000 times for each update, so we have
|
||||||
|
// to optimise carefully.
|
||||||
|
int clip_x = xabs + obj->GetX();
|
||||||
|
int clip_width = obj->GetWidth();
|
||||||
|
if (clip_x < x)
|
||||||
|
{
|
||||||
|
clip_width -= x-clip_x;
|
||||||
|
clip_x = x;
|
||||||
|
}
|
||||||
|
if (clip_width > 0)
|
||||||
|
{
|
||||||
|
if (clip_x + clip_width > x + width)
|
||||||
|
clip_width = x+width-clip_x;
|
||||||
|
|
||||||
|
if (clip_width > 0)
|
||||||
|
{
|
||||||
|
int clip_y = yabs + obj->GetY();
|
||||||
|
int clip_height = obj->GetHeight();
|
||||||
|
if (clip_y < y)
|
||||||
|
{
|
||||||
|
clip_height -= y-clip_y;
|
||||||
|
clip_y = y;
|
||||||
|
}
|
||||||
|
if (clip_height > 0)
|
||||||
|
{
|
||||||
|
if (clip_y + clip_height > y + height)
|
||||||
|
clip_height = y+height-clip_y;
|
||||||
|
|
||||||
|
if (clip_height > 0)
|
||||||
|
obj->Render(xabs,yabs, clip_x, clip_y, clip_width, clip_height );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node = node->Next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCanvasObjectGroup::WriteSVG( wxTextOutputStream &stream )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxCanvasObjectGroup::IsHit( int x, int y, int margin )
|
||||||
|
{
|
||||||
|
wxNode *node = m_objects.Last();
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
wxCanvasObject *obj = (wxCanvasObject*) node->Data();
|
||||||
|
|
||||||
|
if (!obj->IsControl())
|
||||||
|
{
|
||||||
|
if (obj->IsHit(x,y,margin))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node = node->Previous();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxCanvasObject* wxCanvasObjectGroup::IsHitObject( int x, int y, int margin )
|
||||||
|
{
|
||||||
|
wxCanvasObject *obj=0;
|
||||||
|
wxNode *node = m_objects.Last();
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
obj=(wxCanvasObject*) node->Data();
|
||||||
|
|
||||||
|
if (!obj->IsControl())
|
||||||
|
{
|
||||||
|
if (obj->IsHit(x,y,margin))
|
||||||
|
{
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node = node->Previous();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// wxCanvasObjectGroupRef
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxCanvasObjectGroupRef::wxCanvasObjectGroupRef(double x, double y, wxCanvasObjectGroup* group)
|
||||||
|
: wxCanvasObject()
|
||||||
|
{
|
||||||
|
m_x = x;
|
||||||
|
m_y = y;
|
||||||
|
m_validbounds=false;
|
||||||
|
m_group=group;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCanvasObjectGroupRef::SetOwner(wxCanvas* canvas)
|
||||||
|
{
|
||||||
|
m_owner=canvas;
|
||||||
|
m_group->SetOwner(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCanvasObjectGroupRef::ExtendArea(int x, int y)
|
||||||
|
{
|
||||||
|
if (m_validbounds)
|
||||||
|
{
|
||||||
|
if ( x < m_minx ) m_minx = x;
|
||||||
|
if ( y < m_miny ) m_miny = y;
|
||||||
|
if ( x > m_maxx ) m_maxx = x;
|
||||||
|
if ( y > m_maxy ) m_maxy = y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_validbounds = true;
|
||||||
|
|
||||||
|
m_minx = x;
|
||||||
|
m_miny = y;
|
||||||
|
m_maxx = x;
|
||||||
|
m_maxy = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCanvasObjectGroupRef::Recreate()
|
||||||
|
{
|
||||||
|
m_validbounds=false;
|
||||||
|
m_group->Recreate();
|
||||||
|
ExtendArea(m_group->GetXMin(),m_group->GetYMin());
|
||||||
|
ExtendArea(m_group->GetXMax(),m_group->GetYMax());
|
||||||
|
|
||||||
|
//set the area in pixels relative to the parent
|
||||||
|
SetArea( m_owner->GetDeviceX( m_x + m_minx ),
|
||||||
|
m_owner->GetDeviceY( m_y + m_miny ),
|
||||||
|
m_owner->GetDeviceWidth( m_maxx-m_minx ),
|
||||||
|
m_owner->GetDeviceHeight( m_maxy-m_miny ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCanvasObjectGroupRef::Render(int xabs, int yabs, int x, int y, int width, int height )
|
||||||
|
{
|
||||||
|
wxImage *image = m_owner->GetBuffer();
|
||||||
|
xabs+=m_owner->GetDeviceX(GetPosX());
|
||||||
|
yabs+=m_owner->GetDeviceY(GetPosY());
|
||||||
|
|
||||||
|
int clip_x = xabs + m_group->GetXMin();
|
||||||
|
int clip_width = m_group->GetXMax()-m_group->GetXMin();
|
||||||
|
if (clip_x < x)
|
||||||
|
{
|
||||||
|
clip_width -= x-clip_x;
|
||||||
|
clip_x = x;
|
||||||
|
}
|
||||||
|
if (clip_width > 0)
|
||||||
|
{
|
||||||
|
if (clip_x + clip_width > x + width)
|
||||||
|
clip_width = x+width-clip_x;
|
||||||
|
|
||||||
|
if (clip_width > 0)
|
||||||
|
{
|
||||||
|
int clip_y = yabs + m_group->GetYMin();
|
||||||
|
int clip_height = m_group->GetYMax()-m_group->GetYMin();
|
||||||
|
if (clip_y < y)
|
||||||
|
{
|
||||||
|
clip_height -= y-clip_y;
|
||||||
|
clip_y = y;
|
||||||
|
}
|
||||||
|
if (clip_height > 0)
|
||||||
|
{
|
||||||
|
if (clip_y + clip_height > y + height)
|
||||||
|
clip_height = y+height-clip_y;
|
||||||
|
|
||||||
|
if (clip_height > 0)
|
||||||
|
m_group->Render(xabs,yabs, clip_x, clip_y, clip_width, clip_height );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCanvasObjectGroupRef::WriteSVG( wxTextOutputStream &stream )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxCanvasObjectGroupRef::IsHit( int x, int y, int margin )
|
||||||
|
{
|
||||||
|
return m_group->IsHit(x-GetPosX(),y-GetPosY(),margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxCanvasObject* wxCanvasObjectGroupRef::IsHitObject( int x, int y, int margin )
|
||||||
|
{
|
||||||
|
return m_group->IsHitObject(x-GetPosX(),y-GetPosY(),margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCanvasObjectGroupRef::Move( int x, int y )
|
||||||
|
{
|
||||||
|
int old_x = m_x;
|
||||||
|
int old_y = m_y;
|
||||||
|
|
||||||
|
m_x = x;
|
||||||
|
m_y = y;
|
||||||
|
|
||||||
|
if (!m_isControl)
|
||||||
|
{
|
||||||
|
// TODO: sometimes faster to merge into 1 Update or
|
||||||
|
// to break up into four
|
||||||
|
m_owner->Update(m_area.x, m_area.y, m_area.width, m_area.height );
|
||||||
|
//calculate the new area in pixels relative to the parent
|
||||||
|
SetArea( m_owner->GetDeviceX( m_x + m_minx ),
|
||||||
|
m_owner->GetDeviceY( m_y + m_miny ),
|
||||||
|
m_owner->GetDeviceWidth( m_maxx-m_minx ),
|
||||||
|
m_owner->GetDeviceHeight( m_maxy-m_miny ) );
|
||||||
|
m_owner->Update( m_area.x, m_area.y, m_area.width, m_area.height );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// wxCanvasRect
|
// wxCanvasRect
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -152,18 +468,18 @@ void wxCanvasRect::Recreate()
|
|||||||
m_owner->GetDeviceHeight( m_height ) );
|
m_owner->GetDeviceHeight( m_height ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxCanvasRect::Render( int clip_x, int clip_y, int clip_width, int clip_height )
|
void wxCanvasRect::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height )
|
||||||
{
|
{
|
||||||
wxImage *image = m_owner->GetBuffer();
|
wxImage *image = m_owner->GetBuffer();
|
||||||
int buffer_x = m_owner->GetBufferX();
|
int buffer_x = m_owner->GetBufferX();
|
||||||
int buffer_y = m_owner->GetBufferY();
|
int buffer_y = m_owner->GetBufferY();
|
||||||
|
|
||||||
int start_y = clip_y - buffer_y;
|
int start_y = clip_y - buffer_y;
|
||||||
int end_y = clip_y+clip_height - buffer_y;
|
int end_y = clip_y+clip_height - buffer_y;
|
||||||
|
|
||||||
int start_x = clip_x - buffer_x;
|
int start_x = clip_x - buffer_x;
|
||||||
int end_x = clip_x+clip_width - buffer_x;
|
int end_x = clip_x+clip_width - buffer_x;
|
||||||
|
|
||||||
// speed up later
|
// speed up later
|
||||||
for (int y = start_y; y < end_y; y++)
|
for (int y = start_y; y < end_y; y++)
|
||||||
for (int x = start_x; x < end_x; x++)
|
for (int x = start_x; x < end_x; x++)
|
||||||
@ -213,22 +529,22 @@ void wxCanvasLine::Recreate()
|
|||||||
SetArea( x1, y1, x2-x1+1, y2-y1+1 );
|
SetArea( x1, y1, x2-x1+1, y2-y1+1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxCanvasLine::Render( int clip_x, int clip_y, int clip_width, int clip_height )
|
void wxCanvasLine::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height )
|
||||||
{
|
{
|
||||||
wxImage *image = m_owner->GetBuffer();
|
wxImage *image = m_owner->GetBuffer();
|
||||||
int buffer_x = m_owner->GetBufferX();
|
int buffer_x = m_owner->GetBufferX();
|
||||||
int buffer_y = m_owner->GetBufferY();
|
int buffer_y = m_owner->GetBufferY();
|
||||||
|
|
||||||
if ((m_area.width == 0) && (m_area.height == 0))
|
if ((m_area.width == 0) && (m_area.height == 0))
|
||||||
{
|
{
|
||||||
image->SetRGB( m_area.x-buffer_x, m_area.y-buffer_y, m_red, m_green, m_blue );
|
image->SetRGB( m_area.x-buffer_x, m_area.y-buffer_y, m_red, m_green, m_blue );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int x1 = m_owner->GetDeviceX( m_x1 );
|
int x1 = xabs + m_owner->GetDeviceX( m_x1 );
|
||||||
int y1 = m_owner->GetDeviceY( m_y1 );
|
int y1 = yabs + m_owner->GetDeviceY( m_y1 );
|
||||||
int x2 = m_owner->GetDeviceX( m_x2 );
|
int x2 = xabs + m_owner->GetDeviceX( m_x2 );
|
||||||
int y2 = m_owner->GetDeviceY( m_y2 );
|
int y2 = yabs + m_owner->GetDeviceY( m_y2 );
|
||||||
|
|
||||||
wxInt32 d, ii, jj, di, ai, si, dj, aj, sj;
|
wxInt32 d, ii, jj, di, ai, si, dj, aj, sj;
|
||||||
di = x1 - x2;
|
di = x1 - x2;
|
||||||
@ -321,13 +637,13 @@ void wxCanvasImage::Recreate()
|
|||||||
m_tmp = m_image.Scale( m_area.width, m_area.height );
|
m_tmp = m_image.Scale( m_area.width, m_area.height );
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxCanvasImage::Render( int clip_x, int clip_y, int clip_width, int clip_height )
|
void wxCanvasImage::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height )
|
||||||
{
|
{
|
||||||
int buffer_x = m_owner->GetBufferX();
|
int buffer_x = m_owner->GetBufferX();
|
||||||
int buffer_y = m_owner->GetBufferY();
|
int buffer_y = m_owner->GetBufferY();
|
||||||
|
|
||||||
if ((clip_x == m_area.x) &&
|
if ((clip_x == xabs + m_area.x) &&
|
||||||
(clip_y == m_area.y) &&
|
(clip_y == yabs + m_area.y) &&
|
||||||
(clip_width == m_area.width) &&
|
(clip_width == m_area.width) &&
|
||||||
(clip_height == m_area.height))
|
(clip_height == m_area.height))
|
||||||
{
|
{
|
||||||
@ -336,8 +652,8 @@ void wxCanvasImage::Render( int clip_x, int clip_y, int clip_width, int clip_hei
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// local coordinates
|
// local coordinates
|
||||||
int start_x = clip_x - m_area.x;
|
int start_x = clip_x - (xabs + m_area.x);
|
||||||
int start_y = clip_y - m_area.y;
|
int start_y = clip_y - (yabs + m_area.y);
|
||||||
|
|
||||||
wxRect rect( start_x, start_y, clip_width, clip_height );
|
wxRect rect( start_x, start_y, clip_width, clip_height );
|
||||||
wxImage sub_image( m_tmp.GetSubImage( rect ) );
|
wxImage sub_image( m_tmp.GetSubImage( rect ) );
|
||||||
@ -426,7 +742,7 @@ wxCanvasText::wxCanvasText( const wxString &text, double x, double y, const wxSt
|
|||||||
|
|
||||||
wxCanvasText::~wxCanvasText()
|
wxCanvasText::~wxCanvasText()
|
||||||
{
|
{
|
||||||
#if wxUSE_FREETYPE
|
#if wxUSE_FREETYPE
|
||||||
wxFaceData *data = (wxFaceData*) m_faceData;
|
wxFaceData *data = (wxFaceData*) m_faceData;
|
||||||
delete data;
|
delete data;
|
||||||
#endif
|
#endif
|
||||||
@ -446,10 +762,10 @@ void wxCanvasText::SetFlag( int flag )
|
|||||||
m_flag = flag;
|
m_flag = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxCanvasText::Render( int clip_x, int clip_y, int clip_width, int clip_height )
|
void wxCanvasText::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height )
|
||||||
{
|
{
|
||||||
if (!m_alpha) return;
|
if (!m_alpha) return;
|
||||||
|
|
||||||
wxImage *image = m_owner->GetBuffer();
|
wxImage *image = m_owner->GetBuffer();
|
||||||
int buffer_x = m_owner->GetBufferX();
|
int buffer_x = m_owner->GetBufferX();
|
||||||
int buffer_y = m_owner->GetBufferY();
|
int buffer_y = m_owner->GetBufferY();
|
||||||
@ -459,7 +775,7 @@ void wxCanvasText::Render( int clip_x, int clip_y, int clip_width, int clip_heig
|
|||||||
int end_x = clip_width + start_x;
|
int end_x = clip_width + start_x;
|
||||||
int start_y = clip_y - m_area.y;
|
int start_y = clip_y - m_area.y;
|
||||||
int end_y = clip_height + start_y;
|
int end_y = clip_height + start_y;
|
||||||
|
|
||||||
for (int y = start_y; y < end_y; y++)
|
for (int y = start_y; y < end_y; y++)
|
||||||
for (int x = start_x; x < end_x; x++)
|
for (int x = start_x; x < end_x; x++)
|
||||||
{
|
{
|
||||||
@ -484,7 +800,7 @@ void wxCanvasText::Render( int clip_x, int clip_y, int clip_width, int clip_heig
|
|||||||
red2 = (red2 * alpha) / 255;
|
red2 = (red2 * alpha) / 255;
|
||||||
green2 = (green2 * alpha) / 255;
|
green2 = (green2 * alpha) / 255;
|
||||||
blue2 = (blue2 * alpha) / 255;
|
blue2 = (blue2 * alpha) / 255;
|
||||||
|
|
||||||
image->SetRGB( image_x, image_y, red1+red2, green1+green2, blue1+blue2 );
|
image->SetRGB( image_x, image_y, red1+red2, green1+green2, blue1+blue2 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -505,23 +821,23 @@ void wxCanvasText::Recreate()
|
|||||||
m_area.height = m_size;
|
m_area.height = m_size;
|
||||||
m_alpha = new unsigned char[100*m_size];
|
m_alpha = new unsigned char[100*m_size];
|
||||||
memset( m_alpha, 0, m_area.width*m_area.height );
|
memset( m_alpha, 0, m_area.width*m_area.height );
|
||||||
|
|
||||||
#if wxUSE_FREETYPE
|
#if wxUSE_FREETYPE
|
||||||
FT_Face face = ((wxFaceData*)m_faceData)->m_face;
|
FT_Face face = ((wxFaceData*)m_faceData)->m_face;
|
||||||
FT_GlyphSlot slot = face->glyph;
|
FT_GlyphSlot slot = face->glyph;
|
||||||
int pen_x = 0;
|
int pen_x = 0;
|
||||||
int pen_y = m_size;
|
int pen_y = m_size;
|
||||||
|
|
||||||
for (int n = 0; n < (int)m_text.Len(); n++)
|
for (int n = 0; n < (int)m_text.Len(); n++)
|
||||||
{
|
{
|
||||||
FT_UInt index = FT_Get_Char_Index( face, m_text[n] );
|
FT_UInt index = FT_Get_Char_Index( face, m_text[n] );
|
||||||
|
|
||||||
int error = FT_Load_Glyph( face, index, FT_LOAD_DEFAULT );
|
int error = FT_Load_Glyph( face, index, FT_LOAD_DEFAULT );
|
||||||
if (error) continue;
|
if (error) continue;
|
||||||
|
|
||||||
error = FT_Render_Glyph( face->glyph, ft_render_mode_normal );
|
error = FT_Render_Glyph( face->glyph, ft_render_mode_normal );
|
||||||
if (error) continue;
|
if (error) continue;
|
||||||
|
|
||||||
FT_Bitmap *bitmap = &slot->bitmap;
|
FT_Bitmap *bitmap = &slot->bitmap;
|
||||||
unsigned char* buffer = bitmap->buffer;
|
unsigned char* buffer = bitmap->buffer;
|
||||||
for (int y = 0; y < bitmap->rows; y++)
|
for (int y = 0; y < bitmap->rows; y++)
|
||||||
@ -534,10 +850,10 @@ void wxCanvasText::Recreate()
|
|||||||
int yy = pen_y - slot->bitmap_top + y;
|
int yy = pen_y - slot->bitmap_top + y;
|
||||||
m_alpha[ yy * m_area.width + xx ] = alpha;
|
m_alpha[ yy * m_area.width + xx ] = alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
pen_x += slot->advance.x >> 6;
|
pen_x += slot->advance.x >> 6;
|
||||||
pen_y += slot->advance.y >> 6;
|
pen_y += slot->advance.y >> 6;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,7 +881,6 @@ wxCanvas::wxCanvas( wxWindow *parent, wxWindowID id,
|
|||||||
m_bufferX = 0;
|
m_bufferX = 0;
|
||||||
m_bufferY = 0;
|
m_bufferY = 0;
|
||||||
m_needUpdate = FALSE;
|
m_needUpdate = FALSE;
|
||||||
m_objects.DeleteContents( TRUE );
|
|
||||||
m_red = 0;
|
m_red = 0;
|
||||||
m_green = 0;
|
m_green = 0;
|
||||||
m_blue = 0;
|
m_blue = 0;
|
||||||
@ -573,6 +888,11 @@ wxCanvas::wxCanvas( wxWindow *parent, wxWindowID id,
|
|||||||
m_captureMouse = (wxCanvasObject*)NULL;
|
m_captureMouse = (wxCanvasObject*)NULL;
|
||||||
m_frozen = TRUE;
|
m_frozen = TRUE;
|
||||||
m_requestNewBuffer = TRUE;
|
m_requestNewBuffer = TRUE;
|
||||||
|
|
||||||
|
//root group always at 0,0
|
||||||
|
m_root = new wxCanvasObjectGroup();
|
||||||
|
m_root->DeleteContents( TRUE );
|
||||||
|
m_root->SetOwner(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCanvas::~wxCanvas()
|
wxCanvas::~wxCanvas()
|
||||||
@ -655,7 +975,7 @@ void wxCanvas::Thaw()
|
|||||||
void wxCanvas::Update( int x, int y, int width, int height, bool blit )
|
void wxCanvas::Update( int x, int y, int width, int height, bool blit )
|
||||||
{
|
{
|
||||||
if (m_frozen) return;
|
if (m_frozen) return;
|
||||||
|
|
||||||
// clip to buffer
|
// clip to buffer
|
||||||
if (x < m_bufferX)
|
if (x < m_bufferX)
|
||||||
{
|
{
|
||||||
@ -702,52 +1022,8 @@ void wxCanvas::Update( int x, int y, int width, int height, bool blit )
|
|||||||
for (int xx = start_x; xx < end_x; xx++)
|
for (int xx = start_x; xx < end_x; xx++)
|
||||||
m_buffer.SetRGB( xx, yy, m_red, m_green, m_blue );
|
m_buffer.SetRGB( xx, yy, m_red, m_green, m_blue );
|
||||||
|
|
||||||
// cycle through all objects
|
m_root->Render(0,0, x, y, width, height );
|
||||||
wxNode *node = m_objects.First();
|
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
wxCanvasObject *obj = (wxCanvasObject*) node->Data();
|
|
||||||
|
|
||||||
if (!obj->IsControl())
|
|
||||||
{
|
|
||||||
// If we have 10.000 objects, we will go through
|
|
||||||
// this 10.000 times for each update, so we have
|
|
||||||
// to optimise carefully.
|
|
||||||
int clip_x = obj->GetX();
|
|
||||||
int clip_width = obj->GetWidth();
|
|
||||||
if (clip_x < x)
|
|
||||||
{
|
|
||||||
clip_width -= x-clip_x;
|
|
||||||
clip_x = x;
|
|
||||||
}
|
|
||||||
if (clip_width > 0)
|
|
||||||
{
|
|
||||||
if (clip_x + clip_width > x + width)
|
|
||||||
clip_width = x+width-clip_x;
|
|
||||||
|
|
||||||
if (clip_width > 0)
|
|
||||||
{
|
|
||||||
int clip_y = obj->GetY();
|
|
||||||
int clip_height = obj->GetHeight();
|
|
||||||
if (clip_y < y)
|
|
||||||
{
|
|
||||||
clip_height -= y-clip_y;
|
|
||||||
clip_y = y;
|
|
||||||
}
|
|
||||||
if (clip_height > 0)
|
|
||||||
{
|
|
||||||
if (clip_y + clip_height > y + height)
|
|
||||||
clip_height = y+height-clip_y;
|
|
||||||
|
|
||||||
if (clip_height > 0)
|
|
||||||
obj->Render( clip_x, clip_y, clip_width, clip_height );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
node = node->Next();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxCanvas::BlitBuffer( wxDC &dc )
|
void wxCanvas::BlitBuffer( wxDC &dc )
|
||||||
@ -760,7 +1036,7 @@ void wxCanvas::BlitBuffer( wxDC &dc )
|
|||||||
wxRect sub_rect( *rect );
|
wxRect sub_rect( *rect );
|
||||||
sub_rect.x -= m_bufferX;
|
sub_rect.x -= m_bufferX;
|
||||||
sub_rect.y -= m_bufferY;
|
sub_rect.y -= m_bufferY;
|
||||||
|
|
||||||
wxImage sub_image( m_buffer.GetSubImage( sub_rect ) );
|
wxImage sub_image( m_buffer.GetSubImage( sub_rect ) );
|
||||||
|
|
||||||
#ifdef __WXGTK__
|
#ifdef __WXGTK__
|
||||||
@ -838,23 +1114,15 @@ int wxCanvas::GetDeviceHeight( double height )
|
|||||||
|
|
||||||
void wxCanvas::Recreate()
|
void wxCanvas::Recreate()
|
||||||
{
|
{
|
||||||
wxNode *node = m_objects.First();
|
m_root->Recreate();
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
wxCanvasObject *obj = (wxCanvasObject*) node->Data();
|
|
||||||
|
|
||||||
obj->Recreate();
|
|
||||||
|
|
||||||
node = node->Next();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxCanvas::Prepend( wxCanvasObject* obj )
|
void wxCanvas::Prepend( wxCanvasObject* obj )
|
||||||
{
|
{
|
||||||
m_objects.Insert( obj );
|
m_root->Prepend( obj );
|
||||||
|
obj->SetOwner(this);
|
||||||
|
|
||||||
obj->SetOwner( this );
|
m_root->Recreate();
|
||||||
obj->Recreate();
|
|
||||||
|
|
||||||
if (!obj->IsControl())
|
if (!obj->IsControl())
|
||||||
Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() );
|
Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() );
|
||||||
@ -862,10 +1130,10 @@ void wxCanvas::Prepend( wxCanvasObject* obj )
|
|||||||
|
|
||||||
void wxCanvas::Append( wxCanvasObject* obj )
|
void wxCanvas::Append( wxCanvasObject* obj )
|
||||||
{
|
{
|
||||||
m_objects.Append( obj );
|
m_root->Append( obj );
|
||||||
|
obj->SetOwner(this);
|
||||||
|
|
||||||
obj->SetOwner( this );
|
m_root->Recreate();
|
||||||
obj->Recreate();
|
|
||||||
|
|
||||||
if (!obj->IsControl())
|
if (!obj->IsControl())
|
||||||
Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() );
|
Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() );
|
||||||
@ -873,10 +1141,10 @@ void wxCanvas::Append( wxCanvasObject* obj )
|
|||||||
|
|
||||||
void wxCanvas::Insert( size_t before, wxCanvasObject* obj )
|
void wxCanvas::Insert( size_t before, wxCanvasObject* obj )
|
||||||
{
|
{
|
||||||
m_objects.Insert( before, obj );
|
m_root->Insert( before, obj );
|
||||||
|
obj->SetOwner(this);
|
||||||
|
|
||||||
obj->SetOwner( this );
|
m_root->Recreate();
|
||||||
obj->Recreate();
|
|
||||||
|
|
||||||
if (!obj->IsControl())
|
if (!obj->IsControl())
|
||||||
Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() );
|
Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() );
|
||||||
@ -890,7 +1158,7 @@ void wxCanvas::Remove( wxCanvasObject* obj )
|
|||||||
int h = obj->GetHeight();
|
int h = obj->GetHeight();
|
||||||
bool ic = obj->IsControl();
|
bool ic = obj->IsControl();
|
||||||
|
|
||||||
m_objects.DeleteObject( obj );
|
m_root->Remove( obj );
|
||||||
|
|
||||||
if (!ic)
|
if (!ic)
|
||||||
Update( x, y, w, h );
|
Update( x, y, w, h );
|
||||||
@ -902,7 +1170,7 @@ void wxCanvas::OnPaint(wxPaintEvent &event)
|
|||||||
PrepareDC( dc );
|
PrepareDC( dc );
|
||||||
|
|
||||||
if (!m_buffer.Ok()) return;
|
if (!m_buffer.Ok()) return;
|
||||||
|
|
||||||
if (m_frozen) return;
|
if (m_frozen) return;
|
||||||
|
|
||||||
m_needUpdate = TRUE;
|
m_needUpdate = TRUE;
|
||||||
@ -944,7 +1212,7 @@ void wxCanvas::ScrollWindow( int dx, int dy, const wxRect* rect )
|
|||||||
CalcUnscrolledPosition( 0, 0, &m_bufferX, &m_bufferY );
|
CalcUnscrolledPosition( 0, 0, &m_bufferX, &m_bufferY );
|
||||||
|
|
||||||
unsigned char* data = m_buffer.GetData();
|
unsigned char* data = m_buffer.GetData();
|
||||||
|
|
||||||
if (dy != 0)
|
if (dy != 0)
|
||||||
{
|
{
|
||||||
if (dy > 0)
|
if (dy > 0)
|
||||||
@ -953,7 +1221,7 @@ void wxCanvas::ScrollWindow( int dx, int dy, const wxRect* rect )
|
|||||||
unsigned char *dest = data + (dy * m_buffer.GetWidth() * 3);
|
unsigned char *dest = data + (dy * m_buffer.GetWidth() * 3);
|
||||||
size_t count = (size_t) (m_buffer.GetWidth() * 3 * (m_buffer.GetHeight()-dy));
|
size_t count = (size_t) (m_buffer.GetWidth() * 3 * (m_buffer.GetHeight()-dy));
|
||||||
memmove( dest, source, count );
|
memmove( dest, source, count );
|
||||||
|
|
||||||
// We update the new buffer area, but there is no need to
|
// We update the new buffer area, but there is no need to
|
||||||
// blit (last param FALSE) since the ensuing paint event will
|
// blit (last param FALSE) since the ensuing paint event will
|
||||||
// do that anyway.
|
// do that anyway.
|
||||||
@ -965,14 +1233,14 @@ void wxCanvas::ScrollWindow( int dx, int dy, const wxRect* rect )
|
|||||||
unsigned char *source = data + (-dy * m_buffer.GetWidth() * 3);
|
unsigned char *source = data + (-dy * m_buffer.GetWidth() * 3);
|
||||||
size_t count = (size_t) (m_buffer.GetWidth() * 3 * (m_buffer.GetHeight()+dy));
|
size_t count = (size_t) (m_buffer.GetWidth() * 3 * (m_buffer.GetHeight()+dy));
|
||||||
memmove( dest, source, count );
|
memmove( dest, source, count );
|
||||||
|
|
||||||
// We update the new buffer area, but there is no need to
|
// We update the new buffer area, but there is no need to
|
||||||
// blit (last param FALSE) since the ensuing paint event will
|
// blit (last param FALSE) since the ensuing paint event will
|
||||||
// do that anyway.
|
// do that anyway.
|
||||||
Update( m_bufferX, m_bufferY+m_buffer.GetHeight()+dy, m_buffer.GetWidth(), -dy, FALSE );
|
Update( m_bufferX, m_bufferY+m_buffer.GetHeight()+dy, m_buffer.GetWidth(), -dy, FALSE );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dx != 0)
|
if (dx != 0)
|
||||||
{
|
{
|
||||||
if (dx > 0)
|
if (dx > 0)
|
||||||
@ -984,7 +1252,7 @@ void wxCanvas::ScrollWindow( int dx, int dy, const wxRect* rect )
|
|||||||
memmove( dest, source, (m_buffer.GetWidth()-dx) * 3 );
|
memmove( dest, source, (m_buffer.GetWidth()-dx) * 3 );
|
||||||
source += m_buffer.GetWidth()*3;
|
source += m_buffer.GetWidth()*3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We update the new buffer area, but there is no need to
|
// We update the new buffer area, but there is no need to
|
||||||
// blit (last param FALSE) since the ensuing paint event will
|
// blit (last param FALSE) since the ensuing paint event will
|
||||||
// do that anyway.
|
// do that anyway.
|
||||||
@ -999,7 +1267,7 @@ void wxCanvas::ScrollWindow( int dx, int dy, const wxRect* rect )
|
|||||||
memmove( dest, source, (m_buffer.GetWidth()+dx) * 3 );
|
memmove( dest, source, (m_buffer.GetWidth()+dx) * 3 );
|
||||||
dest += m_buffer.GetWidth()*3;
|
dest += m_buffer.GetWidth()*3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We update the new buffer area, but there is no need to
|
// We update the new buffer area, but there is no need to
|
||||||
// blit (last param FALSE) since the ensuing paint event will
|
// blit (last param FALSE) since the ensuing paint event will
|
||||||
// do that anyway.
|
// do that anyway.
|
||||||
@ -1035,50 +1303,42 @@ void wxCanvas::OnMouse(wxMouseEvent &event)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxNode *node = m_objects.Last();
|
wxCanvasObject *obj = m_root->IsHitObject(x,y,0);
|
||||||
while (node)
|
|
||||||
|
if (obj && !obj->IsControl())
|
||||||
{
|
{
|
||||||
wxCanvasObject *obj = (wxCanvasObject*) node->Data();
|
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->IsControl())
|
if ((obj != m_lastMouse) && (m_lastMouse != NULL))
|
||||||
{
|
{
|
||||||
if (obj->IsHit(x,y))
|
child_event.SetEventType( wxEVT_LEAVE_WINDOW );
|
||||||
{
|
child_event.SetEventObject( m_lastMouse );
|
||||||
wxMouseEvent child_event( wxEVT_MOTION );
|
child_event.m_x = x - m_lastMouse->GetX();
|
||||||
child_event.SetEventObject( obj );
|
child_event.m_y = y - m_lastMouse->GetY();
|
||||||
child_event.m_x = x - obj->GetX();
|
m_lastMouse->ProcessEvent( child_event );
|
||||||
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))
|
m_lastMouse = obj;
|
||||||
{
|
child_event.SetEventType( wxEVT_ENTER_WINDOW );
|
||||||
child_event.SetEventType( wxEVT_LEAVE_WINDOW );
|
child_event.SetEventObject( m_lastMouse );
|
||||||
child_event.SetEventObject( m_lastMouse );
|
child_event.m_x = x - m_lastMouse->GetX();
|
||||||
child_event.m_x = x - m_lastMouse->GetX();
|
child_event.m_y = y - m_lastMouse->GetY();
|
||||||
child_event.m_y = y - m_lastMouse->GetY();
|
m_lastMouse->ProcessEvent( child_event );
|
||||||
m_lastMouse->ProcessEvent( child_event );
|
|
||||||
|
|
||||||
m_lastMouse = obj;
|
child_event.SetEventType( wxEVT_MOTION );
|
||||||
child_event.SetEventType( wxEVT_ENTER_WINDOW );
|
child_event.SetEventObject( obj );
|
||||||
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->Previous();
|
obj->ProcessEvent( child_event );
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_lastMouse)
|
if (m_lastMouse)
|
||||||
@ -1100,6 +1360,7 @@ void wxCanvas::OnMouse(wxMouseEvent &event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1108,9 +1369,9 @@ void wxCanvas::OnSize(wxSizeEvent &event)
|
|||||||
int w,h;
|
int w,h;
|
||||||
GetClientSize( &w, &h );
|
GetClientSize( &w, &h );
|
||||||
m_buffer = wxImage( w, h );
|
m_buffer = wxImage( w, h );
|
||||||
|
|
||||||
CalcUnscrolledPosition( 0, 0, &m_bufferX, &m_bufferY );
|
CalcUnscrolledPosition( 0, 0, &m_bufferX, &m_bufferY );
|
||||||
|
|
||||||
wxNode *node = m_updateRects.First();
|
wxNode *node = m_updateRects.First();
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user