1///////////////////////////////////////////////////////////////////////////// 2// Name: samples/drawing/drawing.cpp 3// Purpose: shows and tests wxDC features 4// Author: Robert Roebling 5// Modified by: 6// Created: 04/01/98 7// RCS-ID: $Id: drawing.cpp 43408 2006-11-14 12:12:42Z VZ $ 8// Copyright: (c) Robert Roebling 9// Licence: wxWindows licence 10///////////////////////////////////////////////////////////////////////////// 11 12// ============================================================================ 13// declarations 14// ============================================================================ 15 16// ---------------------------------------------------------------------------- 17// headers 18// ---------------------------------------------------------------------------- 19 20// For compilers that support precompilation, includes "wx/wx.h". 21#include "wx/wxprec.h" 22 23#ifdef __BORLANDC__ 24 #pragma hdrstop 25#endif 26 27// for all others, include the necessary headers (this file is usually all you 28// need because it includes almost all "standard" wxWidgets headers 29#ifndef WX_PRECOMP 30 #include "wx/wx.h" 31#endif 32 33#include "wx/colordlg.h" 34#include "wx/image.h" 35#include "wx/artprov.h" 36 37#define wxTEST_GRAPHICS 1 38 39#if wxTEST_GRAPHICS 40#include "wx/graphics.h" 41#if wxUSE_GRAPHICS_CONTEXT == 0 42#undef wxTEST_GRAPHICS 43#define wxTEST_GRAPHICS 0 44#endif 45#else 46#undef wxUSE_GRAPHICS_CONTEXT 47#define wxUSE_GRAPHICS_CONTEXT 0 48#endif 49 50// ---------------------------------------------------------------------------- 51// ressources 52// ---------------------------------------------------------------------------- 53 54// the application icon 55#if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__) || defined(__WXMGL__) || defined(__WXX11__) 56 #include "mondrian.xpm" 57#endif 58 59// ---------------------------------------------------------------------------- 60// constants 61// ---------------------------------------------------------------------------- 62 63// what do we show on screen (there are too many shapes to put them all on 64// screen simultaneously) 65enum ScreenToShow 66{ 67 Show_Default, 68 Show_Text, 69 Show_Lines, 70 Show_Brushes, 71 Show_Polygons, 72 Show_Mask, 73 Show_Ops, 74 Show_Regions, 75 Show_Circles, 76 Show_Splines, 77#if wxUSE_GRAPHICS_CONTEXT 78 Show_Alpha, 79#endif 80 Show_Gradient, 81 Show_Max 82}; 83 84// ---------------------------------------------------------------------------- 85// global variables 86// ---------------------------------------------------------------------------- 87 88static wxBitmap *gs_bmpNoMask = NULL, 89 *gs_bmpWithColMask = NULL, 90 *gs_bmpMask = NULL, 91 *gs_bmpWithMask = NULL, 92 *gs_bmp4 = NULL, 93 *gs_bmp4_mono = NULL, 94 *gs_bmp36 = NULL; 95 96// ---------------------------------------------------------------------------- 97// private classes 98// ---------------------------------------------------------------------------- 99 100// Define a new application type, each program should derive a class from wxApp 101class MyApp : public wxApp 102{ 103public: 104 // override base class virtuals 105 // ---------------------------- 106 107 // this one is called on application startup and is a good place for the app 108 // initialization (doing it here and not in the ctor allows to have an error 109 // return: if OnInit() returns false, the application terminates) 110 virtual bool OnInit(); 111 112 virtual int OnExit() { DeleteBitmaps(); return 0; } 113 114protected: 115 void DeleteBitmaps(); 116 117 bool LoadImages(); 118}; 119 120class MyCanvas; 121 122// Define a new frame type: this is going to be our main frame 123class MyFrame : public wxFrame 124{ 125public: 126 // ctor(s) 127 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size); 128 129 // event handlers (these functions should _not_ be virtual) 130 void OnQuit(wxCommandEvent& event); 131 void OnAbout(wxCommandEvent& event); 132 void OnClip(wxCommandEvent& event); 133#if wxUSE_GRAPHICS_CONTEXT 134 void OnGraphicContext(wxCommandEvent& event); 135#endif 136 void OnShow(wxCommandEvent &event); 137 void OnOption(wxCommandEvent &event); 138 139#if wxUSE_COLOURDLG 140 wxColour SelectColour(); 141#endif // wxUSE_COLOURDLG 142 void PrepareDC(wxDC& dc); 143 144 int m_backgroundMode; 145 int m_textureBackground; 146 int m_mapMode; 147 double m_xUserScale; 148 double m_yUserScale; 149 int m_xLogicalOrigin; 150 int m_yLogicalOrigin; 151 bool m_xAxisReversed, 152 m_yAxisReversed; 153 wxColour m_colourForeground, // these are _text_ colours 154 m_colourBackground; 155 wxBrush m_backgroundBrush; 156 MyCanvas *m_canvas; 157 158private: 159 // any class wishing to process wxWidgets events must use this macro 160 DECLARE_EVENT_TABLE() 161}; 162 163// define a scrollable canvas for drawing onto 164class MyCanvas: public wxScrolledWindow 165{ 166public: 167 MyCanvas( MyFrame *parent ); 168 169 void OnPaint(wxPaintEvent &event); 170 void OnMouseMove(wxMouseEvent &event); 171 172 void ToShow(ScreenToShow show) { m_show = show; Refresh(); } 173 174 // set or remove the clipping region 175 void Clip(bool clip) { m_clip = clip; Refresh(); } 176#if wxUSE_GRAPHICS_CONTEXT 177 void UseGraphicContext(bool use) { m_useContext = use; Refresh(); } 178#endif 179 180protected: 181 void DrawTestLines( int x, int y, int width, wxDC &dc ); 182 void DrawTestPoly(wxDC& dc); 183 void DrawTestBrushes(wxDC& dc); 184 void DrawText(wxDC& dc); 185 void DrawImages(wxDC& dc); 186 void DrawWithLogicalOps(wxDC& dc); 187#if wxUSE_GRAPHICS_CONTEXT 188 void DrawAlpha(wxDC& dc); 189#endif 190 void DrawRegions(wxDC& dc); 191 void DrawCircles(wxDC& dc); 192 void DrawSplines(wxDC& dc); 193 void DrawDefault(wxDC& dc); 194 void DrawGradients(wxDC& dc); 195 196 void DrawRegionsHelper(wxDC& dc, wxCoord x, bool firstTime); 197 198private: 199 MyFrame *m_owner; 200 201 ScreenToShow m_show; 202 wxBitmap m_smile_bmp; 203 wxIcon m_std_icon; 204 bool m_clip; 205#if wxUSE_GRAPHICS_CONTEXT 206 bool m_useContext ; 207#endif 208 209 DECLARE_EVENT_TABLE() 210}; 211 212// ---------------------------------------------------------------------------- 213// constants 214// ---------------------------------------------------------------------------- 215 216// IDs for the controls and the menu commands 217enum 218{ 219 // menu items 220 File_Quit = wxID_EXIT, 221 File_About = wxID_ABOUT, 222 223 MenuShow_First = wxID_HIGHEST, 224 File_ShowDefault = MenuShow_First, 225 File_ShowText, 226 File_ShowLines, 227 File_ShowBrushes, 228 File_ShowPolygons, 229 File_ShowMask, 230 File_ShowOps, 231 File_ShowRegions, 232 File_ShowCircles, 233 File_ShowSplines, 234#if wxUSE_GRAPHICS_CONTEXT 235 File_ShowAlpha, 236#endif 237 File_ShowGradients, 238 MenuShow_Last = File_ShowGradients, 239 240 File_Clip, 241#if wxUSE_GRAPHICS_CONTEXT 242 File_GraphicContext, 243#endif 244 245 MenuOption_First, 246 247 MapMode_Text = MenuOption_First, 248 MapMode_Lometric, 249 MapMode_Twips, 250 MapMode_Points, 251 MapMode_Metric, 252 253 UserScale_StretchHoriz, 254 UserScale_ShrinkHoriz, 255 UserScale_StretchVertic, 256 UserScale_ShrinkVertic, 257 UserScale_Restore, 258 259 AxisMirror_Horiz, 260 AxisMirror_Vertic, 261 262 LogicalOrigin_MoveDown, 263 LogicalOrigin_MoveUp, 264 LogicalOrigin_MoveLeft, 265 LogicalOrigin_MoveRight, 266 LogicalOrigin_Set, 267 LogicalOrigin_Restore, 268 269#if wxUSE_COLOURDLG 270 Colour_TextForeground, 271 Colour_TextBackground, 272 Colour_Background, 273#endif // wxUSE_COLOURDLG 274 Colour_BackgroundMode, 275 Colour_TextureBackgound, 276 277 MenuOption_Last = Colour_TextureBackgound 278}; 279 280// ---------------------------------------------------------------------------- 281// event tables and other macros for wxWidgets 282// ---------------------------------------------------------------------------- 283 284 285// Create a new application object: this macro will allow wxWidgets to create 286// the application object during program execution (it's better than using a 287// static object for many reasons) and also declares the accessor function 288// wxGetApp() which will return the reference of the right type (i.e. MyApp and 289// not wxApp) 290IMPLEMENT_APP(MyApp) 291 292// ============================================================================ 293// implementation 294// ============================================================================ 295 296// ---------------------------------------------------------------------------- 297// the application class 298// ---------------------------------------------------------------------------- 299 300bool MyApp::LoadImages() 301{ 302 gs_bmpNoMask = new wxBitmap; 303 gs_bmpWithColMask = new wxBitmap; 304 gs_bmpMask = new wxBitmap; 305 gs_bmpWithMask = new wxBitmap; 306 gs_bmp4 = new wxBitmap; 307 gs_bmp4_mono = new wxBitmap; 308 gs_bmp36 = new wxBitmap; 309 310 wxPathList pathList; 311 pathList.Add(_T(".")); 312 pathList.Add(_T("..")); 313 314 wxString path = pathList.FindValidPath(_T("pat4.bmp")); 315 if ( !path ) 316 return false; 317 318 /* 4 colour bitmap */ 319 gs_bmp4->LoadFile(path, wxBITMAP_TYPE_BMP); 320 /* turn into mono-bitmap */ 321 gs_bmp4_mono->LoadFile(path, wxBITMAP_TYPE_BMP); 322 wxMask* mask4 = new wxMask(*gs_bmp4_mono, *wxBLACK); 323 gs_bmp4_mono->SetMask(mask4); 324 325 path = pathList.FindValidPath(_T("pat36.bmp")); 326 if ( !path ) 327 return false; 328 gs_bmp36->LoadFile(path, wxBITMAP_TYPE_BMP); 329 wxMask* mask36 = new wxMask(*gs_bmp36, *wxBLACK); 330 gs_bmp36->SetMask(mask36); 331 332 path = pathList.FindValidPath(_T("image.bmp")); 333 if ( !path ) 334 return false; 335 gs_bmpNoMask->LoadFile(path, wxBITMAP_TYPE_BMP); 336 gs_bmpWithMask->LoadFile(path, wxBITMAP_TYPE_BMP); 337 gs_bmpWithColMask->LoadFile(path, wxBITMAP_TYPE_BMP); 338 339 path = pathList.FindValidPath(_T("mask.bmp")); 340 if ( !path ) 341 return false; 342 gs_bmpMask->LoadFile(path, wxBITMAP_TYPE_BMP); 343 344 wxMask *mask = new wxMask(*gs_bmpMask, *wxBLACK); 345 gs_bmpWithMask->SetMask(mask); 346 347 mask = new wxMask(*gs_bmpWithColMask, *wxWHITE); 348 gs_bmpWithColMask->SetMask(mask); 349 350 return true; 351} 352 353// `Main program' equivalent: the program execution "starts" here 354bool MyApp::OnInit() 355{ 356 // Create the main application window 357 MyFrame *frame = new MyFrame(_T("Drawing sample"), 358 wxPoint(50, 50), wxSize(550, 340)); 359 360 // Show it and tell the application that it's our main window 361 frame->Show(true); 362 SetTopWindow(frame); 363 364 if ( !LoadImages() ) 365 { 366 wxLogError(wxT("Can't load one of the bitmap files needed ") 367 wxT("for this sample from the current or parent ") 368 wxT("directory, please copy them there.")); 369 370 // stop here 371 DeleteBitmaps(); 372 373 return false; 374 } 375 376 // ok, continue 377 return true; 378} 379 380void MyApp::DeleteBitmaps() 381{ 382 delete gs_bmpNoMask; 383 delete gs_bmpWithColMask; 384 delete gs_bmpMask; 385 delete gs_bmpWithMask; 386 delete gs_bmp4; 387 delete gs_bmp4_mono; 388 delete gs_bmp36; 389 390 gs_bmpNoMask = NULL; 391 gs_bmpWithColMask = NULL; 392 gs_bmpMask = NULL; 393 gs_bmpWithMask = NULL; 394 gs_bmp4 = NULL; 395 gs_bmp4_mono = NULL; 396 gs_bmp36 = NULL; 397} 398 399// ---------------------------------------------------------------------------- 400// MyCanvas 401// ---------------------------------------------------------------------------- 402 403// the event tables connect the wxWidgets events with the functions (event 404// handlers) which process them. 405BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow) 406 EVT_PAINT (MyCanvas::OnPaint) 407 EVT_MOTION (MyCanvas::OnMouseMove) 408END_EVENT_TABLE() 409 410#include "smile.xpm" 411 412MyCanvas::MyCanvas(MyFrame *parent) 413 : wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 414 wxHSCROLL | wxVSCROLL | wxNO_FULL_REPAINT_ON_RESIZE) 415{ 416 m_owner = parent; 417 m_show = Show_Default; 418 m_smile_bmp = wxBitmap(smile_xpm); 419 m_std_icon = wxArtProvider::GetIcon(wxART_INFORMATION); 420 m_clip = false; 421#if wxUSE_GRAPHICS_CONTEXT 422 m_useContext = false; 423#endif 424} 425 426void MyCanvas::DrawTestBrushes(wxDC& dc) 427{ 428 static const wxCoord WIDTH = 200; 429 static const wxCoord HEIGHT = 80; 430 431 wxCoord x = 10, 432 y = 10; 433 434 dc.SetBrush(wxBrush(*wxGREEN, wxSOLID)); 435 dc.DrawRectangle(x, y, WIDTH, HEIGHT); 436 dc.DrawText(_T("Solid green"), x + 10, y + 10); 437 438 y += HEIGHT; 439 dc.SetBrush(wxBrush(*wxRED, wxCROSSDIAG_HATCH)); 440 dc.DrawRectangle(x, y, WIDTH, HEIGHT); 441 dc.DrawText(_T("Hatched red"), x + 10, y + 10); 442 443 y += HEIGHT; 444 dc.SetBrush(wxBrush(*gs_bmpMask)); 445 dc.DrawRectangle(x, y, WIDTH, HEIGHT); 446 dc.DrawText(_T("Stipple mono"), x + 10, y + 10); 447 448 y += HEIGHT; 449 dc.SetBrush(wxBrush(*gs_bmpNoMask)); 450 dc.DrawRectangle(x, y, WIDTH, HEIGHT); 451 dc.DrawText(_T("Stipple colour"), x + 10, y + 10); 452} 453 454void MyCanvas::DrawTestPoly(wxDC& dc) 455{ 456 wxBrush brushHatch(*wxRED, wxFDIAGONAL_HATCH); 457 dc.SetBrush(brushHatch); 458 459 wxPoint star[5]; 460 star[0] = wxPoint(100, 60); 461 star[1] = wxPoint(60, 150); 462 star[2] = wxPoint(160, 100); 463 star[3] = wxPoint(40, 100); 464 star[4] = wxPoint(140, 150); 465 466 dc.DrawText(_T("You should see two (irregular) stars below, the left one ") 467 _T("hatched"), 10, 10); 468 dc.DrawText(_T("except for the central region and the right ") 469 _T("one entirely hatched"), 10, 30); 470 dc.DrawText(_T("The third star only has a hatched outline"), 10, 50); 471 472 dc.DrawPolygon(WXSIZEOF(star), star, 0, 30); 473 dc.DrawPolygon(WXSIZEOF(star), star, 160, 30, wxWINDING_RULE); 474 475 wxPoint star2[10]; 476 star2[0] = wxPoint(0, 100); 477 star2[1] = wxPoint(-59, -81); 478 star2[2] = wxPoint(95, 31); 479 star2[3] = wxPoint(-95, 31); 480 star2[4] = wxPoint(59, -81); 481 star2[5] = wxPoint(0, 80); 482 star2[6] = wxPoint(-47, -64); 483 star2[7] = wxPoint(76, 24); 484 star2[8] = wxPoint(-76, 24); 485 star2[9] = wxPoint(47, -64); 486 int count[2] = {5, 5}; 487 488 dc.DrawPolyPolygon(WXSIZEOF(count), count, star2, 450, 150); 489} 490 491void MyCanvas::DrawTestLines( int x, int y, int width, wxDC &dc ) 492{ 493 dc.SetPen( wxPen( wxT("black"), width, wxSOLID) ); 494 dc.SetBrush( *wxRED_BRUSH ); 495 dc.DrawText(wxString::Format(wxT("Testing lines of width %d"), width), x + 10, y - 10); 496 dc.DrawRectangle( x+10, y+10, 100, 190 ); 497 498 dc.DrawText(_T("Solid/dot/short dash/long dash/dot dash"), x + 150, y + 10); 499 dc.SetPen( wxPen( wxT("black"), width, wxSOLID) ); 500 dc.DrawLine( x+20, y+20, 100, y+20 ); 501 dc.SetPen( wxPen( wxT("black"), width, wxDOT) ); 502 dc.DrawLine( x+20, y+30, 100, y+30 ); 503 dc.SetPen( wxPen( wxT("black"), width, wxSHORT_DASH) ); 504 dc.DrawLine( x+20, y+40, 100, y+40 ); 505 dc.SetPen( wxPen( wxT("black"), width, wxLONG_DASH) ); 506 dc.DrawLine( x+20, y+50, 100, y+50 ); 507 dc.SetPen( wxPen( wxT("black"), width, wxDOT_DASH) ); 508 dc.DrawLine( x+20, y+60, 100, y+60 ); 509 510 dc.DrawText(_T("Misc hatches"), x + 150, y + 70); 511 dc.SetPen( wxPen( wxT("black"), width, wxBDIAGONAL_HATCH) ); 512 dc.DrawLine( x+20, y+70, 100, y+70 ); 513 dc.SetPen( wxPen( wxT("black"), width, wxCROSSDIAG_HATCH) ); 514 dc.DrawLine( x+20, y+80, 100, y+80 ); 515 dc.SetPen( wxPen( wxT("black"), width, wxFDIAGONAL_HATCH) ); 516 dc.DrawLine( x+20, y+90, 100, y+90 ); 517 dc.SetPen( wxPen( wxT("black"), width, wxCROSS_HATCH) ); 518 dc.DrawLine( x+20, y+100, 100, y+100 ); 519 dc.SetPen( wxPen( wxT("black"), width, wxHORIZONTAL_HATCH) ); 520 dc.DrawLine( x+20, y+110, 100, y+110 ); 521 dc.SetPen( wxPen( wxT("black"), width, wxVERTICAL_HATCH) ); 522 dc.DrawLine( x+20, y+120, 100, y+120 ); 523 524 dc.DrawText(_T("User dash"), x + 150, y + 140); 525 wxPen ud( wxT("black"), width, wxUSER_DASH ); 526 wxDash dash1[6]; 527 dash1[0] = 8; // Long dash <---------+ 528 dash1[1] = 2; // Short gap | 529 dash1[2] = 3; // Short dash | 530 dash1[3] = 2; // Short gap | 531 dash1[4] = 3; // Short dash | 532 dash1[5] = 2; // Short gap and repeat + 533 ud.SetDashes( 6, dash1 ); 534 dc.SetPen( ud ); 535 dc.DrawLine( x+20, y+140, 100, y+140 ); 536 dash1[0] = 5; // Make first dash shorter 537 ud.SetDashes( 6, dash1 ); 538 dc.SetPen( ud ); 539 dc.DrawLine( x+20, y+150, 100, y+150 ); 540 dash1[2] = 5; // Make second dash longer 541 ud.SetDashes( 6, dash1 ); 542 dc.SetPen( ud ); 543 dc.DrawLine( x+20, y+160, 100, y+160 ); 544 dash1[4] = 5; // Make third dash longer 545 ud.SetDashes( 6, dash1 ); 546 dc.SetPen( ud ); 547 dc.DrawLine( x+20, y+170, 100, y+170 ); 548} 549 550void MyCanvas::DrawDefault(wxDC& dc) 551{ 552 // mark the origin 553 dc.DrawCircle(0, 0, 10); 554 555#if !defined(wxMAC_USE_CORE_GRAPHICS) || !wxMAC_USE_CORE_GRAPHICS 556 // GetPixel and FloodFill not supported by Mac OS X CoreGraphics 557 // (FloodFill uses Blit from a non-wxMemoryDC) 558 //flood fill using brush, starting at 1,1 and replacing whatever colour we find there 559 dc.SetBrush(wxBrush(wxColour(128,128,0), wxSOLID)); 560 561 wxColour tmpColour ; 562 dc.GetPixel(1,1, &tmpColour); 563 dc.FloodFill(1,1, tmpColour, wxFLOOD_SURFACE); 564#endif 565 566 dc.DrawCheckMark(5, 80, 15, 15); 567 dc.DrawCheckMark(25, 80, 30, 30); 568 dc.DrawCheckMark(60, 80, 60, 60); 569 570 // this is the test for "blitting bitmap into DC damages selected brush" bug 571 wxCoord rectSize = m_std_icon.GetWidth() + 10; 572 wxCoord x = 100; 573 dc.SetPen(*wxTRANSPARENT_PEN); 574 dc.SetBrush( *wxGREEN_BRUSH ); 575 dc.DrawRectangle(x, 10, rectSize, rectSize); 576 dc.DrawBitmap(m_std_icon, x + 5, 15, true); 577 x += rectSize + 10; 578 dc.DrawRectangle(x, 10, rectSize, rectSize); 579 dc.DrawIcon(m_std_icon, x + 5, 15); 580 x += rectSize + 10; 581 dc.DrawRectangle(x, 10, rectSize, rectSize); 582 583 // test for "transparent" bitmap drawing (it intersects with the last 584 // rectangle above) 585 //dc.SetBrush( *wxTRANSPARENT_BRUSH ); 586 587 if (m_smile_bmp.Ok()) 588 dc.DrawBitmap(m_smile_bmp, x + rectSize - 20, rectSize - 10, true); 589 590 dc.SetBrush( *wxBLACK_BRUSH ); 591 dc.DrawRectangle( 0, 160, 1000, 300 ); 592 593 // draw lines 594 wxBitmap bitmap(20,70); 595 wxMemoryDC memdc; 596 memdc.SelectObject( bitmap ); 597 memdc.SetBrush( *wxBLACK_BRUSH ); 598 memdc.SetPen( *wxWHITE_PEN ); 599 memdc.DrawRectangle(0,0,20,70); 600 memdc.DrawLine( 10,0,10,70 ); 601 602 // to the right 603 wxPen pen = *wxRED_PEN; 604 memdc.SetPen(pen); 605 memdc.DrawLine( 10, 5,10, 5 ); 606 memdc.DrawLine( 10,10,11,10 ); 607 memdc.DrawLine( 10,15,12,15 ); 608 memdc.DrawLine( 10,20,13,20 ); 609 610/* 611 memdc.SetPen(*wxRED_PEN); 612 memdc.DrawLine( 12, 5,12, 5 ); 613 memdc.DrawLine( 12,10,13,10 ); 614 memdc.DrawLine( 12,15,14,15 ); 615 memdc.DrawLine( 12,20,15,20 ); 616*/ 617 618 // same to the left 619 memdc.DrawLine( 10,25,10,25 ); 620 memdc.DrawLine( 10,30, 9,30 ); 621 memdc.DrawLine( 10,35, 8,35 ); 622 memdc.DrawLine( 10,40, 7,40 ); 623 624 // XOR draw lines 625 dc.SetPen(*wxWHITE_PEN); 626 memdc.SetLogicalFunction( wxINVERT ); 627 memdc.SetPen( *wxWHITE_PEN ); 628 memdc.DrawLine( 10,50,10,50 ); 629 memdc.DrawLine( 10,55,11,55 ); 630 memdc.DrawLine( 10,60,12,60 ); 631 memdc.DrawLine( 10,65,13,65 ); 632 633 memdc.DrawLine( 12,50,12,50 ); 634 memdc.DrawLine( 12,55,13,55 ); 635 memdc.DrawLine( 12,60,14,60 ); 636 memdc.DrawLine( 12,65,15,65 ); 637 638 memdc.SelectObject( wxNullBitmap ); 639 dc.DrawBitmap( bitmap, 10, 170 ); 640 wxImage image = bitmap.ConvertToImage(); 641 image.Rescale( 60,210 ); 642 bitmap = wxBitmap(image); 643 dc.DrawBitmap( bitmap, 50, 170 ); 644 645 // test the rectangle outline drawing - there should be one pixel between 646 // the rect and the lines 647 dc.SetPen(*wxWHITE_PEN); 648 dc.SetBrush( *wxTRANSPARENT_BRUSH ); 649 dc.DrawRectangle(150, 170, 49, 29); 650 dc.DrawRectangle(200, 170, 49, 29); 651 dc.SetPen(*wxWHITE_PEN); 652 dc.DrawLine(250, 210, 250, 170); 653 dc.DrawLine(260, 200, 150, 200); 654 655 // test the rectangle filled drawing - there should be one pixel between 656 // the rect and the lines 657 dc.SetPen(*wxTRANSPARENT_PEN); 658 dc.SetBrush( *wxWHITE_BRUSH ); 659 dc.DrawRectangle(300, 170, 49, 29); 660 dc.DrawRectangle(350, 170, 49, 29); 661 dc.SetPen(*wxWHITE_PEN); 662 dc.DrawLine(400, 170, 400, 210); 663 dc.DrawLine(300, 200, 410, 200); 664 665 // a few more tests of this kind 666 dc.SetPen(*wxRED_PEN); 667 dc.SetBrush( *wxWHITE_BRUSH ); 668 dc.DrawRectangle(300, 220, 1, 1); 669 dc.DrawRectangle(310, 220, 2, 2); 670 dc.DrawRectangle(320, 220, 3, 3); 671 dc.DrawRectangle(330, 220, 4, 4); 672 673 dc.SetPen(*wxTRANSPARENT_PEN); 674 dc.SetBrush( *wxWHITE_BRUSH ); 675 dc.DrawRectangle(300, 230, 1, 1); 676 dc.DrawRectangle(310, 230, 2, 2); 677 dc.DrawRectangle(320, 230, 3, 3); 678 dc.DrawRectangle(330, 230, 4, 4); 679 680 // and now for filled rect with outline 681 dc.SetPen(*wxRED_PEN); 682 dc.SetBrush( *wxWHITE_BRUSH ); 683 dc.DrawRectangle(500, 170, 49, 29); 684 dc.DrawRectangle(550, 170, 49, 29); 685 dc.SetPen(*wxWHITE_PEN); 686 dc.DrawLine(600, 170, 600, 210); 687 dc.DrawLine(500, 200, 610, 200); 688 689 // test the rectangle outline drawing - there should be one pixel between 690 // the rect and the lines 691 dc.SetPen(*wxWHITE_PEN); 692 dc.SetBrush( *wxTRANSPARENT_BRUSH ); 693 dc.DrawRoundedRectangle(150, 270, 49, 29, 6); 694 dc.DrawRoundedRectangle(200, 270, 49, 29, 6); 695 dc.SetPen(*wxWHITE_PEN); 696 dc.DrawLine(250, 270, 250, 310); 697 dc.DrawLine(150, 300, 260, 300); 698 699 // test the rectangle filled drawing - there should be one pixel between 700 // the rect and the lines 701 dc.SetPen(*wxTRANSPARENT_PEN); 702 dc.SetBrush( *wxWHITE_BRUSH ); 703 dc.DrawRoundedRectangle(300, 270, 49, 29, 6); 704 dc.DrawRoundedRectangle(350, 270, 49, 29, 6); 705 dc.SetPen(*wxWHITE_PEN); 706 dc.DrawLine(400, 270, 400, 310); 707 dc.DrawLine(300, 300, 410, 300); 708 709 // Added by JACS to demonstrate bizarre behaviour. 710 // With a size of 70, we get a missing red RHS, 711 // and the height is too small, so we get yellow 712 // showing. With a size of 40, it draws as expected: 713 // it just shows a white rectangle with red outline. 714 int totalWidth = 70; 715 int totalHeight = 70; 716 wxBitmap bitmap2(totalWidth, totalHeight); 717 718 wxMemoryDC memdc2; 719 memdc2.SelectObject(bitmap2); 720 721 wxColour clr(255, 255, 0); 722 wxBrush yellowBrush(clr, wxSOLID); 723 memdc2.SetBackground(yellowBrush); 724 memdc2.Clear(); 725 726 wxPen yellowPen(clr, 1, wxSOLID); 727 728 // Now draw a white rectangle with red outline. It should 729 // entirely eclipse the yellow background. 730 memdc2.SetPen(*wxRED_PEN); 731 memdc2.SetBrush(*wxWHITE_BRUSH); 732 733 memdc2.DrawRectangle(0, 0, totalWidth, totalHeight); 734 735 memdc2.SetPen(wxNullPen); 736 memdc2.SetBrush(wxNullBrush); 737 memdc2.SelectObject(wxNullBitmap); 738 739 dc.DrawBitmap(bitmap2, 500, 270); 740 741 // Repeat, but draw directly on dc 742 // Draw a yellow rectangle filling the bitmap 743 744 x = 600; int y = 270; 745 dc.SetPen(yellowPen); 746 dc.SetBrush(yellowBrush); 747 dc.DrawRectangle(x, y, totalWidth, totalHeight); 748 749 // Now draw a white rectangle with red outline. It should 750 // entirely eclipse the yellow background. 751 dc.SetPen(*wxRED_PEN); 752 dc.SetBrush(*wxWHITE_BRUSH); 753 754 dc.DrawRectangle(x, y, totalWidth, totalHeight); 755} 756 757void MyCanvas::DrawText(wxDC& dc) 758{ 759 // set underlined font for testing 760 dc.SetFont( wxFont(12, wxMODERN, wxNORMAL, wxNORMAL, true) ); 761 dc.DrawText( _T("This is text"), 110, 10 ); 762 dc.DrawRotatedText( _T("That is text"), 20, 10, -45 ); 763 764 // use wxSWISS_FONT and not wxNORMAL_FONT as the latter can't be rotated 765 // under Win9x (it is not TrueType) 766 dc.SetFont( *wxSWISS_FONT ); 767 768 wxString text; 769 dc.SetBackgroundMode(wxTRANSPARENT); 770 771 for ( int n = -180; n < 180; n += 30 ) 772 { 773 text.Printf(wxT(" %d rotated text"), n); 774 dc.DrawRotatedText(text , 400, 400, n); 775 } 776 777 dc.SetFont( wxFont( 18, wxSWISS, wxNORMAL, wxNORMAL ) ); 778 779 dc.DrawText( _T("This is Swiss 18pt text."), 110, 40 ); 780 781 long length; 782 long height; 783 long descent; 784 dc.GetTextExtent( _T("This is Swiss 18pt text."), &length, &height, &descent ); 785 text.Printf( wxT("Dimensions are length %ld, height %ld, descent %ld"), length, height, descent ); 786 dc.DrawText( text, 110, 80 ); 787 788 text.Printf( wxT("CharHeight() returns: %d"), dc.GetCharHeight() ); 789 dc.DrawText( text, 110, 120 ); 790 791 dc.DrawRectangle( 100, 40, 4, height ); 792 793 // test the logical function effect 794 wxCoord y = 150; 795 dc.SetLogicalFunction(wxINVERT); 796 dc.DrawText( _T("There should be no text below"), 110, 150 ); 797 dc.DrawRectangle( 110, y, 100, height ); 798 799 // twice drawn inverted should result in invisible 800 y += height; 801 dc.DrawText( _T("Invisible text"), 110, y ); 802 dc.DrawRectangle( 110, y, 100, height ); 803 dc.DrawText( _T("Invisible text"), 110, y ); 804 dc.DrawRectangle( 110, y, 100, height ); 805 dc.SetLogicalFunction(wxCOPY); 806 807 y += height; 808 dc.DrawRectangle( 110, y, 100, height ); 809 dc.DrawText( _T("Visible text"), 110, y ); 810} 811 812static const struct 813{ 814 const wxChar *name; 815 int rop; 816} rasterOperations[] = 817{ 818 { wxT("wxAND"), wxAND }, 819 { wxT("wxAND_INVERT"), wxAND_INVERT }, 820 { wxT("wxAND_REVERSE"), wxAND_REVERSE }, 821 { wxT("wxCLEAR"), wxCLEAR }, 822 { wxT("wxCOPY"), wxCOPY }, 823 { wxT("wxEQUIV"), wxEQUIV }, 824 { wxT("wxINVERT"), wxINVERT }, 825 { wxT("wxNAND"), wxNAND }, 826 { wxT("wxNO_OP"), wxNO_OP }, 827 { wxT("wxOR"), wxOR }, 828 { wxT("wxOR_INVERT"), wxOR_INVERT }, 829 { wxT("wxOR_REVERSE"), wxOR_REVERSE }, 830 { wxT("wxSET"), wxSET }, 831 { wxT("wxSRC_INVERT"), wxSRC_INVERT }, 832 { wxT("wxXOR"), wxXOR }, 833}; 834 835void MyCanvas::DrawImages(wxDC& dc) 836{ 837 dc.DrawText(_T("original image"), 0, 0); 838 dc.DrawBitmap(*gs_bmpNoMask, 0, 20, 0); 839 dc.DrawText(_T("with colour mask"), 0, 100); 840 dc.DrawBitmap(*gs_bmpWithColMask, 0, 120, true); 841 dc.DrawText(_T("the mask image"), 0, 200); 842 dc.DrawBitmap(*gs_bmpMask, 0, 220, 0); 843 dc.DrawText(_T("masked image"), 0, 300); 844 dc.DrawBitmap(*gs_bmpWithMask, 0, 320, true); 845 846 int cx = gs_bmpWithColMask->GetWidth(), 847 cy = gs_bmpWithColMask->GetHeight(); 848 849 wxMemoryDC memDC; 850 for ( size_t n = 0; n < WXSIZEOF(rasterOperations); n++ ) 851 { 852 wxCoord x = 120 + 150*(n%4), 853 y = 20 + 100*(n/4); 854 855 dc.DrawText(rasterOperations[n].name, x, y - 20); 856 memDC.SelectObject(*gs_bmpWithColMask); 857 dc.Blit(x, y, cx, cy, &memDC, 0, 0, rasterOperations[n].rop, true); 858 } 859} 860 861void MyCanvas::DrawWithLogicalOps(wxDC& dc) 862{ 863 static const wxCoord w = 60; 864 static const wxCoord h = 60; 865 866 // reuse the text colour here 867 dc.SetPen(wxPen(m_owner->m_colourForeground, 1, wxSOLID)); 868 dc.SetBrush(*wxTRANSPARENT_BRUSH); 869 870 size_t n; 871 for ( n = 0; n < WXSIZEOF(rasterOperations); n++ ) 872 { 873 wxCoord x = 20 + 150*(n%4), 874 y = 20 + 100*(n/4); 875 876 dc.DrawText(rasterOperations[n].name, x, y - 20); 877 dc.SetLogicalFunction(rasterOperations[n].rop); 878 dc.DrawRectangle(x, y, w, h); 879 dc.DrawLine(x, y, x + w, y + h); 880 dc.DrawLine(x + w, y, x, y + h); 881 } 882 883 // now some filled rectangles 884 dc.SetBrush(wxBrush(m_owner->m_colourForeground, wxSOLID)); 885 886 for ( n = 0; n < WXSIZEOF(rasterOperations); n++ ) 887 { 888 wxCoord x = 20 + 150*(n%4), 889 y = 500 + 100*(n/4); 890 891 dc.DrawText(rasterOperations[n].name, x, y - 20); 892 dc.SetLogicalFunction(rasterOperations[n].rop); 893 dc.DrawRectangle(x, y, w, h); 894 } 895} 896 897#if wxUSE_GRAPHICS_CONTEXT 898#ifdef __WXGTK20__ 899void MyCanvas::DrawAlpha(wxDC& no_dc) 900#else 901void MyCanvas::DrawAlpha(wxDC& dc) 902#endif 903{ 904#ifdef __WXGTK__ 905 wxGCDC dc( this ); 906 PrepareDC( dc ); 907#endif 908 909 wxDouble margin = 20 ; 910 wxDouble width = 180 ; 911 wxDouble radius = 30 ; 912 913 dc.SetPen( wxPen( wxColour( 128, 0, 0, 255 ),12, wxSOLID)); 914 dc.SetBrush( wxBrush( wxColour( 255, 0, 0, 255),wxSOLID)); 915 916 wxRect r(margin,margin+width*0.66,width,width) ; 917 918 dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ; 919 920 dc.SetPen( wxPen( wxColour( 0, 0, 128, 255 ),12, wxSOLID)); 921 dc.SetBrush( wxBrush( wxColour( 0, 0, 255, 255),wxSOLID)); 922 923 r.Offset( width * 0.8 , - width * 0.66 ) ; 924 925 dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ; 926 927 dc.SetPen( wxPen( wxColour( 128, 128, 0, 255 ),12, wxSOLID)); 928 dc.SetBrush( wxBrush( wxColour( 192, 192, 0, 255),wxSOLID)); 929 930 r.Offset( width * 0.8 , width *0.5 ) ; 931 932 dc.DrawRoundedRectangle( r.x, r.y, r.width, r.width, radius ) ; 933 934 dc.SetPen( *wxTRANSPARENT_PEN ) ; 935 dc.SetBrush( wxBrush( wxColour(255,255,128,128) ) ); 936 dc.DrawRoundedRectangle( 0 , margin + width / 2 , width * 3 , 100 , radius) ; 937 938 dc.SetTextForeground( wxColour(255,255,0,128) ); 939 dc.SetFont( wxFont( 40, wxFONTFAMILY_SWISS, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_NORMAL ) ); 940 dc.DrawText( wxT("Hello!"), 120, 80 ); 941} 942 943#endif 944 945void MyCanvas::DrawCircles(wxDC& dc) 946{ 947 int x = 100, 948 y = 100, 949 r = 20; 950 951 dc.SetPen( *wxRED_PEN ); 952 dc.SetBrush( *wxGREEN_BRUSH ); 953 954 dc.DrawText(_T("Some circles"), 0, y); 955 dc.DrawCircle(x, y, r); 956 dc.DrawCircle(x + 2*r, y, r); 957 dc.DrawCircle(x + 4*r, y, r); 958 959 y += 2*r; 960 dc.DrawText(_T("And ellipses"), 0, y); 961 dc.DrawEllipse(x - r, y, 2*r, r); 962 dc.DrawEllipse(x + r, y, 2*r, r); 963 dc.DrawEllipse(x + 3*r, y, 2*r, r); 964 965 y += 2*r; 966 dc.DrawText(_T("And arcs"), 0, y); 967 dc.DrawArc(x - r, y, x + r, y, x, y); 968 dc.DrawArc(x + 4*r, y, x + 2*r, y, x + 3*r, y); 969 dc.DrawArc(x + 5*r, y, x + 5*r, y, x + 6*r, y); 970 971 y += 2*r; 972 dc.DrawEllipticArc(x - r, y, 2*r, r, 0, 90); 973 dc.DrawEllipticArc(x + r, y, 2*r, r, 90, 180); 974 dc.DrawEllipticArc(x + 3*r, y, 2*r, r, 180, 270); 975 dc.DrawEllipticArc(x + 5*r, y, 2*r, r, 270, 360); 976 977 // same as above, just transparent brush 978 979 dc.SetPen( *wxRED_PEN ); 980 dc.SetBrush( *wxTRANSPARENT_BRUSH ); 981 982 y += 2*r; 983 dc.DrawText(_T("Some circles"), 0, y); 984 dc.DrawCircle(x, y, r); 985 dc.DrawCircle(x + 2*r, y, r); 986 dc.DrawCircle(x + 4*r, y, r); 987 988 y += 2*r; 989 dc.DrawText(_T("And ellipses"), 0, y); 990 dc.DrawEllipse(x - r, y, 2*r, r); 991 dc.DrawEllipse(x + r, y, 2*r, r); 992 dc.DrawEllipse(x + 3*r, y, 2*r, r); 993 994 y += 2*r; 995 dc.DrawText(_T("And arcs"), 0, y); 996 dc.DrawArc(x - r, y, x + r, y, x, y); 997 dc.DrawArc(x + 4*r, y, x + 2*r, y, x + 3*r, y); 998 dc.DrawArc(x + 5*r, y, x + 5*r, y, x + 6*r, y); 999 1000 y += 2*r; 1001 dc.DrawEllipticArc(x - r, y, 2*r, r, 0, 90); 1002 dc.DrawEllipticArc(x + r, y, 2*r, r, 90, 180); 1003 dc.DrawEllipticArc(x + 3*r, y, 2*r, r, 180, 270); 1004 dc.DrawEllipticArc(x + 5*r, y, 2*r, r, 270, 360); 1005 1006} 1007 1008void MyCanvas::DrawSplines(wxDC& dc) 1009{ 1010#if wxUSE_SPLINES 1011 dc.DrawText(_T("Some splines"), 10, 5); 1012 1013 // values are hardcoded rather than randomly generated 1014 // so the output can be compared between native 1015 // implementations on platforms with different random 1016 // generators 1017 1018 const int R = 300; 1019 const wxPoint center( R + 20, R + 20 ); 1020 const int angles[7] = { 0, 10, 33, 77, 13, 145, 90 }; 1021 const int radii[5] = { 100 , 59, 85, 33, 90 }; 1022 const int n = 200; 1023 wxPoint pts[n]; 1024 1025 // background spline calculation 1026 unsigned int radius_pos = 0; 1027 unsigned int angle_pos = 0; 1028 int angle = 0; 1029 for ( int i = 0; i < n; i++ ) 1030 { 1031 angle += angles[ angle_pos ]; 1032 int r = R * radii[ radius_pos ] / 100; 1033 pts[ i ].x = center.x + (wxCoord)( r * cos( M_PI * angle / 180.0) ); 1034 pts[ i ].y = center.y + (wxCoord)( r * sin( M_PI * angle / 180.0) ); 1035 1036 angle_pos++; 1037 if ( angle_pos >= WXSIZEOF(angles) ) angle_pos = 0; 1038 1039 radius_pos++; 1040 if ( radius_pos >= WXSIZEOF(radii) ) radius_pos = 0; 1041 } 1042 1043 // background spline drawing 1044 dc.SetPen(*wxRED_PEN); 1045 dc.DrawSpline(WXSIZEOF(pts), pts); 1046 1047 // less detailed spline calculation 1048 wxPoint letters[4][5]; 1049 // w 1050 letters[0][0] = wxPoint( 0,1); // O O 1051 letters[0][1] = wxPoint( 1,3); // * * 1052 letters[0][2] = wxPoint( 2,2); // * O * 1053 letters[0][3] = wxPoint( 3,3); // * * * * 1054 letters[0][4] = wxPoint( 4,1); // O O 1055 // x1 1056 letters[1][0] = wxPoint( 5,1); // O*O 1057 letters[1][1] = wxPoint( 6,1); // * 1058 letters[1][2] = wxPoint( 7,2); // O 1059 letters[1][3] = wxPoint( 8,3); // * 1060 letters[1][4] = wxPoint( 9,3); // O*O 1061 // x2 1062 letters[2][0] = wxPoint( 5,3); // O*O 1063 letters[2][1] = wxPoint( 6,3); // * 1064 letters[2][2] = wxPoint( 7,2); // O 1065 letters[2][3] = wxPoint( 8,1); // * 1066 letters[2][4] = wxPoint( 9,1); // O*O 1067 // W 1068 letters[3][0] = wxPoint(10,0); // O O 1069 letters[3][1] = wxPoint(11,3); // * * 1070 letters[3][2] = wxPoint(12,1); // * O * 1071 letters[3][3] = wxPoint(13,3); // * * * * 1072 letters[3][4] = wxPoint(14,0); // O O 1073 1074 const int dx = 2 * R / letters[3][4].x; 1075 const int h[4] = { -R/2, 0, R/4, R/2 }; 1076 1077 for ( int m = 0; m < 4; m++ ) 1078 { 1079 for ( int n = 0; n < 5; n++ ) 1080 { 1081 letters[m][n].x = center.x - R + letters[m][n].x * dx; 1082 letters[m][n].y = center.y + h[ letters[m][n].y ]; 1083 } 1084 1085 dc.SetPen( wxPen( wxT("blue"), 1, wxDOT) ); 1086 dc.DrawLines(5, letters[m]); 1087 dc.SetPen( wxPen( wxT("black"), 4, wxSOLID) ); 1088 dc.DrawSpline(5, letters[m]); 1089 } 1090 1091#else 1092 dc.DrawText(_T("Splines not supported."), 10, 5); 1093#endif 1094} 1095 1096void MyCanvas::DrawGradients(wxDC& dc) 1097{ 1098 static const int TEXT_HEIGHT = 15; 1099 1100 // LHS: linear 1101 wxRect r(10, 10, 50, 50); 1102 dc.DrawText(_T("wxRIGHT"), r.x, r.y); 1103 r.Offset(0, TEXT_HEIGHT); 1104 dc.GradientFillLinear(r, *wxWHITE, *wxBLUE, wxRIGHT); 1105 1106 r.Offset(0, r.height + 10); 1107 dc.DrawText(_T("wxLEFT"), r.x, r.y); 1108 r.Offset(0, TEXT_HEIGHT); 1109 dc.GradientFillLinear(r, *wxWHITE, *wxBLUE, wxLEFT); 1110 1111 r.Offset(0, r.height + 10); 1112 dc.DrawText(_T("wxDOWN"), r.x, r.y); 1113 r.Offset(0, TEXT_HEIGHT); 1114 dc.GradientFillLinear(r, *wxWHITE, *wxBLUE, wxDOWN); 1115 1116 r.Offset(0, r.height + 10); 1117 dc.DrawText(_T("wxUP"), r.x, r.y); 1118 r.Offset(0, TEXT_HEIGHT); 1119 dc.GradientFillLinear(r, *wxWHITE, *wxBLUE, wxUP); 1120 1121 1122 // RHS: concentric 1123 r = wxRect(200, 10, 50, 50); 1124 dc.DrawText(_T("Blue inside"), r.x, r.y); 1125 r.Offset(0, TEXT_HEIGHT); 1126 dc.GradientFillConcentric(r, *wxBLUE, *wxWHITE); 1127 1128 r.Offset(0, r.height + 10); 1129 dc.DrawText(_T("White inside"), r.x, r.y); 1130 r.Offset(0, TEXT_HEIGHT); 1131 dc.GradientFillConcentric(r, *wxWHITE, *wxBLUE); 1132 1133 r.Offset(0, r.height + 10); 1134 dc.DrawText(_T("Blue in top left corner"), r.x, r.y); 1135 r.Offset(0, TEXT_HEIGHT); 1136 dc.GradientFillConcentric(r, *wxBLUE, *wxWHITE, wxPoint(0, 0)); 1137 1138 r.Offset(0, r.height + 10); 1139 dc.DrawText(_T("Blue in bottom right corner"), r.x, r.y); 1140 r.Offset(0, TEXT_HEIGHT); 1141 dc.GradientFillConcentric(r, *wxBLUE, *wxWHITE, wxPoint(r.width, r.height)); 1142} 1143 1144void MyCanvas::DrawRegions(wxDC& dc) 1145{ 1146 dc.DrawText(_T("You should see a red rect partly covered by a cyan one ") 1147 _T("on the left"), 10, 5); 1148 dc.DrawText(_T("and 5 smileys from which 4 are partially clipped on the right"), 1149 10, 5 + dc.GetCharHeight()); 1150 dc.DrawText(_T("The second copy should be identical but right part of it ") 1151 _T("should be offset by 10 pixels."), 1152 10, 5 + 2*dc.GetCharHeight()); 1153 1154 DrawRegionsHelper(dc, 10, true); 1155 DrawRegionsHelper(dc, 350, false); 1156} 1157 1158void MyCanvas::DrawRegionsHelper(wxDC& dc, wxCoord x, bool firstTime) 1159{ 1160 wxCoord y = 100; 1161 1162 dc.DestroyClippingRegion(); 1163 dc.SetBrush( *wxWHITE_BRUSH ); 1164 dc.SetPen( *wxTRANSPARENT_PEN ); 1165 dc.DrawRectangle( x, y, 310, 310 ); 1166 1167 dc.SetClippingRegion( x + 10, y + 10, 100, 270 ); 1168 1169 dc.SetBrush( *wxRED_BRUSH ); 1170 dc.DrawRectangle( x, y, 310, 310 ); 1171 1172 dc.SetClippingRegion( x + 10, y + 10, 100, 100 ); 1173 1174 dc.SetBrush( *wxCYAN_BRUSH ); 1175 dc.DrawRectangle( x, y, 310, 310 ); 1176 1177 dc.DestroyClippingRegion(); 1178 1179 wxRegion region(x + 110, y + 20, 100, 270); 1180#if !defined(__WXMOTIF__) && !defined(__WXMAC__) 1181 if ( !firstTime ) 1182 region.Offset(10, 10); 1183#endif 1184 dc.SetClippingRegion(region); 1185 1186 dc.SetBrush( *wxGREY_BRUSH ); 1187 dc.DrawRectangle( x, y, 310, 310 ); 1188 1189 if (m_smile_bmp.Ok()) 1190 { 1191 dc.DrawBitmap( m_smile_bmp, x + 150, y + 150, true ); 1192 dc.DrawBitmap( m_smile_bmp, x + 130, y + 10, true ); 1193 dc.DrawBitmap( m_smile_bmp, x + 130, y + 280, true ); 1194 dc.DrawBitmap( m_smile_bmp, x + 100, y + 70, true ); 1195 dc.DrawBitmap( m_smile_bmp, x + 200, y + 70, true ); 1196 } 1197} 1198 1199void MyCanvas::OnPaint(wxPaintEvent &WXUNUSED(event)) 1200{ 1201 wxPaintDC pdc(this); 1202 1203#if wxUSE_GRAPHICS_CONTEXT 1204 wxGCDC gdc( pdc ) ; 1205 wxDC &dc = m_useContext ? (wxDC&) gdc : (wxDC&) pdc ; 1206#else 1207 wxDC &dc = pdc ; 1208#endif 1209 1210 PrepareDC(dc); 1211 1212 m_owner->PrepareDC(dc); 1213 1214 dc.SetBackgroundMode( m_owner->m_backgroundMode ); 1215 if ( m_owner->m_backgroundBrush.Ok() ) 1216 dc.SetBackground( m_owner->m_backgroundBrush ); 1217 if ( m_owner->m_colourForeground.Ok() ) 1218 dc.SetTextForeground( m_owner->m_colourForeground ); 1219 if ( m_owner->m_colourBackground.Ok() ) 1220 dc.SetTextBackground( m_owner->m_colourBackground ); 1221 1222 if ( m_owner->m_textureBackground) { 1223 if ( ! m_owner->m_backgroundBrush.Ok() ) { 1224 wxColour clr(0,128,0); 1225 wxBrush b(clr, wxSOLID); 1226 dc.SetBackground(b); 1227 } 1228 } 1229 1230 if ( m_clip ) 1231 dc.SetClippingRegion(100, 100, 100, 100); 1232 1233 dc.Clear(); 1234 1235 if ( m_owner->m_textureBackground ) 1236 { 1237 dc.SetPen(*wxMEDIUM_GREY_PEN); 1238 for ( int i = 0; i < 200; i++ ) 1239 dc.DrawLine(0, i*10, i*10, 0); 1240 } 1241 1242 switch ( m_show ) 1243 { 1244 case Show_Default: 1245 DrawDefault(dc); 1246 break; 1247 1248 case Show_Circles: 1249 DrawCircles(dc); 1250 break; 1251 1252 case Show_Splines: 1253 DrawSplines(dc); 1254 break; 1255 1256 case Show_Regions: 1257 DrawRegions(dc); 1258 break; 1259 1260 case Show_Text: 1261 DrawText(dc); 1262 break; 1263 1264 case Show_Lines: 1265 DrawTestLines( 0, 100, 0, dc ); 1266 DrawTestLines( 0, 320, 1, dc ); 1267 DrawTestLines( 0, 540, 2, dc ); 1268 DrawTestLines( 0, 760, 6, dc ); 1269 break; 1270 1271 case Show_Brushes: 1272 DrawTestBrushes(dc); 1273 break; 1274 1275 case Show_Polygons: 1276 DrawTestPoly(dc); 1277 break; 1278 1279 case Show_Mask: 1280 DrawImages(dc); 1281 break; 1282 1283 case Show_Ops: 1284 DrawWithLogicalOps(dc); 1285 break; 1286 1287#if wxUSE_GRAPHICS_CONTEXT 1288 case Show_Alpha: 1289 DrawAlpha(dc); 1290 break; 1291#endif 1292 1293 case Show_Gradient: 1294 DrawGradients(dc); 1295 break; 1296 1297 default: 1298 break; 1299 } 1300} 1301 1302void MyCanvas::OnMouseMove(wxMouseEvent &event) 1303{ 1304#if wxUSE_STATUSBAR 1305 wxClientDC dc(this); 1306 PrepareDC(dc); 1307 m_owner->PrepareDC(dc); 1308 1309 wxPoint pos = event.GetPosition(); 1310 long x = dc.DeviceToLogicalX( pos.x ); 1311 long y = dc.DeviceToLogicalY( pos.y ); 1312 wxString str; 1313 str.Printf( wxT("Current mouse position: %d,%d"), (int)x, (int)y ); 1314 m_owner->SetStatusText( str ); 1315#else 1316 wxUnusedVar(event); 1317#endif // wxUSE_STATUSBAR 1318} 1319 1320// ---------------------------------------------------------------------------- 1321// MyFrame 1322// ---------------------------------------------------------------------------- 1323 1324// the event tables connect the wxWidgets events with the functions (event 1325// handlers) which process them. It can be also done at run-time, but for the 1326// simple menu events like this the static method is much simpler. 1327BEGIN_EVENT_TABLE(MyFrame, wxFrame) 1328 EVT_MENU (File_Quit, MyFrame::OnQuit) 1329 EVT_MENU (File_About, MyFrame::OnAbout) 1330 EVT_MENU (File_Clip, MyFrame::OnClip) 1331#if wxUSE_GRAPHICS_CONTEXT 1332 EVT_MENU (File_GraphicContext, MyFrame::OnGraphicContext) 1333#endif 1334 1335 EVT_MENU_RANGE(MenuShow_First, MenuShow_Last, MyFrame::OnShow) 1336 1337 EVT_MENU_RANGE(MenuOption_First, MenuOption_Last, MyFrame::OnOption) 1338END_EVENT_TABLE() 1339 1340// frame constructor 1341MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) 1342 : wxFrame((wxFrame *)NULL, wxID_ANY, title, pos, size, 1343 wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE) 1344{ 1345 // set the frame icon 1346 SetIcon(wxICON(mondrian)); 1347 1348 wxMenu *menuFile = new wxMenu; 1349 menuFile->Append(File_ShowDefault, _T("&Default screen\tF1")); 1350 menuFile->Append(File_ShowText, _T("&Text screen\tF2")); 1351 menuFile->Append(File_ShowLines, _T("&Lines screen\tF3")); 1352 menuFile->Append(File_ShowBrushes, _T("&Brushes screen\tF4")); 1353 menuFile->Append(File_ShowPolygons, _T("&Polygons screen\tF5")); 1354 menuFile->Append(File_ShowMask, _T("&Mask screen\tF6")); 1355 menuFile->Append(File_ShowOps, _T("&ROP screen\tF7")); 1356 menuFile->Append(File_ShowRegions, _T("Re&gions screen\tF8")); 1357 menuFile->Append(File_ShowCircles, _T("&Circles screen\tF9")); 1358#if wxUSE_GRAPHICS_CONTEXT 1359 menuFile->Append(File_ShowAlpha, _T("&Alpha screen\tF10")); 1360#endif 1361 menuFile->Append(File_ShowSplines, _T("&Splines screen\tF11")); 1362 menuFile->Append(File_ShowGradients, _T("&Gradients screen\tF12")); 1363 menuFile->AppendSeparator(); 1364 menuFile->AppendCheckItem(File_Clip, _T("&Clip\tCtrl-C"), _T("Clip/unclip drawing")); 1365#if wxUSE_GRAPHICS_CONTEXT 1366 menuFile->AppendCheckItem(File_GraphicContext, _T("&Use GraphicContext\tCtrl-Y"), _T("Use GraphicContext")); 1367#endif 1368 menuFile->AppendSeparator(); 1369 menuFile->Append(File_About, _T("&About...\tCtrl-A"), _T("Show about dialog")); 1370 menuFile->AppendSeparator(); 1371 menuFile->Append(File_Quit, _T("E&xit\tAlt-X"), _T("Quit this program")); 1372 1373 wxMenu *menuMapMode = new wxMenu; 1374 menuMapMode->Append( MapMode_Text, _T("&TEXT map mode") ); 1375 menuMapMode->Append( MapMode_Lometric, _T("&LOMETRIC map mode") ); 1376 menuMapMode->Append( MapMode_Twips, _T("T&WIPS map mode") ); 1377 menuMapMode->Append( MapMode_Points, _T("&POINTS map mode") ); 1378 menuMapMode->Append( MapMode_Metric, _T("&METRIC map mode") ); 1379 1380 wxMenu *menuUserScale = new wxMenu; 1381 menuUserScale->Append( UserScale_StretchHoriz, _T("Stretch &horizontally\tCtrl-H") ); 1382 menuUserScale->Append( UserScale_ShrinkHoriz, _T("Shrin&k horizontally\tCtrl-G") ); 1383 menuUserScale->Append( UserScale_StretchVertic, _T("Stretch &vertically\tCtrl-V") ); 1384 menuUserScale->Append( UserScale_ShrinkVertic, _T("&Shrink vertically\tCtrl-W") ); 1385 menuUserScale->AppendSeparator(); 1386 menuUserScale->Append( UserScale_Restore, _T("&Restore to normal\tCtrl-0") ); 1387 1388 wxMenu *menuAxis = new wxMenu; 1389 menuAxis->AppendCheckItem( AxisMirror_Horiz, _T("Mirror horizontally\tCtrl-M") ); 1390 menuAxis->AppendCheckItem( AxisMirror_Vertic, _T("Mirror vertically\tCtrl-N") ); 1391 1392 wxMenu *menuLogical = new wxMenu; 1393 menuLogical->Append( LogicalOrigin_MoveDown, _T("Move &down\tCtrl-D") ); 1394 menuLogical->Append( LogicalOrigin_MoveUp, _T("Move &up\tCtrl-U") ); 1395 menuLogical->Append( LogicalOrigin_MoveLeft, _T("Move &right\tCtrl-L") ); 1396 menuLogical->Append( LogicalOrigin_MoveRight, _T("Move &left\tCtrl-R") ); 1397 menuLogical->AppendSeparator(); 1398 menuLogical->Append( LogicalOrigin_Set, _T("Set to (&100, 100)\tShift-Ctrl-1") ); 1399 menuLogical->Append( LogicalOrigin_Restore, _T("&Restore to normal\tShift-Ctrl-0") ); 1400 1401 wxMenu *menuColour = new wxMenu; 1402#if wxUSE_COLOURDLG 1403 menuColour->Append( Colour_TextForeground, _T("Text &foreground...") ); 1404 menuColour->Append( Colour_TextBackground, _T("Text &background...") ); 1405 menuColour->Append( Colour_Background, _T("Background &colour...") ); 1406#endif // wxUSE_COLOURDLG 1407 menuColour->AppendCheckItem( Colour_BackgroundMode, _T("&Opaque/transparent\tCtrl-B") ); 1408 menuColour->AppendCheckItem( Colour_TextureBackgound, _T("Draw textured back&ground\tCtrl-T") ); 1409 1410 // now append the freshly created menu to the menu bar... 1411 wxMenuBar *menuBar = new wxMenuBar; 1412 menuBar->Append(menuFile, _T("&File")); 1413 menuBar->Append(menuMapMode, _T("&Mode")); 1414 menuBar->Append(menuUserScale, _T("&Scale")); 1415 menuBar->Append(menuAxis, _T("&Axis")); 1416 menuBar->Append(menuLogical, _T("&Origin")); 1417 menuBar->Append(menuColour, _T("&Colours")); 1418 1419 // ... and attach this menu bar to the frame 1420 SetMenuBar(menuBar); 1421 1422#if wxUSE_STATUSBAR 1423 CreateStatusBar(2); 1424 SetStatusText(_T("Welcome to wxWidgets!")); 1425#endif // wxUSE_STATUSBAR 1426 1427 m_mapMode = wxMM_TEXT; 1428 m_xUserScale = 1.0; 1429 m_yUserScale = 1.0; 1430 m_xLogicalOrigin = 0; 1431 m_yLogicalOrigin = 0; 1432 m_xAxisReversed = 1433 m_yAxisReversed = false; 1434 m_backgroundMode = wxSOLID; 1435 m_colourForeground = *wxRED; 1436 m_colourBackground = *wxBLUE; 1437 m_textureBackground = false; 1438 1439 m_canvas = new MyCanvas( this ); 1440 m_canvas->SetScrollbars( 10, 10, 100, 240 ); 1441} 1442 1443// event handlers 1444 1445void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) 1446{ 1447 // true is to force the frame to close 1448 Close(true); 1449} 1450 1451void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) 1452{ 1453 wxString msg; 1454 msg.Printf( wxT("This is the about dialog of the drawing sample.\n") 1455 wxT("This sample tests various primitive drawing functions\n") 1456 wxT("(without any attempts to prevent flicker).\n") 1457 wxT("Copyright (c) Robert Roebling 1999") 1458 ); 1459 1460 wxMessageBox(msg, _T("About Drawing"), wxOK | wxICON_INFORMATION, this); 1461} 1462 1463void MyFrame::OnClip(wxCommandEvent& event) 1464{ 1465 m_canvas->Clip(event.IsChecked()); 1466} 1467 1468#if wxUSE_GRAPHICS_CONTEXT 1469void MyFrame::OnGraphicContext(wxCommandEvent& event) 1470{ 1471 m_canvas->UseGraphicContext(event.IsChecked()); 1472} 1473#endif 1474 1475void MyFrame::OnShow(wxCommandEvent& event) 1476{ 1477 m_canvas->ToShow((ScreenToShow)(event.GetId() - MenuShow_First)); 1478} 1479 1480void MyFrame::OnOption(wxCommandEvent& event) 1481{ 1482 switch (event.GetId()) 1483 { 1484 case MapMode_Text: 1485 m_mapMode = wxMM_TEXT; 1486 break; 1487 case MapMode_Lometric: 1488 m_mapMode = wxMM_LOMETRIC; 1489 break; 1490 case MapMode_Twips: 1491 m_mapMode = wxMM_TWIPS; 1492 break; 1493 case MapMode_Points: 1494 m_mapMode = wxMM_POINTS; 1495 break; 1496 case MapMode_Metric: 1497 m_mapMode = wxMM_METRIC; 1498 break; 1499 1500 case LogicalOrigin_MoveDown: 1501 m_yLogicalOrigin += 10; 1502 break; 1503 case LogicalOrigin_MoveUp: 1504 m_yLogicalOrigin -= 10; 1505 break; 1506 case LogicalOrigin_MoveLeft: 1507 m_xLogicalOrigin += 10; 1508 break; 1509 case LogicalOrigin_MoveRight: 1510 m_xLogicalOrigin -= 10; 1511 break; 1512 case LogicalOrigin_Set: 1513 m_xLogicalOrigin = 1514 m_yLogicalOrigin = -100; 1515 break; 1516 case LogicalOrigin_Restore: 1517 m_xLogicalOrigin = 1518 m_yLogicalOrigin = 0; 1519 break; 1520 1521 case UserScale_StretchHoriz: 1522 m_xUserScale *= 1.10; 1523 break; 1524 case UserScale_ShrinkHoriz: 1525 m_xUserScale /= 1.10; 1526 break; 1527 case UserScale_StretchVertic: 1528 m_yUserScale *= 1.10; 1529 break; 1530 case UserScale_ShrinkVertic: 1531 m_yUserScale /= 1.10; 1532 break; 1533 case UserScale_Restore: 1534 m_xUserScale = 1535 m_yUserScale = 1.0; 1536 break; 1537 1538 case AxisMirror_Vertic: 1539 m_yAxisReversed = !m_yAxisReversed; 1540 break; 1541 case AxisMirror_Horiz: 1542 m_xAxisReversed = !m_xAxisReversed; 1543 break; 1544 1545#if wxUSE_COLOURDLG 1546 case Colour_TextForeground: 1547 m_colourForeground = SelectColour(); 1548 break; 1549 case Colour_TextBackground: 1550 m_colourBackground = SelectColour(); 1551 break; 1552 case Colour_Background: 1553 { 1554 wxColour col = SelectColour(); 1555 if ( col.Ok() ) 1556 { 1557 m_backgroundBrush.SetColour(col); 1558 } 1559 } 1560 break; 1561#endif // wxUSE_COLOURDLG 1562 1563 case Colour_BackgroundMode: 1564 m_backgroundMode = m_backgroundMode == wxSOLID ? wxTRANSPARENT 1565 : wxSOLID; 1566 break; 1567 1568 case Colour_TextureBackgound: 1569 m_textureBackground = ! m_textureBackground; 1570 break; 1571 1572 default: 1573 // skip Refresh() 1574 return; 1575 } 1576 1577 m_canvas->Refresh(); 1578} 1579 1580void MyFrame::PrepareDC(wxDC& dc) 1581{ 1582 dc.SetLogicalOrigin( m_xLogicalOrigin, m_yLogicalOrigin ); 1583 dc.SetAxisOrientation( !m_xAxisReversed, m_yAxisReversed ); 1584 dc.SetUserScale( m_xUserScale, m_yUserScale ); 1585 dc.SetMapMode( m_mapMode ); 1586} 1587 1588#if wxUSE_COLOURDLG 1589wxColour MyFrame::SelectColour() 1590{ 1591 wxColour col; 1592 wxColourData data; 1593 wxColourDialog dialog(this, &data); 1594 1595 if ( dialog.ShowModal() == wxID_OK ) 1596 { 1597 col = dialog.GetColourData().GetColour(); 1598 } 1599 1600 return col; 1601} 1602#endif // wxUSE_COLOURDLG 1603