]> git.saurik.com Git - wxWidgets.git/blob - samples/drawing/drawing.cpp
improved Mac resource creation step in order to allow samples to provide
[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[1];
468 dash1[0] = 0;
469 ud.SetDashes( 1, dash1 );
470 dc.DrawLine( x+20, y+140, 100, y+140 );
471 dash1[0] = 1;
472 ud.SetDashes( 1, dash1 );
473 dc.DrawLine( x+20, y+150, 100, y+150 );
474 dash1[0] = 2;
475 ud.SetDashes( 1, dash1 );
476 dc.DrawLine( x+20, y+160, 100, y+160 );
477 dash1[0] = 0x7F;
478 ud.SetDashes( 1, dash1 );
479 dc.DrawLine( x+20, y+170, 100, y+170 );
480 }
481
482 void MyCanvas::DrawDefault(wxDC& dc)
483 {
484 // mark the origin
485 dc.DrawCircle(0, 0, 10);
486
487 //flood fill using brush, starting at 1,1 and replacing whatever colour we find there
488 dc.SetBrush(wxBrush(wxColour(128,128,0), wxSOLID));
489 wxColour tmpColour ;
490 dc.GetPixel(1,1, &tmpColour);
491 dc.FloodFill(1,1, tmpColour, wxFLOOD_SURFACE);
492
493 dc.DrawCheckMark(5, 80, 15, 15);
494 dc.DrawCheckMark(25, 80, 30, 30);
495 dc.DrawCheckMark(60, 80, 60, 60);
496
497 // this is the test for "blitting bitmap into DC damages selected brush" bug
498 wxCoord rectSize = m_std_icon.GetWidth() + 10;
499 wxCoord x = 100;
500 dc.SetPen(*wxTRANSPARENT_PEN);
501 dc.SetBrush( *wxGREEN_BRUSH );
502 dc.DrawRectangle(x, 10, rectSize, rectSize);
503 dc.DrawBitmap(m_std_icon, x + 5, 15, TRUE);
504 x += rectSize + 10;
505 dc.DrawRectangle(x, 10, rectSize, rectSize);
506 dc.DrawIcon(m_std_icon, x + 5, 15);
507 x += rectSize + 10;
508 dc.DrawRectangle(x, 10, rectSize, rectSize);
509
510 // test for "transparent" bitmap drawing (it intersects with the last
511 // rectangle above)
512 //dc.SetBrush( *wxTRANSPARENT_BRUSH );
513
514 if (m_smile_bmp.Ok())
515 dc.DrawBitmap(m_smile_bmp, x + rectSize - 20, rectSize - 10, TRUE);
516
517 dc.SetBrush( *wxBLACK_BRUSH );
518 dc.DrawRectangle( 0, 160, 1000, 300 );
519
520 // draw lines
521 wxBitmap bitmap(20,70);
522 wxMemoryDC memdc;
523 memdc.SelectObject( bitmap );
524 memdc.SetBrush( *wxBLACK_BRUSH );
525 memdc.SetPen( *wxWHITE_PEN );
526 memdc.DrawRectangle(0,0,20,70);
527 memdc.DrawLine( 10,0,10,70 );
528
529 // to the right
530 wxPen pen = *wxRED_PEN;
531 memdc.SetPen(pen);
532 memdc.DrawLine( 10, 5,10, 5 );
533 memdc.DrawLine( 10,10,11,10 );
534 memdc.DrawLine( 10,15,12,15 );
535 memdc.DrawLine( 10,20,13,20 );
536
537 /*
538 memdc.SetPen(*wxRED_PEN);
539 memdc.DrawLine( 12, 5,12, 5 );
540 memdc.DrawLine( 12,10,13,10 );
541 memdc.DrawLine( 12,15,14,15 );
542 memdc.DrawLine( 12,20,15,20 );
543 */
544
545 // same to the left
546 memdc.DrawLine( 10,25,10,25 );
547 memdc.DrawLine( 10,30, 9,30 );
548 memdc.DrawLine( 10,35, 8,35 );
549 memdc.DrawLine( 10,40, 7,40 );
550
551 // XOR draw lines
552 dc.SetPen(*wxWHITE_PEN);
553 memdc.SetLogicalFunction( wxINVERT );
554 memdc.SetPen( *wxWHITE_PEN );
555 memdc.DrawLine( 10,50,10,50 );
556 memdc.DrawLine( 10,55,11,55 );
557 memdc.DrawLine( 10,60,12,60 );
558 memdc.DrawLine( 10,65,13,65 );
559
560 memdc.DrawLine( 12,50,12,50 );
561 memdc.DrawLine( 12,55,13,55 );
562 memdc.DrawLine( 12,60,14,60 );
563 memdc.DrawLine( 12,65,15,65 );
564
565 memdc.SelectObject( wxNullBitmap );
566 dc.DrawBitmap( bitmap, 10, 170 );
567 wxImage image = bitmap.ConvertToImage();
568 image.Rescale( 60,210 );
569 bitmap = wxBitmap(image);
570 dc.DrawBitmap( bitmap, 50, 170 );
571
572 // test the rectangle outline drawing - there should be one pixel between
573 // the rect and the lines
574 dc.SetPen(*wxWHITE_PEN);
575 dc.SetBrush( *wxTRANSPARENT_BRUSH );
576 dc.DrawRectangle(150, 170, 49, 29);
577 dc.DrawRectangle(200, 170, 49, 29);
578 dc.SetPen(*wxWHITE_PEN);
579 dc.DrawLine(250, 210, 250, 170);
580 dc.DrawLine(260, 200, 150, 200);
581
582 // test the rectangle filled drawing - there should be one pixel between
583 // the rect and the lines
584 dc.SetPen(*wxTRANSPARENT_PEN);
585 dc.SetBrush( *wxWHITE_BRUSH );
586 dc.DrawRectangle(300, 170, 49, 29);
587 dc.DrawRectangle(350, 170, 49, 29);
588 dc.SetPen(*wxWHITE_PEN);
589 dc.DrawLine(400, 170, 400, 210);
590 dc.DrawLine(300, 200, 410, 200);
591
592 // a few more tests of this kind
593 dc.SetPen(*wxRED_PEN);
594 dc.SetBrush( *wxWHITE_BRUSH );
595 dc.DrawRectangle(300, 220, 1, 1);
596 dc.DrawRectangle(310, 220, 2, 2);
597 dc.DrawRectangle(320, 220, 3, 3);
598 dc.DrawRectangle(330, 220, 4, 4);
599
600 dc.SetPen(*wxTRANSPARENT_PEN);
601 dc.SetBrush( *wxWHITE_BRUSH );
602 dc.DrawRectangle(300, 230, 1, 1);
603 dc.DrawRectangle(310, 230, 2, 2);
604 dc.DrawRectangle(320, 230, 3, 3);
605 dc.DrawRectangle(330, 230, 4, 4);
606
607 // and now for filled rect with outline
608 dc.SetPen(*wxRED_PEN);
609 dc.SetBrush( *wxWHITE_BRUSH );
610 dc.DrawRectangle(500, 170, 49, 29);
611 dc.DrawRectangle(550, 170, 49, 29);
612 dc.SetPen(*wxWHITE_PEN);
613 dc.DrawLine(600, 170, 600, 210);
614 dc.DrawLine(500, 200, 610, 200);
615
616 // test the rectangle outline drawing - there should be one pixel between
617 // the rect and the lines
618 dc.SetPen(*wxWHITE_PEN);
619 dc.SetBrush( *wxTRANSPARENT_BRUSH );
620 dc.DrawRoundedRectangle(150, 270, 49, 29, 6);
621 dc.DrawRoundedRectangle(200, 270, 49, 29, 6);
622 dc.SetPen(*wxWHITE_PEN);
623 dc.DrawLine(250, 270, 250, 310);
624 dc.DrawLine(150, 300, 260, 300);
625
626 // test the rectangle filled drawing - there should be one pixel between
627 // the rect and the lines
628 dc.SetPen(*wxTRANSPARENT_PEN);
629 dc.SetBrush( *wxWHITE_BRUSH );
630 dc.DrawRoundedRectangle(300, 270, 49, 29, 6);
631 dc.DrawRoundedRectangle(350, 270, 49, 29, 6);
632 dc.SetPen(*wxWHITE_PEN);
633 dc.DrawLine(400, 270, 400, 310);
634 dc.DrawLine(300, 300, 410, 300);
635
636 // Added by JACS to demonstrate bizarre behaviour.
637 // With a size of 70, we get a missing red RHS,
638 // and the hight is too small, so we get yellow
639 // showing. With a size of 40, it draws as expected:
640 // it just shows a white rectangle with red outline.
641 int totalWidth = 70;
642 int totalHeight = 70;
643 wxBitmap bitmap2(totalWidth, totalHeight);
644
645 wxMemoryDC memdc2;
646 memdc2.SelectObject(bitmap2);
647
648 wxBrush yellowBrush(wxColour(255, 255, 0), wxSOLID);
649 memdc2.SetBackground(yellowBrush);
650 memdc2.Clear();
651
652 wxPen yellowPen(wxColour(255, 255, 0), 1, wxSOLID);
653
654 // Now draw a white rectangle with red outline. It should
655 // entirely eclipse the yellow background.
656 memdc2.SetPen(*wxRED_PEN);
657 memdc2.SetBrush(*wxWHITE_BRUSH);
658
659 memdc2.DrawRectangle(0, 0, totalWidth, totalHeight);
660
661 memdc2.SetPen(wxNullPen);
662 memdc2.SetBrush(wxNullBrush);
663 memdc2.SelectObject(wxNullBitmap);
664
665 dc.DrawBitmap(bitmap2, 500, 270);
666
667 // Repeat, but draw directly on dc
668 // Draw a yellow rectangle filling the bitmap
669
670 x = 600; int y = 270;
671 dc.SetPen(yellowPen);
672 dc.SetBrush(yellowBrush);
673 dc.DrawRectangle(x, y, totalWidth, totalHeight);
674
675 // Now draw a white rectangle with red outline. It should
676 // entirely eclipse the yellow background.
677 dc.SetPen(*wxRED_PEN);
678 dc.SetBrush(*wxWHITE_BRUSH);
679
680 dc.DrawRectangle(x, y, totalWidth, totalHeight);
681 }
682
683 void MyCanvas::DrawText(wxDC& dc)
684 {
685 // set underlined font for testing
686 dc.SetFont( wxFont(12, wxMODERN, wxNORMAL, wxNORMAL, TRUE) );
687 dc.DrawText( _T("This is text"), 110, 10 );
688 dc.DrawRotatedText( _T("That is text"), 20, 10, -45 );
689
690 // use wxSWISS_FONT and not wxNORMAL_FONT as the latter can't be rotated
691 // under Win9x (it is not TrueType)
692 dc.SetFont( *wxSWISS_FONT );
693
694 wxString text;
695 dc.SetBackgroundMode(wxTRANSPARENT);
696
697 for ( int n = -180; n < 180; n += 30 )
698 {
699 text.Printf(wxT(" %d rotated text"), n);
700 dc.DrawRotatedText(text , 400, 400, n);
701 }
702
703 dc.SetFont( wxFont( 18, wxSWISS, wxNORMAL, wxNORMAL ) );
704
705 dc.DrawText( _T("This is Swiss 18pt text."), 110, 40 );
706
707 long length;
708 long height;
709 long descent;
710 dc.GetTextExtent( _T("This is Swiss 18pt text."), &length, &height, &descent );
711 text.Printf( wxT("Dimensions are length %ld, height %ld, descent %ld"), length, height, descent );
712 dc.DrawText( text, 110, 80 );
713
714 text.Printf( wxT("CharHeight() returns: %d"), dc.GetCharHeight() );
715 dc.DrawText( text, 110, 120 );
716
717 dc.DrawRectangle( 100, 40, 4, height );
718
719 // test the logical function effect
720 wxCoord y = 150;
721 dc.SetLogicalFunction(wxINVERT);
722 dc.DrawText( _T("There should be no text below"), 110, 150 );
723 dc.DrawRectangle( 110, y, 100, height );
724
725 // twice drawn inverted should result in invisible
726 y += height;
727 dc.DrawText( _T("Invisible text"), 110, y );
728 dc.DrawRectangle( 110, y, 100, height );
729 dc.DrawText( _T("Invisible text"), 110, y );
730 dc.DrawRectangle( 110, y, 100, height );
731 dc.SetLogicalFunction(wxCOPY);
732
733 y += height;
734 dc.DrawRectangle( 110, y, 100, height );
735 dc.DrawText( _T("Visible text"), 110, y );
736 }
737
738 static const struct
739 {
740 const wxChar *name;
741 int rop;
742 } rasterOperations[] =
743 {
744 { wxT("wxAND"), wxAND },
745 { wxT("wxAND_INVERT"), wxAND_INVERT },
746 { wxT("wxAND_REVERSE"), wxAND_REVERSE },
747 { wxT("wxCLEAR"), wxCLEAR },
748 { wxT("wxCOPY"), wxCOPY },
749 { wxT("wxEQUIV"), wxEQUIV },
750 { wxT("wxINVERT"), wxINVERT },
751 { wxT("wxNAND"), wxNAND },
752 { wxT("wxNO_OP"), wxNO_OP },
753 { wxT("wxOR"), wxOR },
754 { wxT("wxOR_INVERT"), wxOR_INVERT },
755 { wxT("wxOR_REVERSE"), wxOR_REVERSE },
756 { wxT("wxSET"), wxSET },
757 { wxT("wxSRC_INVERT"), wxSRC_INVERT },
758 { wxT("wxXOR"), wxXOR },
759 };
760
761 void MyCanvas::DrawImages(wxDC& dc)
762 {
763 dc.DrawText(_T("original image"), 0, 0);
764 dc.DrawBitmap(*gs_bmpNoMask, 0, 20, 0);
765 dc.DrawText(_T("with colour mask"), 0, 100);
766 dc.DrawBitmap(*gs_bmpWithColMask, 0, 120, TRUE);
767 dc.DrawText(_T("the mask image"), 0, 200);
768 dc.DrawBitmap(*gs_bmpMask, 0, 220, 0);
769 dc.DrawText(_T("masked image"), 0, 300);
770 dc.DrawBitmap(*gs_bmpWithMask, 0, 320, TRUE);
771
772 int cx = gs_bmpWithColMask->GetWidth(),
773 cy = gs_bmpWithColMask->GetHeight();
774
775 wxMemoryDC memDC;
776 for ( size_t n = 0; n < WXSIZEOF(rasterOperations); n++ )
777 {
778 wxCoord x = 120 + 150*(n%4),
779 y = 20 + 100*(n/4);
780
781 dc.DrawText(rasterOperations[n].name, x, y - 20);
782 memDC.SelectObject(*gs_bmpWithColMask);
783 dc.Blit(x, y, cx, cy, &memDC, 0, 0, rasterOperations[n].rop, TRUE);
784 }
785 }
786
787 void MyCanvas::DrawWithLogicalOps(wxDC& dc)
788 {
789 static const wxCoord w = 60;
790 static const wxCoord h = 60;
791
792 // reuse the text colour here
793 dc.SetPen(wxPen(m_owner->m_colourForeground, 1, wxSOLID));
794 dc.SetBrush(*wxTRANSPARENT_BRUSH);
795
796 size_t n;
797 for ( n = 0; n < WXSIZEOF(rasterOperations); n++ )
798 {
799 wxCoord x = 20 + 150*(n%4),
800 y = 20 + 100*(n/4);
801
802 dc.DrawText(rasterOperations[n].name, x, y - 20);
803 dc.SetLogicalFunction(rasterOperations[n].rop);
804 dc.DrawRectangle(x, y, w, h);
805 dc.DrawLine(x, y, x + w, y + h);
806 dc.DrawLine(x + w, y, x, y + h);
807 }
808
809 // now some filled rectangles
810 dc.SetBrush(wxBrush(m_owner->m_colourForeground, wxSOLID));
811
812 for ( n = 0; n < WXSIZEOF(rasterOperations); n++ )
813 {
814 wxCoord x = 20 + 150*(n%4),
815 y = 500 + 100*(n/4);
816
817 dc.DrawText(rasterOperations[n].name, x, y - 20);
818 dc.SetLogicalFunction(rasterOperations[n].rop);
819 dc.DrawRectangle(x, y, w, h);
820 }
821 }
822
823 void MyCanvas::DrawCircles(wxDC& dc)
824 {
825 int x = 100,
826 y = 100,
827 r = 20;
828
829 dc.DrawText(_T("Some circles"), 0, y);
830 dc.DrawCircle(x, y, r);
831 dc.DrawCircle(x + 2*r, y, r);
832 dc.DrawCircle(x + 4*r, y, r);
833
834 y += 2*r;
835 dc.DrawText(_T("And ellipses"), 0, y);
836 dc.DrawEllipse(x - r, y, 2*r, r);
837 dc.DrawEllipse(x + r, y, 2*r, r);
838 dc.DrawEllipse(x + 3*r, y, 2*r, r);
839
840 y += 2*r;
841 dc.DrawText(_T("And arcs"), 0, y);
842 dc.DrawArc(x - r, y, x + r, y, x, y);
843 dc.DrawArc(x + 4*r, y, x + 2*r, y, x + 3*r, y);
844 dc.DrawArc(x + 5*r, y, x + 5*r, y, x + 6*r, y);
845
846 y += 2*r;
847 dc.DrawEllipticArc(x - r, y, 2*r, r, 0, 90);
848 dc.DrawEllipticArc(x + r, y, 2*r, r, 90, 180);
849 dc.DrawEllipticArc(x + 3*r, y, 2*r, r, 180, 270);
850 dc.DrawEllipticArc(x + 5*r, y, 2*r, r, 270, 360);
851 }
852
853 void MyCanvas::DrawRegions(wxDC& dc)
854 {
855 dc.DrawText(_T("You should see a red rect partly covered by a cyan one ")
856 _T("on the left"), 10, 5);
857 dc.DrawText(_T("and 5 smileys from which 4 are partially clipped on the right"),
858 10, 5 + dc.GetCharHeight());
859 dc.DrawText(_T("The second copy should be identical but right part of it ")
860 _T("should be offset by 10 pixels."),
861 10, 5 + 2*dc.GetCharHeight());
862
863 DrawRegionsHelper(dc, 10, TRUE);
864 DrawRegionsHelper(dc, 350, FALSE);
865 }
866
867 void MyCanvas::DrawRegionsHelper(wxDC& dc, wxCoord x, bool firstTime)
868 {
869 wxCoord y = 100;
870
871 dc.DestroyClippingRegion();
872 dc.SetBrush( *wxWHITE_BRUSH );
873 dc.SetPen( *wxTRANSPARENT_PEN );
874 dc.DrawRectangle( x, y, 310, 310 );
875
876 dc.SetClippingRegion( x + 10, y + 10, 100, 270 );
877
878 dc.SetBrush( *wxRED_BRUSH );
879 dc.DrawRectangle( x, y, 310, 310 );
880
881 dc.SetClippingRegion( x + 10, y + 10, 100, 100 );
882
883 dc.SetBrush( *wxCYAN_BRUSH );
884 dc.DrawRectangle( x, y, 310, 310 );
885
886 dc.DestroyClippingRegion();
887
888 wxRegion region(x + 110, y + 20, 100, 270);
889 #if !defined(__WXMOTIF__) && !defined(__WXMAC__)
890 if ( !firstTime )
891 region.Offset(10, 10);
892 #endif
893 dc.SetClippingRegion(region);
894
895 dc.SetBrush( *wxGREY_BRUSH );
896 dc.DrawRectangle( x, y, 310, 310 );
897
898 if (m_smile_bmp.Ok())
899 {
900 dc.DrawBitmap( m_smile_bmp, x + 150, y + 150, TRUE );
901 dc.DrawBitmap( m_smile_bmp, x + 130, y + 10, TRUE );
902 dc.DrawBitmap( m_smile_bmp, x + 130, y + 280, TRUE );
903 dc.DrawBitmap( m_smile_bmp, x + 100, y + 70, TRUE );
904 dc.DrawBitmap( m_smile_bmp, x + 200, y + 70, TRUE );
905 }
906 }
907
908 void MyCanvas::OnPaint(wxPaintEvent &WXUNUSED(event))
909 {
910 wxPaintDC dc(this);
911 PrepareDC(dc);
912
913 m_owner->PrepareDC(dc);
914
915 dc.SetBackgroundMode( m_owner->m_backgroundMode );
916 if ( m_owner->m_backgroundBrush.Ok() )
917 dc.SetBackground( m_owner->m_backgroundBrush );
918 if ( m_owner->m_colourForeground.Ok() )
919 dc.SetTextForeground( m_owner->m_colourForeground );
920 if ( m_owner->m_colourBackground.Ok() )
921 dc.SetTextBackground( m_owner->m_colourBackground );
922
923 if ( m_owner->m_textureBackground) {
924 if ( ! m_owner->m_backgroundBrush.Ok() ) {
925 wxBrush b(wxColour(0,128,0), wxSOLID);
926 dc.SetBackground(b);
927 }
928 }
929
930 if ( m_clip )
931 dc.SetClippingRegion(100, 100, 100, 100);
932
933 dc.Clear();
934
935 if ( m_owner->m_textureBackground )
936 {
937 dc.SetPen(*wxMEDIUM_GREY_PEN);
938 for ( int i = 0; i < 200; i++ )
939 dc.DrawLine(0, i*10, i*10, 0);
940 }
941
942 switch ( m_show )
943 {
944 case Show_Default:
945 DrawDefault(dc);
946 break;
947
948 case Show_Circles:
949 DrawCircles(dc);
950 break;
951
952 case Show_Regions:
953 DrawRegions(dc);
954 break;
955
956 case Show_Text:
957 DrawText(dc);
958 break;
959
960 case Show_Lines:
961 DrawTestLines( 0, 100, 0, dc );
962 DrawTestLines( 0, 320, 1, dc );
963 DrawTestLines( 0, 540, 2, dc );
964 DrawTestLines( 0, 760, 6, dc );
965 break;
966
967 case Show_Brushes:
968 DrawTestBrushes(dc);
969 break;
970
971 case Show_Polygons:
972 DrawTestPoly(dc);
973 break;
974
975 case Show_Mask:
976 DrawImages(dc);
977 break;
978
979 case Show_Ops:
980 DrawWithLogicalOps(dc);
981 break;
982 }
983 }
984
985 void MyCanvas::OnMouseMove(wxMouseEvent &event)
986 {
987 wxClientDC dc(this);
988 PrepareDC(dc);
989 m_owner->PrepareDC(dc);
990
991 wxPoint pos = event.GetPosition();
992 long x = dc.DeviceToLogicalX( pos.x );
993 long y = dc.DeviceToLogicalY( pos.y );
994 wxString str;
995 str.Printf( wxT("Current mouse position: %d,%d"), (int)x, (int)y );
996 m_owner->SetStatusText( str );
997 }
998
999 // ----------------------------------------------------------------------------
1000 // MyFrame
1001 // ----------------------------------------------------------------------------
1002
1003 // the event tables connect the wxWindows events with the functions (event
1004 // handlers) which process them. It can be also done at run-time, but for the
1005 // simple menu events like this the static method is much simpler.
1006 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
1007 EVT_MENU (File_Quit, MyFrame::OnQuit)
1008 EVT_MENU (File_About, MyFrame::OnAbout)
1009 EVT_MENU (File_Clip, MyFrame::OnClip)
1010
1011 EVT_MENU_RANGE(MenuShow_First, MenuShow_Last, MyFrame::OnShow)
1012
1013 EVT_MENU_RANGE(MenuOption_First, MenuOption_Last, MyFrame::OnOption)
1014 END_EVENT_TABLE()
1015
1016 // frame constructor
1017 MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
1018 : wxFrame((wxFrame *)NULL, -1, title, pos, size,
1019 wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE)
1020 {
1021 // set the frame icon
1022 SetIcon(wxICON(mondrian));
1023
1024 wxMenu *menuFile = new wxMenu;
1025 menuFile->Append(File_ShowDefault, _T("&Default screen\tF1"));
1026 menuFile->Append(File_ShowText, _T("&Text screen\tF2"));
1027 menuFile->Append(File_ShowLines, _T("&Lines screen\tF3"));
1028 menuFile->Append(File_ShowBrushes, _T("&Brushes screen\tF4"));
1029 menuFile->Append(File_ShowPolygons, _T("&Polygons screen\tF5"));
1030 menuFile->Append(File_ShowMask, _T("&Mask screen\tF6"));
1031 menuFile->Append(File_ShowOps, _T("&ROP screen\tF7"));
1032 menuFile->Append(File_ShowRegions, _T("Re&gions screen\tF8"));
1033 menuFile->Append(File_ShowCircles, _T("&Circles screen\tF9"));
1034 menuFile->AppendSeparator();
1035 menuFile->AppendCheckItem(File_Clip, _T("&Clip\tCtrl-C"), _T("Clip/unclip drawing"));
1036 menuFile->AppendSeparator();
1037 menuFile->Append(File_About, _T("&About...\tCtrl-A"), _T("Show about dialog"));
1038 menuFile->AppendSeparator();
1039 menuFile->Append(File_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
1040
1041 wxMenu *menuMapMode = new wxMenu;
1042 menuMapMode->Append( MapMode_Text, _T("&TEXT map mode") );
1043 menuMapMode->Append( MapMode_Lometric, _T("&LOMETRIC map mode") );
1044 menuMapMode->Append( MapMode_Twips, _T("T&WIPS map mode") );
1045 menuMapMode->Append( MapMode_Points, _T("&POINTS map mode") );
1046 menuMapMode->Append( MapMode_Metric, _T("&METRIC map mode") );
1047
1048 wxMenu *menuUserScale = new wxMenu;
1049 menuUserScale->Append( UserScale_StretchHoriz, _T("Stretch &horizontally\tCtrl-H") );
1050 menuUserScale->Append( UserScale_ShrinkHoriz, _T("Shrin&k horizontally\tCtrl-G") );
1051 menuUserScale->Append( UserScale_StretchVertic, _T("Stretch &vertically\tCtrl-V") );
1052 menuUserScale->Append( UserScale_ShrinkVertic, _T("&Shrink vertically\tCtrl-W") );
1053 menuUserScale->AppendSeparator();
1054 menuUserScale->Append( UserScale_Restore, _T("&Restore to normal\tCtrl-0") );
1055
1056 wxMenu *menuAxis = new wxMenu;
1057 menuAxis->Append( AxisMirror_Horiz, _T("Mirror horizontally\tCtrl-M"), _T(""), TRUE );
1058 menuAxis->Append( AxisMirror_Vertic, _T("Mirror vertically\tCtrl-N"), _T(""), TRUE );
1059
1060 wxMenu *menuLogical = new wxMenu;
1061 menuLogical->Append( LogicalOrigin_MoveDown, _T("Move &down\tCtrl-D") );
1062 menuLogical->Append( LogicalOrigin_MoveUp, _T("Move &up\tCtrl-U") );
1063 menuLogical->Append( LogicalOrigin_MoveLeft, _T("Move &right\tCtrl-L") );
1064 menuLogical->Append( LogicalOrigin_MoveRight, _T("Move &left\tCtrl-R") );
1065 menuLogical->AppendSeparator();
1066 menuLogical->Append( LogicalOrigin_Set, _T("Set to (&100, 100)\tShift-Ctrl-1") );
1067 menuLogical->Append( LogicalOrigin_Restore, _T("&Restore to normal\tShift-Ctrl-0") );
1068
1069 wxMenu *menuColour = new wxMenu;
1070 menuColour->Append( Colour_TextForeground, _T("Text &foreground...") );
1071 menuColour->Append( Colour_TextBackground, _T("Text &background...") );
1072 menuColour->Append( Colour_Background, _T("Background &colour...") );
1073 menuColour->Append( Colour_BackgroundMode, _T("&Opaque/transparent\tCtrl-B"), _T(""), TRUE );
1074 menuColour->Append( Colour_TextureBackgound, _T("Draw textured back&ground\tCtrl-T"), _T(""), TRUE);
1075
1076 // now append the freshly created menu to the menu bar...
1077 wxMenuBar *menuBar = new wxMenuBar;
1078 menuBar->Append(menuFile, _T("&File"));
1079 menuBar->Append(menuMapMode, _T("&Mode"));
1080 menuBar->Append(menuUserScale, _T("&Scale"));
1081 menuBar->Append(menuAxis, _T("&Axis"));
1082 menuBar->Append(menuLogical, _T("&Origin"));
1083 menuBar->Append(menuColour, _T("&Colours"));
1084
1085 // ... and attach this menu bar to the frame
1086 SetMenuBar(menuBar);
1087
1088 // create a status bar just for fun (by default with 1 pane only)
1089 CreateStatusBar(2);
1090 SetStatusText(_T("Welcome to wxWindows!"));
1091
1092 m_mapMode = wxMM_TEXT;
1093 m_xUserScale = 1.0;
1094 m_yUserScale = 1.0;
1095 m_xLogicalOrigin = 0;
1096 m_yLogicalOrigin = 0;
1097 m_xAxisReversed =
1098 m_yAxisReversed = FALSE;
1099 m_backgroundMode = wxSOLID;
1100 m_colourForeground = *wxRED;
1101 m_colourBackground = *wxBLUE;
1102 m_textureBackground = FALSE;
1103
1104 m_canvas = new MyCanvas( this );
1105 m_canvas->SetScrollbars( 10, 10, 100, 240 );
1106 }
1107
1108 // event handlers
1109
1110 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
1111 {
1112 // TRUE is to force the frame to close
1113 Close(TRUE);
1114 }
1115
1116 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
1117 {
1118 wxString msg;
1119 msg.Printf( wxT("This is the about dialog of the drawing sample.\n")
1120 wxT("This sample tests various primitive drawing functions\n")
1121 wxT("(without any attempts to prevent flicker).\n")
1122 wxT("Copyright (c) Robert Roebling 1999")
1123 );
1124
1125 wxMessageBox(msg, _T("About Drawing"), wxOK | wxICON_INFORMATION, this);
1126 }
1127
1128 void MyFrame::OnClip(wxCommandEvent& event)
1129 {
1130 m_canvas->Clip(event.IsChecked());
1131 }
1132
1133 void MyFrame::OnShow(wxCommandEvent& event)
1134 {
1135 m_canvas->Show((ScreenToShow)(event.GetId() - MenuShow_First));
1136 }
1137
1138 void MyFrame::OnOption(wxCommandEvent& event)
1139 {
1140 switch (event.GetId())
1141 {
1142 case MapMode_Text:
1143 m_mapMode = wxMM_TEXT;
1144 break;
1145 case MapMode_Lometric:
1146 m_mapMode = wxMM_LOMETRIC;
1147 break;
1148 case MapMode_Twips:
1149 m_mapMode = wxMM_TWIPS;
1150 break;
1151 case MapMode_Points:
1152 m_mapMode = wxMM_POINTS;
1153 break;
1154 case MapMode_Metric:
1155 m_mapMode = wxMM_METRIC;
1156 break;
1157
1158 case LogicalOrigin_MoveDown:
1159 m_yLogicalOrigin += 10;
1160 break;
1161 case LogicalOrigin_MoveUp:
1162 m_yLogicalOrigin -= 10;
1163 break;
1164 case LogicalOrigin_MoveLeft:
1165 m_xLogicalOrigin += 10;
1166 break;
1167 case LogicalOrigin_MoveRight:
1168 m_xLogicalOrigin -= 10;
1169 break;
1170 case LogicalOrigin_Set:
1171 m_xLogicalOrigin =
1172 m_yLogicalOrigin = -100;
1173 break;
1174 case LogicalOrigin_Restore:
1175 m_xLogicalOrigin =
1176 m_yLogicalOrigin = 0;
1177 break;
1178
1179 case UserScale_StretchHoriz:
1180 m_xUserScale *= 1.10;
1181 break;
1182 case UserScale_ShrinkHoriz:
1183 m_xUserScale /= 1.10;
1184 break;
1185 case UserScale_StretchVertic:
1186 m_yUserScale *= 1.10;
1187 break;
1188 case UserScale_ShrinkVertic:
1189 m_yUserScale /= 1.10;
1190 break;
1191 case UserScale_Restore:
1192 m_xUserScale =
1193 m_yUserScale = 1.0;
1194 break;
1195
1196 case AxisMirror_Vertic:
1197 m_yAxisReversed = !m_yAxisReversed;
1198 break;
1199 case AxisMirror_Horiz:
1200 m_xAxisReversed = !m_xAxisReversed;
1201 break;
1202
1203 case Colour_TextForeground:
1204 m_colourForeground = SelectColour();
1205 break;
1206 case Colour_TextBackground:
1207 m_colourBackground = SelectColour();
1208 break;
1209 case Colour_Background:
1210 {
1211 wxColour col = SelectColour();
1212 if ( col.Ok() )
1213 {
1214 m_backgroundBrush.SetColour(col);
1215 }
1216 }
1217 break;
1218 case Colour_BackgroundMode:
1219 m_backgroundMode = m_backgroundMode == wxSOLID ? wxTRANSPARENT
1220 : wxSOLID;
1221 break;
1222
1223 case Colour_TextureBackgound:
1224 m_textureBackground = ! m_textureBackground;
1225 break;
1226
1227 default:
1228 // skip Refresh()
1229 return;
1230 }
1231
1232 m_canvas->Refresh();
1233 }
1234
1235 void MyFrame::PrepareDC(wxDC& dc)
1236 {
1237 dc.SetLogicalOrigin( m_xLogicalOrigin, m_yLogicalOrigin );
1238 dc.SetAxisOrientation( !m_xAxisReversed, m_yAxisReversed );
1239 dc.SetUserScale( m_xUserScale, m_yUserScale );
1240 dc.SetMapMode( m_mapMode );
1241 }
1242
1243 wxColour MyFrame::SelectColour()
1244 {
1245 wxColour col;
1246 wxColourData data;
1247 wxColourDialog dialog(this, &data);
1248
1249 if ( dialog.ShowModal() == wxID_OK )
1250 {
1251 col = dialog.GetColourData().GetColour();
1252 }
1253
1254 return col;
1255 }