1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Drag and drop sample
4 // Author: Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
22 #if !wxUSE_DRAG_AND_DROP
23 #error This sample requires drag and drop support in the library
26 // under Windows we also support data transfer of metafiles as an extra bonus,
27 // but they're not available under other platforms
32 #define USE_RESOURCES 0
35 #define USE_RESOURCES 0
42 #include "wx/dirdlg.h"
43 #include "wx/filedlg.h"
45 #include "wx/clipbrd.h"
46 #include "wx/colordlg.h"
48 #include "wx/resource.h"
54 #include "wx/metafile.h"
57 #if defined(__WXGTK__) || defined(__WXMOTIF__)
58 #include "mondrian.xpm"
60 #include "dnd_copy.xpm"
61 #include "dnd_move.xpm"
62 #include "dnd_none.xpm"
65 // ----------------------------------------------------------------------------
66 // Derive two simple classes which just put in the listbox the strings (text or
67 // file names) we drop on them
68 // ----------------------------------------------------------------------------
70 class DnDText
: public wxTextDropTarget
73 DnDText(wxListBox
*pOwner
) { m_pOwner
= pOwner
; }
75 virtual bool OnDropText(wxCoord x
, wxCoord y
, const wxString
& text
);
81 class DnDFile
: public wxFileDropTarget
84 DnDFile(wxListBox
*pOwner
) { m_pOwner
= pOwner
; }
86 virtual bool OnDropFiles(wxCoord x
, wxCoord y
,
87 const wxArrayString
& filenames
);
93 // ----------------------------------------------------------------------------
94 // Define a custom dtop target accepting URLs
95 // ----------------------------------------------------------------------------
97 class URLDropTarget
: public wxDropTarget
100 URLDropTarget() { SetDataObject(new wxURLDataObject
); }
102 void OnDropURL(wxCoord x
, wxCoord y
, const wxString
& text
)
104 // of course, a real program would do something more useful here...
105 wxMessageBox(text
, _T("wxDnD sample: got URL"),
106 wxICON_INFORMATION
| wxOK
);
109 // URLs can't be moved, only copied
110 virtual wxDragResult
OnDragOver(wxCoord
WXUNUSED(x
), wxCoord
WXUNUSED(y
),
113 return wxDragLink
; // At least IE 5.x needs wxDragLink, the
114 // other browsers on MSW seem okay with it too.
117 // translate this to calls to OnDropURL() just for convenience
118 virtual wxDragResult
OnData(wxCoord x
, wxCoord y
, wxDragResult def
)
123 OnDropURL(x
, y
, ((wxURLDataObject
*)m_dataObject
)->GetURL());
129 // ----------------------------------------------------------------------------
130 // Define a new application type
131 // ----------------------------------------------------------------------------
133 class DnDApp
: public wxApp
136 virtual bool OnInit();
139 IMPLEMENT_APP(DnDApp
);
141 // ----------------------------------------------------------------------------
142 // Define canvas class to show a bitmap
143 // ----------------------------------------------------------------------------
145 class DnDCanvasBitmap
: public wxScrolledWindow
148 DnDCanvasBitmap(wxWindow
*parent
) : wxScrolledWindow(parent
) { }
150 void SetBitmap(const wxBitmap
& bitmap
)
154 SetScrollbars(10, 10,
155 m_bitmap
.GetWidth() / 10, m_bitmap
.GetHeight() / 10);
160 void OnPaint(wxPaintEvent
& event
)
168 dc
.DrawBitmap(m_bitmap
, 0, 0);
175 DECLARE_EVENT_TABLE()
180 // and the same thing fo metafiles
181 class DnDCanvasMetafile
: public wxScrolledWindow
184 DnDCanvasMetafile(wxWindow
*parent
) : wxScrolledWindow(parent
) { }
186 void SetMetafile(const wxMetafile
& metafile
)
188 m_metafile
= metafile
;
190 SetScrollbars(10, 10,
191 m_metafile
.GetWidth() / 10, m_metafile
.GetHeight() / 10);
196 void OnPaint(wxPaintEvent
& event
)
200 if ( m_metafile
.Ok() )
204 m_metafile
.Play(&dc
);
209 wxMetafile m_metafile
;
211 DECLARE_EVENT_TABLE()
214 #endif // USE_METAFILES
216 // ----------------------------------------------------------------------------
217 // Define a new frame type for the main frame
218 // ----------------------------------------------------------------------------
220 class DnDFrame
: public wxFrame
223 DnDFrame(wxFrame
*frame
, char *title
, int x
, int y
, int w
, int h
);
226 void OnPaint(wxPaintEvent
& event
);
227 void OnQuit (wxCommandEvent
& event
);
228 void OnAbout(wxCommandEvent
& event
);
229 void OnDrag (wxCommandEvent
& event
);
230 void OnNewFrame(wxCommandEvent
& event
);
231 void OnHelp (wxCommandEvent
& event
);
232 void OnLogClear(wxCommandEvent
& event
);
234 void OnCopy(wxCommandEvent
& event
);
235 void OnPaste(wxCommandEvent
& event
);
237 void OnCopyBitmap(wxCommandEvent
& event
);
238 void OnPasteBitmap(wxCommandEvent
& event
);
241 void OnPasteMetafile(wxCommandEvent
& event
);
242 #endif // USE_METAFILES
244 void OnCopyFiles(wxCommandEvent
& event
);
246 void OnLeftDown(wxMouseEvent
& event
);
247 void OnRightDown(wxMouseEvent
& event
);
249 void OnUpdateUIPasteText(wxUpdateUIEvent
& event
);
250 void OnUpdateUIPasteBitmap(wxUpdateUIEvent
& event
);
252 DECLARE_EVENT_TABLE()
255 wxListBox
*m_ctrlFile
,
257 wxTextCtrl
*m_ctrlLog
;
265 // ----------------------------------------------------------------------------
266 // A shape is an example of application-specific data which may be transported
267 // via drag-and-drop or clipboard: in our case, we have different geometric
268 // shapes, each one with its own colour and position
269 // ----------------------------------------------------------------------------
282 DnDShape(const wxPoint
& pos
,
285 : m_pos(pos
), m_size(size
), m_col(col
)
289 // this is for debugging - lets us see when exactly an object is freed
290 // (this may be later than you think if it's on the clipboard, for example)
291 virtual ~DnDShape() { }
293 // the functions used for drag-and-drop: they dump and restore a shape into
294 // some bitwise-copiable data (might use streams too...)
295 // ------------------------------------------------------------------------
297 // restore from buffer
298 static DnDShape
*New(const void *buf
);
300 virtual size_t GetDataSize() const
302 return sizeof(ShapeDump
);
305 virtual void GetDataHere(void *buf
) const
307 ShapeDump
& dump
= *(ShapeDump
*)buf
;
312 dump
.r
= m_col
.Red();
313 dump
.g
= m_col
.Green();
314 dump
.b
= m_col
.Blue();
319 const wxPoint
& GetPosition() const { return m_pos
; }
320 const wxColour
& GetColour() const { return m_col
; }
321 const wxSize
& GetSize() const { return m_size
; }
323 void Move(const wxPoint
& pos
) { m_pos
= pos
; }
325 // to implement in derived classes
326 virtual Kind
GetKind() const = 0;
328 virtual void Draw(wxDC
& dc
)
330 dc
.SetPen(wxPen(m_col
, 1, wxSOLID
));
334 wxPoint
GetCentre() const
335 { return wxPoint(m_pos
.x
+ m_size
.x
/ 2, m_pos
.y
+ m_size
.y
/ 2); }
339 int x
, y
, // position
350 class DnDTriangularShape
: public DnDShape
353 DnDTriangularShape(const wxPoint
& pos
,
356 : DnDShape(pos
, size
, col
)
358 wxLogMessage(wxT("DnDTriangularShape is being created"));
361 virtual ~DnDTriangularShape()
363 wxLogMessage(wxT("DnDTriangularShape is being deleted"));
366 virtual Kind
GetKind() const { return Triangle
; }
367 virtual void Draw(wxDC
& dc
)
371 // well, it's a bit difficult to describe a triangle by position and
372 // size, but we're not doing geometry here, do we? ;-)
374 wxPoint
p2(m_pos
.x
+ m_size
.x
, m_pos
.y
);
375 wxPoint
p3(m_pos
.x
, m_pos
.y
+ m_size
.y
);
382 dc
.FloodFill(GetCentre(), m_col
, wxFLOOD_BORDER
);
387 class DnDRectangularShape
: public DnDShape
390 DnDRectangularShape(const wxPoint
& pos
,
393 : DnDShape(pos
, size
, col
)
395 wxLogMessage(wxT("DnDRectangularShape is being created"));
398 virtual ~DnDRectangularShape()
400 wxLogMessage(wxT("DnDRectangularShape is being deleted"));
403 virtual Kind
GetKind() const { return Rectangle
; }
404 virtual void Draw(wxDC
& dc
)
409 wxPoint
p2(p1
.x
+ m_size
.x
, p1
.y
);
410 wxPoint
p3(p2
.x
, p2
.y
+ m_size
.y
);
411 wxPoint
p4(p1
.x
, p3
.y
);
419 dc
.FloodFill(GetCentre(), m_col
, wxFLOOD_BORDER
);
424 class DnDEllipticShape
: public DnDShape
427 DnDEllipticShape(const wxPoint
& pos
,
430 : DnDShape(pos
, size
, col
)
432 wxLogMessage(wxT("DnDEllipticShape is being created"));
435 virtual ~DnDEllipticShape()
437 wxLogMessage(wxT("DnDEllipticShape is being deleted"));
440 virtual Kind
GetKind() const { return Ellipse
; }
441 virtual void Draw(wxDC
& dc
)
445 dc
.DrawEllipse(m_pos
, m_size
);
448 dc
.FloodFill(GetCentre(), m_col
, wxFLOOD_BORDER
);
453 // ----------------------------------------------------------------------------
454 // A wxDataObject specialisation for the application-specific data
455 // ----------------------------------------------------------------------------
457 static const wxChar
*shapeFormatId
= wxT("wxShape");
459 class DnDShapeDataObject
: public wxDataObject
462 // ctor doesn't copy the pointer, so it shouldn't go away while this object
464 DnDShapeDataObject(DnDShape
*shape
= (DnDShape
*)NULL
)
468 // we need to copy the shape because the one we're handled may be
469 // deleted while it's still on the clipboard (for example) - and we
470 // reuse the serialisation methods here to copy it
471 void *buf
= malloc(shape
->DnDShape::GetDataSize());
472 shape
->GetDataHere(buf
);
473 m_shape
= DnDShape::New(buf
);
483 // this string should uniquely identify our format, but is otherwise
485 m_formatShape
.SetId(shapeFormatId
);
487 // we don't draw the shape to a bitmap until it's really needed (i.e.
488 // we're asked to do so)
491 m_hasMetaFile
= FALSE
;
495 virtual ~DnDShapeDataObject() { delete m_shape
; }
497 // after a call to this function, the shape is owned by the caller and it
498 // is responsible for deleting it!
500 // NB: a better solution would be to make DnDShapes ref counted and this
501 // is what should probably be done in a real life program, otherwise
502 // the ownership problems become too complicated really fast
505 DnDShape
*shape
= m_shape
;
507 m_shape
= (DnDShape
*)NULL
;
510 m_hasMetaFile
= FALSE
;
516 // implement base class pure virtuals
517 // ----------------------------------
519 virtual wxDataFormat
GetPreferredFormat(Direction
WXUNUSED(dir
)) const
521 return m_formatShape
;
524 virtual size_t GetFormatCount(Direction dir
) const
526 // our custom format is supported by both GetData() and SetData()
530 // but the bitmap format(s) are only supported for output
531 nFormats
+= m_dobjBitmap
.GetFormatCount(dir
);
534 nFormats
+= m_dobjMetaFile
.GetFormatCount(dir
);
541 virtual void GetAllFormats(wxDataFormat
*formats
, Direction dir
) const
543 formats
[0] = m_formatShape
;
546 // in Get direction we additionally support bitmaps and metafiles
548 m_dobjBitmap
.GetAllFormats(&formats
[1], dir
);
551 // don't assume that m_dobjBitmap has only 1 format
552 m_dobjMetaFile
.GetAllFormats(&formats
[1 +
553 m_dobjBitmap
.GetFormatCount(dir
)], dir
);
558 virtual size_t GetDataSize(const wxDataFormat
& format
) const
560 if ( format
== m_formatShape
)
562 return m_shape
->GetDataSize();
565 else if ( m_dobjMetaFile
.IsSupported(format
) )
567 if ( !m_hasMetaFile
)
570 return m_dobjMetaFile
.GetDataSize(format
);
575 wxASSERT_MSG( m_dobjBitmap
.IsSupported(format
),
576 wxT("unexpected format") );
581 return m_dobjBitmap
.GetDataSize();
585 virtual bool GetDataHere(const wxDataFormat
& format
, void *pBuf
) const
587 if ( format
== m_formatShape
)
589 m_shape
->GetDataHere(pBuf
);
594 else if ( m_dobjMetaFile
.IsSupported(format
) )
596 if ( !m_hasMetaFile
)
599 return m_dobjMetaFile
.GetDataHere(format
, pBuf
);
604 wxASSERT_MSG( m_dobjBitmap
.IsSupported(format
),
605 wxT("unexpected format") );
610 return m_dobjBitmap
.GetDataHere(pBuf
);
614 virtual bool SetData(const wxDataFormat
& format
,
615 size_t len
, const void *buf
)
617 wxCHECK_MSG( format
== m_formatShape
, FALSE
,
618 wxT( "unsupported format") );
621 m_shape
= DnDShape::New(buf
);
623 // the shape has changed
627 m_hasMetaFile
= FALSE
;
634 // creates a bitmap and assigns it to m_dobjBitmap (also sets m_hasBitmap)
635 void CreateBitmap() const;
637 void CreateMetaFile() const;
640 wxDataFormat m_formatShape
; // our custom format
642 wxBitmapDataObject m_dobjBitmap
; // it handles bitmaps
643 bool m_hasBitmap
; // true if m_dobjBitmap has valid bitmap
646 wxMetaFileDataObject m_dobjMetaFile
;// handles metafiles
647 bool m_hasMetaFile
; // true if we have valid metafile
650 DnDShape
*m_shape
; // our data
653 // ----------------------------------------------------------------------------
654 // A dialog to edit shape properties
655 // ----------------------------------------------------------------------------
657 class DnDShapeDialog
: public wxDialog
660 DnDShapeDialog(wxFrame
*parent
, DnDShape
*shape
);
662 DnDShape
*GetShape() const;
664 virtual bool TransferDataToWindow();
665 virtual bool TransferDataFromWindow();
667 void OnColour(wxCommandEvent
& event
);
674 DnDShape::Kind m_shapeKind
;
686 DECLARE_EVENT_TABLE()
689 // ----------------------------------------------------------------------------
690 // A frame for the shapes which can be drag-and-dropped between frames
691 // ----------------------------------------------------------------------------
693 class DnDShapeFrame
: public wxFrame
696 DnDShapeFrame(wxFrame
*parent
);
699 void SetShape(DnDShape
*shape
);
702 void OnNewShape(wxCommandEvent
& event
);
703 void OnEditShape(wxCommandEvent
& event
);
704 void OnClearShape(wxCommandEvent
& event
);
706 void OnCopyShape(wxCommandEvent
& event
);
707 void OnPasteShape(wxCommandEvent
& event
);
709 void OnUpdateUICopy(wxUpdateUIEvent
& event
);
710 void OnUpdateUIPaste(wxUpdateUIEvent
& event
);
712 void OnDrag(wxMouseEvent
& event
);
713 void OnPaint(wxPaintEvent
& event
);
714 void OnDrop(wxCoord x
, wxCoord y
, DnDShape
*shape
);
719 static DnDShapeFrame
*ms_lastDropTarget
;
721 DECLARE_EVENT_TABLE()
724 // ----------------------------------------------------------------------------
725 // wxDropTarget derivation for DnDShapes
726 // ----------------------------------------------------------------------------
728 class DnDShapeDropTarget
: public wxDropTarget
731 DnDShapeDropTarget(DnDShapeFrame
*frame
)
732 : wxDropTarget(new DnDShapeDataObject
)
737 // override base class (pure) virtuals
738 virtual wxDragResult
OnEnter(wxCoord x
, wxCoord y
, wxDragResult def
)
739 { m_frame
->SetStatusText("Mouse entered the frame"); return OnDragOver(x
, y
, def
); }
740 virtual void OnLeave()
741 { m_frame
->SetStatusText("Mouse left the frame"); }
742 virtual wxDragResult
OnData(wxCoord x
, wxCoord y
, wxDragResult def
)
746 wxLogError(wxT("Failed to get drag and drop data"));
751 m_frame
->OnDrop(x
, y
,
752 ((DnDShapeDataObject
*)GetDataObject())->GetShape());
758 DnDShapeFrame
*m_frame
;
761 // ----------------------------------------------------------------------------
762 // functions prototypes
763 // ----------------------------------------------------------------------------
765 static void ShowBitmap(const wxBitmap
& bitmap
);
768 static void ShowMetaFile(const wxMetaFile
& metafile
);
769 #endif // USE_METAFILES
771 // ----------------------------------------------------------------------------
772 // IDs for the menu commands
773 // ----------------------------------------------------------------------------
789 Menu_Shape_New
= 500,
792 Menu_ShapeClipboard_Copy
,
793 Menu_ShapeClipboard_Paste
,
797 BEGIN_EVENT_TABLE(DnDFrame
, wxFrame
)
798 EVT_MENU(Menu_Quit
, DnDFrame::OnQuit
)
799 EVT_MENU(Menu_About
, DnDFrame::OnAbout
)
800 EVT_MENU(Menu_Drag
, DnDFrame::OnDrag
)
801 EVT_MENU(Menu_NewFrame
, DnDFrame::OnNewFrame
)
802 EVT_MENU(Menu_Help
, DnDFrame::OnHelp
)
803 EVT_MENU(Menu_Clear
, DnDFrame::OnLogClear
)
804 EVT_MENU(Menu_Copy
, DnDFrame::OnCopy
)
805 EVT_MENU(Menu_Paste
, DnDFrame::OnPaste
)
806 EVT_MENU(Menu_CopyBitmap
, DnDFrame::OnCopyBitmap
)
807 EVT_MENU(Menu_PasteBitmap
,DnDFrame::OnPasteBitmap
)
809 EVT_MENU(Menu_PasteMFile
, DnDFrame::OnPasteMetafile
)
810 #endif // USE_METAFILES
811 EVT_MENU(Menu_CopyFiles
, DnDFrame::OnCopyFiles
)
813 EVT_UPDATE_UI(Menu_Paste
, DnDFrame::OnUpdateUIPasteText
)
814 EVT_UPDATE_UI(Menu_PasteBitmap
, DnDFrame::OnUpdateUIPasteBitmap
)
816 EVT_LEFT_DOWN( DnDFrame::OnLeftDown
)
817 EVT_RIGHT_DOWN( DnDFrame::OnRightDown
)
818 EVT_PAINT( DnDFrame::OnPaint
)
821 BEGIN_EVENT_TABLE(DnDShapeFrame
, wxFrame
)
822 EVT_MENU(Menu_Shape_New
, DnDShapeFrame::OnNewShape
)
823 EVT_MENU(Menu_Shape_Edit
, DnDShapeFrame::OnEditShape
)
824 EVT_MENU(Menu_Shape_Clear
, DnDShapeFrame::OnClearShape
)
826 EVT_MENU(Menu_ShapeClipboard_Copy
, DnDShapeFrame::OnCopyShape
)
827 EVT_MENU(Menu_ShapeClipboard_Paste
, DnDShapeFrame::OnPasteShape
)
829 EVT_UPDATE_UI(Menu_ShapeClipboard_Copy
, DnDShapeFrame::OnUpdateUICopy
)
830 EVT_UPDATE_UI(Menu_ShapeClipboard_Paste
, DnDShapeFrame::OnUpdateUIPaste
)
832 EVT_LEFT_DOWN(DnDShapeFrame::OnDrag
)
834 EVT_PAINT(DnDShapeFrame::OnPaint
)
837 BEGIN_EVENT_TABLE(DnDShapeDialog
, wxDialog
)
838 EVT_BUTTON(Button_Colour
, DnDShapeDialog::OnColour
)
841 BEGIN_EVENT_TABLE(DnDCanvasBitmap
, wxScrolledWindow
)
842 EVT_PAINT(DnDCanvasBitmap::OnPaint
)
846 BEGIN_EVENT_TABLE(DnDCanvasMetafile
, wxScrolledWindow
)
847 EVT_PAINT(DnDCanvasMetafile::OnPaint
)
849 #endif // USE_METAFILES
851 // ============================================================================
853 // ============================================================================
855 // `Main program' equivalent, creating windows and returning main app frame
856 bool DnDApp::OnInit()
859 // load our ressources
863 pathList
.Add("./Debug");
864 pathList
.Add("./Release");
867 wxString path
= pathList
.FindValidPath("dnd.wxr");
870 wxLogError(wxT("Can't find the resource file dnd.wxr in the current ")
871 wxT("directory, aborting."));
876 wxDefaultResourceTable
->ParseResourceFile(path
);
879 // switch on trace messages
880 #if defined(__WXGTK__)
881 wxLog::AddTraceMask(_T("clipboard"));
882 #elif defined(__WXMSW__)
883 wxLog::AddTraceMask(wxTRACE_OleCalls
);
887 wxImage::AddHandler( new wxPNGHandler
);
890 // under X we usually want to use the primary selection by default (which
891 // is shared with other apps)
892 wxTheClipboard
->UsePrimarySelection();
894 // create the main frame window
895 DnDFrame
*frame
= new DnDFrame((wxFrame
*) NULL
,
896 "Drag-and-Drop/Clipboard wxWindows Sample",
907 DnDFrame::DnDFrame(wxFrame
*frame
, char *title
, int x
, int y
, int w
, int h
)
908 : wxFrame(frame
, -1, title
, wxPoint(x
, y
), wxSize(w
, h
)),
909 m_strText("wxWindows drag & drop works :-)")
912 // frame icon and status bar
913 SetIcon(wxICON(mondrian
));
918 wxMenu
*file_menu
= new wxMenu
;
919 file_menu
->Append(Menu_Drag
, "&Test drag...");
920 file_menu
->AppendSeparator();
921 file_menu
->Append(Menu_NewFrame
, "&New frame\tCtrl-N");
922 file_menu
->AppendSeparator();
923 file_menu
->Append(Menu_Quit
, "E&xit");
925 wxMenu
*log_menu
= new wxMenu
;
926 log_menu
->Append(Menu_Clear
, "Clear\tCtrl-L");
928 wxMenu
*help_menu
= new wxMenu
;
929 help_menu
->Append(Menu_Help
, "&Help...");
930 help_menu
->AppendSeparator();
931 help_menu
->Append(Menu_About
, "&About");
933 wxMenu
*clip_menu
= new wxMenu
;
934 clip_menu
->Append(Menu_Copy
, "&Copy text\tCtrl-C");
935 clip_menu
->Append(Menu_Paste
, "&Paste text\tCtrl-V");
936 clip_menu
->AppendSeparator();
937 clip_menu
->Append(Menu_CopyBitmap
, "Copy &bitmap\tCtrl-Shift-C");
938 clip_menu
->Append(Menu_PasteBitmap
, "Paste b&itmap\tCtrl-Shift-V");
940 clip_menu
->AppendSeparator();
941 clip_menu
->Append(Menu_PasteMFile
, "Paste &metafile\tCtrl-M");
942 #endif // USE_METAFILES
943 clip_menu
->AppendSeparator();
944 clip_menu
->Append(Menu_CopyFiles
, "Copy &files\tCtrl-F");
946 wxMenuBar
*menu_bar
= new wxMenuBar
;
947 menu_bar
->Append(file_menu
, "&File");
948 menu_bar
->Append(log_menu
, "&Log");
949 menu_bar
->Append(clip_menu
, "&Clipboard");
950 menu_bar
->Append(help_menu
, "&Help");
952 SetMenuBar(menu_bar
);
954 // make a panel with 3 subwindows
956 wxSize
size(400, 200);
958 wxString
strFile("Drop files here!"), strText("Drop text on me");
960 m_ctrlFile
= new wxListBox(this, -1, pos
, size
, 1, &strFile
,
961 wxLB_HSCROLL
| wxLB_ALWAYS_SB
);
962 m_ctrlText
= new wxListBox(this, -1, pos
, size
, 1, &strText
,
963 wxLB_HSCROLL
| wxLB_ALWAYS_SB
);
965 m_ctrlLog
= new wxTextCtrl(this, -1, "", pos
, size
,
966 wxTE_MULTILINE
| wxTE_READONLY
|
969 // redirect log messages to the text window
970 m_pLog
= new wxLogTextCtrl(m_ctrlLog
);
971 m_pLogPrev
= wxLog::SetActiveTarget(m_pLog
);
973 // associate drop targets with the controls
974 m_ctrlFile
->SetDropTarget(new DnDFile(m_ctrlFile
));
975 m_ctrlText
->SetDropTarget(new DnDText(m_ctrlText
));
976 m_ctrlLog
->SetDropTarget(new URLDropTarget
);
978 wxLayoutConstraints
*c
;
981 c
= new wxLayoutConstraints
;
982 c
->left
.SameAs(this, wxLeft
);
983 c
->top
.SameAs(this, wxTop
);
984 c
->right
.PercentOf(this, wxRight
, 50);
985 c
->height
.PercentOf(this, wxHeight
, 30);
986 m_ctrlFile
->SetConstraints(c
);
989 c
= new wxLayoutConstraints
;
990 c
->left
.SameAs (m_ctrlFile
, wxRight
);
991 c
->top
.SameAs (this, wxTop
);
992 c
->right
.SameAs (this, wxRight
);
993 c
->height
.PercentOf(this, wxHeight
, 30);
994 m_ctrlText
->SetConstraints(c
);
996 // Lower text control
997 c
= new wxLayoutConstraints
;
998 c
->left
.SameAs (this, wxLeft
);
999 c
->right
.SameAs (this, wxRight
);
1000 c
->height
.PercentOf(this, wxHeight
, 50);
1001 c
->top
.SameAs(m_ctrlText
, wxBottom
);
1002 m_ctrlLog
->SetConstraints(c
);
1004 SetAutoLayout(TRUE
);
1007 void DnDFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
1012 void DnDFrame::OnPaint(wxPaintEvent
& WXUNUSED(event
))
1016 GetClientSize( &w
, &h
);
1019 dc
.SetFont( wxFont( 24, wxDECORATIVE
, wxNORMAL
, wxNORMAL
, FALSE
, "charter" ) );
1020 dc
.DrawText( "Drag text from here!", 100, h
-50 );
1023 void DnDFrame::OnUpdateUIPasteText(wxUpdateUIEvent
& event
)
1026 // too many trace messages if we don't do it - this function is called
1031 event
.Enable( wxTheClipboard
->IsSupported(wxDF_TEXT
) );
1034 void DnDFrame::OnUpdateUIPasteBitmap(wxUpdateUIEvent
& event
)
1037 // too many trace messages if we don't do it - this function is called
1042 event
.Enable( wxTheClipboard
->IsSupported(wxDF_BITMAP
) );
1045 void DnDFrame::OnNewFrame(wxCommandEvent
& WXUNUSED(event
))
1047 (new DnDShapeFrame(this))->Show(TRUE
);
1049 wxLogStatus(this, wxT("Double click the new frame to select a shape for it"));
1052 void DnDFrame::OnDrag(wxCommandEvent
& WXUNUSED(event
))
1054 wxString strText
= wxGetTextFromUser
1056 "After you enter text in this dialog, press any mouse\n"
1057 "button in the bottom (empty) part of the frame and \n"
1058 "drag it anywhere - you will be in fact dragging the\n"
1059 "text object containing this text",
1060 "Please enter some text", m_strText
, this
1063 m_strText
= strText
;
1066 void DnDFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
1068 wxMessageBox("Drag-&-Drop Demo\n"
1069 "Please see \"Help|Help...\" for details\n"
1070 "Copyright (c) 1998 Vadim Zeitlin",
1072 wxICON_INFORMATION
| wxOK
,
1076 void DnDFrame::OnHelp(wxCommandEvent
& /* event */)
1078 wxMessageDialog
dialog(this,
1079 "This small program demonstrates drag & drop support in wxWindows. The program window\n"
1080 "consists of 3 parts: the bottom pane is for debug messages, so that you can see what's\n"
1081 "going on inside. The top part is split into 2 listboxes, the left one accepts files\n"
1082 "and the right one accepts text.\n"
1084 "To test wxDropTarget: open wordpad (write.exe), select some text in it and drag it to\n"
1085 "the right listbox (you'll notice the usual visual feedback, i.e. the cursor will change).\n"
1086 "Also, try dragging some files (you can select several at once) from Windows Explorer (or \n"
1087 "File Manager) to the left pane. Hold down Ctrl/Shift keys when you drop text (doesn't \n"
1088 "work with files) and see what changes.\n"
1090 "To test wxDropSource: just press any mouse button on the empty zone of the window and drag\n"
1091 "it to wordpad or any other droptarget accepting text (and of course you can just drag it\n"
1092 "to the right pane). Due to a lot of trace messages, the cursor might take some time to \n"
1093 "change, don't release the mouse button until it does. You can change the string being\n"
1094 "dragged in in \"File|Test drag...\" dialog.\n"
1097 "Please send all questions/bug reports/suggestions &c to \n"
1098 "Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>",
1104 void DnDFrame::OnLogClear(wxCommandEvent
& /* event */ )
1107 m_ctrlText
->Clear();
1108 m_ctrlFile
->Clear();
1111 void DnDFrame::OnLeftDown(wxMouseEvent
&WXUNUSED(event
) )
1113 if ( !m_strText
.IsEmpty() )
1115 // start drag operation
1116 wxTextDataObject
textData(m_strText
);
1118 wxFileDataObject textData;
1119 textData.AddFile( "/file1.txt" );
1120 textData.AddFile( "/file2.txt" );
1122 wxDropSource
source(textData
, this,
1123 wxDROP_ICON(dnd_copy
),
1124 wxDROP_ICON(dnd_move
),
1125 wxDROP_ICON(dnd_none
));
1129 switch ( source
.DoDragDrop(TRUE
) )
1131 case wxDragError
: pc
= "Error!"; break;
1132 case wxDragNone
: pc
= "Nothing"; break;
1133 case wxDragCopy
: pc
= "Copied"; break;
1134 case wxDragMove
: pc
= "Moved"; break;
1135 case wxDragCancel
: pc
= "Cancelled"; break;
1136 default: pc
= "Huh?"; break;
1139 SetStatusText(wxString("Drag result: ") + pc
);
1143 void DnDFrame::OnRightDown(wxMouseEvent
&event
)
1145 wxMenu
menu("Dnd sample menu");
1147 menu
.Append(Menu_Drag
, "&Test drag...");
1148 menu
.AppendSeparator();
1149 menu
.Append(Menu_About
, "&About");
1151 PopupMenu( &menu
, event
.GetX(), event
.GetY() );
1154 DnDFrame::~DnDFrame()
1156 if ( m_pLog
!= NULL
) {
1157 if ( wxLog::SetActiveTarget(m_pLogPrev
) == m_pLog
)
1162 // ---------------------------------------------------------------------------
1164 // ---------------------------------------------------------------------------
1166 void DnDFrame::OnCopyBitmap(wxCommandEvent
& WXUNUSED(event
))
1168 // PNG support is not always compiled in under Windows, so use BMP there
1170 wxFileDialog
dialog(this, "Open a BMP file", "", "", "BMP files (*.bmp)|*.bmp", 0);
1172 wxFileDialog
dialog(this, "Open a PNG file", "", "", "PNG files (*.png)|*.png", 0);
1175 if (dialog
.ShowModal() != wxID_OK
)
1177 wxLogMessage( _T("Aborted file open") );
1181 if (dialog
.GetPath().IsEmpty())
1183 wxLogMessage( _T("Returned empty string.") );
1187 if (!wxFileExists(dialog
.GetPath()))
1189 wxLogMessage( _T("File doesn't exist.") );
1194 image
.LoadFile( dialog
.GetPath(),
1203 wxLogError( _T("Invalid image file...") );
1207 wxLogStatus( _T("Decoding image file...") );
1210 wxBitmap
bitmap( image
.ConvertToBitmap() );
1212 if ( !wxTheClipboard
->Open() )
1214 wxLogError(_T("Can't open clipboard."));
1219 wxLogMessage( _T("Creating wxBitmapDataObject...") );
1222 if ( !wxTheClipboard
->AddData(new wxBitmapDataObject(bitmap
)) )
1224 wxLogError(_T("Can't copy image to the clipboard."));
1228 wxLogMessage(_T("Image has been put on the clipboard.") );
1229 wxLogMessage(_T("You can paste it now and look at it.") );
1232 wxTheClipboard
->Close();
1235 void DnDFrame::OnPasteBitmap(wxCommandEvent
& WXUNUSED(event
))
1237 if ( !wxTheClipboard
->Open() )
1239 wxLogError(_T("Can't open clipboard."));
1244 if ( !wxTheClipboard
->IsSupported(wxDF_BITMAP
) )
1246 wxLogWarning(_T("No bitmap on clipboard"));
1248 wxTheClipboard
->Close();
1252 wxBitmapDataObject data
;
1253 if ( !wxTheClipboard
->GetData(data
) )
1255 wxLogError(_T("Can't paste bitmap from the clipboard"));
1259 const wxBitmap
& bmp
= data
.GetBitmap();
1261 wxLogMessage(_T("Bitmap %dx%d pasted from the clipboard"),
1262 bmp
.GetWidth(), bmp
.GetHeight());
1266 wxTheClipboard
->Close();
1269 #ifdef USE_METAFILES
1271 void DnDFrame::OnPasteMetafile(wxCommandEvent
& WXUNUSED(event
))
1273 if ( !wxTheClipboard
->Open() )
1275 wxLogError(_T("Can't open clipboard."));
1280 if ( !wxTheClipboard
->IsSupported(wxDF_METAFILE
) )
1282 wxLogWarning(_T("No metafile on clipboard"));
1286 wxMetaFileDataObject data
;
1287 if ( !wxTheClipboard
->GetData(data
) )
1289 wxLogError(_T("Can't paste metafile from the clipboard"));
1293 const wxMetaFile
& mf
= data
.GetMetafile();
1295 wxLogMessage(_T("Metafile %dx%d pasted from the clipboard"),
1296 mf
.GetWidth(), mf
.GetHeight());
1302 wxTheClipboard
->Close();
1305 #endif // USE_METAFILES
1307 // ----------------------------------------------------------------------------
1309 // ----------------------------------------------------------------------------
1311 void DnDFrame::OnCopyFiles(wxCommandEvent
& WXUNUSED(event
))
1314 wxFileDialog
dialog(this, "Select a file to copy", "", "",
1315 "All files (*.*)|*.*", 0);
1317 wxArrayString filenames
;
1318 while ( dialog
.ShowModal() == wxID_OK
)
1320 filenames
.Add(dialog
.GetPath());
1323 if ( !filenames
.IsEmpty() )
1325 wxFileDataObject
*dobj
= new wxFileDataObject
;
1326 size_t count
= filenames
.GetCount();
1327 for ( size_t n
= 0; n
< count
; n
++ )
1329 dobj
->AddFile(filenames
[n
]);
1332 wxClipboardLocker locker
;
1335 wxLogError(wxT("Can't open clipboard"));
1339 if ( !wxTheClipboard
->AddData(dobj
) )
1341 wxLogError(wxT("Can't copy file(s) to the clipboard"));
1345 wxLogStatus(this, wxT("%d file%s copied to the clipboard"),
1346 count
, count
== 1 ? wxT("") : wxT("s"));
1352 wxLogStatus(this, wxT("Aborted"));
1355 wxLogError(wxT("Sorry, not implemented"));
1359 // ---------------------------------------------------------------------------
1361 // ---------------------------------------------------------------------------
1363 void DnDFrame::OnCopy(wxCommandEvent
& WXUNUSED(event
))
1365 if ( !wxTheClipboard
->Open() )
1367 wxLogError(_T("Can't open clipboard."));
1372 if ( !wxTheClipboard
->AddData(new wxTextDataObject(m_strText
)) )
1374 wxLogError(_T("Can't copy data to the clipboard"));
1378 wxLogMessage(_T("Text '%s' put on the clipboard"), m_strText
.c_str());
1381 wxTheClipboard
->Close();
1384 void DnDFrame::OnPaste(wxCommandEvent
& WXUNUSED(event
))
1386 if ( !wxTheClipboard
->Open() )
1388 wxLogError(_T("Can't open clipboard."));
1393 if ( !wxTheClipboard
->IsSupported(wxDF_TEXT
) )
1395 wxLogWarning(_T("No text data on clipboard"));
1397 wxTheClipboard
->Close();
1401 wxTextDataObject text
;
1402 if ( !wxTheClipboard
->GetData(text
) )
1404 wxLogError(_T("Can't paste data from the clipboard"));
1408 wxLogMessage(_T("Text '%s' pasted from the clipboard"),
1409 text
.GetText().c_str());
1412 wxTheClipboard
->Close();
1415 // ----------------------------------------------------------------------------
1416 // Notifications called by the base class
1417 // ----------------------------------------------------------------------------
1419 bool DnDText::OnDropText(wxCoord
, wxCoord
, const wxString
& text
)
1421 m_pOwner
->Append(text
);
1426 bool DnDFile::OnDropFiles(wxCoord
, wxCoord
, const wxArrayString
& filenames
)
1428 size_t nFiles
= filenames
.GetCount();
1430 str
.Printf( _T("%d files dropped"), nFiles
);
1431 m_pOwner
->Append(str
);
1432 for ( size_t n
= 0; n
< nFiles
; n
++ ) {
1433 m_pOwner
->Append(filenames
[n
]);
1439 // ----------------------------------------------------------------------------
1441 // ----------------------------------------------------------------------------
1443 DnDShapeDialog::DnDShapeDialog(wxFrame
*parent
, DnDShape
*shape
)
1445 :wxDialog( parent
, 6001, wxT("Choose Shape"), wxPoint( 10, 10 ),
1447 wxRAISED_BORDER
|wxCAPTION
|wxTHICK_FRAME
|wxSYSTEM_MENU
)
1452 LoadFromResource(parent
, "dialogShape");
1454 m_textX
= (wxTextCtrl
*)wxFindWindowByName("textX", this);
1455 m_textY
= (wxTextCtrl
*)wxFindWindowByName("textY", this);
1456 m_textW
= (wxTextCtrl
*)wxFindWindowByName("textW", this);
1457 m_textH
= (wxTextCtrl
*)wxFindWindowByName("textH", this);
1459 m_radio
= (wxRadioBox
*)wxFindWindowByName("radio", this);
1461 wxBoxSizer
* topSizer
= new wxBoxSizer( wxVERTICAL
);
1464 wxBoxSizer
* shapesSizer
= new wxBoxSizer( wxHORIZONTAL
);
1465 const wxString choices
[] = { wxT("None"), wxT("Triangle"),
1466 wxT("Rectangle"), wxT("Ellipse") };
1468 m_radio
= new wxRadioBox( this, -1, wxT("&Shape"),
1469 wxDefaultPosition
, wxDefaultSize
, 4, choices
, 4,
1470 wxRA_SPECIFY_COLS
);
1471 shapesSizer
->Add( m_radio
, 0, wxGROW
|wxALL
, 5 );
1472 topSizer
->Add( shapesSizer
, 0, wxALL
, 2 );
1475 wxStaticBox
* box
= new wxStaticBox( this, -1, wxT("&Attributes") );
1476 wxStaticBoxSizer
* attrSizer
= new wxStaticBoxSizer( box
, wxHORIZONTAL
);
1477 wxFlexGridSizer
* xywhSizer
= new wxFlexGridSizer( 4, 2 );
1481 st
= new wxStaticText( this, -1, wxT("Position &X:") );
1482 m_textX
= new wxTextCtrl( this, -1, wxEmptyString
, wxDefaultPosition
,
1484 xywhSizer
->Add( st
, 1, wxGROW
|wxALL
, 2 );
1485 xywhSizer
->Add( m_textX
, 1, wxGROW
|wxALL
, 2 );
1487 st
= new wxStaticText( this, -1, wxT("Size &width:") );
1488 m_textW
= new wxTextCtrl( this, -1, wxEmptyString
, wxDefaultPosition
,
1490 xywhSizer
->Add( st
, 1, wxGROW
|wxALL
, 2 );
1491 xywhSizer
->Add( m_textW
, 1, wxGROW
|wxALL
, 2 );
1493 st
= new wxStaticText( this, -1, wxT("&Y:") );
1494 m_textY
= new wxTextCtrl( this, -1, wxEmptyString
, wxDefaultPosition
,
1496 xywhSizer
->Add( st
, 1, wxALL
|wxALIGN_RIGHT
, 2 );
1497 xywhSizer
->Add( m_textY
, 1, wxGROW
|wxALL
, 2 );
1499 st
= new wxStaticText( this, -1, wxT("&height:") );
1500 m_textH
= new wxTextCtrl( this, -1, wxEmptyString
, wxDefaultPosition
,
1502 xywhSizer
->Add( st
, 1, wxALL
|wxALIGN_RIGHT
, 2 );
1503 xywhSizer
->Add( m_textH
, 1, wxGROW
|wxALL
, 2 );
1505 wxButton
* col
= new wxButton( this, Button_Colour
, wxT("&Colour...") );
1506 attrSizer
->Add( xywhSizer
, 1, wxGROW
);
1507 attrSizer
->Add( col
, 0, wxALL
|wxALIGN_CENTRE_VERTICAL
, 2 );
1508 topSizer
->Add( attrSizer
, 0, wxGROW
|wxALL
, 5 );
1511 wxBoxSizer
* buttonSizer
= new wxBoxSizer( wxHORIZONTAL
);
1513 bt
= new wxButton( this, wxID_OK
, wxT("Ok") );
1514 buttonSizer
->Add( bt
, 0, wxALL
, 2 );
1515 bt
= new wxButton( this, wxID_CANCEL
, wxT("Cancel") );
1516 buttonSizer
->Add( bt
, 0, wxALL
, 2 );
1517 topSizer
->Add( buttonSizer
, 0, wxALL
|wxALIGN_RIGHT
, 2 );
1519 SetAutoLayout( TRUE
);
1520 SetSizer( topSizer
);
1521 topSizer
->Fit( this );
1525 DnDShape
*DnDShapeDialog::GetShape() const
1527 switch ( m_shapeKind
)
1530 case DnDShape::None
: return NULL
;
1531 case DnDShape::Triangle
: return new DnDTriangularShape(m_pos
, m_size
, m_col
);
1532 case DnDShape::Rectangle
: return new DnDRectangularShape(m_pos
, m_size
, m_col
);
1533 case DnDShape::Ellipse
: return new DnDEllipticShape(m_pos
, m_size
, m_col
);
1537 bool DnDShapeDialog::TransferDataToWindow()
1542 m_radio
->SetSelection(m_shape
->GetKind());
1543 m_pos
= m_shape
->GetPosition();
1544 m_size
= m_shape
->GetSize();
1545 m_col
= m_shape
->GetColour();
1549 m_radio
->SetSelection(DnDShape::None
);
1550 m_pos
= wxPoint(1, 1);
1551 m_size
= wxSize(100, 100);
1554 m_textX
->SetValue(wxString() << m_pos
.x
);
1555 m_textY
->SetValue(wxString() << m_pos
.y
);
1556 m_textW
->SetValue(wxString() << m_size
.x
);
1557 m_textH
->SetValue(wxString() << m_size
.y
);
1562 bool DnDShapeDialog::TransferDataFromWindow()
1564 m_shapeKind
= (DnDShape::Kind
)m_radio
->GetSelection();
1566 m_pos
.x
= wxAtoi(m_textX
->GetValue());
1567 m_pos
.y
= wxAtoi(m_textY
->GetValue());
1568 m_size
.x
= wxAtoi(m_textW
->GetValue());
1569 m_size
.y
= wxAtoi(m_textH
->GetValue());
1571 if ( !m_pos
.x
|| !m_pos
.y
|| !m_size
.x
|| !m_size
.y
)
1573 wxMessageBox("All sizes and positions should be non null!",
1574 "Invalid shape", wxICON_HAND
| wxOK
, this);
1582 void DnDShapeDialog::OnColour(wxCommandEvent
& WXUNUSED(event
))
1585 data
.SetChooseFull(TRUE
);
1586 for (int i
= 0; i
< 16; i
++)
1588 wxColour
colour(i
*16, i
*16, i
*16);
1589 data
.SetCustomColour(i
, colour
);
1592 wxColourDialog
dialog(this, &data
);
1593 if ( dialog
.ShowModal() == wxID_OK
)
1595 m_col
= dialog
.GetColourData().GetColour();
1599 // ----------------------------------------------------------------------------
1601 // ----------------------------------------------------------------------------
1603 DnDShapeFrame
*DnDShapeFrame::ms_lastDropTarget
= NULL
;
1605 DnDShapeFrame::DnDShapeFrame(wxFrame
*parent
)
1606 : wxFrame(parent
, -1, "Shape Frame",
1607 wxDefaultPosition
, wxSize(250, 150))
1611 wxMenu
*menuShape
= new wxMenu
;
1612 menuShape
->Append(Menu_Shape_New
, "&New default shape\tCtrl-S");
1613 menuShape
->Append(Menu_Shape_Edit
, "&Edit shape\tCtrl-E");
1614 menuShape
->AppendSeparator();
1615 menuShape
->Append(Menu_Shape_Clear
, "&Clear shape\tCtrl-L");
1617 wxMenu
*menuClipboard
= new wxMenu
;
1618 menuClipboard
->Append(Menu_ShapeClipboard_Copy
, "&Copy\tCtrl-C");
1619 menuClipboard
->Append(Menu_ShapeClipboard_Paste
, "&Paste\tCtrl-V");
1621 wxMenuBar
*menubar
= new wxMenuBar
;
1622 menubar
->Append(menuShape
, "&Shape");
1623 menubar
->Append(menuClipboard
, "&Clipboard");
1625 SetMenuBar(menubar
);
1627 SetStatusText("Press Ctrl-S to create a new shape");
1629 SetDropTarget(new DnDShapeDropTarget(this));
1633 SetBackgroundColour(*wxWHITE
);
1636 DnDShapeFrame::~DnDShapeFrame()
1642 void DnDShapeFrame::SetShape(DnDShape
*shape
)
1651 void DnDShapeFrame::OnDrag(wxMouseEvent
& event
)
1660 // start drag operation
1661 DnDShapeDataObject
shapeData(m_shape
);
1662 wxDropSource
source(shapeData
, this);
1664 const char *pc
= NULL
;
1665 switch ( source
.DoDragDrop(TRUE
) )
1669 wxLogError(wxT("An error occured during drag and drop operation"));
1673 SetStatusText("Nothing happened");
1682 if ( ms_lastDropTarget
!= this )
1684 // don't delete the shape if we dropped it on ourselves!
1690 SetStatusText("Drag and drop operation cancelled");
1696 SetStatusText(wxString("Shape successfully ") + pc
);
1698 //else: status text already set
1701 void DnDShapeFrame::OnDrop(wxCoord x
, wxCoord y
, DnDShape
*shape
)
1703 ms_lastDropTarget
= this;
1708 s
.Printf(wxT("Shape dropped at (%ld, %ld)"), pt
.x
, pt
.y
);
1715 void DnDShapeFrame::OnEditShape(wxCommandEvent
& event
)
1717 DnDShapeDialog
dlg(this, m_shape
);
1718 if ( dlg
.ShowModal() == wxID_OK
)
1720 SetShape(dlg
.GetShape());
1724 SetStatusText("You can now drag the shape to another frame");
1729 void DnDShapeFrame::OnNewShape(wxCommandEvent
& event
)
1731 SetShape(new DnDEllipticShape(wxPoint(10, 10), wxSize(80, 60), *wxRED
));
1733 SetStatusText("You can now drag the shape to another frame");
1736 void DnDShapeFrame::OnClearShape(wxCommandEvent
& event
)
1741 void DnDShapeFrame::OnCopyShape(wxCommandEvent
& event
)
1745 wxClipboardLocker clipLocker
;
1748 wxLogError(wxT("Can't open the clipboard"));
1753 wxTheClipboard
->AddData(new DnDShapeDataObject(m_shape
));
1757 void DnDShapeFrame::OnPasteShape(wxCommandEvent
& event
)
1759 wxClipboardLocker clipLocker
;
1762 wxLogError(wxT("Can't open the clipboard"));
1767 DnDShapeDataObject
shapeDataObject(NULL
);
1768 if ( wxTheClipboard
->GetData(shapeDataObject
) )
1770 SetShape(shapeDataObject
.GetShape());
1774 wxLogStatus(wxT("No shape on the clipboard"));
1778 void DnDShapeFrame::OnUpdateUICopy(wxUpdateUIEvent
& event
)
1780 event
.Enable( m_shape
!= NULL
);
1783 void DnDShapeFrame::OnUpdateUIPaste(wxUpdateUIEvent
& event
)
1785 event
.Enable( wxTheClipboard
->IsSupported(wxDataFormat(shapeFormatId
)) );
1788 void DnDShapeFrame::OnPaint(wxPaintEvent
& event
)
1802 // ----------------------------------------------------------------------------
1804 // ----------------------------------------------------------------------------
1806 DnDShape
*DnDShape::New(const void *buf
)
1808 const ShapeDump
& dump
= *(const ShapeDump
*)buf
;
1812 return new DnDTriangularShape(wxPoint(dump
.x
, dump
.y
),
1813 wxSize(dump
.w
, dump
.h
),
1814 wxColour(dump
.r
, dump
.g
, dump
.b
));
1817 return new DnDRectangularShape(wxPoint(dump
.x
, dump
.y
),
1818 wxSize(dump
.w
, dump
.h
),
1819 wxColour(dump
.r
, dump
.g
, dump
.b
));
1822 return new DnDEllipticShape(wxPoint(dump
.x
, dump
.y
),
1823 wxSize(dump
.w
, dump
.h
),
1824 wxColour(dump
.r
, dump
.g
, dump
.b
));
1827 wxFAIL_MSG(wxT("invalid shape!"));
1832 // ----------------------------------------------------------------------------
1833 // DnDShapeDataObject
1834 // ----------------------------------------------------------------------------
1836 #ifdef USE_METAFILES
1838 void DnDShapeDataObject::CreateMetaFile() const
1840 wxPoint pos
= m_shape
->GetPosition();
1841 wxSize size
= m_shape
->GetSize();
1843 wxMetaFileDC
dcMF(wxEmptyString
, pos
.x
+ size
.x
, pos
.y
+ size
.y
);
1845 m_shape
->Draw(dcMF
);
1847 wxMetafile
*mf
= dcMF
.Close();
1849 DnDShapeDataObject
*self
= (DnDShapeDataObject
*)this; // const_cast
1850 self
->m_dobjMetaFile
.SetMetafile(*mf
);
1851 self
->m_hasMetaFile
= TRUE
;
1858 void DnDShapeDataObject::CreateBitmap() const
1860 wxPoint pos
= m_shape
->GetPosition();
1861 wxSize size
= m_shape
->GetSize();
1862 int x
= pos
.x
+ size
.x
,
1864 wxBitmap
bitmap(x
, y
);
1866 dc
.SelectObject(bitmap
);
1867 dc
.SetBrush(wxBrush(wxT("white"), wxSOLID
));
1870 dc
.SelectObject(wxNullBitmap
);
1872 DnDShapeDataObject
*self
= (DnDShapeDataObject
*)this; // const_cast
1873 self
->m_dobjBitmap
.SetBitmap(bitmap
);
1874 self
->m_hasBitmap
= TRUE
;
1877 // ----------------------------------------------------------------------------
1879 // ----------------------------------------------------------------------------
1881 static void ShowBitmap(const wxBitmap
& bitmap
)
1883 wxFrame
*frame
= new wxFrame(NULL
, -1, _T("Bitmap view"));
1884 frame
->CreateStatusBar();
1885 DnDCanvasBitmap
*canvas
= new DnDCanvasBitmap(frame
);
1886 canvas
->SetBitmap(bitmap
);
1888 int w
= bitmap
.GetWidth(),
1889 h
= bitmap
.GetHeight();
1890 frame
->SetStatusText(wxString::Format(_T("%dx%d"), w
, h
));
1892 frame
->SetClientSize(w
> 100 ? 100 : w
, h
> 100 ? 100 : h
);
1896 #ifdef USE_METAFILES
1898 static void ShowMetaFile(const wxMetaFile
& metafile
)
1900 wxFrame
*frame
= new wxFrame(NULL
, -1, _T("Metafile view"));
1901 frame
->CreateStatusBar();
1902 DnDCanvasMetafile
*canvas
= new DnDCanvasMetafile(frame
);
1903 canvas
->SetMetafile(metafile
);
1905 wxSize size
= metafile
.GetSize();
1906 frame
->SetStatusText(wxString::Format(_T("%dx%d"), size
.x
, size
.y
));
1908 frame
->SetClientSize(size
.x
> 100 ? 100 : size
.x
,
1909 size
.y
> 100 ? 100 : size
.y
);
1913 #endif // USE_METAFILES