1 /////////////////////////////////////////////////////////////////////////////
3 // Author: Vaclav Slavik
5 // Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
9 // ============================================================================
11 // ============================================================================
13 // ----------------------------------------------------------------------------
15 // ----------------------------------------------------------------------------
18 #pragma implementation "univtoplevel.h"
21 // For compilers that support precompilation, includes "wx.h".
22 #include "wx/wxprec.h"
29 #include "wx/toplevel.h"
30 #include "wx/univ/renderer.h"
31 #include "wx/dcclient.h"
32 #include "wx/bitmap.h"
34 #include "wx/cshelp.h"
37 // ----------------------------------------------------------------------------
39 // ----------------------------------------------------------------------------
41 BEGIN_EVENT_TABLE(wxTopLevelWindow
, wxTopLevelWindowNative
)
42 WX_EVENT_TABLE_INPUT_CONSUMER(wxTopLevelWindow
)
43 EVT_NC_PAINT(wxTopLevelWindow::OnNcPaint
)
46 WX_FORWARD_TO_INPUT_CONSUMER(wxTopLevelWindow
)
48 // ============================================================================
50 // ============================================================================
52 int wxTopLevelWindow::ms_drawDecorations
= -1;
54 void wxTopLevelWindow::Init()
61 bool wxTopLevelWindow::Create(wxWindow
*parent
,
63 const wxString
& title
,
69 // init them to avoid compiler warnings
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
78 if ( ms_drawDecorations
)
80 CreateInputHandler(wxINP_HANDLER_TOPLEVEL
);
83 exstyleOrig
= GetExtraStyle();
84 style
&= ~(wxCAPTION
| wxMINIMIZE_BOX
| wxMAXIMIZE_BOX
|
85 wxSYSTEM_MENU
| wxRESIZE_BORDER
| wxFRAME_TOOL_WINDOW
|
87 style
= wxSIMPLE_BORDER
;
88 SetExtraStyle(exstyleOrig
&
89 ~(wxFRAME_EX_CONTEXTHELP
| wxDIALOG_EX_CONTEXTHELP
));
92 if ( !wxTopLevelWindowNative::Create(parent
, id
, title
, pos
,
96 // FIXME: to be removed as soon as wxTLW/wxFrame/wxDialog creation code in
97 // wxMSW is rationalized
99 extern const wxChar
*wxFrameClassName
;
100 if ( !MSWCreate(id
, NULL
, wxFrameClassName
, this, title
,
101 pos
.x
, pos
.y
, size
.x
, size
.y
, style
) )
105 if ( ms_drawDecorations
)
107 m_windowStyle
= styleOrig
;
108 m_exStyle
= exstyleOrig
;
114 bool wxTopLevelWindow::ShowFullScreen(bool show
, long style
)
116 if ( show
== IsFullScreen() ) return FALSE
;
118 if ( ms_drawDecorations
)
122 m_fsSavedStyle
= m_windowStyle
;
123 if ( style
& wxFULLSCREEN_NOBORDER
)
124 m_windowStyle
|= wxSIMPLE_BORDER
;
125 if ( style
& wxFULLSCREEN_NOCAPTION
)
126 m_windowStyle
&= ~wxCAPTION
;
130 m_windowStyle
= m_fsSavedStyle
;
134 return wxTopLevelWindowNative::ShowFullScreen(show
, style
);
137 long wxTopLevelWindow::GetDecorationsStyle() const
141 if ( m_windowStyle
& wxCAPTION
)
143 style
|= wxTOPLEVEL_TITLEBAR
| wxTOPLEVEL_BUTTON_CLOSE
;
144 if ( m_windowStyle
& wxMINIMIZE_BOX
)
145 style
|= wxTOPLEVEL_BUTTON_ICONIZE
;
146 if ( m_windowStyle
& wxMAXIMIZE_BOX
)
147 style
|= wxTOPLEVEL_BUTTON_MAXIMIZE
;
149 if ( m_exStyle
& (wxFRAME_EX_CONTEXTHELP
| wxDIALOG_EX_CONTEXTHELP
))
150 style
|= wxTOPLEVEL_BUTTON_HELP
;
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
;
159 style
|= wxTOPLEVEL_MAXIMIZED
;
160 if ( GetIcon().Ok() )
161 style
|= wxTOPLEVEL_ICON
;
163 style
|= wxTOPLEVEL_ACTIVE
;
168 void wxTopLevelWindow::RefreshTitleBar()
170 wxNcPaintEvent
event(GetId());
171 event
.SetEventObject(this);
172 GetEventHandler()->ProcessEvent(event
);
175 // ----------------------------------------------------------------------------
176 // client area handling
177 // ----------------------------------------------------------------------------
179 wxPoint
wxTopLevelWindow::GetClientAreaOrigin() const
181 if ( ms_drawDecorations
)
184 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
185 wxRect rect
= wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
187 rect
= m_renderer
->GetFrameClientArea(rect
,
188 GetDecorationsStyle());
189 return rect
.GetPosition();
193 return wxTopLevelWindowNative::GetClientAreaOrigin();
197 void wxTopLevelWindow::DoGetClientSize(int *width
, int *height
) const
199 if ( ms_drawDecorations
)
202 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
203 wxRect rect
= wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
205 rect
= m_renderer
->GetFrameClientArea(rect
,
206 GetDecorationsStyle());
210 *height
= rect
.height
;
213 wxTopLevelWindowNative::DoGetClientSize(width
, height
);
216 void wxTopLevelWindow::DoSetClientSize(int width
, int height
)
218 if ( ms_drawDecorations
)
220 wxSize size
= m_renderer
->GetFrameTotalSize(wxSize(width
, height
),
221 GetDecorationsStyle());
222 wxTopLevelWindowNative::DoSetClientSize(size
.x
, size
.y
);
225 wxTopLevelWindowNative::DoSetClientSize(width
, height
);
228 void wxTopLevelWindow::OnNcPaint(wxPaintEvent
& event
)
230 if ( !ms_drawDecorations
|| !m_renderer
)
234 // get the window rect
236 wxSize size
= GetSize();
240 rect
.height
= size
.y
;
243 m_renderer
->DrawFrameTitleBar(dc
, rect
,
244 GetTitle(), m_titlebarIcon
,
245 GetDecorationsStyle(),
251 long wxTopLevelWindow::HitTest(const wxPoint
& pt
) const
254 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
255 wxRect
rect(wxTopLevelWindowNative::GetClientAreaOrigin(), wxSize(w
, h
));
257 return m_renderer
->HitTestFrame(rect
, pt
, GetDecorationsStyle());
260 // ----------------------------------------------------------------------------
262 // ----------------------------------------------------------------------------
264 void wxTopLevelWindow::SetIcon(const wxIcon
& icon
)
266 wxTopLevelWindowNative::SetIcon(icon
);
267 if ( !m_renderer
) return;
269 wxSize size
= m_renderer
->GetFrameIconSize();
271 if ( !icon
.Ok() || size
.x
== -1 )
272 m_titlebarIcon
= icon
;
276 bmp1
.CopyFromIcon(icon
);
278 m_titlebarIcon
= wxNullIcon
;
279 else if ( bmp1
.GetWidth() == size
.x
&& bmp1
.GetHeight() == size
.y
)
280 m_titlebarIcon
= icon
;
283 wxImage img
= bmp1
.ConvertToImage();
284 img
.Rescale(size
.x
, size
.y
);
285 m_titlebarIcon
.CopyFromBitmap(wxBitmap(img
));
290 // ----------------------------------------------------------------------------
292 // ----------------------------------------------------------------------------
294 void wxTopLevelWindow::ClickTitleBarButton(long button
)
298 case wxTOPLEVEL_BUTTON_CLOSE
:
302 case wxTOPLEVEL_BUTTON_ICONIZE
:
306 case wxTOPLEVEL_BUTTON_MAXIMIZE
:
310 case wxTOPLEVEL_BUTTON_RESTORE
:
314 case wxTOPLEVEL_BUTTON_HELP
:
317 wxContextHelp
contextHelp(this);
323 wxFAIL_MSG(wxT("incorrect button specification"));
327 bool wxTopLevelWindow::PerformAction(const wxControlAction
& action
,
329 const wxString
& strArg
)
331 bool isActive
= numArg
!= 0;
333 if ( action
== wxACTION_TOPLEVEL_ACTIVATE
)
335 if ( m_isActive
!= isActive
)
338 m_isActive
= isActive
;
339 wxNcPaintEvent
event(GetId());
340 event
.SetEventObject(this);
341 GetEventHandler()->ProcessEvent(event
);
346 else if ( action
== wxACTION_TOPLEVEL_BUTTON_PRESS
)
348 m_pressedButton
= numArg
;
353 else if ( action
== wxACTION_TOPLEVEL_BUTTON_RELEASE
)
360 else if ( action
== wxACTION_TOPLEVEL_BUTTON_CLICK
)
364 ClickTitleBarButton(numArg
);
373 // ============================================================================
374 // wxStdFrameInputHandler: handles focus, resizing and titlebar buttons clicks
375 // ============================================================================
377 wxStdFrameInputHandler::wxStdFrameInputHandler(wxInputHandler
*inphand
)
378 : wxStdInputHandler(inphand
)
385 bool wxStdFrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
386 const wxMouseEvent
& event
)
388 // the button has 2 states: pressed and normal with the following
389 // transitions between them:
391 // normal -> left down -> capture mouse and go to pressed state
392 // pressed -> left up inside -> generate click -> go to normal
393 // outside ------------------>
395 // the other mouse buttons are ignored
396 if ( event
.Button(1) )
398 if ( event
.ButtonDown(1) )
400 wxTopLevelWindow
*w
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
401 long hit
= w
->HitTest(event
.GetPosition());
403 if ( hit
& wxHT_TOPLEVEL_ANY_BUTTON
)
406 m_winCapture
->CaptureMouse();
409 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS
, m_winPressed
);
418 m_winCapture
->ReleaseMouse();
421 if ( m_winHitTest
== m_winPressed
)
423 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
, m_winPressed
);
427 //else: the mouse was released outside the window, this doesn't
432 return wxStdInputHandler::HandleMouse(consumer
, event
);
435 bool wxStdFrameInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
436 const wxMouseEvent
& event
)
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
)
442 long hit
= m_winCapture
->HitTest(event
.GetPosition());
444 if ( hit
!= m_winHitTest
)
446 if ( hit
!= m_winPressed
)
447 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_RELEASE
, m_winPressed
);
449 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS
, m_winPressed
);
456 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
459 bool wxStdFrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
462 consumer
->PerformAction(wxACTION_TOPLEVEL_ACTIVATE
, activated
);