]> git.saurik.com Git - wxWidgets.git/commitdiff
Added wxDragImage generic implementation and sample; added mask handling to Motif's
authorJulian Smart <julian@anthemion.co.uk>
Wed, 1 Mar 2000 11:05:49 +0000 (11:05 +0000)
committerJulian Smart <julian@anthemion.co.uk>
Wed, 1 Mar 2000 11:05:49 +0000 (11:05 +0000)
wxImage::ConvertToBitmap

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6372 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

55 files changed:
configure.in
distrib/msw/generic.rsp
distrib/msw/makefile.rsp
distrib/msw/tmake/filelist.txt
distrib/msw/vc.rsp
docs/latex/wx/classes.tex
docs/latex/wx/dragimag.tex [new file with mode: 0644]
include/wx/dragimag.h
include/wx/generic/dragimgg.h [new file with mode: 0644]
include/wx/motif/bitmap.h
include/wx/msw/dragimag.h
samples/configure
samples/configure.in
samples/dragimag/Makefile.in [new file with mode: 0644]
samples/dragimag/backgrnd.png [new file with mode: 0644]
samples/dragimag/dragicon.ico [new file with mode: 0644]
samples/dragimag/dragicon.xpm [new file with mode: 0644]
samples/dragimag/makefile.b32 [new file with mode: 0644]
samples/dragimag/makefile.bcc [new file with mode: 0644]
samples/dragimag/makefile.dos [new file with mode: 0644]
samples/dragimag/makefile.g95 [new file with mode: 0644]
samples/dragimag/makefile.sc [new file with mode: 0644]
samples/dragimag/makefile.sl [new file with mode: 0644]
samples/dragimag/makefile.twn [new file with mode: 0644]
samples/dragimag/makefile.unx [new file with mode: 0644]
samples/dragimag/makefile.va [new file with mode: 0644]
samples/dragimag/makefile.vc [new file with mode: 0644]
samples/dragimag/makefile.wat [new file with mode: 0644]
samples/dragimag/mondrian.ico [new file with mode: 0644]
samples/dragimag/mondrian.xpm [new file with mode: 0644]
samples/dragimag/shape01.png [new file with mode: 0644]
samples/dragimag/shape02.png [new file with mode: 0644]
samples/dragimag/shape03.png [new file with mode: 0644]
samples/dragimag/test.cpp [new file with mode: 0644]
samples/dragimag/test.def [new file with mode: 0644]
samples/dragimag/test.h [new file with mode: 0644]
samples/dragimag/test.rc [new file with mode: 0644]
src/common/image.cpp
src/generic/dragimgg.cpp [new file with mode: 0644]
src/gtk/files.lst
src/gtk1/files.lst
src/html/htmprint.cpp
src/motif/dcscreen.cpp
src/motif/files.lst
src/msw/dragimag.cpp
src/msw/makefile.b32
src/msw/makefile.bcc
src/msw/makefile.dos
src/msw/makefile.g95
src/msw/makefile.vc
src/msw/makefile.wat
src/msw/treectrl.cpp
src/wxvc.dsp
src/wxvc_dll.dsp
utils/projgen/makeproj.cpp

index a6a88b32f87a11b08ae7e5628c8fa00fd39288fc..faa58f106f3654e1c355a434c3f10ae35c45db47 100644 (file)
@@ -3397,7 +3397,7 @@ if test "$wxUSE_GUI" = "yes"; then
 
     dnl TODO some samples are never built so far:
     dnl      ipc, mfc, nativdlg, oleauto, ownerdrw, proplist
-    SAMPLES_SUBDIRS="$SAMPLES_SUBDIRS controls dialogs drawing dynamic \
+    SAMPLES_SUBDIRS="$SAMPLES_SUBDIRS controls dialogs dragimag drawing dynamic \
                      font fractal image minimal richedit"
 
     dnl this is needed to be able to find AFM files
