| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506 | 
							- /////////////////////////////////////////////////////////////////////////////
 
- // Name:        dragimag.cpp
 
- // Purpose:     wxDragImage sample
 
- // Author:      Julian Smart
 
- // Modified by:
 
- // Created:     28/2/2000
 
- // Copyright:   (c) Julian Smart
 
- // Licence:     wxWindows licence
 
- /////////////////////////////////////////////////////////////////////////////
 
- // For compilers that support precompilation, includes "wx/wx.h".
 
- #include "wx/wxprec.h"
 
- #ifdef __BORLANDC__
 
- #pragma hdrstop
 
- #endif
 
- #ifndef WX_PRECOMP
 
- #include "wx/wx.h"
 
- #endif
 
- #include "wx/image.h"
 
- // Under Windows, change this to 1
 
- // to use wxGenericDragImage
 
- #define wxUSE_GENERIC_DRAGIMAGE 1
 
- #if wxUSE_GENERIC_DRAGIMAGE
 
- #include "wx/generic/dragimgg.h"
 
- #define wxDragImage wxGenericDragImage
 
- #else
 
- #include "wx/dragimag.h"
 
- #endif
 
- #include "dragimag.h"
 
- #ifndef wxHAS_IMAGES_IN_RESOURCES
 
-     #include "../sample.xpm"
 
-     #include "dragicon.xpm"
 
- #endif
 
- // main program
 
- IMPLEMENT_APP(MyApp)
 
- // MyCanvas
 
- IMPLEMENT_CLASS(MyCanvas, wxScrolledWindow)
 
- wxBEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
 
-   EVT_PAINT(MyCanvas::OnPaint)
 
-   EVT_ERASE_BACKGROUND(MyCanvas::OnEraseBackground)
 
-   EVT_MOUSE_EVENTS(MyCanvas::OnMouseEvent)
 
- wxEND_EVENT_TABLE()
 
- MyCanvas::MyCanvas( wxWindow *parent, wxWindowID id,
 
-                     const wxPoint &pos, const wxSize &size )
 
-         : wxScrolledWindow( parent, id, pos, size, wxSUNKEN_BORDER )
 
- {
 
-     SetBackgroundColour(* wxWHITE);
 
-     SetCursor(wxCursor(wxCURSOR_ARROW));
 
-     m_dragMode = TEST_DRAG_NONE;
 
-     m_draggedShape = (DragShape*) NULL;
 
-     m_dragImage = (wxDragImage*) NULL;
 
-     m_currentlyHighlighted = (DragShape*) NULL;
 
- }
 
- MyCanvas::~MyCanvas()
 
- {
 
-     ClearShapes();
 
-     if (m_dragImage)
 
-         delete m_dragImage;
 
- }
 
- void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) )
 
- {
 
-     wxPaintDC dc( this );
 
-     PrepareDC( dc );
 
-     DrawShapes(dc);
 
- }
 
- void MyCanvas::OnEraseBackground(wxEraseEvent& event)
 
- {
 
-     if (wxGetApp().GetBackgroundBitmap().IsOk())
 
-     {
 
-         wxSize sz = GetClientSize();
 
-         wxRect rect(0, 0, sz.x, sz.y);
 
-         if (event.GetDC())
 
-         {
 
-             wxGetApp().TileBitmap(rect, *(event.GetDC()), wxGetApp().GetBackgroundBitmap());
 
-         }
 
-         else
 
-         {
 
-             wxClientDC dc(this);
 
-             wxGetApp().TileBitmap(rect, dc, wxGetApp().GetBackgroundBitmap());
 
-         }
 
-     }
 
-     else
 
-         event.Skip(); // The official way of doing it
 
- }
 
- void MyCanvas::OnMouseEvent(wxMouseEvent& event)
 
