]> git.saurik.com Git - wxWidgets.git/commitdiff
Added wxCanvasLine, Freeze() and Thaw() and mouse events (untested)
authorRobert Roebling <robert@roebling.de>
Sat, 2 Sep 2000 18:01:32 +0000 (18:01 +0000)
committerRobert Roebling <robert@roebling.de>
Sat, 2 Sep 2000 18:01:32 +0000 (18:01 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8241 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

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

index cdcb441b0d9069c00ac87767389773a5aba32d41..6c3747eed2a5c907cbcc0828f9cf1a874ccb96fd 100644 (file)
@@ -34,6 +34,8 @@ public:
     wxCanvasObject( int x, int y, int width, int height );
     
     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 WriteSVG( wxTextOutputStream &stream );
     
@@ -76,6 +78,24 @@ private:
     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
 //----------------------------------------------------------------------------
@@ -125,6 +145,7 @@ public:
     void CreateBuffer();
     void SetRGB( unsigned char red, unsigned char green, unsigned char blue );
     void SetFlag( int flag );
+    int GetFlag()              { return m_flag; }
     
 private:
     wxString        m_text;
@@ -157,6 +178,9 @@ public:
     virtual void Update( int x, int y, int width, int height );
     virtual void UpdateNow();
     
+    virtual void Freeze();
+    virtual void Thaw();
+    
     virtual void Prepend( wxCanvasObject* obj );
     virtual void Append( wxCanvasObject* obj );
     virtual void Insert( size_t before, wxCanvasObject* obj );
@@ -168,11 +192,14 @@ public:
     void BlitBuffer( wxDC &dc );
     
 private:
-    wxImage        m_buffer;
-    bool           m_needUpdate;
-    wxList         m_updateRects;
-    wxList         m_objects;
-    unsigned char  m_green,m_red,m_blue;
+    wxImage          m_buffer;
+    bool             m_needUpdate;
+    wxList           m_updateRects;
+    wxList           m_objects;
+    unsigned char    m_green,m_red,m_blue;
+    bool             m_frozen;
+    wxCanvasObject  *m_lastMouse;
+    
     
     friend class wxCanvasObject;
     
index e31de9ae4a136eb120cd955b9fd3b0eee4c9d088..6f109d3f2c497b71c73c878c045d16caf9ce0b01 100644 (file)
@@ -20,6 +20,8 @@
 #include <wx/image.h>
 #include <wx/file.h>
 #include <wx/timer.h>
+#include <wx/log.h>
+
 
 #include "smile.xpm"
 
@@ -43,10 +45,13 @@ public:
     void OnQuit( wxCommandEvent &event );
     void OnTimer( wxTimerEvent &event );
 
-    wxCanvas        *m_canvas;
-    wxCanvasObject  *m_sm1;
-    wxCanvasObject  *m_sm2;
-    wxTimer         *m_timer;
+    wxCanvas         *m_canvas;
+    wxCanvasObject   *m_sm1;
+    wxCanvasObject   *m_sm2;
+    wxCanvasObject   *m_sm3;
+    wxCanvasObject   *m_sm4;
+    wxTimer          *m_timer;
+    wxTextCtrl       *m_log;
 
 private:
     DECLARE_DYNAMIC_CLASS(MyFrame)
@@ -85,51 +90,76 @@ END_EVENT_TABLE()
 
 MyFrame::MyFrame()
        : wxFrame( (wxFrame *)NULL, -1, "wxCanvas sample",
-                  wxPoint(20,20), wxSize(470,360) )
+                  wxPoint(20,20), wxSize(470,460) )
 {
-  wxMenu *file_menu = new wxMenu();
-  file_menu->Append( ID_ABOUT, "&About...");
-  file_menu->AppendSeparator();
-  file_menu->Append( ID_QUIT, "E&xit");
+    wxMenu *file_menu = new wxMenu();
+    file_menu->Append( ID_ABOUT, "&About...");
+    file_menu->AppendSeparator();
+    file_menu->Append( ID_QUIT, "E&xit");
+
+    wxMenuBar *menu_bar = new wxMenuBar();
+    menu_bar->Append(file_menu, "&File");
+
+    SetMenuBar( menu_bar );
+
+    CreateStatusBar(2);
+    int widths[] = { -1, 100 };
+    SetStatusWidths( 2, widths );
+
+    m_canvas = new wxCanvas( this, -1, wxPoint(0,0), wxSize(10,10) );
+    
+    m_canvas->Freeze();
+
+    m_canvas->SetArea( 400, 600 );
+    m_canvas->SetColour( 255, 255, 255 );
 
-  wxMenuBar *menu_bar = new wxMenuBar();
-  menu_bar->Append(file_menu, "&File");
+    wxBitmap bitmap( smile_xpm );
+    wxImage image( bitmap );
 
-  SetMenuBar( menu_bar );
+    m_sm1 = new wxCanvasImage( image, 0, 70 );
+    m_canvas->Append( m_sm1 );
 
-  CreateStatusBar(2);
-  int widths[] = { -1, 100 };
-  SetStatusWidths( 2, widths );
+    int i;
+    for (i = 10; i < 300; i+=10)
+        m_canvas->Append( new wxCanvasRect( i,50,3,140, 255,0,0 ) );
 
-  m_canvas = new wxCanvas( this, -1, wxPoint(0,0), wxSize(10,10) );
+    m_sm2 = new wxCanvasImage( image, 0, 140 );
+    m_canvas->Append( m_sm2 );
 
-  m_canvas->SetArea( 400, 600 );
-  m_canvas->SetColour( 255, 255, 255 );
+    for (i = 15; i < 300; i+=10)
+        m_canvas->Append( new wxCanvasRect( i,50,3,140, 255,0,0 ) );
 
-  wxBitmap bitmap( smile_xpm );
-  wxImage image( bitmap );
+    wxButton *button = new wxButton( m_canvas, -1, "Hello", wxPoint(80,50) );
+    m_canvas->Append( new wxCanvasControl( button ) );
 
-  m_sm1 = new wxCanvasImage( image, 0, 70 );
-  m_canvas->Append( m_sm1 );
+    m_canvas->Append( new wxCanvasText( "Hello", 180, 50,
+                      wxGetApp().GetFontPath() + "/times.ttf", 20 ) );
 
-  int i;
-  for (i = 10; i < 300; i+=10)
-      m_canvas->Append( new wxCanvasRect( i,50,3,140, 255,0,0 ) );
+    m_sm3 = new wxCanvasImage( image, 0, 210 );
+    m_canvas->Append( m_sm3 );
 
-  m_sm2 = new wxCanvasImage( image, 0, 140 );
-  m_canvas->Append( m_sm2 );
+    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 );
 