index 9dc78798cb8802745ee92f425b7f3d15e93727b9..a980f6cd88c15e34a27917081df8c8776f860f75 100644 (file)
@@ -1035,6 +1035,16 @@ samples/rotate/*.xpm
 samples/rotate/*.txt
 samples/rotate/*.bmp
 
+samples/dragimag/*.cpp
+samples/dragimag/*.h
+samples/dragimag/makefile*
+samples/dragimag/*.rc
+samples/dragimag/*.def
+samples/dragimag/*.ico
+samples/dragimag/*.xpm
+samples/dragimag/*.png
+samples/dragimag/*.bmp
+
 samples/treelay/*.cpp
 samples/treelay/*.h
 samples/treelay/makefile*
index 35b2761e03572df562f065598821490adfd36c8e..9c309552b9f496eb04615b040915f6d95a5528fa 100644 (file)
@@ -12,6 +12,7 @@ samples/dialogs/Makefile.in
 samples/dnd/Makefile.in
 samples/docview/Makefile.in
 samples/docvwmdi/Makefile.in
+samples/dragimag/Makefile.in
 samples/drawing/Makefile.in
 samples/dynamic/Makefile.in
 samples/exec/Makefile.in
index 801e92b7a289e37376a67fb4c348fa0d7a9efe78..74623a3143de90a6d4abc26a5d140677669f3748 100644 (file)
@@ -66,6 +66,7 @@ choicdgg.cpp  G
 colrdlgg.cpp   G       G
 dcpsg.cpp      G       U
 dirdlgg.cpp    G       16,P
+dragimgg.cpp   G       P
 fontdlgg.cpp   G       G,R,P
 filedlgg.cpp   G       U,X,P
 grid.cpp       G
@@ -1078,6 +1079,7 @@ choicdgg.h        N
 colrdlgg.h     N
 dcpsg.h        N
 dirdlgg.h      N       16
+dragimgg.h     N       16
 fontdlgg.h     N
 filedlgg.h     N
 grid.h N
index b990f4aabd0ea9856a155fa7f728f5e88351149c..b97ffdd0da8b8fe192e55984b920596816541e84 100644 (file)
@@ -39,6 +39,9 @@ samples/dialup/DialupVC.dsw
 samples/dnd/DndVC.dsp
 samples/dnd/DndVC.dsw
 
+samples/dragimag/DragimagVC.dsp
+samples/dragimag/DragimagVC.dsw
+
 samples/docview/DocviewVC.dsp
 samples/docview/DocviewVC.dsw
 
index 3705f9fd10c47ac0e4a4f4b6a822b82baf2e2d18..867e0c2c1539336039fc5b709d868a4af269bf9b 100644 (file)
@@ -63,6 +63,7 @@
 \input docprfrm.tex
 \input doctempl.tex
 \input document.tex
+\input dragimag.tex
 \input dropevt.tex
 \input dropsrc.tex
 \input droptrgt.tex
diff --git a/docs/latex/wx/dragimag.tex b/docs/latex/wx/dragimag.tex
new file mode 100644 (file)
index 0000000..3f36e0c
--- /dev/null
@@ -0,0 +1,155 @@
+\section{\class{wxDragImage}}\label{wxdragimage}
+
+This class is used when you wish to drag an object on the screen,
+and a simple cursor is not enough.
+
+On Windows, the WIN32 API is used to do achieve smooth dragging. On other platforms,
+wxGenericDragImage is used. Applications may also prefer to use
+wxGenericDragImage on Windows, too.
+
+To use this class, when you wish to start dragging an image, create a wxDragImage
+object and store it somewhere you can access it as the drag progresses.
+Call BeginDrag to start, and EndDrag to stop the drag. To move the image,
+initially call Show and then Move. If you wish to update the screen contents
+during the drag (for example, highlight an item as in the dragimag sample), first call Hide,
+update the screen, call Move, and then call Show.
+
+Please see {\tt samples/dragimag} for an example.
+
+\wxheading{Derived from}
+
+\helpref{wxObject}{wxobject}
+
+\wxheading{Include files}
+
+<wx/dragimag.h>\\
+<wx/generic/dragimgg.h>
+
+\latexignore{\rtfignore{\wxheading{Members}}}
+
+\membersection{wxDragImage::wxDragImage}\label{wxdragimageconstr}
+
+\func{}{wxDragImage}{\void}
+
+Default constructor.
+
+\func{}{wxDragImage}{\param{const wxBitmap\& }{image}, \param{const wxCursor\& }{cursor = wxNullCursor},
+ \param{const wxPoint& }{hotspot = wxPoint(0, 0)}}
+
+Constructs a drag image from a bitmap and optional cursor.
+
+\func{}{wxDragImage}{\param{const wxIcon\& }{image}, \param{const wxCursor\& }{cursor = wxNullCursor},
+ \param{const wxPoint& }{hotspot = wxPoint(0, 0)}}
+
+Constructs a drag image from an icon and optional cursor.
+
+\func{}{wxDragImage}{\param{const wxString\& }{text}, \param{const wxCursor\& }{cursor = wxNullCursor},
+ \param{const wxPoint& }{hotspot = wxPoint(0, 0)}}
+
+Constructs a drag image from a text string and optional cursor.
+
+\func{}{wxDragImage}{\param{const wxTreeCtrl\& }{treeCtrl}, \param{wxTreeItemId\& }{id}}
+
+Constructs a drag image from the text in the given tree control item, and optional cursor.
+
+\func{}{wxDragImage}{\param{const wxListCtrl\& }{treeCtrl}, \param{long }{id}}
+
+Constructs a drag image from the text in the given tree control item, and optional cursor.
+
+\wxheading{Parameters}
+
+\docparam{image}{Icon or bitmap to be used as the drag image. The bitmap can
+have a mask.}
+
+\docparam{text}{Text used to construct a drag image.}
+
+\docparam{cursor}{Optional cursor to combine with the image.}
+
+\docparam{hotspot}{Position of the hotspot within the new image.}
+
+\docparam{treeCtrl}{Tree control for constructing a tree drag image.}
+
+\docparam{listCtrl}{List control for constructing a list drag image.}
+
+\docparam{id}{Tree or list control item id.}
+
+\membersection{wxDragImage::BeginDrag}\label{wxdragimagebegindrag}
+
+\func{bool}{BeginDrag}{\param{const wxPoint\& }{hotspot}, \param{wxWindow* }{window}, \param{bool}{ fullScreen = FALSE}, \param{wxRect*}{ rect = NULL}}
+
+Start dragging the image, in a window or full screen.
+
+\func{bool}{BeginDrag}{\param{const wxPoint\& }{hotspot}, \param{wxWindow* }{window}, \param{wxWindow*}{ boundingWindow}}
+
+Start dragging the image, using the first window to capture the mouse and the second
+to specify the bounding area. This form is equivalent to using the first form,
+but more convenient than working out the bounding rectangle explicitly.
+
+You need to then call \helpref{wxDragImage::Show}{wxdragimageshow} 
+and \helpref{wxDragImage::Move}{wxdragimagemove} to show the image on the screen.
+
+Call \helpref{wxDragImage::EndDrag}{wxdragimageenddrag} when the drag has finished.
+
+Note that this call automatically calls CaptureMouse.
+
+\wxheading{Parameters}
+
+\docparam{hotspot}{The location of the drag position relative to the upper-left corner
+of the image.}
+
+\docparam{window}{The window that captures the mouse, and within which the dragging
+is limited unless {\it fullScreen} is TRUE.}
+
+\docparam{boundingWindow}{In the second form of the function, specifies the
+area within which the drag occurs.}
+
+\docparam{fullScreen}{If TRUE, specifies that the drag will be visible over the full
+screen, or over as much of the screen as is specified by {\it rect}. Note that the mouse will
+still be captured in {\it window}.}
+
+\docparam{rect}{If non-NULL, specifies the rectangle (in screen coordinates) that
+bounds the dragging operation. Specifying this can make the operation more efficient
+by cutting down on the area under consideration, and it can also make a visual difference
+since the drag is clipped to this area.}
+
+{\bf Please note:} full screen dragging only works on Windows at present,
+because on Motif and GTK, the wxScreenDC used to implement full screen dragging only looks at the X root window and not
+the windows on top, when copying from the screen to the backing bitmap.
+Suggestions for solving this one are welcome!
+
+\membersection{wxDragImage::EndDrag}\label{wxdragimageenddrag}
+
+\func{bool}{EndDrag}{\void}
+
+Call this when the drag has finished.
+
+Note that this call automatically calls ReleaseMouse.
+
+\membersection{wxDragImage::Hide}\label{wxdragimagehide}
+
+\func{bool}{Hide}{\void}
+
+Hides the image. You may wish to call this before updating the window
+contents (perhaps highlighting an item). Then call \helpref{wxDragImage::Move}{wxdragimagemove} 
+and \helpref{wxDragImage::Show}{wxdragimageshow}.
+
+\membersection{wxDragImage::Move}\label{wxdragimagemove}
+
+\func{bool}{Move}{\param{const wxPoint\& }{pt}}
+
+Call this to move the image to a new position. The image will only be shown if 
+\helpref{wxDragImage::Show}{wxdragimageshow} has been called previously (for example
+at the start of the drag).
+
+{\it pt} is the position in window coordinates (or screen coordinates if no
+window was specified to BeginDrag.
+
+You can move the image either when the image is hidden or shown, but in general dragging
+will be smoother if you move the image when it is shown.
+
+\membersection{wxDragImage::Show}\label{wxdragimageshow}
+
+\func{bool}{Show}{\void}
+
+Shows the image. Call this at least once when dragging.
+
index 02da2e77dde7f4ef56a4b63d46d88b0675f0baa8..d137c02f21bf209f9fcf102897a27e68790dd7cf 100644 (file)
@@ -3,22 +3,43 @@
 
 #if defined(__WXMSW__)
 #ifdef __WIN16__
-#include "wx/generic/dragimag.h"
+#include "wx/generic/dragimgg.h"
+#define wxDragImage wxGenericDragImage
+#define sm_classwxDragImage sm_classwxGenericDragImage
+
 #else
 #include "wx/msw/dragimag.h"
 #endif
 #elif defined(__WXMOTIF__)
-#include "wx/generic/dragimag.h"
+#include "wx/generic/dragimgg.h"
+#define wxDragImage wxGenericDragImage
+#define sm_classwxDragImage sm_classwxGenericDragImage
+
 #elif defined(__WXGTK__)
-#include "wx/generic/dragimag.h"
+#include "wx/generic/dragimgg.h"
+#define wxDragImage wxGenericDragImage
+#define sm_classwxDragImage sm_classwxGenericDragImage
+
 #elif defined(__WXQT__)
-#include "wx/generic/dragimag.h"
+#include "wx/generic/dragimgg.h"
+#define wxDragImage wxGenericDragImage
+#define sm_classwxDragImage sm_classwxGenericDragImage
+
 #elif defined(__WXMAC__)
-#include "wx/generic/dragimag.h"
+#include "wx/generic/dragimgg.h"
+#define wxDragImage wxGenericDragImage
+#define sm_classwxDragImage sm_classwxGenericDragImage
+
 #elif defined(__WXPM__)
-#include "wx/generic/dragimag.h"
+#include "wx/generic/dragimgg.h"
+#define wxDragImage wxGenericDragImage
+#define sm_classwxDragImage sm_classwxGenericDragImage
+
 #elif defined(__WXSTUBS__)
-#include "wx/generic/dragimag.h"
+#include "wx/generic/dragimgg.h"
+#define wxDragImage wxGenericDragImage
+#define sm_classwxDragImage sm_classwxGenericDragImage
+
 #endif
 
 #endif
diff --git a/include/wx/generic/dragimgg.h b/include/wx/generic/dragimgg.h
new file mode 100644 (file)
index 0000000..f35a28c
--- /dev/null
@@ -0,0 +1,211 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        wx/generic/dragimgg.h
+// Purpose:     wxDragImage class: a kind of a cursor, that can cope
+//              with more sophisticated images
+// Author:      Julian Smart
+// Modified by:
+// Created:     29/2/2000
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_DRAGIMGG_H_
+#define _WX_DRAGIMGG_H_
+
+#ifdef __GNUG__
+#pragma interface "dragimgg.h"
+#endif
+
+#include "wx/bitmap.h"
+#include "wx/icon.h"
+#include "wx/cursor.h"
+#include "wx/treectrl.h"
+#include "wx/listctrl.h"
+
+/*
+  To use this class, create a wxDragImage when you start dragging, for example:
+
+  void MyTreeCtrl::OnBeginDrag(wxTreeEvent& event)
+  {
+#ifdef __WXMSW__
+    ::UpdateWindow((HWND) GetHWND()); // We need to implement this in wxWindows
+#endif
+
+    CaptureMouse();
+
+    m_dragImage = new wxDragImage(* this, itemId);
+    m_dragImage->BeginDrag(wxPoint(0, 0), this);
+    m_dragImage->Move(pt, this);
+    m_dragImage->Show(this);
+    ...
+  }
+
+  In your OnMouseMove function, hide the image, do any display updating required,
+  then move and show the image again:
+
+  void MyTreeCtrl::OnMouseMove(wxMouseEvent& event)
+  {
+    if (m_dragMode == MY_TREE_DRAG_NONE)
+    {
+        event.Skip();
+        return;
+    }
+
+    // Prevent screen corruption by hiding the image
+    if (m_dragImage)
+        m_dragImage->Hide(this);
+
+    // Do some updating of the window, such as highlighting the drop target
+    ...
+
+#ifdef __WXMSW__
+    if (updateWindow)
+        ::UpdateWindow((HWND) GetHWND());
+#endif
+
+    // Move and show the image again
+    m_dragImage->Move(event.GetPosition(), this);
+    m_dragImage->Show(this);
+ }
+
+ Eventually we end the drag and delete the drag image.
+
+ void MyTreeCtrl::OnLeftUp(wxMouseEvent& event)
+ {
+    ...
+
+    // End the drag and delete the drag image
+    if (m_dragImage)
+    {
+        m_dragImage->EndDrag(this);
+        delete m_dragImage;
+        m_dragImage = NULL;
+    }
+    ReleaseMouse();
+ }
+*/
+
+/*
+ * wxGenericDragImage
+ */
+
+class WXDLLEXPORT wxGenericDragImage: public wxObject
+{
+public:
+
+    // Ctors & dtor
+    ////////////////////////////////////////////////////////////////////////////
+
+    wxGenericDragImage();
+    wxGenericDragImage(const wxBitmap& image, const wxCursor& cursor = wxNullCursor, const wxPoint& hotspot = wxPoint(0, 0))
+    {
+        Init();
+
+        Create(image, cursor, hotspot);
+    }
+    wxGenericDragImage(const wxIcon& image, const wxCursor& cursor = wxNullCursor, const wxPoint& hotspot = wxPoint(0, 0))
+    {
+        Init();
+
+        Create(image, cursor, hotspot);
+    }
+    wxGenericDragImage(const wxString& str, const wxCursor& cursor = wxNullCursor, const wxPoint& hotspot = wxPoint(0, 0))
+    {
+        Init();
+
+        Create(str, cursor, hotspot);
+    }
+    wxGenericDragImage(const wxTreeCtrl& treeCtrl, wxTreeItemId& id)
+    {
+        Init();
+
+        Create(treeCtrl, id);
+    }
+    wxGenericDragImage(const wxListCtrl& listCtrl, long id)
+    {
+        Init();
+
+        Create(listCtrl, id);
+    }
+    ~wxGenericDragImage();
+
+    // Attributes
+    ////////////////////////////////////////////////////////////////////////////
+
+    // Operations
+    ////////////////////////////////////////////////////////////////////////////
+
+    // Create a drag image from a bitmap and optional cursor
+    bool Create(const wxBitmap& image, const wxCursor& cursor = wxNullCursor, const wxPoint& hotspot = wxPoint(0, 0));
+
+    // Create a drag image from an icon and optional cursor
+    bool Create(const wxIcon& image, const wxCursor& cursor = wxNullCursor, const wxPoint& hotspot = wxPoint(0, 0));
+
+    // Create a drag image from a string and optional cursor
+    bool Create(const wxString& str, const wxCursor& cursor = wxNullCursor, const wxPoint& hotspot = wxPoint(0, 0));
+
+    // Create a drag image for the given tree control item
+    bool Create(const wxTreeCtrl& treeCtrl, wxTreeItemId& id);
+
+    // Create a drag image for the given list control item
+    bool Create(const wxListCtrl& listCtrl, long id);
+
+    // Begin drag. hotspot is the location of the drag position relative to the upper-left
+    // corner of the image.
+    bool BeginDrag(const wxPoint& hotspot, wxWindow* window, bool fullScreen = FALSE, wxRect* rect = (wxRect*) NULL);
+
+    // Begin drag. hotspot is the location of the drag position relative to the upper-left
+    // corner of the image. This is full screen only. fullScreenRect gives the
+    // position of the window on the screen, to restrict the drag to.
+    bool BeginDrag(const wxPoint& hotspot, wxWindow* window, wxWindow* fullScreenRect);
+
+    // End drag
+    bool EndDrag();
+
+    // Move the image: call from OnMouseMove. Pt is in window client coordinates if window
+    // is non-NULL, or in screen coordinates if NULL.
+    bool Move(const wxPoint& pt);
+
+    // Show the image
+    bool Show();
+
+    // Hide the image
+    bool Hide();
+
+    // Implementation
+    ////////////////////////////////////////////////////////////////////////////
+
+    void Init();
+
+    wxRect GetImageRect(const wxPoint& pos) const;
+
+    // Erase and redraw simultaneously if possible
+    bool RedrawImage(const wxPoint& oldPos, const wxPoint& newPos, bool eraseOld, bool drawNew);
+
+protected:
+    wxBitmap        m_bitmap;
+    wxIcon          m_icon;
+    wxCursor        m_cursor;
+    wxCursor        m_oldCursor;
+    wxPoint         m_hotspot;
+    wxPoint         m_position;
+    bool            m_isDirty;
+    bool            m_isShown;
+    wxWindow*       m_window;
+    wxDC*           m_windowDC;
+
+    // Stores the window contents while we're dragging the image around
+    wxBitmap        m_backingBitmap;
+    // A temporary bitmap for repairing/redrawing
+    wxBitmap        m_repairBitmap;
+
+    wxRect          m_boundingRect;
+    bool            m_fullScreen;
+
+private:
+    DECLARE_DYNAMIC_CLASS(wxGenericDragImage)
+};
+
+#endif
+    // _WX_DRAGIMGG_H_
index 17b7142ce7ce02967eaa4921f0d913fd115fa982..c673a408fabce15b5d390680f6a32713d1b8272b 100644 (file)
@@ -201,10 +201,11 @@ public:
   // Motif implementation
 public:
   WXDisplay* GetDisplay() const { return M_BITMAPDATA->m_display; }
-  WXDisplay* GetPixmap() const { return M_BITMAPDATA->m_pixmap; }
+  WXPixmap GetPixmap() const { return (WXPixmap) M_BITMAPDATA->m_pixmap; }
   virtual WXPixmap GetLabelPixmap(WXWidget w) ;
   virtual WXPixmap GetArmPixmap(WXWidget w) ;
   virtual WXPixmap GetInsensPixmap(WXWidget w = (WXWidget) 0) ;
+  void SetPixmapNull() { M_BITMAPDATA->m_pixmap = 0; }
 
 protected:
   static wxList sm_handlers;
index ac37bff488ef9dd6e29e5ab47297883776217f66..12281325144399218733d94a1ad26cf9726d20fc 100644 (file)
@@ -108,27 +108,32 @@ public:
     wxDragImage();
     wxDragImage(const wxBitmap& image, const wxCursor& cursor = wxNullCursor, const wxPoint& hotspot = wxPoint(0, 0))
     {
-        m_hImageList = 0;
-        Create(image, cursor);
+        Init();
+
+        Create(image, cursor, hotspot);
     }
     wxDragImage(const wxIcon& image, const wxCursor& cursor = wxNullCursor, const wxPoint& hotspot = wxPoint(0, 0))
     {
-        m_hImageList = 0;
-        Create(image, cursor);
+        Init();
+
+        Create(image, cursor, hotspot);
     }
     wxDragImage(const wxString& str, const wxCursor& cursor = wxNullCursor, const wxPoint& hotspot = wxPoint(0, 0))
     {
-        m_hImageList = 0;
-        Create(str, cursor);
+        Init();
+
+        Create(str, cursor, hotspot);
     }
     wxDragImage(const wxTreeCtrl& treeCtrl, wxTreeItemId& id)
     {
-        m_hImageList = 0;
+        Init();
+
         Create(treeCtrl, id);
     }
     wxDragImage(const wxListCtrl& listCtrl, long id)
     {
-        m_hImageList = 0;
+        Init();
+
         Create(listCtrl, id);
     }
     ~wxDragImage();
@@ -156,32 +161,47 @@ public:
 
     // Begin drag. hotspot is the location of the drag position relative to the upper-left
     // corner of the image.
-    bool BeginDrag(const wxPoint& hotspot, wxWindow* window);
+    bool BeginDrag(const wxPoint& hotspot, wxWindow* window, bool fullScreen = FALSE, wxRect* rect = (wxRect*) NULL);
+
+    // Begin drag. hotspot is the location of the drag position relative to the upper-left
+    // corner of the image. This is full screen only. fullScreenRect gives the
+    // position of the window on the screen, to restrict the drag to.
+    bool BeginDrag(const wxPoint& hotspot, wxWindow* window, wxWindow* fullScreenRect);
 
     // End drag
-    bool EndDrag(wxWindow* window);
+    bool EndDrag();
 
     // Move the image: call from OnMouseMove. Pt is in window client coordinates if window
     // is non-NULL, or in screen coordinates if NULL.
-    bool Move(const wxPoint& pt, wxWindow* window);
+    bool Move(const wxPoint& pt);
 
     // Show the image
-    bool Show(wxWindow* window);
+    bool Show();
 
     // Hide the image
