/[pcsx2_0.9.7]/branch/r3113_0.9.7_beta/3rdparty/wxWidgets/src/generic/dragimgg.cpp
ViewVC logotype

Annotation of /branch/r3113_0.9.7_beta/3rdparty/wxWidgets/src/generic/dragimgg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 32 - (hide annotations) (download)
Tue Sep 7 03:29:01 2010 UTC (10 years ago) by william
File size: 16260 byte(s)
branching from upstream revision (http://pcsx2.googlecode.com/svn/trunk
): r3113 to
https://svn.netsolutions.dnsalias.com/websvn/ps2/pcsx2/pcsx2_0.9.7/branch/r3113_0.9.7_beta
1 william 31 /////////////////////////////////////////////////////////////////////////////
2     // Name: src/generic/dragimgg.cpp
3     // Purpose: Generic wxDragImage implementation
4     // Author: Julian Smart
5     // Modified by:
6     // Created: 29/2/2000
7     // RCS-ID: $Id: dragimgg.cpp 42397 2006-10-25 12:12:56Z VS $
8     // Copyright: (c) Julian Smart
9     // Licence: wxWindows licence
10     /////////////////////////////////////////////////////////////////////////////
11    
12     // ============================================================================
13     // declarations
14     // ============================================================================
15    
16     // ----------------------------------------------------------------------------
17     // headers
18     // ----------------------------------------------------------------------------
19    
20     // For compilers that support precompilation, includes "wx.h".
21     #include "wx/wxprec.h"
22    
23     #ifdef __BORLANDC__
24     #pragma hdrstop
25     #endif
26    
27     #if wxUSE_DRAGIMAGE
28    
29     #ifndef WX_PRECOMP
30     #include <stdio.h>
31     #include "wx/window.h"
32     #include "wx/frame.h"
33     #include "wx/dcclient.h"
34     #include "wx/dcscreen.h"
35     #include "wx/dcmemory.h"
36     #include "wx/settings.h"
37     #include "wx/intl.h"
38     #include "wx/log.h"
39     #include "wx/image.h"
40     #endif
41    
42     #define wxUSE_IMAGE_IN_DRAGIMAGE 1
43    
44     #include "wx/generic/dragimgg.h"
45    
46     // ----------------------------------------------------------------------------
47     // macros
48     // ----------------------------------------------------------------------------
49    
50     IMPLEMENT_DYNAMIC_CLASS(wxGenericDragImage, wxObject)
51    
52     // ============================================================================
53     // implementation
54     // ============================================================================
55    
56     // ----------------------------------------------------------------------------
57     // wxGenericDragImage ctors/dtor
58     // ----------------------------------------------------------------------------
59    
60     wxGenericDragImage::~wxGenericDragImage()
61     {
62     if (m_windowDC)
63     {
64     delete m_windowDC;
65     }
66     }
67    
68     void wxGenericDragImage::Init()
69     {
70     m_isDirty = false;
71     m_isShown = false;
72     m_windowDC = (wxDC*) NULL;
73     m_window = (wxWindow*) NULL;
74     m_fullScreen = false;
75     #ifdef wxHAS_NATIVE_OVERLAY
76     m_dcOverlay = NULL;
77     #else
78     m_pBackingBitmap = (wxBitmap*) NULL;
79     #endif
80     }
81    
82     #if WXWIN_COMPATIBILITY_2_6
83     wxGenericDragImage::wxGenericDragImage(const wxCursor& cursor, const wxPoint& WXUNUSED(cursorHotspot))
84     {
85     Init();
86     Create(cursor);
87     }
88    
89     wxGenericDragImage::wxGenericDragImage(const wxBitmap& image, const wxCursor& cursor, const wxPoint& WXUNUSED(cursorHotspot))
90     {
91     Init();
92    
93     Create(image, cursor);
94     }
95    
96     wxGenericDragImage::wxGenericDragImage(const wxIcon& image, const wxCursor& cursor, const wxPoint& WXUNUSED(cursorHotspot))
97     {
98     Init();
99    
100     Create(image, cursor);
101     }
102    
103     wxGenericDragImage::wxGenericDragImage(const wxString& str, const wxCursor& cursor, const wxPoint& WXUNUSED(cursorHotspot))
104     {
105     Init();
106    
107     Create(str, cursor);
108     }
109    
110     bool wxGenericDragImage::Create(const wxCursor& cursor, const wxPoint& WXUNUSED(cursorHotspot))
111     {
112     return Create(cursor);
113     }
114    
115     bool wxGenericDragImage::Create(const wxBitmap& image, const wxCursor& cursor, const wxPoint& WXUNUSED(cursorHotspot))
116     {
117     return Create(image, cursor);
118     }
119    
120     bool wxGenericDragImage::Create(const wxIcon& image, const wxCursor& cursor, const wxPoint& WXUNUSED(cursorHotspot))
121     {
122     return Create(image, cursor);
123     }
124    
125     bool wxGenericDragImage::Create(const wxString& str, const wxCursor& cursor, const wxPoint& WXUNUSED(cursorHotspot))
126     {
127     return Create(str, cursor);
128     }
129     #endif // WXWIN_COMPATIBILITY_2_6
130    
131     // Attributes
132     ////////////////////////////////////////////////////////////////////////////
133    
134    
135     // Operations
136     ////////////////////////////////////////////////////////////////////////////
137    
138     // Create a drag image with a virtual image (need to override DoDrawImage, GetImageRect)
139     bool wxGenericDragImage::Create(const wxCursor& cursor)
140     {
141     m_cursor = cursor;
142    
143     return true;
144     }
145    
146     // Create a drag image from a bitmap and optional cursor
147     bool wxGenericDragImage::Create(const wxBitmap& image, const wxCursor& cursor)
148     {
149     // We don't have to combine the cursor explicitly since we simply show the cursor
150     // as we drag. This currently will only work within one window.
151    
152     m_cursor = cursor;
153     m_bitmap = image;
154    
155     return true ;
156     }
157    
158     // Create a drag image from an icon and optional cursor
159     bool wxGenericDragImage::Create(const wxIcon& image, const wxCursor& cursor)
160     {
161     // We don't have to combine the cursor explicitly since we simply show the cursor
162     // as we drag. This currently will only work within one window.
163    
164     m_cursor = cursor;
165     m_icon = image;
166    
167     return true ;
168     }
169    
170     // Create a drag image from a string and optional cursor
171     bool wxGenericDragImage::Create(const wxString& str, const wxCursor& cursor)
172     {
173     wxFont font(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
174    
175     long w = 0, h = 0;
176     wxScreenDC dc;
177     dc.SetFont(font);
178     dc.GetTextExtent(str, & w, & h);
179     dc.SetFont(wxNullFont);
180    
181     wxMemoryDC dc2;
182    
183     // Sometimes GetTextExtent isn't accurate enough, so make it longer
184     wxBitmap bitmap((int) ((w+2) * 1.5), (int) h+2);
185     dc2.SelectObject(bitmap);
186    
187     dc2.SetFont(font);
188     dc2.SetBackground(* wxWHITE_BRUSH);
189     dc2.Clear();
190     dc2.SetBackgroundMode(wxTRANSPARENT);
191     dc2.SetTextForeground(* wxLIGHT_GREY);
192     dc2.DrawText(str, 0, 0);
193     dc2.DrawText(str, 1, 0);
194     dc2.DrawText(str, 2, 0);
195     dc2.DrawText(str, 1, 1);
196     dc2.DrawText(str, 2, 1);
197     dc2.DrawText(str, 1, 2);
198     dc2.DrawText(str, 2, 2);
199    
200     dc2.SetTextForeground(* wxBLACK);
201     dc2.DrawText(str, 1, 1);
202    
203     dc2.SelectObject(wxNullBitmap);
204    
205     #if wxUSE_IMAGE_IN_DRAGIMAGE && (!defined(__WXMSW__) || wxUSE_WXDIB)
206     // Make the bitmap masked
207     wxImage image = bitmap.ConvertToImage();
208     image.SetMaskColour(255, 255, 255);
209     bitmap = wxBitmap(image);
210     #endif
211    
212     return Create(bitmap, cursor);
213     }
214    
215     #if wxUSE_TREECTRL
216     // Create a drag image for the given tree control item
217     bool wxGenericDragImage::Create(const wxTreeCtrl& treeCtrl, wxTreeItemId& id)
218     {
219     wxString str = treeCtrl.GetItemText(id);
220     return Create(str);
221     }
222     #endif
223    
224     #if wxUSE_LISTCTRL
225     // Create a drag image for the given list control item
226     bool wxGenericDragImage::Create(const wxListCtrl& listCtrl, long id)
227     {
228     wxString str = listCtrl.GetItemText(id);
229     return Create(str);
230     }
231     #endif
232    
233     // Begin drag
234     bool wxGenericDragImage::BeginDrag(const wxPoint& hotspot,
235     wxWindow* window,
236     bool fullScreen,
237     wxRect* rect)
238     {
239     wxASSERT_MSG( (window != 0), wxT("Window must not be null in BeginDrag."));
240    
241     // The image should be offset by this amount
242     m_offset = hotspot;
243     m_window = window;
244     m_fullScreen = fullScreen;
245    
246     if (rect)
247     m_boundingRect = * rect;
248    
249     m_isDirty = false;
250     m_isDirty = false;
251    
252     if (window)
253     {
254     window->CaptureMouse();
255    
256     if (m_cursor.Ok())
257     {
258     m_oldCursor = window->GetCursor();
259     window->SetCursor(m_cursor);
260     }
261     }
262    
263     // Make a copy of the window so we can repair damage done as the image is
264     // dragged.
265    
266     wxSize clientSize;
267     wxPoint pt;
268     if (!m_fullScreen)
269     {
270     clientSize = window->GetClientSize();
271     m_boundingRect.x = 0; m_boundingRect.y = 0;
272     m_boundingRect.width = clientSize.x; m_boundingRect.height = clientSize.y;
273     }
274     else
275     {
276     int w, h;
277     wxDisplaySize(& w, & h);
278     clientSize.x = w; clientSize.y = h;
279     if (rect)
280     {
281     pt.x = m_boundingRect.x; pt.y = m_boundingRect.y;
282     clientSize.x = m_boundingRect.width; clientSize.y = m_boundingRect.height;
283     }
284     else
285     {
286     m_boundingRect.x = 0; m_boundingRect.y = 0;
287     m_boundingRect.width = w; m_boundingRect.height = h;
288     }
289     }
290    
291     #ifndef wxHAS_NATIVE_OVERLAY
292     wxBitmap* backing = (m_pBackingBitmap ? m_pBackingBitmap : (wxBitmap*) & m_backingBitmap);
293    
294     if (!backing->Ok() || (backing->GetWidth() < clientSize.x || backing->GetHeight() < clientSize.y))
295     (*backing) = wxBitmap(clientSize.x, clientSize.y);
296     #endif // !wxHAS_NATIVE_OVERLAY
297    
298     if (!m_fullScreen)
299     {
300     m_windowDC = new wxClientDC(window);
301     }
302     else
303     {
304     m_windowDC = new wxScreenDC;
305    
306     #if 0
307     // Use m_boundingRect to limit the area considered.
308     ((wxScreenDC*) m_windowDC)->StartDrawingOnTop(rect);
309     #endif
310    
311     m_windowDC->SetClippingRegion(m_boundingRect.x, m_boundingRect.y,
312     m_boundingRect.width, m_boundingRect.height);
313     }
314    
315     return true;
316     }
317    
318     // Begin drag. hotspot is the location of the drag position relative to the upper-left
319     // corner of the image. This is full screen only. fullScreenRect gives the
320     // position of the window on the screen, to restrict the drag to.
321     bool wxGenericDragImage::BeginDrag(const wxPoint& hotspot, wxWindow* window, wxWindow* fullScreenRect)
322     {
323     wxRect rect;
324    
325     int x = fullScreenRect->GetPosition().x;
326     int y = fullScreenRect->GetPosition().y;
327    
328     wxSize sz = fullScreenRect->GetSize();
329    
330     if (fullScreenRect->GetParent() && !fullScreenRect->IsKindOf(CLASSINFO(wxFrame)))
331     fullScreenRect->GetParent()->ClientToScreen(& x, & y);
332    
333     rect.x = x; rect.y = y;
334     rect.width = sz.x; rect.height = sz.y;
335    
336     return BeginDrag(hotspot, window, true, & rect);
337     }
338    
339     // End drag
340     bool wxGenericDragImage::EndDrag()
341     {
342     if (m_window)
343     {
344     #ifdef __WXMSW__
345     // Under Windows we can be pretty sure this test will give
346     // the correct results
347     if (wxWindow::GetCapture() == m_window)
348     #endif
349     m_window->ReleaseMouse();
350    
351     if (m_cursor.Ok() && m_oldCursor.Ok())
352     {
353     m_window->SetCursor(m_oldCursor);
354     }
355     }
356    
357     if (m_windowDC)
358     {
359     #ifdef wxHAS_NATIVE_OVERLAY
360     m_overlay.Reset();
361     #else
362     m_windowDC->DestroyClippingRegion();
363     #endif
364     delete m_windowDC;
365     m_windowDC = (wxDC*) NULL;
366     }
367    
368     #ifndef wxHAS_NATIVE_OVERLAY
369     m_repairBitmap = wxNullBitmap;
370     #endif
371    
372     return true;
373     }
374    
375     // Move the image: call from OnMouseMove. Pt is in window client coordinates if window
376     // is non-NULL, or in screen coordinates if NULL.
377     bool wxGenericDragImage::Move(const wxPoint& pt)
378     {
379     wxASSERT_MSG( (m_windowDC != (wxDC*) NULL), wxT("No window DC in wxGenericDragImage::Move()") );
380    
381     wxPoint pt2(pt);
382     if (m_fullScreen)
383     pt2 = m_window->ClientToScreen(pt);
384    
385     // Erase at old position, then show at the current position
386     wxPoint oldPos = m_position;
387    
388     bool eraseOldImage = (m_isDirty && m_isShown);
389    
390     if (m_isShown)
391     RedrawImage(oldPos - m_offset, pt2 - m_offset, eraseOldImage, true);
392    
393     m_position = pt2;
394    
395     if (m_isShown)
396     m_isDirty = true;
397    
398     return true;
399     }
400    
401     bool wxGenericDragImage::Show()
402     {
403     wxASSERT_MSG( (m_windowDC != (wxDC*) NULL), wxT("No window DC in wxGenericDragImage::Show()") );
404    
405     // Show at the current position
406    
407     if (!m_isShown)
408     {
409     // This is where we restore the backing bitmap, in case
410     // something has changed on the window.
411    
412     #ifndef wxHAS_NATIVE_OVERLAY
413     wxBitmap* backing = (m_pBackingBitmap ? m_pBackingBitmap : (wxBitmap*) & m_backingBitmap);
414     wxMemoryDC memDC;
415     memDC.SelectObject(* backing);
416    
417     UpdateBackingFromWindow(* m_windowDC, memDC, m_boundingRect, wxRect(0, 0, m_boundingRect.width, m_boundingRect.height));
418    
419     //memDC.Blit(0, 0, m_boundingRect.width, m_boundingRect.height, m_windowDC, m_boundingRect.x, m_boundingRect.y);
420     memDC.SelectObject(wxNullBitmap);
421     #endif // !wxHAS_NATIVE_OVERLAY
422    
423     RedrawImage(m_position - m_offset, m_position - m_offset, false, true);
424     }
425    
426     m_isShown = true;
427     m_isDirty = true;
428    
429     return true;
430     }
431    
432     bool wxGenericDragImage::UpdateBackingFromWindow(wxDC& windowDC, wxMemoryDC& destDC,
433     const wxRect& sourceRect, const wxRect& destRect) const
434     {
435     return destDC.Blit(destRect.x, destRect.y, destRect.width, destRect.height, & windowDC,
436     sourceRect.x, sourceRect.y);
437     }
438    
439     bool wxGenericDragImage::Hide()
440     {
441     wxASSERT_MSG( (m_windowDC != (wxDC*) NULL), wxT("No window DC in wxGenericDragImage::Hide()") );
442    
443     // Repair the old position
444    
445     if (m_isShown && m_isDirty)
446     {
447     RedrawImage(m_position - m_offset, m_position - m_offset, true, false);
448     }
449    
450     m_isShown = false;
451     m_isDirty = false;
452    
453     return true;
454     }
455    
456     // More efficient: erase and redraw simultaneously if possible
457     bool wxGenericDragImage::RedrawImage(const wxPoint& oldPos, const wxPoint& newPos,
458     bool eraseOld, bool drawNew)
459     {
460     if (!m_windowDC)
461     return false;
462    
463     #ifdef wxHAS_NATIVE_OVERLAY
464     wxDCOverlay dcoverlay( m_overlay, (wxWindowDC*) m_windowDC ) ;
465     if ( eraseOld )
466     dcoverlay.Clear() ;
467     if (drawNew)
468     DoDrawImage(*m_windowDC, newPos);
469     #else // !wxHAS_NATIVE_OVERLAY
470     wxBitmap* backing = (m_pBackingBitmap ? m_pBackingBitmap : (wxBitmap*) & m_backingBitmap);
471     if (!backing->Ok())
472     return false;
473    
474     wxRect oldRect(GetImageRect(oldPos));
475     wxRect newRect(GetImageRect(newPos));
476    
477     wxRect fullRect;
478    
479     // Full rect: the combination of both rects
480     if (eraseOld && drawNew)
481     {
482     int oldRight = oldRect.GetRight();
483     int oldBottom = oldRect.GetBottom();
484     int newRight = newRect.GetRight();
485     int newBottom = newRect.GetBottom();
486    
487     wxPoint topLeft = wxPoint(wxMin(oldPos.x, newPos.x), wxMin(oldPos.y, newPos.y));
488     wxPoint bottomRight = wxPoint(wxMax(oldRight, newRight), wxMax(oldBottom, newBottom));
489    
490     fullRect.x = topLeft.x; fullRect.y = topLeft.y;
491     fullRect.SetRight(bottomRight.x);
492     fullRect.SetBottom(bottomRight.y);
493     }
494     else if (eraseOld)
495     fullRect = oldRect;
496     else if (drawNew)
497     fullRect = newRect;
498    
499     // Make the bitmap bigger than it need be, so we don't
500     // keep reallocating all the time.
501     int excess = 50;
502    
503     if (!m_repairBitmap.Ok() || (m_repairBitmap.GetWidth() < fullRect.GetWidth() || m_repairBitmap.GetHeight() < fullRect.GetHeight()))
504     {
505     m_repairBitmap = wxBitmap(fullRect.GetWidth() + excess, fullRect.GetHeight() + excess);
506     }
507    
508     wxMemoryDC memDC;
509     memDC.SelectObject(* backing);
510    
511     wxMemoryDC memDCTemp;
512     memDCTemp.SelectObject(m_repairBitmap);
513    
514     // Draw the backing bitmap onto the repair bitmap.
515     // If full-screen, we may have specified the rect on the
516     // screen that we're using for our backing bitmap.
517     // So subtract this when we're blitting from the backing bitmap
518     // (translate from screen to backing-bitmap coords).
519    
520     memDCTemp.Blit(0, 0, fullRect.GetWidth(), fullRect.GetHeight(), & memDC, fullRect.x - m_boundingRect.x, fullRect.y - m_boundingRect.y);
521    
522     // If drawing, draw the image onto the mem DC
523     if (drawNew)
524     {
525     wxPoint pos(newPos.x - fullRect.x, newPos.y - fullRect.y) ;
526     DoDrawImage(memDCTemp, pos);
527     }
528    
529     // Now blit to the window
530     // Finally, blit the temp mem DC to the window.
531     m_windowDC->Blit(fullRect.x, fullRect.y, fullRect.width, fullRect.height, & memDCTemp, 0, 0);
532    
533     memDCTemp.SelectObject(wxNullBitmap);
534     memDC.SelectObject(wxNullBitmap);
535     #endif // wxHAS_NATIVE_OVERLAY/!wxHAS_NATIVE_OVERLAY
536    
537     return true;
538     }
539    
540     // Override this if you are using a virtual image (drawing your own image)
541     bool wxGenericDragImage::DoDrawImage(wxDC& dc, const wxPoint& pos) const
542     {
543     if (m_bitmap.Ok())
544     {
545     dc.DrawBitmap(m_bitmap, pos.x, pos.y, (m_bitmap.GetMask() != 0));
546     return true;
547     }
548     else if (m_icon.Ok())
549     {
550     dc.DrawIcon(m_icon, pos.x, pos.y);
551     return true;
552     }
553     else
554     return false;
555     }
556    
557     // Override this if you are using a virtual image (drawing your own image)
558     wxRect wxGenericDragImage::GetImageRect(const wxPoint& pos) const
559     {
560     if (m_bitmap.Ok())
561     {
562     return wxRect(pos.x, pos.y, m_bitmap.GetWidth(), m_bitmap.GetHeight());
563     }
564     else if (m_icon.Ok())
565     {
566     return wxRect(pos.x, pos.y, m_icon.GetWidth(), m_icon.GetHeight());
567     }
568     else
569     {
570     return wxRect(pos.x, pos.y, 0, 0);
571     }
572     }
573    
574     #endif // wxUSE_DRAGIMAGE

  ViewVC Help
Powered by ViewVC 1.1.22