X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ff7c6c9c36b1501707625fea6c5acd3576cc54ca..14dd645ee16eb022afb19f35d0c8cfdf2d3cdee9:/samples/drawing/drawing.cpp?ds=sidebyside diff --git a/samples/drawing/drawing.cpp b/samples/drawing/drawing.cpp index 033c391e33..4903011b23 100644 --- a/samples/drawing/drawing.cpp +++ b/samples/drawing/drawing.cpp @@ -36,13 +36,14 @@ #endif #include "wx/colordlg.h" +#include "wx/image.h" // ---------------------------------------------------------------------------- // ressources // ---------------------------------------------------------------------------- // the application icon -#if defined(__WXGTK__) || defined(__WXMOTIF__) +#if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__) #include "mondrian.xpm" #endif @@ -58,19 +59,23 @@ enum ScreenToShow Show_Text, Show_Lines, Show_Polygons, - Show_Mask + Show_Mask, + Show_Ops, + Show_Regions, + Show_Circles }; // ---------------------------------------------------------------------------- // global variables // ---------------------------------------------------------------------------- -static wxBitmap gs_bmpNoMask, - gs_bmpWithColMask, - gs_bmpMask, - gs_bmpWithMask, - gs_bmp4, - gs_bmp36; +static wxBitmap *gs_bmpNoMask = NULL, + *gs_bmpWithColMask = NULL, + *gs_bmpMask = NULL, + *gs_bmpWithMask = NULL, + *gs_bmp4 = NULL, + *gs_bmp4_mono = NULL, + *gs_bmp36 = NULL; // ---------------------------------------------------------------------------- // private classes @@ -88,7 +93,11 @@ public: // return: if OnInit() returns false, the application terminates) virtual bool OnInit(); + virtual int OnExit() { DeleteBitmaps(); return 0; } + protected: + void DeleteBitmaps(); + bool LoadImages(); }; @@ -111,6 +120,7 @@ public: void PrepareDC(wxDC& dc); int m_backgroundMode; + int m_textureBackground; int m_mapMode; double m_xUserScale; double m_yUserScale; @@ -144,12 +154,19 @@ protected: void DrawTestLines( int x, int y, int width, wxDC &dc ); void DrawText(wxDC& dc); void DrawImages(wxDC& dc); + void DrawWithLogicalOps(wxDC& dc); + void DrawRegions(wxDC& dc); + void DrawCircles(wxDC& dc); void DrawDefault(wxDC& dc); + void DrawRegionsHelper(wxDC& dc, wxCoord x); + private: MyFrame *m_owner; ScreenToShow m_show; + wxBitmap m_smile_bmp; + wxIcon m_std_icon; DECLARE_EVENT_TABLE() }; @@ -171,7 +188,10 @@ enum File_ShowLines, File_ShowPolygons, File_ShowMask, - MenuShow_Last = File_ShowMask, + File_ShowOps, + File_ShowRegions, + File_ShowCircles, + MenuShow_Last = File_ShowCircles, MenuOption_First, @@ -199,8 +219,9 @@ enum Colour_TextBackground, Colour_Background, Colour_BackgroundMode, + Colour_TextureBackgound, - MenuOption_Last = Colour_BackgroundMode + MenuOption_Last = Colour_TextureBackgound }; // ---------------------------------------------------------------------------- @@ -225,6 +246,14 @@ IMPLEMENT_APP(MyApp) bool MyApp::LoadImages() { + gs_bmpNoMask = new wxBitmap; + gs_bmpWithColMask = new wxBitmap; + gs_bmpMask = new wxBitmap; + gs_bmpWithMask = new wxBitmap; + gs_bmp4 = new wxBitmap; + gs_bmp4_mono = new wxBitmap; + gs_bmp36 = new wxBitmap; + wxPathList pathList; pathList.Add("."); pathList.Add(".."); @@ -232,38 +261,38 @@ bool MyApp::LoadImages() wxString path = pathList.FindValidPath("pat4.bmp"); if ( !path ) return FALSE; - gs_bmp4.LoadFile(path, wxBITMAP_TYPE_BMP); - wxMask* mask4 = new wxMask(gs_bmp4, *wxBLACK); - gs_bmp4.SetMask(mask4); + + /* 4 colour bitmap */ + gs_bmp4->LoadFile(path, wxBITMAP_TYPE_BMP); + /* turn into mono-bitmap */ + gs_bmp4_mono->LoadFile(path, wxBITMAP_TYPE_BMP); + wxMask* mask4 = new wxMask(*gs_bmp4_mono, *wxBLACK); + gs_bmp4_mono->SetMask(mask4); path = pathList.FindValidPath("pat36.bmp"); if ( !path ) return FALSE; - gs_bmp36.LoadFile(path, wxBITMAP_TYPE_BMP); - wxMask* mask36 = new wxMask(gs_bmp36, *wxBLACK); - gs_bmp36.SetMask(mask36); + gs_bmp36->LoadFile(path, wxBITMAP_TYPE_BMP); + wxMask* mask36 = new wxMask(*gs_bmp36, *wxBLACK); + gs_bmp36->SetMask(mask36); path = pathList.FindValidPath("image.bmp"); if ( !path ) return FALSE; - gs_bmpNoMask.LoadFile(path, wxBITMAP_TYPE_BMP); - gs_bmpWithMask.LoadFile(path, wxBITMAP_TYPE_BMP); - gs_bmpWithColMask.LoadFile(path, wxBITMAP_TYPE_BMP); + gs_bmpNoMask->LoadFile(path, wxBITMAP_TYPE_BMP); + gs_bmpWithMask->LoadFile(path, wxBITMAP_TYPE_BMP); + gs_bmpWithColMask->LoadFile(path, wxBITMAP_TYPE_BMP); path = pathList.FindValidPath("mask.bmp"); if ( !path ) return FALSE; - gs_bmpMask.LoadFile(path, wxBITMAP_TYPE_BMP); - -// This is so wrong, it hurts. -// gs_bmpMask.SetDepth(1); -// wxMask *mask = new wxMask(gs_bmpMask); + gs_bmpMask->LoadFile(path, wxBITMAP_TYPE_BMP); - wxMask *mask = new wxMask(gs_bmpMask, *wxBLACK); - gs_bmpWithMask.SetMask(mask); + wxMask *mask = new wxMask(*gs_bmpMask, *wxBLACK); + gs_bmpWithMask->SetMask(mask); - mask = new wxMask(gs_bmpWithColMask, *wxWHITE); - gs_bmpWithColMask.SetMask(mask); + mask = new wxMask(*gs_bmpWithColMask, *wxWHITE); + gs_bmpWithColMask->SetMask(mask); return TRUE; } @@ -281,11 +310,13 @@ bool MyApp::OnInit() if ( !LoadImages() ) { - wxLogError("Can't load one of the bitmap files needed for this sample " - "from the current or parent directory, please copy them " - "there."); + wxLogError(wxT("Can't load one of the bitmap files needed ") + wxT("for this sample from the current or parent ") + wxT("directory, please copy them there.")); // stop here + DeleteBitmaps(); + return FALSE; } @@ -293,6 +324,17 @@ bool MyApp::OnInit() return TRUE; } +void MyApp::DeleteBitmaps() +{ + delete gs_bmpNoMask; + delete gs_bmpWithColMask; + delete gs_bmpMask; + delete gs_bmpWithMask; + delete gs_bmp4; + delete gs_bmp4_mono; + delete gs_bmp36; +} + // ---------------------------------------------------------------------------- // MyCanvas // ---------------------------------------------------------------------------- @@ -304,27 +346,35 @@ BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow) EVT_MOTION (MyCanvas::OnMouseMove) END_EVENT_TABLE() -MyCanvas::MyCanvas( MyFrame *parent ) : wxScrolledWindow( parent ) +#include "smile.xpm" + +MyCanvas::MyCanvas(MyFrame *parent) + : wxScrolledWindow(parent, -1, wxDefaultPosition, wxDefaultSize, + wxHSCROLL | wxVSCROLL | wxNO_FULL_REPAINT_ON_RESIZE) { m_owner = parent; m_show = Show_Default; + m_smile_bmp = wxBitmap(smile_xpm); + m_std_icon = wxTheApp->GetStdIcon(wxICON_INFORMATION); } -//draw a polygon and an overlapping rectangle -//is transparent is 1, the fill pattern are made transparent -//is transparent is 2, the fill pattern are made transparent but inversed -//is transparent is 0 the text for and background color will be used to represent/map -//the colors of the monochrome bitmap pixels to the fillpattern +// Draw a polygon and an overlapping rectangle +// If transparent is 1, the fill pattern is made transparent. +// If transparent is 2, the fill pattern is made transparent but inversed +// If is transparent is 0 the text for and background color will be used to represent/map +// the colors of the monochrome bitmap pixels to the fillpattern // -//i miss_used the the menu items for setting so called back and fore ground color -//just to show how the those colors do influence the fillpatterns -//just play with those, -//and with the code -//variations are endless using other logical functions +// I abused the the menu items for setting so called back and fore ground color +// just to show how the those colors do influence the fillpatterns just play +// with those, and with the code variations are endless using other logical +// functions. + void MyCanvas::DrawTestPoly( int x, int y,wxDC &dc,int transparent ) { - wxBrush* brush4 = new wxBrush(gs_bmp4); - wxBrush* brush36 = new wxBrush(gs_bmp36); +// wxBrush* brush4 = new wxBrush(*gs_bmp4); + wxBrush* brush4 = new wxBrush(*wxBLACK,wxFDIAGONAL_HATCH); + wxBrush* brush4_mono = new wxBrush(*gs_bmp4_mono); + wxBrush* brush36 = new wxBrush(*gs_bmp36); wxPoint todraw[5]; todraw[0].x=(long)x+100; @@ -354,20 +404,26 @@ void MyCanvas::DrawTestPoly( int x, int y,wxDC &dc,int transparent ) { case 0: { + dc.SetLogicalFunction(wxCOPY); + dc.SetPen( wxPen( "black", 4, wxSOLID) ); dc.SetBrush( *brush4 ); - dc.SetTextForeground(*wxGREEN); - dc.SetTextBackground(m_owner->m_colourForeground); - dc.SetLogicalFunction(wxCOPY); dc.DrawPolygon(5,todraw,0,0,wxWINDING_RULE); - //don't understand hwo but the outline is also depending on logicalfunction dc.SetPen( wxPen( "red", 4, wxSOLID) ); dc.SetBrush( *brush36 ); dc.SetTextForeground(*wxCYAN); dc.SetTextBackground(m_owner->m_colourBackground); - dc.SetLogicalFunction(wxCOPY); dc.DrawRectangle( x+10, y+10, 200, 200 ); + + dc.SetPen( wxPen( "green", 4, wxSOLID) ); + dc.SetBrush( *brush4_mono ); + dc.SetTextForeground(*wxCYAN); + dc.SetTextBackground(m_owner->m_colourBackground); + dc.DrawRectangle( x+50, y+50, 200, 200 ); + + dc.DrawCircle( x+400, y+50, 130 ); + dc.SetBrush(wxNullBrush); dc.SetPen(wxNullPen); break; @@ -508,6 +564,7 @@ void MyCanvas::DrawTestPoly( int x, int y,wxDC &dc,int transparent ) } delete brush4; + delete brush4_mono; delete brush36; } @@ -515,8 +572,10 @@ void MyCanvas::DrawTestLines( int x, int y, int width, wxDC &dc ) { dc.SetPen( wxPen( "black", width, wxSOLID) ); dc.SetBrush( *wxRED_BRUSH ); + dc.DrawText(wxString::Format(wxT("Testing lines of width %d"), width), x + 10, y - 10); dc.DrawRectangle( x+10, y+10, 100, 190 ); + dc.DrawText("Solid/dot/short dash/long dash/dot dash", x + 150, y + 10); dc.SetPen( wxPen( "black", width, wxSOLID) ); dc.DrawLine( x+20, y+20, 100, y+20 ); dc.SetPen( wxPen( "black", width, wxDOT) ); @@ -528,6 +587,7 @@ void MyCanvas::DrawTestLines( int x, int y, int width, wxDC &dc ) dc.SetPen( wxPen( "black", width, wxDOT_DASH) ); dc.DrawLine( x+20, y+60, 100, y+60 ); + dc.DrawText("Misc hatches", x + 150, y + 70); dc.SetPen( wxPen( "black", width, wxBDIAGONAL_HATCH) ); dc.DrawLine( x+20, y+70, 100, y+70 ); dc.SetPen( wxPen( "black", width, wxCROSSDIAG_HATCH) ); @@ -541,6 +601,7 @@ void MyCanvas::DrawTestLines( int x, int y, int width, wxDC &dc ) dc.SetPen( wxPen( "black", width, wxVERTICAL_HATCH) ); dc.DrawLine( x+20, y+120, 100, y+120 ); + dc.DrawText("User dash", x + 150, y + 140); wxPen ud( "black", width, wxUSER_DASH ); wxDash dash1[1]; dash1[0] = 0; @@ -552,67 +613,208 @@ void MyCanvas::DrawTestLines( int x, int y, int width, wxDC &dc ) dash1[0] = 2; ud.SetDashes( 1, dash1 ); dc.DrawLine( x+20, y+160, 100, y+160 ); - dash1[0] = 0xFF; + dash1[0] = 0x7F; ud.SetDashes( 1, dash1 ); dc.DrawLine( x+20, y+170, 100, y+170 ); - } void MyCanvas::DrawDefault(wxDC& dc) { // mark the origin dc.DrawCircle(0, 0, 10); -#if !(defined __WXGTK__) && !(defined __WXMOTIF__) +#if !(defined __WXGTK__) && !(defined __WXMOTIF__) && !(defined __WXMGL__) // not implemented in wxGTK or wxMOTIF :-( dc.FloodFill(0, 0, wxColour(255, 0, 0)); #endif // - dc.DrawIcon( wxICON(mondrian), 410, 40 ); + dc.DrawCheckMark(5, 80, 15, 15); + dc.DrawCheckMark(25, 80, 30, 30); + dc.DrawCheckMark(60, 80, 60, 60); - dc.SetBrush( *wxBLACK_BRUSH ); + // this is the test for "blitting bitmap into DC damages selected brush" bug + wxCoord rectSize = m_std_icon.GetWidth() + 10; + wxCoord x = 100; dc.SetPen(*wxTRANSPARENT_PEN); - dc.DrawRectangle( 0, 100, 1000, 300 ); + dc.SetBrush( *wxGREEN_BRUSH ); + dc.DrawRectangle(x, 10, rectSize, rectSize); + dc.DrawBitmap(m_std_icon, x + 5, 15, TRUE); + x += rectSize + 10; + dc.DrawRectangle(x, 10, rectSize, rectSize); + dc.DrawIcon(m_std_icon, x + 5, 15); + x += rectSize + 10; + dc.DrawRectangle(x, 10, rectSize, rectSize); + + // test for "transparent" bitmap drawing (it intersects with the last + // rectangle above) + //dc.SetBrush( *wxTRANSPARENT_BRUSH ); + + if (m_smile_bmp.Ok()) + dc.DrawBitmap(m_smile_bmp, x + rectSize - 20, rectSize - 10, TRUE); - // test the rectangle outline drawing - there should be one pixel between + dc.SetBrush( *wxBLACK_BRUSH ); + dc.DrawRectangle( 0, 160, 1000, 300 ); + + // draw lines + wxBitmap bitmap(20,70); + wxMemoryDC memdc; + memdc.SelectObject( bitmap ); + memdc.SetBrush( *wxBLACK_BRUSH ); + memdc.SetPen( *wxWHITE_PEN ); + memdc.DrawRectangle(0,0,20,70); + memdc.DrawLine( 10,0,10,70 ); + + // to the right + wxPen pen = *wxRED_PEN; + memdc.SetPen(pen); + memdc.DrawLine( 10, 5,10, 5 ); + memdc.DrawLine( 10,10,11,10 ); + memdc.DrawLine( 10,15,12,15 ); + memdc.DrawLine( 10,20,13,20 ); + +/* + memdc.SetPen(*wxRED_PEN); + memdc.DrawLine( 12, 5,12, 5 ); + memdc.DrawLine( 12,10,13,10 ); + memdc.DrawLine( 12,15,14,15 ); + memdc.DrawLine( 12,20,15,20 ); +*/ + + // same to the left + memdc.DrawLine( 10,25,10,25 ); + memdc.DrawLine( 10,30, 9,30 ); + memdc.DrawLine( 10,35, 8,35 ); + memdc.DrawLine( 10,40, 7,40 ); + + // XOR draw lines + dc.SetPen(*wxWHITE_PEN); + memdc.SetLogicalFunction( wxINVERT ); + memdc.SetPen( *wxWHITE_PEN ); + memdc.DrawLine( 10,50,10,50 ); + memdc.DrawLine( 10,55,11,55 ); + memdc.DrawLine( 10,60,12,60 ); + memdc.DrawLine( 10,65,13,65 ); + + memdc.DrawLine( 12,50,12,50 ); + memdc.DrawLine( 12,55,13,55 ); + memdc.DrawLine( 12,60,14,60 ); + memdc.DrawLine( 12,65,15,65 ); + + memdc.SelectObject( wxNullBitmap ); + dc.DrawBitmap( bitmap, 10, 170 ); + wxImage image( bitmap ); + image.Rescale( 60,210 ); + bitmap = image.ConvertToBitmap(); + dc.DrawBitmap( bitmap, 50, 170 ); + + // test the rectangle outline drawing - there should be one pixel between // the rect and the lines dc.SetPen(*wxWHITE_PEN); dc.SetBrush( *wxTRANSPARENT_BRUSH ); - dc.DrawRectangle(100, 170, 49, 29); dc.DrawRectangle(150, 170, 49, 29); + dc.DrawRectangle(200, 170, 49, 29); dc.SetPen(*wxWHITE_PEN); - dc.DrawLine(200, 160, 200, 210); - dc.DrawLine(100, 200, 210, 200); - - // test the rectangle filled drawing - there should be one pixel between + dc.DrawLine(250, 210, 250, 170); + dc.DrawLine(260, 200, 150, 200); + + // test the rectangle filled drawing - there should be one pixel between // the rect and the lines dc.SetPen(*wxTRANSPARENT_PEN); dc.SetBrush( *wxWHITE_BRUSH ); dc.DrawRectangle(300, 170, 49, 29); dc.DrawRectangle(350, 170, 49, 29); dc.SetPen(*wxWHITE_PEN); - dc.DrawLine(400, 160, 400, 210); - dc.DrawLine(300, 200, 410, 200); - - // test the rectangle outline drawing - there should be one pixel between + dc.DrawLine(400, 170, 400, 210); + dc.DrawLine(300, 200, 410, 200); + + // a few more tests of this kind + dc.SetPen(*wxRED_PEN); + dc.SetBrush( *wxWHITE_BRUSH ); + dc.DrawRectangle(300, 220, 1, 1); + dc.DrawRectangle(310, 220, 2, 2); + dc.DrawRectangle(320, 220, 3, 3); + dc.DrawRectangle(330, 220, 4, 4); + + dc.SetPen(*wxTRANSPARENT_PEN); + dc.SetBrush( *wxWHITE_BRUSH ); + dc.DrawRectangle(300, 230, 1, 1); + dc.DrawRectangle(310, 230, 2, 2); + dc.DrawRectangle(320, 230, 3, 3); + dc.DrawRectangle(330, 230, 4, 4); + + // and now for filled rect with outline + dc.SetPen(*wxRED_PEN); + dc.SetBrush( *wxWHITE_BRUSH ); + dc.DrawRectangle(500, 170, 49, 29); + dc.DrawRectangle(550, 170, 49, 29); + dc.SetPen(*wxWHITE_PEN); + dc.DrawLine(600, 170, 600, 210); + dc.DrawLine(500, 200, 610, 200); + + // test the rectangle outline drawing - there should be one pixel between // the rect and the lines dc.SetPen(*wxWHITE_PEN); dc.SetBrush( *wxTRANSPARENT_BRUSH ); - dc.DrawRoundedRectangle(100, 270, 49, 29, 6); dc.DrawRoundedRectangle(150, 270, 49, 29, 6); + dc.DrawRoundedRectangle(200, 270, 49, 29, 6); dc.SetPen(*wxWHITE_PEN); - dc.DrawLine(200, 260, 200, 310); - dc.DrawLine(100, 300, 210, 300); - - // test the rectangle filled drawing - there should be one pixel between + dc.DrawLine(250, 270, 250, 310); + dc.DrawLine(150, 300, 260, 300); + + // test the rectangle filled drawing - there should be one pixel between // the rect and the lines dc.SetPen(*wxTRANSPARENT_PEN); dc.SetBrush( *wxWHITE_BRUSH ); dc.DrawRoundedRectangle(300, 270, 49, 29, 6); dc.DrawRoundedRectangle(350, 270, 49, 29, 6); dc.SetPen(*wxWHITE_PEN); - dc.DrawLine(400, 260, 400, 310); - dc.DrawLine(300, 300, 410, 300); + dc.DrawLine(400, 270, 400, 310); + dc.DrawLine(300, 300, 410, 300); + + // Added by JACS to demonstrate bizarre behaviour. + // With a size of 70, we get a missing red RHS, + // and the hight is too small, so we get yellow + // showing. With a size of 40, it draws as expected: + // it just shows a white rectangle with red outline. + int totalWidth = 70; + int totalHeight = 70; + wxBitmap bitmap2(totalWidth, totalHeight); + + wxMemoryDC memdc2; + memdc2.SelectObject(bitmap2); + + wxBrush yellowBrush(wxColour(255, 255, 0), wxSOLID); + memdc2.SetBackground(yellowBrush); + memdc2.Clear(); + + wxPen yellowPen(wxColour(255, 255, 0), 1, wxSOLID); + + // Now draw a white rectangle with red outline. It should + // entirely eclipse the yellow background. + memdc2.SetPen(*wxRED_PEN); + memdc2.SetBrush(*wxWHITE_BRUSH); + memdc2.DrawRectangle(0, 0, totalWidth, totalHeight); + + memdc2.SetPen(wxNullPen); + memdc2.SetBrush(wxNullBrush); + memdc2.SelectObject(wxNullBitmap); + + dc.DrawBitmap(bitmap2, 500, 270); + + // Repeat, but draw directly on dc + // Draw a yellow rectangle filling the bitmap + + x = 600; int y = 270; + dc.SetPen(yellowPen); + dc.SetBrush(yellowBrush); + dc.DrawRectangle(x, y, totalWidth, totalHeight); + + // Now draw a white rectangle with red outline. It should + // entirely eclipse the yellow background. + dc.SetPen(*wxRED_PEN); + dc.SetBrush(*wxWHITE_BRUSH); + + dc.DrawRectangle(x, y, totalWidth, totalHeight); } void MyCanvas::DrawText(wxDC& dc) @@ -622,14 +824,16 @@ void MyCanvas::DrawText(wxDC& dc) dc.DrawText( "This is text", 110, 10 ); dc.DrawRotatedText( "That is text", 20, 10, -45 ); - dc.SetFont( *wxNORMAL_FONT ); + // use wxSWISS_FONT and not wxNORMAL_FONT as the latter can't be rotated + // under Win9x (it is not TrueType) + dc.SetFont( *wxSWISS_FONT ); wxString text; - dc. SetBackgroundMode(wxTRANSPARENT); + dc.SetBackgroundMode(wxTRANSPARENT); for ( int n = -180; n < 180; n += 30 ) { - text.Printf(" %d rotated text", n); + text.Printf(wxT(" %d rotated text"), n); dc.DrawRotatedText(text , 400, 400, n); } @@ -641,51 +845,69 @@ void MyCanvas::DrawText(wxDC& dc) long height; long descent; dc.GetTextExtent( "This is Swiss 18pt text.", &length, &height, &descent ); - text.Printf( "Dimensions are length %ld, height %ld, descent %ld", length, height, descent ); + text.Printf( wxT("Dimensions are length %ld, height %ld, descent %ld"), length, height, descent ); dc.DrawText( text, 110, 80 ); - text.Printf( "CharHeight() returns: %d", dc.GetCharHeight() ); + text.Printf( wxT("CharHeight() returns: %d"), dc.GetCharHeight() ); dc.DrawText( text, 110, 120 ); dc.DrawRectangle( 100, 40, 4, height ); + + // test the logical function effect + wxCoord y = 150; + dc.SetLogicalFunction(wxINVERT); + dc.DrawText( "There should be no text below", 110, 150 ); + dc.DrawRectangle( 110, y, 100, height ); + + // twice drawn inverted should result in invisible + y += height; + dc.DrawText( "Invisible text", 110, y ); + dc.DrawRectangle( 110, y, 100, height ); + dc.DrawText( "Invisible text", 110, y ); + dc.DrawRectangle( 110, y, 100, height ); + dc.SetLogicalFunction(wxCOPY); + + y += height; + dc.DrawRectangle( 110, y, 100, height ); + dc.DrawText( "Visible text", 110, y ); } -void MyCanvas::DrawImages(wxDC& dc) +static const struct { - static const struct - { - const wxChar *name; - int rop; - } rasterOperations[] = - { - { "wxAND", wxAND }, - { "wxAND_INVERT", wxAND_INVERT }, - { "wxAND_REVERSE", wxAND_REVERSE }, - { "wxCLEAR", wxCLEAR }, - { "wxCOPY", wxCOPY }, - { "wxEQUIV", wxEQUIV }, - { "wxINVERT", wxINVERT }, - { "wxNAND", wxNAND }, - { "wxNO_OP", wxNO_OP }, - { "wxOR", wxOR }, - { "wxOR_INVERT", wxOR_INVERT }, - { "wxOR_REVERSE", wxOR_REVERSE }, - { "wxSET", wxSET }, - { "wxSRC_INVERT", wxSRC_INVERT }, - { "wxXOR", wxXOR }, - }; + const wxChar *name; + int rop; +} rasterOperations[] = +{ + { wxT("wxAND"), wxAND }, + { wxT("wxAND_INVERT"), wxAND_INVERT }, + { wxT("wxAND_REVERSE"), wxAND_REVERSE }, + { wxT("wxCLEAR"), wxCLEAR }, + { wxT("wxCOPY"), wxCOPY }, + { wxT("wxEQUIV"), wxEQUIV }, + { wxT("wxINVERT"), wxINVERT }, + { wxT("wxNAND"), wxNAND }, + { wxT("wxNO_OP"), wxNO_OP }, + { wxT("wxOR"), wxOR }, + { wxT("wxOR_INVERT"), wxOR_INVERT }, + { wxT("wxOR_REVERSE"), wxOR_REVERSE }, + { wxT("wxSET"), wxSET }, + { wxT("wxSRC_INVERT"), wxSRC_INVERT }, + { wxT("wxXOR"), wxXOR }, +}; +void MyCanvas::DrawImages(wxDC& dc) +{ dc.DrawText("original image", 0, 0); - dc.DrawBitmap(gs_bmpNoMask, 0, 20, 0); + dc.DrawBitmap(*gs_bmpNoMask, 0, 20, 0); dc.DrawText("with colour mask", 0, 100); - dc.DrawBitmap(gs_bmpWithColMask, 0, 120, TRUE); + dc.DrawBitmap(*gs_bmpWithColMask, 0, 120, TRUE); dc.DrawText("the mask image", 0, 200); - dc.DrawBitmap(gs_bmpMask, 0, 220, 0); + dc.DrawBitmap(*gs_bmpMask, 0, 220, 0); dc.DrawText("masked image", 0, 300); - dc.DrawBitmap(gs_bmpWithMask, 0, 320, TRUE); + dc.DrawBitmap(*gs_bmpWithMask, 0, 320, TRUE); - int cx = gs_bmpWithColMask.GetWidth(), - cy = gs_bmpWithColMask.GetHeight(); + int cx = gs_bmpWithColMask->GetWidth(), + cy = gs_bmpWithColMask->GetHeight(); wxMemoryDC memDC; for ( size_t n = 0; n < WXSIZEOF(rasterOperations); n++ ) @@ -694,15 +916,133 @@ void MyCanvas::DrawImages(wxDC& dc) y = 20 + 100*(n/4); dc.DrawText(rasterOperations[n].name, x, y - 20); - memDC.SelectObject(gs_bmpWithColMask); + memDC.SelectObject(*gs_bmpWithColMask); dc.Blit(x, y, cx, cy, &memDC, 0, 0, rasterOperations[n].rop, TRUE); } } +void MyCanvas::DrawWithLogicalOps(wxDC& dc) +{ + static const wxCoord w = 60; + static const wxCoord h = 60; + + // reuse the text colour here + dc.SetPen(wxPen(m_owner->m_colourForeground, 1, wxSOLID)); + dc.SetBrush(*wxTRANSPARENT_BRUSH); + + size_t n; + for ( n = 0; n < WXSIZEOF(rasterOperations); n++ ) + { + wxCoord x = 20 + 150*(n%4), + y = 20 + 100*(n/4); + + dc.DrawText(rasterOperations[n].name, x, y - 20); + dc.SetLogicalFunction(rasterOperations[n].rop); + dc.DrawRectangle(x, y, w, h); + dc.DrawLine(x, y, x + w, y + h); + dc.DrawLine(x + w, y, x, y + h); + } + + // now some filled rectangles + dc.SetBrush(wxBrush(m_owner->m_colourForeground, wxSOLID)); + + for ( n = 0; n < WXSIZEOF(rasterOperations); n++ ) + { + wxCoord x = 20 + 150*(n%4), + y = 500 + 100*(n/4); + + dc.DrawText(rasterOperations[n].name, x, y - 20); + dc.SetLogicalFunction(rasterOperations[n].rop); + dc.DrawRectangle(x, y, w, h); + } +} + +void MyCanvas::DrawCircles(wxDC& dc) +{ + int x = 100, + y = 100, + r = 20; + + dc.DrawText("Some circles", 0, y); + dc.DrawCircle(x, y, r); + dc.DrawCircle(x + 2*r, y, r); + dc.DrawCircle(x + 4*r, y, r); + + y += 2*r; + dc.DrawText("And ellipses", 0, y); + dc.DrawEllipse(x - r, y, 2*r, r); + dc.DrawEllipse(x + r, y, 2*r, r); + dc.DrawEllipse(x + 3*r, y, 2*r, r); + + y += 2*r; + dc.DrawText("And arcs", 0, y); + dc.DrawArc(x - r, y, x + r, y, x, y); + dc.DrawArc(x + 4*r, y, x + 2*r, y, x + 3*r, y); + dc.DrawArc(x + 5*r, y, x + 5*r, y, x + 6*r, y); + + y += 2*r; + dc.DrawEllipticArc(x - r, y, 2*r, r, 0, 90); + dc.DrawEllipticArc(x + r, y, 2*r, r, 90, 180); + dc.DrawEllipticArc(x + 3*r, y, 2*r, r, 180, 270); + dc.DrawEllipticArc(x + 5*r, y, 2*r, r, 270, 360); +} + +void MyCanvas::DrawRegions(wxDC& dc) +{ + dc.DrawText("You should see a red rect partly covered by a cyan one " + "on the left", 10, 5); + dc.DrawText("and 5 smileys from which 4 are partially clipped on the " + "right (2 copies should be identical)", + 10, 5 + dc.GetCharHeight()); + + DrawRegionsHelper(dc, 10); + DrawRegionsHelper(dc, 350); +} + +void MyCanvas::DrawRegionsHelper(wxDC& dc, wxCoord x) +{ + dc.DestroyClippingRegion(); + dc.SetBrush( *wxWHITE_BRUSH ); + dc.SetPen( *wxTRANSPARENT_PEN ); + dc.DrawRectangle( x,50,310,310 ); + + dc.SetClippingRegion( x+10,60,100,270 ); + + dc.SetBrush( *wxRED_BRUSH ); + dc.DrawRectangle( x,50,310,310 ); + + dc.SetClippingRegion( x+10,60,100,100 ); + + dc.SetBrush( *wxCYAN_BRUSH ); + dc.DrawRectangle( x,50,310,310 ); + + // when drawing the left half, destroy the clipping region, when drawing + // the right one - leave it + // + // normally it shouldn't make any difference as SetClippingRegion() + // replaces the old clipping region + if ( x < 300 ) + dc.DestroyClippingRegion(); + dc.SetClippingRegion( x+110,70,100,270 ); + + dc.SetBrush( *wxGREY_BRUSH ); + dc.DrawRectangle( x,50,310,310 ); + + if (m_smile_bmp.Ok()) + { + dc.DrawBitmap( m_smile_bmp, x+150, 200, TRUE ); + dc.DrawBitmap( m_smile_bmp, x+130, 60, TRUE ); + dc.DrawBitmap( m_smile_bmp, x+130, 330, TRUE ); + dc.DrawBitmap( m_smile_bmp, x+100, 120, TRUE ); + dc.DrawBitmap( m_smile_bmp, x+200, 120, TRUE ); + } +} + void MyCanvas::OnPaint(wxPaintEvent &WXUNUSED(event)) { wxPaintDC dc(this); PrepareDC(dc); + m_owner->PrepareDC(dc); dc.SetBackgroundMode( m_owner->m_backgroundMode ); @@ -713,32 +1053,68 @@ void MyCanvas::OnPaint(wxPaintEvent &WXUNUSED(event)) if ( m_owner->m_colourBackground.Ok() ) dc.SetTextBackground( m_owner->m_colourBackground ); + if ( m_owner->m_textureBackground) { + if ( ! m_owner->m_backgroundBrush.Ok() ) { + wxBrush b(wxColour(0,128,0), wxSOLID); + dc.SetBackground(b); + } + } + + dc.Clear(); + + if ( m_owner->m_textureBackground) { + dc.SetPen(*wxMEDIUM_GREY_PEN); + for (int i=0; i<200; i++) + dc.DrawLine(0, i*10, i*10, 0); + } + switch ( m_show ) { case Show_Default: DrawDefault(dc); break; + case Show_Circles: + DrawCircles(dc); + break; + + case Show_Regions: + DrawRegions(dc); + break; + case Show_Text: DrawText(dc); break; case Show_Lines: DrawTestLines( 0, 100, 0, dc ); - DrawTestLines( 0, 300, 1, dc ); - DrawTestLines( 0, 500, 2, dc ); - DrawTestLines( 0, 700, 6, dc ); + DrawTestLines( 0, 320, 1, dc ); + DrawTestLines( 0, 540, 2, dc ); + DrawTestLines( 0, 760, 6, dc ); break; case Show_Polygons: DrawTestPoly( 0, 100, dc, 0 ); +/* DrawTestPoly( 33, 500, dc, 1 ); DrawTestPoly( 43, 1000, dc, 2 ); +*/ break; case Show_Mask: DrawImages(dc); break; + + case Show_Ops: + DrawWithLogicalOps(dc); + break; + + default: + { + dc.SetPen( *wxBLACK_PEN ); + dc.DrawLine( 0,0,100,100 ); + } + } } @@ -752,7 +1128,7 @@ void MyCanvas::OnMouseMove(wxMouseEvent &event) long x = dc.DeviceToLogicalX( pos.x ); long y = dc.DeviceToLogicalY( pos.y ); wxString str; - str.Printf( "Current mouse position: %d,%d", (int)x, (int)y ); + str.Printf( wxT("Current mouse position: %d,%d"), (int)x, (int)y ); m_owner->SetStatusText( str ); } @@ -774,7 +1150,8 @@ END_EVENT_TABLE() // frame constructor MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) - : wxFrame((wxFrame *)NULL, -1, title, pos, size) + : wxFrame((wxFrame *)NULL, -1, title, pos, size, + wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE) { // set the frame icon SetIcon(wxICON(mondrian)); @@ -785,6 +1162,9 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) menuFile->Append(File_ShowLines, "&Lines screen\tF3"); menuFile->Append(File_ShowPolygons, "&Polygons screen\tF4"); menuFile->Append(File_ShowMask, "wx&Mask screen\tF5"); + menuFile->Append(File_ShowOps, "&ROP screen\tF6"); + menuFile->Append(File_ShowRegions, "Re&gions screen\tF7"); + menuFile->Append(File_ShowCircles, "&Circles screen\tF8"); menuFile->AppendSeparator(); menuFile->Append(File_About, "&About...\tCtrl-A", "Show about dialog"); menuFile->AppendSeparator(); @@ -820,6 +1200,7 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) menuColour->Append( Colour_TextBackground, "Text background..." ); menuColour->Append( Colour_Background, "Background colour..." ); menuColour->Append( Colour_BackgroundMode, "Opaque/transparent\tCtrl-B", "", TRUE ); + menuColour->Append( Colour_TextureBackgound, "Draw textured background\tCtrl-T", "", TRUE); // now append the freshly created menu to the menu bar... wxMenuBar *menuBar = new wxMenuBar; @@ -847,6 +1228,7 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) m_backgroundMode = wxSOLID; m_colourForeground = *wxRED; m_colourBackground = *wxBLUE; + m_textureBackground = FALSE; m_canvas = new MyCanvas( this ); m_canvas->SetScrollbars( 10, 10, 100, 240 ); @@ -863,8 +1245,10 @@ void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) { wxString msg; - msg.Printf( _T("This is the about dialog of the drawing sample.\n") - _T("Copyright (c) Robert Roebling 1999") + msg.Printf( wxT("This is the about dialog of the drawing sample.\n") + wxT("This sample tests various primitive drawing functions\n") + wxT("without any tests to prevent flicker.\n") + wxT("Copyright (c) Robert Roebling 1999") ); wxMessageBox(msg, "About Drawing", wxOK | wxICON_INFORMATION, this); @@ -872,12 +1256,12 @@ void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) void MyFrame::OnShow(wxCommandEvent& event) { - m_canvas->Show((ScreenToShow)(event.GetInt() - MenuShow_First)); + m_canvas->Show((ScreenToShow)(event.GetId() - MenuShow_First)); } void MyFrame::OnOption(wxCommandEvent& event) { - switch (event.GetInt()) + switch (event.GetId()) { case MapMode_Text: m_mapMode = wxMM_TEXT; @@ -952,6 +1336,10 @@ void MyFrame::OnOption(wxCommandEvent& event) : wxSOLID; break; + case Colour_TextureBackgound: + m_textureBackground = ! m_textureBackground; + break; + default: // skip Refresh() return;