-    bool Hide(wxWindow* window);
+    bool Hide();
 
     // Implementation
     ////////////////////////////////////////////////////////////////////////////
 
+    // Initialize variables
+    void Init();
+
     // Returns the native image list handle
     WXHIMAGELIST GetHIMAGELIST() const { return m_hImageList; }
 
+    // Returns the native image list handle for the cursor
+    WXHIMAGELIST GetCursorHIMAGELIST() const { return m_hCursorImageList; }
+
 protected:
     WXHIMAGELIST    m_hImageList;
+    WXHIMAGELIST    m_hCursorImageList;
     wxCursor        m_cursor;
     wxPoint         m_hotspot;
     wxPoint         m_position;
+    wxWindow*       m_window;
+    wxRect          m_boundingRect;
+    bool            m_fullScreen;
 
 private:
     DECLARE_DYNAMIC_CLASS(wxDragImage)
index 59f6f4652d76f4fa763e3d75174ca6444a0e0e41..07c762adf717e6b31288459415220dc3dada6d2d 100755 (executable)
@@ -652,6 +652,7 @@ trap 'rm -fr `echo "
             docview/Makefile
             docvwmdi/Makefile
             dnd/Makefile
+            dragimag/Makefile
             drawing/Makefile
             exec/Makefile
             font/Makefile