- {
 
-     if (event.LeftDown())
 
-     {
 
-         DragShape* shape = FindShape(event.GetPosition());
 
-         if (shape)
 
-         {
 
-             // We tentatively start dragging, but wait for
 
-             // mouse movement before dragging properly.
 
-             m_dragMode = TEST_DRAG_START;
 
-             m_dragStartPos = event.GetPosition();
 
-             m_draggedShape = shape;
 
-         }
 
-     }
 
-     else if (event.LeftUp() && m_dragMode != TEST_DRAG_NONE)
 
-     {
 
-         // Finish dragging
 
-         m_dragMode = TEST_DRAG_NONE;
 
-         if (!m_draggedShape || !m_dragImage)
 
-             return;
 
-         m_draggedShape->SetPosition(m_draggedShape->GetPosition()
 
-                                     + event.GetPosition() - m_dragStartPos);
 
-         m_dragImage->Hide();
 
-         m_dragImage->EndDrag();
 
-         wxDELETE(m_dragImage);
 
-         m_draggedShape->SetShow(true);
 
-         m_currentlyHighlighted = (DragShape*) NULL;
 
-         m_draggedShape = (DragShape*) NULL;
 
-         Refresh(true);
 
-     }
 
-     else if (event.Dragging() && m_dragMode != TEST_DRAG_NONE)
 
-     {
 
-         if (m_dragMode == TEST_DRAG_START)
 
-         {
 
-             // We will start dragging if we've moved beyond a couple of pixels
 
-             int tolerance = 2;
 
-             int dx = abs(event.GetPosition().x - m_dragStartPos.x);
 
-             int dy = abs(event.GetPosition().y - m_dragStartPos.y);
 
-             if (dx <= tolerance && dy <= tolerance)
 
-                 return;
 
-             // Start the drag.
 
-             m_dragMode = TEST_DRAG_DRAGGING;
 
-             if (m_dragImage)
 
-                 delete m_dragImage;
 
-             // Erase the dragged shape from the canvas
 
-             m_draggedShape->SetShow(false);
 
-             // redraw immediately
 
-             Refresh(true);
 
-             Update();
 
-             switch (m_draggedShape->GetDragMethod())
 
-             {
 
-                 case SHAPE_DRAG_BITMAP:
 
-                 {
 
-                     m_dragImage = new MyDragImage(this, m_draggedShape->GetBitmap(), wxCursor(wxCURSOR_HAND));
 
-                     break;
 
-                 }
 
-                 case SHAPE_DRAG_TEXT:
 
-                 {
 
-                     m_dragImage = new MyDragImage(this, wxString(wxT("Dragging some test text")), wxCursor(wxCURSOR_HAND));
 
-                     break;
 
-                 }
 
-                 case SHAPE_DRAG_ICON:
 
-                 {
 
-                     m_dragImage = new MyDragImage(this, wxICON(dragicon), wxCursor(wxCURSOR_HAND));
 
-                     break;
 
-                 }
 
-             }
 
-             bool fullScreen = wxGetApp().GetUseScreen();
 
-             // The offset between the top-left of the shape image and the current shape position
 
-             wxPoint beginDragHotSpot = m_dragStartPos - m_draggedShape->GetPosition();
 
-             // Now we do this inside the implementation: always assume
 
-             // coordinates relative to the capture window (client coordinates)
 
-             //if (fullScreen)
 
-             //    beginDragHotSpot -= ClientToScreen(wxPoint(0, 0));
 
-             if (!m_dragImage->BeginDrag(beginDragHotSpot, this, fullScreen))
 
-             {
 
-                 wxDELETE(m_dragImage);
 
-                 m_dragMode = TEST_DRAG_NONE;
 
-             } else
 
-             {
 
-                 m_dragImage->Move(event.GetPosition());
 
-                 m_dragImage->Show();
 
-             }
 
-         }
 
-         else if (m_dragMode == TEST_DRAG_DRAGGING)
 
-         {
 
-             // We're currently dragging. See if we're over another shape.
 
-             DragShape* onShape = FindShape(event.GetPosition());
 
-             bool mustUnhighlightOld = false;
 
-             bool mustHighlightNew = false;
 
-             if (m_currentlyHighlighted)
 
-             {
 
-                 if ((onShape == (DragShape*) NULL) || (m_currentlyHighlighted != onShape))
 
-                     mustUnhighlightOld = true;
 
-             }
 
-             if (onShape && (onShape != m_currentlyHighlighted) && onShape->IsShown())
 
-                 mustHighlightNew = true;
 
-             if (mustUnhighlightOld || mustHighlightNew)
 
-                 m_dragImage->Hide();
 
-             // Now with the drag image switched off, we can change the window contents.
 
-             if (mustUnhighlightOld)
 
-                 m_currentlyHighlighted = (DragShape*) NULL;
 
-             if (mustHighlightNew)
 
-                 m_currentlyHighlighted = onShape;
 
-             if (mustUnhighlightOld || mustHighlightNew)
 
-             {
 
-                 Refresh(mustUnhighlightOld);
 
-                 Update();
 
-             }
 
-             // Move and show the image again
 
-             m_dragImage->Move(event.GetPosition());
 
-             if (mustUnhighlightOld || mustHighlightNew)
 
-                  m_dragImage->Show();
 
-         }
 
-     }
 
- }
 
- void MyCanvas::DrawShapes(wxDC& dc)
 
- {
 
-     wxList::compatibility_iterator node = m_displayList.GetFirst();
 
-     while (node)
 
-     {
 
-         DragShape* shape = (DragShape*) node->GetData();
 
-         if (shape->IsShown() && m_draggedShape != shape)
 
-         {
 
-             shape->Draw(dc, (m_currentlyHighlighted == shape));
 
-         }
 
-         node = node->GetNext();
 
-     }
 
- }
 
