Trying to make wxCanvas less simple.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8273 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2000-09-06 13:08:28 +00:00
parent 0e929d5fd6
commit 41328253cd
3 changed files with 133 additions and 44 deletions

View File

@@ -222,7 +222,7 @@ public:
virtual void SetArea( int width, int height ); virtual void SetArea( int width, int height );
virtual void SetColour( unsigned char red, unsigned char green, unsigned char blue ); virtual void SetColour( unsigned char red, unsigned char green, unsigned char blue );
virtual void Update( int x, int y, int width, int height ); virtual void Update( int x, int y, int width, int height, bool blit = TRUE );
virtual void UpdateNow(); virtual void UpdateNow();
virtual void Freeze(); virtual void Freeze();
@@ -242,7 +242,12 @@ public:
// ... and call this to tell all objets to recreate then // ... and call this to tell all objets to recreate then
virtual void Recreate(); virtual void Recreate();
wxImage *GetBuffer() { return &m_buffer; } inline wxImage *GetBuffer() { return &m_buffer; }
inline int GetBufferX() { return m_bufferX; }
inline int GetBufferY() { return m_bufferY; }
inline int GetBufferWidth() { return m_buffer.GetWidth(); }
inline int GetBufferHeight() { return m_buffer.GetHeight(); }
bool NeedUpdate() { return m_needUpdate; } bool NeedUpdate() { return m_needUpdate; }
bool IsFrozen() { return m_frozen; } bool IsFrozen() { return m_frozen; }
@@ -250,14 +255,19 @@ public:
void SetCaptureMouse( wxCanvasObject *obj ); void SetCaptureMouse( wxCanvasObject *obj );
virtual void ScrollWindow( int dx, int dy,
const wxRect* rect = (wxRect *) NULL );
private: private:
wxImage m_buffer; wxImage m_buffer;
int m_bufferX;
int m_bufferY;
bool m_needUpdate; bool m_needUpdate;
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; bool m_frozen;
bool m_requestNewBuffer;
wxCanvasObject *m_lastMouse; wxCanvasObject *m_lastMouse;
wxCanvasObject *m_captureMouse; wxCanvasObject *m_captureMouse;

View File

@@ -53,8 +53,8 @@ MywxCanvasImage::MywxCanvasImage( const wxImage &image, double x, double y, doub
void MywxCanvasImage::OnMouse(wxMouseEvent &event) void MywxCanvasImage::OnMouse(wxMouseEvent &event)
{ {
static bool first=false; static bool first=false;
static dx=0; static int dx=0;
static dy=0; static int dy=0;
int x = event.GetX(); int x = event.GetX();
int y = event.GetY(); int y = event.GetY();
@@ -155,8 +155,6 @@ 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 );
@@ -194,8 +192,6 @@ 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->Thaw();
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;
@@ -228,6 +224,7 @@ void MyFrame::OnTimer( wxTimerEvent &WXUNUSED(event) )
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()+1, m_sm4->GetY() );
wxWakeUpIdle(); wxWakeUpIdle();
} }

View File

