1. wxPostEvent added and documented

2. Made it possible to have wxDataObjects which support multiple formats
   painlessly
3. Extensively modified dnd sample to show a "real life" wxDataObject


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4028 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
1999-10-17 01:18:49 +00:00
parent 6d693bb4fc
commit 8e193f384f
24 changed files with 1359 additions and 637 deletions

View File

@@ -19,8 +19,8 @@
#include "wx/wx.h"
#endif
#ifdef __WXMOTIF__
#error Sorry, drag and drop is not yet implemented on wxMotif.
#if !wxUSE_DRAG_AND_DROP
#error This sample requires drag and drop support in the library
#endif
#include "wx/intl.h"
@@ -31,6 +31,8 @@
#include "wx/filedlg.h"
#include "wx/image.h"
#include "wx/clipbrd.h"
#include "wx/colordlg.h"
#include "wx/resource.h"
#if defined(__WXGTK__) || defined(__WXMOTIF__)
#include "mondrian.xpm"
@@ -74,14 +76,15 @@ private:
class DnDApp : public wxApp
{
public:
bool OnInit();
virtual bool OnInit();
};
IMPLEMENT_APP(DnDApp);
// ----------------------------------------------------------------------------
// Define a new frame type
// Define a new frame type for the main frame
// ----------------------------------------------------------------------------
class DnDFrame : public wxFrame
{
public:
@@ -92,6 +95,7 @@ public:
void OnQuit (wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
void OnDrag (wxCommandEvent& event);
void OnNewFrame(wxCommandEvent& event);
void OnHelp (wxCommandEvent& event);
void OnLogClear(wxCommandEvent& event);
void OnCopy(wxCommandEvent& event);
@@ -117,6 +121,355 @@ private:
wxBitmap m_bitmap;
};
// ----------------------------------------------------------------------------
// A shape is an example of application-specific data which may be transported
// via drag-and-drop or clipboard: in our case, we have different geometric
// shapes, each one with its own colour and position
// ----------------------------------------------------------------------------
class DnDShape
{
public:
enum Kind
{
None,
Triangle,
Rectangle,
Ellipse
};
DnDShape(const wxPoint& pos,
const wxSize& size,
const wxColour& col)
: m_pos(pos), m_size(size), m_col(col)
{
}
// the functions used for drag-and-drop: they dump and restore a shape into
// some bitwise-copiable data
//
// NB: here we profit from the fact that wxPoint, wxSize and wxColour are
// POD (plain old data) and so can be copied directly - but it wouldn't
// work for other types!
// ------------------------------------------------------------------------
// restore from buffer
static DnDShape *New(const void *buf);
virtual size_t GetDataSize() const
{
return sizeof(ShapeDump);
}
virtual void GetDataHere(void *buf) const
{
ShapeDump& dump = *(ShapeDump *)buf;
dump.x = m_pos.x;
dump.y = m_pos.y;
dump.w = m_size.x;
dump.h = m_size.y;
dump.r = m_col.Red();
dump.g = m_col.Green();
dump.b = m_col.Blue();
dump.k = GetKind();
}
// accessors
const wxPoint& GetPosition() const { return m_pos; }
const wxColour& GetColour() const { return m_col; }
const wxSize& GetSize() const { return m_size; }
// to implement in derived classes
virtual Kind GetKind() const = 0;
virtual void Draw(wxDC& dc) = 0
{
dc.SetPen(wxPen(m_col, 1, wxSOLID));
}
protected:
wxPoint GetCentre() const
{ return wxPoint(m_pos.x + m_size.x / 2, m_pos.y + m_size.y / 2); }
struct ShapeDump
{
int x, y, // position
w, h, // size
r, g, b, // colour
k; // kind
};
wxPoint m_pos;
wxSize m_size;
wxColour m_col;
};
class DnDTriangularShape : public DnDShape
{
public:
DnDTriangularShape(const wxPoint& pos,
const wxSize& size,
const wxColour& col)
: DnDShape(pos, size, col)
{
}
virtual Kind GetKind() const { return Triangle; }
virtual void Draw(wxDC& dc)
{
DnDShape::Draw(dc);
// well, it's a bit difficult to describe a triangle by position and
// size, but we're not doing geometry here, do we? ;-)
wxPoint p1(m_pos);
wxPoint p2(m_pos.x + m_size.x, m_pos.y);
wxPoint p3(m_pos.x, m_pos.y + m_size.y);
dc.DrawLine(p1, p2);
dc.DrawLine(p2, p3);
dc.DrawLine(p3, p1);
dc.FloodFill(GetCentre(), m_col, wxFLOOD_BORDER);
}
};
class DnDRectangularShape : public DnDShape
{
public:
DnDRectangularShape(const wxPoint& pos,
const wxSize& size,
const wxColour& col)
: DnDShape(pos, size, col)
{
}
virtual Kind GetKind() const { return Rectangle; }
virtual void Draw(wxDC& dc)
{
DnDShape::Draw(dc);
wxPoint p1(m_pos);
wxPoint p2(p1.x + m_size.x, p1.y);
wxPoint p3(p2.x, p2.y + m_size.y);
wxPoint p4(p1.x, p3.y);
dc.DrawLine(p1, p2);
dc.DrawLine(p2, p3);
dc.DrawLine(p3, p4);
dc.DrawLine(p4, p1);
dc.FloodFill(GetCentre(), m_col, wxFLOOD_BORDER);
}
};
class DnDEllipticShape : public DnDShape
{
public:
DnDEllipticShape(const wxPoint& pos,
const wxSize& size,
const wxColour& col)
: DnDShape(pos, size, col)
{
}
virtual Kind GetKind() const { return Ellipse; }
virtual void Draw(wxDC& dc)
{
DnDShape::Draw(dc);
dc.DrawEllipse(m_pos, m_size);
dc.FloodFill(GetCentre(), m_col, wxFLOOD_BORDER);
}
};
// ----------------------------------------------------------------------------
// A wxDataObject specialisation for the application-specific data
// ----------------------------------------------------------------------------
static const char *shapeFormatId = "wxShape";
class DnDShapeDataObject : public wxDataObject
{
public:
// ctor doesn't copy the pointer, so it shouldn't go away while this object
// is alive
DnDShapeDataObject(DnDShape *shape)
{
m_shape = shape;
// this string should uniquely identify our format, but is otherwise
// arbitrary
m_formatShape.SetId(shapeFormatId);
// we don't draw the shape to a bitmap until it's really needed (i.e.
// we're asked to do so)
m_hasBitmap = FALSE;
}
// implement base class pure virtuals
// ----------------------------------
virtual wxDataFormat GetPreferredFormat() const
{
return m_formatShape;
}
virtual size_t GetFormatCount() const
{
// +1 for our custom format
return m_dataobj.GetFormatCount() + 1;
}
virtual void GetAllFormats(wxDataFormat *formats) const
{
formats[0] = m_formatShape;
m_dataobj.GetAllFormats(&formats[1]);
}
virtual size_t GetDataSize(const wxDataFormat& format) const
{
if ( format == m_formatShape )
{
return m_shape->GetDataSize();
}
else
{
wxASSERT_MSG( format == wxDF_BITMAP, "unsupported format" );
if ( !m_hasBitmap )
CreateBitmap();
return m_dataobj.GetDataSize(format);
}
}
virtual void GetDataHere(const wxDataFormat& format, void *pBuf) const
{
if ( format == m_formatShape )
{
m_shape->GetDataHere(pBuf);
}
else
{
wxASSERT_MSG( format == wxDF_BITMAP, "unsupported format" );
if ( !m_hasBitmap )
CreateBitmap();
m_dataobj.GetDataHere(format, pBuf);
}
}
private:
// creates a bitmap and assigns it to m_dataobj (also sets m_hasBitmap)
void CreateBitmap() const;
wxDataFormat m_formatShape; // our custom format
wxBitmapDataObject m_dataobj; // it handles bitmaps
bool m_hasBitmap; // true if m_dataobj has valid bitmap
DnDShape *m_shape; // our data
};
// ----------------------------------------------------------------------------
// A dialog to edit shape properties
// ----------------------------------------------------------------------------
class DnDShapeDialog : public wxDialog
{
public:
DnDShapeDialog(wxFrame *parent, DnDShape *shape);
DnDShape *GetShape() const;
virtual bool TransferDataToWindow();
virtual bool TransferDataFromWindow();
void OnColour(wxCommandEvent& event);
private:
// input
DnDShape *m_shape;
// output
DnDShape::Kind m_shapeKind;
wxPoint m_pos;
wxSize m_size;
wxColour m_col;
// controls
wxRadioBox *m_radio;
wxTextCtrl *m_textX,
*m_textY,
*m_textW,
*m_textH;
DECLARE_EVENT_TABLE()
};
// ----------------------------------------------------------------------------
// A frame for the shapes which can be drag-and-dropped between frames
// ----------------------------------------------------------------------------
class DnDShapeFrame : public wxFrame
{
public:
DnDShapeFrame(wxFrame *parent);
~DnDShapeFrame();
void SetShape(DnDShape *shape);
// callbacks
void OnDrag(wxMouseEvent& event);
void OnEdit(wxMouseEvent& event);
void OnPaint(wxPaintEvent& event);
void OnDrop(long x, long y, DnDShape *shape);
private:
DnDShape *m_shape;
DECLARE_EVENT_TABLE()
};
// ----------------------------------------------------------------------------
// wxDropTarget derivation for DnDShapes
// ----------------------------------------------------------------------------
class DnDShapeDropTarget : public wxDropTarget
{
public:
DnDShapeDropTarget(DnDShapeFrame *frame)
{
m_frame = frame;
// the same as used by DnDShapeDataObject
m_formatShape.SetId(shapeFormatId);
}
// override base class (pure) virtuals
virtual void OnEnter()
{ m_frame->SetStatusText("Mouse entered the frame"); }
virtual void OnLeave()
{ m_frame->SetStatusText("Mouse left the frame"); }
virtual bool OnDrop(long x, long y, const void *pData)
{
m_frame->OnDrop(x, y, DnDShape::New(pData));
return TRUE;
}
protected:
virtual size_t GetFormatCount() const { return 1; }
virtual wxDataFormat GetFormat(size_t WXUNUSED(n)) const
{ return m_formatShape; }
private:
DnDShapeFrame *m_frame;
wxDataFormat m_formatShape;
};
// ----------------------------------------------------------------------------
// IDs for the menu commands
// ----------------------------------------------------------------------------
@@ -125,6 +478,7 @@ enum
{
Menu_Quit = 1,
Menu_Drag,
Menu_NewFrame,
Menu_About = 101,
Menu_Help,
Menu_Clear,
@@ -135,13 +489,15 @@ enum
Menu_HasText,
Menu_HasBitmap,
Menu_ToBeGreyed, /* for testing */
Menu_ToBeDeleted /* for testing */
Menu_ToBeDeleted, /* for testing */
Button_Colour = 1001
};
BEGIN_EVENT_TABLE(DnDFrame, wxFrame)
EVT_MENU(Menu_Quit, DnDFrame::OnQuit)
EVT_MENU(Menu_About, DnDFrame::OnAbout)
EVT_MENU(Menu_Drag, DnDFrame::OnDrag)
EVT_MENU(Menu_NewFrame, DnDFrame::OnNewFrame)
EVT_MENU(Menu_Help, DnDFrame::OnHelp)
EVT_MENU(Menu_Clear, DnDFrame::OnLogClear)
EVT_MENU(Menu_Copy, DnDFrame::OnCopy)
@@ -156,7 +512,21 @@ BEGIN_EVENT_TABLE(DnDFrame, wxFrame)
EVT_PAINT( DnDFrame::OnPaint)
END_EVENT_TABLE()
// `Main program' equivalent, creating windows and returning main app frame
BEGIN_EVENT_TABLE(DnDShapeFrame, wxFrame)
EVT_RIGHT_DOWN(DnDShapeFrame::OnDrag)
EVT_LEFT_DCLICK(DnDShapeFrame::OnEdit)
EVT_PAINT(DnDShapeFrame::OnPaint)
END_EVENT_TABLE()
BEGIN_EVENT_TABLE(DnDShapeDialog, wxDialog)
EVT_BUTTON(Button_Colour, OnColour)
END_EVENT_TABLE()
// ============================================================================
// implementation
// ============================================================================
// `Main program' equivalent, creating windows and returning main app frame
bool DnDApp::OnInit()
{
#if wxUSE_LIBPNG
@@ -173,6 +543,8 @@ bool DnDApp::OnInit()
SetTopWindow(frame);
wxDefaultResourceTable->ParseResourceFile("dnd.wxr");
return TRUE;
}
@@ -186,19 +558,13 @@ DnDFrame::DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h)
CreateStatusBar();
// construct sub menu for testing
wxMenu *sub_menu = new wxMenu;
sub_menu->Append(Menu_Quit, "E&xit");
sub_menu->Append(Menu_Quit, "E&xit");
sub_menu->Append(Menu_Quit, "E&xit");
// construct menu
wxMenu *file_menu = new wxMenu;
file_menu->Append(Menu_Drag, "&Test drag...");
file_menu->AppendSeparator();
file_menu->Append(Menu_Quit, "E&xit");
file_menu->Append(Menu_NewFrame, "&New frame\tCtrl-N");
file_menu->AppendSeparator();
file_menu->Append( 0, "More exit menus", sub_menu);
file_menu->Append(Menu_Quit, "E&xit");
wxMenu *log_menu = new wxMenu;
log_menu->Append(Menu_Clear, "Clear");
@@ -217,7 +583,7 @@ DnDFrame::DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h)
clip_menu->AppendSeparator();
clip_menu->Append(Menu_HasText, "Clipboard has &text\tCtrl+T");
clip_menu->Append(Menu_HasBitmap, "Clipboard has a &bitmap\tCtrl+B");
wxMenuBar *menu_bar = new wxMenuBar;
menu_bar->Append(file_menu, "&File");
menu_bar->Append(log_menu, "&Log");
@@ -238,7 +604,10 @@ DnDFrame::DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h)
m_ctrlLog = new wxTextCtrl(this, -1, "", pos, size,
wxTE_MULTILINE | wxTE_READONLY |
wxSUNKEN_BORDER );
// redirect log messages to the text window (don't forget to delete it!)
// redirect log messages to the text window and switch on OLE messages
// logging
wxLog::AddTraceMask(wxTRACE_OleCalls);
m_pLog = new wxLogTextCtrl(m_ctrlLog);
m_pLogPrev = wxLog::SetActiveTarget(m_pLog);
@@ -289,7 +658,7 @@ void DnDFrame::OnPaint(wxPaintEvent& WXUNUSED(event))
wxPaintDC dc(this);
dc.SetFont( wxFont( 24, wxDECORATIVE, wxNORMAL, wxNORMAL, FALSE, "charter" ) );
dc.DrawText( "Drag text from here!", 20, h-50 );
if (m_bitmap.Ok())
dc.DrawBitmap( m_bitmap, 280, h-120, TRUE );
}
@@ -336,6 +705,13 @@ void DnDFrame::OnClipboardHasBitmap(wxCommandEvent& WXUNUSED(event))
wxTheClipboard->Close();
}
void DnDFrame::OnNewFrame(wxCommandEvent& WXUNUSED(event))
{
(new DnDShapeFrame(this))->Show(TRUE);
wxLogStatus(this, "Double click the new frame to select a shape for it");
}
void DnDFrame::OnDrag(wxCommandEvent& WXUNUSED(event))
{
wxString strText = wxGetTextFromUser
@@ -395,18 +771,15 @@ void DnDFrame::OnLogClear(wxCommandEvent& /* event */ )
void DnDFrame::OnLeftDown(wxMouseEvent &WXUNUSED(event) )
{
if ( !m_strText.IsEmpty() )
if ( !m_strText.IsEmpty() )
{
// start drag operation
#ifdef __WXMSW__
wxTextDataObject textData(m_strText);
wxDropSource dragSource( textData, this );
#else
wxDropSource dragSource( new wxTextDataObject (m_strText), this, wxIcon(mondrian_xpm) );
#endif
wxDropSource source(textData, this, wxICON(mondrian));
const char *pc;
switch ( dragSource.DoDragDrop(TRUE) )
switch ( source.DoDragDrop(TRUE) )
{
case wxDragError: pc = "Error!"; break;
case wxDragNone: pc = "Nothing"; break;
@@ -429,7 +802,7 @@ void DnDFrame::OnRightDown(wxMouseEvent &event )
menu->Append(Menu_Quit, "E&xit");
menu->Append(Menu_ToBeDeleted, "To be deleted");
menu->Append(Menu_ToBeGreyed, "To be greyed");
menu->Delete( Menu_ToBeDeleted );
menu->Enable( Menu_ToBeGreyed, FALSE );
@@ -458,25 +831,25 @@ void DnDFrame::OnCopyBitmap(wxCommandEvent& WXUNUSED(event))
#endif
if (dialog.ShowModal() != wxID_OK)
{
{
wxLogMessage( _T("Aborted file open") );
return;
}
if (dialog.GetPath().IsEmpty())
{
{
wxLogMessage( _T("Returned empty string.") );
return;
}
if (!wxFileExists(dialog.GetPath()))
{
wxLogMessage( _T("File doesn't exist.") );
return;
}
wxImage image;
image.LoadFile( dialog.GetPath(),
image.LoadFile( dialog.GetPath(),
#ifdef __WXMSW__
wxBITMAP_TYPE_BMP
#else
@@ -485,13 +858,13 @@ void DnDFrame::OnCopyBitmap(wxCommandEvent& WXUNUSED(event))
);
if (!image.Ok())
{
wxLogMessage( _T("Invalid image file...") );
wxLogError( _T("Invalid image file...") );
return;
}
wxLogMessage( _T("Decoding image file...") );
wxLogStatus( _T("Decoding image file...") );
wxYield();
wxBitmap bitmap( image.ConvertToBitmap() );
if ( !wxTheClipboard->Open() )
@@ -503,7 +876,7 @@ void DnDFrame::OnCopyBitmap(wxCommandEvent& WXUNUSED(event))
wxLogMessage( _T("Creating wxBitmapDataObject...") );
wxYield();
if ( !wxTheClipboard->AddData(new wxBitmapDataObject(bitmap)) )
{
wxLogError(_T("Can't copy image to the clipboard."));
@@ -542,8 +915,8 @@ void DnDFrame::OnPasteBitmap(wxCommandEvent& WXUNUSED(event))
else
{
wxLogMessage(_T("Bitmap pasted from the clipboard") );
m_bitmap = data.GetBitmap();
Refresh();
m_bitmap = data.GetBitmap();
Refresh();
}
wxTheClipboard->Close();
@@ -628,3 +1001,251 @@ bool DnDFile::OnDropFiles( wxDropPointCoord, wxDropPointCoord, size_t nFiles,
return TRUE;
}
// ----------------------------------------------------------------------------
// DnDShapeDialog
// ----------------------------------------------------------------------------
DnDShapeDialog::DnDShapeDialog(wxFrame *parent, DnDShape *shape)
{
m_shape = shape;
LoadFromResource(parent, "dialogShape");
m_textX = (wxTextCtrl *)wxFindWindowByName("textX", this);
m_textY = (wxTextCtrl *)wxFindWindowByName("textY", this);
m_textW = (wxTextCtrl *)wxFindWindowByName("textW", this);
m_textH = (wxTextCtrl *)wxFindWindowByName("textH", this);
m_radio = (wxRadioBox *)wxFindWindowByName("radio", this);
}
DnDShape *DnDShapeDialog::GetShape() const
{
switch ( m_shapeKind )
{
default:
case DnDShape::None: return NULL;
case DnDShape::Triangle: return new DnDTriangularShape(m_pos, m_size, m_col);
case DnDShape::Rectangle: return new DnDRectangularShape(m_pos, m_size, m_col);
case DnDShape::Ellipse: return new DnDEllipticShape(m_pos, m_size, m_col);
}
}
bool DnDShapeDialog::TransferDataToWindow()
{
if ( m_shape )
{
m_radio->SetSelection(m_shape->GetKind());
m_pos = m_shape->GetPosition();
m_size = m_shape->GetSize();
m_col = m_shape->GetColour();
}
else
{
m_radio->SetSelection(DnDShape::None);
m_pos = wxPoint(1, 1);
m_size = wxSize(100, 100);
}
m_textX->SetValue(wxString() << m_pos.x);
m_textY->SetValue(wxString() << m_pos.y);
m_textW->SetValue(wxString() << m_size.x);
m_textH->SetValue(wxString() << m_size.y);
return TRUE;
}
bool DnDShapeDialog::TransferDataFromWindow()
{
m_shapeKind = (DnDShape::Kind)m_radio->GetSelection();
m_pos.x = atoi(m_textX->GetValue());
m_pos.y = atoi(m_textY->GetValue());
m_size.x = atoi(m_textW->GetValue());
m_size.y = atoi(m_textH->GetValue());
if ( !m_pos.x || !m_pos.y || !m_size.x || !m_size.y )
{
wxMessageBox("All sizes and positions should be non null!",
"Invalid shape", wxICON_HAND | wxOK, this);
return FALSE;
}
return TRUE;
}
void DnDShapeDialog::OnColour(wxCommandEvent& WXUNUSED(event))
{
wxColourData data;
data.SetChooseFull(TRUE);
for (int i = 0; i < 16; i++)
{
wxColour colour(i*16, i*16, i*16);
data.SetCustomColour(i, colour);
}
wxColourDialog dialog(this, &data);
if ( dialog.ShowModal() == wxID_OK )
{
m_col = dialog.GetColourData().GetColour();
}
}
// ----------------------------------------------------------------------------
// DnDShapeFrame
// ----------------------------------------------------------------------------
DnDShapeFrame::DnDShapeFrame(wxFrame *parent)
: wxFrame(parent, -1, "Shape Frame",
wxDefaultPosition, wxSize(250, 150))
{
SetBackgroundColour(*wxWHITE);
CreateStatusBar();
SetStatusText("Double click the frame to create a shape");
SetDropTarget(new DnDShapeDropTarget(this));
m_shape = NULL;
}
DnDShapeFrame::~DnDShapeFrame()
{
delete m_shape;
}
void DnDShapeFrame::SetShape(DnDShape *shape)
{
delete m_shape;
m_shape = shape;
Refresh();
}
// callbacks
void DnDShapeFrame::OnDrag(wxMouseEvent& event)
{
if ( !m_shape )
{
event.Skip();
return;
}
// start drag operation
DnDShapeDataObject shapeData(m_shape);
wxDropSource source(shapeData, this, wxICON(mondrian));
const char *pc = NULL;
switch ( source.DoDragDrop(TRUE) )
{
default:
case wxDragError:
wxLogError("An error occured during drag and drop operation");
break;
case wxDragNone:
SetStatusText("Nothing happened");
break;
case wxDragCopy:
pc = "copied";
break;
case wxDragMove:
pc = "moved";
SetShape(NULL);
break;
case wxDragCancel:
SetStatusText("Drag and drop operation cancelled");
break;
}
if ( pc )
{
SetStatusText(wxString("Shape successfully ") + pc);
}
//else: status text already set
}
void DnDShapeFrame::OnEdit(wxMouseEvent& event)
{
DnDShapeDialog dlg(this, m_shape);
if ( dlg.ShowModal() == wxID_OK )
{
SetShape(dlg.GetShape());
if ( m_shape )
{
SetStatusText("Right click now drag the shape to another frame");
}
}
}
void DnDShapeFrame::OnPaint(wxPaintEvent& event)
{
if ( m_shape )
m_shape->Draw(wxPaintDC(this));
else
event.Skip();
}
void DnDShapeFrame::OnDrop(long x, long y, DnDShape *shape)
{
wxString s;
s.Printf("Drop occured at (%ld, %ld)", x, y);
SetStatusText(s);
SetShape(shape);
}
// ----------------------------------------------------------------------------
// DnDShape
// ----------------------------------------------------------------------------
DnDShape *DnDShape::New(const void *buf)
{
const ShapeDump& dump = *(const ShapeDump *)buf;
switch ( dump.k )
{
case Triangle:
return new DnDTriangularShape(wxPoint(dump.x, dump.y),
wxSize(dump.w, dump.h),
wxColour(dump.r, dump.g, dump.b));
case Rectangle:
return new DnDRectangularShape(wxPoint(dump.x, dump.y),
wxSize(dump.w, dump.h),
wxColour(dump.r, dump.g, dump.b));
case Ellipse:
return new DnDEllipticShape(wxPoint(dump.x, dump.y),
wxSize(dump.w, dump.h),
wxColour(dump.r, dump.g, dump.b));
default:
wxFAIL_MSG("invalid shape!");
return NULL;
}
}
// ----------------------------------------------------------------------------
// DnDShapeDataObject
// ----------------------------------------------------------------------------
void DnDShapeDataObject::CreateBitmap() const
{
wxBitmap bitmap;
wxMemoryDC dc;
dc.SelectObject(bitmap);
m_shape->Draw(dc);
dc.SelectObject(wxNullBitmap);
DnDShapeDataObject *self = (DnDShapeDataObject *)this; // const_cast
self->m_dataobj.SetBitmap(bitmap);
self->m_hasBitmap = TRUE;
}