- void MyCanvas::EraseShape(DragShape* shape, wxDC& dc)
 
- {
 
-     wxSize sz = GetClientSize();
 
-     wxRect rect(0, 0, sz.x, sz.y);
 
-     wxRect rect2(shape->GetRect());
 
-     dc.SetClippingRegion(rect2.x, rect2.y, rect2.width, rect2.height);
 
-     wxGetApp().TileBitmap(rect, dc, wxGetApp().GetBackgroundBitmap());
 
-     dc.DestroyClippingRegion();
 
- }
 
- void MyCanvas::ClearShapes()
 
- {
 
-     wxList::compatibility_iterator node = m_displayList.GetFirst();
 
-     while (node)
 
-     {
 
-         DragShape* shape = (DragShape*) node->GetData();
 
-         delete shape;
 
-         node = node->GetNext();
 
-     }
 
-     m_displayList.Clear();
 
- }
 
- DragShape* MyCanvas::FindShape(const wxPoint& pt) const
 
- {
 
-     wxList::compatibility_iterator node = m_displayList.GetFirst();
 
-     while (node)
 
-     {
 
-         DragShape* shape = (DragShape*) node->GetData();
 
-         if (shape->HitTest(pt))
 
-             return shape;
 
-         node = node->GetNext();
 
-     }
 
-     return (DragShape*) NULL;
 
- }
 
- // MyFrame
 
- IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
 
- wxBEGIN_EVENT_TABLE(MyFrame,wxFrame)
 
-   EVT_MENU    (wxID_ABOUT, MyFrame::OnAbout)
 
-   EVT_MENU    (wxID_EXIT,  MyFrame::OnQuit)
 
- wxEND_EVENT_TABLE()
 
- MyFrame::MyFrame()
 
- : wxFrame( (wxFrame *)NULL, wxID_ANY, wxT("wxDragImage sample"),
 
-           wxPoint(20,20), wxSize(470,360) )
 
- {
 
-     wxMenu *file_menu = new wxMenu();
 
-     file_menu->Append( wxID_ABOUT, wxT("&About"));
 
-     file_menu->AppendCheckItem( TEST_USE_SCREEN, wxT("&Use whole screen for dragging"), wxT("Use whole screen"));
 
-     file_menu->Append( wxID_EXIT, wxT("E&xit"));
 
-     wxMenuBar *menu_bar = new wxMenuBar();
 
-     menu_bar->Append(file_menu, wxT("&File"));
 
-     SetIcon(wxICON(sample));
 
-     SetMenuBar( menu_bar );
 
- #if wxUSE_STATUSBAR
 
-     CreateStatusBar(2);
 
-     int widths[] = { -1, 100 };
 
-     SetStatusWidths( 2, widths );
 
- #endif // wxUSE_STATUSBAR
 
-     m_canvas = new MyCanvas( this, wxID_ANY, wxPoint(0,0), wxSize(10,10) );
 
- }
 
- void MyFrame::OnQuit( wxCommandEvent &WXUNUSED(event) )
 
- {
 
-     Close( true );
 
- }
 
- void MyFrame::OnAbout( wxCommandEvent &WXUNUSED(event) )
 
- {
 
-     (void)wxMessageBox( wxT("wxDragImage demo\n")
 
-         wxT("Julian Smart (c) 2000"),
 
-         wxT("About wxDragImage Demo"),
 
-         wxICON_INFORMATION | wxOK );
 
- }
 
- //-----------------------------------------------------------------------------
 
- // MyApp
 
- //-----------------------------------------------------------------------------
 
- wxBEGIN_EVENT_TABLE(MyApp, wxApp)
 
-     EVT_MENU(TEST_USE_SCREEN, MyApp::OnUseScreen)
 
- wxEND_EVENT_TABLE()
 
- MyApp::MyApp()
 
- {
 
-     // Drag across whole screen
 
-     m_useScreen = false;
 
- }
 
- bool MyApp::OnInit()
 