index feb575b07125cc16519a533bfadf8e0d2dbe768b..5e3d529a705575dd3cb230a48e63090ed04ec26e 100644 (file)
@@ -20,6 +20,7 @@ AC_OUTPUT([
             docview/Makefile
             docvwmdi/Makefile
             dnd/Makefile
+            dragimag/Makefile
             drawing/Makefile
             exec/Makefile
             font/Makefile
diff --git a/samples/dragimag/Makefile.in b/samples/dragimag/Makefile.in
new file mode 100644 (file)
index 0000000..6affd07
--- /dev/null
@@ -0,0 +1,21 @@
+#
+# File:                makefile.unx
+# Author:      Julian Smart
+# Created:     1998
+# Updated:     
+# Copyright:   (c) 1998 Julian Smart
+#
+# "%W% %G%"
+#
+# Makefile for dragimag  example (UNIX).
+
+top_srcdir = @top_srcdir@/..
+top_builddir = ../..
+program_dir = samples/dragimag
+
+PROGRAM=test
+
+OBJECTS=$(PROGRAM).o
+
+include ../../src/makeprog.env
+
diff --git a/samples/dragimag/backgrnd.png b/samples/dragimag/backgrnd.png
new file mode 100644 (file)
index 0000000..59349aa
Binary files /dev/null and b/samples/dragimag/backgrnd.png differ
diff --git a/samples/dragimag/dragicon.ico b/samples/dragimag/dragicon.ico
new file mode 100644 (file)
index 0000000..2310c5d
Binary files /dev/null and b/samples/dragimag/dragicon.ico differ
diff --git a/samples/dragimag/dragicon.xpm b/samples/dragimag/dragicon.xpm
new file mode 100644 (file)
index 0000000..87a76ea
--- /dev/null
@@ -0,0 +1,44 @@
+/* XPM */
+static char *dragicon_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"32 32 6 1",
+"  c Black",
+". c Blue",
+"X c #00bf00",
+"o c Red",
+"O c Yellow",
+"+ c Gray100",
+/* pixels */
+"                                ",
+" oooooo +++++++++++++++++++++++ ",
+" oooooo +++++++++++++++++++++++ ",
+" oooooo +++++++++++++++++++++++ ",
+" oooooo +++++++++++++++++++++++ ",
+" oooooo +++++++++++++++++++++++ ",
+" oooooo +++++++++++++++++++++++ ",
+" oooooo +++++++++++++++++++++++ ",
+"                                ",
+" ++++++ ++++++++++++++++++ .... ",
+" ++++++ ++++++++++++++++++ .... ",
+" ++++++ ++++++++++++++++++ .... ",
+" ++++++ ++++++++++++++++++ .... ",
+" ++++++ ++++++++++++++++++ .... ",
+" ++++++ ++++++++++++++++++      ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++                    ++++ ",
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
+"                                "
+};
diff --git a/samples/dragimag/makefile.b32 b/samples/dragimag/makefile.b32
new file mode 100644 (file)
index 0000000..95ddc80
--- /dev/null
@@ -0,0 +1,16 @@
+#
+# File:                makefile.b32
+# Author:      Julian Smart
+# Created:     1999
+# Updated:     
+# Copyright:
+#
+# Makefile : Builds sample for 32-bit BC++
+
+WXDIR = $(WXWIN)
+
+TARGET=test
+OBJECTS = $(TARGET).obj
+
+!include $(WXDIR)\src\makeprog.b32
+
diff --git a/samples/dragimag/makefile.bcc b/samples/dragimag/makefile.bcc
new file mode 100644 (file)
index 0000000..669f019
--- /dev/null
@@ -0,0 +1,19 @@
+#
+# File:                makefile.bcc
+# Author:      Julian Smart
+# Created:     1998
+# Updated:     
+#
+# Builds a BC++ 16-bit sample
+
+!if "$(WXWIN)" == ""
+!error You must define the WXWIN variable in autoexec.bat, e.g. WXWIN=c:\wx
+!endif
+
+WXDIR = $(WXWIN)
+
+TARGET=test
+OBJECTS=$(TARGET).obj
+
+!include $(WXDIR)\src\makeprog.bcc
+
diff --git a/samples/dragimag/makefile.dos b/samples/dragimag/makefile.dos
new file mode 100644 (file)
index 0000000..983ef2d
--- /dev/null
@@ -0,0 +1,17 @@
+#
+# File:                makefile.dos
+# Author:      Julian Smart
+# Created:     1998
+# Updated:     
+#
+# Makefile : Builds 16-bit sample, VC++ 1.5
+# Use FINAL=1 argument to nmake to build final version with no debugging
+# info
+
+WXDIR = $(WXWIN)
+
+TARGET=test
+OBJECTS=$(TARGET).obj
+
+!include $(WXDIR)\src\makeprog.msc
+
diff --git a/samples/dragimag/makefile.g95 b/samples/dragimag/makefile.g95
new file mode 100644 (file)
index 0000000..b4a920f
--- /dev/null
@@ -0,0 +1,16 @@
+#
+# File:         makefile.g95
+# Author:       Julian Smart
+# Created:      1999
+# Updated:
+# Copyright:    (c) Julian Smart, 1999
+#
+# Makefile for wxWindows sample (Cygwin/Mingw32).
+
+WXDIR = ../..
+
+TARGET=test
+OBJECTS = $(TARGET).o
+
+include $(WXDIR)/src/makeprog.g95
+
diff --git a/samples/dragimag/makefile.sc b/samples/dragimag/makefile.sc
new file mode 100644 (file)
index 0000000..9f70cf6
--- /dev/null
@@ -0,0 +1,36 @@
+# Symantec C++ makefile
+
+WXDIR = $(WXWIN)
+WXLIB = $(WXDIR)\lib\wx.lib
+INCDIR = $(WXDIR)\include
+INCLUDE=$(INCDIR)
+TARGET=test
+
+include $(WXDIR)\src\makesc.env
+
+test.exe: test.obj $(DEFFILE) test.res
+       *$(CC) $(LDFLAGS) -o$@ $** $(LIBS)
+    *$(RC) -k test.res
+
+sc32.def:
+     echo EXETYPE NT > sc32.def
+     echo SUBSYSTEM WINDOWS >> sc32.def
+
+sc16.def:
+     echo NAME $(TARGET) > sc16.def
+     echo EXETYPE WINDOWS >> sc16.def
+     echo STUB         'WINSTUB.EXE' >> sc16.def
+     echo CODE         PRELOAD MOVEABLE DISCARDABLE >> sc16.def
+     echo DATA         PRELOAD MOVEABLE MULTIPLE >> sc16.def
+     echo HEAPSIZE     1024 >> sc16.def
+     echo STACKSIZE    8192 >> sc16.def
+
+clean:
+    -del *.obj
+       -del *.exe
+       -del *.res
+       -del *.map
+       -del *.rws
+    -del sc32.def
+    -del sc16.def
+
diff --git a/samples/dragimag/makefile.sl b/samples/dragimag/makefile.sl
new file mode 100644 (file)
index 0000000..c604d39
--- /dev/null
@@ -0,0 +1,18 @@
+#
+# File:                makefile.sl
+# Author:      Julian Smart
+# Created:     1998
+#
+# Makefile : Builds a wxWindows sample for Salford C++, WIN32
+
+PROGRAM = test
+OBJECTS = $(PROGRAM).obj
+
+include ..\..\src\makeprog.sl
+
+all:        wx $(TARGET)
+
+wx:
+    cd $(WXDIR)\src\msw ^ mk32 -f makefile.sl all
+    cd $(WXDIR)\samples\test
+
diff --git a/samples/dragimag/makefile.twn b/samples/dragimag/makefile.twn
new file mode 100644 (file)
index 0000000..76ab72b
--- /dev/null
@@ -0,0 +1,43 @@
+#
+# File:                makefile.unx
+# Author:      Julian Smart
+# Created:     1993
+# Updated:     
+# Copyright:   (c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile for test example (UNIX).
+
+WXDIR = ../..
+
+# All common UNIX compiler flags and options are now in
+# this central makefile.
+include $(WXDIR)/src/maketwin.env
+
+OBJECTS = $(OBJDIR)/test.$(OBJSUFF) $(OBJDIR)/test_resources.$(OBJSUFF)
+
+all:    $(OBJDIR) test$(GUISUFFIX)$(EXESUFF)
+
+wx:
+
+$(OBJDIR):
+       mkdir $(OBJDIR)
+
+test$(GUISUFFIX)$(EXESUFF):    $(OBJECTS) $(WXLIB)
+       $(CC) $(LDFLAGS) -o test$(GUISUFFIX)$(EXESUFF) $(OBJECTS) $(LDLIBS)
+
+$(OBJDIR)/test.$(OBJSUFF):     test.$(SRCSUFF)
+       $(CC) -c $(CPPFLAGS) -o $@ test.$(SRCSUFF)
+
+test_resources.c:  test.rc
+       $(RESCOMP) $(RCINPUTSWITCH) test.rc $(RCOUTPUTSWITCH) test_resources.c $(RESFLAGS)
+
+$(OBJDIR)/test_resources.$(OBJSUFF):   test_resources.c
+       $(CC) -c $(CPPFLAGS) -o $@ test_resources.c
+
+#$(OBJDIR)/test_resources.o:  test.rc
+#      $(RESCOMP) $(RCINPUTSWITCH) test.rc $(RCOUTPUTSWITCH) $(OBJDIR)/test_resources.o $(RESFLAGS)
+
+clean:
+       rm -f $(OBJECTS) test$(GUISUFFIX).exe core *.rsc *.res
diff --git a/samples/dragimag/makefile.unx b/samples/dragimag/makefile.unx
new file mode 100644 (file)
index 0000000..21cab3c
--- /dev/null
@@ -0,0 +1,35 @@
+#
+# File:                Makefile for samples
+# Author:      Robert Roebling
+# Created:     1999
+# Updated:     
+# Copyright:   (c) 1998 Robert Roebling
+#
+# This makefile requires a Unix version of wxWindows
+# to be installed on your system. This is most often
+# done typing "make install" when using the complete
+# sources of wxWindows or by installing the two
+# RPM packages wxGTK.XXX.rpm and wxGTK-devel.XXX.rpm
+# under Linux.
+#
+
+CC = gcc
+
+PROGRAM = test
+
+OBJECTS = $(PROGRAM).o
+
+# implementation
+
+.SUFFIXES:     .o .cpp
+
+.cpp.o :
+       $(CC) -c `wx-config --cflags` -o $@ $<
+
+all:    $(PROGRAM)
+
+$(PROGRAM):    $(OBJECTS)
+       $(CC) -o $(PROGRAM) $(OBJECTS) `wx-config --libs`
+
+clean: 
+       rm -f *.o $(PROGRAM)
diff --git a/samples/dragimag/makefile.va b/samples/dragimag/makefile.va
new file mode 100644 (file)
index 0000000..3cfa8cb
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# File:     makefile.va
+# Author:   David Webster
+# Created:  1999
+# Updated:
+# Copyright:    (c) David Webster
+#
+# Makefile : Builds sample (VisualAgeC++ V3.0, OS/2 PM)
+# Use FINAL=1 argument to nmake to build final version with no debug info.
+
+# Set WXDIR for your system
+WXDIR = $(WXWIN)
+
+WXUSINGDLL=0
+
+!include $(WXDIR)\src\makeva.env
+
+PROGRAM=$D\test
+OBJECTS = $(PROGRAM).obj
+
+!if [md $D]
+!endif
+
+!include $(WXDIR)\src\makeprog.va
+
diff --git a/samples/dragimag/makefile.vc b/samples/dragimag/makefile.vc
new file mode 100644 (file)
index 0000000..4ada748
--- /dev/null
@@ -0,0 +1,18 @@
+#
+# File:                makefile.vc
+# Author:      Julian Smart
+# Created:     1999
+# Updated:     
+# Copyright:   (c) Julian Smart
+#
+# Makefile : Builds sample (VC++, WIN32)
+# Use FINAL=1 argument to nmake to build final version with no debug info.
+
+# Set WXDIR for your system
+WXDIR = $(WXWIN)
+
+PROGRAM=test
+OBJECTS = $(PROGRAM).obj
+
+!include $(WXDIR)\src\makeprog.vc
+
diff --git a/samples/dragimag/makefile.wat b/samples/dragimag/makefile.wat
new file mode 100644 (file)
index 0000000..81a83e4
--- /dev/null
@@ -0,0 +1,15 @@
+#
+# Makefile for WATCOM
+#
+# Created by Julian Smart, January 1999
+# 
+#
+
+WXDIR = $(%WXWIN)
+
+PROGRAM = test
+OBJECTS = $(PROGRAM).obj
+
+!include $(WXDIR)\src\makeprog.wat
+
+
diff --git a/samples/dragimag/mondrian.ico b/samples/dragimag/mondrian.ico
new file mode 100644 (file)
index 0000000..2310c5d
Binary files /dev/null and b/samples/dragimag/mondrian.ico differ
diff --git a/samples/dragimag/mondrian.xpm b/samples/dragimag/mondrian.xpm
new file mode 100644 (file)
index 0000000..409f27a
--- /dev/null
@@ -0,0 +1,44 @@
+/* XPM */
+static char *mondrian_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"32 32 6 1",
+"  c Black",
+". c Blue",
+"X c #00bf00",
+"o c Red",
+"O c Yellow",
+"+ c Gray100",
+/* pixels */
+"                                ",
+" oooooo +++++++++++++++++++++++ ",
+" oooooo +++++++++++++++++++++++ ",
+" oooooo +++++++++++++++++++++++ ",
+" oooooo +++++++++++++++++++++++ ",
+" oooooo +++++++++++++++++++++++ ",
+" oooooo +++++++++++++++++++++++ ",
+" oooooo +++++++++++++++++++++++ ",
+"                                ",
+" ++++++ ++++++++++++++++++ .... ",
+" ++++++ ++++++++++++++++++ .... ",
+" ++++++ ++++++++++++++++++ .... ",
+" ++++++ ++++++++++++++++++ .... ",
+" ++++++ ++++++++++++++++++ .... ",
+" ++++++ ++++++++++++++++++      ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++                    ++++ ",
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
+"                                "
+};
diff --git a/samples/dragimag/shape01.png b/samples/dragimag/shape01.png
new file mode 100644 (file)
index 0000000..a54b1d2
Binary files /dev/null and b/samples/dragimag/shape01.png differ
diff --git a/samples/dragimag/shape02.png b/samples/dragimag/shape02.png
new file mode 100644 (file)
index 0000000..aafd08e
Binary files /dev/null and b/samples/dragimag/shape02.png differ
diff --git a/samples/dragimag/shape03.png b/samples/dragimag/shape03.png
new file mode 100644 (file)
index 0000000..992deb0
Binary files /dev/null and b/samples/dragimag/shape03.png differ
diff --git a/samples/dragimag/test.cpp b/samples/dragimag/test.cpp
new file mode 100644 (file)
index 0000000..08acf09
--- /dev/null
@@ -0,0 +1,512 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        test.cpp
+// Purpose:     wxDragImage sample
+// Author:      Julian Smart
+// Modified by:
+// Created:     28/2/2000
+// RCS-ID:      $Id$
+// 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 0
+
+#if wxUSE_GENERIC_DRAGIMAGE
+#include <wx/generic/dragimgg.h>
+#define wxDragImage wxGenericDragImage
+#else
+#include <wx/dragimag.h>
+#endif
+
+#include "test.h"
+
+#if defined(__WXGTK__) || defined(__WXMOTIF__)
+#include "mondrian.xpm"
+#include "dragicon.xpm"
+#endif
+
+// main program
+
+IMPLEMENT_APP(MyApp)
+
+// MyCanvas
+
+IMPLEMENT_CLASS(MyCanvas, wxScrolledWindow)
+
+BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
+  EVT_PAINT(MyCanvas::OnPaint)
+  EVT_ERASE_BACKGROUND(MyCanvas::OnEraseBackground)
+  EVT_MOUSE_EVENTS(MyCanvas::OnMouseEvent)
+END_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().Ok())
+    {
+        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;
+
+        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_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;
+
+            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;
+
+            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:
+                {
+                    wxPoint hotSpot(event.GetPosition().x - newPos.x, event.GetPosition().y - newPos.y);
+                    m_dragImage = new wxDragImage(m_draggedShape->GetBitmap(), wxCursor(wxCURSOR_HAND), hotSpot);
+                    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);
+                    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);
+                    break;
+                }
+            }
+
+            bool fullScreen = FALSE;
+            if (wxGetApp().GetUseScreen())
+            {
+                newPos = ClientToScreen(newPos);
+                fullScreen = TRUE;
+            }
+
+            bool retValue;
+
+            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);
+
+            if (!retValue)
+            {
+                delete m_dragImage;
+                m_dragImage = (wxDragImage*) NULL;
+                m_dragMode = TEST_DRAG_NONE;
+            }
+            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;
+
+            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);
+            }
+
+            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())
+            {
+                newPos = ClientToScreen(newPos);
+            }
+
+            // Move and show the image again
+            m_dragImage->Move(newPos);
+
+            if (mustUnhighlightOld || mustHighlightNew)
+                 m_dragImage->Show();
+        }
+    }
+}
+
+void MyCanvas::DrawShapes(wxDC& dc)
+{
+    wxNode* node = m_displayList.First();
+    while (node)
+    {
+        DragShape* shape = (DragShape*) node->Data();
+        if (shape->IsShown())
+          shape->Draw(dc);
+        node = node->Next();
+    }
+}
+
+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()
+{
+    wxNode* node = m_displayList.First();
+    while (node)
+    {
+        DragShape* shape = (DragShape*) node->Data();
+        delete shape;
+        node = node->Next();
+    }
+    m_displayList.Clear();
+}
+
+DragShape* MyCanvas::FindShape(const wxPoint& pt) const
+{
+    wxNode* node = m_displayList.First();
+    while (node)
+    {
+        DragShape* shape = (DragShape*) node->Data();
+        if (shape->HitTest(pt))
+            return shape;
+        node = node->Next();
+    }
+    return (DragShape*) NULL;
+}
+
+// MyFrame
+
+IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
+
+BEGIN_EVENT_TABLE(MyFrame,wxFrame)
+  EVT_MENU    (wxID_ABOUT, MyFrame::OnAbout)
+  EVT_MENU    (wxID_EXIT,  MyFrame::OnQuit)
+END_EVENT_TABLE()
+
+MyFrame::MyFrame()
+       : wxFrame( (wxFrame *)NULL, -1, "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");
+
+  wxMenuBar *menu_bar = new wxMenuBar();
+  menu_bar->Append(file_menu, "&File");
+
+  SetMenuBar( menu_bar );
+
+  CreateStatusBar(2);
+  int widths[] = { -1, 100 };
+  SetStatusWidths( 2, widths );
+
+  m_canvas = new MyCanvas( this, -1, wxPoint(0,0), wxSize(10,10) );
+}
+
+void MyFrame::OnQuit( wxCommandEvent &WXUNUSED(event) )
+{
+  Close( TRUE );
+}
+
+void MyFrame::OnAbout( wxCommandEvent &WXUNUSED(event) )
+{
+  (void)wxMessageBox( "wxDragImage demo\n"
+                      "Julian Smart (c) 2000",
+                      "About wxDragImage Demo", wxICON_INFORMATION | wxOK );
+}
+
+//-----------------------------------------------------------------------------
+// MyApp
+//-----------------------------------------------------------------------------
+
+BEGIN_EVENT_TABLE(MyApp, wxApp)
+    EVT_MENU(TEST_USE_SCREEN, MyApp::OnUseScreen)
+END_EVENT_TABLE()
+
+MyApp::MyApp()
+{
+    // Drag across whole screen
+    m_useScreen = FALSE;
+}
+
+bool MyApp::OnInit()
+{
+#if wxUSE_LIBPNG
+    wxImage::AddHandler( new wxPNGHandler );
+#endif
+
+    wxImage image;
+    if (image.LoadFile("backgrnd.png", wxBITMAP_TYPE_PNG))
+    {
+        m_background = image.ConvertToBitmap();
+    }
+
+
+    MyFrame *frame = new MyFrame();
+
+    wxString rootName("shape0");
+
+    int i;
+    for (i = 1; i < 4; i++)
+    {
+        wxString filename;
+        filename.Printf("%s%d.png", (const char*) rootName, i);
+        if (image.LoadFile(filename, wxBITMAP_TYPE_PNG))
+        {
+            DragShape* newShape = new DragShape(image.ConvertToBitmap());
+            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;
+}
+
+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& 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;
+}
+
+DragShape::~DragShape()
+{
+}
+
+bool DragShape::HitTest(const wxPoint& pt) const
+{
+    wxRect rect(GetRect());
+    return rect.Inside(pt.x, pt.y);
+}
+
+bool DragShape::Draw(wxDC& dc, int op)
+{
+    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);
+
+        return TRUE;
+    }
+    else
+        return FALSE;
+}
+
diff --git a/samples/dragimag/test.def b/samples/dragimag/test.def
new file mode 100644 (file)
index 0000000..59f0db7
--- /dev/null
@@ -0,0 +1,7 @@
+NAME         Minimal
+DESCRIPTION  'Minimal wxWindows application'
+EXETYPE      WINDOWS
+CODE         PRELOAD MOVEABLE DISCARDABLE
+DATA         PRELOAD MOVEABLE MULTIPLE
+HEAPSIZE     4048
+STACKSIZE    16000
diff --git a/samples/dragimag/test.h b/samples/dragimag/test.h
new file mode 100644 (file)
index 0000000..6d94bf4
--- /dev/null
@@ -0,0 +1,156 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        test.h
+// Purpose:     wxDragImage sample
+// Author:      Julian Smart
+// Modified by:
+// Created:     28/2/2000
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_DRAGIMAGSAMPLE_
+#define _WX_DRAGIMAGSAMPLE_
+
+// derived classes
+
+class MyFrame;
+class MyApp;
+class MyCanvas;
+class DragShape;
+
+// MyFrame
+
+class MyFrame: public wxFrame
+{
+public:
+    MyFrame();
+
+    void OnAbout( wxCommandEvent &event );
+    void OnQuit( wxCommandEvent &event );
+
+    MyCanvas* GetCanvas() const { return m_canvas; }
+    void SetCanvas(MyCanvas* canvas) { m_canvas = canvas; }
+
+private:
+    MyCanvas*       m_canvas;
+
+    DECLARE_DYNAMIC_CLASS(MyFrame)
+    DECLARE_EVENT_TABLE()
+};
+
+// MyApp
+
+class MyApp: public wxApp
+{
+public:
+    MyApp();
+    virtual bool OnInit();
+
+//// Operations
+
+    // Tile the bitmap
+    bool TileBitmap(const wxRect& rect, wxDC& dc, wxBitmap& bitmap);
+
+//// Accessors
+    wxBitmap& GetBackgroundBitmap() const { return (wxBitmap&) m_background; }
+
+    bool GetUseScreen() const { return m_useScreen; }
+    void SetUseScreen(bool useScreen) { m_useScreen = useScreen; }
+
+    void OnUseScreen(wxCommandEvent& event);
+
+protected:
+    wxBitmap    m_background;
+    bool        m_useScreen;
+
+DECLARE_EVENT_TABLE()
+};
+
+DECLARE_APP(MyApp)
+
+#define TEST_USE_SCREEN   100
+
+// MyCanvas
+
+// Dragging modes
+#define TEST_DRAG_NONE     0
+#define TEST_DRAG_START    1
+#define TEST_DRAG_DRAGGING 2
+
+class MyCanvas: public wxScrolledWindow
+{
+public:
+    MyCanvas( wxWindow *parent, wxWindowID, const wxPoint &pos, const wxSize &size );
+    ~MyCanvas();
+
+    void OnPaint( wxPaintEvent &event );
+    void OnEraseBackground(wxEraseEvent& event);
+    void OnMouseEvent(wxMouseEvent& event);
+
+    void DrawShapes(wxDC& dc);
+    void EraseShape(DragShape* shape, wxDC& dc);
+    void ClearShapes();
+    DragShape* FindShape(const wxPoint& pt) const;
+
+    wxList& GetDisplayList() { return m_displayList; }
+
+protected:
+
+private:
+    wxList          m_displayList; // A list of DragShapes
+    int             m_dragMode;
+    DragShape*      m_draggedShape;
+    DragShape*      m_currentlyHighlighted; // The shape that's being highlighted
+    wxPoint         m_dragStartPos;
+    wxDragImage*    m_dragImage;
+
+    DECLARE_CLASS(MyCanvas)
+    DECLARE_EVENT_TABLE()
+};
+
+
+// Ways to drag a shape
+
+#define SHAPE_DRAG_BITMAP       1
+#define SHAPE_DRAG_TEXT         2
+#define SHAPE_DRAG_ICON         3
+
+// Shape
+
+class DragShape: public wxObject
+{
+public:
+    DragShape(const wxBitmap& bitmap);
+    ~DragShape();
+
+//// Operations
+
+    bool HitTest(const wxPoint& pt) const;
+    bool Draw(wxDC& dc, int op = wxCOPY);
+
+//// Accessors
+
+    wxPoint GetPosition() const { return m_pos; }
+    void SetPosition(const wxPoint& pos) { m_pos = pos; }
+
+    wxRect GetRect() const { return wxRect(m_pos.x, m_pos.y, m_bitmap.GetWidth(), m_bitmap.GetHeight()); }
+
+    wxBitmap& GetBitmap() const { return (wxBitmap&) m_bitmap; }
+    void SetBitmap(const wxBitmap& bitmap) { m_bitmap = bitmap; }
+
+    int GetDragMethod() const { return m_dragMethod; }
+    void SetDragMethod(int method) { m_dragMethod = method; }
+
+    bool IsShown() const { return m_show; }
+    void SetShow(bool show) { m_show = show; }
+
+protected:
+    wxPoint     m_pos;
+    wxBitmap    m_bitmap;
+    int         m_dragMethod;
+    bool        m_show;
+};
+
+#endif
+    // _WX_DRAGIMAGSAMPLE_
diff --git a/samples/dragimag/test.rc b/samples/dragimag/test.rc
new file mode 100644 (file)
index 0000000..754a072
--- /dev/null
@@ -0,0 +1,5 @@
+mondrian ICON "mondrian.ico"
+dragicon ICON "dragicon.ico"
+
+#include "wx/msw/wx.rc"
+
index 908e1f89a3e9d3171c714cd197b92bf40b03cfe5..5f61154db289e9d03f7353f94bb75dea0a67356f 100644 (file)
@@ -1945,23 +1945,14 @@ wxBitmap wxImage::ConvertToBitmap() const
 
     bitmap.Create( width, height, bpp );
 
