X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/11e2dfd37dcac4e8c155807de8e1ba222c3e83fb..f3793429150870568992e96fedacbdf87c0c3340:/samples/dragimag/dragimag.cpp diff --git a/samples/dragimag/dragimag.cpp b/samples/dragimag/dragimag.cpp index 2ef5db853c..31b3f4c2e0 100644 --- a/samples/dragimag/dragimag.cpp +++ b/samples/dragimag/dragimag.cpp @@ -25,7 +25,7 @@ // Under Windows, change this to 1 // to use wxGenericDragImage -#define wxUSE_GENERIC_DRAGIMAGE 0 +#define wxUSE_GENERIC_DRAGIMAGE 1 #if wxUSE_GENERIC_DRAGIMAGE #include "wx/generic/dragimgg.h" @@ -36,7 +36,7 @@ #include "dragimag.h" -#if defined(__WXGTK__) || defined(__WXMOTIF__) +#if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXMGL__) || defined(__WXX11__) #include "mondrian.xpm" #include "dragicon.xpm" #endif @@ -83,7 +83,6 @@ void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) ) PrepareDC( dc ); DrawShapes(dc); - } void MyCanvas::OnEraseBackground(wxEraseEvent& event) @@ -92,7 +91,7 @@ void MyCanvas::OnEraseBackground(wxEraseEvent& event) { wxSize sz = GetClientSize(); wxRect rect(0, 0, sz.x, sz.y); - + if (event.GetDC()) { wxGetApp().TileBitmap(rect, *(event.GetDC()), wxGetApp().GetBackgroundBitmap()); @@ -131,27 +130,21 @@ void MyCanvas::OnMouseEvent(wxMouseEvent& event) if (!m_draggedShape || !m_dragImage) return; - wxPoint newPos(m_draggedShape->GetPosition().x + (event.GetPosition().x - m_dragStartPos.x), - m_draggedShape->GetPosition().y + (event.GetPosition().y - m_dragStartPos.y)); - - m_draggedShape->SetPosition(newPos); + m_draggedShape->SetPosition(m_draggedShape->GetPosition() + + event.GetPosition() - m_dragStartPos); m_dragImage->Hide(); m_dragImage->EndDrag(); delete m_dragImage; m_dragImage = NULL; - wxClientDC dc(this); - if (m_currentlyHighlighted) - { - m_currentlyHighlighted->Draw(dc); - } - m_draggedShape->SetShow(TRUE); - m_draggedShape->Draw(dc); + m_draggedShape->SetShow(true); m_currentlyHighlighted = (DragShape*) NULL; m_draggedShape = (DragShape*) NULL; + + Refresh(true); } else if (event.Dragging() && m_dragMode != TEST_DRAG_NONE) { @@ -165,9 +158,6 @@ void MyCanvas::OnMouseEvent(wxMouseEvent& event) if (dx <= tolerance && dy <= tolerance) return; - wxPoint newPos(m_draggedShape->GetPosition().x + (event.GetPosition().x - m_dragStartPos.x), - m_draggedShape->GetPosition().y + (event.GetPosition().y - m_dragStartPos.y)); - // Start the drag. m_dragMode = TEST_DRAG_DRAGGING; @@ -175,113 +165,89 @@ void MyCanvas::OnMouseEvent(wxMouseEvent& event) delete m_dragImage; // Erase the dragged shape from the canvas - m_draggedShape->SetShow(FALSE); - wxClientDC dc(this); - EraseShape(m_draggedShape, dc); - DrawShapes(dc); + m_draggedShape->SetShow(false); + + // redraw immediately + Refresh(true); + Update(); switch (m_draggedShape->GetDragMethod()) { case SHAPE_DRAG_BITMAP: { - wxPoint hotSpot(event.GetPosition().x - newPos.x, event.GetPosition().y - newPos.y); - m_dragImage = new wxDragImage(m_draggedShape->GetBitmap(), wxCursor(wxCURSOR_HAND), hotSpot); + m_dragImage = new MyDragImage(this, m_draggedShape->GetBitmap(), wxCursor(wxCURSOR_HAND)); break; } case SHAPE_DRAG_TEXT: { - wxPoint hotSpot(event.GetPosition().x - newPos.x, event.GetPosition().y - newPos.y); - m_dragImage = new wxDragImage("Dragging some test text", wxCursor(wxCURSOR_HAND), hotSpot); + m_dragImage = new MyDragImage(this, wxString(_T("Dragging some test text")), wxCursor(wxCURSOR_HAND)); break; } case SHAPE_DRAG_ICON: { - wxPoint hotSpot(event.GetPosition().x - newPos.x, event.GetPosition().y - newPos.y); - - // Can anyone explain why this test is necessary, - // to prevent a gcc error? -#ifdef __WXMOTIF__ - wxIcon icon(dragicon_xpm); -#else - wxIcon icon(wxICON(dragicon)); -#endif - - m_dragImage = new wxDragImage(icon, wxCursor(wxCURSOR_HAND), hotSpot); + m_dragImage = new MyDragImage(this, wxICON(dragicon), wxCursor(wxCURSOR_HAND)); break; } } - bool fullScreen = FALSE; - if (wxGetApp().GetUseScreen()) - { - newPos = ClientToScreen(newPos); - fullScreen = TRUE; - } + bool fullScreen = wxGetApp().GetUseScreen(); - bool retValue; + // The offset between the top-left of the shape image and the current shape position + wxPoint beginDragHotSpot = m_dragStartPos - m_draggedShape->GetPosition(); - if (fullScreen) - // This line uses the whole screen... - retValue = m_dragImage->BeginDrag(wxPoint(0, 0), this, TRUE); - // while this line restricts dragging to the parent frame. - // retValue = m_dragImage->BeginDrag(wxPoint(0, 0), this, GetParent()); - else - retValue = m_dragImage->BeginDrag(wxPoint(0, 0), this); + // 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 (!retValue) + if (!m_dragImage->BeginDrag(beginDragHotSpot, this, fullScreen)) { delete m_dragImage; m_dragImage = (wxDragImage*) NULL; m_dragMode = TEST_DRAG_NONE; + + } else + { + m_dragImage->Move(event.GetPosition()); + m_dragImage->Show(); } - m_dragImage->Move(newPos); - 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; + bool mustUnhighlightOld = false; + bool mustHighlightNew = false; if (m_currentlyHighlighted) { if ((onShape == (DragShape*) NULL) || (m_currentlyHighlighted != onShape)) - mustUnhighlightOld = TRUE; + mustUnhighlightOld = true; } if (onShape && (onShape != m_currentlyHighlighted) && onShape->IsShown()) - mustHighlightNew = TRUE; + mustHighlightNew = true; if (mustUnhighlightOld || mustHighlightNew) m_dragImage->Hide(); - + // Now with the drag image switched off, we can change the window contents. - if (mustUnhighlightOld) - { - wxClientDC clientDC(this); - m_currentlyHighlighted->Draw(clientDC); m_currentlyHighlighted = (DragShape*) NULL; - } + if (mustHighlightNew) - { - wxClientDC clientDC(this); m_currentlyHighlighted = onShape; - m_currentlyHighlighted->Draw(clientDC, wxINVERT); - } - wxPoint newPos(m_draggedShape->GetPosition().x + (event.GetPosition().x - m_dragStartPos.x), - m_draggedShape->GetPosition().y + (event.GetPosition().y - m_dragStartPos.y)); - - if (wxGetApp().GetUseScreen()) + if (mustUnhighlightOld || mustHighlightNew) { - newPos = ClientToScreen(newPos); + Refresh(mustUnhighlightOld); + Update(); } // Move and show the image again - m_dragImage->Move(newPos); + m_dragImage->Move(event.GetPosition()); if (mustUnhighlightOld || mustHighlightNew) m_dragImage->Show(); @@ -291,13 +257,15 @@ void MyCanvas::OnMouseEvent(wxMouseEvent& event) void MyCanvas::DrawShapes(wxDC& dc) { - wxNode* node = m_displayList.First(); + wxList::compatibility_iterator node = m_displayList.GetFirst(); while (node) { - DragShape* shape = (DragShape*) node->Data(); - if (shape->IsShown()) - shape->Draw(dc); - node = node->Next(); + DragShape* shape = (DragShape*) node->GetData(); + if (shape->IsShown() && m_draggedShape != shape) + { + shape->Draw(dc, (m_currentlyHighlighted == shape)); + } + node = node->GetNext(); } } @@ -308,7 +276,7 @@ void MyCanvas::EraseShape(DragShape* shape, wxDC& dc) wxRect rect2(shape->GetRect()); dc.SetClippingRegion(rect2.x, rect2.y, rect2.width, rect2.height); - + wxGetApp().TileBitmap(rect, dc, wxGetApp().GetBackgroundBitmap()); dc.DestroyClippingRegion(); @@ -316,31 +284,30 @@ void MyCanvas::EraseShape(DragShape* shape, wxDC& dc) void MyCanvas::ClearShapes() { - wxNode* node = m_displayList.First(); + wxList::compatibility_iterator node = m_displayList.GetFirst(); while (node) { - DragShape* shape = (DragShape*) node->Data(); + DragShape* shape = (DragShape*) node->GetData(); delete shape; - node = node->Next(); + node = node->GetNext(); } m_displayList.Clear(); } DragShape* MyCanvas::FindShape(const wxPoint& pt) const { - wxNode* node = m_displayList.First(); + wxList::compatibility_iterator node = m_displayList.GetFirst(); while (node) { - DragShape* shape = (DragShape*) node->Data(); + DragShape* shape = (DragShape*) node->GetData(); if (shape->HitTest(pt)) return shape; - node = node->Next(); + node = node->GetNext(); } return (DragShape*) NULL; } // MyFrame - IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame ) BEGIN_EVENT_TABLE(MyFrame,wxFrame) @@ -349,36 +316,40 @@ BEGIN_EVENT_TABLE(MyFrame,wxFrame) END_EVENT_TABLE() MyFrame::MyFrame() - : wxFrame( (wxFrame *)NULL, -1, "wxDragImage sample", - wxPoint(20,20), wxSize(470,360) ) +: wxFrame( (wxFrame *)NULL, wxID_ANY, _T("wxDragImage sample"), + wxPoint(20,20), wxSize(470,360) ) { - wxMenu *file_menu = new wxMenu(); - file_menu->Append( wxID_ABOUT, "&About..."); - file_menu->Append( TEST_USE_SCREEN, "&Use whole screen for dragging", "Use whole screen", TRUE); - file_menu->Append( wxID_EXIT, "E&xit"); + wxMenu *file_menu = new wxMenu(); + file_menu->Append( wxID_ABOUT, _T("&About...")); + file_menu->AppendCheckItem( TEST_USE_SCREEN, _T("&Use whole screen for dragging"), _T("Use whole screen")); + file_menu->Append( wxID_EXIT, _T("E&xit")); - wxMenuBar *menu_bar = new wxMenuBar(); - menu_bar->Append(file_menu, "&File"); + wxMenuBar *menu_bar = new wxMenuBar(); + menu_bar->Append(file_menu, _T("&File")); - SetMenuBar( menu_bar ); + SetIcon(wxICON(mondrian)); + SetMenuBar( menu_bar ); - CreateStatusBar(2); - int widths[] = { -1, 100 }; - SetStatusWidths( 2, widths ); +#if wxUSE_STATUSBAR + CreateStatusBar(2); + int widths[] = { -1, 100 }; + SetStatusWidths( 2, widths ); +#endif // wxUSE_STATUSBAR - m_canvas = new MyCanvas( this, -1, wxPoint(0,0), wxSize(10,10) ); + m_canvas = new MyCanvas( this, wxID_ANY, wxPoint(0,0), wxSize(10,10) ); } void MyFrame::OnQuit( wxCommandEvent &WXUNUSED(event) ) { - Close( TRUE ); + Close( true ); } void MyFrame::OnAbout( wxCommandEvent &WXUNUSED(event) ) { - (void)wxMessageBox( "wxDragImage demo\n" - "Julian Smart (c) 2000", - "About wxDragImage Demo", wxICON_INFORMATION | wxOK ); + (void)wxMessageBox( _T("wxDragImage demo\n") + _T("Julian Smart (c) 2000"), + _T("About wxDragImage Demo"), + wxICON_INFORMATION | wxOK ); } //----------------------------------------------------------------------------- @@ -392,34 +363,36 @@ END_EVENT_TABLE() MyApp::MyApp() { // Drag across whole screen - m_useScreen = FALSE; + m_useScreen = false; } bool MyApp::OnInit() { + if ( !wxApp::OnInit() ) + return false; + #if wxUSE_LIBPNG wxImage::AddHandler( new wxPNGHandler ); #endif wxImage image; - if (image.LoadFile("backgrnd.png", wxBITMAP_TYPE_PNG)) + if (image.LoadFile(_T("backgrnd.png"), wxBITMAP_TYPE_PNG)) { - m_background = image.ConvertToBitmap(); + m_background = wxBitmap(image); } - MyFrame *frame = new MyFrame(); - wxString rootName("shape0"); + wxString rootName(_T("shape0")); - int i; - for (i = 1; i < 4; i++) + for (int i = 1; i < 4; i++) { - wxString filename; - filename.Printf("%s%d.png", (const char*) rootName, i); - if (image.LoadFile(filename, wxBITMAP_TYPE_PNG)) + /* 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(image.ConvertToBitmap()); + DragShape* newShape = new DragShape(wxBitmap(image)); newShape->SetPosition(wxPoint(i*50, i*50)); if (i == 2) @@ -449,26 +422,31 @@ bool MyApp::OnInit() m_background = bitmap; #endif - frame->Show( TRUE ); + frame->Show( true ); + + return 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; + return true; } -void MyApp::OnUseScreen(wxCommandEvent& event) +void MyApp::OnUseScreen(wxCommandEvent& WXUNUSED(event)) { m_useScreen = !m_useScreen; } @@ -481,32 +459,51 @@ DragShape::DragShape(const wxBitmap& bitmap) m_pos.x = 0; m_pos.y = 0; m_dragMethod = SHAPE_DRAG_BITMAP; - m_show = TRUE; -} - -DragShape::~DragShape() -{ + m_show = true; } bool DragShape::HitTest(const wxPoint& pt) const { wxRect rect(GetRect()); - return rect.Inside(pt.x, pt.y); + return rect.Contains(pt.x, pt.y); } -bool DragShape::Draw(wxDC& dc, int op) +bool DragShape::Draw(wxDC& dc, bool highlight) { if (m_bitmap.Ok()) { wxMemoryDC memDC; memDC.SelectObject(m_bitmap); - + dc.Blit(m_pos.x, m_pos.y, m_bitmap.GetWidth(), m_bitmap.GetHeight(), - & memDC, 0, 0, op, TRUE); + & 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; + return true; } else - return FALSE; + 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().Ok()) + wxGetApp().TileBitmap(destRect, destDC, wxGetApp().GetBackgroundBitmap()); + + m_canvas->DrawShapes(destDC); + return true; }