1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Shaped Window sample
6 // Created: 28-Mar-2003
8 // Copyright: (c) Robin Dunn
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
27 // for all others, include the necessary headers
33 #include "wx/stattext.h"
35 #include "wx/layout.h"
36 #include "wx/msgdlg.h"
40 #include "wx/dcclient.h"
41 #include "wx/graphics.h"
44 #ifndef wxHAS_IMAGES_IN_RESOURCES
45 #include "../sample.xpm"
48 // ----------------------------------------------------------------------------
50 // ----------------------------------------------------------------------------
58 // must be consecutive and in the same order as wxShowEffect enum elements
60 Show_Effect_Roll
= Show_Effect_First
,
64 Show_Effect_Last
= Show_Effect_Expand
67 // ----------------------------------------------------------------------------
69 // ----------------------------------------------------------------------------
71 // Define a new application type, each program should derive a class from wxApp
72 class MyApp
: public wxApp
75 // override base class virtuals
76 // ----------------------------
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();
85 // Main frame just contains the menu items invoking the other tests
86 class MainFrame
: public wxFrame
92 void OnShowShaped(wxCommandEvent
& event
);
93 void OnShowTransparent(wxCommandEvent
& event
);
94 void OnShowEffect(wxCommandEvent
& event
);
95 void OnExit(wxCommandEvent
& event
);
100 // Define a new frame type: this is going to the frame showing the
101 // effect of wxFRAME_SHAPED
102 class ShapedFrame
: public wxFrame
106 ShapedFrame(wxFrame
*parent
);
107 void SetWindowShape();
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
);
122 #if wxUSE_GRAPHICS_CONTEXT
124 #endif // wxUSE_GRAPHICS_CONTEXT
131 // any class wishing to process wxWidgets events must use this macro
132 DECLARE_EVENT_TABLE()
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)
138 class SeeThroughFrame
: public wxFrame
144 // event handlers (these functions should _not_ be virtual)
145 void OnDoubleClick(wxMouseEvent
& evt
);
146 void OnPaint(wxPaintEvent
& evt
);
157 State m_currentState
;
159 // any class wishing to process wxWidgets events must use this macro
160 DECLARE_EVENT_TABLE()
163 class EffectFrame
: public wxFrame
166 EffectFrame(wxWindow
*parent
,
168 // TODO: add menu command to the main frame to allow changing
170 unsigned timeout
= 1000)
171 : wxFrame(parent
, wxID_ANY
,
172 wxString::Format("Frame shown with %s effect",
173 GetEffectName(effect
)),
174 wxDefaultPosition
, wxSize(450, 300)),
178 new wxStaticText(this, wxID_ANY
,
179 wxString::Format("Effect: %s", GetEffectName(effect
)),
181 new wxStaticText(this, wxID_ANY
,
182 wxString::Format("Timeout: %ums", m_timeout
),
185 ShowWithEffect(m_effect
, m_timeout
);
187 Connect(wxEVT_CLOSE_WINDOW
, wxCloseEventHandler(EffectFrame::OnClose
));
191 static const char *GetEffectName(wxShowEffect effect
)
193 static const char *names
[] =
207 wxCOMPILE_TIME_ASSERT( WXSIZEOF(names
) == wxSHOW_EFFECT_MAX
,
208 EffectNamesMismatch
);
210 return names
[effect
];
213 void OnClose(wxCloseEvent
& event
)
215 HideWithEffect(m_effect
, m_timeout
);
220 wxShowEffect m_effect
;
224 // ============================================================================
226 // ============================================================================
228 // ----------------------------------------------------------------------------
229 // the application class
230 // ----------------------------------------------------------------------------
234 // `Main program' equivalent: the program execution "starts" here
237 if ( !wxApp::OnInit() )
240 wxInitAllImageHandlers();
244 // success: wxApp::OnRun() will be called which will enter the main message
245 // loop and the application will run. If we returned false here, the
246 // application would exit immediately.
250 // ----------------------------------------------------------------------------
252 // ----------------------------------------------------------------------------
254 BEGIN_EVENT_TABLE(MainFrame
, wxFrame
)
255 EVT_MENU(Show_Shaped
, MainFrame::OnShowShaped
)
256 EVT_MENU(Show_Transparent
, MainFrame::OnShowTransparent
)
257 EVT_MENU_RANGE(Show_Effect_First
, Show_Effect_Last
, MainFrame::OnShowEffect
)
258 EVT_MENU(wxID_EXIT
, MainFrame::OnExit
)
261 MainFrame::MainFrame()
262 : wxFrame(NULL
, wxID_ANY
, "wxWidgets Shaped Sample",
263 wxDefaultPosition
, wxSize(200, 100))
265 SetIcon(wxICON(sample
));
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();
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();
277 menuFrames
->Append(wxID_EXIT
, "E&xit");
279 mbar
->Append(menuFrames
, "&Show");
285 void MainFrame::OnShowShaped(wxCommandEvent
& WXUNUSED(event
))
287 ShapedFrame
*shapedFrame
= new ShapedFrame(this);
288 shapedFrame
->Show(true);
291 void MainFrame::OnShowTransparent(wxCommandEvent
& WXUNUSED(event
))
293 SeeThroughFrame
*seeThroughFrame
= new SeeThroughFrame();
294 seeThroughFrame
->Show(true);
297 void MainFrame::OnShowEffect(wxCommandEvent
& event
)
299 int effect
= event
.GetId();
300 static wxDirection direction
= wxLEFT
;
301 direction
= (wxDirection
)(((int)direction
)<< 1);
302 if ( direction
> wxDOWN
)
308 case Show_Effect_Roll
:
312 eff
= wxSHOW_EFFECT_ROLL_TO_LEFT
;
315 eff
= wxSHOW_EFFECT_ROLL_TO_RIGHT
;
318 eff
= wxSHOW_EFFECT_ROLL_TO_TOP
;
321 eff
= wxSHOW_EFFECT_ROLL_TO_BOTTOM
;
324 wxFAIL_MSG( "invalid direction" );
328 case Show_Effect_Slide
:
332 eff
= wxSHOW_EFFECT_SLIDE_TO_LEFT
;
335 eff
= wxSHOW_EFFECT_SLIDE_TO_RIGHT
;
338 eff
= wxSHOW_EFFECT_SLIDE_TO_TOP
;
341 eff
= wxSHOW_EFFECT_SLIDE_TO_BOTTOM
;
344 wxFAIL_MSG( "invalid direction" );
349 case Show_Effect_Blend
:
350 eff
= wxSHOW_EFFECT_BLEND
;
353 case Show_Effect_Expand
:
354 eff
= wxSHOW_EFFECT_EXPAND
;
358 wxFAIL_MSG( "invalid effect" );
362 new EffectFrame(this, eff
, 1000);
365 void MainFrame::OnExit(wxCommandEvent
& WXUNUSED(event
))
370 // ----------------------------------------------------------------------------
372 // ----------------------------------------------------------------------------
374 BEGIN_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
)
380 EVT_PAINT(ShapedFrame::OnPaint
)
385 ShapedFrame::ShapedFrame(wxFrame
*parent
)
386 : wxFrame(parent
, wxID_ANY
, wxEmptyString
,
387 wxDefaultPosition
, wxSize(100, 100),
395 m_shapeKind
= Shape_None
;
396 m_bmp
= wxBitmap(wxT("star.png"), wxBITMAP_TYPE_PNG
);
397 SetSize(wxSize(m_bmp
.GetWidth(), m_bmp
.GetHeight()));
398 SetToolTip(wxT("Right-click to close, double click to cycle shape"));
402 void ShapedFrame::SetWindowShape()
404 switch ( m_shapeKind
)
407 SetShape(wxRegion());
411 SetShape(wxRegion(m_bmp
, *wxWHITE
));
414 #if wxUSE_GRAPHICS_CONTEXT
418 path
= wxGraphicsRenderer::GetDefaultRenderer()->CreatePath();
419 path
.AddCircle(m_bmp
.GetWidth()/2, m_bmp
.GetHeight()/2, 30);
423 #endif // wxUSE_GRAPHICS_CONTEXT
426 wxFAIL_MSG( "invalid shape kind" );
431 void ShapedFrame::OnDoubleClick(wxMouseEvent
& WXUNUSED(evt
))
433 m_shapeKind
= static_cast<ShapeKind
>((m_shapeKind
+ 1) % Shape_Max
);
437 void ShapedFrame::OnLeftDown(wxMouseEvent
& evt
)
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
);
447 void ShapedFrame::OnLeftUp(wxMouseEvent
& WXUNUSED(evt
))
455 void ShapedFrame::OnMouseMove(wxMouseEvent
& evt
)
457 wxPoint pt
= evt
.GetPosition();
458 if (evt
.Dragging() && evt
.LeftIsDown())
460 wxPoint pos
= ClientToScreen(pt
);
461 Move(wxPoint(pos
.x
- m_delta
.x
, pos
.y
- m_delta
.y
));
465 void ShapedFrame::OnExit(wxMouseEvent
& WXUNUSED(evt
))
470 void ShapedFrame::OnPaint(wxPaintEvent
& WXUNUSED(evt
))
473 dc
.DrawBitmap(m_bmp
, 0, 0, true);
476 // ----------------------------------------------------------------------------
478 // ----------------------------------------------------------------------------
480 BEGIN_EVENT_TABLE(SeeThroughFrame
, wxFrame
)
481 EVT_LEFT_DCLICK(SeeThroughFrame::OnDoubleClick
)
482 EVT_PAINT(SeeThroughFrame::OnPaint
)
485 SeeThroughFrame::SeeThroughFrame()
486 : wxFrame(NULL
, wxID_ANY
, "Transparency test: double click here",
487 wxPoint(100, 30), wxSize(300, 300),
488 wxDEFAULT_FRAME_STYLE
|
489 wxFULL_REPAINT_ON_RESIZE
|
491 m_currentState(STATE_SEETHROUGH
)
493 SetBackgroundColour(*wxWHITE
);
494 SetBackgroundStyle(wxBG_STYLE_TRANSPARENT
);
497 // Paints a grid of varying hue and alpha
498 void SeeThroughFrame::OnPaint(wxPaintEvent
& WXUNUSED(evt
))
501 dc
.SetPen(wxNullPen
);
506 float xstep
= 1. / xcount
;
507 float ystep
= 1. / ycount
;
509 int width
= GetClientSize().GetWidth();
510 int height
= GetClientSize().GetHeight();
512 for ( float x
= 0.; x
< 1.; x
+= xstep
)
514 for ( float y
= 0.; y
< 1.; y
+= ystep
)
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
);
528 // Switches between colour and transparent background on doubleclick
529 void SeeThroughFrame::OnDoubleClick(wxMouseEvent
& WXUNUSED(evt
))
531 m_currentState
= (State
)((m_currentState
+ 1) % STATE_MAX
);
533 switch ( m_currentState
)
536 SetBackgroundStyle(wxBG_STYLE_COLOUR
);
541 case STATE_SEETHROUGH
:
542 SetBackgroundStyle(wxBG_STYLE_TRANSPARENT
);
544 SetTitle("See through");
547 case STATE_TRANSPARENT
:
548 SetBackgroundStyle(wxBG_STYLE_COLOUR
);
550 SetTitle("Semi-transparent");
554 wxFAIL_MSG( "unreachable" );