]> git.saurik.com Git - wxWidgets.git/commitdiff
Various improvements and addition to wxCanvas
authorRobert Roebling <robert@roebling.de>
Fri, 1 Sep 2000 10:25:39 +0000 (10:25 +0000)
committerRobert Roebling <robert@roebling.de>
Fri, 1 Sep 2000 10:25:39 +0000 (10:25 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8226 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

contrib/include/wx/canvas/canvas.h
contrib/samples/canvas/test/test.cpp
contrib/src/canvas/canvas.cpp

index 4015e9d3dd1f8826c8f1c9f7466ad8d3764c6b43..cdcb441b0d9069c00ac87767389773a5aba32d41 100644 (file)
@@ -58,6 +58,24 @@ protected:
     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
 //----------------------------------------------------------------------------
index b0bcacb4555e1dfebf9f31cec6533f045dc1a8d1..7377a35b0e927dd76332347a2d2ddfad2409e94e 100644 (file)
@@ -44,7 +44,8 @@ public:
     void OnTimer( wxTimerEvent &event );
 
     wxCanvas        *m_canvas;
-    wxCanvasObject  *m_co;
+    wxCanvasObject  *m_sm1;
+    wxCanvasObject  *m_sm2;
     wxTimer         *m_timer;
 
 private:
@@ -102,11 +103,20 @@ MyFrame::MyFrame()
   
   wxBitmap bitmap( smile_xpm );
   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) );
   m_canvas->Append( new wxCanvasControl( button ) );
 
@@ -128,7 +138,8 @@ void MyFrame::OnQuit( wxCommandEvent &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();
 }
 
index 27fe98cb4a8ea5a8cd5efc41d4c6ba8d97d9ae7c..109ec8f2da3f1f4f768d973e3d94c39ee1a6f243 100644 (file)
@@ -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
 //----------------------------------------------------------------------------
@@ -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 )
 {
-    int start_x = wxMax( 0, clip_x-m_area.x );
-    int end_x = wxMin( m_area.width, clip_width+clip_x-m_area.x );
-    int start_y = wxMax( 0, clip_y-m_area.y );
-    int end_y = wxMin( m_area.height, clip_height+clip_y-m_area.y );
-    
-    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))
+    if ((clip_x == m_area.x) && 
+        (clip_y == m_area.y) && 
+        (clip_width == m_area.width) &&
+        (clip_height == 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
     {
-        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 ) );
-        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 )
    : wxCanvasObject( -1, -1, -1, -1 )
 {
+    m_isControl = TRUE;
     m_control = control;
     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();
 
-    int start_x = wxMax( 0, clip_x-m_area.x );
-    int end_x = wxMin( m_area.width, clip_width+clip_x-m_area.x );
-    int start_y = wxMax( 0, clip_y-m_area.y );
-    int end_y = wxMin( m_area.height, clip_height+clip_y-m_area.y );
+    // local coordinates
+    int start_x = clip_x - m_area.x;
+    int end_x = clip_width + start_x;
+    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 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 )
 {
+    // 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;
     
+    // has to be blitted to screen later
     m_updateRects.Append(
         (wxObject*) new wxRect( x,y,width,height ) );
     
-    // speed up with direct access, maybe add wxImage::Clear(x,y,w,h)
-    int xx,yy,ww,hh;
-    for (yy = y; yy < y+height; yy++)
-        for (xx = x; xx < x+width; xx++)
+    // speed up with direct access, maybe add wxImage::Clear(x,y,w,h,r,g,b)
+    for (int yy = y; yy < y+height; yy++)
+        for (int xx = x; xx < x+width; xx++)
             m_buffer.SetRGB( xx, yy, m_red, m_green, m_blue );
 
+    // cycle through all objects
     wxNode *node = m_objects.First();
     while (node)
     {
         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();
@@ -522,12 +603,14 @@ void wxCanvas::OnPaint(wxPaintEvent &event)
         
         int w = it.GetWidth();
         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++;
     }