1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/univ/topluniv.cpp
3 // Author: Vaclav Slavik
4 // Copyright: (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com)
5 // Licence: wxWindows licence
6 /////////////////////////////////////////////////////////////////////////////
8 // ============================================================================
10 // ============================================================================
12 // ----------------------------------------------------------------------------
14 // ----------------------------------------------------------------------------
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
23 #include "wx/toplevel.h"
26 #include "wx/dcclient.h"
27 #include "wx/settings.h"
28 #include "wx/bitmap.h"
33 #include "wx/univ/renderer.h"
34 #include "wx/cshelp.h"
35 #include "wx/evtloop.h"
37 // ----------------------------------------------------------------------------
38 // wxStdTLWInputHandler: handles focus, resizing and titlebar buttons clicks
39 // ----------------------------------------------------------------------------
41 class WXDLLEXPORT wxStdTLWInputHandler
: public wxStdInputHandler
44 wxStdTLWInputHandler(wxInputHandler
*inphand
);
46 virtual bool HandleMouse(wxInputConsumer
*consumer
,
47 const wxMouseEvent
& event
);
48 virtual bool HandleMouseMove(wxInputConsumer
*consumer
, const wxMouseEvent
& event
);
49 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
52 // the window (button) which has capture or NULL and the last hittest result
53 wxTopLevelWindow
*m_winCapture
;
56 bool m_borderCursorOn
;
57 wxCursor m_origCursor
;
61 // ----------------------------------------------------------------------------
63 // ----------------------------------------------------------------------------
65 BEGIN_EVENT_TABLE(wxTopLevelWindow
, wxTopLevelWindowNative
)
66 WX_EVENT_TABLE_INPUT_CONSUMER(wxTopLevelWindow
)
67 EVT_NC_PAINT(wxTopLevelWindow::OnNcPaint
)
68 EVT_MENU_RANGE(wxID_CLOSE_FRAME
, wxID_RESTORE_FRAME
, wxTopLevelWindow::OnSystemMenu
)
71 WX_FORWARD_TO_INPUT_CONSUMER(wxTopLevelWindow
)
73 // ============================================================================
75 // ============================================================================
77 int wxTopLevelWindow::ms_drawDecorations
= -1;
78 int wxTopLevelWindow::ms_canIconize
= -1;
80 void wxTopLevelWindow::Init()
82 // once-only ms_drawDecorations initialization
83 if ( ms_drawDecorations
== -1 )
86 !wxSystemSettings::HasFeature(wxSYS_CAN_DRAW_FRAME_DECORATIONS
) ||
87 wxGetEnv(wxT("WXDECOR"), NULL
);
90 m_usingNativeDecorations
= ms_drawDecorations
== 0;
96 bool wxTopLevelWindow::Create(wxWindow
*parent
,
98 const wxString
& title
,
102 const wxString
&name
)
104 // init them to avoid compiler warnings
108 if ( !m_usingNativeDecorations
)
110 CreateInputHandler(wxINP_HANDLER_TOPLEVEL
);
113 exstyleOrig
= GetExtraStyle();
114 style
&= ~(wxCAPTION
| wxMINIMIZE_BOX
| wxMAXIMIZE_BOX
|
115 wxSYSTEM_MENU
| wxFRAME_TOOL_WINDOW
| wxRESIZE_BORDER
);
116 style
|= wxBORDER_NONE
;
117 SetExtraStyle(exstyleOrig
& ~wxWS_EX_CONTEXTHELP
);
120 if ( !wxTopLevelWindowNative::Create(parent
, id
, title
, pos
,
124 if ( !m_usingNativeDecorations
)
126 m_windowStyle
= styleOrig
;
127 m_exStyle
= exstyleOrig
;
133 bool wxTopLevelWindow::ShowFullScreen(bool show
, long style
)
135 if ( show
== IsFullScreen() ) return false;
137 if ( !m_usingNativeDecorations
)
141 m_fsSavedStyle
= m_windowStyle
;
142 if ( style
& wxFULLSCREEN_NOBORDER
)
143 m_windowStyle
|= wxSIMPLE_BORDER
;
144 if ( style
& wxFULLSCREEN_NOCAPTION
)
145 m_windowStyle
&= ~wxCAPTION
;
149 m_windowStyle
= m_fsSavedStyle
;
153 return wxTopLevelWindowNative::ShowFullScreen(show
, style
);
157 void wxTopLevelWindow::UseNativeDecorationsByDefault(bool native
)
159 ms_drawDecorations
= !native
;
162 void wxTopLevelWindow::UseNativeDecorations(bool native
)
164 wxASSERT_MSG( !m_windowStyle
, wxT("must be called before Create()") );
166 m_usingNativeDecorations
= native
;
169 bool wxTopLevelWindow::IsUsingNativeDecorations() const
171 return m_usingNativeDecorations
;
174 long wxTopLevelWindow::GetDecorationsStyle() const
178 if ( m_windowStyle
& wxCAPTION
)
180 if ( ms_canIconize
== -1 )
182 ms_canIconize
= wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
);
185 style
|= wxTOPLEVEL_TITLEBAR
;
186 if ( m_windowStyle
& wxCLOSE_BOX
)
187 style
|= wxTOPLEVEL_BUTTON_CLOSE
;
188 if ( (m_windowStyle
& wxMINIMIZE_BOX
) && ms_canIconize
)
189 style
|= wxTOPLEVEL_BUTTON_ICONIZE
;
190 if ( m_windowStyle
& wxMAXIMIZE_BOX
)
193 style
|= wxTOPLEVEL_BUTTON_RESTORE
;
195 style
|= wxTOPLEVEL_BUTTON_MAXIMIZE
;
198 if ( m_exStyle
& wxWS_EX_CONTEXTHELP
)
199 style
|= wxTOPLEVEL_BUTTON_HELP
;
202 if ( (m_windowStyle
& (wxSIMPLE_BORDER
| wxNO_BORDER
)) == 0 )
203 style
|= wxTOPLEVEL_BORDER
;
204 if ( m_windowStyle
& wxRESIZE_BORDER
)
205 style
|= wxTOPLEVEL_RESIZEABLE
;
208 style
|= wxTOPLEVEL_MAXIMIZED
;
209 if ( GetIcon().IsOk() )
210 style
|= wxTOPLEVEL_ICON
;
212 style
|= wxTOPLEVEL_ACTIVE
;
217 void wxTopLevelWindow::RefreshTitleBar()
219 wxNcPaintEvent
event(GetId());
220 event
.SetEventObject(this);
221 GetEventHandler()->ProcessEvent(event
);
224 // ----------------------------------------------------------------------------
225 // client area handling
226 // ----------------------------------------------------------------------------
228 wxPoint
wxTopLevelWindow::GetClientAreaOrigin() const
230 if ( !m_usingNativeDecorations
)
233 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
234 wxRect rect
= wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
236 rect
= m_renderer
->GetFrameClientArea(rect
,
237 GetDecorationsStyle());
238 return rect
.GetPosition();
242 return wxTopLevelWindowNative::GetClientAreaOrigin();
246 void wxTopLevelWindow::DoGetClientSize(int *width
, int *height
) const
248 if ( !m_usingNativeDecorations
)
251 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
252 wxRect rect
= wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
254 rect
= m_renderer
->GetFrameClientArea(rect
,
255 GetDecorationsStyle());
259 *height
= rect
.height
;
262 wxTopLevelWindowNative::DoGetClientSize(width
, height
);
265 void wxTopLevelWindow::DoSetClientSize(int width
, int height
)
267 if ( !m_usingNativeDecorations
)
269 wxSize size
= m_renderer
->GetFrameTotalSize(wxSize(width
, height
),
270 GetDecorationsStyle());
271 wxTopLevelWindowNative::DoSetClientSize(size
.x
, size
.y
);
274 wxTopLevelWindowNative::DoSetClientSize(width
, height
);
277 void wxTopLevelWindow::OnNcPaint(wxNcPaintEvent
& event
)
279 if ( m_usingNativeDecorations
|| !m_renderer
)
283 else // we're drawing the decorations ourselves
285 // get the window rect
286 wxRect
rect(GetSize());
289 m_renderer
->DrawFrameTitleBar(dc
, rect
,
290 GetTitle(), m_titlebarIcon
,
291 GetDecorationsStyle(),
297 long wxTopLevelWindow::HitTest(const wxPoint
& pt
) const
300 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
301 wxRect
rect(wxTopLevelWindowNative::GetClientAreaOrigin(), wxSize(w
, h
));
303 return m_renderer
->HitTestFrame(rect
, pt
+GetClientAreaOrigin(), GetDecorationsStyle());
306 wxSize
wxTopLevelWindow::GetMinSize() const
308 wxSize size
= wxTopLevelWindowNative::GetMinSize();
309 if ( !m_usingNativeDecorations
)
311 size
.IncTo(m_renderer
->GetFrameMinSize(GetDecorationsStyle()));
317 // ----------------------------------------------------------------------------
319 // ----------------------------------------------------------------------------
321 void wxTopLevelWindow::SetIcons(const wxIconBundle
& icons
)
323 wxTopLevelWindowNative::SetIcons(icons
);
325 if ( !m_usingNativeDecorations
&& m_renderer
)
327 wxSize size
= m_renderer
->GetFrameIconSize();
328 const wxIcon
& icon
= icons
.GetIcon( size
);
330 if ( !icon
.IsOk() || size
.x
== wxDefaultCoord
)
331 m_titlebarIcon
= icon
;
335 bmp1
.CopyFromIcon(icon
);
337 m_titlebarIcon
= wxNullIcon
;
338 else if ( bmp1
.GetWidth() == size
.x
&& bmp1
.GetHeight() == size
.y
)
339 m_titlebarIcon
= icon
;
343 wxImage img
= bmp1
.ConvertToImage();
344 img
.Rescale(size
.x
, size
.y
);
345 m_titlebarIcon
.CopyFromBitmap(wxBitmap(img
));
347 #endif // wxUSE_IMAGE
352 // ----------------------------------------------------------------------------
353 // interactive manipulation
354 // ----------------------------------------------------------------------------
357 static bool wxGetResizingCursor(long hitTestResult
, wxCursor
& cursor
)
359 if ( hitTestResult
& wxHT_TOPLEVEL_ANY_BORDER
)
361 switch (hitTestResult
)
363 case wxHT_TOPLEVEL_BORDER_N
:
364 case wxHT_TOPLEVEL_BORDER_S
:
365 cursor
= wxCursor(wxCURSOR_SIZENS
);
367 case wxHT_TOPLEVEL_BORDER_W
:
368 case wxHT_TOPLEVEL_BORDER_E
:
369 cursor
= wxCursor(wxCURSOR_SIZEWE
);
371 case wxHT_TOPLEVEL_BORDER_NE
:
372 case wxHT_TOPLEVEL_BORDER_SW
:
373 cursor
= wxCursor(wxCURSOR_SIZENESW
);
375 case wxHT_TOPLEVEL_BORDER_NW
:
376 case wxHT_TOPLEVEL_BORDER_SE
:
377 cursor
= wxCursor(wxCURSOR_SIZENWSE
);
388 #define wxINTERACTIVE_RESIZE_DIR \
389 (wxINTERACTIVE_RESIZE_W | wxINTERACTIVE_RESIZE_E | \
390 wxINTERACTIVE_RESIZE_S | wxINTERACTIVE_RESIZE_N)
392 struct wxInteractiveMoveData
394 wxTopLevelWindow
*m_window
;
395 wxEventLoop
*m_evtLoop
;
400 wxSize m_minSize
, m_maxSize
;
404 class wxInteractiveMoveHandler
: public wxEvtHandler
407 wxInteractiveMoveHandler(wxInteractiveMoveData
& data
) : m_data(data
) {}
410 DECLARE_EVENT_TABLE()
411 void OnMouseMove(wxMouseEvent
& event
);
412 void OnMouseDown(wxMouseEvent
& event
);
413 void OnMouseUp(wxMouseEvent
& event
);
414 void OnKeyDown(wxKeyEvent
& event
);
416 wxInteractiveMoveData
& m_data
;
419 BEGIN_EVENT_TABLE(wxInteractiveMoveHandler
, wxEvtHandler
)
420 EVT_MOTION(wxInteractiveMoveHandler::OnMouseMove
)
421 EVT_LEFT_DOWN(wxInteractiveMoveHandler::OnMouseDown
)
422 EVT_LEFT_UP(wxInteractiveMoveHandler::OnMouseUp
)
423 EVT_KEY_DOWN(wxInteractiveMoveHandler::OnKeyDown
)
427 static inline LINKAGEMODE
428 void wxApplyResize(wxInteractiveMoveData
& data
, const wxPoint
& diff
)
430 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
432 data
.m_rect
.x
+= diff
.x
;
433 data
.m_rect
.width
-= diff
.x
;
435 else if ( data
.m_flags
& wxINTERACTIVE_RESIZE_E
)
437 data
.m_rect
.width
+= diff
.x
;
439 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
441 data
.m_rect
.y
+= diff
.y
;
442 data
.m_rect
.height
-= diff
.y
;
444 else if ( data
.m_flags
& wxINTERACTIVE_RESIZE_S
)
446 data
.m_rect
.height
+= diff
.y
;
449 if ( data
.m_minSize
.x
!= wxDefaultCoord
&& data
.m_rect
.width
< data
.m_minSize
.x
)
451 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
452 data
.m_rect
.x
-= data
.m_minSize
.x
- data
.m_rect
.width
;
453 data
.m_rect
.width
= data
.m_minSize
.x
;
455 if ( data
.m_maxSize
.x
!= wxDefaultCoord
&& data
.m_rect
.width
> data
.m_maxSize
.x
)
457 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
458 data
.m_rect
.x
-= data
.m_minSize
.x
- data
.m_rect
.width
;
459 data
.m_rect
.width
= data
.m_maxSize
.x
;
461 if ( data
.m_minSize
.y
!= wxDefaultCoord
&& data
.m_rect
.height
< data
.m_minSize
.y
)
463 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
464 data
.m_rect
.y
-= data
.m_minSize
.y
- data
.m_rect
.height
;
465 data
.m_rect
.height
= data
.m_minSize
.y
;
467 if ( data
.m_maxSize
.y
!= wxDefaultCoord
&& data
.m_rect
.height
> data
.m_maxSize
.y
)
469 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
470 data
.m_rect
.y
-= data
.m_minSize
.y
- data
.m_rect
.height
;
471 data
.m_rect
.height
= data
.m_maxSize
.y
;
475 void wxInteractiveMoveHandler::OnMouseMove(wxMouseEvent
& event
)
477 if ( m_data
.m_flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
480 else if ( m_data
.m_flags
& wxINTERACTIVE_MOVE
)
482 wxPoint diff
= wxGetMousePosition() - m_data
.m_pos
;
483 m_data
.m_rect
= m_data
.m_rectOrig
;
484 m_data
.m_rect
.Offset(diff
);
485 m_data
.m_window
->Move(m_data
.m_rect
.GetPosition());
488 else if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE
)
490 wxPoint diff
= wxGetMousePosition() - m_data
.m_pos
;
491 m_data
.m_rect
= m_data
.m_rectOrig
;
492 wxApplyResize(m_data
, diff
);
493 m_data
.m_window
->SetSize(m_data
.m_rect
);
497 void wxInteractiveMoveHandler::OnMouseDown(wxMouseEvent
& WXUNUSED(event
))
499 if ( m_data
.m_flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
501 m_data
.m_evtLoop
->Exit();
505 void wxInteractiveMoveHandler::OnKeyDown(wxKeyEvent
& event
)
507 wxPoint
diff(wxDefaultCoord
,wxDefaultCoord
);
509 switch ( event
.GetKeyCode() )
511 case WXK_UP
: diff
= wxPoint(0, -16); break;
512 case WXK_DOWN
: diff
= wxPoint(0, 16); break;
513 case WXK_LEFT
: diff
= wxPoint(-16, 0); break;
514 case WXK_RIGHT
: diff
= wxPoint(16, 0); break;
516 m_data
.m_window
->SetSize(m_data
.m_rectOrig
);
517 m_data
.m_evtLoop
->Exit();
520 m_data
.m_evtLoop
->Exit();
524 if ( diff
.x
!= wxDefaultCoord
)
526 if ( m_data
.m_flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
528 m_data
.m_flags
&= ~wxINTERACTIVE_WAIT_FOR_INPUT
;
529 if ( m_data
.m_sizingCursor
)
532 m_data
.m_sizingCursor
= false;
535 if ( m_data
.m_flags
& wxINTERACTIVE_MOVE
)
537 m_data
.m_pos
= m_data
.m_window
->GetPosition() +
538 wxPoint(m_data
.m_window
->GetSize().x
/2, 8);
543 bool changeCur
= false;
545 if ( m_data
.m_flags
& wxINTERACTIVE_MOVE
)
547 m_data
.m_rect
.Offset(diff
);
548 m_data
.m_window
->Move(m_data
.m_rect
.GetPosition());
549 warp
= wxPoint(m_data
.m_window
->GetSize().x
/2, 8);
551 else /* wxINTERACTIVE_RESIZE */
553 if ( !(m_data
.m_flags
&
554 (wxINTERACTIVE_RESIZE_N
| wxINTERACTIVE_RESIZE_S
)) )
558 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_N
;
559 m_data
.m_pos
.y
= m_data
.m_window
->GetPosition().y
;
562 else if ( diff
.y
> 0 )
564 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_S
;
565 m_data
.m_pos
.y
= m_data
.m_window
->GetPosition().y
+
566 m_data
.m_window
->GetSize().y
;
570 if ( !(m_data
.m_flags
&
571 (wxINTERACTIVE_RESIZE_W
| wxINTERACTIVE_RESIZE_E
)) )
575 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_W
;
576 m_data
.m_pos
.x
= m_data
.m_window
->GetPosition().x
;
579 else if ( diff
.x
> 0 )
581 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_E
;
582 m_data
.m_pos
.x
= m_data
.m_window
->GetPosition().x
+
583 m_data
.m_window
->GetSize().x
;
588 wxApplyResize(m_data
, diff
);
589 m_data
.m_window
->SetSize(m_data
.m_rect
);
591 if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
593 else if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_E
)
594 warp
.x
= m_data
.m_window
->GetSize().x
-1;
596 warp
.x
= wxGetMousePosition().x
- m_data
.m_window
->GetPosition().x
;
598 if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
600 else if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_S
)
601 warp
.y
= m_data
.m_window
->GetSize().y
-1;
603 warp
.y
= wxGetMousePosition().y
- m_data
.m_window
->GetPosition().y
;
606 warp
-= m_data
.m_window
->GetClientAreaOrigin();
607 m_data
.m_window
->WarpPointer(warp
.x
, warp
.y
);
611 long hit
= m_data
.m_window
->HitTest(warp
);
613 if ( wxGetResizingCursor(hit
, cur
) )
615 if ( m_data
.m_sizingCursor
)
617 wxBeginBusyCursor(&cur
);
618 m_data
.m_sizingCursor
= true;
624 void wxInteractiveMoveHandler::OnMouseUp(wxMouseEvent
& WXUNUSED(event
))
626 m_data
.m_evtLoop
->Exit();
630 void wxTopLevelWindow::InteractiveMove(int flags
)
632 wxASSERT_MSG( !((flags
& wxINTERACTIVE_MOVE
) && (flags
& wxINTERACTIVE_RESIZE
)),
633 wxT("can't move and resize window at the same time") );
635 wxASSERT_MSG( !(flags
& wxINTERACTIVE_RESIZE
) ||
636 (flags
& wxINTERACTIVE_WAIT_FOR_INPUT
) ||
637 (flags
& wxINTERACTIVE_RESIZE_DIR
),
638 wxT("direction of resizing not specified") );
640 wxInteractiveMoveData data
;
646 if ( flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
648 wxCursor
sizingCursor(wxCURSOR_SIZING
);
649 wxBeginBusyCursor(&sizingCursor
);
650 data
.m_sizingCursor
= true;
654 data
.m_sizingCursor
= false;
656 data
.m_window
= this;
657 data
.m_evtLoop
= &loop
;
658 data
.m_flags
= flags
;
659 data
.m_rect
= data
.m_rectOrig
= GetRect();
660 data
.m_pos
= wxGetMousePosition();
661 data
.m_minSize
= wxSize(GetMinWidth(), GetMinHeight());
662 data
.m_maxSize
= wxSize(GetMaxWidth(), GetMaxHeight());
664 wxEvtHandler
*handler
= new wxInteractiveMoveHandler(data
);
665 this->PushEventHandler(handler
);
671 this->RemoveEventHandler(handler
);
674 if ( data
.m_sizingCursor
)
678 // ----------------------------------------------------------------------------
680 // ----------------------------------------------------------------------------
682 void wxTopLevelWindow::ClickTitleBarButton(long button
)
686 case wxTOPLEVEL_BUTTON_CLOSE
:
690 case wxTOPLEVEL_BUTTON_ICONIZE
:
694 case wxTOPLEVEL_BUTTON_MAXIMIZE
:
698 case wxTOPLEVEL_BUTTON_RESTORE
:
702 case wxTOPLEVEL_BUTTON_HELP
:
705 wxContextHelp
contextHelp(this);
711 wxFAIL_MSG(wxT("incorrect button specification"));
715 bool wxTopLevelWindow::PerformAction(const wxControlAction
& action
,
717 const wxString
& WXUNUSED(strArg
))
719 bool isActive
= numArg
!= 0;
721 if ( action
== wxACTION_TOPLEVEL_ACTIVATE
)
723 if ( m_isActive
!= isActive
)
725 m_isActive
= isActive
;
731 else if ( action
== wxACTION_TOPLEVEL_BUTTON_PRESS
)
733 m_pressedButton
= numArg
;
738 else if ( action
== wxACTION_TOPLEVEL_BUTTON_RELEASE
)
745 else if ( action
== wxACTION_TOPLEVEL_BUTTON_CLICK
)
749 ClickTitleBarButton(numArg
);
753 else if ( action
== wxACTION_TOPLEVEL_MOVE
)
755 InteractiveMove(wxINTERACTIVE_MOVE
);
759 else if ( action
== wxACTION_TOPLEVEL_RESIZE
)
761 int flags
= wxINTERACTIVE_RESIZE
;
762 if ( numArg
& wxHT_TOPLEVEL_BORDER_N
)
763 flags
|= wxINTERACTIVE_RESIZE_N
;
764 if ( numArg
& wxHT_TOPLEVEL_BORDER_S
)
765 flags
|= wxINTERACTIVE_RESIZE_S
;
766 if ( numArg
& wxHT_TOPLEVEL_BORDER_W
)
767 flags
|= wxINTERACTIVE_RESIZE_W
;
768 if ( numArg
& wxHT_TOPLEVEL_BORDER_E
)
769 flags
|= wxINTERACTIVE_RESIZE_E
;
770 InteractiveMove(flags
);
778 void wxTopLevelWindow::OnSystemMenu(wxCommandEvent
& event
)
782 switch (event
.GetId())
784 case wxID_CLOSE_FRAME
:
785 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
786 wxTOPLEVEL_BUTTON_CLOSE
);
788 case wxID_MOVE_FRAME
:
789 InteractiveMove(wxINTERACTIVE_MOVE
| wxINTERACTIVE_WAIT_FOR_INPUT
);
791 case wxID_RESIZE_FRAME
:
792 InteractiveMove(wxINTERACTIVE_RESIZE
| wxINTERACTIVE_WAIT_FOR_INPUT
);
794 case wxID_MAXIMIZE_FRAME
:
795 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
796 wxTOPLEVEL_BUTTON_MAXIMIZE
);
798 case wxID_ICONIZE_FRAME
:
799 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
800 wxTOPLEVEL_BUTTON_ICONIZE
);
802 case wxID_RESTORE_FRAME
:
803 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
804 wxTOPLEVEL_BUTTON_RESTORE
);
817 wxTopLevelWindow::GetStdInputHandler(wxInputHandler
*handlerDef
)
819 static wxStdTLWInputHandler
s_handler(handlerDef
);
824 // ============================================================================
825 // wxStdTLWInputHandler: handles focus, resizing and titlebar buttons clicks
826 // ============================================================================
828 wxStdTLWInputHandler::wxStdTLWInputHandler(wxInputHandler
*inphand
)
829 : wxStdInputHandler(inphand
)
834 m_borderCursorOn
= false;
837 bool wxStdTLWInputHandler::HandleMouse(wxInputConsumer
*consumer
,
838 const wxMouseEvent
& event
)
840 // the button has 2 states: pressed and normal with the following
841 // transitions between them:
843 // normal -> left down -> capture mouse and go to pressed state
844 // pressed -> left up inside -> generate click -> go to normal
845 // outside ------------------>
847 // the other mouse buttons are ignored
848 if ( event
.Button(1) )
850 if ( event
.ButtonDown(1) )
852 wxTopLevelWindow
*w
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
853 long hit
= w
->HitTest(event
.GetPosition());
855 if ( hit
& wxHT_TOPLEVEL_ANY_BUTTON
)
858 m_winCapture
->CaptureMouse();
861 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS
, m_winPressed
);
864 else if ( (hit
& wxHT_TOPLEVEL_TITLEBAR
) && !w
->IsMaximized() )
866 consumer
->PerformAction(wxACTION_TOPLEVEL_MOVE
);
869 else if ( (consumer
->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER
)
870 && (hit
& wxHT_TOPLEVEL_ANY_BORDER
) )
872 consumer
->PerformAction(wxACTION_TOPLEVEL_RESIZE
, hit
);
881 m_winCapture
->ReleaseMouse();
884 if ( m_winHitTest
== m_winPressed
)
886 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
, m_winPressed
);
890 //else: the mouse was released outside the window, this doesn't
895 return wxStdInputHandler::HandleMouse(consumer
, event
);
898 bool wxStdTLWInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
899 const wxMouseEvent
& event
)
901 if ( event
.GetEventObject() == m_winCapture
)
903 long hit
= m_winCapture
->HitTest(event
.GetPosition());
905 if ( hit
!= m_winHitTest
)
907 if ( hit
!= m_winPressed
)
908 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_RELEASE
, m_winPressed
);
910 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS
, m_winPressed
);
916 else if ( consumer
->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER
)
918 wxTopLevelWindow
*win
= wxStaticCast(consumer
->GetInputWindow(),
920 long hit
= win
->HitTest(event
.GetPosition());
922 if ( hit
!= m_winHitTest
)
926 if ( m_borderCursorOn
)
928 m_borderCursorOn
= false;
929 win
->SetCursor(m_origCursor
);
932 if ( hit
& wxHT_TOPLEVEL_ANY_BORDER
)
936 m_borderCursorOn
= wxGetResizingCursor(hit
, cur
);
937 if ( m_borderCursorOn
)
939 m_origCursor
= win
->GetCursor();
946 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
949 bool wxStdTLWInputHandler::HandleActivation(wxInputConsumer
*consumer
,
952 if ( m_borderCursorOn
)
954 consumer
->GetInputWindow()->SetCursor(m_origCursor
);
955 m_borderCursorOn
= false;
957 consumer
->PerformAction(wxACTION_TOPLEVEL_ACTIVATE
, activated
);