-    /*
     // Create mask
 
-      GdkImage *mask_image = (GdkImage*) NULL;
-
-        if (HasMask())
-        {
-        unsigned char *mask_data = (unsigned char*)malloc( ((width >> 3)+8) * height );
-
-          mask_image =  gdk_image_new_bitmap( gdk_visual_get_system(), mask_data, width, height );
-
-            wxMask *mask = new wxMask();
-            mask->m_bitmap = gdk_pixmap_new( (GdkWindow*)&gdk_root_parent, width, height, 1 );
-
-              bitmap.SetMask( mask );
-              }
-    */
+    XImage *mask_image = (XImage*) NULL;
+    if (HasMask())
+    {
+        mask_image = XCreateImage( dpy, vis, 1, ZPixmap, 0, 0, width, height, 32, 0 );
+        mask_image->data = (char*) malloc( mask_image->bytes_per_line * mask_image->height );
+    }
 
     // Retrieve depth info
 
@@ -1997,11 +1988,9 @@ wxBitmap wxImage::ConvertToBitmap() const
         else if ((vi->green_mask > vi->blue_mask) && (vi->blue_mask > vi->red_mask))  b_o = GBR;
     }
 
-    /*
     int r_mask = GetMaskRed();
     int g_mask = GetMaskGreen();
     int b_mask = GetMaskBlue();
-    */
 
     XColor colors[256];
     if (bpp == 8)
@@ -2015,6 +2004,8 @@ wxBitmap wxImage::ConvertToBitmap() const
     wxSearchColor scolor( 256, colors );
     unsigned char* data = GetData();
 
+    bool hasMask = HasMask();
+
     int index = 0;
     for (int y = 0; y < height; y++)
     {
@@ -2027,15 +2018,13 @@ wxBitmap wxImage::ConvertToBitmap() const
             int b = data[index];
             index++;
 
-            /*
-            if (HasMask())
+            if (hasMask)
             {
-            if ((r == r_mask) && (b == b_mask) && (g == g_mask))
-            gdk_image_put_pixel( mask_image, x, y, 1 );
-            else
-            gdk_image_put_pixel( mask_image, x, y, 0 );
+              if ((r == r_mask) && (b == b_mask) && (g == g_mask))
+                XPutPixel( mask_image, x, y, 0 );
+              else
+                XPutPixel( mask_image, x, y, 1 );
             }
-            */
 
             switch (bpp)
             {
@@ -2113,19 +2102,24 @@ wxBitmap wxImage::ConvertToBitmap() const
     XDestroyImage( data_image );
     XFreeGC( dpy, gc );
 
-    /*
     // Blit mask
+    if (HasMask())
+    {
+        wxBitmap maskBitmap(width, height, 1);
 
-      if (HasMask())
-      {
-      GdkGC *mask_gc = gdk_gc_new( bitmap.GetMask()->GetBitmap() );
+        GC gcMask = XCreateGC( dpy, (Pixmap) maskBitmap.GetPixmap(), (XtGCMask) 0, (XGCValues*)NULL );
+        XPutImage( dpy, (Drawable)maskBitmap.GetPixmap(), gcMask, mask_image, 0, 0, 0, 0, width, height );
 
-        gdk_draw_image( bitmap.GetMask()->GetBitmap(), mask_gc, mask_image, 0, 0, 0, 0, width, height );
+        XDestroyImage( mask_image );
+        XFreeGC( dpy, gcMask );
 
-          gdk_image_destroy( mask_image );
-          gdk_gc_unref( mask_gc );
-          }
-    */
+        wxMask* mask = new wxMask;
+        mask->SetPixmap(maskBitmap.GetPixmap());
+
+        bitmap.SetMask(mask);
+
+        maskBitmap.SetPixmapNull();
+    }
 
     return bitmap;
 }
