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