Use flat generic status bar by default and add wxSB_SUNKEN.
[wxWidgets.git] / src / generic / splash.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/splash.cpp
3 // Purpose: wxSplashScreen class
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 28/6/2000
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #if wxUSE_SPLASH
20
21 #ifdef __WXGTK20__
22 #include <gtk/gtk.h>
23 #endif
24
25 #include "wx/splash.h"
26
27 #ifndef WX_PRECOMP
28 #include "wx/dcmemory.h"
29 #include "wx/dcclient.h"
30 #endif
31
32
33 // ----------------------------------------------------------------------------
34 // wxSplashScreen
35 // ----------------------------------------------------------------------------
36
37 #define wxSPLASH_TIMER_ID 9999
38
39 IMPLEMENT_DYNAMIC_CLASS(wxSplashScreen, wxFrame)
40 BEGIN_EVENT_TABLE(wxSplashScreen, wxFrame)
41 EVT_TIMER(wxSPLASH_TIMER_ID, wxSplashScreen::OnNotify)
42 EVT_CLOSE(wxSplashScreen::OnCloseWindow)
43 END_EVENT_TABLE()
44
45 void wxSplashScreen::Init()
46 {
47 m_window = NULL;
48
49 wxEvtHandler::AddFilter(this);
50 }
51
52 /* Note that unless we pass a non-default size to the frame, SetClientSize
53 * won't work properly under Windows, and the splash screen frame is sized
54 * slightly too small.
55 */
56
57 wxSplashScreen::wxSplashScreen(const wxBitmap& bitmap, long splashStyle, int milliseconds,
58 wxWindow* parent, wxWindowID id, const wxPoint& pos,
59 const wxSize& size, long style)
60 : wxFrame(parent, id, wxEmptyString, wxPoint(0,0), wxSize(100, 100),
61 style | wxFRAME_TOOL_WINDOW | wxFRAME_NO_TASKBAR)
62 {
63 Init();
64
65 // splash screen must not be used as parent by the other windows because it
66 // is going to disappear soon, indicate it by giving it this special style
67 SetExtraStyle(GetExtraStyle() | wxWS_EX_TRANSIENT);
68
69 #if defined(__WXGTK20__)
70 gtk_window_set_type_hint(GTK_WINDOW(m_widget),
71 GDK_WINDOW_TYPE_HINT_SPLASHSCREEN);
72 #endif
73
74 m_splashStyle = splashStyle;
75 m_milliseconds = milliseconds;
76
77 m_window = new wxSplashScreenWindow(bitmap, this, wxID_ANY, pos, size, wxNO_BORDER);
78
79 SetClientSize(bitmap.GetWidth(), bitmap.GetHeight());
80
81 if (m_splashStyle & wxSPLASH_CENTRE_ON_PARENT)
82 CentreOnParent();
83 else if (m_splashStyle & wxSPLASH_CENTRE_ON_SCREEN)
84 CentreOnScreen();
85
86 if (m_splashStyle & wxSPLASH_TIMEOUT)
87 {
88 m_timer.SetOwner(this, wxSPLASH_TIMER_ID);
89 m_timer.Start(milliseconds, true);
90 }
91
92 Show(true);
93 m_window->SetFocus();
94 #if defined( __WXMSW__ ) || defined(__WXMAC__)
95 Update(); // Without this, you see a blank screen for an instant
96 #elif defined(__WXGTK20__)
97 // we don't need to do anything at least on wxGTK with GTK+ 2.12.9
98 #else
99 wxYieldIfNeeded(); // Should eliminate this
100 #endif
101 }
102
103 wxSplashScreen::~wxSplashScreen()
104 {
105 m_timer.Stop();
106
107 wxEvtHandler::RemoveFilter(this);
108 }
109
110 int wxSplashScreen::FilterEvent(wxEvent& event)
111 {
112 const wxEventType t = event.GetEventType();
113 if ( t == wxEVT_KEY_DOWN ||
114 t == wxEVT_LEFT_DOWN ||
115 t == wxEVT_RIGHT_DOWN ||
116 t == wxEVT_MIDDLE_DOWN )
117 Close(true);
118
119 return -1;
120 }
121
122 void wxSplashScreen::OnNotify(wxTimerEvent& WXUNUSED(event))
123 {
124 Close(true);
125 }
126
127 void wxSplashScreen::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
128 {
129 m_timer.Stop();
130 this->Destroy();
131 }
132
133 // ----------------------------------------------------------------------------
134 // wxSplashScreenWindow
135 // ----------------------------------------------------------------------------
136
137 BEGIN_EVENT_TABLE(wxSplashScreenWindow, wxWindow)
138 #ifdef __WXGTK__
139 EVT_PAINT(wxSplashScreenWindow::OnPaint)
140 #endif
141 EVT_ERASE_BACKGROUND(wxSplashScreenWindow::OnEraseBackground)
142 END_EVENT_TABLE()
143
144 wxSplashScreenWindow::wxSplashScreenWindow(const wxBitmap& bitmap, wxWindow* parent,
145 wxWindowID id, const wxPoint& pos,
146 const wxSize& size, long style)
147 : wxWindow(parent, id, pos, size, style)
148 {
149 m_bitmap = bitmap;
150
151 #if !defined(__WXGTK__) && wxUSE_PALETTE
152 bool hiColour = (wxDisplayDepth() >= 16) ;
153
154 if (bitmap.GetPalette() && !hiColour)
155 {
156 SetPalette(* bitmap.GetPalette());
157 }
158 #endif
159 }
160
161 // VZ: why don't we do it under wxGTK?
162 #if !defined(__WXGTK__) && wxUSE_PALETTE
163 #define USE_PALETTE_IN_SPLASH
164 #endif
165
166 static void wxDrawSplashBitmap(wxDC& dc, const wxBitmap& bitmap, int WXUNUSED(x), int WXUNUSED(y))
167 {
168 wxMemoryDC dcMem;
169
170 #ifdef USE_PALETTE_IN_SPLASH
171 bool hiColour = (wxDisplayDepth() >= 16) ;
172
173 if (bitmap.GetPalette() && !hiColour)
174 {
175 dcMem.SetPalette(* bitmap.GetPalette());
176 }
177 #endif // USE_PALETTE_IN_SPLASH
178
179 dcMem.SelectObjectAsSource(bitmap);
180 dc.Blit(0, 0, bitmap.GetWidth(), bitmap.GetHeight(), &dcMem, 0, 0, wxCOPY,
181 true /* use mask */);
182 dcMem.SelectObject(wxNullBitmap);
183
184 #ifdef USE_PALETTE_IN_SPLASH
185 if (bitmap.GetPalette() && !hiColour)
186 {
187 dcMem.SetPalette(wxNullPalette);
188 }
189 #endif // USE_PALETTE_IN_SPLASH
190 }
191
192 void wxSplashScreenWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
193 {
194 wxPaintDC dc(this);
195 if (m_bitmap.IsOk())
196 wxDrawSplashBitmap(dc, m_bitmap, 0, 0);
197 }
198
199 void wxSplashScreenWindow::OnEraseBackground(wxEraseEvent& event)
200 {
201 if (event.GetDC() && m_bitmap.IsOk())
202 {
203 wxDrawSplashBitmap(* event.GetDC(), m_bitmap, 0, 0);
204 }
205 else
206 {
207 wxClientDC dc(this);
208 if (m_bitmap.IsOk())
209 wxDrawSplashBitmap(dc, m_bitmap, 0, 0);
210 }
211 }
212
213 #endif // wxUSE_SPLASH