]> git.saurik.com Git - wxWidgets.git/blob - src/common/toplvcmn.cpp
Improved size handling.
[wxWidgets.git] / src / common / toplvcmn.cpp
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$
7 // Copyright: (c) 1998 Robert Roebling and Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
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"
29 #include "wx/app.h"
30 #endif // WX_PRECOMP
31
32 // ----------------------------------------------------------------------------
33 // event table
34 // ----------------------------------------------------------------------------
35
36 BEGIN_EVENT_TABLE(wxTopLevelWindowBase, wxWindow)
37 EVT_CLOSE(wxTopLevelWindowBase::OnCloseWindow)
38 EVT_SIZE(wxTopLevelWindowBase::OnSize)
39 END_EVENT_TABLE()
40
41 // ============================================================================
42 // implementation
43 // ============================================================================
44
45 IMPLEMENT_ABSTRACT_CLASS(wxTopLevelWindow, wxWindow)
46
47 // ----------------------------------------------------------------------------
48 // construction/destruction
49 // ----------------------------------------------------------------------------
50
51 wxTopLevelWindowBase::wxTopLevelWindowBase()
52 {
53 // Unlike windows, top level windows are created hidden by default.
54 m_isShown = false;
55 }
56
57 wxTopLevelWindowBase::~wxTopLevelWindowBase()
58 {
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);
66
67 if ( shouldExit )
68 {
69 // then do it
70 wxTheApp->ExitMainLoop();
71 }
72 }
73
74 bool 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
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
87 // at all anymore during which we
88 // could delete any pending events.
89 Hide();
90 }
91
92 return true;
93 }
94
95 bool wxTopLevelWindowBase::IsLastBeforeExit() const
96 {
97 // we exit the application if there are no more top level windows left
98 // normally but wxApp can prevent this from happening
99 return wxTopLevelWindows.GetCount() == 1 &&
100 wxTopLevelWindows.GetFirst()->GetData() == (wxWindow *)this &&
101 wxTheApp && wxTheApp->GetExitOnFrameDelete();
102 }
103
104 // ----------------------------------------------------------------------------
105 // wxTopLevelWindow geometry
106 // ----------------------------------------------------------------------------
107
108 void wxTopLevelWindowBase::GetRectForTopLevelChildren(int *x, int *y, int *w, int *h)
109 {
110 GetPosition(x,y);
111 GetSize(w,h);
112 }
113
114 wxSize wxTopLevelWindowBase::GetMaxSize() const
115 {
116 wxSize size( GetMaxWidth(), GetMaxHeight() );
117 int w, h;
118
119 wxClientDisplayRect( 0, 0, &w, &h );
120
121 if( size.GetWidth() == wxDefaultCoord )
122 size.SetWidth( w );
123
124 if( size.GetHeight() == wxDefaultCoord )
125 size.SetHeight( h );
126
127 return size;
128 }
129
130 /* static */
131 wxSize 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
154 // ----------------------------------------------------------------------------
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
158 // ----------------------------------------------------------------------------
159
160 void wxTopLevelWindowBase::DoScreenToClient(int *x, int *y) const
161 {
162 wxWindow::DoScreenToClient(x, y);
163
164 // translate the wxWindow client coords to our client coords
165 wxPoint pt(GetClientAreaOrigin());
166 if ( x )
167 *x -= pt.x;
168 if ( y )
169 *y -= pt.y;
170 }
171
172 void wxTopLevelWindowBase::DoClientToScreen(int *x, int *y) const
173 {
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;
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
192 void wxTopLevelWindowBase::DoLayout()
193 {
194 // if we're using constraints or sizers - do use them
195 if ( GetAutoLayout() )
196 {
197 Layout();
198 }
199 else
200 {
201 // do we have _exactly_ one child?
202 wxWindow *child = (wxWindow *)NULL;
203 for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
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
238 child->SetSize(ofs, ofs, clientW - 2*ofs, clientH - 2*ofs);
239 }
240 }
241 }
242
243 // The default implementation for the close window event.
244 void wxTopLevelWindowBase::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
245 {
246 Destroy();
247 }
248
249 bool wxTopLevelWindowBase::SendIconizeEvent(bool iconized)
250 {
251 wxIconizeEvent event(GetId(), iconized);
252 event.SetEventObject(this);
253
254 return GetEventHandler()->ProcessEvent(event);
255 }
256
257 // do the window-specific processing after processing the update event
258 void wxTopLevelWindowBase::DoUpdateWindowUI(wxUpdateUIEvent& event)
259 {
260 if ( event.GetSetEnabled() )
261 Enable(event.GetEnabled());
262
263 if ( event.GetSetText() )
264 {
265 if ( event.GetText() != GetTitle() )
266 SetTitle(event.GetText());
267 }
268 }
269
270 void wxTopLevelWindowBase::RequestUserAttention(int WXUNUSED(flags))
271 {
272 // it's probably better than do nothing, isn't it?
273 Raise();
274 }
275