bool MyApp::OnInit() { #if wxUSE_LIBPNG wxImage::AddHandler( new wxPNGHandler ); #endif wxImage image; if (image.LoadFile(_T("backgrnd.png"), wxBITMAP_TYPE_PNG)) { m_background = wxBitmap(image); } MyFrame *frame = new MyFrame(); wxString rootName(_T("shape0")); int i; for (i = 1; i < 4; i++) { wxString filename; filename.Printf(wxT("%s%d.png"), (const wxChar*)rootName, 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(filename, 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; }
void MyCanvas::DrawShapes(wxDC& dc) { wxList::compatibility_iterator node = m_displayList.GetFirst(); while (node) { DragShape* shape = (DragShape*) node->GetData(); if (shape->IsShown()) shape->Draw(dc); node = node->GetNext(); } }
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; }
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::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(); 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_currentlyHighlighted = (DragShape*) NULL; m_draggedShape = (DragShape*) NULL; } 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); wxClientDC dc(this); EraseShape(m_draggedShape, dc); DrawShapes(dc); switch (m_draggedShape->GetDragMethod()) { case SHAPE_DRAG_BITMAP: { m_dragImage = new wxDragImage(m_draggedShape->GetBitmap(), wxCursor(wxCURSOR_HAND)); break; } case SHAPE_DRAG_TEXT: { m_dragImage = new wxDragImage(wxString(_T("Dragging some test text")), wxCursor(wxCURSOR_HAND)); break; } case SHAPE_DRAG_ICON: { m_dragImage = new wxDragImage(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)) { delete m_dragImage; m_dragImage = (wxDragImage*) NULL; 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) { wxClientDC clientDC(this); m_currentlyHighlighted->Draw(clientDC); m_currentlyHighlighted = (DragShape*) NULL; } if (mustHighlightNew) { wxClientDC clientDC(this); m_currentlyHighlighted = onShape; m_currentlyHighlighted->Draw(clientDC, wxINVERT); } // Move and show the image again m_dragImage->Move(event.GetPosition()); if (mustUnhighlightOld || mustHighlightNew) m_dragImage->Show(); } } }