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"
31 #include "wx/dcclient.h"
32 #include "wx/settings.h"
35 #include "wx/toplevel.h"
36 #include "wx/univ/renderer.h"
37 #include "wx/bitmap.h"
39 #include "wx/cshelp.h"
42 // ----------------------------------------------------------------------------
44 // ----------------------------------------------------------------------------
46 BEGIN_EVENT_TABLE(wxTopLevelWindow
, wxTopLevelWindowNative
)
47 WX_EVENT_TABLE_INPUT_CONSUMER(wxTopLevelWindow
)
48 EVT_NC_PAINT(wxTopLevelWindow::OnNcPaint
)
51 WX_FORWARD_TO_INPUT_CONSUMER(wxTopLevelWindow
)
53 // ============================================================================
55 // ============================================================================
57 int wxTopLevelWindow::ms_drawDecorations
= -1;
59 void wxTopLevelWindow::Init()
66 bool wxTopLevelWindow::Create(wxWindow
*parent
,
68 const wxString
& title
,
74 // init them to avoid compiler warnings
78 if ( ms_drawDecorations
== -1 )
79 ms_drawDecorations
= !wxSystemSettings::HasFrameDecorations();
80 // FIXME -- wxUniv should provide a way to force non-native decorations!
82 if ( ms_drawDecorations
)
84 CreateInputHandler(wxINP_HANDLER_TOPLEVEL
);
87 exstyleOrig
= GetExtraStyle();
88 style
&= ~(wxCAPTION
| wxMINIMIZE_BOX
| wxMAXIMIZE_BOX
|
89 wxSYSTEM_MENU
| wxRESIZE_BORDER
| wxFRAME_TOOL_WINDOW
|
91 style
= wxSIMPLE_BORDER
;
92 SetExtraStyle(exstyleOrig
&
93 ~(wxFRAME_EX_CONTEXTHELP
| wxDIALOG_EX_CONTEXTHELP
));
96 if ( !wxTopLevelWindowNative::Create(parent
, id
, title
, pos
,
100 // FIXME: to be removed as soon as wxTLW/wxFrame/wxDialog creation code in
101 // wxMSW is rationalized
103 extern const wxChar
*wxFrameClassName
;
104 if ( !MSWCreate(id
, NULL
, wxFrameClassName
, this, title
,
105 pos
.x
, pos
.y
, size
.x
, size
.y
, style
) )
109 if ( ms_drawDecorations
)
111 m_windowStyle
= styleOrig
;
112 m_exStyle
= exstyleOrig
;
118 bool wxTopLevelWindow::ShowFullScreen(bool show
, long style
)
120 if ( show
== IsFullScreen() ) return FALSE
;
122 if ( ms_drawDecorations
)
126 m_fsSavedStyle
= m_windowStyle
;
127 if ( style
& wxFULLSCREEN_NOBORDER
)
128 m_windowStyle
|= wxSIMPLE_BORDER
;
129 if ( style
& wxFULLSCREEN_NOCAPTION
)
130 m_windowStyle
&= ~wxCAPTION
;
134 m_windowStyle
= m_fsSavedStyle
;
138 return wxTopLevelWindowNative::ShowFullScreen(show
, style
);
141 long wxTopLevelWindow::GetDecorationsStyle() const
145 if ( m_windowStyle
& wxCAPTION
)
147 style
|= wxTOPLEVEL_TITLEBAR
| wxTOPLEVEL_BUTTON_CLOSE
;
148 if ( m_windowStyle
& wxMINIMIZE_BOX
)
149 style
|= wxTOPLEVEL_BUTTON_ICONIZE
;
150 if ( m_windowStyle
& wxMAXIMIZE_BOX
)
153 style
|= wxTOPLEVEL_BUTTON_RESTORE
;
155 style
|= wxTOPLEVEL_BUTTON_MAXIMIZE
;
158 if ( m_exStyle
& (wxFRAME_EX_CONTEXTHELP
| wxDIALOG_EX_CONTEXTHELP
))
159 style
|= wxTOPLEVEL_BUTTON_HELP
;
162 if ( (m_windowStyle
& (wxSIMPLE_BORDER
| wxNO_BORDER
)) == 0 )
163 style
|= wxTOPLEVEL_BORDER
;
164 if ( m_windowStyle
& (wxRESIZE_BORDER
| wxTHICK_FRAME
) )
165 style
|= wxTOPLEVEL_RESIZEABLE
;
168 style
|= wxTOPLEVEL_MAXIMIZED
;
169 if ( GetIcon().Ok() )
170 style
|= wxTOPLEVEL_ICON
;
172 style
|= wxTOPLEVEL_ACTIVE
;
177 void wxTopLevelWindow::RefreshTitleBar()
179 wxNcPaintEvent
event(GetId());
180 event
.SetEventObject(this);
181 GetEventHandler()->ProcessEvent(event
);
184 // ----------------------------------------------------------------------------
185 // client area handling
186 // ----------------------------------------------------------------------------
188 wxPoint
wxTopLevelWindow::GetClientAreaOrigin() const
190 if ( ms_drawDecorations
)
193 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
194 wxRect rect
= wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
196 rect
= m_renderer
->GetFrameClientArea(rect
,
197 GetDecorationsStyle());
198 return rect
.GetPosition();
202 return wxTopLevelWindowNative::GetClientAreaOrigin();
206 void wxTopLevelWindow::DoGetClientSize(int *width
, int *height
) const
208 if ( ms_drawDecorations
)
211 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
212 wxRect rect
= wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
214 rect
= m_renderer
->GetFrameClientArea(rect
,
215 GetDecorationsStyle());
219 *height
= rect
.height
;
222 wxTopLevelWindowNative::DoGetClientSize(width
, height
);
225 void wxTopLevelWindow::DoSetClientSize(int width
, int height
)
227 if ( ms_drawDecorations
)
229 wxSize size
= m_renderer
->GetFrameTotalSize(wxSize(width
, height
),
230 GetDecorationsStyle());
231 wxTopLevelWindowNative::DoSetClientSize(size
.x
, size
.y
);
234 wxTopLevelWindowNative::DoSetClientSize(width
, height
);
237 void wxTopLevelWindow::OnNcPaint(wxPaintEvent
& event
)
239 if ( !ms_drawDecorations
|| !m_renderer
)
243 // get the window rect
245 wxSize size
= GetSize();
249 rect
.height
= size
.y
;
252 m_renderer
->DrawFrameTitleBar(dc
, rect
,
253 GetTitle(), m_titlebarIcon
,
254 GetDecorationsStyle(),
260 long wxTopLevelWindow::HitTest(const wxPoint
& pt
) const
263 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
264 wxRect
rect(wxTopLevelWindowNative::GetClientAreaOrigin(), wxSize(w
, h
));
266 return m_renderer
->HitTestFrame(rect
, pt
, GetDecorationsStyle());
269 // ----------------------------------------------------------------------------
271 // ----------------------------------------------------------------------------
273 void wxTopLevelWindow::SetIcon(const wxIcon
& icon
)
275 wxTopLevelWindowNative::SetIcon(icon
);
277 if ( ms_drawDecorations
&& m_renderer
)
279 wxSize size
= m_renderer
->GetFrameIconSize();
281 if ( !icon
.Ok() || size
.x
== -1 )
282 m_titlebarIcon
= icon
;
286 bmp1
.CopyFromIcon(icon
);
288 m_titlebarIcon
= wxNullIcon
;
289 else if ( bmp1
.GetWidth() == size
.x
&& bmp1
.GetHeight() == size
.y
)
290 m_titlebarIcon
= icon
;
293 wxImage img
= bmp1
.ConvertToImage();
294 img
.Rescale(size
.x
, size
.y
);
295 m_titlebarIcon
.CopyFromBitmap(wxBitmap(img
));
301 // ----------------------------------------------------------------------------
303 // ----------------------------------------------------------------------------
305 void wxTopLevelWindow::ClickTitleBarButton(long button
)
309 case wxTOPLEVEL_BUTTON_CLOSE
:
313 case wxTOPLEVEL_BUTTON_ICONIZE
:
317 case wxTOPLEVEL_BUTTON_MAXIMIZE
:
321 case wxTOPLEVEL_BUTTON_RESTORE
:
325 case wxTOPLEVEL_BUTTON_HELP
:
328 wxContextHelp
contextHelp(this);
334 wxFAIL_MSG(wxT("incorrect button specification"));
338 bool wxTopLevelWindow::PerformAction(const wxControlAction
& action
,
340 const wxString
& strArg
)
342 bool isActive
= numArg
!= 0;
344 if ( action
== wxACTION_TOPLEVEL_ACTIVATE
)
346 if ( m_isActive
!= isActive
)
348 m_isActive
= isActive
;
354 else if ( action
== wxACTION_TOPLEVEL_BUTTON_PRESS
)
356 m_pressedButton
= numArg
;
361 else if ( action
== wxACTION_TOPLEVEL_BUTTON_RELEASE
)
368 else if ( action
== wxACTION_TOPLEVEL_BUTTON_CLICK
)
372 ClickTitleBarButton(numArg
);
376 else if ( action
== wxACTION_TOPLEVEL_MOVE
)
378 InteractiveMove(wxINTERACTIVE_MOVE
);
382 else if ( action
== wxACTION_TOPLEVEL_RESIZE
)
384 int flags
= wxINTERACTIVE_RESIZE
;
385 if ( numArg
& wxHT_TOPLEVEL_BORDER_N
)
386 flags
|= wxINTERACTIVE_RESIZE_N
;
387 if ( numArg
& wxHT_TOPLEVEL_BORDER_S
)
388 flags
|= wxINTERACTIVE_RESIZE_S
;
389 if ( numArg
& wxHT_TOPLEVEL_BORDER_W
)
390 flags
|= wxINTERACTIVE_RESIZE_W
;
391 if ( numArg
& wxHT_TOPLEVEL_BORDER_E
)
392 flags
|= wxINTERACTIVE_RESIZE_E
;
393 InteractiveMove(flags
);
402 // ============================================================================
403 // wxStdFrameInputHandler: handles focus, resizing and titlebar buttons clicks
404 // ============================================================================
406 wxStdFrameInputHandler::wxStdFrameInputHandler(wxInputHandler
*inphand
)
407 : wxStdInputHandler(inphand
)
412 m_borderCursorOn
= FALSE
;
415 bool wxStdFrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
416 const wxMouseEvent
& event
)
418 // the button has 2 states: pressed and normal with the following
419 // transitions between them:
421 // normal -> left down -> capture mouse and go to pressed state
422 // pressed -> left up inside -> generate click -> go to normal
423 // outside ------------------>
425 // the other mouse buttons are ignored
426 if ( event
.Button(1) )
428 if ( event
.ButtonDown(1) )
430 wxTopLevelWindow
*w
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
431 long hit
= w
->HitTest(event
.GetPosition());
433 if ( hit
& wxHT_TOPLEVEL_ANY_BUTTON
)
436 m_winCapture
->CaptureMouse();
439 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS
, m_winPressed
);
442 else if ( hit
& wxHT_TOPLEVEL_TITLEBAR
)
444 consumer
->PerformAction(wxACTION_TOPLEVEL_MOVE
);
447 else if ( (consumer
->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER
)
448 && (hit
& wxHT_TOPLEVEL_ANY_BORDER
) )
450 consumer
->PerformAction(wxACTION_TOPLEVEL_RESIZE
, hit
);
459 m_winCapture
->ReleaseMouse();
462 if ( m_winHitTest
== m_winPressed
)
464 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
, m_winPressed
);
468 //else: the mouse was released outside the window, this doesn't
473 return wxStdInputHandler::HandleMouse(consumer
, event
);
476 bool wxStdFrameInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
477 const wxMouseEvent
& event
)
479 if ( event
.GetEventObject() == m_winCapture
)
481 long hit
= m_winCapture
->HitTest(event
.GetPosition());
483 if ( hit
!= m_winHitTest
)
485 if ( hit
!= m_winPressed
)
486 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_RELEASE
, m_winPressed
);
488 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS
, m_winPressed
);
494 else if ( consumer
->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER
)
496 wxTopLevelWindow
*win
= wxStaticCast(consumer
->GetInputWindow(),
498 long hit
= win
->HitTest(event
.GetPosition());
500 if ( hit
!= m_winHitTest
)
504 if ( m_borderCursorOn
)
506 m_borderCursorOn
= FALSE
;
507 win
->SetCursor(m_origCursor
);
510 if ( hit
& wxHT_TOPLEVEL_ANY_BORDER
)
512 m_borderCursorOn
= TRUE
;
517 case wxHT_TOPLEVEL_BORDER_N
:
518 case wxHT_TOPLEVEL_BORDER_S
:
519 cur
= wxCursor(wxCURSOR_SIZENS
);
521 case wxHT_TOPLEVEL_BORDER_W
:
522 case wxHT_TOPLEVEL_BORDER_E
:
523 cur
= wxCursor(wxCURSOR_SIZEWE
);
525 case wxHT_TOPLEVEL_BORDER_NE
:
526 case wxHT_TOPLEVEL_BORDER_SW
:
527 cur
= wxCursor(wxCURSOR_SIZENESW
);
529 case wxHT_TOPLEVEL_BORDER_NW
:
530 case wxHT_TOPLEVEL_BORDER_SE
:
531 cur
= wxCursor(wxCURSOR_SIZENWSE
);
534 m_borderCursorOn
= FALSE
;
537 if ( m_borderCursorOn
)
539 m_origCursor
= win
->GetCursor();
546 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
549 bool wxStdFrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
552 if ( m_borderCursorOn
)
554 consumer
->GetInputWindow()->SetCursor(m_origCursor
);
555 m_borderCursorOn
= FALSE
;
557 consumer
->PerformAction(wxACTION_TOPLEVEL_ACTIVATE
, activated
);