1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: shows and tests wxDC features
4 // Author: Robert Roebling
8 // Copyright: (c) Robert Roebling
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "drawing.cpp"
22 #pragma interface "drawing.cpp"
25 // For compilers that support precompilation, includes "wx/wx.h".
26 #include "wx/wxprec.h"
32 // for all others, include the necessary headers (this file is usually all you
33 // need because it includes almost all "standard" wxWindows headers
38 #include "wx/colordlg.h"
41 // ----------------------------------------------------------------------------
43 // ----------------------------------------------------------------------------
45 // the application icon
46 #if defined(__WXGTK__) || defined(__WXMOTIF__)
47 #include "mondrian.xpm"
50 // ----------------------------------------------------------------------------
52 // ----------------------------------------------------------------------------
54 // what do we show on screen (there are too many shapes to put them all on
55 // screen simultaneously)
67 // ----------------------------------------------------------------------------
69 // ----------------------------------------------------------------------------
71 static wxBitmap gs_bmpNoMask
,
79 // ----------------------------------------------------------------------------
81 // ----------------------------------------------------------------------------
83 // Define a new application type, each program should derive a class from wxApp
84 class MyApp
: public wxApp
87 // override base class virtuals
88 // ----------------------------
90 // this one is called on application startup and is a good place for the app
91 // initialization (doing it here and not in the ctor allows to have an error
92 // return: if OnInit() returns false, the application terminates)
93 virtual bool OnInit();
101 // Define a new frame type: this is going to be our main frame
102 class MyFrame
: public wxFrame
106 MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
);
108 // event handlers (these functions should _not_ be virtual)
109 void OnQuit(wxCommandEvent
& event
);
110 void OnAbout(wxCommandEvent
& event
);
111 void OnShow(wxCommandEvent
&event
);
112 void OnOption(wxCommandEvent
&event
);
114 wxColour
SelectColour();
115 void PrepareDC(wxDC
& dc
);
117 int m_backgroundMode
;
118 int m_textureBackground
;
122 int m_xLogicalOrigin
;
123 int m_yLogicalOrigin
;
124 bool m_xAxisReversed
,
126 wxColour m_colourForeground
, // these are _text_ colours
128 wxBrush m_backgroundBrush
;
132 // any class wishing to process wxWindows events must use this macro
133 DECLARE_EVENT_TABLE()
136 // define a scrollable canvas for drawing onto
137 class MyCanvas
: public wxScrolledWindow
140 MyCanvas( MyFrame
*parent
);
142 void OnPaint(wxPaintEvent
&event
);
143 void OnMouseMove(wxMouseEvent
&event
);
145 void Show(ScreenToShow show
) { m_show
= show
; Refresh(); }
148 void DrawTestPoly( int x
, int y
, wxDC
&dc
,int transparent
);
149 void DrawTestLines( int x
, int y
, int width
, wxDC
&dc
);
150 void DrawText(wxDC
& dc
);
151 void DrawImages(wxDC
& dc
);
152 void DrawWithLogicalOps(wxDC
& dc
);
153 void DrawRegions(wxDC
& dc
);
154 void DrawDefault(wxDC
& dc
);
160 wxBitmap m_smile_bmp
;
163 DECLARE_EVENT_TABLE()
166 // ----------------------------------------------------------------------------
168 // ----------------------------------------------------------------------------
170 // IDs for the controls and the menu commands
178 File_ShowDefault
= MenuShow_First
,
185 MenuShow_Last
= File_ShowRegions
,
189 MapMode_Text
= MenuOption_First
,
195 UserScale_StretchHoriz
,
196 UserScale_ShrinkHoriz
,
197 UserScale_StretchVertic
,
198 UserScale_ShrinkVertic
,
204 LogicalOrigin_MoveDown
,
205 LogicalOrigin_MoveUp
,
206 LogicalOrigin_MoveLeft
,
207 LogicalOrigin_MoveRight
,
209 Colour_TextForeground
,
210 Colour_TextBackground
,
212 Colour_BackgroundMode
,
213 Colour_TextureBackgound
,
215 MenuOption_Last
= Colour_TextureBackgound
218 // ----------------------------------------------------------------------------
219 // event tables and other macros for wxWindows
220 // ----------------------------------------------------------------------------
223 // Create a new application object: this macro will allow wxWindows to create
224 // the application object during program execution (it's better than using a
225 // static object for many reasons) and also declares the accessor function
226 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
230 // ============================================================================
232 // ============================================================================
234 // ----------------------------------------------------------------------------
235 // the application class
236 // ----------------------------------------------------------------------------
238 bool MyApp::LoadImages()
244 wxString path
= pathList
.FindValidPath("pat4.bmp");
247 /* 4 colour bitmap */
248 gs_bmp4
.LoadFile(path
, wxBITMAP_TYPE_BMP
);
249 /* turn into mono-bitmap */
250 gs_bmp4_mono
.LoadFile(path
, wxBITMAP_TYPE_BMP
);
251 wxMask
* mask4
= new wxMask(gs_bmp4_mono
, *wxBLACK
);
252 gs_bmp4_mono
.SetMask(mask4
);
254 path
= pathList
.FindValidPath("pat36.bmp");
257 gs_bmp36
.LoadFile(path
, wxBITMAP_TYPE_BMP
);
258 wxMask
* mask36
= new wxMask(gs_bmp36
, *wxBLACK
);
259 gs_bmp36
.SetMask(mask36
);
261 path
= pathList
.FindValidPath("image.bmp");
264 gs_bmpNoMask
.LoadFile(path
, wxBITMAP_TYPE_BMP
);
265 gs_bmpWithMask
.LoadFile(path
, wxBITMAP_TYPE_BMP
);
266 gs_bmpWithColMask
.LoadFile(path
, wxBITMAP_TYPE_BMP
);
268 path
= pathList
.FindValidPath("mask.bmp");
271 gs_bmpMask
.LoadFile(path
, wxBITMAP_TYPE_BMP
);
273 // This is so wrong, it hurts.
274 // gs_bmpMask.SetDepth(1);
275 // wxMask *mask = new wxMask(gs_bmpMask);
277 wxMask
*mask
= new wxMask(gs_bmpMask
, *wxBLACK
);
278 gs_bmpWithMask
.SetMask(mask
);
280 mask
= new wxMask(gs_bmpWithColMask
, *wxWHITE
);
281 gs_bmpWithColMask
.SetMask(mask
);
286 // `Main program' equivalent: the program execution "starts" here
289 // Create the main application window
290 MyFrame
*frame
= new MyFrame("Drawing sample",
291 wxPoint(50, 50), wxSize(550, 340));
293 // Show it and tell the application that it's our main window
299 wxLogError("Can't load one of the bitmap files needed for this sample "
300 "from the current or parent directory, please copy them "
311 // ----------------------------------------------------------------------------
313 // ----------------------------------------------------------------------------
315 // the event tables connect the wxWindows events with the functions (event
316 // handlers) which process them.
317 BEGIN_EVENT_TABLE(MyCanvas
, wxScrolledWindow
)
318 EVT_PAINT (MyCanvas::OnPaint
)
319 EVT_MOTION (MyCanvas::OnMouseMove
)
322 #include "../image/smile.xpm"
324 MyCanvas::MyCanvas( MyFrame
*parent
) : wxScrolledWindow( parent
)
327 m_show
= Show_Default
;
328 m_smile_bmp
= wxBitmap(smile_xpm
);
329 m_std_icon
= wxTheApp
->GetStdIcon(wxICON_INFORMATION
);
332 // Draw a polygon and an overlapping rectangle
333 // If transparent is 1, the fill pattern is made transparent.
334 // If transparent is 2, the fill pattern is made transparent but inversed
335 // If is transparent is 0 the text for and background color will be used to represent/map
336 // the colors of the monochrome bitmap pixels to the fillpattern
338 // I abused the the menu items for setting so called back and fore ground color
339 // just to show how the those colors do influence the fillpatterns just play
340 // with those, and with the code variations are endless using other logical
343 void MyCanvas::DrawTestPoly( int x
, int y
,wxDC
&dc
,int transparent
)
345 wxBrush
* brush4
= new wxBrush(gs_bmp4
);
346 wxBrush
* brush4_mono
= new wxBrush(gs_bmp4_mono
);
347 wxBrush
* brush36
= new wxBrush(gs_bmp36
);
350 todraw
[0].x
=(long)x
+100;
351 todraw
[0].y
=(long)y
+100;
352 todraw
[1].x
=(long)x
+300;
353 todraw
[1].y
=(long)y
+100;
354 todraw
[2].x
=(long)x
+300;
355 todraw
[2].y
=(long)y
+300;
356 todraw
[3].x
=(long)x
+150;
357 todraw
[3].y
=(long)y
+350;
358 todraw
[4].x
=(long)x
+100;
359 todraw
[4].y
=(long)y
+300;
377 dc
.SetLogicalFunction(wxCOPY
);
379 dc
.SetPen( wxPen( "black", 4, wxSOLID
) );
380 dc
.SetBrush( *brush4
);
381 dc
.DrawPolygon(5,todraw
,0,0,wxWINDING_RULE
);
383 dc
.SetPen( wxPen( "red", 4, wxSOLID
) );
384 dc
.SetBrush( *brush36
);
385 dc
.SetTextForeground(*wxCYAN
);
386 dc
.SetTextBackground(m_owner
->m_colourBackground
);
387 dc
.DrawRectangle( x
+10, y
+10, 200, 200 );
389 dc
.SetPen( wxPen( "green", 4, wxSOLID
) );
390 dc
.SetBrush( *brush4_mono
);
391 dc
.SetTextForeground(*wxCYAN
);
392 dc
.SetTextBackground(m_owner
->m_colourBackground
);
393 dc
.DrawRectangle( x
+50, y
+50, 200, 200 );
395 dc
.SetBrush(wxNullBrush
);
396 dc
.SetPen(wxNullPen
);
399 case 1: //now with transparent fillpatterns
402 wxBitmap
* bmpBlit
= new wxBitmap(600,400);
403 wxMemoryDC
* memDC
= new wxMemoryDC();
404 // wxBrush _clearbrush(*wxGREEN,wxSOLID);
405 wxBrush
_clearbrush(*wxBLACK
,wxSOLID
);
406 memDC
->SelectObject(*bmpBlit
);
407 memDC
->BeginDrawing();
408 memDC
->SetBackground(_clearbrush
);
410 memDC
->SetBackground(wxNullBrush
);
412 memDC
->SetPen( wxPen( "black", 4, wxSOLID
) );
413 memDC
->SetBrush( wxNullBrush
);
414 memDC
->SetBrush( *brush4
);
415 memDC
->SetTextForeground(*wxBLACK
); // 0s --> 0x000000 (black)
416 memDC
->SetTextBackground(*wxWHITE
); // 1s --> 0xFFFFFF (white)
417 memDC
->SetLogicalFunction(wxAND_INVERT
);
419 // BLACK OUT the opaque pixels and leave the rest as is
420 memDC
->DrawPolygon(5,todraw2
,0,0,wxWINDING_RULE
);
422 // Set background and foreground colors for fill pattern
423 //the previous blacked out pixels are now merged with the layer color
424 //while the non blacked out pixels stay as they are.
425 memDC
->SetTextForeground(*wxBLACK
); // 0s --> 0x000000 (black)
427 //now define what will be the color of the fillpattern parts that are not transparent
428 // memDC->SetTextBackground(*wxBLUE);
429 memDC
->SetTextBackground(m_owner
->m_colourForeground
);
430 memDC
->SetLogicalFunction(wxOR
);
433 //don't understand how but the outline is also depending on logicalfunction
434 memDC
->SetPen( wxPen( "red", 4, wxSOLID
) );
435 memDC
->DrawPolygon(5,todraw2
,0,0,wxWINDING_RULE
);
437 memDC
->SetLogicalFunction(wxCOPY
);
439 memDC
->SetPen( wxPen( "black", 4, wxSOLID
) );
440 memDC
->SetBrush( wxNullBrush
);
441 memDC
->SetBrush( *brush36
);
442 memDC
->SetTextForeground(*wxBLACK
); // 0s --> 0x000000 (black)
443 memDC
->SetTextBackground(*wxWHITE
); // 1s --> 0xFFFFFF (white)
444 memDC
->SetLogicalFunction(wxAND_INVERT
);
446 memDC
->DrawRectangle( 10, 10, 200, 200 );
448 // Set background and foreground colors for fill pattern
449 //the previous blacked out pixels are now merged with the layer color
450 //while the non blacked out pixels stay as they are.
451 memDC
->SetTextForeground(*wxBLACK
); // 0s --> 0x000000 (black)
452 //now define what will be the color of the fillpattern parts that are not transparent
453 // memDC->SetTextBackground(*wxRED);
454 memDC
->SetTextBackground(m_owner
->m_colourBackground
);
455 memDC
->SetLogicalFunction(wxOR
);
457 //don't understand how but the outline is also depending on logicalfunction
458 memDC
->SetPen( wxPen( "yellow", 4, wxSOLID
) );
459 memDC
->DrawRectangle( 10, 10, 200, 200 );
461 memDC
->SetBrush(wxNullBrush
);
462 memDC
->SetPen(wxNullPen
);
465 dc
.Blit(x
,y
,600,400,memDC
,0,0,wxCOPY
);
470 case 2: //now with transparent inversed fillpatterns
472 wxBitmap
* bmpBlit
= new wxBitmap(600,400);
473 wxMemoryDC
* memDC
= new wxMemoryDC();
474 wxBrush
_clearbrush(*wxWHITE
,wxSOLID
);
475 memDC
->SelectObject(*bmpBlit
);
476 memDC
->BeginDrawing();
477 memDC
->SetBackground(_clearbrush
);
479 memDC
->SetBackground(wxNullBrush
);
481 memDC
->SetPen( wxPen( "black", 4, wxSOLID
) );
482 memDC
->SetBrush( *brush4
);
483 memDC
->SetTextBackground(*wxBLACK
); // 0s --> 0x000000 (black)
484 memDC
->SetTextForeground(*wxWHITE
); // 1s --> 0xFFFFFF (white)
485 memDC
->SetLogicalFunction(wxAND_INVERT
);
487 // BLACK OUT the opaque pixels and leave the rest as is
488 memDC
->DrawPolygon(5,todraw2
,0,0,wxWINDING_RULE
);
490 // Set background and foreground colors for fill pattern
491 //the previous blacked out pixels are now merged with the layer color
492 //while the non blacked out pixels stay as they are.
493 memDC
->SetTextBackground(*wxBLACK
); // 0s --> 0x000000 (black)
495 //now define what will be the color of the fillpattern parts that are not transparent
496 memDC
->SetTextForeground(m_owner
->m_colourForeground
);
497 memDC
->SetLogicalFunction(wxOR
);
500 //don't understand how but the outline is also depending on logicalfunction
501 memDC
->SetPen( wxPen( "red", 4, wxSOLID
) );
502 memDC
->DrawPolygon(5,todraw2
,0,0,wxWINDING_RULE
);
504 memDC
->SetLogicalFunction(wxCOPY
);
506 memDC
->SetPen( wxPen( "black", 4, wxSOLID
) );
507 memDC
->SetBrush( *brush36
);
508 memDC
->SetTextBackground(*wxBLACK
); // 0s --> 0x000000 (black)
509 memDC
->SetTextForeground(*wxWHITE
); // 1s --> 0xFFFFFF (white)
510 memDC
->SetLogicalFunction(wxAND_INVERT
);
512 memDC
->DrawRectangle( 10,10, 200, 200 );
514 // Set background and foreground colors for fill pattern
515 //the previous blacked out pixels are now merged with the layer color
516 //while the non blacked out pixels stay as they are.
517 memDC
->SetTextBackground(*wxBLACK
); // 0s --> 0x000000 (black)
518 //now define what will be the color of the fillpattern parts that are not transparent
519 memDC
->SetTextForeground(m_owner
->m_colourBackground
);
520 memDC
->SetLogicalFunction(wxOR
);
522 //don't understand how but the outline is also depending on logicalfunction
523 memDC
->SetPen( wxPen( "yellow", 4, wxSOLID
) );
524 memDC
->DrawRectangle( 10, 10, 200, 200 );
526 memDC
->SetBrush(wxNullBrush
);
527 memDC
->SetPen(wxNullPen
);
528 dc
.Blit(x
,y
,600,400,memDC
,0,0,wxCOPY
);
539 void MyCanvas::DrawTestLines( int x
, int y
, int width
, wxDC
&dc
)
541 dc
.SetPen( wxPen( "black", width
, wxSOLID
) );
542 dc
.SetBrush( *wxRED_BRUSH
);
543 dc
.DrawRectangle( x
+10, y
+10, 100, 190 );
545 dc
.SetPen( wxPen( "black", width
, wxSOLID
) );
546 dc
.DrawLine( x
+20, y
+20, 100, y
+20 );
547 dc
.SetPen( wxPen( "black", width
, wxDOT
) );
548 dc
.DrawLine( x
+20, y
+30, 100, y
+30 );
549 dc
.SetPen( wxPen( "black", width
, wxSHORT_DASH
) );
550 dc
.DrawLine( x
+20, y
+40, 100, y
+40 );
551 dc
.SetPen( wxPen( "black", width
, wxLONG_DASH
) );
552 dc
.DrawLine( x
+20, y
+50, 100, y
+50 );
553 dc
.SetPen( wxPen( "black", width
, wxDOT_DASH
) );
554 dc
.DrawLine( x
+20, y
+60, 100, y
+60 );
556 dc
.SetPen( wxPen( "black", width
, wxBDIAGONAL_HATCH
) );
557 dc
.DrawLine( x
+20, y
+70, 100, y
+70 );
558 dc
.SetPen( wxPen( "black", width
, wxCROSSDIAG_HATCH
) );
559 dc
.DrawLine( x
+20, y
+80, 100, y
+80 );
560 dc
.SetPen( wxPen( "black", width
, wxFDIAGONAL_HATCH
) );
561 dc
.DrawLine( x
+20, y
+90, 100, y
+90 );
562 dc
.SetPen( wxPen( "black", width
, wxCROSS_HATCH
) );
563 dc
.DrawLine( x
+20, y
+100, 100, y
+100 );
564 dc
.SetPen( wxPen( "black", width
, wxHORIZONTAL_HATCH
) );
565 dc
.DrawLine( x
+20, y
+110, 100, y
+110 );
566 dc
.SetPen( wxPen( "black", width
, wxVERTICAL_HATCH
) );
567 dc
.DrawLine( x
+20, y
+120, 100, y
+120 );
569 wxPen
ud( "black", width
, wxUSER_DASH
);
572 ud
.SetDashes( 1, dash1
);
573 dc
.DrawLine( x
+20, y
+140, 100, y
+140 );
575 ud
.SetDashes( 1, dash1
);
576 dc
.DrawLine( x
+20, y
+150, 100, y
+150 );
578 ud
.SetDashes( 1, dash1
);
579 dc
.DrawLine( x
+20, y
+160, 100, y
+160 );
581 ud
.SetDashes( 1, dash1
);
582 dc
.DrawLine( x
+20, y
+170, 100, y
+170 );
585 void MyCanvas::DrawDefault(wxDC
& dc
)
588 dc
.DrawCircle(0, 0, 10);
589 #if !(defined __WXGTK__) && !(defined __WXMOTIF__)
590 // not implemented in wxGTK or wxMOTIF :-(
591 dc
.FloodFill(0, 0, wxColour(255, 0, 0));
594 dc
.DrawCheckMark(5, 80, 15, 15);
595 dc
.DrawCheckMark(25, 80, 30, 30);
596 dc
.DrawCheckMark(60, 80, 60, 60);
598 // this is the test for "blitting bitmap into DC damages selected brush" bug
599 wxCoord rectSize
= m_std_icon
.GetWidth() + 10;
601 dc
.SetPen(*wxTRANSPARENT_PEN
);
602 dc
.SetBrush( *wxGREEN_BRUSH
);
603 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
604 dc
.DrawBitmap(m_std_icon
, x
+ 5, 15, TRUE
);
606 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
607 dc
.DrawIcon(m_std_icon
, x
+ 5, 15);
609 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
611 // test for "transparent" bitmap drawing (it intersects with the last
613 //dc.SetBrush( *wxTRANSPARENT_BRUSH );
615 if (m_smile_bmp
.Ok())
616 dc
.DrawBitmap(m_smile_bmp
, x
+ rectSize
- 20, rectSize
- 10, TRUE
);
618 dc
.SetBrush( *wxBLACK_BRUSH
);
619 dc
.DrawRectangle( 0, 160, 1000, 300 );
622 wxBitmap
bitmap(20,70);
624 memdc
.SelectObject( bitmap
);
625 memdc
.SetBrush( *wxBLACK_BRUSH
);
626 memdc
.SetPen( *wxWHITE_PEN
);
627 memdc
.DrawRectangle(0,0,20,70);
628 memdc
.DrawLine( 10,0,10,70 );
631 wxPen pen
= *wxRED_PEN
;
633 memdc
.DrawLine( 10, 5,10, 5 );
634 memdc
.DrawLine( 10,10,11,10 );
635 memdc
.DrawLine( 10,15,12,15 );
636 memdc
.DrawLine( 10,20,13,20 );
639 memdc.SetPen(*wxRED_PEN);
640 memdc.DrawLine( 12, 5,12, 5 );
641 memdc.DrawLine( 12,10,13,10 );
642 memdc.DrawLine( 12,15,14,15 );
643 memdc.DrawLine( 12,20,15,20 );
647 memdc
.DrawLine( 10,25,10,25 );
648 memdc
.DrawLine( 10,30, 9,30 );
649 memdc
.DrawLine( 10,35, 8,35 );
650 memdc
.DrawLine( 10,40, 7,40 );
653 dc
.SetPen(*wxWHITE_PEN
);
654 memdc
.SetLogicalFunction( wxINVERT
);
655 memdc
.SetPen( *wxWHITE_PEN
);
656 memdc
.DrawLine( 10,50,10,50 );
657 memdc
.DrawLine( 10,55,11,55 );
658 memdc
.DrawLine( 10,60,12,60 );
659 memdc
.DrawLine( 10,65,13,65 );
661 memdc
.DrawLine( 12,50,12,50 );
662 memdc
.DrawLine( 12,55,13,55 );
663 memdc
.DrawLine( 12,60,14,60 );
664 memdc
.DrawLine( 12,65,15,65 );
666 memdc
.SelectObject( wxNullBitmap
);
667 dc
.DrawBitmap( bitmap
, 10, 170 );
668 wxImage
image( bitmap
);
669 image
.Rescale( 60,210 );
670 bitmap
= image
.ConvertToBitmap();
671 dc
.DrawBitmap( bitmap
, 50, 170 );
673 // test the rectangle outline drawing - there should be one pixel between
674 // the rect and the lines
675 dc
.SetPen(*wxWHITE_PEN
);
676 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
677 dc
.DrawRectangle(150, 170, 49, 29);
678 dc
.DrawRectangle(200, 170, 49, 29);
679 dc
.SetPen(*wxWHITE_PEN
);
680 dc
.DrawLine(250, 210, 250, 170);
681 dc
.DrawLine(260, 200, 150, 200);
683 // test the rectangle filled drawing - there should be one pixel between
684 // the rect and the lines
685 dc
.SetPen(*wxTRANSPARENT_PEN
);
686 dc
.SetBrush( *wxWHITE_BRUSH
);
687 dc
.DrawRectangle(300, 170, 49, 29);
688 dc
.DrawRectangle(350, 170, 49, 29);
689 dc
.SetPen(*wxWHITE_PEN
);
690 dc
.DrawLine(400, 170, 400, 210);
691 dc
.DrawLine(300, 200, 410, 200);
693 // a few more tests of this kind
694 dc
.SetPen(*wxRED_PEN
);
695 dc
.SetBrush( *wxWHITE_BRUSH
);
696 dc
.DrawRectangle(300, 220, 1, 1);
697 dc
.DrawRectangle(310, 220, 2, 2);
698 dc
.DrawRectangle(320, 220, 3, 3);
699 dc
.DrawRectangle(330, 220, 4, 4);
701 dc
.SetPen(*wxTRANSPARENT_PEN
);
702 dc
.SetBrush( *wxWHITE_BRUSH
);
703 dc
.DrawRectangle(300, 230, 1, 1);
704 dc
.DrawRectangle(310, 230, 2, 2);
705 dc
.DrawRectangle(320, 230, 3, 3);
706 dc
.DrawRectangle(330, 230, 4, 4);
708 // and now for filled rect with outline
709 dc
.SetPen(*wxRED_PEN
);
710 dc
.SetBrush( *wxWHITE_BRUSH
);
711 dc
.DrawRectangle(500, 170, 49, 29);
712 dc
.DrawRectangle(550, 170, 49, 29);
713 dc
.SetPen(*wxWHITE_PEN
);
714 dc
.DrawLine(600, 170, 600, 210);
715 dc
.DrawLine(500, 200, 610, 200);
717 // test the rectangle outline drawing - there should be one pixel between
718 // the rect and the lines
719 dc
.SetPen(*wxWHITE_PEN
);
720 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
721 dc
.DrawRoundedRectangle(150, 270, 49, 29, 6);
722 dc
.DrawRoundedRectangle(200, 270, 49, 29, 6);
723 dc
.SetPen(*wxWHITE_PEN
);
724 dc
.DrawLine(250, 270, 250, 310);
725 dc
.DrawLine(150, 300, 260, 300);
727 // test the rectangle filled drawing - there should be one pixel between
728 // the rect and the lines
729 dc
.SetPen(*wxTRANSPARENT_PEN
);
730 dc
.SetBrush( *wxWHITE_BRUSH
);
731 dc
.DrawRoundedRectangle(300, 270, 49, 29, 6);
732 dc
.DrawRoundedRectangle(350, 270, 49, 29, 6);
733 dc
.SetPen(*wxWHITE_PEN
);
734 dc
.DrawLine(400, 270, 400, 310);
735 dc
.DrawLine(300, 300, 410, 300);
737 // Added by JACS to demonstrate bizarre behaviour.
738 // With a size of 70, we get a missing red RHS,
739 // and the hight is too small, so we get yellow
740 // showing. With a size of 40, it draws as expected:
741 // it just shows a white rectangle with red outline.
743 int totalHeight
= 70;
744 wxBitmap
bitmap2(totalWidth
, totalHeight
);
747 memdc2
.SelectObject(bitmap2
);
749 wxBrush
yellowBrush(wxColour(255, 255, 0), wxSOLID
);
750 memdc2
.SetBackground(yellowBrush
);
753 wxPen
yellowPen(wxColour(255, 255, 0), 1, wxSOLID
);
755 // Now draw a white rectangle with red outline. It should
756 // entirely eclipse the yellow background.
757 memdc2
.SetPen(*wxRED_PEN
);
758 memdc2
.SetBrush(*wxWHITE_BRUSH
);
760 memdc2
.DrawRectangle(0, 0, totalWidth
, totalHeight
);
762 memdc2
.SetPen(wxNullPen
);
763 memdc2
.SetBrush(wxNullBrush
);
764 memdc2
.SelectObject(wxNullBitmap
);
766 dc
.DrawBitmap(bitmap2
, 500, 270);
768 // Repeat, but draw directly on dc
769 // Draw a yellow rectangle filling the bitmap
771 x
= 600; int y
= 270;
772 dc
.SetPen(yellowPen
);
773 dc
.SetBrush(yellowBrush
);
774 dc
.DrawRectangle(x
, y
, totalWidth
, totalHeight
);
776 // Now draw a white rectangle with red outline. It should
777 // entirely eclipse the yellow background.
778 dc
.SetPen(*wxRED_PEN
);
779 dc
.SetBrush(*wxWHITE_BRUSH
);
781 dc
.DrawRectangle(x
, y
, totalWidth
, totalHeight
);
784 void MyCanvas::DrawText(wxDC
& dc
)
786 // set underlined font for testing
787 dc
.SetFont( wxFont(12, wxMODERN
, wxNORMAL
, wxNORMAL
, TRUE
) );
788 dc
.DrawText( "This is text", 110, 10 );
789 dc
.DrawRotatedText( "That is text", 20, 10, -45 );
791 dc
.SetFont( *wxNORMAL_FONT
);
794 dc
. SetBackgroundMode(wxTRANSPARENT
);
796 for ( int n
= -180; n
< 180; n
+= 30 )
798 text
.Printf(" %d rotated text", n
);
799 dc
.DrawRotatedText(text
, 400, 400, n
);
802 dc
.SetFont( wxFont( 18, wxSWISS
, wxNORMAL
, wxNORMAL
) );
804 dc
.DrawText( "This is Swiss 18pt text.", 110, 40 );
809 dc
.GetTextExtent( "This is Swiss 18pt text.", &length
, &height
, &descent
);
810 text
.Printf( "Dimensions are length %ld, height %ld, descent %ld", length
, height
, descent
);
811 dc
.DrawText( text
, 110, 80 );
813 text
.Printf( "CharHeight() returns: %d", dc
.GetCharHeight() );
814 dc
.DrawText( text
, 110, 120 );
816 dc
.DrawRectangle( 100, 40, 4, height
);
823 } rasterOperations
[] =
826 { "wxAND_INVERT", wxAND_INVERT
},
827 { "wxAND_REVERSE", wxAND_REVERSE
},
828 { "wxCLEAR", wxCLEAR
},
829 { "wxCOPY", wxCOPY
},
830 { "wxEQUIV", wxEQUIV
},
831 { "wxINVERT", wxINVERT
},
832 { "wxNAND", wxNAND
},
833 { "wxNO_OP", wxNO_OP
},
835 { "wxOR_INVERT", wxOR_INVERT
},
836 { "wxOR_REVERSE", wxOR_REVERSE
},
838 { "wxSRC_INVERT", wxSRC_INVERT
},
842 void MyCanvas::DrawImages(wxDC
& dc
)
844 dc
.DrawText("original image", 0, 0);
845 dc
.DrawBitmap(gs_bmpNoMask
, 0, 20, 0);
846 dc
.DrawText("with colour mask", 0, 100);
847 dc
.DrawBitmap(gs_bmpWithColMask
, 0, 120, TRUE
);
848 dc
.DrawText("the mask image", 0, 200);
849 dc
.DrawBitmap(gs_bmpMask
, 0, 220, 0);
850 dc
.DrawText("masked image", 0, 300);
851 dc
.DrawBitmap(gs_bmpWithMask
, 0, 320, TRUE
);
853 int cx
= gs_bmpWithColMask
.GetWidth(),
854 cy
= gs_bmpWithColMask
.GetHeight();
857 for ( size_t n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
859 wxCoord x
= 120 + 150*(n%4
),
862 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
863 memDC
.SelectObject(gs_bmpWithColMask
);
864 dc
.Blit(x
, y
, cx
, cy
, &memDC
, 0, 0, rasterOperations
[n
].rop
, TRUE
);
868 void MyCanvas::DrawWithLogicalOps(wxDC
& dc
)
870 static const wxCoord w
= 60;
871 static const wxCoord h
= 60;
873 // reuse the text colour here
874 dc
.SetPen(wxPen(m_owner
->m_colourForeground
, 1, wxSOLID
));
875 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
878 for ( n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
880 wxCoord x
= 20 + 150*(n%4
),
883 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
884 dc
.SetLogicalFunction(rasterOperations
[n
].rop
);
885 dc
.DrawRectangle(x
, y
, w
, h
);
886 dc
.DrawLine(x
, y
, x
+ w
, y
+ h
);
887 dc
.DrawLine(x
+ w
, y
, x
, y
+ h
);
890 // now some filled rectangles
891 dc
.SetBrush(wxBrush(m_owner
->m_colourForeground
, wxSOLID
));
893 for ( n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
895 wxCoord x
= 20 + 150*(n%4
),
898 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
899 dc
.SetLogicalFunction(rasterOperations
[n
].rop
);
900 dc
.DrawRectangle(x
, y
, w
, h
);
904 void MyCanvas::DrawRegions(wxDC
& dc
)
906 dc
.SetBrush( *wxWHITE_BRUSH
);
907 dc
.SetPen( *wxTRANSPARENT_PEN
);
908 dc
.DrawRectangle( 10,10,310,310 );
910 dc
.SetClippingRegion( 20,20,100,270 );
912 dc
.SetBrush( *wxRED_BRUSH
);
913 dc
.DrawRectangle( 10,10,310,310 );
915 dc
.SetClippingRegion( 20,20,100,100 );
917 dc
.SetBrush( *wxCYAN_BRUSH
);
918 dc
.DrawRectangle( 10,10,310,310 );
920 dc
.DestroyClippingRegion();
921 dc
.SetClippingRegion( 120,30,100,270 );
923 dc
.SetBrush( *wxGREY_BRUSH
);
924 dc
.DrawRectangle( 10,10,310,310 );
926 if (m_smile_bmp
.Ok())
928 dc
.DrawBitmap( m_smile_bmp
, 140, 20, TRUE
);
929 dc
.DrawBitmap( m_smile_bmp
, 140, 290, TRUE
);
930 dc
.DrawBitmap( m_smile_bmp
, 110, 80, TRUE
);
931 dc
.DrawBitmap( m_smile_bmp
, 210, 80, TRUE
);
935 void MyCanvas::OnPaint(wxPaintEvent
&WXUNUSED(event
))
939 m_owner
->PrepareDC(dc
);
941 dc
.SetBackgroundMode( m_owner
->m_backgroundMode
);
942 if ( m_owner
->m_backgroundBrush
.Ok() )
943 dc
.SetBackground( m_owner
->m_backgroundBrush
);
944 if ( m_owner
->m_colourForeground
.Ok() )
945 dc
.SetTextForeground( m_owner
->m_colourForeground
);
946 if ( m_owner
->m_colourBackground
.Ok() )
947 dc
.SetTextBackground( m_owner
->m_colourBackground
);
949 if ( m_owner
->m_textureBackground
) {
950 if ( ! m_owner
->m_backgroundBrush
.Ok() ) {
951 wxBrush
b(wxColour(0,128,0), wxSOLID
);
958 if ( m_owner
->m_textureBackground
) {
959 dc
.SetPen(*wxMEDIUM_GREY_PEN
);
960 for (int i
=0; i
<200; i
++)
961 dc
.DrawLine(0, i
*10, i
*10, 0);
979 DrawTestLines( 0, 100, 0, dc
);
980 DrawTestLines( 0, 300, 1, dc
);
981 DrawTestLines( 0, 500, 2, dc
);
982 DrawTestLines( 0, 700, 6, dc
);
986 DrawTestPoly( 0, 100, dc
, 0 );
988 DrawTestPoly( 33, 500, dc, 1 );
989 DrawTestPoly( 43, 1000, dc, 2 );
998 DrawWithLogicalOps(dc
);
1003 void MyCanvas::OnMouseMove(wxMouseEvent
&event
)
1005 wxClientDC
dc(this);
1007 m_owner
->PrepareDC(dc
);
1009 wxPoint pos
= event
.GetPosition();
1010 long x
= dc
.DeviceToLogicalX( pos
.x
);
1011 long y
= dc
.DeviceToLogicalY( pos
.y
);
1013 str
.Printf( "Current mouse position: %d,%d", (int)x
, (int)y
);
1014 m_owner
->SetStatusText( str
);
1017 // ----------------------------------------------------------------------------
1019 // ----------------------------------------------------------------------------
1021 // the event tables connect the wxWindows events with the functions (event
1022 // handlers) which process them. It can be also done at run-time, but for the
1023 // simple menu events like this the static method is much simpler.
1024 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
1025 EVT_MENU (File_Quit
, MyFrame::OnQuit
)
1026 EVT_MENU (File_About
, MyFrame::OnAbout
)
1028 EVT_MENU_RANGE(MenuShow_First
, MenuShow_Last
, MyFrame::OnShow
)
1030 EVT_MENU_RANGE(MenuOption_First
, MenuOption_Last
, MyFrame::OnOption
)
1033 // frame constructor
1034 MyFrame::MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
)
1035 : wxFrame((wxFrame
*)NULL
, -1, title
, pos
, size
)
1037 // set the frame icon
1038 SetIcon(wxICON(mondrian
));
1040 wxMenu
*menuFile
= new wxMenu
;
1041 menuFile
->Append(File_ShowDefault
, "&Default screen\tF1");
1042 menuFile
->Append(File_ShowText
, "&Text screen\tF2");
1043 menuFile
->Append(File_ShowLines
, "&Lines screen\tF3");
1044 menuFile
->Append(File_ShowPolygons
, "&Polygons screen\tF4");
1045 menuFile
->Append(File_ShowMask
, "wx&Mask screen\tF5");
1046 menuFile
->Append(File_ShowOps
, "&ROP screen\tF6");
1047 menuFile
->Append(File_ShowRegions
, "Re&gions screen\tF6");
1048 menuFile
->AppendSeparator();
1049 menuFile
->Append(File_About
, "&About...\tCtrl-A", "Show about dialog");
1050 menuFile
->AppendSeparator();
1051 menuFile
->Append(File_Quit
, "E&xit\tAlt-X", "Quit this program");
1053 wxMenu
*menuMapMode
= new wxMenu
;
1054 menuMapMode
->Append( MapMode_Text
, "&TEXT map mode" );
1055 menuMapMode
->Append( MapMode_Lometric
, "&LOMETRIC map mode" );
1056 menuMapMode
->Append( MapMode_Twips
, "T&WIPS map mode" );
1057 menuMapMode
->Append( MapMode_Points
, "&POINTS map mode" );
1058 menuMapMode
->Append( MapMode_Metric
, "&METRIC map mode" );
1060 wxMenu
*menuUserScale
= new wxMenu
;
1061 menuUserScale
->Append( UserScale_StretchHoriz
, "Stretch horizontally\tCtrl-H" );
1062 menuUserScale
->Append( UserScale_ShrinkHoriz
, "Shrink horizontally\tCtrl-G" );
1063 menuUserScale
->Append( UserScale_StretchVertic
, "Stretch vertically\tCtrl-V" );
1064 menuUserScale
->Append( UserScale_ShrinkVertic
, "Shrink vertically\tCtrl-W" );
1065 menuUserScale
->AppendSeparator();
1066 menuUserScale
->Append( UserScale_Restore
, "Restore to normal\tCtrl-0" );
1068 wxMenu
*menuAxis
= new wxMenu
;
1069 menuAxis
->Append( AxisMirror_Horiz
, "Mirror horizontally\tCtrl-M", "", TRUE
);
1070 menuAxis
->Append( AxisMirror_Vertic
, "Mirror vertically\tCtrl-N", "", TRUE
);
1072 wxMenu
*menuLogical
= new wxMenu
;
1073 menuLogical
->Append( LogicalOrigin_MoveDown
, "Move &down\tCtrl-D" );
1074 menuLogical
->Append( LogicalOrigin_MoveUp
, "Move &up\tCtrl-U" );
1075 menuLogical
->Append( LogicalOrigin_MoveLeft
, "Move &right\tCtrl-L" );
1076 menuLogical
->Append( LogicalOrigin_MoveRight
, "Move &left\tCtrl-R" );
1078 wxMenu
*menuColour
= new wxMenu
;
1079 menuColour
->Append( Colour_TextForeground
, "Text foreground..." );
1080 menuColour
->Append( Colour_TextBackground
, "Text background..." );
1081 menuColour
->Append( Colour_Background
, "Background colour..." );
1082 menuColour
->Append( Colour_BackgroundMode
, "Opaque/transparent\tCtrl-B", "", TRUE
);
1083 menuColour
->Append( Colour_TextureBackgound
, "Draw textured background\tCtrl-T", "", TRUE
);
1085 // now append the freshly created menu to the menu bar...
1086 wxMenuBar
*menuBar
= new wxMenuBar
;
1087 menuBar
->Append(menuFile
, "&File");
1088 menuBar
->Append(menuMapMode
, "&MapMode");
1089 menuBar
->Append(menuUserScale
, "&UserScale");
1090 menuBar
->Append(menuAxis
, "&Axis");
1091 menuBar
->Append(menuLogical
, "&LogicalOrigin");
1092 menuBar
->Append(menuColour
, "&Colours");
1094 // ... and attach this menu bar to the frame
1095 SetMenuBar(menuBar
);
1097 // create a status bar just for fun (by default with 1 pane only)
1099 SetStatusText("Welcome to wxWindows!");
1101 m_mapMode
= wxMM_TEXT
;
1104 m_xLogicalOrigin
= 0;
1105 m_yLogicalOrigin
= 0;
1107 m_yAxisReversed
= FALSE
;
1108 m_backgroundMode
= wxSOLID
;
1109 m_colourForeground
= *wxRED
;
1110 m_colourBackground
= *wxBLUE
;
1111 m_textureBackground
= FALSE
;
1113 m_canvas
= new MyCanvas( this );
1114 m_canvas
->SetScrollbars( 10, 10, 100, 240 );
1119 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
1121 // TRUE is to force the frame to close
1125 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
1128 msg
.Printf( wxT("This is the about dialog of the drawing sample.\n")
1129 wxT("This sample tests various primitive drawing functions\n")
1130 wxT("without any tests to prevent flicker.\n")
1131 wxT("Copyright (c) Robert Roebling 1999")
1134 wxMessageBox(msg
, "About Drawing", wxOK
| wxICON_INFORMATION
, this);
1137 void MyFrame::OnShow(wxCommandEvent
& event
)
1139 m_canvas
->Show((ScreenToShow
)(event
.GetInt() - MenuShow_First
));
1142 void MyFrame::OnOption(wxCommandEvent
& event
)
1144 switch (event
.GetInt())
1147 m_mapMode
= wxMM_TEXT
;
1149 case MapMode_Lometric
:
1150 m_mapMode
= wxMM_LOMETRIC
;
1153 m_mapMode
= wxMM_TWIPS
;
1155 case MapMode_Points
:
1156 m_mapMode
= wxMM_POINTS
;
1158 case MapMode_Metric
:
1159 m_mapMode
= wxMM_METRIC
;
1162 case LogicalOrigin_MoveDown
:
1163 m_yLogicalOrigin
+= 10;
1165 case LogicalOrigin_MoveUp
:
1166 m_yLogicalOrigin
-= 10;
1168 case LogicalOrigin_MoveLeft
:
1169 m_xLogicalOrigin
+= 10;
1171 case LogicalOrigin_MoveRight
:
1172 m_xLogicalOrigin
-= 10;
1175 case UserScale_StretchHoriz
:
1176 m_xUserScale
*= 1.10;
1178 case UserScale_ShrinkHoriz
:
1179 m_xUserScale
/= 1.10;
1181 case UserScale_StretchVertic
:
1182 m_yUserScale
*= 1.10;
1184 case UserScale_ShrinkVertic
:
1185 m_yUserScale
/= 1.10;
1187 case UserScale_Restore
:
1192 case AxisMirror_Vertic
:
1193 m_yAxisReversed
= !m_yAxisReversed
;
1195 case AxisMirror_Horiz
:
1196 m_xAxisReversed
= !m_xAxisReversed
;
1199 case Colour_TextForeground
:
1200 m_colourForeground
= SelectColour();
1202 case Colour_TextBackground
:
1203 m_colourBackground
= SelectColour();
1205 case Colour_Background
:
1207 wxColour col
= SelectColour();
1210 m_backgroundBrush
.SetColour(col
);
1214 case Colour_BackgroundMode
:
1215 m_backgroundMode
= m_backgroundMode
== wxSOLID
? wxTRANSPARENT
1219 case Colour_TextureBackgound
:
1220 m_textureBackground
= ! m_textureBackground
;
1228 m_canvas
->Refresh();
1231 void MyFrame::PrepareDC(wxDC
& dc
)
1233 dc
.SetMapMode( m_mapMode
);
1234 dc
.SetUserScale( m_xUserScale
, m_yUserScale
);
1235 dc
.SetLogicalOrigin( m_xLogicalOrigin
, m_yLogicalOrigin
);
1236 dc
.SetAxisOrientation( !m_xAxisReversed
, m_yAxisReversed
);
1239 wxColour
MyFrame::SelectColour()
1243 wxColourDialog
dialog(this, &data
);
1245 if ( dialog
.ShowModal() == wxID_OK
)
1247 col
= dialog
.GetColourData().GetColour();