wxIScan
wxiviewcanvas.cpp
Go to the documentation of this file.
00001 /////////////////////////////////////////////////////////////////////////////
00002 // Project:     wxIView
00003 // Purpose:     Complex wxWidgets sample
00004 // Name:        wxiviewcanvas.cpp
00005 // Author:      Daniel Nell
00006 // Created:     2005/10/18
00007 // Copyright:   (c) Daniel Nell
00008 // Licence:     wxWindows license
00009 // Modified by:
00010 /////////////////////////////////////////////////////////////////////////////
00011 
00012 // For compilers that support precompilation, includes "wx/wx.h".
00013 #include <wx/wxprec.h>
00014 #ifndef WX_PRECOMP
00015 #   include <wx/wx.h>
00016 #endif
00017 
00018 // Include additional wxWidgets headers.
00019 #include <wx/image.h>
00020 #include <wx/timer.h>
00021 
00022 // Include private wxIView headers.
00023 #include "wxiviewcanvas.h"
00024 
00025 
00026 //////////////////////////////////////////////////////////
00027 // The canvas window
00028 //
00029 // Define some event types introduced in the header file.
00030 //
00031 DEFINE_EVENT_TYPE( wxEVT_IVIEWCANVASSIZE     )
00032 DEFINE_EVENT_TYPE( wxEVT_IVIEWCANVASSELECTED )
00033 
00034 
00035 // Event table,
00036 //
00037 BEGIN_EVENT_TABLE( wxIViewCanvas, wxScrolledWindow )
00038     EVT_PAINT(           wxIViewCanvas::OnPaint  )
00039     EVT_SIZE(            wxIViewCanvas::OnSize   )
00040     EVT_TIMER( wxID_ANY, wxIViewCanvas::OnTimer  )
00041     EVT_MOUSE_EVENTS(    wxIViewCanvas::OnMouse_ )
00042 END_EVENT_TABLE()
00043 
00044 
00045 // Standard constructor.
00046 //
00047 wxIViewCanvas::wxIViewCanvas( wxWindow *poParent, wxWindowID nId,
00048                               const wxPoint &oPos, const wxSize &oSize,
00049                               long nStyle, const wxString& strName )
00050   : wxScrolledWindow( poParent, nId, oPos, oSize, nStyle, strName ),
00051     m_nOptions( wxICANVAS_MOUSE_SCROLL | wxICANVAS_MOUSEWHEEL_SCROLL )
00052 {
00053     // Initialization.
00054     m_oTimer.SetOwner( this );
00055 
00056     // Reset selection.
00057     ClearSelection();
00058 }
00059 
00060 // Event handlers.
00061 //
00062 // Creates and prepares a device context and calls Paint( wxDC& oDc ).
00063 //
00064 void wxIViewCanvas::OnPaint( wxPaintEvent& oEvent )
00065 {
00066     // Create a device context...
00067     //
00068     wxPaintDC oDc( this );
00069 
00070     // ... and prepare it even if there is not a bitmap to paint
00071     // for to repaint at least the window background etc.
00072     //
00073     PrepareDC( oDc );
00074 
00075     // Paint (the bitmap).
00076     Paint( oDc );
00077 }
00078 
00079 // Handle resizing.
00080 //
00081 void wxIViewCanvas::OnSize( wxSizeEvent& WXUNUSED( oEvent ) )
00082 {
00083     // Check if the timer is running, and...
00084     if( m_oTimer.IsRunning() )
00085     {
00086         // ... stop it.
00087         m_oTimer.Stop();
00088     }
00089 
00090     // Create a one shot timer event in 50ms.
00091     m_oTimer.Start( WXIVIEWCANVASDELAY, wxTIMER_ONE_SHOT );
00092 }
00093 
00094 // Handle timer events.
00095 //
00096 void wxIViewCanvas::OnTimer( wxTimerEvent& WXUNUSED( oEvent ) )
00097 {
00098     // Notify the next window in the parent chain that the canvas size
00099     // has changed.
00100     //
00101     // Note: An event of type wxIViewCanvasSizeEvent is propageted
00102     //       to the parent window chain by default.
00103     wxIViewCanvasSizeEvent oEvent;
00104 
00105     ProcessEvent( oEvent );
00106 }
00107 
00108 // Handle mouse events.
00109 //
00110 void wxIViewCanvas::OnMouse( wxMouseEvent& oEvent )
00111 {
00112     if( m_nOptions & wxICANVAS_MOUSE_SCROLL )
00113     {
00114         // Process right mouse button events.
00115         if( oEvent.RightDown() )
00116         {
00117             // Change mouse cursor.
00118             SetCursor( wxCursor( wxCURSOR_HAND ) );
00119 
00120             // Remember former mouse position.
00121             m_oMousePosOld= wxPoint( oEvent.GetX(), oEvent.GetY() );
00122         }
00123         else if ( oEvent.RightUp() )
00124         {
00125             // Reset mouse cursor.
00126             SetCursor( wxNullCursor );
00127         }
00128         else if ( oEvent.Dragging() && oEvent.RightIsDown() )
00129         {
00130             // Get mouse position.
00131             wxPoint oMousePos( oEvent.GetX(), oEvent.GetY() );
00132 
00133             // Get the virtual position of upper left corner
00134             // (the view start).
00135             wxPoint nViewStart;
00136 
00137             GetViewStart( &nViewStart.x, &nViewStart.y );
00138 
00139             // Calculate scrolling parameters and scroll image.
00140             //
00141             // NOTE: This only works because scroll unit size ist set to
00142             //       1 pixel per horizontal/vertikal scroll unit in
00143             //       void wxIViewCanvas::SetBitmap( const wxBitmap &oBitmap ).
00144             //
00145             Scroll( nViewStart.x - ( oMousePos.x - m_oMousePosOld.x ),
00146                     nViewStart.y - ( oMousePos.y - m_oMousePosOld.y ) );
00147 
00148             // Save the mouse position for further use.
00149             m_oMousePosOld= oMousePos;
00150         }
00151     }
00152     if( m_nOptions & wxICANVAS_MOUSEWHEEL_SCROLL )
00153     {
00154         if( oEvent.GetWheelRotation() != 0 )
00155         {
00156             // Get the virtual position of upper left corner
00157             // (the view start).
00158             wxPoint nViewStart;
00159 
00160             GetViewStart( &nViewStart.x, &nViewStart.y );
00161 
00162             // Calculate scrolling parameters and scroll image.
00163             //
00164             // NOTE: This only works because scroll unit size ist set to
00165             //       1 pixel per horizontal/vertikal scroll unit in
00166             //       void wxIViewCanvas::SetBitmap( const wxBitmap &oBitmap ).
00167             //
00168             Scroll( nViewStart.x,
00169                     nViewStart.y - oEvent.GetWheelRotation() / 5 );
00170         }
00171     }
00172     if( m_nOptions & wxICANVAS_MOUSE_SELECTION )
00173     {
00174         // Process left mouse button events
00175         if( oEvent.LeftDown() )
00176         {
00177             // Clear a posible selection.
00178             ClearSelection();
00179 
00180             // Change mouse cursor.
00181             SetCursor( wxCursor( wxCURSOR_CROSS ) );
00182 
00183             // Remember former mouse position.
00184             m_oMousePosOld= wxPoint( oEvent.GetX(), oEvent.GetY() );
00185 
00186             // Save starting point of the mouse movement.
00187             m_oMousePosBegin= m_oMousePosOld;
00188         }
00189         else if ( oEvent.LeftUp() )
00190         {
00191             // Reset mouse cursor.
00192             SetCursor( wxNullCursor );
00193 
00194             // Get mouse position.
00195             wxPoint oMousePos( oEvent.GetX(), oEvent.GetY() );
00196 
00197             // Get the virtual position of upper left corner
00198             // (the view start).
00199             wxPoint nViewStart;
00200 
00201             GetViewStart( &nViewStart.x, &nViewStart.y );
00202 
00203             // Remember selection.
00204             m_oSelection= wxRect( nViewStart.x + m_oMousePosBegin.x, nViewStart.y + m_oMousePosBegin.y,
00205                                   oMousePos.x - m_oMousePosBegin.x + 1, oMousePos.y - m_oMousePosBegin.y + 1 );
00206 
00207             // Do some coordinate corrections.
00208             if( m_oSelection.width < 0 )
00209             {
00210                 m_oSelection.x += m_oSelection.width;
00211                 m_oSelection.width= -m_oSelection.width;
00212             }
00213             if( m_oSelection.height < 0 )
00214             {
00215                 m_oSelection.y += m_oSelection.height;
00216                 m_oSelection.height= -m_oSelection.height;
00217             }
00218             if( m_oSelection.x < 0 )
00219             {
00220                 m_oSelection.width += m_oSelection.x;
00221                 m_oSelection.x= 0;
00222             }
00223             if( m_oSelection.y < 0 )
00224             {
00225                 m_oSelection.height += m_oSelection.y;
00226                 m_oSelection.y= 0;
00227             }
00228 
00229             // Notify the next window in the parent chain that there
00230             // is a new selection.
00231             //
00232             // Note: An event of type wxIViewCanvasSelectedEvent is
00233             //       propageted to the parent window chain by default.
00234             wxIViewCanvasSelectedEvent oIViewCanvasSelectedEvent;
00235 
00236             oIViewCanvasSelectedEvent.m_bShift= oEvent.ShiftDown();
00237             oIViewCanvasSelectedEvent.m_bAlt  = oEvent.AltDown();
00238             oIViewCanvasSelectedEvent.m_bCtrl = oEvent.ControlDown();
00239             oIViewCanvasSelectedEvent.m_bMeta = oEvent.MetaDown();
00240             oIViewCanvasSelectedEvent.m_oSelection= m_oSelection;
00241 
00242             ProcessEvent( oIViewCanvasSelectedEvent );
00243         }
00244         else if ( oEvent.Dragging() && oEvent.LeftIsDown() )
00245         {
00246             // Get mouse position.
00247             wxPoint oMousePos( oEvent.GetX(), oEvent.GetY() );
00248 
00249             // ..
00250             wxClientDC oDc( this );
00251 
00252             oDc.SetPen( *wxBLACK_DASHED_PEN );
00253             oDc.SetBrush( *wxTRANSPARENT_BRUSH );
00254             oDc.SetLogicalFunction( wxINVERT );
00255             oDc.DrawRectangle( m_oMousePosBegin.x, m_oMousePosBegin.y,
00256                                m_oMousePosOld.x - m_oMousePosBegin.x + 1, m_oMousePosOld.y - m_oMousePosBegin.y + 1 );
00257             oDc.DrawRectangle( m_oMousePosBegin.x, m_oMousePosBegin.y,
00258                                oMousePos.x - m_oMousePosBegin.x + 1, oMousePos.y - m_oMousePosBegin.y + 1 );
00259 
00260             // Save the mouse position for further use.
00261             m_oMousePosOld= oMousePos;
00262         }
00263     }
00264 }
00265 
00266 // Repaints the image (using an internal bitmap).
00267 //
00268 void wxIViewCanvas::Paint( wxDC& oDc )
00269 {
00270 #if wxCHECK_VERSION( 2, 9, 0 )
00271     if( oDc.IsOk() )
00272 #else
00273     if( oDc.Ok() )
00274 #endif // wxCHECK_VERSION( 2, 9, 0 )
00275     {
00276         // If there is a bitmap connected to this canvas window (re)paint it.
00277         if( m_oBitmap.Ok() )
00278         {
00279             // Repaint the bitmap.
00280             oDc.DrawBitmap( m_oBitmap, 0, 0 );
00281 
00282         }
00283 
00284         // If there is a selection repaint the surrounding rectangle.
00285         if( IsSelected() )
00286         {
00287             oDc.SetPen( *wxBLACK_DASHED_PEN );
00288             oDc.SetBrush( *wxTRANSPARENT_BRUSH );
00289             oDc.SetLogicalFunction( wxINVERT );
00290             oDc.DrawRectangle( m_oSelection.x, m_oSelection.y, m_oSelection.width, m_oSelection.height );
00291         }
00292     }
00293 }
00294 
00295 // Sets the internal bitmap.
00296 //
00297 void wxIViewCanvas::SetBitmap( const wxBitmap &oBitmap )
00298 {
00299     // Save the (new) bitmap,...
00300     m_oBitmap= oBitmap;
00301 
00302     // ... adjust the scrollbars, ...
00303     SetScrollbars( 1, 1, m_oBitmap.GetWidth(), m_oBitmap.GetHeight() );
00304 
00305     // ... clear a posible selection, ...
00306     ClearSelection();
00307 
00308     // .. and refresh (repaint) the windown content.
00309     Refresh();
00310 }