Various improvements and addition to wxCanvas
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8226 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
		| @@ -58,6 +58,24 @@ protected: | |||||||
|     friend class wxCanvas; |     friend class wxCanvas; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | //---------------------------------------------------------------------------- | ||||||
|  | // wxCanvasRect | ||||||
|  | //---------------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | class wxCanvasRect: public wxCanvasObject | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     wxCanvasRect( 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 | ||||||
| //---------------------------------------------------------------------------- | //---------------------------------------------------------------------------- | ||||||
|   | |||||||
| @@ -44,7 +44,8 @@ public: | |||||||
|     void OnTimer( wxTimerEvent &event ); |     void OnTimer( wxTimerEvent &event ); | ||||||
|  |  | ||||||
|     wxCanvas        *m_canvas; |     wxCanvas        *m_canvas; | ||||||
|     wxCanvasObject  *m_co; |     wxCanvasObject  *m_sm1; | ||||||
|  |     wxCanvasObject  *m_sm2; | ||||||
|     wxTimer         *m_timer; |     wxTimer         *m_timer; | ||||||
|  |  | ||||||
| private: | private: | ||||||
| @@ -102,10 +103,19 @@ MyFrame::MyFrame() | |||||||
|    |    | ||||||
|   wxBitmap bitmap( smile_xpm ); |   wxBitmap bitmap( smile_xpm ); | ||||||
|   wxImage image( bitmap ); |   wxImage image( bitmap ); | ||||||
|   m_co = new wxCanvasImage( image, 10, 50 ); |  | ||||||
|   m_canvas->Append( m_co ); |  | ||||||
|    |    | ||||||
|   m_canvas->Append( new wxCanvasImage( image, 40, 50 ) ); |   m_sm1 = new wxCanvasImage( image, 0, 70 ); | ||||||
|  |   m_canvas->Append( m_sm1 ); | ||||||
|  |    | ||||||
|  |   int i; | ||||||
|  |   for (i = 10; i < 300; i+=10) | ||||||
|  |       m_canvas->Append( new wxCanvasRect( i,50,3,140, 255,0,0 ) ); | ||||||
|  |    | ||||||
|  |   m_sm2 = new wxCanvasImage( image, 0, 140 ); | ||||||
|  |   m_canvas->Append( m_sm2 ); | ||||||
|  |    | ||||||
|  |   for (i = 15; i < 300; i+=10) | ||||||
|  |       m_canvas->Append( new wxCanvasRect( i,50,3,140, 255,0,0 ) ); | ||||||
|        |        | ||||||
|   wxButton *button = new wxButton( m_canvas, -1, "Hello", wxPoint(80,50) ); |   wxButton *button = new wxButton( m_canvas, -1, "Hello", wxPoint(80,50) ); | ||||||
|   m_canvas->Append( new wxCanvasControl( button ) ); |   m_canvas->Append( new wxCanvasControl( button ) ); | ||||||
| @@ -128,7 +138,8 @@ void MyFrame::OnQuit( wxCommandEvent &WXUNUSED(event) ) | |||||||
|  |  | ||||||
| void MyFrame::OnTimer( wxTimerEvent &WXUNUSED(event) ) | void MyFrame::OnTimer( wxTimerEvent &WXUNUSED(event) ) | ||||||
| { | { | ||||||
|     m_co->Move( m_co->GetX()+1, m_co->GetY() ); |     m_sm1->Move( m_sm1->GetX()+1, m_sm1->GetY() ); | ||||||
|  |     m_sm2->Move( m_sm2->GetX()+1, m_sm2->GetY() ); | ||||||
|     wxWakeUpIdle(); |     wxWakeUpIdle(); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -80,6 +80,31 @@ void wxCanvasObject::Render( int clip_x, int clip_y, int clip_width, int clip_he | |||||||
| { | { | ||||||
| } | } | ||||||
|  |  | ||||||
|  | //---------------------------------------------------------------------------- | ||||||
|  | // wxCanvasRect | ||||||
|  | //---------------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | wxCanvasRect::wxCanvasRect( 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 wxCanvasRect::Render( int clip_x, int clip_y, int clip_width, int clip_height ) | ||||||
|  | { | ||||||
|  |     wxImage *image = m_owner->GetBuffer(); | ||||||
|  |     // speed up later | ||||||
|  |     for (int y = clip_y; y < clip_y+clip_height; y++) | ||||||
|  |         for (int x = clip_x; x < clip_x+clip_width; x++) | ||||||
|  |             image->SetRGB( x, y, m_red, m_green, m_blue ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void wxCanvasRect::WriteSVG( wxTextOutputStream &stream ) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
| //---------------------------------------------------------------------------- | //---------------------------------------------------------------------------- | ||||||
| // wxCanvasImage | // wxCanvasImage | ||||||
| //---------------------------------------------------------------------------- | //---------------------------------------------------------------------------- | ||||||
| @@ -93,26 +118,22 @@ wxCanvasImage::wxCanvasImage( const wxImage &image, int x, int y ) | |||||||
|  |  | ||||||
| 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 start_x = wxMax( 0, clip_x-m_area.x ); |     if ((clip_x == m_area.x) &&  | ||||||
|     int end_x = wxMin( m_area.width, clip_width+clip_x-m_area.x ); |         (clip_y == m_area.y) &&  | ||||||
|     int start_y = wxMax( 0, clip_y-m_area.y ); |         (clip_width == m_area.width) && | ||||||
|     int end_y = wxMin( m_area.height, clip_height+clip_y-m_area.y ); |         (clip_height == m_area.height)) | ||||||
|      |  | ||||||
|     if (end_x < start_x) return; |  | ||||||
|     if (end_y < start_y) return; |  | ||||||
|      |  | ||||||
|     if ((start_x == 0) &&  |  | ||||||
|         (start_y == 0) &&  |  | ||||||
|         (end_x == m_area.width) && |  | ||||||
|         (end_y == m_area.height)) |  | ||||||
|     { |     { | ||||||
|         m_owner->GetBuffer()->Paste( m_image, m_area.x, m_area.y ); |         m_owner->GetBuffer()->Paste( m_image, clip_x, clip_y ); | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         wxRect rect( start_x, start_y, end_x-start_x, end_y-start_y ); |         // local coordinates | ||||||
|  |         int start_x = clip_x - m_area.x; | ||||||
|  |         int start_y = clip_y - m_area.y; | ||||||
|  |      | ||||||
|  |         wxRect rect( start_x, start_y, clip_width, clip_height ); | ||||||
|         wxImage sub_image( m_image.GetSubImage( rect ) ); |         wxImage sub_image( m_image.GetSubImage( rect ) ); | ||||||
|         m_owner->GetBuffer()->Paste( sub_image, m_area.x+start_x, m_area.y+start_y ); |         m_owner->GetBuffer()->Paste( sub_image, clip_x, clip_y ); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -128,6 +149,7 @@ void wxCanvasImage::WriteSVG( wxTextOutputStream &stream ) | |||||||
| wxCanvasControl::wxCanvasControl( wxWindow *control ) | wxCanvasControl::wxCanvasControl( wxWindow *control ) | ||||||
|    : wxCanvasObject( -1, -1, -1, -1 ) |    : wxCanvasObject( -1, -1, -1, -1 ) | ||||||
| { | { | ||||||
|  |     m_isControl = TRUE; | ||||||
|     m_control = control; |     m_control = control; | ||||||
|     UpdateSize(); |     UpdateSize(); | ||||||
| } | } | ||||||
| @@ -225,10 +247,11 @@ void wxCanvasText::Render( int clip_x, int clip_y, int clip_width, int clip_heig | |||||||
|      |      | ||||||
|     wxImage *image = m_owner->GetBuffer(); |     wxImage *image = m_owner->GetBuffer(); | ||||||
|  |  | ||||||
|     int start_x = wxMax( 0, clip_x-m_area.x ); |     // local coordinates | ||||||
|     int end_x = wxMin( m_area.width, clip_width+clip_x-m_area.x ); |     int start_x = clip_x - m_area.x; | ||||||
|     int start_y = wxMax( 0, clip_y-m_area.y ); |     int end_x = clip_width + start_x; | ||||||
|     int end_y = wxMin( m_area.height, clip_height+clip_y-m_area.y ); |     int start_y = clip_y - m_area.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++) | ||||||
| @@ -368,29 +391,87 @@ void wxCanvas::SetColour( unsigned char red, unsigned char green, unsigned char | |||||||
|  |  | ||||||
| void wxCanvas::Update( int x, int y, int width, int height ) | void wxCanvas::Update( int x, int y, int width, int height ) | ||||||
| { | { | ||||||
|  |     // clip to buffer | ||||||
|  |     if (x < 0) | ||||||
|  |     { | ||||||
|  |         width -= x; | ||||||
|  |         x = 0; | ||||||
|  |     } | ||||||
|  |     if (width < 0) return; | ||||||
|  |      | ||||||
|  |     if (y < 0) | ||||||
|  |     { | ||||||
|  |         height -= y; | ||||||
|  |         y = 0; | ||||||
|  |     } | ||||||
|  |     if (height < 0) return; | ||||||
|  |      | ||||||
|  |     if (x+width > m_buffer.GetWidth()) | ||||||
|  |     { | ||||||
|  |         width = m_buffer.GetWidth() - x; | ||||||
|  |     } | ||||||
|  |     if (width < 0) return; | ||||||
|  |      | ||||||
|  |     if (y+height > m_buffer.GetHeight()) | ||||||
|  |     { | ||||||
|  |         height = m_buffer.GetHeight() - y; | ||||||
|  |     } | ||||||
|  |     if (height < 0) return; | ||||||
|  |      | ||||||
|  |     // update is within the buffer | ||||||
|     m_needUpdate = TRUE; |     m_needUpdate = TRUE; | ||||||
|      |      | ||||||
|  |     // has to be blitted to screen later | ||||||
|     m_updateRects.Append( |     m_updateRects.Append( | ||||||
|         (wxObject*) new wxRect( x,y,width,height ) ); |         (wxObject*) new wxRect( x,y,width,height ) ); | ||||||
|      |      | ||||||
|     // speed up with direct access, maybe add wxImage::Clear(x,y,w,h) |     // speed up with direct access, maybe add wxImage::Clear(x,y,w,h,r,g,b) | ||||||
|     int xx,yy,ww,hh; |     for (int yy = y; yy < y+height; yy++) | ||||||
|     for (yy = y; yy < y+height; yy++) |         for (int xx = x; xx < x+width; xx++) | ||||||
|         for (xx = x; xx < x+width; 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 | ||||||
|     wxNode *node = m_objects.First(); |     wxNode *node = m_objects.First(); | ||||||
|     while (node) |     while (node) | ||||||
|     { |     { | ||||||
|         wxCanvasObject *obj = (wxCanvasObject*) node->Data(); |         wxCanvasObject *obj = (wxCanvasObject*) node->Data(); | ||||||
|         xx = obj->GetX(); |  | ||||||
|         yy = obj->GetY(); |  | ||||||
|         ww = obj->GetWidth(); |  | ||||||
|         hh = obj->GetHeight(); |  | ||||||
|          |          | ||||||
|         if (!obj->IsControl())  // calc intersection ! |         if (!obj->IsControl()) | ||||||
|         { |         { | ||||||
|             obj->Render( x, y, width, height ); |             // 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(); |         node = node->Next(); | ||||||
| @@ -522,12 +603,14 @@ void wxCanvas::OnPaint(wxPaintEvent &event) | |||||||
|          |          | ||||||
|         int w = it.GetWidth(); |         int w = it.GetWidth(); | ||||||
|         int h = it.GetHeight(); |         int h = it.GetHeight(); | ||||||
|         if (x + w > m_buffer.GetWidth()) |  | ||||||
|             w = m_buffer.GetWidth()-x; |  | ||||||
|         if (y + h > m_buffer.GetHeight()) |  | ||||||
|             h = m_buffer.GetHeight()-y; |  | ||||||
|          |          | ||||||
|         m_updateRects.Append( (wxObject*) new wxRect( x, y, w, h ) ); |         if (x+w > m_buffer.GetWidth()) | ||||||
|  |             w = m_buffer.GetWidth() - x; | ||||||
|  |         if (y+h > m_buffer.GetHeight()) | ||||||
|  |             h = m_buffer.GetHeight() - y; | ||||||
|  |          | ||||||
|  |         if ((w > 0) && (h > 0)) | ||||||
|  |             m_updateRects.Append( (wxObject*) new wxRect( x, y, w, h ) ); | ||||||
|          |          | ||||||
|         it++; |         it++; | ||||||
|     } |     } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user