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