]> git.saurik.com Git - wxWidgets.git/blob - samples/drawing/drawing.cpp
modifications to show non monochrome masks in action
[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 #ifdef __GNUG__
20 #pragma implementation "drawing.cpp"
21 #pragma interface "drawing.cpp"
22 #endif
23
24 // For compilers that support precompilation, includes "wx/wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 // for all others, include the necessary headers (this file is usually all you
32 // need because it includes almost all "standard" wxWindows headers
33 #ifndef WX_PRECOMP
34 #include "wx/wx.h"
35 #endif
36
37 #include "wx/colordlg.h"
38
39 // ----------------------------------------------------------------------------
40 // ressources
41 // ----------------------------------------------------------------------------
42 // the application icon
43 #if defined(__WXGTK__) || defined(__WXMOTIF__)
44 #include "mondrian.xpm"
45 #endif
46
47 // ----------------------------------------------------------------------------
48 // private classes
49 // ----------------------------------------------------------------------------
50
51 // Define a new application type, each program should derive a class from wxApp
52 class MyApp : public wxApp
53 {
54 public:
55 // override base class virtuals
56 // ----------------------------
57
58 // this one is called on application startup and is a good place for the app
59 // initialization (doing it here and not in the ctor allows to have an error
60 // return: if OnInit() returns false, the application terminates)
61 virtual bool OnInit();
62 };
63
64 class MyCanvas;
65
66 // Define a new frame type: this is going to be our main frame
67 class MyFrame : public wxFrame
68 {
69 public:
70 // ctor(s)
71 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
72
73 // event handlers (these functions should _not_ be virtual)
74 void OnQuit(wxCommandEvent& event);
75 void OnAbout(wxCommandEvent& event);
76 void OnOption(wxCommandEvent &event);
77
78 wxColour SelectColour();
79 void PrepareDC(wxDC& dc);
80
81 int m_backgroundMode;
82 int m_mapMode;
83 double m_xUserScale;
84 double m_yUserScale;
85 int m_xLogicalOrigin;
86 int m_yLogicalOrigin;
87 bool m_xAxisReversed,
88 m_yAxisReversed;
89 wxColour m_colourForeground, // these are _text_ colours
90 m_colourBackground;
91 wxBrush m_backgroundBrush;
92 MyCanvas *m_canvas;
93
94 private:
95 // any class wishing to process wxWindows events must use this macro
96 DECLARE_EVENT_TABLE()
97 };
98
99 // define a scrollable canvas for drawing onto
100 class MyCanvas: public wxScrolledWindow
101 {
102 public:
103 MyCanvas( MyFrame *parent );
104
105 void DrawTestPoly( int x, int y, wxDC &dc ,int transparent );
106 void DrawTestLines( int x, int y, int width, wxDC &dc );
107 void OnPaint(wxPaintEvent &event);
108 void OnMouseMove(wxMouseEvent &event);
109
110 protected:
111 MyFrame *m_owner;
112
113 private:
114 DECLARE_EVENT_TABLE()
115 };
116
117 // ----------------------------------------------------------------------------
118 // constants
119 // ----------------------------------------------------------------------------
120
121 // IDs for the controls and the menu commands
122 enum
123 {
124 // menu items
125 Minimal_Quit = 1,
126 Minimal_About,
127
128 MenuOption_First,
129
130 MapMode_Text = MenuOption_First,
131 MapMode_Lometric,
132 MapMode_Twips,
133 MapMode_Points,
134 MapMode_Metric,
135
136 UserScale_StretchHoriz,
137 UserScale_ShrinkHoriz,
138 UserScale_StretchVertic,
139 UserScale_ShrinkVertic,
140 UserScale_Restore,
141
142 AxisMirror_Horiz,
143 AxisMirror_Vertic,
144
145 LogicalOrigin_MoveDown,
146 LogicalOrigin_MoveUp,
147 LogicalOrigin_MoveLeft,
148 LogicalOrigin_MoveRight,
149
150 Colour_TextForeground,
151 Colour_TextBackground,
152 Colour_Background,
153 Colour_BackgroundMode,
154
155 MenuOption_Last = Colour_BackgroundMode
156 };
157
158 // ----------------------------------------------------------------------------
159 // event tables and other macros for wxWindows
160 // ----------------------------------------------------------------------------
161
162
163 // Create a new application object: this macro will allow wxWindows to create
164 // the application object during program execution (it's better than using a
165 // static object for many reasons) and also declares the accessor function
166 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
167 // not wxApp)
168 IMPLEMENT_APP(MyApp)
169
170 // ============================================================================
171 // implementation
172 // ============================================================================
173
174 // ----------------------------------------------------------------------------
175 // the application class
176 // ----------------------------------------------------------------------------
177
178 // `Main program' equivalent: the program execution "starts" here
179 bool MyApp::OnInit()
180 {
181 // Create the main application window
182 MyFrame *frame = new MyFrame("Drawing sample",
183 wxPoint(50, 50), wxSize(550, 340));
184
185 // Show it and tell the application that it's our main window
186 frame->Show(TRUE);
187 SetTopWindow(frame);
188
189 // success: wxApp::OnRun() will be called which will enter the main message
190 // loop and the application will run. If we returned FALSE here, the
191 // application would exit immediately.
192 return TRUE;
193 }
194
195 // ----------------------------------------------------------------------------
196 // MyCanvas
197 // ----------------------------------------------------------------------------
198
199 // the event tables connect the wxWindows events with the functions (event
200 // handlers) which process them.
201 BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
202 EVT_PAINT (MyCanvas::OnPaint)
203 EVT_MOTION (MyCanvas::OnMouseMove)
204 END_EVENT_TABLE()
205
206 MyCanvas::MyCanvas( MyFrame *parent ) : wxScrolledWindow( parent )
207 {
208 m_owner = parent;
209 }
210
211 //draw a polygon and an overlapping rectangle
212 //is transparent is 1, the fill pattern are made transparent
213 //is transparent is 2, the fill pattern are made transparent but inversed
214 //is transparent is 0 the text for and background color will be used to represent/map
215 //the colors of the monochrome bitmap pixels to the fillpattern
216 //
217 //i miss_used the the menu items for setting so called back and fore ground color
218 //just to show how the those colors do influence the fillpatterns
219 //just play with those,
220 //and with the code
221 //variations are endless using other logical functions
222 void MyCanvas::DrawTestPoly( int x, int y,wxDC &dc,int transparent )
223 {
224 char pathfile[80];
225
226 #ifdef __WXMSW__
227 //this if run from ide project file
228 sprintf(pathfile,"./drawing/pat%i.bmp",4);
229 wxBitmap* nonMonoBitmap4 = new wxBitmap(32,32,-1);
230 nonMonoBitmap4->LoadFile(pathfile,wxBITMAP_TYPE_BMP);
231
232 sprintf(pathfile,"./drawing/pat%i.bmp",36);
233 wxBitmap* nonMonoBitmap36 = new wxBitmap(32,32,-1);
234 nonMonoBitmap36->LoadFile(pathfile,wxBITMAP_TYPE_BMP);
235 #else
236 sprintf(pathfile,"./pat%i.bmp",4);
237 wxBitmap* nonMonoBitmap4 = new wxBitmap(32,32,-1);
238 nonMonoBitmap4->LoadFile(pathfile,wxBITMAP_TYPE_BMP);
239
240 sprintf(pathfile,"./pat%i.bmp",36);
241 wxBitmap* nonMonoBitmap36 = new wxBitmap(32,32,-1);
242 nonMonoBitmap36->LoadFile(pathfile,wxBITMAP_TYPE_BMP);
243 #endif
244
245 if ( !nonMonoBitmap4->Ok() || !nonMonoBitmap36->Ok() )
246 {
247 static bool s_errorGiven = FALSE;
248
249 if ( !s_errorGiven )
250 {
251 wxLogError("Couldn't find bitmap files near the program file, "
252 "please copy them there.");
253
254 s_errorGiven = TRUE;
255 }
256 }
257
258 //set mask to monochrome bitmap based on color bitmap
259 wxColour white("WHITE");
260 wxPen _Pen = wxPen(white,1,wxSOLID);
261 wxColour black("BLACK");
262
263 wxMask* monochrome_mask4 = new wxMask(*nonMonoBitmap4,black);
264 nonMonoBitmap4->SetMask(monochrome_mask4);
265
266 wxMask* monochrome_mask36 = new wxMask(*nonMonoBitmap36,black);
267 nonMonoBitmap36->SetMask(monochrome_mask36);
268
269 wxBrush* _brush4 = new wxBrush(*nonMonoBitmap4);
270 wxBrush* _brush36 = new wxBrush(*nonMonoBitmap36);
271
272 wxPoint todraw[5];
273 todraw[0].x=(long)x+100;
274 todraw[0].y=(long)y+100;
275 todraw[1].x=(long)x+300;
276 todraw[1].y=(long)y+100;
277 todraw[2].x=(long)x+300;
278 todraw[2].y=(long)y+300;
279 todraw[3].x=(long)x+150;
280 todraw[3].y=(long)y+350;
281 todraw[4].x=(long)x+100;
282 todraw[4].y=(long)y+300;
283
284 wxPoint todraw2[5];
285 todraw2[0].x=100;
286 todraw2[0].y=100;
287 todraw2[1].x=300;
288 todraw2[1].y=100;
289 todraw2[2].x=300;
290 todraw2[2].y=300;
291 todraw2[3].x=150;
292 todraw2[3].y=350;
293 todraw2[4].x=100;
294 todraw2[4].y=300;
295
296 switch (transparent)
297 {
298 case 0:
299 {
300 dc.SetPen( wxPen( "black", 4, wxSOLID) );
301 dc.SetBrush( *_brush4 );
302 dc.SetTextForeground(*wxGREEN);
303 // dc.SetTextBackground(*wxBLUE);
304 dc.SetTextBackground(m_owner->m_colourForeground);
305 dc.SetLogicalFunction(wxCOPY);
306 dc.DrawPolygon(5,todraw,0,0,wxWINDING_RULE);
307
308 //don't understand hwo but the outline is also depending on logicalfunction
309 dc.SetPen( wxPen( "red", 4, wxSOLID) );
310 dc.SetBrush( *_brush36 );
311 dc.SetTextForeground(*wxCYAN);
312 // dc.SetTextBackground(*wxRED);
313 dc.SetTextBackground(m_owner->m_colourBackground);
314 dc.SetLogicalFunction(wxCOPY);
315 dc.DrawRectangle( x+10, y+10, 200, 200 );
316 dc.SetBrush(wxNullBrush);
317 dc.SetPen(wxNullPen);
318 break;
319 }
320 case 1: //now with transparent fillpatterns
321 {
322
323 wxBitmap* _blitbitmap = new wxBitmap(600,400);
324 wxMemoryDC* _memDC= new wxMemoryDC();
325 // wxBrush _clearbrush(*wxGREEN,wxSOLID);
326 wxBrush _clearbrush(*wxBLACK,wxSOLID);
327 _memDC->SelectObject(*_blitbitmap);
328 _memDC->BeginDrawing();
329 _memDC->SetBackground(_clearbrush);
330 _memDC->Clear();
331 _memDC->SetBackground(wxNullBrush);
332
333 _memDC->SetPen( wxPen( "black", 4, wxSOLID) );
334 _memDC->SetBrush( wxNullBrush);
335 _memDC->SetBrush( *_brush4 );
336 _memDC->SetTextForeground(*wxBLACK); // 0s --> 0x000000 (black)
337 _memDC->SetTextBackground(*wxWHITE); // 1s --> 0xFFFFFF (white)
338 _memDC->SetLogicalFunction(wxAND_INVERT);
339
340 // BLACK OUT the opaque pixels and leave the rest as is
341 _memDC->DrawPolygon(5,todraw2,0,0,wxWINDING_RULE);
342
343 // Set background and foreground colors for fill pattern
344 //the previous blacked out pixels are now merged with the layer color
345 //while the non blacked out pixels stay as they are.
346 _memDC->SetTextForeground(*wxBLACK); // 0s --> 0x000000 (black)
347
348 //now define what will be the color of the fillpattern parts that are not transparent
349 // _memDC->SetTextBackground(*wxBLUE);
350 _memDC->SetTextBackground(m_owner->m_colourForeground);
351 _memDC->SetLogicalFunction(wxOR);
352
353
354 //don't understand how but the outline is also depending on logicalfunction
355 _memDC->SetPen( wxPen( "red", 4, wxSOLID) );
356 _memDC->DrawPolygon(5,todraw2,0,0,wxWINDING_RULE);
357
358 _memDC->SetLogicalFunction(wxCOPY);
359
360 _memDC->SetPen( wxPen( "black", 4, wxSOLID) );
361 _memDC->SetBrush( wxNullBrush);
362 _memDC->SetBrush( *_brush36 );
363 _memDC->SetTextForeground(*wxBLACK); // 0s --> 0x000000 (black)
364 _memDC->SetTextBackground(*wxWHITE); // 1s --> 0xFFFFFF (white)
365 _memDC->SetLogicalFunction(wxAND_INVERT);
366
367 _memDC->DrawRectangle( 10, 10, 200, 200 );
368
369 // Set background and foreground colors for fill pattern
370 //the previous blacked out pixels are now merged with the layer color
371 //while the non blacked out pixels stay as they are.
372 _memDC->SetTextForeground(*wxBLACK); // 0s --> 0x000000 (black)
373 //now define what will be the color of the fillpattern parts that are not transparent
374 // _memDC->SetTextBackground(*wxRED);
375 _memDC->SetTextBackground(m_owner->m_colourBackground);
376 _memDC->SetLogicalFunction(wxOR);
377
378 //don't understand how but the outline is also depending on logicalfunction
379 _memDC->SetPen( wxPen( "yellow", 4, wxSOLID) );
380 _memDC->DrawRectangle( 10, 10, 200, 200 );
381
382 _memDC->SetBrush(wxNullBrush);
383 _memDC->SetPen(wxNullPen);
384
385 _memDC->EndDrawing();
386 dc.Blit(x,y,600,400,_memDC,0,0,wxCOPY);
387 delete _blitbitmap;
388 delete _memDC;
389 break;
390 }
391 case 2: //now with transparent inversed fillpatterns
392 {
393 wxBitmap* _blitbitmap = new wxBitmap(600,400);
394 wxMemoryDC* _memDC= new wxMemoryDC();
395 wxBrush _clearbrush(*wxWHITE,wxSOLID);
396 _memDC->SelectObject(*_blitbitmap);
397 _memDC->BeginDrawing();
398 _memDC->SetBackground(_clearbrush);
399 _memDC->Clear();
400 _memDC->SetBackground(wxNullBrush);
401
402 _memDC->SetPen( wxPen( "black", 4, wxSOLID) );
403 _memDC->SetBrush( *_brush4 );
404 _memDC->SetTextBackground(*wxBLACK); // 0s --> 0x000000 (black)
405 _memDC->SetTextForeground(*wxWHITE); // 1s --> 0xFFFFFF (white)
406 _memDC->SetLogicalFunction(wxAND_INVERT);
407
408 // BLACK OUT the opaque pixels and leave the rest as is
409 _memDC->DrawPolygon(5,todraw2,0,0,wxWINDING_RULE);
410
411 // Set background and foreground colors for fill pattern
412 //the previous blacked out pixels are now merged with the layer color
413 //while the non blacked out pixels stay as they are.
414 _memDC->SetTextBackground(*wxBLACK); // 0s --> 0x000000 (black)
415
416 //now define what will be the color of the fillpattern parts that are not transparent
417 _memDC->SetTextForeground(m_owner->m_colourForeground);
418 _memDC->SetLogicalFunction(wxOR);
419
420
421 //don't understand how but the outline is also depending on logicalfunction
422 _memDC->SetPen( wxPen( "red", 4, wxSOLID) );
423 _memDC->DrawPolygon(5,todraw2,0,0,wxWINDING_RULE);
424
425 _memDC->SetLogicalFunction(wxCOPY);
426
427 _memDC->SetPen( wxPen( "black", 4, wxSOLID) );
428 _memDC->SetBrush( *_brush36 );
429 _memDC->SetTextBackground(*wxBLACK); // 0s --> 0x000000 (black)
430 _memDC->SetTextForeground(*wxWHITE); // 1s --> 0xFFFFFF (white)
431 _memDC->SetLogicalFunction(wxAND_INVERT);
432
433 _memDC->DrawRectangle( 10,10, 200, 200 );
434
435 // Set background and foreground colors for fill pattern
436 //the previous blacked out pixels are now merged with the layer color
437 //while the non blacked out pixels stay as they are.
438 _memDC->SetTextBackground(*wxBLACK); // 0s --> 0x000000 (black)
439 //now define what will be the color of the fillpattern parts that are not transparent
440 _memDC->SetTextForeground(m_owner->m_colourBackground);
441 _memDC->SetLogicalFunction(wxOR);
442
443 //don't understand how but the outline is also depending on logicalfunction
444 _memDC->SetPen( wxPen( "yellow", 4, wxSOLID) );
445 _memDC->DrawRectangle( 10, 10, 200, 200 );
446
447 _memDC->SetBrush(wxNullBrush);
448 _memDC->SetPen(wxNullPen);
449 dc.Blit(x,y,600,400,_memDC,0,0,wxCOPY);
450 delete _blitbitmap;
451 delete _memDC;
452 }
453 }
454
455 delete _brush4;
456 delete _brush36;
457 }
458
459 void MyCanvas::DrawTestLines( int x, int y, int width, wxDC &dc )
460 {
461 dc.SetPen( wxPen( "black", width, wxSOLID) );
462 dc.SetBrush( *wxRED_BRUSH );
463 dc.DrawRectangle( x+10, y+10, 100, 190 );
464
465 dc.SetPen( wxPen( "black", width, wxSOLID) );
466 dc.DrawLine( x+20, y+20, 100, y+20 );
467 dc.SetPen( wxPen( "black", width, wxDOT) );
468 dc.DrawLine( x+20, y+30, 100, y+30 );
469 dc.SetPen( wxPen( "black", width, wxSHORT_DASH) );
470 dc.DrawLine( x+20, y+40, 100, y+40 );
471 dc.SetPen( wxPen( "black", width, wxLONG_DASH) );
472 dc.DrawLine( x+20, y+50, 100, y+50 );
473 dc.SetPen( wxPen( "black", width, wxDOT_DASH) );
474 dc.DrawLine( x+20, y+60, 100, y+60 );
475
476 dc.SetPen( wxPen( "black", width, wxBDIAGONAL_HATCH) );
477 dc.DrawLine( x+20, y+70, 100, y+70 );
478 dc.SetPen( wxPen( "black", width, wxCROSSDIAG_HATCH) );
479 dc.DrawLine( x+20, y+80, 100, y+80 );
480 dc.SetPen( wxPen( "black", width, wxFDIAGONAL_HATCH) );
481 dc.DrawLine( x+20, y+90, 100, y+90 );
482 dc.SetPen( wxPen( "black", width, wxCROSS_HATCH) );
483 dc.DrawLine( x+20, y+100, 100, y+100 );
484 dc.SetPen( wxPen( "black", width, wxHORIZONTAL_HATCH) );
485 dc.DrawLine( x+20, y+110, 100, y+110 );
486 dc.SetPen( wxPen( "black", width, wxVERTICAL_HATCH) );
487 dc.DrawLine( x+20, y+120, 100, y+120 );
488
489 wxPen ud( "black", width, wxUSER_DASH );
490 wxDash dash1[1];
491 dash1[0] = 0;
492 ud.SetDashes( 1, dash1 );
493 dc.DrawLine( x+20, y+140, 100, y+140 );
494 dash1[0] = 1;
495 ud.SetDashes( 1, dash1 );
496 dc.DrawLine( x+20, y+150, 100, y+150 );
497 dash1[0] = 2;
498 ud.SetDashes( 1, dash1 );
499 dc.DrawLine( x+20, y+160, 100, y+160 );
500 dash1[0] = 0xFF;
501 ud.SetDashes( 1, dash1 );
502 dc.DrawLine( x+20, y+170, 100, y+170 );
503
504 }
505
506 void MyCanvas::OnPaint(wxPaintEvent &WXUNUSED(event))
507 {
508 wxPaintDC dc(this);
509 PrepareDC(dc);
510 m_owner->PrepareDC(dc);
511
512 dc.SetBackgroundMode( m_owner->m_backgroundMode );
513 if ( m_owner->m_backgroundBrush.Ok() )
514 dc.SetBackground( m_owner->m_backgroundBrush );
515 if ( m_owner->m_colourForeground.Ok() )
516 dc.SetTextForeground( m_owner->m_colourForeground );
517 if ( m_owner->m_colourBackground.Ok() )
518 dc.SetTextBackground( m_owner->m_colourBackground );
519
520 // mark the origin
521 dc.DrawCircle(0, 0, 10);
522 #if !(defined __WXGTK__) && !(defined __WXMOTIF__)
523 // not implemented in wxGTK or wxMOTIF :-(
524 dc.FloodFill(0, 0, wxColour(255, 0, 0));
525 #endif //
526
527 // set underlined font for testing
528 dc.SetFont( wxFont(12, wxMODERN, wxNORMAL, wxNORMAL, TRUE) );
529 dc.DrawText( "This is text", 110, 10 );
530 dc.DrawRotatedText( "That is text", 60, 30, -45 );
531
532 dc.SetFont( *wxNORMAL_FONT );
533
534 wxString text;
535 dc. SetBackgroundMode(wxTRANSPARENT);
536
537 for ( int n = -180; n < 180; n += 30 )
538 {
539 text.Printf(" %d rotated text", n);
540 dc.DrawRotatedText(text , 400, 400, n);
541 }
542
543 dc.SetFont( wxFont( 18, wxSWISS, wxNORMAL, wxNORMAL ) );
544
545 dc.DrawText( "This is Swiss 18pt text.", 110, 40 );
546
547 long length;
548 long height;
549 long descent;
550 dc.GetTextExtent( "This is Swiss 18pt text.", &length, &height, &descent );
551 text.Printf( "Dimensions are length %ld, height %ld, descent %ld", length, height, descent );
552 dc.DrawText( text, 110, 80 );
553
554 dc.DrawRectangle( 100, 40, 4, height );
555
556 text.Printf( "CharHeight() returns: %d", dc.GetCharHeight() );
557 dc.DrawText( text, 110, 120 );
558
559
560 dc.DrawIcon( wxICON(mondrian), 310, 40 );
561
562 DrawTestLines( 0, 200, 0, dc );
563
564 DrawTestLines( 0, 400, 1, dc );
565
566 DrawTestLines( 0, 600, 2, dc );
567
568 DrawTestLines( 0, 800, 6, dc );
569
570 DrawTestPoly( 0, 1000, dc ,0);
571 DrawTestPoly( 33, 1400, dc ,1);
572 DrawTestPoly( 43, 1900, dc ,2);
573 }
574
575 void MyCanvas::OnMouseMove(wxMouseEvent &event)
576 {
577 wxClientDC dc(this);
578 PrepareDC(dc);
579 m_owner->PrepareDC(dc);
580
581 wxPoint pos = event.GetPosition();
582 long x = dc.DeviceToLogicalX( pos.x );
583 long y = dc.DeviceToLogicalY( pos.y );
584 wxString str;
585 str.Printf( "Current mouse position: %d,%d", (int)x, (int)y );
586 m_owner->SetStatusText( str );
587 }
588
589 // ----------------------------------------------------------------------------
590 // MyFrame
591 // ----------------------------------------------------------------------------
592
593 // the event tables connect the wxWindows events with the functions (event
594 // handlers) which process them. It can be also done at run-time, but for the
595 // simple menu events like this the static method is much simpler.
596 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
597 EVT_MENU (Minimal_Quit, MyFrame::OnQuit)
598 EVT_MENU (Minimal_About, MyFrame::OnAbout)
599 EVT_MENU_RANGE(MenuOption_First, MenuOption_Last, MyFrame::OnOption)
600 END_EVENT_TABLE()
601
602 // frame constructor
603 MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
604 : wxFrame((wxFrame *)NULL, -1, title, pos, size)
605 {
606 // set the frame icon
607 SetIcon(wxICON(mondrian));
608
609 wxMenu *menuFile = new wxMenu;
610 menuFile->Append(Minimal_About, "&About...\tCtrl-A", "Show about dialog");
611 menuFile->AppendSeparator();
612 menuFile->Append(Minimal_Quit, "E&xit\tAlt-X", "Quit this program");
613
614 wxMenu *menuMapMode = new wxMenu;
615 menuMapMode->Append( MapMode_Text, "&TEXT map mode" );
616 menuMapMode->Append( MapMode_Lometric, "&LOMETRIC map mode" );
617 menuMapMode->Append( MapMode_Twips, "T&WIPS map mode" );
618 menuMapMode->Append( MapMode_Points, "&POINTS map mode" );
619 menuMapMode->Append( MapMode_Metric, "&METRIC map mode" );
620
621 wxMenu *menuUserScale = new wxMenu;
622 menuUserScale->Append( UserScale_StretchHoriz, "Stretch horizontally\tCtrl-H" );
623 menuUserScale->Append( UserScale_ShrinkHoriz, "Shrink horizontally\tCtrl-G" );
624 menuUserScale->Append( UserScale_StretchVertic, "Stretch vertically\tCtrl-V" );
625 menuUserScale->Append( UserScale_ShrinkVertic, "Shrink vertically\tCtrl-W" );
626 menuUserScale->AppendSeparator();
627 menuUserScale->Append( UserScale_Restore, "Restore to normal\tCtrl-0" );
628
629 wxMenu *menuAxis = new wxMenu;
630 menuAxis->Append( AxisMirror_Horiz, "Mirror horizontally\tCtrl-M", "", TRUE );
631 menuAxis->Append( AxisMirror_Vertic, "Mirror vertically\tCtrl-N", "", TRUE );
632
633 wxMenu *menuLogical = new wxMenu;
634 menuLogical->Append( LogicalOrigin_MoveDown, "Move &down\tCtrl-D" );
635 menuLogical->Append( LogicalOrigin_MoveUp, "Move &up\tCtrl-U" );
636 menuLogical->Append( LogicalOrigin_MoveLeft, "Move &right\tCtrl-L" );
637 menuLogical->Append( LogicalOrigin_MoveRight, "Move &left\tCtrl-R" );
638
639 wxMenu *menuColour = new wxMenu;
640 menuColour->Append( Colour_TextForeground, "Text foreground..." );
641 menuColour->Append( Colour_TextBackground, "Text background..." );
642 menuColour->Append( Colour_Background, "Background colour..." );
643 menuColour->Append( Colour_BackgroundMode, "Opaque/transparent\tCtrl-B", "", TRUE );
644
645 // now append the freshly created menu to the menu bar...
646 wxMenuBar *menuBar = new wxMenuBar;
647 menuBar->Append(menuFile, "&File");
648 menuBar->Append(menuMapMode, "&MapMode");
649 menuBar->Append(menuUserScale, "&UserScale");
650 menuBar->Append(menuAxis, "&Axis");
651 menuBar->Append(menuLogical, "&LogicalOrigin");
652 menuBar->Append(menuColour, "&Colours");
653
654 // ... and attach this menu bar to the frame
655 SetMenuBar(menuBar);
656
657 // create a status bar just for fun (by default with 1 pane only)
658 CreateStatusBar(2);
659 SetStatusText("Welcome to wxWindows!");
660
661 m_mapMode = wxMM_TEXT;
662 m_xUserScale = 1.0;
663 m_yUserScale = 1.0;
664 m_xLogicalOrigin = 0;
665 m_yLogicalOrigin = 0;
666 m_xAxisReversed =
667 m_yAxisReversed = FALSE;
668 m_backgroundMode = wxSOLID;
669 m_colourForeground = *wxRED;
670 m_colourBackground = *wxBLUE;
671
672 m_canvas = new MyCanvas( this );
673 m_canvas->SetScrollbars( 10, 10, 100, 240 );
674 }
675
676 // event handlers
677
678 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
679 {
680 // TRUE is to force the frame to close
681 Close(TRUE);
682 }
683
684 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
685 {
686 wxString msg;
687 msg.Printf( _T("This is the about dialog of the drawing sample.\n")
688 _T("Copyright (c) Robert Roebling 1999")
689 );
690
691 wxMessageBox(msg, "About Drawing", wxOK | wxICON_INFORMATION, this);
692 }
693
694 void MyFrame::OnOption(wxCommandEvent &event)
695 {
696 switch (event.GetInt())
697 {
698 case MapMode_Text:
699 m_mapMode = wxMM_TEXT;
700 break;
701 case MapMode_Lometric:
702 m_mapMode = wxMM_LOMETRIC;
703 break;
704 case MapMode_Twips:
705 m_mapMode = wxMM_TWIPS;
706 break;
707 case MapMode_Points:
708 m_mapMode = wxMM_POINTS;
709 break;
710 case MapMode_Metric:
711 m_mapMode = wxMM_METRIC;
712 break;
713
714 case LogicalOrigin_MoveDown:
715 m_yLogicalOrigin += 10;
716 break;
717 case LogicalOrigin_MoveUp:
718 m_yLogicalOrigin -= 10;
719 break;
720 case LogicalOrigin_MoveLeft:
721 m_xLogicalOrigin += 10;
722 break;
723 case LogicalOrigin_MoveRight:
724 m_xLogicalOrigin -= 10;
725 break;
726
727 case UserScale_StretchHoriz:
728 m_xUserScale *= 1.10;
729 break;
730 case UserScale_ShrinkHoriz:
731 m_xUserScale /= 1.10;
732 break;
733 case UserScale_StretchVertic:
734 m_yUserScale *= 1.10;
735 break;
736 case UserScale_ShrinkVertic:
737 m_yUserScale /= 1.10;
738 break;
739 case UserScale_Restore:
740 m_xUserScale =
741 m_yUserScale = 1.0;
742 break;
743
744 case AxisMirror_Vertic:
745 m_yAxisReversed = !m_yAxisReversed;
746 break;
747 case AxisMirror_Horiz:
748 m_xAxisReversed = !m_xAxisReversed;
749 break;
750
751 case Colour_TextForeground:
752 m_colourForeground = SelectColour();
753 break;
754 case Colour_TextBackground:
755 m_colourBackground = SelectColour();
756 break;
757 case Colour_Background:
758 {
759 wxColour col = SelectColour();
760 if ( col.Ok() )
761 {
762 m_backgroundBrush.SetColour(col);
763 }
764 }
765 break;
766 case Colour_BackgroundMode:
767 m_backgroundMode = m_backgroundMode == wxSOLID ? wxTRANSPARENT
768 : wxSOLID;
769 break;
770
771 default:
772 // skip Refresh()
773 return;
774 }
775
776 m_canvas->Refresh();
777 }
778
779 void MyFrame::PrepareDC(wxDC& dc)
780 {
781 dc.SetMapMode( m_mapMode );
782 dc.SetUserScale( m_xUserScale, m_yUserScale );
783 dc.SetLogicalOrigin( m_xLogicalOrigin, m_yLogicalOrigin );
784 dc.SetAxisOrientation( !m_xAxisReversed, m_yAxisReversed );
785 }
786
787 wxColour MyFrame::SelectColour()
788 {
789 wxColour col;
790 wxColourData data;
791 wxColourDialog dialog(this, &data);
792
793 if ( dialog.ShowModal() == wxID_OK )
794 {
795 col = dialog.GetColourData().GetColour();
796 }
797
798 return col;
799 }