-  for (i = 15; i < 300; i+=10)
-      m_canvas->Append( new wxCanvasRect( i,50,3,140, 255,0,0 ) );
+    m_canvas->Thaw();
 
-  wxButton *button = new wxButton( m_canvas, -1, "Hello", wxPoint(80,50) );
-  m_canvas->Append( new wxCanvasControl( button ) );
+    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 );
 
-  m_canvas->Append( new wxCanvasText( "Hello", 180, 50,
-                    wxGetApp().GetFontPath() + "/times.ttf", 20 ) );
+    SetAutoLayout( TRUE );
+    SetSizer( topsizer );
 
-  m_timer = new wxTimer( this );
-  m_timer->Start( 100, FALSE );
+    m_timer = new wxTimer( this );
+    m_timer->Start( 100, FALSE );
 }
 
 MyFrame::~MyFrame()
@@ -146,6 +176,8 @@ void MyFrame::OnTimer( wxTimerEvent &WXUNUSED(event) )
 {
     m_sm1->Move( m_sm1->GetX()+1, m_sm1->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();
 }
 
index 109ec8f2da3f1f4f768d973e3d94c39ee1a6f243..e248757bdcf85b0163f7cebeda2cd69a0f9757b7 100644 (file)
@@ -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 )
 {
 }
@@ -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
 //----------------------------------------------------------------------------
@@ -349,6 +444,8 @@ wxCanvas::wxCanvas( wxWindow *parent, wxWindowID id,
     m_red = 0;
     m_green = 0;
     m_blue = 0;
+    m_lastMouse = (wxCanvasObject*)NULL;
+    m_frozen = FALSE;
 }
 
 wxCanvas::~wxCanvas()
@@ -375,6 +472,8 @@ void wxCanvas::SetColour( unsigned char red, unsigned char green, unsigned char
     m_green = green;
     m_blue = blue;
     
+    if (m_frozen) return;
+    
     unsigned char *data = m_buffer.GetData();
     
     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 )
 {
+    if (m_frozen) return;
+    
     // clip to buffer
     if (x < 0)
     {
@@ -620,7 +742,79 @@ void wxCanvas::OnPaint(wxPaintEvent &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)