- {
 
-     if ( !wxApp::OnInit() )
 
-         return false;
 
- #if wxUSE_LIBPNG
 
-     wxImage::AddHandler( new wxPNGHandler );
 
- #endif
 
-     wxImage image;
 
-     if (image.LoadFile(wxT("backgrnd.png"), wxBITMAP_TYPE_PNG))
 
-     {
 
-         m_background = wxBitmap(image);
 
-     }
 
-     MyFrame *frame = new MyFrame();
 
-     wxString rootName(wxT("shape0"));
 
-     for (int i = 1; i < 4; i++)
 
-     {
 
-     /* For some reason under wxX11, the 2nd LoadFile in this loop fails, with
 
-        a BadMatch inside CreateFromImage (inside ConvertToBitmap). This happens even if you copy
 
-        the first file over the second file. */
 
-         if (image.LoadFile(wxString::Format("%s%d.png", rootName, i), wxBITMAP_TYPE_PNG))
 
-         {
 
-             DragShape* newShape = new DragShape(wxBitmap(image));
 
-             newShape->SetPosition(wxPoint(i*50, i*50));
 
-             if (i == 2)
 
-                 newShape->SetDragMethod(SHAPE_DRAG_TEXT);
 
-             else if (i == 3)
 
-                 newShape->SetDragMethod(SHAPE_DRAG_ICON);
 
-             else
 
-                 newShape->SetDragMethod(SHAPE_DRAG_BITMAP);
 
-             frame->GetCanvas()->GetDisplayList().Append(newShape);
 
-         }
 
-     }
 
- #if 0
 
-     // Under Motif or GTK, this demonstrates that
 
-     // wxScreenDC only gets the root window content.
 
-     // We need to be able to copy the overall content
 
-     // for full-screen dragging to work.
 
-     int w, h;
 
-     wxDisplaySize(& w, & h);
 
-     wxBitmap bitmap(w, h);
 
-     wxScreenDC dc;
 
-     wxMemoryDC memDC;
 
-     memDC.SelectObject(bitmap);
 
-     memDC.Blit(0, 0, w, h, & dc, 0, 0);
 
-     memDC.SelectObject(wxNullBitmap);
 
-     m_background = bitmap;
 
- #endif
 
-     frame->Show( true );
 
-     return true;
 
- }
 
- int MyApp::OnExit()
 
- {
 
-     return 0;
 
- }
 
- bool MyApp::TileBitmap(const wxRect& rect, wxDC& dc, wxBitmap& bitmap)
 
- {
 
-     int w = bitmap.GetWidth();
 
-     int h = bitmap.GetHeight();
 
-     int i, j;
 
-     for (i = rect.x; i < rect.x + rect.width; i += w)
 
-     {
 
-         for (j = rect.y; j < rect.y + rect.height; j+= h)
 
-             dc.DrawBitmap(bitmap, i, j);
 
-     }
 
-     return true;
 
- }
 
- void MyApp::OnUseScreen(wxCommandEvent& WXUNUSED(event))
 
- {
 
-     m_useScreen = !m_useScreen;
 
- }
 
- // DragShape
 
- DragShape::DragShape(const wxBitmap& bitmap)
 
- {
 
-     m_bitmap = bitmap;
 
-     m_pos.x = 0;
 
-     m_pos.y = 0;
 
-     m_dragMethod = SHAPE_DRAG_BITMAP;
 
-     m_show = true;
 
- }
 
- bool DragShape::HitTest(const wxPoint& pt) const
 
- {
 
-     wxRect rect(GetRect());
 
-     return rect.Contains(pt.x, pt.y);
 
- }
 
- bool DragShape::Draw(wxDC& dc, bool highlight)
 
- {
 
-     if (m_bitmap.IsOk())
 
-     {
 
-         wxMemoryDC memDC;
 
-         memDC.SelectObject(m_bitmap);
 
-         dc.Blit(m_pos.x, m_pos.y, m_bitmap.GetWidth(), m_bitmap.GetHeight(),
 
-             & memDC, 0, 0, wxCOPY, true);
 
-         if (highlight)
 
-         {
 
-             dc.SetPen(*wxWHITE_PEN);
 
-             dc.SetBrush(*wxTRANSPARENT_BRUSH);
 
-             dc.DrawRectangle(m_pos.x, m_pos.y, m_bitmap.GetWidth(), m_bitmap.GetHeight());
 
-         }
 
-         return true;
 
-     }
 
-     else
 
-         return false;
 
- }
 
- // MyDragImage
 
- // On some platforms, notably Mac OS X with Core Graphics, we can't blit from
 
- // a window, so we need to draw the background explicitly.
 
- bool MyDragImage::UpdateBackingFromWindow(wxDC& WXUNUSED(windowDC), wxMemoryDC& destDC, const wxRect& WXUNUSED(sourceRect),
 
-                     const wxRect& destRect) const
 
- {
 
-     destDC.SetClippingRegion(destRect);
 
-     if (wxGetApp().GetBackgroundBitmap().IsOk())
 
-         wxGetApp().TileBitmap(destRect, destDC, wxGetApp().GetBackgroundBitmap());
 
-     m_canvas->DrawShapes(destDC);
 
-     return true;
 
- }
 
 
  |