]> git.saurik.com Git - wxWidgets.git/blame - src/common/toplvcmn.cpp
improved wxMac event loop implementation and refactored the code to share it with...
[wxWidgets.git] / src / common / toplvcmn.cpp
CommitLineData
7d9f12f3
VS
1/////////////////////////////////////////////////////////////////////////////
2// Name: common/toplvcmn.cpp
3// Purpose: common (for all platforms) wxTopLevelWindow functions
4// Author: Julian Smart, Vadim Zeitlin
5// Created: 01/02/97
6// Id: $Id$
55d99c7a 7// Copyright: (c) 1998 Robert Roebling and Julian Smart
65571936 8// Licence: wxWindows licence
7d9f12f3
VS
9/////////////////////////////////////////////////////////////////////////////
10
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
7d9f12f3
VS
19// For compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
26#ifndef WX_PRECOMP
27 #include "wx/toplevel.h"
28 #include "wx/dcclient.h"
5f1d3069 29 #include "wx/app.h"
7d9f12f3
VS
30#endif // WX_PRECOMP
31
32// ----------------------------------------------------------------------------
33// event table
34// ----------------------------------------------------------------------------
35
36BEGIN_EVENT_TABLE(wxTopLevelWindowBase, wxWindow)
37 EVT_CLOSE(wxTopLevelWindowBase::OnCloseWindow)
38 EVT_SIZE(wxTopLevelWindowBase::OnSize)
39END_EVENT_TABLE()
40
41// ============================================================================
42// implementation
43// ============================================================================
44
f58585c0 45IMPLEMENT_ABSTRACT_CLASS(wxTopLevelWindow, wxWindow)
82c9f85c 46
7d9f12f3
VS
47// ----------------------------------------------------------------------------
48// construction/destruction
49// ----------------------------------------------------------------------------
50
51wxTopLevelWindowBase::wxTopLevelWindowBase()
52{
c7e61a5e
DE
53 // Unlike windows, top level windows are created hidden by default.
54 m_isShown = false;
7d9f12f3
VS
55}
56
799ea011
GD
57wxTopLevelWindowBase::~wxTopLevelWindowBase()
58{
1cbee0b4
VZ
59 // don't let wxTheApp keep any stale pointers to us
60 if ( wxTheApp && wxTheApp->GetTopWindow() == this )
61 wxTheApp->SetTopWindow(NULL);
62
63 bool shouldExit = IsLastBeforeExit();
64
65 wxTopLevelWindows.DeleteObject(this);
cb719f2e 66
1cbee0b4
VZ
67 if ( shouldExit )
68 {
69 // then do it
70 wxTheApp->ExitMainLoop();
71 }
799ea011
GD
72}
73
7d9f12f3
VS
74bool wxTopLevelWindowBase::Destroy()
75{
76 // delayed destruction: the frame will be deleted during the next idle
77 // loop iteration
78 if ( !wxPendingDelete.Member(this) )
79 wxPendingDelete.Append(this);
80
b3bd912d
RR
81 if (wxTopLevelWindows.GetCount() > 1)
82 {
83 // Hide it immediately. This should
84 // not be done if this TLW is the
85 // only one left since we then would
86 // risk not to get any idle events
cb719f2e 87 // at all anymore during which we
b3bd912d
RR
88 // could delete any pending events.
89 Hide();
90 }
cafcf62a 91
cb719f2e 92 return true;
7d9f12f3
VS
93}
94
5c363878 95bool wxTopLevelWindowBase::IsLastBeforeExit() const
1cbee0b4
VZ
96{
97 // we exit the application if there are no more top level windows left
98 // normally but wxApp can prevent this from happening
5c363878
VZ
99 return wxTopLevelWindows.GetCount() == 1 &&
100 wxTopLevelWindows.GetFirst()->GetData() == (wxWindow *)this &&
1cbee0b4
VZ
101 wxTheApp && wxTheApp->GetExitOnFrameDelete();
102}
103
104// ----------------------------------------------------------------------------
105// wxTopLevelWindow geometry
106// ----------------------------------------------------------------------------
107
0bba37f5
DE
108void wxTopLevelWindowBase::GetRectForTopLevelChildren(int *x, int *y, int *w, int *h)
109{
110 GetPosition(x,y);
111 GetSize(w,h);
112}
113
34c3ffca
RL
114wxSize wxTopLevelWindowBase::GetMaxSize() const
115{
116 wxSize size( GetMaxWidth(), GetMaxHeight() );
117 int w, h;
118
119 wxClientDisplayRect( 0, 0, &w, &h );
120
cb719f2e 121 if( size.GetWidth() == wxDefaultCoord )
34c3ffca
RL
122 size.SetWidth( w );
123
cb719f2e 124 if( size.GetHeight() == wxDefaultCoord )
34c3ffca
RL
125 size.SetHeight( h );
126
127 return size;
128}
129
0c089c08
VZ
130/* static */
131wxSize wxTopLevelWindowBase::GetDefaultSize()
132{
133 wxSize size = wxGetClientDisplayRect().GetSize();
134
135 // create proportionally bigger windows on small screens
136 if ( size.x >= 1024 )
137 size.x = 400;
138 else if ( size.x >= 800 )
139 size.x = 300;
140 else if ( size.x >= 320 )
141 size.x = 240;
142
143 if ( size.y >= 768 )
144 size.y = 250;
145 else if ( size.y > 200 )
146 {
147 size.y *= 2;
148 size.y /= 3;
149 }
150
151 return size;
152}
153
7d9f12f3 154// ----------------------------------------------------------------------------
82c9f85c
VZ
155// wxTopLevelWindow size management: we exclude the areas taken by
156// menu/status/toolbars from the client area, so the client area is what's
157// really available for the frame contents
7d9f12f3
VS
158// ----------------------------------------------------------------------------
159
160void wxTopLevelWindowBase::DoScreenToClient(int *x, int *y) const
161{
162 wxWindow::DoScreenToClient(x, y);
163
82c9f85c 164 // translate the wxWindow client coords to our client coords
7d9f12f3 165 wxPoint pt(GetClientAreaOrigin());
82c9f85c
VZ
166 if ( x )
167 *x -= pt.x;
168 if ( y )
169 *y -= pt.y;
7d9f12f3
VS
170}
171
172void wxTopLevelWindowBase::DoClientToScreen(int *x, int *y) const
173{
82c9f85c
VZ
174 // our client area origin (0, 0) may be really something like (0, 30) for
175 // wxWindow if we have a toolbar, account for it before translating
176 wxPoint pt(GetClientAreaOrigin());
177 if ( x )
178 *x += pt.x;
179 if ( y )
180 *y += pt.y;
7d9f12f3
VS
181
182 wxWindow::DoClientToScreen(x, y);
183}
184
185
186// ----------------------------------------------------------------------------
187// event handlers
188// ----------------------------------------------------------------------------
189
190// default resizing behaviour - if only ONE subwindow, resize to fill the
191// whole client area
5e62d4a5 192void wxTopLevelWindowBase::DoLayout()
7d9f12f3 193{
bc55104d 194 // if we're using constraints or sizers - do use them
7d9f12f3
VS
195 if ( GetAutoLayout() )
196 {
197 Layout();
198 }
199 else
7d9f12f3
VS
200 {
201 // do we have _exactly_ one child?
202 wxWindow *child = (wxWindow *)NULL;
222ed1d6 203 for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
7d9f12f3
VS
204 node;
205 node = node->GetNext() )
206 {
207 wxWindow *win = node->GetData();
208
209 // exclude top level and managed windows (status bar isn't
210 // currently in the children list except under wxMac anyhow, but
211 // it makes no harm to test for it)
212 if ( !win->IsTopLevel() && !IsOneOfBars(win) )
213 {
214 if ( child )
215 {
216 return; // it's our second subwindow - nothing to do
217 }
218
219 child = win;
220 }
221 }
222
223 // do we have any children at all?
224 if ( child )
225 {
226 // exactly one child - set it's size to fill the whole frame
227 int clientW, clientH;
228 DoGetClientSize(&clientW, &clientH);
229
230 // for whatever reasons, wxGTK wants to have a small offset - it
231 // probably looks better with it?
232#ifdef __WXGTK__
233 static const int ofs = 1;
234#else
235 static const int ofs = 0;
236#endif
237
45e0dc94 238 child->SetSize(ofs, ofs, clientW - 2*ofs, clientH - 2*ofs);
7d9f12f3
VS
239 }
240 }
241}
242
243// The default implementation for the close window event.
244void wxTopLevelWindowBase::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
245{
246 Destroy();
247}
248
249bool wxTopLevelWindowBase::SendIconizeEvent(bool iconized)
250{
251 wxIconizeEvent event(GetId(), iconized);
252 event.SetEventObject(this);
253
254 return GetEventHandler()->ProcessEvent(event);
255}
34c3ffca 256
e39af974
JS
257// do the window-specific processing after processing the update event
258void wxTopLevelWindowBase::DoUpdateWindowUI(wxUpdateUIEvent& event)
259{
260 if ( event.GetSetEnabled() )
261 Enable(event.GetEnabled());
cb719f2e 262
e39af974
JS
263 if ( event.GetSetText() )
264 {
265 if ( event.GetText() != GetTitle() )
266 SetTitle(event.GetText());
267 }
268}
269
447fd332 270void wxTopLevelWindowBase::RequestUserAttention(int WXUNUSED(flags))
9b59c95b
VZ
271{
272 // it's probably better than do nothing, isn't it?
273 Raise();
274}
275