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