diff --git a/src/generic/dragimgg.cpp b/src/generic/dragimgg.cpp
new file mode 100644 (file)
index 0000000..747b155
--- /dev/null
@@ -0,0 +1,462 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dragimgg.cpp
+// Purpose:     Generic wxDragImage implementation
+// Author:      Julian Smart
+// Modified by:
+// Created:     29/2/2000
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+#pragma implementation "dragimgg.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include <stdio.h>
+#include "wx/setup.h"
+#include "wx/window.h"
+#include "wx/frame.h"
+#include "wx/dcclient.h"
+#include "wx/dcscreen.h"
+#include "wx/dcmemory.h"
+#include "wx/settings.h"
+#endif
+
+#include "wx/log.h"
+#include "wx/intl.h"
+
+#ifdef __WIN16__
+#define wxUSE_IMAGE_IN_DRAGIMAGE 0
+#else
+#define wxUSE_IMAGE_IN_DRAGIMAGE 1
+#endif
+
+#if wxUSE_IMAGE_IN_DRAGIMAGE
+#include "wx/image.h"
+#endif
+
+#include "wx/generic/dragimgg.h"
+
+// ----------------------------------------------------------------------------
+// macros
+// ----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxGenericDragImage, wxObject)
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxGenericDragImage ctors/dtor
+// ----------------------------------------------------------------------------
+
+wxGenericDragImage::wxGenericDragImage()
+{
+    Init();
+}
+
+wxGenericDragImage::~wxGenericDragImage()
+{
+    if (m_windowDC)
+    {
+        delete m_windowDC;
+    }
+}
+
+void wxGenericDragImage::Init()
+{
+    m_isDirty = FALSE;
+    m_isShown = FALSE;
+    m_windowDC = (wxDC*) NULL;
+    m_window = (wxWindow*) NULL;
+    m_fullScreen = FALSE;
+}
+
+// Attributes
+////////////////////////////////////////////////////////////////////////////
+
+
+// Operations
+////////////////////////////////////////////////////////////////////////////
+
+// Create a drag image from a bitmap and optional cursor
+bool wxGenericDragImage::Create(const wxBitmap& image, const wxCursor& cursor, const wxPoint& hotspot)
+{
+    // We don't have to combine the cursor explicitly since we simply show the cursor
+    // as we drag. This currently will only work within one window.
+
+    m_cursor = cursor;
+    m_hotspot = hotspot;
+    m_bitmap = image;
+
+    return TRUE ;
+}
+
+// Create a drag image from an icon and optional cursor
+bool wxGenericDragImage::Create(const wxIcon& image, const wxCursor& cursor, const wxPoint& hotspot)
+{
+    // We don't have to combine the cursor explicitly since we simply show the cursor
+    // as we drag. This currently will only work within one window.
+
+    m_cursor = cursor;
+    m_hotspot = hotspot;
+    m_icon = image;
+
+    return TRUE ;
+}
+
+// Create a drag image from a string and optional cursor
+bool wxGenericDragImage::Create(const wxString& str, const wxCursor& cursor, const wxPoint& hotspot)
+{
+    wxFont font(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
+
+    long w, h;
+    wxScreenDC dc;
+    dc.SetFont(font);
+    dc.GetTextExtent(str, & w, & h);
+    dc.SetFont(wxNullFont);
+
+    wxMemoryDC dc2;
+    dc2.SetFont(font);
+
+    // Sometimes GetTextExtent isn't accurate enough, so make it longer
+    wxBitmap bitmap((int) ((w+2) * 1.5), (int) h+2);
+    dc2.SelectObject(bitmap);
+
+    dc2.SetBackground(* wxWHITE_BRUSH);
+    dc2.Clear();
+    dc2.SetBackgroundMode(wxTRANSPARENT);
+    dc2.SetTextForeground(* wxLIGHT_GREY);
+    dc2.DrawText(str, 0, 0);
+    dc2.DrawText(str, 1, 0);
+    dc2.DrawText(str, 2, 0);
+    dc2.DrawText(str, 1, 1);
+    dc2.DrawText(str, 2, 1);
+    dc2.DrawText(str, 1, 2);
+    dc2.DrawText(str, 2, 2);
+
+    dc2.SetTextForeground(* wxBLACK);
+    dc2.DrawText(str, 1, 1);
+
+    dc2.SelectObject(wxNullBitmap);
+
+#if wxUSE_IMAGE_IN_DRAGIMAGE
+    // Make the bitmap masked
+    wxImage image(bitmap);
+    image.SetMaskColour(255, 255, 255);
+    bitmap = image.ConvertToBitmap();
+#endif
+
+    return Create(bitmap, cursor, hotspot);
+}
+
+// Create a drag image for the given tree control item
+bool wxGenericDragImage::Create(const wxTreeCtrl& treeCtrl, wxTreeItemId& id)
+{
+    wxString str = treeCtrl.GetItemText(id);
+    return Create(str);
+}
+
+// Create a drag image for the given list control item
+bool wxGenericDragImage::Create(const wxListCtrl& listCtrl, long id)
+{
+    wxString str = listCtrl.GetItemText(id);
+    return Create(str);
+}
+
+// Begin drag
+bool wxGenericDragImage::BeginDrag(const wxPoint& hotspot, wxWindow* window, bool fullScreen, wxRect* rect)
+{
+    wxASSERT_MSG( (window != 0), wxT("Window must not be null in BeginDrag."));
+
+    m_window = window;
+    m_fullScreen = fullScreen;
+
+    if (rect)
+        m_boundingRect = * rect;
+
+    m_isDirty = FALSE;
+    m_isDirty = FALSE;
+
+    if (window)
+    {
+        window->CaptureMouse();
+
+        if (m_cursor.Ok())
+        {
+            m_oldCursor = window->GetCursor();
+            window->SetCursor(m_cursor);
+        }
+    }
+
+    // Make a copy of the window so we can repair damage done as the image is
+    // dragged.
+
+    wxSize clientSize;
+    wxPoint pt(0, 0);
+    if (!m_fullScreen)
+    {
+        clientSize = window->GetClientSize();
+        m_boundingRect.x = 0; m_boundingRect.y = 0;
+        m_boundingRect.width = clientSize.x; m_boundingRect.height = clientSize.y;
+    }
+    else
+    {
+        int w, h;
+        wxDisplaySize(& w, & h);
+        clientSize.x = w; clientSize.y = h;
+        if (rect)
+        {
+            pt.x = m_boundingRect.x; pt.y = m_boundingRect.y;
+            clientSize.x = m_boundingRect.width; clientSize.y = m_boundingRect.height;
+        }
+        else
+        {
+            m_boundingRect.x = 0; m_boundingRect.y = 0;
+            m_boundingRect.width = w; m_boundingRect.height = h;
+        }
+    }
+
+    if (!m_backingBitmap.Ok() || (m_backingBitmap.GetWidth() < clientSize.x || m_backingBitmap.GetHeight() < clientSize.y))
+        m_backingBitmap = wxBitmap(clientSize.x, clientSize.y);
+
+    if (!m_fullScreen)
+        m_windowDC = new wxClientDC(window);
+    else
+    {
+        m_windowDC = new wxScreenDC;
+
+#if 0
+        // Use m_boundingRect to limit the area considered.
+        ((wxScreenDC*) m_windowDC)->StartDrawingOnTop(rect);
+#endif
+
+        m_windowDC->SetClippingRegion(m_boundingRect.x, m_boundingRect.y,
+            m_boundingRect.width, m_boundingRect.height);
+    }
+
+    return TRUE;
+}
+
+// Begin drag. hotspot is the location of the drag position relative to the upper-left
+// corner of the image. This is full screen only. fullScreenRect gives the
+// position of the window on the screen, to restrict the drag to.
+bool wxGenericDragImage::BeginDrag(const wxPoint& hotspot, wxWindow* window, wxWindow* fullScreenRect)
+{
+    wxRect rect;
+
+    int x = fullScreenRect->GetPosition().x;
+    int y = fullScreenRect->GetPosition().y;
+    
+    wxSize sz = fullScreenRect->GetSize();
+
+    if (fullScreenRect->GetParent() && !fullScreenRect->IsKindOf(CLASSINFO(wxFrame)))
+        fullScreenRect->GetParent()->ClientToScreen(& x, & y);
+
+    rect.x = x; rect.y = y;
+    rect.width = sz.x; rect.height = sz.y;
+
+    return BeginDrag(hotspot, window, TRUE, & rect);
+}
+
+// End drag
+bool wxGenericDragImage::EndDrag()
+{
+    if (m_window)
+    {
+        m_window->ReleaseMouse();
+        if (m_cursor.Ok() && m_oldCursor.Ok())
+        {
+            m_window->SetCursor(m_oldCursor);
+        }
+    }
+
+    if (m_windowDC)
+    {
+        m_windowDC->DestroyClippingRegion();
+        delete m_windowDC;
+        m_windowDC = (wxDC*) NULL;
+    }
+
+    m_repairBitmap = wxNullBitmap;
+
+    return TRUE;
+}
+
+// Move the image: call from OnMouseMove. Pt is in window client coordinates if window
+// is non-NULL, or in screen coordinates if NULL.
+bool wxGenericDragImage::Move(const wxPoint& pt)
+{
+    wxASSERT_MSG( (m_windowDC != (wxDC*) NULL), "No window DC in wxGenericDragImage::Move()" );
+
+    // Erase at old position, then show at the current position
+    wxPoint oldPos = m_position;
+
+    bool eraseOldImage = (m_isDirty && m_isShown);
+    
+    if (m_isShown)
+        RedrawImage(oldPos, pt, eraseOldImage, TRUE);
+
+    m_position = pt;
+
+    if (m_isShown)
+        m_isDirty = TRUE;
+
+    return TRUE;
+}
+
+bool wxGenericDragImage::Show()
+{
+    wxASSERT_MSG( (m_windowDC != (wxDC*) NULL), "No window DC in wxGenericDragImage::Show()" );
+    
+    // Show at the current position
+
+    if (!m_isShown)
+    {
+        // This is where we restore the backing bitmap, in case
+        // something has changed on the window.
+
+        wxMemoryDC memDC;
+        memDC.SelectObject(m_backingBitmap);
+        memDC.Blit(0, 0, m_boundingRect.width, m_boundingRect.height, m_windowDC, m_boundingRect.x, m_boundingRect.y);
+        memDC.SelectObject(wxNullBitmap);
+
+        RedrawImage(m_position, m_position, FALSE, TRUE);
+    }
+
+    m_isShown = TRUE;
+    m_isDirty = TRUE;
+
+    return TRUE;
+}
+
+bool wxGenericDragImage::Hide()
+{
+    wxASSERT_MSG( (m_windowDC != (wxDC*) NULL), "No window DC in wxGenericDragImage::Hide()" );
+
+    // Repair the old position
+
+    if (m_isShown && m_isDirty)
+    {
+        RedrawImage(m_position, m_position, TRUE, FALSE);
+    }
+
+    m_isShown = FALSE;
+    m_isDirty = FALSE;
+
+    return TRUE;
+}
+
+// More efficient: erase and redraw simultaneously if possible
+bool wxGenericDragImage::RedrawImage(const wxPoint& oldPos, const wxPoint& newPos,
+                                     bool eraseOld, bool drawNew)
+{
+    if (!m_windowDC)
+        return FALSE;
+
+    if (!m_backingBitmap.Ok())
+        return FALSE;
+
+    wxRect oldRect(GetImageRect(oldPos));
+    wxRect newRect(GetImageRect(newPos));
+
+    wxRect fullRect;
+
+    // Full rect: the combination of both rects
+    if (eraseOld && drawNew)
+    {
+        int oldRight = oldRect.GetRight();
+        int oldBottom = oldRect.GetBottom();
+        int newRight = newRect.GetRight();
+        int newBottom = newRect.GetBottom();
+
+        wxPoint topLeft = wxPoint(wxMin(oldPos.x, newPos.x), wxMin(oldPos.y, newPos.y));
+        wxPoint bottomRight = wxPoint(wxMax(oldRight, newRight), wxMax(oldBottom, newBottom));
+
+        fullRect.x = topLeft.x; fullRect.y = topLeft.y;
+        fullRect.SetRight(bottomRight.x);
+        fullRect.SetBottom(bottomRight.y);
+    }
+    else if (eraseOld)
+        fullRect = oldRect;
+    else if (drawNew)
+        fullRect = newRect;
+
+    // Make the bitmap bigger than it need be, so we don't
+    // keep reallocating all the time.
+    int excess = 50;
+
+    if (!m_repairBitmap.Ok() || (m_repairBitmap.GetWidth() < fullRect.GetWidth() || m_repairBitmap.GetHeight() < fullRect.GetHeight()))
+    {
+        m_repairBitmap = wxBitmap(fullRect.GetWidth() + excess, fullRect.GetHeight() + excess);
+    }
+
+    wxMemoryDC memDC;
+    memDC.SelectObject(m_backingBitmap);
+
+    wxMemoryDC memDCTemp;
+    memDCTemp.SelectObject(m_repairBitmap);
+
+    // Draw the backing bitmap onto the repair bitmap.
+    // If full-screen, we may have specified the rect on the
+    // screen that we're using for our backing bitmap.
+    // So subtract this when we're blitting from the backing bitmap
+    // (translate from screen to backing-bitmap coords).
+
+    memDCTemp.Blit(0, 0, fullRect.GetWidth(), fullRect.GetHeight(), & memDC, fullRect.x - m_boundingRect.x, fullRect.y - m_boundingRect.y);
+
+    // If drawing, draw the image onto the mem DC
+    if (drawNew)
+    {
+        int x = newPos.x - fullRect.x;
+        int y = newPos.y - fullRect.y;
+        if (m_bitmap.Ok())
+            memDCTemp.DrawBitmap(m_bitmap, x, y, (m_bitmap.GetMask() != 0));
+        else if (m_icon.Ok())
+            memDCTemp.DrawIcon(m_icon, x, y);
+    }
+
+    // Now blit to the window
+    // Finally, blit the temp mem DC to the window.
+    m_windowDC->Blit(fullRect.x, fullRect.y, fullRect.width, fullRect.height, & memDCTemp, 0, 0);
+
+    memDCTemp.SelectObject(wxNullBitmap);
+    memDC.SelectObject(wxNullBitmap);
+
+    return TRUE;
+}
+
+wxRect wxGenericDragImage::GetImageRect(const wxPoint& pos) const
+{
+    if (m_bitmap.Ok())
+    {
+        return wxRect(pos.x, pos.y, m_bitmap.GetWidth(), m_bitmap.GetHeight());
+    }
+    else if (m_icon.Ok())
+    {
+        return wxRect(pos.x, pos.y, m_icon.GetWidth(), m_icon.GetHeight());
+    }
+    else
+    {
+        return wxRect(pos.x, pos.y, 0, 0);
+    }
+}
+
index 7748558b13a3c56360bc970840ea3372dcb72eb6..9ccf0479185ab59ab34788ea7089d5aece8bf44f 100644 (file)
@@ -8,6 +8,7 @@ ALL_SOURCES = \
                generic/colrdlgg.cpp \
                generic/dcpsg.cpp \
                generic/dirdlgg.cpp \
+               generic/dragimgg.cpp \
                generic/filedlgg.cpp \
                generic/grid.cpp \
                generic/helpext.cpp \
@@ -748,6 +749,7 @@ GENERICOBJS = \
                caret.o \
                choicdgg.o \
                colrdlgg.o \
+               dragimgg.o \
                dcpsg.o \
                dirdlgg.o \
                filedlgg.o \
@@ -788,6 +790,7 @@ GENERICDEPS = \
                colrdlgg.d \
                dcpsg.d \
                dirdlgg.d \
+               dragimgg.d \
                filedlgg.d \
                grid.d \
                helpext.d \
index 7748558b13a3c56360bc970840ea3372dcb72eb6..9ccf0479185ab59ab34788ea7089d5aece8bf44f 100644 (file)
@@ -8,6 +8,7 @@ ALL_SOURCES = \
                generic/colrdlgg.cpp \
                generic/dcpsg.cpp \
                generic/dirdlgg.cpp \
+               generic/dragimgg.cpp \
                generic/filedlgg.cpp \
                generic/grid.cpp \
                generic/helpext.cpp \
@@ -748,6 +749,7 @@ GENERICOBJS = \
                caret.o \
                choicdgg.o \
                colrdlgg.o \
+               dragimgg.o \
                dcpsg.o \
                dirdlgg.o \
                filedlgg.o \
@@ -788,6 +790,7 @@ GENERICDEPS = \
                colrdlgg.d \
                dcpsg.d \
                dirdlgg.d \
+               dragimgg.d \
                filedlgg.d \
                grid.d \
                helpext.d \
index ef8c0b5a23b8edec31fb053e7777e5166e8fd373..e552d63d800ac19639151ae61da5965e8ec59fb1 100644 (file)
@@ -191,8 +191,8 @@ bool wxHtmlPrintout::OnBeginDocument(int startPage, int endPage)
     /* prepare headers/footers renderer: */
     
     m_RendererHdr -> SetDC(GetDC(), (double)ppiPrinterY / (double)ppiScreenY);
-    m_RendererHdr -> SetSize(ppmm_h * (mm_w - m_MarginLeft - m_MarginTop), 
-                          ppmm_v * (mm_h - m_MarginTop - m_MarginBottom));
+    m_RendererHdr -> SetSize((int) (ppmm_h * (mm_w - m_MarginLeft - m_MarginTop)), 
+                          (int) (ppmm_v * (mm_h - m_MarginTop - m_MarginBottom)));
     if (m_Headers[0] != wxEmptyString) {
         m_RendererHdr -> SetHtmlText(TranslateHeader(m_Headers[0], 1));
         m_HeaderHeight = m_RendererHdr -> GetTotalHeight();
@@ -212,12 +212,12 @@ bool wxHtmlPrintout::OnBeginDocument(int startPage, int endPage)
     
     /* prepare main renderer: */
     m_Renderer -> SetDC(GetDC(), (double)ppiPrinterY / (double)ppiScreenY);
-    m_Renderer -> SetSize(ppmm_h * (mm_w - m_MarginLeft - m_MarginTop), 
-                          ppmm_v * (mm_h - m_MarginTop - m_MarginBottom) - 
+    m_Renderer -> SetSize((int) (ppmm_h * (mm_w - m_MarginLeft - m_MarginTop)), 
+                          (int) (ppmm_v * (mm_h - m_MarginTop - m_MarginBottom) - 
                           m_FooterHeight - m_HeaderHeight -
                           ((m_HeaderHeight == 0) ? 0 : m_MarginSpace * ppmm_v) -
                           ((m_FooterHeight == 0) ? 0 : m_MarginSpace * ppmm_v)
-                          );
+                          ));
     m_Renderer -> SetHtmlText(m_Document, m_BasePath, m_BasePathIsDir);
     CountPages();
     return TRUE;
@@ -317,8 +317,8 @@ void wxHtmlPrintout::CountPages()
     
     m_PageBreaks[0] = 0;
     do {
-        pos = m_Renderer -> Render(ppmm_h * m_MarginLeft
-                                   ppmm_v * (m_MarginTop + (m_HeaderHeight == 0 ? 0 : m_MarginSpace)) + m_HeaderHeight,
+        pos = m_Renderer -> Render((int)( ppmm_h * m_MarginLeft)
+                                   (int) (ppmm_v * (m_MarginTop + (m_HeaderHeight == 0 ? 0 : m_MarginSpace)) + m_HeaderHeight),
                                    pos, TRUE);
         m_PageBreaks[++m_NumPages] = pos;
     } while (pos < m_Renderer -> GetTotalHeight());
@@ -351,18 +351,18 @@ void wxHtmlPrintout::RenderPage(wxDC *dc, int page)
     
     dc -> SetBackgroundMode(wxTRANSPARENT);
 
-    m_Renderer -> Render(ppmm_h * m_MarginLeft
-                         ppmm_v * (m_MarginTop + (m_HeaderHeight == 0 ? 0 : m_MarginSpace)) + m_HeaderHeight,
+    m_Renderer -> Render((int) (ppmm_h * m_MarginLeft)
+                         (int) (ppmm_v * (m_MarginTop + (m_HeaderHeight == 0 ? 0 : m_MarginSpace)) + m_HeaderHeight),
                          m_PageBreaks[page-1]);
     
     m_RendererHdr -> SetDC(dc, (double)ppiPrinterY / (double)ppiScreenY);
     if (m_Headers[page % 2] != wxEmptyString) {
         m_RendererHdr -> SetHtmlText(TranslateHeader(m_Headers[page % 2], page));
-        m_RendererHdr -> Render(ppmm_h * m_MarginLeft, ppmm_v * m_MarginTop);
+        m_RendererHdr -> Render((int) (ppmm_h * m_MarginLeft), (int) (ppmm_v * m_MarginTop));
     }
     if (m_Footers[page % 2] != wxEmptyString) {
         m_RendererHdr -> SetHtmlText(TranslateHeader(m_Footers[page % 2], page));
-        m_RendererHdr -> Render(ppmm_h * m_MarginLeft, pageHeight - ppmm_v * m_MarginBottom - m_FooterHeight);
+        m_RendererHdr -> Render((int) (ppmm_h * m_MarginLeft), (int) (pageHeight - ppmm_v * m_MarginBottom - m_FooterHeight));
     }
 }
 
index 1b0597df23a1a5608bcd467fe710ada2ba3cc1a0..1da45d5e3935713455f9ae29d709db7bdba5f624 100644 (file)
@@ -14,6 +14,7 @@
 #endif
 
 #include "wx/window.h"
+#include "wx/frame.h"
 #include "wx/dcscreen.h"
 #include "wx/utils.h"
 
@@ -64,6 +65,7 @@ wxScreenDC::wxScreenDC()
 
 wxScreenDC::~wxScreenDC()
 {
+    EndDrawingOnTop();
 }
 
 bool wxScreenDC::StartDrawingOnTop(wxWindow* window)
@@ -71,7 +73,7 @@ bool wxScreenDC::StartDrawingOnTop(wxWindow* window)
     wxRect rect;
     int x, y, width, height;
     window->GetPosition(& x, & y);
-    if (window->GetParent())
+    if (window->GetParent() && !window->IsKindOf(CLASSINFO(wxFrame)))
         window->GetParent()->ClientToScreen(& x, & y);
     window->GetSize(& width, & height);
     rect.x = x; rect.y = y;
index cb9ff4bff6db16cc481c58376167fba5e5a73849..c26d29d5641f2058aad5788e53f297ca5af589ab 100644 (file)
@@ -8,6 +8,7 @@ ALL_SOURCES = \
                generic/colrdlgg.cpp \
                generic/dcpsg.cpp \
                generic/dirdlgg.cpp \
+               generic/dragimgg.cpp \
                generic/fontdlgg.cpp \
                generic/grid.cpp \
                generic/helpext.cpp \
@@ -745,6 +746,7 @@ GENERICOBJS = \
                caret.o \
                choicdgg.o \
                colrdlgg.o \
+               dragimgg.o \
                dcpsg.o \
                dirdlgg.o \
                fontdlgg.o \
@@ -785,6 +787,7 @@ GENERICDEPS = \
                calctrl.d \
                caret.d \
                choicdgg.d \
+               dragimgg.d \
                colrdlgg.d \
                dcpsg.d \
                dirdlgg.d \
index 1ce8b4e5482c3647d64476dc799de4b27233a3af..b5aca15c5109de8a343fdfb51bb50ad8ef2a2137 100644 (file)
@@ -43,6 +43,8 @@
 
 #include "wx/log.h"
 #include "wx/intl.h"
+#include "wx/frame.h"
+#include "wx/image.h"
 
 #include "wx/msw/dragimag.h"
 #include "wx/msw/private.h"
@@ -69,15 +71,24 @@ IMPLEMENT_DYNAMIC_CLASS(wxDragImage, wxObject)
 
 wxDragImage::wxDragImage()
 {
-    m_hImageList = 0;
+    Init();
 }
 
 wxDragImage::~wxDragImage()
 {
     if ( m_hImageList )
         ImageList_Destroy(GetHimageList());
+    if ( m_hCursorImageList )
+        ImageList_Destroy((HIMAGELIST) m_hCursorImageList);
 }
 
+void wxDragImage::Init()
+{
+    m_hImageList = 0;
+    m_hCursorImageList = 0;
+    m_window = (wxWindow*) NULL;
+    m_fullScreen = FALSE;
+}
 
 // Attributes
 ////////////////////////////////////////////////////////////////////////////
@@ -93,24 +104,43 @@ bool wxDragImage::Create(const wxBitmap& image, const wxCursor& cursor, const wx
         ImageList_Destroy(GetHimageList());
     m_hImageList = 0;
 
-    UINT flags = 0;
-    bool mask = TRUE; // ?
+    UINT flags = 0 ;
+    if (image.GetDepth() <= 4)
+        flags = ILC_COLOR4;
+    else if (image.GetDepth() <= 8)
+        flags = ILC_COLOR8;
+    else if (image.GetDepth() <= 16)
+        flags = ILC_COLOR16;
+    else if (image.GetDepth() <= 24)
+        flags = ILC_COLOR24;
+    else
+        flags = ILC_COLOR32;
+
+    bool mask = (image.GetMask() != 0);
     if ( mask )
         flags |= ILC_MASK;
 
     m_hImageList = (WXHIMAGELIST) ImageList_Create(image.GetWidth(), image.GetHeight(), flags, 1, 1);
 
-    HBITMAP hBitmap1 = (HBITMAP) image.GetHBITMAP();
-    HBITMAP hBitmap2 = 0;
-    if ( image.GetMask() )
-        hBitmap2 = (HBITMAP) image.GetMask()->GetMaskBitmap();
+    int index;
+    if (!mask)
+    {
+        HBITMAP hBitmap1 = (HBITMAP) image.GetHBITMAP();
+        index = ImageList_Add(GetHimageList(), hBitmap1, 0);
+    }
+    else
+    {
+        HBITMAP hBitmap1 = (HBITMAP) image.GetHBITMAP();
+        HBITMAP hBitmap2 = (HBITMAP) image.GetMask()->GetMaskBitmap();
+        HBITMAP hbmpMask = wxInvertMask(hBitmap2);
 
-    int index = ImageList_Add(GetHimageList(), hBitmap1, hBitmap2);
+        index = ImageList_Add(GetHimageList(), hBitmap1, hbmpMask);
+        ::DeleteObject(hbmpMask);
+    }
     if ( index == -1 )
     {
         wxLogError(_("Couldn't add an image to the image list."));
     }
-
     m_cursor = cursor; // Can only combine with drag image after calling BeginDrag.
     m_hotspot = hotspot;
 
@@ -124,8 +154,18 @@ bool wxDragImage::Create(const wxIcon& image, const wxCursor& cursor, const wxPo
         ImageList_Destroy(GetHimageList());
     m_hImageList = 0;
 
-    UINT flags = 0;
-    bool mask = TRUE; // ?
+    UINT flags = 0 ;
+    if (image.GetDepth() <= 4)
+        flags = ILC_COLOR4;
+    else if (image.GetDepth() <= 8)
+        flags = ILC_COLOR8;
+    else if (image.GetDepth() <= 16)
+        flags = ILC_COLOR16;
+    else if (image.GetDepth() <= 24)
+        flags = ILC_COLOR24;
+    else
+        flags = ILC_COLOR32;
+    bool mask = TRUE;
     if ( mask )
         flags |= ILC_MASK;
 
@@ -154,18 +194,34 @@ bool wxDragImage::Create(const wxString& str, const wxCursor& cursor, const wxPo
     wxScreenDC dc;
     dc.SetFont(font);
     dc.GetTextExtent(str, & w, & h);
+    dc.SetFont(wxNullFont);
 
     wxMemoryDC dc2;
     dc2.SetFont(font);
-    wxBitmap bitmap((int) w, (int) h);
+    wxBitmap bitmap((int) w+2, (int) h+2);
     dc2.SelectObject(bitmap);
 
     dc2.SetBackground(* wxWHITE_BRUSH);
     dc2.Clear();
+    dc2.SetBackgroundMode(wxTRANSPARENT);
+    dc2.SetTextForeground(* wxLIGHT_GREY);
     dc2.DrawText(str, 0, 0);
+    dc2.DrawText(str, 1, 0);
+    dc2.DrawText(str, 2, 0);
+    dc2.DrawText(str, 1, 1);
+    dc2.DrawText(str, 2, 1);
+    dc2.DrawText(str, 1, 2);
+    dc2.DrawText(str, 2, 2);
+    dc2.SetTextForeground(* wxBLACK);
+    dc2.DrawText(str, 1, 1);
 
     dc2.SelectObject(wxNullBitmap);
 
+    // Make the bitmap masked
+    wxImage image(bitmap);
+    image.SetMaskColour(255, 255, 255);
+    bitmap = image.ConvertToBitmap();
+
     return Create(bitmap, cursor, hotspot);
 }
 
@@ -190,9 +246,14 @@ bool wxDragImage::Create(const wxListCtrl& listCtrl, long id)
 }
 
 // Begin drag
-bool wxDragImage::BeginDrag(const wxPoint& hotspot, wxWindow* window)
+bool wxDragImage::BeginDrag(const wxPoint& hotspot, wxWindow* window, bool fullScreen, wxRect* rect)
 {
     wxASSERT_MSG( (m_hImageList != 0), wxT("Image list must not be null in BeginDrag."));
+    wxASSERT_MSG( (window != 0), wxT("Window must not be null in BeginDrag."));
+
+    m_fullScreen = fullScreen;
+    if (rect)
+        m_boundingRect = * rect;
 
     bool ret = (ImageList_BeginDrag(GetHimageList(), 0, hotspot.x, hotspot.y) != 0);
 
@@ -205,25 +266,57 @@ bool wxDragImage::BeginDrag(const wxPoint& hotspot, wxWindow* window)
 
     if (m_cursor.Ok())
     {
+        if (!m_hCursorImageList)
+        {           
+            int cxCursor = GetSystemMetrics(SM_CXCURSOR); 
+            int cyCursor = GetSystemMetrics(SM_CYCURSOR); 
+            m_hCursorImageList = (WXHIMAGELIST) ImageList_Create(cxCursor, cyCursor, ILC_MASK, 1, 1);
+        }
+
         // First add the cursor to the image list
-        int cursorIndex = ImageList_AddIcon(GetHimageList(), (HICON) m_cursor.GetHCURSOR());
+        HCURSOR hCursor = (HCURSOR) m_cursor.GetHCURSOR();
+        int cursorIndex = ImageList_AddIcon((HIMAGELIST) m_hCursorImageList, (HICON) hCursor);
 
         wxASSERT_MSG( (cursorIndex != -1), wxT("ImageList_AddIcon failed in BeginDrag."));
 
         if (cursorIndex != -1)
         {
-            ImageList_SetDragCursorImage(GetHimageList(), cursorIndex, m_hotspot.x, m_hotspot.y);
+            ImageList_SetDragCursorImage((HIMAGELIST) m_hCursorImageList, cursorIndex, m_hotspot.x, m_hotspot.y);
         }
     }
 
+    m_window = window;
     ::ShowCursor(FALSE);
+
     ::SetCapture(GetHwndOf(window));
 
     return TRUE;
 }
 
+// Begin drag. hotspot is the location of the drag position relative to the upper-left
+// corner of the image. This is full screen only. fullScreenRect gives the
+// position of the window on the screen, to restrict the drag to.
+bool wxDragImage::BeginDrag(const wxPoint& hotspot, wxWindow* window, wxWindow* fullScreenRect)
+{
+    wxRect rect;
+
+    int x = fullScreenRect->GetPosition().x;
+    int y = fullScreenRect->GetPosition().y;
+    
+    wxSize sz = fullScreenRect->GetSize();
+
+    if (fullScreenRect->GetParent() && !fullScreenRect->IsKindOf(CLASSINFO(wxFrame)))
+        fullScreenRect->GetParent()->ClientToScreen(& x, & y);
+
+    rect.x = x; rect.y = y;
+    rect.width = sz.x; rect.height = sz.y;
+
+    return BeginDrag(hotspot, window, TRUE, & rect);
+}
+
 // End drag
-bool wxDragImage::EndDrag(wxWindow* WXUNUSED(window))
+bool wxDragImage::EndDrag()
 {
     wxASSERT_MSG( (m_hImageList != 0), wxT("Image list must not be null in EndDrag."));
 
@@ -235,13 +328,14 @@ bool wxDragImage::EndDrag(wxWindow* WXUNUSED(window))
     }
 
     ::ShowCursor(TRUE);
+    m_window = (wxWindow*) NULL;
 
     return TRUE;
 }
 
 // Move the image: call from OnMouseMove. Pt is in window client coordinates if window
 // is non-NULL, or in screen coordinates if NULL.
-bool wxDragImage::Move(const wxPoint& pt, wxWindow* window)
+bool wxDragImage::Move(const wxPoint& pt)
 {
     wxASSERT_MSG( (m_hImageList != 0), wxT("Image list must not be null in Move."));
 
@@ -253,26 +347,26 @@ bool wxDragImage::Move(const wxPoint& pt, wxWindow* window)
     return ret;
 }
 
-bool wxDragImage::Show(wxWindow* window)
+bool wxDragImage::Show()
 {
     wxASSERT_MSG( (m_hImageList != 0), wxT("Image list must not be null in Show."));
 
     HWND hWnd = 0;
-    if (window)
-        hWnd = (HWND) window->GetHWND();
+    if (m_window && !m_fullScreen)
+        hWnd = (HWND) m_window->GetHWND();
 
     bool ret = (ImageList_DragEnter( hWnd, m_position.x, m_position.y ) != 0);
 
     return ret;
 }
 
-bool wxDragImage::Hide(wxWindow* window)
+bool wxDragImage::Hide()
 {
     wxASSERT_MSG( (m_hImageList != 0), wxT("Image list must not be null in Hide."));
 
     HWND hWnd = 0;
-    if (window)
-        hWnd = (HWND) window->GetHWND();
+    if (m_window && !m_fullScreen)
+        hWnd = (HWND) m_window->GetHWND();
 
     bool ret = (ImageList_DragLeave( hWnd ) != 0);
 
index 9429f461a065260c57d9ee79310d6d0f0f8e8da9..a6db54f78744b509e38f3fcd6ca0da3ae5c2a489 100644 (file)
@@ -1,6 +1,6 @@
 
 
-# This file was automatically generated by tmake at 12:24, 2000/02/28
+# This file was automatically generated by tmake at 16:52, 2000/02/29
 # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE B32.T!
 
 #
@@ -81,6 +81,7 @@ DOCDIR = $(WXDIR)\docs
 GENERICOBJS= $(MSWDIR)\busyinfo.obj \
                $(MSWDIR)\calctrl.obj \
                $(MSWDIR)\choicdgg.obj \
+               $(MSWDIR)\dragimgg.obj \
                $(MSWDIR)\grid.obj \
                $(MSWDIR)\laywin.obj \
                $(MSWDIR)\logg.obj \
@@ -794,6 +795,8 @@ $(MSWDIR)\calctrl.obj: $(GENDIR)\calctrl.$(SRCSUFF)
 
 $(MSWDIR)\choicdgg.obj: $(GENDIR)\choicdgg.$(SRCSUFF)
 
+$(MSWDIR)\dragimgg.obj: $(GENDIR)\dragimgg.$(SRCSUFF)
+
 $(MSWDIR)\grid.obj: $(GENDIR)\grid.$(SRCSUFF)
 
 $(MSWDIR)\laywin.obj: $(GENDIR)\laywin.$(SRCSUFF)
index d647a8395be737fb1d188b423552bcc6c7f2a9a6..5075d23e13f1536666234c416093bb2e5912946f 100644 (file)
@@ -1,6 +1,6 @@
 
 
-# This file was automatically generated by tmake at 12:24, 2000/02/28
+# This file was automatically generated by tmake at 16:52, 2000/02/29
 # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE BCC.T!
 
 #
@@ -77,6 +77,7 @@ GENERICOBJS= $(MSWDIR)\busyinfo.obj \
                $(MSWDIR)\calctrl.obj \
                $(MSWDIR)\choicdgg.obj \
                $(MSWDIR)\dirdlgg.obj \
+               $(MSWDIR)\dragimgg.obj \
                $(MSWDIR)\grid.obj \
                $(MSWDIR)\imaglist.obj \
                $(MSWDIR)\laywin.obj \
@@ -649,6 +650,8 @@ $(MSWDIR)\choicdgg.obj: $(GENDIR)\choicdgg.$(SRCSUFF)
 
 $(MSWDIR)\dirdlgg.obj: $(GENDIR)\dirdlgg.$(SRCSUFF)
 
+$(MSWDIR)\dragimgg.obj: $(GENDIR)\dragimgg.$(SRCSUFF)
+
 $(MSWDIR)\grid.obj: $(GENDIR)\grid.$(SRCSUFF)
 
 $(MSWDIR)\imaglist.obj: $(GENDIR)\imaglist.$(SRCSUFF)
index 970f6796260244575133f06938a48043419b20d6..07a1334b3c2e3b5b5dce421006f106c912825dc0 100644 (file)
@@ -1,4 +1,4 @@
-# This file was automatically generated by tmake at 18:32, 2000/02/17
+# This file was automatically generated by tmake at 15:56, 2000/02/29
 # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE DOS.T!
 
 #
@@ -61,6 +61,7 @@ GENERICOBJS= $(GENDIR)\busyinfo.obj \
                $(GENDIR)\calctrl.obj \
                $(GENDIR)\choicdgg.obj \
                $(GENDIR)\dirdlgg.obj \
+               $(GENDIR)\dragimgg.obj \
                $(GENDIR)\grid.obj \
                $(GENDIR)\imaglist.obj \
                $(GENDIR)\laywin.obj \
@@ -216,6 +217,7 @@ MSWOBJS1 = $(MSWDIR)\accel.obj \
                $(MSWDIR)\gaugemsw.obj \
                $(MSWDIR)\gdiimage.obj \
                $(MSWDIR)\gdiobj.obj \
+               $(MSWDIR)\glcanvas.obj \
                $(MSWDIR)\gsocket.obj \
                $(MSWDIR)\helpwin.obj \
                $(MSWDIR)\icon.obj \
@@ -529,6 +531,11 @@ $(MSWDIR)/gdiobj.obj:     $*.$(SRCSUFF)
 $(CPPFLAGS) /Fo$@ /c /Tp $*.$(SRCSUFF)
 <<
 
+$(MSWDIR)/glcanvas.obj:     $*.$(SRCSUFF)
+        cl @<<
+$(CPPFLAGS) /Fo$@ /c /Tp $*.$(SRCSUFF)
+<<
+
 $(MSWDIR)/gsocket.obj:     $*.c
         cl @<<
 $(CPPFLAGS2) /Fo$@ /c /Tc $*.c
@@ -1169,6 +1176,11 @@ $(GENDIR)/dirdlgg.obj:     $*.$(SRCSUFF)
 $(CPPFLAGS) /Fo$@ /c /Tp $*.$(SRCSUFF)
 <<
 
+$(GENDIR)/dragimgg.obj:     $*.$(SRCSUFF)
+        cl @<<
+$(CPPFLAGS) /Fo$@ /c /Tp $*.$(SRCSUFF)
+<<
+
 $(GENDIR)/grid.obj:     $*.$(SRCSUFF)
         cl @<<
 $(CPPFLAGS) /Fo$@ /c /Tp $*.$(SRCSUFF)
@@ -1284,6 +1296,11 @@ $(GENDIR)/treectrl.obj:     $*.$(SRCSUFF)
 $(CPPFLAGS) /Fo$@ /c /Tp $*.$(SRCSUFF)
 <<
 
+$(GENDIR)/treelay.obj:     $*.$(SRCSUFF)
+        cl @<<
+$(CPPFLAGS) /Fo$@ /c /Tp $*.$(SRCSUFF)
+<<
+
 $(GENDIR)/wizard.obj:     $*.$(SRCSUFF)
         cl @<<
 $(CPPFLAGS) /Fo$@ /c /Tp $*.$(SRCSUFF)
index 1004d5662fea1400cb81cd3150b87bd0b6d4bee9..df4e156f6b8fccc672fc5c3b360b698fecd959e4 100644 (file)
@@ -72,6 +72,7 @@ GENERICOBJS = \
                 $(GENDIR)/busyinfo.$(OBJSUFF) \
                $(GENDIR)/calctrl.$(OBJSUFF) \
                $(GENDIR)/choicdgg.$(OBJSUFF) \
+               $(GENDIR)/dragimgg.$(OBJSUFF) \
                $(GENDIR)/grid.$(OBJSUFF) \
                $(GENDIR)/laywin.$(OBJSUFF) \
                $(GENDIR)/logg.$(OBJSUFF) \
index b5f724b0d048a694ac2791caf09aa292a2cfda36..36afd2f14ccab749ac3eee20c794150fe8cfc70b 100644 (file)
@@ -1,4 +1,4 @@
-# This file was automatically generated by tmake at 12:24, 2000/02/28
+# This file was automatically generated by tmake at 16:52, 2000/02/29
 # DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE VC.T!
 
 # File:     makefile.vc
@@ -86,6 +86,7 @@ $(CPPFLAGS) /Fo$@ /c /Tp $<
 GENERICOBJS= ..\generic\$D\busyinfo.obj \
                ..\generic\$D\calctrl.obj \
                ..\generic\$D\choicdgg.obj \
+               ..\generic\$D\dragimgg.obj \
                ..\generic\$D\grid.obj \
                ..\generic\$D\laywin.obj \
                ..\generic\$D\logg.obj \
index fbda5947ab4ad0685be5a1032355fd30e7c00020..4fad98fd22092cb5ecf297af99676c6992e5b706 100644 (file)
@@ -42,6 +42,7 @@ DOCDIR = $(WXDIR)\docs
 GENERICOBJS= busyinfo.obj &
        calctrl.obj &
        choicdgg.obj &
+       dragimgg.obj &
        grid.obj &
        laywin.obj &
        logg.obj &
index c6c1cd6d355d36883bba61270fbb905081fba866..c0eb3fd506e0f814e5ba2a618b66afd7747c13e8 100644 (file)
@@ -1725,6 +1725,15 @@ long wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
             case WM_LBUTTONDOWN:
                 if ( htItem && isMultiple )
                 {
+<<<<<<< treectrl.cpp
+                    int x = GET_X_LPARAM(lParam),
+                        y = GET_Y_LPARAM(lParam);
+
+                    m_dragImage->Move(wxPoint(x, y));
+
+                    HTREEITEM htiTarget = GetItemFromPoint(GetHwnd(), x, y);
+                    if ( htiTarget )
+=======
                     if ( wParam & MK_CONTROL )
                     {
                         SetFocus();
@@ -1783,9 +1792,9 @@ long wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
                     {
                         // highlight the item as target (hiding drag image is
                         // necessary - otherwise the display will be corrupted)
-                        m_dragImage->Hide(this);
+                        m_dragImage->Hide();
                         TreeView_SelectDropTarget(GetHwnd(), htItem);
-                        m_dragImage->Show(this);
+                        m_dragImage->Show();
                     }
                 }
                 break;
@@ -1794,7 +1803,7 @@ long wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
             case WM_RBUTTONUP:
                 if ( m_dragImage )
                 {
-                    m_dragImage->EndDrag(this);
+                    m_dragImage->EndDrag();
                     delete m_dragImage;
                     m_dragImage = NULL;
 
@@ -2202,7 +2211,7 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 
                 m_dragImage = new wxDragImage(*this, event.m_item);
                 m_dragImage->BeginDrag(wxPoint(0, 0), this);
-                m_dragImage->Show(this);
+                m_dragImage->Show();
             }
             break;
 
index 6270077de38ce42b4e14dd5826c2f025a16d4a28..2e41ab533731a2e61870e15579ce2220332a80ad 100644 (file)
@@ -512,6 +512,10 @@ SOURCE=.\generic\choicdgg.cpp
 # End Source File
 # Begin Source File
 
+SOURCE=.\generic\dragimgg.cpp
+# End Source File
+# Begin Source File
+
 SOURCE=.\generic\grid.cpp
 # End Source File
 # Begin Source File
index 4a2ff43239f31756ca76e6744aff4772a56f0c27..0121b5f25cfc4793643cd0a9094d5641931b5115 100644 (file)
@@ -514,6 +514,10 @@ SOURCE=.\generic\choicdgg.cpp
 # End Source File
 # Begin Source File
 
+SOURCE=.\generic\dragimgg.cpp
+# End Source File
+# Begin Source File
+
 SOURCE=.\generic\grid.cpp
 # End Source File
 # Begin Source File
index 63c8ce205c1491e4525179b6e035cb82863f9547..5b0bd7374076f8e87954b994e68758432c774171 100644 (file)
@@ -304,6 +304,7 @@ void MyApp::GenerateSamples(const wxString& dir)
     GenerateSample("FontVC", "font", dir + wxString("/samples/font"), wxStringList("font.cpp", 0));
     GenerateSample("MenuVC", "menu", dir + wxString("/samples/menu"), wxStringList("menu.cpp", 0));
     GenerateSample("TreelayVC", "test", dir + wxString("/samples/treelay"), wxStringList("test.cpp", "test.h", 0));
+    GenerateSample("DragimagVC", "test", dir + wxString("/samples/dragimag"), wxStringList("test.cpp", "test.h", 0));
 
     //// Demos