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)
66 // ----------------------------------------------------------------------------
68 // ----------------------------------------------------------------------------
70 static wxBitmap gs_bmpNoMask
,
77 // ----------------------------------------------------------------------------
79 // ----------------------------------------------------------------------------
81 // Define a new application type, each program should derive a class from wxApp
82 class MyApp
: public wxApp
85 // override base class virtuals
86 // ----------------------------
88 // this one is called on application startup and is a good place for the app
89 // initialization (doing it here and not in the ctor allows to have an error
90 // return: if OnInit() returns false, the application terminates)
91 virtual bool OnInit();
99 // Define a new frame type: this is going to be our main frame
100 class MyFrame
: public wxFrame
104 MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
);
106 // event handlers (these functions should _not_ be virtual)
107 void OnQuit(wxCommandEvent
& event
);
108 void OnAbout(wxCommandEvent
& event
);
109 void OnShow(wxCommandEvent
&event
);
110 void OnOption(wxCommandEvent
&event
);
112 wxColour
SelectColour();
113 void PrepareDC(wxDC
& dc
);
115 int m_backgroundMode
;
116 int m_textureBackground
;
120 int m_xLogicalOrigin
;
121 int m_yLogicalOrigin
;
122 bool m_xAxisReversed
,
124 wxColour m_colourForeground
, // these are _text_ colours
126 wxBrush m_backgroundBrush
;
130 // any class wishing to process wxWindows events must use this macro
131 DECLARE_EVENT_TABLE()
134 // define a scrollable canvas for drawing onto
135 class MyCanvas
: public wxScrolledWindow
138 MyCanvas( MyFrame
*parent
);
140 void OnPaint(wxPaintEvent
&event
);
141 void OnMouseMove(wxMouseEvent
&event
);
143 void Show(ScreenToShow show
) { m_show
= show
; Refresh(); }
146 void DrawTestPoly( int x
, int y
, wxDC
&dc
,int transparent
);
147 void DrawTestLines( int x
, int y
, int width
, wxDC
&dc
);
148 void DrawText(wxDC
& dc
);
149 void DrawImages(wxDC
& dc
);
150 void DrawWithLogicalOps(wxDC
& dc
);
151 void DrawDefault(wxDC
& dc
);
158 DECLARE_EVENT_TABLE()
161 // ----------------------------------------------------------------------------
163 // ----------------------------------------------------------------------------
165 // IDs for the controls and the menu commands
173 File_ShowDefault
= MenuShow_First
,
179 MenuShow_Last
= File_ShowOps
,
183 MapMode_Text
= MenuOption_First
,
189 UserScale_StretchHoriz
,
190 UserScale_ShrinkHoriz
,
191 UserScale_StretchVertic
,
192 UserScale_ShrinkVertic
,
198 LogicalOrigin_MoveDown
,
199 LogicalOrigin_MoveUp
,
200 LogicalOrigin_MoveLeft
,
201 LogicalOrigin_MoveRight
,
203 Colour_TextForeground
,
204 Colour_TextBackground
,
206 Colour_BackgroundMode
,
207 Colour_TextureBackgound
,
209 MenuOption_Last
= Colour_TextureBackgound
212 // ----------------------------------------------------------------------------
213 // event tables and other macros for wxWindows
214 // ----------------------------------------------------------------------------
217 // Create a new application object: this macro will allow wxWindows to create
218 // the application object during program execution (it's better than using a
219 // static object for many reasons) and also declares the accessor function
220 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
224 // ============================================================================
226 // ============================================================================
228 // ----------------------------------------------------------------------------
229 // the application class
230 // ----------------------------------------------------------------------------
232 bool MyApp
::LoadImages()
238 wxString path
= pathList
.FindValidPath("pat4.bmp");
241 gs_bmp4
.LoadFile(path
, wxBITMAP_TYPE_BMP
);
242 wxMask
* mask4
= new wxMask(gs_bmp4
, *wxBLACK
);
243 gs_bmp4
.SetMask(mask4
);
245 path
= pathList
.FindValidPath("pat36.bmp");
248 gs_bmp36
.LoadFile(path
, wxBITMAP_TYPE_BMP
);
249 wxMask
* mask36
= new wxMask(gs_bmp36
, *wxBLACK
);
250 gs_bmp36
.SetMask(mask36
);
252 path
= pathList
.FindValidPath("image.bmp");
255 gs_bmpNoMask
.LoadFile(path
, wxBITMAP_TYPE_BMP
);
256 gs_bmpWithMask
.LoadFile(path
, wxBITMAP_TYPE_BMP
);
257 gs_bmpWithColMask
.LoadFile(path
, wxBITMAP_TYPE_BMP
);
259 path
= pathList
.FindValidPath("mask.bmp");
262 gs_bmpMask
.LoadFile(path
, wxBITMAP_TYPE_BMP
);
264 // This is so wrong, it hurts.
265 // gs_bmpMask.SetDepth(1);
266 // wxMask *mask = new wxMask(gs_bmpMask);
268 wxMask
*mask
= new wxMask(gs_bmpMask
, *wxBLACK
);
269 gs_bmpWithMask
.SetMask(mask
);
271 mask
= new wxMask(gs_bmpWithColMask
, *wxWHITE
);
272 gs_bmpWithColMask
.SetMask(mask
);
277 // `Main program' equivalent: the program execution "starts" here
280 // Create the main application window
281 MyFrame
*frame
= new MyFrame("Drawing sample",
282 wxPoint(50, 50), wxSize(550, 340));
284 // Show it and tell the application that it's our main window
290 wxLogError("Can't load one of the bitmap files needed for this sample "
291 "from the current or parent directory, please copy them "
302 // ----------------------------------------------------------------------------
304 // ----------------------------------------------------------------------------
306 // the event tables connect the wxWindows events with the functions (event
307 // handlers) which process them.
308 BEGIN_EVENT_TABLE(MyCanvas
, wxScrolledWindow
)
309 EVT_PAINT (MyCanvas
::OnPaint
)
310 EVT_MOTION (MyCanvas
::OnMouseMove
)
313 MyCanvas
::MyCanvas( MyFrame
*parent
) : wxScrolledWindow( parent
)
316 m_show
= Show_Default
;
319 //draw a polygon and an overlapping rectangle
320 //is transparent is 1, the fill pattern are made transparent
321 //is transparent is 2, the fill pattern are made transparent but inversed
322 //is transparent is 0 the text for and background color will be used to represent/map
323 //the colors of the monochrome bitmap pixels to the fillpattern
325 //i miss_used the the menu items for setting so called back and fore ground color
326 //just to show how the those colors do influence the fillpatterns
327 //just play with those,
329 //variations are endless using other logical functions
330 void MyCanvas
::DrawTestPoly( int x
, int y
,wxDC
&dc
,int transparent
)
332 wxBrush
* brush4
= new wxBrush(gs_bmp4
);
333 wxBrush
* brush36
= new wxBrush(gs_bmp36
);
336 todraw
[0].x
=(long)x
+100;
337 todraw
[0].y
=(long)y
+100;
338 todraw
[1].x
=(long)x
+300;
339 todraw
[1].y
=(long)y
+100;
340 todraw
[2].x
=(long)x
+300;
341 todraw
[2].y
=(long)y
+300;
342 todraw
[3].x
=(long)x
+150;
343 todraw
[3].y
=(long)y
+350;
344 todraw
[4].x
=(long)x
+100;
345 todraw
[4].y
=(long)y
+300;
363 dc
.SetPen( wxPen( "black", 4, wxSOLID
) );
364 dc
.SetBrush( *brush4
);
365 dc
.SetTextForeground(*wxGREEN
);
366 dc
.SetTextBackground(m_owner
->m_colourForeground
);
367 dc
.SetLogicalFunction(wxCOPY
);
368 dc
.DrawPolygon(5,todraw
,0,0,wxWINDING_RULE
);
370 //don't understand hwo but the outline is also depending on logicalfunction
371 dc
.SetPen( wxPen( "red", 4, wxSOLID
) );
372 dc
.SetBrush( *brush36
);
373 dc
.SetTextForeground(*wxCYAN
);
374 dc
.SetTextBackground(m_owner
->m_colourBackground
);
375 dc
.SetLogicalFunction(wxCOPY
);
376 dc
.DrawRectangle( x
+10, y
+10, 200, 200 );
377 dc
.SetBrush(wxNullBrush
);
378 dc
.SetPen(wxNullPen
);
381 case 1: //now with transparent fillpatterns
384 wxBitmap
* bmpBlit
= new wxBitmap(600,400);
385 wxMemoryDC
* memDC
= new wxMemoryDC();
386 // wxBrush _clearbrush(*wxGREEN,wxSOLID);
387 wxBrush
_clearbrush(*wxBLACK
,wxSOLID
);
388 memDC
->SelectObject(*bmpBlit
);
389 memDC
->BeginDrawing();
390 memDC
->SetBackground(_clearbrush
);
392 memDC
->SetBackground(wxNullBrush
);
394 memDC
->SetPen( wxPen( "black", 4, wxSOLID
) );
395 memDC
->SetBrush( wxNullBrush
);
396 memDC
->SetBrush( *brush4
);
397 memDC
->SetTextForeground(*wxBLACK
); // 0s --> 0x000000 (black)
398 memDC
->SetTextBackground(*wxWHITE
); // 1s --> 0xFFFFFF (white)
399 memDC
->SetLogicalFunction(wxAND_INVERT
);
401 // BLACK OUT the opaque pixels and leave the rest as is
402 memDC
->DrawPolygon(5,todraw2
,0,0,wxWINDING_RULE
);
404 // Set background and foreground colors for fill pattern
405 //the previous blacked out pixels are now merged with the layer color
406 //while the non blacked out pixels stay as they are.
407 memDC
->SetTextForeground(*wxBLACK
); // 0s --> 0x000000 (black)
409 //now define what will be the color of the fillpattern parts that are not transparent
410 // memDC->SetTextBackground(*wxBLUE);
411 memDC
->SetTextBackground(m_owner
->m_colourForeground
);
412 memDC
->SetLogicalFunction(wxOR
);
415 //don't understand how but the outline is also depending on logicalfunction
416 memDC
->SetPen( wxPen( "red", 4, wxSOLID
) );
417 memDC
->DrawPolygon(5,todraw2
,0,0,wxWINDING_RULE
);
419 memDC
->SetLogicalFunction(wxCOPY
);
421 memDC
->SetPen( wxPen( "black", 4, wxSOLID
) );
422 memDC
->SetBrush( wxNullBrush
);
423 memDC
->SetBrush( *brush36
);
424 memDC
->SetTextForeground(*wxBLACK
); // 0s --> 0x000000 (black)
425 memDC
->SetTextBackground(*wxWHITE
); // 1s --> 0xFFFFFF (white)
426 memDC
->SetLogicalFunction(wxAND_INVERT
);
428 memDC
->DrawRectangle( 10, 10, 200, 200 );
430 // Set background and foreground colors for fill pattern
431 //the previous blacked out pixels are now merged with the layer color
432 //while the non blacked out pixels stay as they are.
433 memDC
->SetTextForeground(*wxBLACK
); // 0s --> 0x000000 (black)
434 //now define what will be the color of the fillpattern parts that are not transparent
435 // memDC->SetTextBackground(*wxRED);
436 memDC
->SetTextBackground(m_owner
->m_colourBackground
);
437 memDC
->SetLogicalFunction(wxOR
);
439 //don't understand how but the outline is also depending on logicalfunction
440 memDC
->SetPen( wxPen( "yellow", 4, wxSOLID
) );
441 memDC
->DrawRectangle( 10, 10, 200, 200 );
443 memDC
->SetBrush(wxNullBrush
);
444 memDC
->SetPen(wxNullPen
);
447 dc
.Blit(x
,y
,600,400,memDC
,0,0,wxCOPY
);
452 case 2: //now with transparent inversed fillpatterns
454 wxBitmap
* bmpBlit
= new wxBitmap(600,400);
455 wxMemoryDC
* memDC
= new wxMemoryDC();
456 wxBrush
_clearbrush(*wxWHITE
,wxSOLID
);
457 memDC
->SelectObject(*bmpBlit
);
458 memDC
->BeginDrawing();
459 memDC
->SetBackground(_clearbrush
);
461 memDC
->SetBackground(wxNullBrush
);
463 memDC
->SetPen( wxPen( "black", 4, wxSOLID
) );
464 memDC
->SetBrush( *brush4
);
465 memDC
->SetTextBackground(*wxBLACK
); // 0s --> 0x000000 (black)
466 memDC
->SetTextForeground(*wxWHITE
); // 1s --> 0xFFFFFF (white)
467 memDC
->SetLogicalFunction(wxAND_INVERT
);
469 // BLACK OUT the opaque pixels and leave the rest as is
470 memDC
->DrawPolygon(5,todraw2
,0,0,wxWINDING_RULE
);
472 // Set background and foreground colors for fill pattern
473 //the previous blacked out pixels are now merged with the layer color
474 //while the non blacked out pixels stay as they are.
475 memDC
->SetTextBackground(*wxBLACK
); // 0s --> 0x000000 (black)
477 //now define what will be the color of the fillpattern parts that are not transparent
478 memDC
->SetTextForeground(m_owner
->m_colourForeground
);
479 memDC
->SetLogicalFunction(wxOR
);
482 //don't understand how but the outline is also depending on logicalfunction
483 memDC
->SetPen( wxPen( "red", 4, wxSOLID
) );
484 memDC
->DrawPolygon(5,todraw2
,0,0,wxWINDING_RULE
);
486 memDC
->SetLogicalFunction(wxCOPY
);
488 memDC
->SetPen( wxPen( "black", 4, wxSOLID
) );
489 memDC
->SetBrush( *brush36
);
490 memDC
->SetTextBackground(*wxBLACK
); // 0s --> 0x000000 (black)
491 memDC
->SetTextForeground(*wxWHITE
); // 1s --> 0xFFFFFF (white)
492 memDC
->SetLogicalFunction(wxAND_INVERT
);
494 memDC
->DrawRectangle( 10,10, 200, 200 );
496 // Set background and foreground colors for fill pattern
497 //the previous blacked out pixels are now merged with the layer color
498 //while the non blacked out pixels stay as they are.
499 memDC
->SetTextBackground(*wxBLACK
); // 0s --> 0x000000 (black)
500 //now define what will be the color of the fillpattern parts that are not transparent
501 memDC
->SetTextForeground(m_owner
->m_colourBackground
);
502 memDC
->SetLogicalFunction(wxOR
);
504 //don't understand how but the outline is also depending on logicalfunction
505 memDC
->SetPen( wxPen( "yellow", 4, wxSOLID
) );
506 memDC
->DrawRectangle( 10, 10, 200, 200 );
508 memDC
->SetBrush(wxNullBrush
);
509 memDC
->SetPen(wxNullPen
);
510 dc
.Blit(x
,y
,600,400,memDC
,0,0,wxCOPY
);
520 void MyCanvas
::DrawTestLines( int x
, int y
, int width
, wxDC
&dc
)
522 dc
.SetPen( wxPen( "black", width
, wxSOLID
) );
523 dc
.SetBrush( *wxRED_BRUSH
);
524 dc
.DrawRectangle( x
+10, y
+10, 100, 190 );
526 dc
.SetPen( wxPen( "black", width
, wxSOLID
) );
527 dc
.DrawLine( x
+20, y
+20, 100, y
+20 );
528 dc
.SetPen( wxPen( "black", width
, wxDOT
) );
529 dc
.DrawLine( x
+20, y
+30, 100, y
+30 );
530 dc
.SetPen( wxPen( "black", width
, wxSHORT_DASH
) );
531 dc
.DrawLine( x
+20, y
+40, 100, y
+40 );
532 dc
.SetPen( wxPen( "black", width
, wxLONG_DASH
) );
533 dc
.DrawLine( x
+20, y
+50, 100, y
+50 );
534 dc
.SetPen( wxPen( "black", width
, wxDOT_DASH
) );
535 dc
.DrawLine( x
+20, y
+60, 100, y
+60 );
537 dc
.SetPen( wxPen( "black", width
, wxBDIAGONAL_HATCH
) );
538 dc
.DrawLine( x
+20, y
+70, 100, y
+70 );
539 dc
.SetPen( wxPen( "black", width
, wxCROSSDIAG_HATCH
) );
540 dc
.DrawLine( x
+20, y
+80, 100, y
+80 );
541 dc
.SetPen( wxPen( "black", width
, wxFDIAGONAL_HATCH
) );
542 dc
.DrawLine( x
+20, y
+90, 100, y
+90 );
543 dc
.SetPen( wxPen( "black", width
, wxCROSS_HATCH
) );
544 dc
.DrawLine( x
+20, y
+100, 100, y
+100 );
545 dc
.SetPen( wxPen( "black", width
, wxHORIZONTAL_HATCH
) );
546 dc
.DrawLine( x
+20, y
+110, 100, y
+110 );
547 dc
.SetPen( wxPen( "black", width
, wxVERTICAL_HATCH
) );
548 dc
.DrawLine( x
+20, y
+120, 100, y
+120 );
550 wxPen
ud( "black", width
, wxUSER_DASH
);
553 ud
.SetDashes( 1, dash1
);
554 dc
.DrawLine( x
+20, y
+140, 100, y
+140 );
556 ud
.SetDashes( 1, dash1
);
557 dc
.DrawLine( x
+20, y
+150, 100, y
+150 );
559 ud
.SetDashes( 1, dash1
);
560 dc
.DrawLine( x
+20, y
+160, 100, y
+160 );
562 ud
.SetDashes( 1, dash1
);
563 dc
.DrawLine( x
+20, y
+170, 100, y
+170 );
566 void MyCanvas
::DrawDefault(wxDC
& dc
)
569 dc
.DrawCircle(0, 0, 10);
570 #if !(defined __WXGTK__) && !(defined __WXMOTIF__)
571 // not implemented in wxGTK or wxMOTIF :-(
572 dc
.FloodFill(0, 0, wxColour(255, 0, 0));
575 dc
.DrawIcon( wxICON(mondrian
), 40, 40 );
577 dc
.DrawCheckMark(5, 80, 15, 15);
578 dc
.DrawCheckMark(25, 80, 30, 30);
579 dc
.DrawCheckMark(60, 80, 60, 60);
581 // this is the test for "blitting bitmap into DC damages selected brush"
583 wxIcon icon
= wxTheApp
->GetStdIcon(wxICON_INFORMATION
);
584 wxCoord rectSize
= icon
.GetWidth() + 10;
586 dc
.SetPen(*wxTRANSPARENT_PEN
);
587 dc
.SetBrush( *wxGREEN_BRUSH
);
588 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
589 dc
.DrawBitmap(icon
, x
+ 5, 15, TRUE
);
591 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
592 dc
.DrawIcon(wxTheApp
->GetStdIcon(wxICON_INFORMATION
), x
+ 5, 15);
594 dc
.DrawRectangle(x
, 10, rectSize
, rectSize
);
596 // test for "transparent" bitmap drawing (it intersects with the last
598 //dc.SetBrush( *wxTRANSPARENT_BRUSH );
599 #include "../image/smile.xpm"
600 wxBitmap
bmp(smile_xpm
);
603 dc
.DrawBitmap(bmp
, x
+ rectSize
- 20, rectSize
- 10, TRUE
);
605 dc
.SetBrush( *wxBLACK_BRUSH
);
606 dc
.DrawRectangle( 0, 160, 1000, 300 );
609 wxBitmap
bitmap(20,70);
611 memdc
.SelectObject( bitmap
);
612 memdc
.SetBrush( *wxBLACK_BRUSH
);
613 memdc
.SetPen( *wxWHITE_PEN
);
614 memdc
.DrawRectangle(0,0,20,70);
615 memdc
.DrawLine( 10,0,10,70 );
618 wxPen pen
= *wxRED_PEN
;
620 memdc
.DrawLine( 10, 5,10, 5 );
621 memdc
.DrawLine( 10,10,11,10 );
622 memdc
.DrawLine( 10,15,12,15 );
623 memdc
.DrawLine( 10,20,13,20 );
626 memdc.SetPen(*wxRED_PEN);
627 memdc.DrawLine( 12, 5,12, 5 );
628 memdc.DrawLine( 12,10,13,10 );
629 memdc.DrawLine( 12,15,14,15 );
630 memdc.DrawLine( 12,20,15,20 );
634 memdc
.DrawLine( 10,25,10,25 );
635 memdc
.DrawLine( 10,30, 9,30 );
636 memdc
.DrawLine( 10,35, 8,35 );
637 memdc
.DrawLine( 10,40, 7,40 );
640 dc
.SetPen(*wxWHITE_PEN
);
641 memdc
.SetLogicalFunction( wxINVERT
);
642 memdc
.SetPen( *wxWHITE_PEN
);
643 memdc
.DrawLine( 10,50,10,50 );
644 memdc
.DrawLine( 10,55,11,55 );
645 memdc
.DrawLine( 10,60,12,60 );
646 memdc
.DrawLine( 10,65,13,65 );
648 memdc
.DrawLine( 12,50,12,50 );
649 memdc
.DrawLine( 12,55,13,55 );
650 memdc
.DrawLine( 12,60,14,60 );
651 memdc
.DrawLine( 12,65,15,65 );
653 memdc
.SelectObject( wxNullBitmap
);
654 dc
.DrawBitmap( bitmap
, 10, 170 );
655 wxImage
image( bitmap
);
656 image
.Rescale( 60,210 );
657 bitmap
= image
.ConvertToBitmap();
658 dc
.DrawBitmap( bitmap
, 50, 170 );
660 // test the rectangle outline drawing - there should be one pixel between
661 // the rect and the lines
662 dc
.SetPen(*wxWHITE_PEN
);
663 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
664 dc
.DrawRectangle(150, 170, 49, 29);
665 dc
.DrawRectangle(200, 170, 49, 29);
666 dc
.SetPen(*wxWHITE_PEN
);
667 dc
.DrawLine(250, 210, 250, 170);
668 dc
.DrawLine(260, 200, 150, 200);
670 // test the rectangle filled drawing - there should be one pixel between
671 // the rect and the lines
672 dc
.SetPen(*wxTRANSPARENT_PEN
);
673 dc
.SetBrush( *wxWHITE_BRUSH
);
674 dc
.DrawRectangle(300, 170, 49, 29);
675 dc
.DrawRectangle(350, 170, 49, 29);
676 dc
.SetPen(*wxWHITE_PEN
);
677 dc
.DrawLine(400, 170, 400, 210);
678 dc
.DrawLine(300, 200, 410, 200);
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);
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);
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);
709 // Added by JACS to demonstrate bizarre behaviour.
710 // With a size of 70, we get a missing red RHS,
711 // and the hight 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.
715 int totalHeight
= 70;
716 wxBitmap
bitmap2(totalWidth
, totalHeight
);
719 memdc2
.SelectObject(bitmap2
);
721 wxBrush
yellowBrush(wxColour(255, 255, 0), wxSOLID
);
722 memdc2
.SetBackground(yellowBrush
);
725 wxPen
yellowPen(wxColour(255, 255, 0), 1, wxSOLID
);
727 // Now draw a white rectangle with red outline. It should
728 // entirely eclipse the yellow background.
729 memdc2
.SetPen(*wxRED_PEN
);
730 memdc2
.SetBrush(*wxWHITE_BRUSH
);
732 memdc2
.DrawRectangle(0, 0, totalWidth
, totalHeight
);
734 memdc2
.SetPen(wxNullPen
);
735 memdc2
.SetBrush(wxNullBrush
);
736 memdc2
.SelectObject(wxNullBitmap
);
738 dc
.DrawBitmap(bitmap2
, 500, 270);
740 // Repeat, but draw directly on dc
741 // Draw a yellow rectangle filling the bitmap
743 x
= 600; int y
= 270;
744 dc
.SetPen(yellowPen
);
745 dc
.SetBrush(yellowBrush
);
746 dc
.DrawRectangle(x
, y
, totalWidth
, totalHeight
);
748 // Now draw a white rectangle with red outline. It should
749 // entirely eclipse the yellow background.
750 dc
.SetPen(*wxRED_PEN
);
751 dc
.SetBrush(*wxWHITE_BRUSH
);
753 dc
.DrawRectangle(x
, y
, totalWidth
, totalHeight
);
756 void MyCanvas
::DrawText(wxDC
& dc
)
758 // set underlined font for testing
759 dc
.SetFont( wxFont(12, wxMODERN
, wxNORMAL
, wxNORMAL
, TRUE
) );
760 dc
.DrawText( "This is text", 110, 10 );
761 dc
.DrawRotatedText( "That is text", 20, 10, -45 );
763 dc
.SetFont( *wxNORMAL_FONT
);
766 dc
. SetBackgroundMode(wxTRANSPARENT
);
768 for ( int n
= -180; n
< 180; n
+= 30 )
770 text
.Printf(" %d rotated text", n
);
771 dc
.DrawRotatedText(text
, 400, 400, n
);
774 dc
.SetFont( wxFont( 18, wxSWISS
, wxNORMAL
, wxNORMAL
) );
776 dc
.DrawText( "This is Swiss 18pt text.", 110, 40 );
781 dc
.GetTextExtent( "This is Swiss 18pt text.", &length
, &height
, &descent
);
782 text
.Printf( "Dimensions are length %ld, height %ld, descent %ld", length
, height
, descent
);
783 dc
.DrawText( text
, 110, 80 );
785 text
.Printf( "CharHeight() returns: %d", dc
.GetCharHeight() );
786 dc
.DrawText( text
, 110, 120 );
788 dc
.DrawRectangle( 100, 40, 4, height
);
795 } rasterOperations
[] =
798 { "wxAND_INVERT", wxAND_INVERT
},
799 { "wxAND_REVERSE", wxAND_REVERSE
},
800 { "wxCLEAR", wxCLEAR
},
801 { "wxCOPY", wxCOPY
},
802 { "wxEQUIV", wxEQUIV
},
803 { "wxINVERT", wxINVERT
},
804 { "wxNAND", wxNAND
},
805 { "wxNO_OP", wxNO_OP
},
807 { "wxOR_INVERT", wxOR_INVERT
},
808 { "wxOR_REVERSE", wxOR_REVERSE
},
810 { "wxSRC_INVERT", wxSRC_INVERT
},
814 void MyCanvas
::DrawImages(wxDC
& dc
)
816 dc
.DrawText("original image", 0, 0);
817 dc
.DrawBitmap(gs_bmpNoMask
, 0, 20, 0);
818 dc
.DrawText("with colour mask", 0, 100);
819 dc
.DrawBitmap(gs_bmpWithColMask
, 0, 120, TRUE
);
820 dc
.DrawText("the mask image", 0, 200);
821 dc
.DrawBitmap(gs_bmpMask
, 0, 220, 0);
822 dc
.DrawText("masked image", 0, 300);
823 dc
.DrawBitmap(gs_bmpWithMask
, 0, 320, TRUE
);
825 int cx
= gs_bmpWithColMask
.GetWidth(),
826 cy
= gs_bmpWithColMask
.GetHeight();
829 for ( size_t n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
831 wxCoord x
= 120 + 150*(n
%4),
834 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
835 memDC
.SelectObject(gs_bmpWithColMask
);
836 dc
.Blit(x
, y
, cx
, cy
, &memDC
, 0, 0, rasterOperations
[n
].rop
, TRUE
);
840 void MyCanvas
::DrawWithLogicalOps(wxDC
& dc
)
842 static const wxCoord w
= 60;
843 static const wxCoord h
= 60;
845 // reuse the text colour here
846 dc
.SetPen(wxPen(m_owner
->m_colourForeground
, 1, wxSOLID
));
847 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
850 for ( n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
852 wxCoord x
= 20 + 150*(n
%4),
855 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
856 dc
.SetLogicalFunction(rasterOperations
[n
].rop
);
857 dc
.DrawRectangle(x
, y
, w
, h
);
858 dc
.DrawLine(x
, y
, x
+ w
, y
+ h
);
859 dc
.DrawLine(x
+ w
, y
, x
, y
+ h
);
862 // now some filled rectangles
863 dc
.SetBrush(wxBrush(m_owner
->m_colourForeground
, wxSOLID
));
865 for ( n
= 0; n
< WXSIZEOF(rasterOperations
); n
++ )
867 wxCoord x
= 20 + 150*(n
%4),
870 dc
.DrawText(rasterOperations
[n
].name
, x
, y
- 20);
871 dc
.SetLogicalFunction(rasterOperations
[n
].rop
);
872 dc
.DrawRectangle(x
, y
, w
, h
);
876 void MyCanvas
::OnPaint(wxPaintEvent
&WXUNUSED(event
))
880 m_owner
->PrepareDC(dc
);
882 dc
.SetBackgroundMode( m_owner
->m_backgroundMode
);
883 if ( m_owner
->m_backgroundBrush
.Ok() )
884 dc
.SetBackground( m_owner
->m_backgroundBrush
);
885 if ( m_owner
->m_colourForeground
.Ok() )
886 dc
.SetTextForeground( m_owner
->m_colourForeground
);
887 if ( m_owner
->m_colourBackground
.Ok() )
888 dc
.SetTextBackground( m_owner
->m_colourBackground
);
890 if ( m_owner
->m_textureBackground
) {
891 if ( ! m_owner
->m_backgroundBrush
.Ok() ) {
892 wxBrush
b(wxColour(0,128,0), wxSOLID
);
899 if ( m_owner
->m_textureBackground
) {
900 dc
.SetPen(*wxMEDIUM_GREY_PEN
);
901 for (int i
=0; i
<200; i
++)
902 dc
.DrawLine(0, i
*10, i
*10, 0);
916 DrawTestLines( 0, 100, 0, dc
);
917 DrawTestLines( 0, 300, 1, dc
);
918 DrawTestLines( 0, 500, 2, dc
);
919 DrawTestLines( 0, 700, 6, dc
);
923 DrawTestPoly( 0, 100, dc
, 0 );
924 DrawTestPoly( 33, 500, dc
, 1 );
925 DrawTestPoly( 43, 1000, dc
, 2 );
933 DrawWithLogicalOps(dc
);
938 void MyCanvas
::OnMouseMove(wxMouseEvent
&event
)
942 m_owner
->PrepareDC(dc
);
944 wxPoint pos
= event
.GetPosition();
945 long x
= dc
.DeviceToLogicalX( pos
.x
);
946 long y
= dc
.DeviceToLogicalY( pos
.y
);
948 str
.Printf( "Current mouse position: %d,%d", (int)x
, (int)y
);
949 m_owner
->SetStatusText( str
);
952 // ----------------------------------------------------------------------------
954 // ----------------------------------------------------------------------------
956 // the event tables connect the wxWindows events with the functions (event
957 // handlers) which process them. It can be also done at run-time, but for the
958 // simple menu events like this the static method is much simpler.
959 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
960 EVT_MENU (File_Quit
, MyFrame
::OnQuit
)
961 EVT_MENU (File_About
, MyFrame
::OnAbout
)
963 EVT_MENU_RANGE(MenuShow_First
, MenuShow_Last
, MyFrame
::OnShow
)
965 EVT_MENU_RANGE(MenuOption_First
, MenuOption_Last
, MyFrame
::OnOption
)
969 MyFrame
::MyFrame(const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
)
970 : wxFrame((wxFrame
*)NULL
, -1, title
, pos
, size
)
972 // set the frame icon
973 SetIcon(wxICON(mondrian
));
975 wxMenu
*menuFile
= new wxMenu
;
976 menuFile
->Append(File_ShowDefault
, "&Default screen\tF1");
977 menuFile
->Append(File_ShowText
, "&Text screen\tF2");
978 menuFile
->Append(File_ShowLines
, "&Lines screen\tF3");
979 menuFile
->Append(File_ShowPolygons
, "&Polygons screen\tF4");
980 menuFile
->Append(File_ShowMask
, "wx&Mask screen\tF5");
981 menuFile
->Append(File_ShowOps
, "&ROP screen\tF6");
982 menuFile
->AppendSeparator();
983 menuFile
->Append(File_About
, "&About...\tCtrl-A", "Show about dialog");
984 menuFile
->AppendSeparator();
985 menuFile
->Append(File_Quit
, "E&xit\tAlt-X", "Quit this program");
987 wxMenu
*menuMapMode
= new wxMenu
;
988 menuMapMode
->Append( MapMode_Text
, "&TEXT map mode" );
989 menuMapMode
->Append( MapMode_Lometric
, "&LOMETRIC map mode" );
990 menuMapMode
->Append( MapMode_Twips
, "T&WIPS map mode" );
991 menuMapMode
->Append( MapMode_Points
, "&POINTS map mode" );
992 menuMapMode
->Append( MapMode_Metric
, "&METRIC map mode" );
994 wxMenu
*menuUserScale
= new wxMenu
;
995 menuUserScale
->Append( UserScale_StretchHoriz
, "Stretch horizontally\tCtrl-H" );
996 menuUserScale
->Append( UserScale_ShrinkHoriz
, "Shrink horizontally\tCtrl-G" );
997 menuUserScale
->Append( UserScale_StretchVertic
, "Stretch vertically\tCtrl-V" );
998 menuUserScale
->Append( UserScale_ShrinkVertic
, "Shrink vertically\tCtrl-W" );
999 menuUserScale
->AppendSeparator();
1000 menuUserScale
->Append( UserScale_Restore
, "Restore to normal\tCtrl-0" );
1002 wxMenu
*menuAxis
= new wxMenu
;
1003 menuAxis
->Append( AxisMirror_Horiz
, "Mirror horizontally\tCtrl-M", "", TRUE
);
1004 menuAxis
->Append( AxisMirror_Vertic
, "Mirror vertically\tCtrl-N", "", TRUE
);
1006 wxMenu
*menuLogical
= new wxMenu
;
1007 menuLogical
->Append( LogicalOrigin_MoveDown
, "Move &down\tCtrl-D" );
1008 menuLogical
->Append( LogicalOrigin_MoveUp
, "Move &up\tCtrl-U" );
1009 menuLogical
->Append( LogicalOrigin_MoveLeft
, "Move &right\tCtrl-L" );
1010 menuLogical
->Append( LogicalOrigin_MoveRight
, "Move &left\tCtrl-R" );
1012 wxMenu
*menuColour
= new wxMenu
;
1013 menuColour
->Append( Colour_TextForeground
, "Text foreground..." );
1014 menuColour
->Append( Colour_TextBackground
, "Text background..." );
1015 menuColour
->Append( Colour_Background
, "Background colour..." );
1016 menuColour
->Append( Colour_BackgroundMode
, "Opaque/transparent\tCtrl-B", "", TRUE
);
1017 menuColour
->Append( Colour_TextureBackgound
, "Draw textured background\tCtrl-T", "", TRUE
);
1019 // now append the freshly created menu to the menu bar...
1020 wxMenuBar
*menuBar
= new wxMenuBar
;
1021 menuBar
->Append(menuFile
, "&File");
1022 menuBar
->Append(menuMapMode
, "&MapMode");
1023 menuBar
->Append(menuUserScale
, "&UserScale");
1024 menuBar
->Append(menuAxis
, "&Axis");
1025 menuBar
->Append(menuLogical
, "&LogicalOrigin");
1026 menuBar
->Append(menuColour
, "&Colours");
1028 // ... and attach this menu bar to the frame
1029 SetMenuBar(menuBar
);
1031 // create a status bar just for fun (by default with 1 pane only)
1033 SetStatusText("Welcome to wxWindows!");
1035 m_mapMode
= wxMM_TEXT
;
1038 m_xLogicalOrigin
= 0;
1039 m_yLogicalOrigin
= 0;
1041 m_yAxisReversed
= FALSE
;
1042 m_backgroundMode
= wxSOLID
;
1043 m_colourForeground
= *wxRED
;
1044 m_colourBackground
= *wxBLUE
;
1045 m_textureBackground
= FALSE
;
1047 m_canvas
= new MyCanvas( this );
1048 m_canvas
->SetScrollbars( 10, 10, 100, 240 );
1053 void MyFrame
::OnQuit(wxCommandEvent
& WXUNUSED(event
))
1055 // TRUE is to force the frame to close
1059 void MyFrame
::OnAbout(wxCommandEvent
& WXUNUSED(event
))
1062 msg
.Printf( wxT("This is the about dialog of the drawing sample.\n")
1063 wxT("This sample tests various primitive drawing functions\n")
1064 wxT("without any tests to prevent flicker.\n")
1065 wxT("Copyright (c) Robert Roebling 1999")
1068 wxMessageBox(msg
, "About Drawing", wxOK
| wxICON_INFORMATION
, this);
1071 void MyFrame
::OnShow(wxCommandEvent
& event
)
1073 m_canvas
->Show((ScreenToShow
)(event
.GetInt() - MenuShow_First
));
1076 void MyFrame
::OnOption(wxCommandEvent
& event
)
1078 switch (event
.GetInt())
1081 m_mapMode
= wxMM_TEXT
;
1083 case MapMode_Lometric
:
1084 m_mapMode
= wxMM_LOMETRIC
;
1087 m_mapMode
= wxMM_TWIPS
;
1089 case MapMode_Points
:
1090 m_mapMode
= wxMM_POINTS
;
1092 case MapMode_Metric
:
1093 m_mapMode
= wxMM_METRIC
;
1096 case LogicalOrigin_MoveDown
:
1097 m_yLogicalOrigin
+= 10;
1099 case LogicalOrigin_MoveUp
:
1100 m_yLogicalOrigin
-= 10;
1102 case LogicalOrigin_MoveLeft
:
1103 m_xLogicalOrigin
+= 10;
1105 case LogicalOrigin_MoveRight
:
1106 m_xLogicalOrigin
-= 10;
1109 case UserScale_StretchHoriz
:
1110 m_xUserScale
*= 1.10;
1112 case UserScale_ShrinkHoriz
:
1113 m_xUserScale
/= 1.10;
1115 case UserScale_StretchVertic
:
1116 m_yUserScale
*= 1.10;
1118 case UserScale_ShrinkVertic
:
1119 m_yUserScale
/= 1.10;
1121 case UserScale_Restore
:
1126 case AxisMirror_Vertic
:
1127 m_yAxisReversed
= !m_yAxisReversed
;
1129 case AxisMirror_Horiz
:
1130 m_xAxisReversed
= !m_xAxisReversed
;
1133 case Colour_TextForeground
:
1134 m_colourForeground
= SelectColour();
1136 case Colour_TextBackground
:
1137 m_colourBackground
= SelectColour();
1139 case Colour_Background
:
1141 wxColour col
= SelectColour();
1144 m_backgroundBrush
.SetColour(col
);
1148 case Colour_BackgroundMode
:
1149 m_backgroundMode
= m_backgroundMode
== wxSOLID ? wxTRANSPARENT
1153 case Colour_TextureBackgound
:
1154 m_textureBackground
= ! m_textureBackground
;
1162 m_canvas
->Refresh();
1165 void MyFrame
::PrepareDC(wxDC
& dc
)
1167 dc
.SetMapMode( m_mapMode
);
1168 dc
.SetUserScale( m_xUserScale
, m_yUserScale
);
1169 dc
.SetLogicalOrigin( m_xLogicalOrigin
, m_yLogicalOrigin
);
1170 dc
.SetAxisOrientation( !m_xAxisReversed
, m_yAxisReversed
);
1173 wxColour MyFrame
::SelectColour()
1177 wxColourDialog
dialog(this, &data
);
1179 if ( dialog
.ShowModal() == wxID_OK
)
1181 col
= dialog
.GetColourData().GetColour();