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