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