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