]> git.saurik.com Git - wxWidgets.git/blame - samples/shaped/shaped.cpp
Change version to 3.0.0.
[wxWidgets.git] / samples / shaped / shaped.cpp
CommitLineData
1542ea39
RD
1/////////////////////////////////////////////////////////////////////////////
2// Name: shaped.cpp
3// Purpose: Shaped Window sample
4// Author: Robin Dunn
5// Modified by:
6// Created: 28-Mar-2003
1542ea39
RD
7// Copyright: (c) Robin Dunn
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
1542ea39
RD
19// For compilers that support precompilation, includes "wx/wx.h".
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
26// for all others, include the necessary headers
27#ifndef WX_PRECOMP
28 #include "wx/app.h"
29 #include "wx/log.h"
30 #include "wx/frame.h"
31 #include "wx/panel.h"
32 #include "wx/stattext.h"
33 #include "wx/menu.h"
34 #include "wx/layout.h"
35 #include "wx/msgdlg.h"
6a7e6411 36 #include "wx/image.h"
1542ea39
RD
37#endif
38
39#include "wx/dcclient.h"
e520c3f7 40#include "wx/graphics.h"
3b3ca9be 41#include "wx/image.h"
1542ea39 42
e7092398 43#ifndef wxHAS_IMAGES_IN_RESOURCES
41f02b9a
FM
44 #include "../sample.xpm"
45#endif
eed04c99 46
dd1406f5
VZ
47// ----------------------------------------------------------------------------
48// constants
49// ----------------------------------------------------------------------------
50
51// menu ids
52enum
53{
fb81ee21 54 Show_Shaped = 100,
376d7d97
VZ
55 Show_Transparent,
56
57 // must be consecutive and in the same order as wxShowEffect enum elements
58 Show_Effect_First,
59 Show_Effect_Roll = Show_Effect_First,
60 Show_Effect_Slide,
61 Show_Effect_Blend,
62 Show_Effect_Expand,
63 Show_Effect_Last = Show_Effect_Expand
dd1406f5
VZ
64};
65
1542ea39
RD
66// ----------------------------------------------------------------------------
67// private classes
68// ----------------------------------------------------------------------------
69
70// Define a new application type, each program should derive a class from wxApp
71class MyApp : public wxApp
72{
73public:
74 // override base class virtuals
75 // ----------------------------
76
77 // this one is called on application startup and is a good place for the app
78 // initialization (doing it here and not in the ctor allows to have an error
79 // return: if OnInit() returns false, the application terminates)
80 virtual bool OnInit();
81};
82
83
dd1406f5
VZ
84// Main frame just contains the menu items invoking the other tests
85class MainFrame : public wxFrame
86{
87public:
88 MainFrame();
89
90private:
91 void OnShowShaped(wxCommandEvent& event);
92 void OnShowTransparent(wxCommandEvent& event);
376d7d97 93 void OnShowEffect(wxCommandEvent& event);
06b3e19f 94 void OnExit(wxCommandEvent& event);
dd1406f5
VZ
95
96 DECLARE_EVENT_TABLE()
97};
98
4488a1d3
VZ
99// Define a new frame type: this is going to the frame showing the
100// effect of wxFRAME_SHAPED
1542ea39
RD
101class ShapedFrame : public wxFrame
102{
103public:
104 // ctor(s)
4488a1d3 105 ShapedFrame(wxFrame *parent);
1542ea39
RD
106 void SetWindowShape();
107
108 // event handlers (these functions should _not_ be virtual)
109 void OnDoubleClick(wxMouseEvent& evt);
110 void OnLeftDown(wxMouseEvent& evt);
111 void OnLeftUp(wxMouseEvent& evt);
112 void OnMouseMove(wxMouseEvent& evt);
113 void OnExit(wxMouseEvent& evt);
114 void OnPaint(wxPaintEvent& evt);
1542ea39
RD
115
116private:
e520c3f7
VZ
117 enum ShapeKind
118 {
119 Shape_None,
120 Shape_Star,
121#if wxUSE_GRAPHICS_CONTEXT
122 Shape_Circle,
123#endif // wxUSE_GRAPHICS_CONTEXT
124 Shape_Max
125 } m_shapeKind;
126
1542ea39
RD
127 wxBitmap m_bmp;
128 wxPoint m_delta;
129
be5a51fb 130 // any class wishing to process wxWidgets events must use this macro
1542ea39
RD
131 DECLARE_EVENT_TABLE()
132};
133
4488a1d3
VZ
134// Define a new frame type: this is going to the frame showing the
135// effect of wxWindow::SetTransparent and of
136// wxWindow::SetBackgroundStyle(wxBG_STYLE_TRANSPARENT)
137class SeeThroughFrame : public wxFrame
138{
139public:
140 // ctor(s)
141 SeeThroughFrame();
142
143 // event handlers (these functions should _not_ be virtual)
144 void OnDoubleClick(wxMouseEvent& evt);
145 void OnPaint(wxPaintEvent& evt);
4488a1d3
VZ
146
147private:
148 enum State
149 {
150 STATE_SEETHROUGH,
151 STATE_TRANSPARENT,
152 STATE_OPAQUE,
153 STATE_MAX
154 };
155
156 State m_currentState;
157
158 // any class wishing to process wxWidgets events must use this macro
159 DECLARE_EVENT_TABLE()
160};
161
376d7d97
VZ
162class EffectFrame : public wxFrame
163{
164public:
165 EffectFrame(wxWindow *parent,
166 wxShowEffect effect,
167 // TODO: add menu command to the main frame to allow changing
168 // these parameters
eed04c99 169 unsigned timeout = 1000)
376d7d97
VZ
170 : wxFrame(parent, wxID_ANY,
171 wxString::Format("Frame shown with %s effect",
172 GetEffectName(effect)),
173 wxDefaultPosition, wxSize(450, 300)),
174 m_effect(effect),
eed04c99 175 m_timeout(timeout)
376d7d97
VZ
176 {
177 new wxStaticText(this, wxID_ANY,
178 wxString::Format("Effect: %s", GetEffectName(effect)),
179 wxPoint(20, 20));
180 new wxStaticText(this, wxID_ANY,
181 wxString::Format("Timeout: %ums", m_timeout),
182 wxPoint(20, 60));
183
eed04c99 184 ShowWithEffect(m_effect, m_timeout);
376d7d97
VZ
185
186 Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(EffectFrame::OnClose));
187 }
188
189private:
190 static const char *GetEffectName(wxShowEffect effect)
191 {
192 static const char *names[] =
193 {
ffa50e73 194 "none",
eed04c99
VS
195 "roll to left",
196 "roll to right",
197 "roll to top",
198 "roll to bottom",
199 "slide to left",
200 "slide to right",
201 "slide to top",
202 "slide to bottom",
203 "fade",
204 "expand",
376d7d97
VZ
205 };
206 wxCOMPILE_TIME_ASSERT( WXSIZEOF(names) == wxSHOW_EFFECT_MAX,
207 EffectNamesMismatch );
208
209 return names[effect];
210 }
211
212 void OnClose(wxCloseEvent& event)
213 {
eed04c99 214 HideWithEffect(m_effect, m_timeout);
376d7d97
VZ
215
216 event.Skip();
217 }
218
219 wxShowEffect m_effect;
220 unsigned m_timeout;
376d7d97
VZ
221};
222
1542ea39
RD
223// ============================================================================
224// implementation
225// ============================================================================
226
227// ----------------------------------------------------------------------------
228// the application class
229// ----------------------------------------------------------------------------
230
dd1406f5
VZ
231IMPLEMENT_APP(MyApp)
232
1542ea39
RD
233// `Main program' equivalent: the program execution "starts" here
234bool MyApp::OnInit()
235{
45e6e6f8
VZ
236 if ( !wxApp::OnInit() )
237 return false;
238
1542ea39
RD
239 wxInitAllImageHandlers();
240
dd1406f5 241 new MainFrame;
1542ea39
RD
242
243 // success: wxApp::OnRun() will be called which will enter the main message
b62ca03d 244 // loop and the application will run. If we returned false here, the
1542ea39 245 // application would exit immediately.
b62ca03d 246 return true;
1542ea39
RD
247}
248
dd1406f5
VZ
249// ----------------------------------------------------------------------------
250// main frame
251// ----------------------------------------------------------------------------
252
253BEGIN_EVENT_TABLE(MainFrame, wxFrame)
254 EVT_MENU(Show_Shaped, MainFrame::OnShowShaped)
255 EVT_MENU(Show_Transparent, MainFrame::OnShowTransparent)
376d7d97 256 EVT_MENU_RANGE(Show_Effect_First, Show_Effect_Last, MainFrame::OnShowEffect)
06b3e19f 257 EVT_MENU(wxID_EXIT, MainFrame::OnExit)
dd1406f5
VZ
258END_EVENT_TABLE()
259
260MainFrame::MainFrame()
261 : wxFrame(NULL, wxID_ANY, "wxWidgets Shaped Sample",
262 wxDefaultPosition, wxSize(200, 100))
263{
41f02b9a
FM
264 SetIcon(wxICON(sample));
265
dd1406f5
VZ
266 wxMenuBar * const mbar = new wxMenuBar;
267 wxMenu * const menuFrames = new wxMenu;
268 menuFrames->Append(Show_Shaped, "Show &shaped window\tCtrl-S");
269 menuFrames->Append(Show_Transparent, "Show &transparent window\tCtrl-T");
270 menuFrames->AppendSeparator();
376d7d97
VZ
271 menuFrames->Append(Show_Effect_Roll, "Show &rolled effect\tCtrl-R");
272 menuFrames->Append(Show_Effect_Slide, "Show s&lide effect\tCtrl-L");
273 menuFrames->Append(Show_Effect_Blend, "Show &fade effect\tCtrl-F");
274 menuFrames->Append(Show_Effect_Expand, "Show &expand effect\tCtrl-E");
275 menuFrames->AppendSeparator();
dd1406f5
VZ
276 menuFrames->Append(wxID_EXIT, "E&xit");
277
278 mbar->Append(menuFrames, "&Show");
279 SetMenuBar(mbar);
280
281 Show();
282}
283
284void MainFrame::OnShowShaped(wxCommandEvent& WXUNUSED(event))
285{
286 ShapedFrame *shapedFrame = new ShapedFrame(this);
287 shapedFrame->Show(true);
288}
289
290void MainFrame::OnShowTransparent(wxCommandEvent& WXUNUSED(event))
291{
292 SeeThroughFrame *seeThroughFrame = new SeeThroughFrame();
293 seeThroughFrame->Show(true);
294}
295
376d7d97
VZ
296void MainFrame::OnShowEffect(wxCommandEvent& event)
297{
eed04c99 298 int effect = event.GetId();
fb81ee21
SC
299 static wxDirection direction = wxLEFT;
300 direction = (wxDirection)(((int)direction)<< 1);
301 if ( direction > wxDOWN )
302 direction = wxLEFT ;
eed04c99
VS
303
304 wxShowEffect eff;
305 switch ( effect )
306 {
307 case Show_Effect_Roll:
308 switch ( direction )
309 {
310 case wxLEFT:
311 eff = wxSHOW_EFFECT_ROLL_TO_LEFT;
312 break;
313 case wxRIGHT:
314 eff = wxSHOW_EFFECT_ROLL_TO_RIGHT;
315 break;
316 case wxTOP:
317 eff = wxSHOW_EFFECT_ROLL_TO_TOP;
318 break;
319 case wxBOTTOM:
320 eff = wxSHOW_EFFECT_ROLL_TO_BOTTOM;
321 break;
322 default:
323 wxFAIL_MSG( "invalid direction" );
324 return;
325 }
326 break;
327 case Show_Effect_Slide:
328 switch ( direction )
329 {
330 case wxLEFT:
331 eff = wxSHOW_EFFECT_SLIDE_TO_LEFT;
332 break;
333 case wxRIGHT:
334 eff = wxSHOW_EFFECT_SLIDE_TO_RIGHT;
335 break;
336 case wxTOP:
337 eff = wxSHOW_EFFECT_SLIDE_TO_TOP;
338 break;
339 case wxBOTTOM:
340 eff = wxSHOW_EFFECT_SLIDE_TO_BOTTOM;
341 break;
342 default:
343 wxFAIL_MSG( "invalid direction" );
344 return;
345 }
346 break;
347
348 case Show_Effect_Blend:
349 eff = wxSHOW_EFFECT_BLEND;
350 break;
351
352 case Show_Effect_Expand:
353 eff = wxSHOW_EFFECT_EXPAND;
354 break;
355
356 default:
357 wxFAIL_MSG( "invalid effect" );
358 return;
359 }
360
ffa50e73 361 new EffectFrame(this, eff, 1000);
376d7d97
VZ
362}
363
06b3e19f
VZ
364void MainFrame::OnExit(wxCommandEvent& WXUNUSED(event))
365{
366 Close();
367}
368
1542ea39 369// ----------------------------------------------------------------------------
4488a1d3 370// shaped frame
1542ea39
RD
371// ----------------------------------------------------------------------------
372
dd1406f5
VZ
373BEGIN_EVENT_TABLE(ShapedFrame, wxFrame)
374 EVT_LEFT_DCLICK(ShapedFrame::OnDoubleClick)
375 EVT_LEFT_DOWN(ShapedFrame::OnLeftDown)
376 EVT_LEFT_UP(ShapedFrame::OnLeftUp)
377 EVT_MOTION(ShapedFrame::OnMouseMove)
378 EVT_RIGHT_UP(ShapedFrame::OnExit)
dd1406f5 379 EVT_PAINT(ShapedFrame::OnPaint)
dd1406f5
VZ
380END_EVENT_TABLE()
381
382
1542ea39 383// frame constructor
4488a1d3
VZ
384ShapedFrame::ShapedFrame(wxFrame *parent)
385 : wxFrame(parent, wxID_ANY, wxEmptyString,
dd1406f5 386 wxDefaultPosition, wxSize(100, 100),
6a7e6411
RD
387 0
388 | wxFRAME_SHAPED
389 | wxSIMPLE_BORDER
390 | wxFRAME_NO_TASKBAR
391 | wxSTAY_ON_TOP
392 )
1542ea39 393{
e520c3f7 394 m_shapeKind = Shape_None;
9a83f860 395 m_bmp = wxBitmap(wxT("star.png"), wxBITMAP_TYPE_PNG);
1542ea39 396 SetSize(wxSize(m_bmp.GetWidth(), m_bmp.GetHeight()));
e520c3f7 397 SetToolTip(wxT("Right-click to close, double click to cycle shape"));
1542ea39 398 SetWindowShape();
1542ea39
RD
399}
400
401void ShapedFrame::SetWindowShape()
402{
e520c3f7
VZ
403 switch ( m_shapeKind )
404 {
405 case Shape_None:
406 SetShape(wxRegion());
407 break;
408
409 case Shape_Star:
410 SetShape(wxRegion(m_bmp, *wxWHITE));
411 break;
412
413#if wxUSE_GRAPHICS_CONTEXT
414 case Shape_Circle:
415 {
416 wxGraphicsPath
417 path = wxGraphicsRenderer::GetDefaultRenderer()->CreatePath();
418 path.AddCircle(m_bmp.GetWidth()/2, m_bmp.GetHeight()/2, 30);
419 SetShape(path);
420 }
421 break;
422#endif // wxUSE_GRAPHICS_CONTEXT
423
424 case Shape_Max:
425 wxFAIL_MSG( "invalid shape kind" );
426 break;
427 }
1542ea39
RD
428}
429
256b8649 430void ShapedFrame::OnDoubleClick(wxMouseEvent& WXUNUSED(evt))
1542ea39 431{
e520c3f7
VZ
432 m_shapeKind = static_cast<ShapeKind>((m_shapeKind + 1) % Shape_Max);
433 SetWindowShape();
1542ea39
RD
434}
435
436void ShapedFrame::OnLeftDown(wxMouseEvent& evt)
437{
438 CaptureMouse();
439 wxPoint pos = ClientToScreen(evt.GetPosition());
440 wxPoint origin = GetPosition();
441 int dx = pos.x - origin.x;
442 int dy = pos.y - origin.y;
443 m_delta = wxPoint(dx, dy);
444}
445
256b8649 446void ShapedFrame::OnLeftUp(wxMouseEvent& WXUNUSED(evt))
1542ea39
RD
447{
448 if (HasCapture())
6a7e6411 449 {
1542ea39 450 ReleaseMouse();
256b8649 451 }
1542ea39
RD
452}
453
454void ShapedFrame::OnMouseMove(wxMouseEvent& evt)
455{
6a7e6411 456 wxPoint pt = evt.GetPosition();
1542ea39
RD
457 if (evt.Dragging() && evt.LeftIsDown())
458 {
6a7e6411 459 wxPoint pos = ClientToScreen(pt);
1542ea39
RD
460 Move(wxPoint(pos.x - m_delta.x, pos.y - m_delta.y));
461 }
462}
463
256b8649 464void ShapedFrame::OnExit(wxMouseEvent& WXUNUSED(evt))
1542ea39
RD
465{
466 Close();
467}
468
256b8649 469void ShapedFrame::OnPaint(wxPaintEvent& WXUNUSED(evt))
1542ea39
RD
470{
471 wxPaintDC dc(this);
b62ca03d 472 dc.DrawBitmap(m_bmp, 0, 0, true);
1542ea39
RD
473}
474
4488a1d3
VZ
475// ----------------------------------------------------------------------------
476// see-through frame
477// ----------------------------------------------------------------------------
478
dd1406f5
VZ
479BEGIN_EVENT_TABLE(SeeThroughFrame, wxFrame)
480 EVT_LEFT_DCLICK(SeeThroughFrame::OnDoubleClick)
481 EVT_PAINT(SeeThroughFrame::OnPaint)
482END_EVENT_TABLE()
483
4488a1d3
VZ
484SeeThroughFrame::SeeThroughFrame()
485 : wxFrame(NULL, wxID_ANY, "Transparency test: double click here",
486 wxPoint(100, 30), wxSize(300, 300),
dd1406f5
VZ
487 wxDEFAULT_FRAME_STYLE |
488 wxFULL_REPAINT_ON_RESIZE |
489 wxSTAY_ON_TOP),
4488a1d3
VZ
490 m_currentState(STATE_SEETHROUGH)
491{
ea92bb67 492 SetBackgroundColour(*wxWHITE);
4488a1d3
VZ
493 SetBackgroundStyle(wxBG_STYLE_TRANSPARENT);
494}
495
4488a1d3
VZ
496// Paints a grid of varying hue and alpha
497void SeeThroughFrame::OnPaint(wxPaintEvent& WXUNUSED(evt))
498{
499 wxPaintDC dc(this);
500 dc.SetPen(wxNullPen);
501
502 int xcount = 8;
503 int ycount = 8;
504
505 float xstep = 1. / xcount;
506 float ystep = 1. / ycount;
507
508 int width = GetClientSize().GetWidth();
509 int height = GetClientSize().GetHeight();
510
511 for ( float x = 0.; x < 1.; x += xstep )
512 {
513 for ( float y = 0.; y < 1.; y += ystep )
514 {
515 wxImage::RGBValue v = wxImage::HSVtoRGB(wxImage::HSVValue(x, 1., 1.));
516 dc.SetBrush(wxBrush(wxColour(v.red, v.green, v.blue,
517 (int)(255*(1. - y)))));
518 int x1 = (int)(x * width);
519 int y1 = (int)(y * height);
520 int x2 = (int)((x + xstep) * width);
521 int y2 = (int)((y + ystep) * height);
522 dc.DrawRectangle(x1, y1, x2 - x1, y2 - y1);
523 }
524 }
525}
526
527// Switches between colour and transparent background on doubleclick
528void SeeThroughFrame::OnDoubleClick(wxMouseEvent& WXUNUSED(evt))
529{
530 m_currentState = (State)((m_currentState + 1) % STATE_MAX);
531
532 switch ( m_currentState )
533 {
534 case STATE_OPAQUE:
535 SetBackgroundStyle(wxBG_STYLE_COLOUR);
536 SetTransparent(255);
537 SetTitle("Opaque");
538 break;
539
540 case STATE_SEETHROUGH:
541 SetBackgroundStyle(wxBG_STYLE_TRANSPARENT);
542 SetTransparent(255);
543 SetTitle("See through");
544 break;
545
546 case STATE_TRANSPARENT:
547 SetBackgroundStyle(wxBG_STYLE_COLOUR);
548 SetTransparent(128);
549 SetTitle("Semi-transparent");
550 break;
551
552 case STATE_MAX:
553 wxFAIL_MSG( "unreachable" );
554 }
555
556 Refresh();
557}
558