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;
58 int wxTopLevelWindow::ms_canIconize
= -1;
60 void wxTopLevelWindow::Init()
67 bool wxTopLevelWindow::Create(wxWindow
*parent
,
69 const wxString
& title
,
75 // init them to avoid compiler warnings
79 if ( ms_drawDecorations
== -1 )
82 !wxSystemSettings::GetCapability(wxSYS_CAN_DRAW_FRAME_DECORATIONS
)
83 || wxGetEnv(wxT("WXDECOR"), NULL
);
84 // FIXME -- wxUniv should provide a way to force non-native decorations!
85 // $WXDECOR is just a hack in absence of better wxUniv solution
88 if ( ms_canIconize
== -1 )
90 ms_canIconize
= wxSystemSettings::GetCapability(wxSYS_CAN_ICONIZE_FRAME
);
93 if ( ms_drawDecorations
)
95 CreateInputHandler(wxINP_HANDLER_TOPLEVEL
);
98 exstyleOrig
= GetExtraStyle();
99 style
&= ~(wxCAPTION
| wxMINIMIZE_BOX
| wxMAXIMIZE_BOX
|
100 wxSYSTEM_MENU
| wxRESIZE_BORDER
| wxFRAME_TOOL_WINDOW
|
102 style
= wxSIMPLE_BORDER
;
103 SetExtraStyle(exstyleOrig
&
104 ~(wxFRAME_EX_CONTEXTHELP
| wxDIALOG_EX_CONTEXTHELP
));
107 if ( !wxTopLevelWindowNative::Create(parent
, id
, title
, pos
,
111 if ( ms_drawDecorations
)
113 m_windowStyle
= styleOrig
;
114 m_exStyle
= exstyleOrig
;
120 bool wxTopLevelWindow::ShowFullScreen(bool show
, long style
)
122 if ( show
== IsFullScreen() ) return FALSE
;
124 if ( ms_drawDecorations
)
128 m_fsSavedStyle
= m_windowStyle
;
129 if ( style
& wxFULLSCREEN_NOBORDER
)
130 m_windowStyle
|= wxSIMPLE_BORDER
;
131 if ( style
& wxFULLSCREEN_NOCAPTION
)
132 m_windowStyle
&= ~wxCAPTION
;
136 m_windowStyle
= m_fsSavedStyle
;
140 return wxTopLevelWindowNative::ShowFullScreen(show
, style
);
143 long wxTopLevelWindow::GetDecorationsStyle() const
147 if ( m_windowStyle
& wxCAPTION
)
149 style
|= wxTOPLEVEL_TITLEBAR
| wxTOPLEVEL_BUTTON_CLOSE
;
150 if ( (m_windowStyle
& wxMINIMIZE_BOX
) && ms_canIconize
)
151 style
|= wxTOPLEVEL_BUTTON_ICONIZE
;
152 if ( m_windowStyle
& wxMAXIMIZE_BOX
)
155 style
|= wxTOPLEVEL_BUTTON_RESTORE
;
157 style
|= wxTOPLEVEL_BUTTON_MAXIMIZE
;
160 if ( m_exStyle
& (wxFRAME_EX_CONTEXTHELP
| wxDIALOG_EX_CONTEXTHELP
))
161 style
|= wxTOPLEVEL_BUTTON_HELP
;
164 if ( (m_windowStyle
& (wxSIMPLE_BORDER
| wxNO_BORDER
)) == 0 )
165 style
|= wxTOPLEVEL_BORDER
;
166 if ( m_windowStyle
& (wxRESIZE_BORDER
| wxTHICK_FRAME
) )
167 style
|= wxTOPLEVEL_RESIZEABLE
;
170 style
|= wxTOPLEVEL_MAXIMIZED
;
171 if ( GetIcon().Ok() )
172 style
|= wxTOPLEVEL_ICON
;
174 style
|= wxTOPLEVEL_ACTIVE
;
179 void wxTopLevelWindow::RefreshTitleBar()
181 wxNcPaintEvent
event(GetId());
182 event
.SetEventObject(this);
183 GetEventHandler()->ProcessEvent(event
);
186 // ----------------------------------------------------------------------------
187 // client area handling
188 // ----------------------------------------------------------------------------
190 wxPoint
wxTopLevelWindow::GetClientAreaOrigin() const
192 if ( ms_drawDecorations
)
195 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
196 wxRect rect
= wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
198 rect
= m_renderer
->GetFrameClientArea(rect
,
199 GetDecorationsStyle());
200 return rect
.GetPosition();
204 return wxTopLevelWindowNative::GetClientAreaOrigin();
208 void wxTopLevelWindow::DoGetClientSize(int *width
, int *height
) const
210 if ( ms_drawDecorations
)
213 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
214 wxRect rect
= wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
216 rect
= m_renderer
->GetFrameClientArea(rect
,
217 GetDecorationsStyle());
221 *height
= rect
.height
;
224 wxTopLevelWindowNative::DoGetClientSize(width
, height
);
227 void wxTopLevelWindow::DoSetClientSize(int width
, int height
)
229 if ( ms_drawDecorations
)
231 wxSize size
= m_renderer
->GetFrameTotalSize(wxSize(width
, height
),
232 GetDecorationsStyle());
233 wxTopLevelWindowNative::DoSetClientSize(size
.x
, size
.y
);
236 wxTopLevelWindowNative::DoSetClientSize(width
, height
);
239 void wxTopLevelWindow::OnNcPaint(wxPaintEvent
& event
)
241 if ( !ms_drawDecorations
|| !m_renderer
)
245 // get the window rect
247 wxSize size
= GetSize();
251 rect
.height
= size
.y
;
254 m_renderer
->DrawFrameTitleBar(dc
, rect
,
255 GetTitle(), m_titlebarIcon
,
256 GetDecorationsStyle(),
262 long wxTopLevelWindow::HitTest(const wxPoint
& pt
) const
265 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
266 wxRect
rect(wxTopLevelWindowNative::GetClientAreaOrigin(), wxSize(w
, h
));
268 return m_renderer
->HitTestFrame(rect
, pt
, GetDecorationsStyle());
271 // ----------------------------------------------------------------------------
273 // ----------------------------------------------------------------------------
275 void wxTopLevelWindow::SetIcon(const wxIcon
& icon
)
277 wxTopLevelWindowNative::SetIcon(icon
);
279 if ( ms_drawDecorations
&& m_renderer
)
281 wxSize size
= m_renderer
->GetFrameIconSize();
283 if ( !icon
.Ok() || size
.x
== -1 )
284 m_titlebarIcon
= icon
;
288 bmp1
.CopyFromIcon(icon
);
290 m_titlebarIcon
= wxNullIcon
;
291 else if ( bmp1
.GetWidth() == size
.x
&& bmp1
.GetHeight() == size
.y
)
292 m_titlebarIcon
= icon
;
295 wxImage img
= bmp1
.ConvertToImage();
296 img
.Rescale(size
.x
, size
.y
);
297 m_titlebarIcon
.CopyFromBitmap(wxBitmap(img
));
303 // ----------------------------------------------------------------------------
305 // ----------------------------------------------------------------------------
307 void wxTopLevelWindow::ClickTitleBarButton(long button
)
311 case wxTOPLEVEL_BUTTON_CLOSE
:
315 case wxTOPLEVEL_BUTTON_ICONIZE
:
319 case wxTOPLEVEL_BUTTON_MAXIMIZE
:
323 case wxTOPLEVEL_BUTTON_RESTORE
:
327 case wxTOPLEVEL_BUTTON_HELP
:
330 wxContextHelp
contextHelp(this);
336 wxFAIL_MSG(wxT("incorrect button specification"));
340 bool wxTopLevelWindow::PerformAction(const wxControlAction
& action
,
342 const wxString
& strArg
)
344 bool isActive
= numArg
!= 0;
346 if ( action
== wxACTION_TOPLEVEL_ACTIVATE
)
348 if ( m_isActive
!= isActive
)
350 m_isActive
= isActive
;
356 else if ( action
== wxACTION_TOPLEVEL_BUTTON_PRESS
)
358 m_pressedButton
= numArg
;
363 else if ( action
== wxACTION_TOPLEVEL_BUTTON_RELEASE
)
370 else if ( action
== wxACTION_TOPLEVEL_BUTTON_CLICK
)
374 ClickTitleBarButton(numArg
);
378 else if ( action
== wxACTION_TOPLEVEL_MOVE
)
380 InteractiveMove(wxINTERACTIVE_MOVE
);
384 else if ( action
== wxACTION_TOPLEVEL_RESIZE
)
386 int flags
= wxINTERACTIVE_RESIZE
;
387 if ( numArg
& wxHT_TOPLEVEL_BORDER_N
)
388 flags
|= wxINTERACTIVE_RESIZE_N
;
389 if ( numArg
& wxHT_TOPLEVEL_BORDER_S
)
390 flags
|= wxINTERACTIVE_RESIZE_S
;
391 if ( numArg
& wxHT_TOPLEVEL_BORDER_W
)
392 flags
|= wxINTERACTIVE_RESIZE_W
;
393 if ( numArg
& wxHT_TOPLEVEL_BORDER_E
)
394 flags
|= wxINTERACTIVE_RESIZE_E
;
395 InteractiveMove(flags
);
404 // ============================================================================
405 // wxStdFrameInputHandler: handles focus, resizing and titlebar buttons clicks
406 // ============================================================================
408 wxStdFrameInputHandler::wxStdFrameInputHandler(wxInputHandler
*inphand
)
409 : wxStdInputHandler(inphand
)
414 m_borderCursorOn
= FALSE
;
417 bool wxStdFrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
418 const wxMouseEvent
& event
)
420 // the button has 2 states: pressed and normal with the following
421 // transitions between them:
423 // normal -> left down -> capture mouse and go to pressed state
424 // pressed -> left up inside -> generate click -> go to normal
425 // outside ------------------>
427 // the other mouse buttons are ignored
428 if ( event
.Button(1) )
430 if ( event
.ButtonDown(1) )
432 wxTopLevelWindow
*w
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
433 long hit
= w
->HitTest(event
.GetPosition());
435 if ( hit
& wxHT_TOPLEVEL_ANY_BUTTON
)
438 m_winCapture
->CaptureMouse();
441 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS
, m_winPressed
);
444 else if ( hit
& wxHT_TOPLEVEL_TITLEBAR
)
446 consumer
->PerformAction(wxACTION_TOPLEVEL_MOVE
);
449 else if ( (consumer
->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER
)
450 && (hit
& wxHT_TOPLEVEL_ANY_BORDER
) )
452 consumer
->PerformAction(wxACTION_TOPLEVEL_RESIZE
, hit
);
461 m_winCapture
->ReleaseMouse();
464 if ( m_winHitTest
== m_winPressed
)
466 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
, m_winPressed
);
470 //else: the mouse was released outside the window, this doesn't
475 return wxStdInputHandler::HandleMouse(consumer
, event
);
478 bool wxStdFrameInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
479 const wxMouseEvent
& event
)
481 if ( event
.GetEventObject() == m_winCapture
)
483 long hit
= m_winCapture
->HitTest(event
.GetPosition());
485 if ( hit
!= m_winHitTest
)
487 if ( hit
!= m_winPressed
)
488 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_RELEASE
, m_winPressed
);
490 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS
, m_winPressed
);
496 else if ( consumer
->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER
)
498 wxTopLevelWindow
*win
= wxStaticCast(consumer
->GetInputWindow(),
500 long hit
= win
->HitTest(event
.GetPosition());
502 if ( hit
!= m_winHitTest
)
506 if ( m_borderCursorOn
)
508 m_borderCursorOn
= FALSE
;
509 win
->SetCursor(m_origCursor
);
512 if ( hit
& wxHT_TOPLEVEL_ANY_BORDER
)
514 m_borderCursorOn
= TRUE
;
519 case wxHT_TOPLEVEL_BORDER_N
:
520 case wxHT_TOPLEVEL_BORDER_S
:
521 cur
= wxCursor(wxCURSOR_SIZENS
);
523 case wxHT_TOPLEVEL_BORDER_W
:
524 case wxHT_TOPLEVEL_BORDER_E
:
525 cur
= wxCursor(wxCURSOR_SIZEWE
);
527 case wxHT_TOPLEVEL_BORDER_NE
:
528 case wxHT_TOPLEVEL_BORDER_SW
:
529 cur
= wxCursor(wxCURSOR_SIZENESW
);
531 case wxHT_TOPLEVEL_BORDER_NW
:
532 case wxHT_TOPLEVEL_BORDER_SE
:
533 cur
= wxCursor(wxCURSOR_SIZENWSE
);
536 m_borderCursorOn
= FALSE
;
539 if ( m_borderCursorOn
)
541 m_origCursor
= win
->GetCursor();
548 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
551 bool wxStdFrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
554 if ( m_borderCursorOn
)
556 consumer
->GetInputWindow()->SetCursor(m_origCursor
);
557 m_borderCursorOn
= FALSE
;
559 consumer
->PerformAction(wxACTION_TOPLEVEL_ACTIVATE
, activated
);