@@ -155,9 +155,18 @@ void wxCanvasRect::Recreate()
void wxCanvasRect::Render( int clip_x, int clip_y, int clip_width, int clip_height ) void wxCanvasRect::Render( 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_y = m_owner->GetBufferY();
int start_y = clip_y - buffer_y;
int end_y = clip_y+clip_height - buffer_y;
int start_x = clip_x - buffer_x;
int end_x = clip_x+clip_width - buffer_x;
// speed up later // speed up later
for (int y = clip_y; y < clip_y+clip_height; y++) for (int y = start_y; y < end_y; y++)
for (int x = clip_x; x < clip_x+clip_width; x++) for (int x = start_x; x < end_x; x++)
image->SetRGB( x, y, m_red, m_green, m_blue ); image->SetRGB( x, y, m_red, m_green, m_blue );
} }
@@ -207,10 +216,12 @@ void wxCanvasLine::Recreate()
void wxCanvasLine::Render( int clip_x, int clip_y, int clip_width, int clip_height ) void wxCanvasLine::Render( 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_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, m_area.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
{ {
@@ -240,7 +251,7 @@ void wxCanvasLine::Render( int clip_x, int clip_y, int clip_width, int clip_heig
if ((ii >= clip_x) && (ii <= clip_x+clip_width) && if ((ii >= clip_x) && (ii <= clip_x+clip_width) &&
(jj >= clip_y) && (jj <= clip_y+clip_height)) (jj >= clip_y) && (jj <= clip_y+clip_height))
{ {
image->SetRGB( ii, jj, m_red, m_blue, m_green ); image->SetRGB( ii-buffer_x, jj-buffer_y, m_red, m_blue, m_green );
} }
if (d >= 0) if (d >= 0)
{ {
@@ -261,7 +272,7 @@ void wxCanvasLine::Render( int clip_x, int clip_y, int clip_width, int clip_heig
if ((ii >= clip_x) && (ii <= clip_x+clip_width) && if ((ii >= clip_x) && (ii <= clip_x+clip_width) &&
(jj >= clip_y) && (jj <= clip_y+clip_height)) (jj >= clip_y) && (jj <= clip_y+clip_height))
{ {
image->SetRGB( ii, jj, m_red, m_blue, m_green ); image->SetRGB( ii-buffer_x, jj-buffer_y, m_red, m_blue, m_green );
} }
if (d >= 0) if (d >= 0)
{ {
@@ -312,12 +323,15 @@ void wxCanvasImage::Recreate()
void wxCanvasImage::Render( int clip_x, int clip_y, int clip_width, int clip_height ) void wxCanvasImage::Render( int clip_x, int clip_y, int clip_width, int clip_height )
{ {
int buffer_x = m_owner->GetBufferX();
int buffer_y = m_owner->GetBufferY();
if ((clip_x == m_area.x) && if ((clip_x == m_area.x) &&
(clip_y == m_area.y) && (clip_y == m_area.y) &&
(clip_width == m_area.width) && (clip_width == m_area.width) &&
(clip_height == m_area.height)) (clip_height == m_area.height))
{ {
m_owner->GetBuffer()->Paste( m_tmp, clip_x, clip_y ); m_owner->GetBuffer()->Paste( m_tmp, clip_x-buffer_x, clip_y-buffer_y );
} }
else else
{ {
@@ -327,7 +341,7 @@ void wxCanvasImage::Render( int clip_x, int clip_y, int clip_width, int clip_hei
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 ) );
m_owner->GetBuffer()->Paste( sub_image, clip_x, clip_y ); m_owner->GetBuffer()->Paste( sub_image, clip_x-buffer_x, clip_y-buffer_y );
} }
} }
@@ -437,6 +451,8 @@ void wxCanvasText::Render( int clip_x, int clip_y, int clip_width, int clip_heig
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_y = m_owner->GetBufferY();
// local coordinates // local coordinates
int start_x = clip_x - m_area.x; int start_x = clip_x - m_area.x;
@@ -450,8 +466,8 @@ void wxCanvasText::Render( int clip_x, int clip_y, int clip_width, int clip_heig
int alpha = m_alpha[y*m_area.width + x]; int alpha = m_alpha[y*m_area.width + x];
if (alpha) if (alpha)
{ {
int image_x = m_area.x+x; int image_x = m_area.x+x - buffer_x;
int image_y = m_area.y+y; int image_y = m_area.y+y - buffer_y;
if (alpha == 255) if (alpha == 255)
{ {
image->SetRGB( image_x, image_y, m_red, m_green, m_blue ); image->SetRGB( image_x, image_y, m_red, m_green, m_blue );
@@ -545,6 +561,8 @@ wxCanvas::wxCanvas( wxWindow *parent, wxWindowID id,
const wxPoint &position, const wxSize& size, long style ) : const wxPoint &position, const wxSize& size, long style ) :
wxScrolledWindow( parent, id, position, size, style ) wxScrolledWindow( parent, id, position, size, style )
{ {
m_bufferX = 0;
m_bufferY = 0;
m_needUpdate = FALSE; m_needUpdate = FALSE;
m_objects.DeleteContents( TRUE ); m_objects.DeleteContents( TRUE );
m_red = 0; m_red = 0;
@@ -552,7 +570,8 @@ wxCanvas::wxCanvas( wxWindow *parent, wxWindowID id,
m_blue = 0; m_blue = 0;
m_lastMouse = (wxCanvasObject*)NULL; m_lastMouse = (wxCanvasObject*)NULL;
m_captureMouse = (wxCanvasObject*)NULL; m_captureMouse = (wxCanvasObject*)NULL;
m_frozen = FALSE; m_frozen = TRUE;
m_requestNewBuffer = TRUE;
} }
wxCanvas::~wxCanvas() wxCanvas::~wxCanvas()
@@ -569,7 +588,6 @@ wxCanvas::~wxCanvas()
void wxCanvas::SetArea( int width, int height ) void wxCanvas::SetArea( int width, int height )
{ {
m_buffer = wxImage( width, height );
SetScrollbars( 10, 10, width/10, height/10 ); SetScrollbars( 10, 10, width/10, height/10 );
} }
@@ -627,37 +645,38 @@ void wxCanvas::Thaw()
m_frozen = FALSE; m_frozen = FALSE;
Update( 0, 0, m_buffer.GetWidth(), m_buffer.GetHeight() ); if (m_buffer.Ok())
Update( m_bufferX, m_bufferY, 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, bool blit )
{ {
if (m_frozen) return; if (m_frozen) return;
// clip to buffer // clip to buffer
if (x < 0) if (x < m_bufferX)
{ {
width -= x; width -= m_bufferX-x;
x = 0; x = m_bufferX;
} }
if (width < 0) return; if (width < 0) return;
if (y < 0) if (y < m_bufferY)
{ {
height -= y; height -= m_bufferY-y;
y = 0; y = m_bufferY;
} }
if (height < 0) return; if (height < 0) return;
if (x+width > m_buffer.GetWidth()) if (x+width > m_bufferX+m_buffer.GetWidth())
{ {
width = m_buffer.GetWidth() - x; width = m_bufferX+m_buffer.GetWidth() - x;
} }
if (width < 0) return; if (width < 0) return;
if (y+height > m_buffer.GetHeight()) if (y+height > m_bufferY+m_buffer.GetHeight())
{ {
height = m_buffer.GetHeight() - y; height = m_bufferY+m_buffer.GetHeight() - y;
} }
if (height < 0) return; if (height < 0) return;
@@ -665,12 +684,19 @@ void wxCanvas::Update( int x, int y, int width, int height )
m_needUpdate = TRUE; m_needUpdate = TRUE;
// has to be blitted to screen later // has to be blitted to screen later
m_updateRects.Append( if (blit)
(wxObject*) new wxRect( x,y,width,height ) ); {
m_updateRects.Append(
(wxObject*) new wxRect( x,y,width,height ) );
}
// speed up with direct access, maybe add wxImage::Clear(x,y,w,h,r,g,b) // speed up with direct access, maybe add wxImage::Clear(x,y,w,h,r,g,b)
for (int yy = y; yy < y+height; yy++) int start_y = y - m_bufferY;
for (int xx = x; xx < x+width; xx++) int end_y = y+height - m_bufferY;
int start_x = x - m_bufferX;
int end_x = x+width - m_bufferX;
for (int yy = start_y; yy < end_y; yy++)
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 // cycle through all objects
@@ -727,9 +753,12 @@ void wxCanvas::BlitBuffer( wxDC &dc )
while (node) while (node)
{ {
wxRect *rect = (wxRect*) node->Data(); wxRect *rect = (wxRect*) node->Data();
wxImage sub_image( m_buffer.GetSubImage( *rect ) );
// DirectDraw here, please wxRect sub_rect( *rect );
sub_rect.x -= m_bufferX;
sub_rect.y -= m_bufferY;
wxImage sub_image( m_buffer.GetSubImage( sub_rect ) );
#ifdef __WXGTK__ #ifdef __WXGTK__
int bpp = wxDisplayDepth(); int bpp = wxDisplayDepth();
@@ -744,13 +773,9 @@ void wxCanvas::BlitBuffer( wxDC &dc )
s_hasInitialized = TRUE; s_hasInitialized = TRUE;
} }
int x = rect->x;
int y = rect->y;
CalcScrolledPosition( x, y, &x, &y );
gdk_draw_rgb_image( GTK_PIZZA(m_wxwindow)->bin_window, gdk_draw_rgb_image( GTK_PIZZA(m_wxwindow)->bin_window,
m_wxwindow->style->black_gc, m_wxwindow->style->black_gc,
x, y, sub_rect.x, sub_rect.y,
sub_image.GetWidth(), sub_image.GetHeight(), sub_image.GetWidth(), sub_image.GetHeight(),
GDK_RGB_DITHER_NONE, GDK_RGB_DITHER_NONE,
sub_image.GetData(), sub_image.GetData(),
@@ -871,6 +896,8 @@ void wxCanvas::OnPaint(wxPaintEvent &event)
wxPaintDC dc(this); wxPaintDC dc(this);
PrepareDC( dc ); PrepareDC( dc );
if (!m_buffer.Ok()) return;
m_needUpdate = TRUE; m_needUpdate = TRUE;
wxRegionIterator it( GetUpdateRegion() ); wxRegionIterator it( GetUpdateRegion() );
@@ -878,7 +905,6 @@ void wxCanvas::OnPaint(wxPaintEvent &event)
{ {
int x = it.GetX(); int x = it.GetX();
int y = it.GetY(); int y = it.GetY();
CalcUnscrolledPosition( x, y, &x, &y );
int w = it.GetWidth(); int w = it.GetWidth();
int h = it.GetHeight(); int h = it.GetHeight();
@@ -889,7 +915,10 @@ void wxCanvas::OnPaint(wxPaintEvent &event)
h = m_buffer.GetHeight() - y; h = m_buffer.GetHeight() - y;
if ((w > 0) && (h > 0)) if ((w > 0) && (h > 0))
{
CalcUnscrolledPosition( x, y, &x, &y );
m_updateRects.Append( (wxObject*) new wxRect( x, y, w, h ) ); m_updateRects.Append( (wxObject*) new wxRect( x, y, w, h ) );
}
it++; it++;
} }
@@ -897,6 +926,43 @@ void wxCanvas::OnPaint(wxPaintEvent &event)
BlitBuffer( dc ); BlitBuffer( dc );
} }
void wxCanvas::ScrollWindow( int dx, int dy, const wxRect* rect )
{
UpdateNow();
CalcUnscrolledPosition( 0, 0, &m_bufferX, &m_bufferY );
unsigned char* data = m_buffer.GetData();
if (dy != 0)
{
if (dy > 0)
{
unsigned char *source = data;
unsigned char *dest = data + (dy * m_buffer.GetWidth() * 3);
size_t count = (size_t) (m_buffer.GetWidth() * 3 * (m_buffer.GetHeight()-dy));
memmove( dest, source, count );
Update( m_bufferX, m_bufferY, m_buffer.GetWidth(), dy, FALSE );
}
else
{
unsigned char *dest = data;
unsigned char *source = data + (-dy * m_buffer.GetWidth() * 3);
size_t count = (size_t) (m_buffer.GetWidth() * 3 * (m_buffer.GetHeight()+dy));
memmove( dest, source, count );
Update( m_bufferX, m_bufferY+m_buffer.GetHeight()+dy, m_buffer.GetWidth(), -dy, FALSE );
}
}
if (dx != 0)
{
}
wxWindow::ScrollWindow( dx, dy, rect );
}
void wxCanvas::OnMouse(wxMouseEvent &event) void wxCanvas::OnMouse(wxMouseEvent &event)
{ {
int x = event.GetX(); int x = event.GetX();
@@ -992,11 +1058,27 @@ void wxCanvas::OnMouse(wxMouseEvent &event)
void wxCanvas::OnSize(wxSizeEvent &event) void wxCanvas::OnSize(wxSizeEvent &event)
{ {
m_requestNewBuffer = TRUE;
Freeze();
event.Skip(); event.Skip();
} }
void wxCanvas::OnIdle(wxIdleEvent &event) void wxCanvas::OnIdle(wxIdleEvent &event)
{ {
if (m_requestNewBuffer)
{
m_requestNewBuffer = FALSE;
int w,h;
GetClientSize( &w, &h );
m_buffer = wxImage( w, h );
CalcUnscrolledPosition( 0, 0, &m_bufferX, &m_bufferY );
Thaw();
}
UpdateNow(); UpdateNow();
event.Skip(); event.Skip();
} }