]> git.saurik.com Git - wxWidgets.git/blame - src/univ/topluniv.cpp
fixes for wxUSE_PALETTE=0 compilation
[wxWidgets.git] / src / univ / topluniv.cpp
CommitLineData
0f1bf77d
VS
1/////////////////////////////////////////////////////////////////////////////
2// Name: topluniv.cpp
3// Author: Vaclav Slavik
4// Id: $Id$
5// Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
6// Licence: wxWindows licence
7/////////////////////////////////////////////////////////////////////////////
8
9// ============================================================================
10// declarations
11// ============================================================================
12
13// ----------------------------------------------------------------------------
14// headers
15// ----------------------------------------------------------------------------
16
17#ifdef __GNUG__
18 #pragma implementation "univtoplevel.h"
19#endif
20
21// For compilers that support precompilation, includes "wx.h".
22#include "wx/wxprec.h"
23
24#ifdef __BORLANDC__
25#pragma hdrstop
26#endif
27
28#include "wx/defs.h"
29#include "wx/toplevel.h"
24a23c35
VS
30#include "wx/univ/renderer.h"
31#include "wx/dcclient.h"
32#include "wx/bitmap.h"
33#include "wx/image.h"
813edf09 34#include "wx/cshelp.h"
0f1bf77d
VS
35
36
37// ----------------------------------------------------------------------------
38// event tables
39// ----------------------------------------------------------------------------
40
24a23c35 41BEGIN_EVENT_TABLE(wxTopLevelWindow, wxTopLevelWindowNative)
ea1b0d6c 42 WX_EVENT_TABLE_INPUT_CONSUMER(wxTopLevelWindow)
24a23c35
VS
43 EVT_NC_PAINT(wxTopLevelWindow::OnNcPaint)
44END_EVENT_TABLE()
45
ea1b0d6c
VS
46WX_FORWARD_TO_INPUT_CONSUMER(wxTopLevelWindow)
47
0f1bf77d
VS
48// ============================================================================
49// implementation
50// ============================================================================
51
24a23c35
VS
52int wxTopLevelWindow::ms_drawDecorations = -1;
53
0f1bf77d
VS
54void wxTopLevelWindow::Init()
55{
24a23c35 56 m_isActive = FALSE;
ea1b0d6c 57 m_windowStyle = 0;
813edf09 58 m_pressedButton = 0;
0f1bf77d
VS
59}
60
61bool wxTopLevelWindow::Create(wxWindow *parent,
62 wxWindowID id,
63 const wxString& title,
64 const wxPoint& pos,
7ee7c43f 65 const wxSize& size,
0f1bf77d
VS
66 long style,
67 const wxString &name)
68{
2e9f62da
VZ
69 // init them to avoid compiler warnings
70 long styleOrig = 0,
71 exstyleOrig = 0;
24a23c35
VS
72
73 if ( ms_drawDecorations == -1 )
74 ms_drawDecorations = TRUE;
75 // FIXME_MGL -- this is temporary; we assume for now that native TLW
76 // can't do decorations, which is not true
77
78 if ( ms_drawDecorations )
79 {
ea1b0d6c
VS
80 CreateInputHandler(wxINP_HANDLER_TOPLEVEL);
81
24a23c35
VS
82 styleOrig = style;
83 exstyleOrig = GetExtraStyle();
7ee7c43f
VZ
84 style &= ~(wxCAPTION | wxMINIMIZE_BOX | wxMAXIMIZE_BOX |
85 wxSYSTEM_MENU | wxRESIZE_BORDER | wxFRAME_TOOL_WINDOW |
813edf09
VS
86 wxTHICK_FRAME);
87 style = wxSIMPLE_BORDER;
7ee7c43f 88 SetExtraStyle(exstyleOrig &
813edf09 89 ~(wxFRAME_EX_CONTEXTHELP | wxDIALOG_EX_CONTEXTHELP));
24a23c35
VS
90 }
91
7ee7c43f
VZ
92 if ( !wxTopLevelWindowNative::Create(parent, id, title, pos,
93 size, style, name) )
94 return FALSE;
95
96 // FIXME: to be removed as soon as wxTLW/wxFrame/wxDialog creation code in
97 // wxMSW is rationalized
98#ifdef __WXMSW__
99 extern const wxChar *wxFrameClassName;
100 if ( !MSWCreate(id, NULL, wxFrameClassName, this, title,
101 pos.x, pos.y, size.x, size.y, style) )
0f1bf77d 102 return FALSE;
7ee7c43f 103#endif // __WXMSW__
0f1bf77d 104
24a23c35
VS
105 if ( ms_drawDecorations )
106 {
107 m_windowStyle = styleOrig;
108 m_exStyle = exstyleOrig;
109 }
7ee7c43f 110
0f1bf77d
VS
111 return TRUE;
112}
113
114bool wxTopLevelWindow::ShowFullScreen(bool show, long style)
115{
116 if ( show == IsFullScreen() ) return FALSE;
7ee7c43f 117
ea1b0d6c
VS
118 if ( ms_drawDecorations )
119 {
120 if ( show )
121 {
122 m_fsSavedStyle = m_windowStyle;
123 if ( style & wxFULLSCREEN_NOBORDER )
124 m_windowStyle |= wxSIMPLE_BORDER;
125 if ( style & wxFULLSCREEN_NOCAPTION )
126 m_windowStyle &= ~wxCAPTION;
127 }
128 else
129 {
130 m_windowStyle = m_fsSavedStyle;
131 }
132 }
2e9f62da 133
ea1b0d6c 134 return wxTopLevelWindowNative::ShowFullScreen(show, style);
0f1bf77d
VS
135}
136
24a23c35
VS
137long wxTopLevelWindow::GetDecorationsStyle() const
138{
139 long style = 0;
140
141 if ( m_windowStyle & wxCAPTION )
142 {
ea1b0d6c 143 style |= wxTOPLEVEL_TITLEBAR | wxTOPLEVEL_BUTTON_CLOSE;
24a23c35 144 if ( m_windowStyle & wxMINIMIZE_BOX )
813edf09 145 style |= wxTOPLEVEL_BUTTON_ICONIZE;
24a23c35 146 if ( m_windowStyle & wxMAXIMIZE_BOX )
ea1b0d6c 147 style |= wxTOPLEVEL_BUTTON_MAXIMIZE;
813edf09 148#if wxUSE_HELP
24a23c35 149 if ( m_exStyle & (wxFRAME_EX_CONTEXTHELP | wxDIALOG_EX_CONTEXTHELP))
ea1b0d6c 150 style |= wxTOPLEVEL_BUTTON_HELP;
813edf09 151#endif
24a23c35
VS
152 }
153 if ( (m_windowStyle & (wxSIMPLE_BORDER | wxNO_BORDER)) == 0 )
154 style |= wxTOPLEVEL_BORDER;
155 if ( m_windowStyle & (wxRESIZE_BORDER | wxTHICK_FRAME) )
156 style |= wxTOPLEVEL_RESIZEABLE;
7ee7c43f 157
24a23c35
VS
158 if ( IsMaximized() )
159 style |= wxTOPLEVEL_MAXIMIZED;
160 if ( GetIcon().Ok() )
161 style |= wxTOPLEVEL_ICON;
ea1b0d6c 162 if ( m_isActive )
24a23c35
VS
163 style |= wxTOPLEVEL_ACTIVE;
164
165 return style;
166}
167
813edf09
VS
168void wxTopLevelWindow::RefreshTitleBar()
169{
170 wxNcPaintEvent event(GetId());
171 event.SetEventObject(this);
172 GetEventHandler()->ProcessEvent(event);
173}
174
24a23c35
VS
175// ----------------------------------------------------------------------------
176// client area handling
177// ----------------------------------------------------------------------------
178
179wxPoint wxTopLevelWindow::GetClientAreaOrigin() const
180{
181 if ( ms_drawDecorations )
182 {
183 int w, h;
184 wxTopLevelWindowNative::DoGetClientSize(&w, &h);
185 wxRect rect = wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
186 wxSize(w, h));
7ee7c43f 187 rect = m_renderer->GetFrameClientArea(rect,
24a23c35
VS
188 GetDecorationsStyle());
189 return rect.GetPosition();
190 }
191 else
192 {
193 return wxTopLevelWindowNative::GetClientAreaOrigin();
194 }
195}
196
197void wxTopLevelWindow::DoGetClientSize(int *width, int *height) const
198{
199 if ( ms_drawDecorations )
200 {
201 int w, h;
202 wxTopLevelWindowNative::DoGetClientSize(&w, &h);
203 wxRect rect = wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
204 wxSize(w, h));
7ee7c43f 205 rect = m_renderer->GetFrameClientArea(rect,
24a23c35
VS
206 GetDecorationsStyle());
207 if ( width )
208 *width = rect.width;
209 if ( height )
210 *height = rect.height;
211 }
212 else
213 wxTopLevelWindowNative::DoGetClientSize(width, height);
214}
215
216void wxTopLevelWindow::DoSetClientSize(int width, int height)
217{
218 if ( ms_drawDecorations )
219 {
7ee7c43f 220 wxSize size = m_renderer->GetFrameTotalSize(wxSize(width, height),
24a23c35
VS
221 GetDecorationsStyle());
222 wxTopLevelWindowNative::DoSetClientSize(size.x, size.y);
223 }
224 else
225 wxTopLevelWindowNative::DoSetClientSize(width, height);
226}
227
228void wxTopLevelWindow::OnNcPaint(wxPaintEvent& event)
229{
230 if ( !ms_drawDecorations || !m_renderer )
231 event.Skip();
232 else
233 {
234 // get the window rect
235 wxRect rect;
236 wxSize size = GetSize();
237 rect.x =
238 rect.y = 0;
239 rect.width = size.x;
240 rect.height = size.y;
241
242 wxWindowDC dc(this);
7ee7c43f 243 m_renderer->DrawFrameTitleBar(dc, rect,
24a23c35 244 GetTitle(), m_titlebarIcon,
813edf09
VS
245 GetDecorationsStyle(),
246 m_pressedButton,
247 wxCONTROL_PRESSED);
24a23c35
VS
248 }
249}
250
813edf09
VS
251long wxTopLevelWindow::HitTest(const wxPoint& pt) const
252{
253 int w, h;
254 wxTopLevelWindowNative::DoGetClientSize(&w, &h);
255 wxRect rect(wxTopLevelWindowNative::GetClientAreaOrigin(), wxSize(w, h));
7ee7c43f 256
813edf09
VS
257 return m_renderer->HitTestFrame(rect, pt, GetDecorationsStyle());
258}
259
24a23c35
VS
260// ----------------------------------------------------------------------------
261// icons
262// ----------------------------------------------------------------------------
263
264void wxTopLevelWindow::SetIcon(const wxIcon& icon)
265{
266 wxTopLevelWindowNative::SetIcon(icon);
267 if ( !m_renderer ) return;
268
269 wxSize size = m_renderer->GetFrameIconSize();
7ee7c43f 270
24a23c35
VS
271 if ( !icon.Ok() || size.x == -1 )
272 m_titlebarIcon = icon;
273 else
274 {
275 wxBitmap bmp1;
276 bmp1.CopyFromIcon(icon);
277 if ( !bmp1.Ok() )
278 m_titlebarIcon = wxNullIcon;
279 else if ( bmp1.GetWidth() == size.x && bmp1.GetHeight() == size.y )
280 m_titlebarIcon = icon;
281 else
282 {
283 wxImage img = bmp1.ConvertToImage();
284 img.Rescale(size.x, size.y);
ea1b0d6c 285 m_titlebarIcon.CopyFromBitmap(wxBitmap(img));
24a23c35
VS
286 }
287 }
288}
ea1b0d6c
VS
289
290// ----------------------------------------------------------------------------
291// actions
292// ----------------------------------------------------------------------------
293
813edf09
VS
294void wxTopLevelWindow::ClickTitleBarButton(long button)
295{
296 switch ( button )
297 {
298 case wxTOPLEVEL_BUTTON_CLOSE:
299 Close();
300 break;
301
302 case wxTOPLEVEL_BUTTON_ICONIZE:
303 Iconize();
304 break;
305
306 case wxTOPLEVEL_BUTTON_MAXIMIZE:
307 Maximize();
308 break;
309
310 case wxTOPLEVEL_BUTTON_RESTORE:
311 Restore();
312 break;
313
314 case wxTOPLEVEL_BUTTON_HELP:
315#if wxUSE_HELP
316 {
317 wxContextHelp contextHelp(this);
318 }
319#endif
320 break;
7ee7c43f 321
813edf09
VS
322 default:
323 wxFAIL_MSG(wxT("incorrect button specification"));
324 }
325}
326
ea1b0d6c
VS
327bool wxTopLevelWindow::PerformAction(const wxControlAction& action,
328 long numArg,
329 const wxString& strArg)
330{
7ee7c43f
VZ
331 bool isActive = numArg != 0;
332
ea1b0d6c
VS
333 if ( action == wxACTION_TOPLEVEL_ACTIVATE )
334 {
7ee7c43f 335 if ( m_isActive != isActive )
ea1b0d6c
VS
336 {
337 Refresh();
7ee7c43f 338 m_isActive = isActive;
ea1b0d6c
VS
339 wxNcPaintEvent event(GetId());
340 event.SetEventObject(this);
341 GetEventHandler()->ProcessEvent(event);
ea1b0d6c
VS
342 }
343 return TRUE;
344 }
7ee7c43f 345
813edf09
VS
346 else if ( action == wxACTION_TOPLEVEL_BUTTON_PRESS )
347 {
348 m_pressedButton = numArg;
349 RefreshTitleBar();
350 return TRUE;
351 }
7ee7c43f 352
813edf09
VS
353 else if ( action == wxACTION_TOPLEVEL_BUTTON_RELEASE )
354 {
355 m_pressedButton = 0;
356 RefreshTitleBar();
357 return TRUE;
358 }
7ee7c43f 359
813edf09
VS
360 else if ( action == wxACTION_TOPLEVEL_BUTTON_CLICK )
361 {
362 m_pressedButton = 0;
363 RefreshTitleBar();
364 ClickTitleBarButton(numArg);
365 return TRUE;
366 }
7ee7c43f 367
ea1b0d6c
VS
368 else
369 return FALSE;
370}
371
372
373// ============================================================================
374// wxStdFrameInputHandler: handles focus, resizing and titlebar buttons clicks
375// ============================================================================
376
377wxStdFrameInputHandler::wxStdFrameInputHandler(wxInputHandler *inphand)
378 : wxStdInputHandler(inphand)
379{
813edf09
VS
380 m_winCapture = NULL;
381 m_winHitTest = 0;
382 m_winPressed = 0;
ea1b0d6c
VS
383}
384
385bool wxStdFrameInputHandler::HandleMouse(wxInputConsumer *consumer,
386 const wxMouseEvent& event)
387{
813edf09
VS
388 // the button has 2 states: pressed and normal with the following
389 // transitions between them:
390 //
391 // normal -> left down -> capture mouse and go to pressed state
392 // pressed -> left up inside -> generate click -> go to normal
393 // outside ------------------>
394 //
395 // the other mouse buttons are ignored
396 if ( event.Button(1) )
397 {
398 if ( event.ButtonDown(1) )
399 {
400 wxTopLevelWindow *w = wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow);
401 long hit = w->HitTest(event.GetPosition());
7ee7c43f 402
813edf09
VS
403 if ( hit & wxHT_TOPLEVEL_ANY_BUTTON )
404 {
405 m_winCapture = w;
406 m_winCapture->CaptureMouse();
407 m_winHitTest = hit;
408 m_winPressed = hit;
409 consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS, m_winPressed);
410 return TRUE;
411 }
412 }
413
414 else // up
415 {
416 if ( m_winCapture )
417 {
418 m_winCapture->ReleaseMouse();
419 m_winCapture = NULL;
420
421 if ( m_winHitTest == m_winPressed )
422 {
423 consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK, m_winPressed);
424 return TRUE;
425 }
426 }
427 //else: the mouse was released outside the window, this doesn't
428 // count as a click
429 }
430 }
431
ea1b0d6c
VS
432 return wxStdInputHandler::HandleMouse(consumer, event);
433}
434
7ee7c43f 435bool wxStdFrameInputHandler::HandleMouseMove(wxInputConsumer *consumer,
ea1b0d6c
VS
436 const wxMouseEvent& event)
437{
813edf09
VS
438 // we only have to do something when the mouse leaves/enters the pressed
439 // button and don't care about the other ones
440 if ( event.GetEventObject() == m_winCapture )
441 {
442 long hit = m_winCapture->HitTest(event.GetPosition());
443
444 if ( hit != m_winHitTest )
445 {
446 if ( hit != m_winPressed )
447 consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_RELEASE, m_winPressed);
448 else
449 consumer->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS, m_winPressed);
7ee7c43f 450
813edf09
VS
451 m_winHitTest = hit;
452 return TRUE;
453 }
454 }
455
ea1b0d6c
VS
456 return wxStdInputHandler::HandleMouseMove(consumer, event);
457}
458
7ee7c43f 459bool wxStdFrameInputHandler::HandleActivation(wxInputConsumer *consumer,
ea1b0d6c
VS
460 bool activated)
461{
462 consumer->PerformAction(wxACTION_TOPLEVEL_ACTIVATE, activated);
463 return FALSE;
464}