1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/univ/topluniv.cpp
3 // Author: Vaclav Slavik
5 // Copyright: (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com)
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
9 // ============================================================================
11 // ============================================================================
13 // ----------------------------------------------------------------------------
15 // ----------------------------------------------------------------------------
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
24 #include "wx/toplevel.h"
27 #include "wx/dcclient.h"
28 #include "wx/settings.h"
29 #include "wx/bitmap.h"
34 #include "wx/univ/renderer.h"
35 #include "wx/cshelp.h"
36 #include "wx/evtloop.h"
38 // ----------------------------------------------------------------------------
39 // wxStdTLWInputHandler: handles focus, resizing and titlebar buttons clicks
40 // ----------------------------------------------------------------------------
42 class WXDLLEXPORT wxStdTLWInputHandler
: public wxStdInputHandler
45 wxStdTLWInputHandler(wxInputHandler
*inphand
);
47 virtual bool HandleMouse(wxInputConsumer
*consumer
,
48 const wxMouseEvent
& event
);
49 virtual bool HandleMouseMove(wxInputConsumer
*consumer
, const wxMouseEvent
& event
);
50 virtual bool HandleActivation(wxInputConsumer
*consumer
, bool activated
);
53 // the window (button) which has capture or NULL and the last hittest result
54 wxTopLevelWindow
*m_winCapture
;
57 bool m_borderCursorOn
;
58 wxCursor m_origCursor
;
62 // ----------------------------------------------------------------------------
64 // ----------------------------------------------------------------------------
66 BEGIN_EVENT_TABLE(wxTopLevelWindow
, wxTopLevelWindowNative
)
67 WX_EVENT_TABLE_INPUT_CONSUMER(wxTopLevelWindow
)
68 EVT_NC_PAINT(wxTopLevelWindow::OnNcPaint
)
69 EVT_MENU_RANGE(wxID_CLOSE_FRAME
, wxID_RESTORE_FRAME
, wxTopLevelWindow::OnSystemMenu
)
72 WX_FORWARD_TO_INPUT_CONSUMER(wxTopLevelWindow
)
74 // ============================================================================
76 // ============================================================================
78 int wxTopLevelWindow::ms_drawDecorations
= -1;
79 int wxTopLevelWindow::ms_canIconize
= -1;
81 void wxTopLevelWindow::Init()
83 // once-only ms_drawDecorations initialization
84 if ( ms_drawDecorations
== -1 )
87 !wxSystemSettings::HasFeature(wxSYS_CAN_DRAW_FRAME_DECORATIONS
) ||
88 wxGetEnv(wxT("WXDECOR"), NULL
);
91 m_usingNativeDecorations
= ms_drawDecorations
== 0;
97 bool wxTopLevelWindow::Create(wxWindow
*parent
,
99 const wxString
& title
,
103 const wxString
&name
)
105 // init them to avoid compiler warnings
109 if ( !m_usingNativeDecorations
)
111 CreateInputHandler(wxINP_HANDLER_TOPLEVEL
);
114 exstyleOrig
= GetExtraStyle();
115 style
&= ~(wxCAPTION
| wxMINIMIZE_BOX
| wxMAXIMIZE_BOX
|
116 wxSYSTEM_MENU
| wxFRAME_TOOL_WINDOW
| wxRESIZE_BORDER
);
117 style
|= wxBORDER_NONE
;
118 SetExtraStyle(exstyleOrig
& ~wxWS_EX_CONTEXTHELP
);
121 if ( !wxTopLevelWindowNative::Create(parent
, id
, title
, pos
,
125 if ( !m_usingNativeDecorations
)
127 m_windowStyle
= styleOrig
;
128 m_exStyle
= exstyleOrig
;
134 bool wxTopLevelWindow::ShowFullScreen(bool show
, long style
)
136 if ( show
== IsFullScreen() ) return false;
138 if ( !m_usingNativeDecorations
)
142 m_fsSavedStyle
= m_windowStyle
;
143 if ( style
& wxFULLSCREEN_NOBORDER
)
144 m_windowStyle
|= wxSIMPLE_BORDER
;
145 if ( style
& wxFULLSCREEN_NOCAPTION
)
146 m_windowStyle
&= ~wxCAPTION
;
150 m_windowStyle
= m_fsSavedStyle
;
154 return wxTopLevelWindowNative::ShowFullScreen(show
, style
);
158 void wxTopLevelWindow::UseNativeDecorationsByDefault(bool native
)
160 ms_drawDecorations
= !native
;
163 void wxTopLevelWindow::UseNativeDecorations(bool native
)
165 wxASSERT_MSG( !m_windowStyle
, wxT("must be called before Create()") );
167 m_usingNativeDecorations
= native
;
170 bool wxTopLevelWindow::IsUsingNativeDecorations() const
172 return m_usingNativeDecorations
;
175 long wxTopLevelWindow::GetDecorationsStyle() const
179 if ( m_windowStyle
& wxCAPTION
)
181 if ( ms_canIconize
== -1 )
183 ms_canIconize
= wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
);
186 style
|= wxTOPLEVEL_TITLEBAR
;
187 if ( m_windowStyle
& wxCLOSE_BOX
)
188 style
|= wxTOPLEVEL_BUTTON_CLOSE
;
189 if ( (m_windowStyle
& wxMINIMIZE_BOX
) && ms_canIconize
)
190 style
|= wxTOPLEVEL_BUTTON_ICONIZE
;
191 if ( m_windowStyle
& wxMAXIMIZE_BOX
)
194 style
|= wxTOPLEVEL_BUTTON_RESTORE
;
196 style
|= wxTOPLEVEL_BUTTON_MAXIMIZE
;
199 if ( m_exStyle
& wxWS_EX_CONTEXTHELP
)
200 style
|= wxTOPLEVEL_BUTTON_HELP
;
203 if ( (m_windowStyle
& (wxSIMPLE_BORDER
| wxNO_BORDER
)) == 0 )
204 style
|= wxTOPLEVEL_BORDER
;
205 if ( m_windowStyle
& wxRESIZE_BORDER
)
206 style
|= wxTOPLEVEL_RESIZEABLE
;
209 style
|= wxTOPLEVEL_MAXIMIZED
;
210 if ( GetIcon().IsOk() )
211 style
|= wxTOPLEVEL_ICON
;
213 style
|= wxTOPLEVEL_ACTIVE
;
218 void wxTopLevelWindow::RefreshTitleBar()
220 wxNcPaintEvent
event(GetId());
221 event
.SetEventObject(this);
222 GetEventHandler()->ProcessEvent(event
);
225 // ----------------------------------------------------------------------------
226 // client area handling
227 // ----------------------------------------------------------------------------
229 wxPoint
wxTopLevelWindow::GetClientAreaOrigin() const
231 if ( !m_usingNativeDecorations
)
234 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
235 wxRect rect
= wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
237 rect
= m_renderer
->GetFrameClientArea(rect
,
238 GetDecorationsStyle());
239 return rect
.GetPosition();
243 return wxTopLevelWindowNative::GetClientAreaOrigin();
247 void wxTopLevelWindow::DoGetClientSize(int *width
, int *height
) const
249 if ( !m_usingNativeDecorations
)
252 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
253 wxRect rect
= wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
255 rect
= m_renderer
->GetFrameClientArea(rect
,
256 GetDecorationsStyle());
260 *height
= rect
.height
;
263 wxTopLevelWindowNative::DoGetClientSize(width
, height
);
266 void wxTopLevelWindow::DoSetClientSize(int width
, int height
)
268 if ( !m_usingNativeDecorations
)
270 wxSize size
= m_renderer
->GetFrameTotalSize(wxSize(width
, height
),
271 GetDecorationsStyle());
272 wxTopLevelWindowNative::DoSetClientSize(size
.x
, size
.y
);
275 wxTopLevelWindowNative::DoSetClientSize(width
, height
);
278 void wxTopLevelWindow::OnNcPaint(wxNcPaintEvent
& event
)
280 if ( m_usingNativeDecorations
|| !m_renderer
)
284 else // we're drawing the decorations ourselves
286 // get the window rect
287 wxRect
rect(GetSize());
290 m_renderer
->DrawFrameTitleBar(dc
, rect
,
291 GetTitle(), m_titlebarIcon
,
292 GetDecorationsStyle(),
298 long wxTopLevelWindow::HitTest(const wxPoint
& pt
) const
301 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
302 wxRect
rect(wxTopLevelWindowNative::GetClientAreaOrigin(), wxSize(w
, h
));
304 return m_renderer
->HitTestFrame(rect
, pt
+GetClientAreaOrigin(), GetDecorationsStyle());
307 wxSize
wxTopLevelWindow::GetMinSize() const
309 wxSize size
= wxTopLevelWindowNative::GetMinSize();
310 if ( !m_usingNativeDecorations
)
312 size
.IncTo(m_renderer
->GetFrameMinSize(GetDecorationsStyle()));
318 // ----------------------------------------------------------------------------
320 // ----------------------------------------------------------------------------
322 void wxTopLevelWindow::SetIcons(const wxIconBundle
& icons
)
324 wxTopLevelWindowNative::SetIcons(icons
);
326 if ( !m_usingNativeDecorations
&& m_renderer
)
328 wxSize size
= m_renderer
->GetFrameIconSize();
329 const wxIcon
& icon
= icons
.GetIcon( size
);
331 if ( !icon
.IsOk() || size
.x
== wxDefaultCoord
)
332 m_titlebarIcon
= icon
;
336 bmp1
.CopyFromIcon(icon
);
338 m_titlebarIcon
= wxNullIcon
;
339 else if ( bmp1
.GetWidth() == size
.x
&& bmp1
.GetHeight() == size
.y
)
340 m_titlebarIcon
= icon
;
344 wxImage img
= bmp1
.ConvertToImage();
345 img
.Rescale(size
.x
, size
.y
);
346 m_titlebarIcon
.CopyFromBitmap(wxBitmap(img
));
348 #endif // wxUSE_IMAGE
353 // ----------------------------------------------------------------------------
354 // interactive manipulation
355 // ----------------------------------------------------------------------------
358 static bool wxGetResizingCursor(long hitTestResult
, wxCursor
& cursor
)
360 if ( hitTestResult
& wxHT_TOPLEVEL_ANY_BORDER
)
362 switch (hitTestResult
)
364 case wxHT_TOPLEVEL_BORDER_N
:
365 case wxHT_TOPLEVEL_BORDER_S
:
366 cursor
= wxCursor(wxCURSOR_SIZENS
);
368 case wxHT_TOPLEVEL_BORDER_W
:
369 case wxHT_TOPLEVEL_BORDER_E
:
370 cursor
= wxCursor(wxCURSOR_SIZEWE
);
372 case wxHT_TOPLEVEL_BORDER_NE
:
373 case wxHT_TOPLEVEL_BORDER_SW
:
374 cursor
= wxCursor(wxCURSOR_SIZENESW
);
376 case wxHT_TOPLEVEL_BORDER_NW
:
377 case wxHT_TOPLEVEL_BORDER_SE
:
378 cursor
= wxCursor(wxCURSOR_SIZENWSE
);
389 #define wxINTERACTIVE_RESIZE_DIR \
390 (wxINTERACTIVE_RESIZE_W | wxINTERACTIVE_RESIZE_E | \
391 wxINTERACTIVE_RESIZE_S | wxINTERACTIVE_RESIZE_N)
393 struct wxInteractiveMoveData
395 wxTopLevelWindow
*m_window
;
396 wxEventLoop
*m_evtLoop
;
401 wxSize m_minSize
, m_maxSize
;
405 class wxInteractiveMoveHandler
: public wxEvtHandler
408 wxInteractiveMoveHandler(wxInteractiveMoveData
& data
) : m_data(data
) {}
411 DECLARE_EVENT_TABLE()
412 void OnMouseMove(wxMouseEvent
& event
);
413 void OnMouseDown(wxMouseEvent
& event
);
414 void OnMouseUp(wxMouseEvent
& event
);
415 void OnKeyDown(wxKeyEvent
& event
);
417 wxInteractiveMoveData
& m_data
;
420 BEGIN_EVENT_TABLE(wxInteractiveMoveHandler
, wxEvtHandler
)
421 EVT_MOTION(wxInteractiveMoveHandler::OnMouseMove
)
422 EVT_LEFT_DOWN(wxInteractiveMoveHandler::OnMouseDown
)
423 EVT_LEFT_UP(wxInteractiveMoveHandler::OnMouseUp
)
424 EVT_KEY_DOWN(wxInteractiveMoveHandler::OnKeyDown
)
428 static inline LINKAGEMODE
429 void wxApplyResize(wxInteractiveMoveData
& data
, const wxPoint
& diff
)
431 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
433 data
.m_rect
.x
+= diff
.x
;
434 data
.m_rect
.width
-= diff
.x
;
436 else if ( data
.m_flags
& wxINTERACTIVE_RESIZE_E
)
438 data
.m_rect
.width
+= diff
.x
;
440 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
442 data
.m_rect
.y
+= diff
.y
;
443 data
.m_rect
.height
-= diff
.y
;
445 else if ( data
.m_flags
& wxINTERACTIVE_RESIZE_S
)
447 data
.m_rect
.height
+= diff
.y
;
450 if ( data
.m_minSize
.x
!= wxDefaultCoord
&& data
.m_rect
.width
< data
.m_minSize
.x
)
452 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
453 data
.m_rect
.x
-= data
.m_minSize
.x
- data
.m_rect
.width
;
454 data
.m_rect
.width
= data
.m_minSize
.x
;
456 if ( data
.m_maxSize
.x
!= wxDefaultCoord
&& data
.m_rect
.width
> data
.m_maxSize
.x
)
458 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
459 data
.m_rect
.x
-= data
.m_minSize
.x
- data
.m_rect
.width
;
460 data
.m_rect
.width
= data
.m_maxSize
.x
;
462 if ( data
.m_minSize
.y
!= wxDefaultCoord
&& data
.m_rect
.height
< data
.m_minSize
.y
)
464 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
465 data
.m_rect
.y
-= data
.m_minSize
.y
- data
.m_rect
.height
;
466 data
.m_rect
.height
= data
.m_minSize
.y
;
468 if ( data
.m_maxSize
.y
!= wxDefaultCoord
&& data
.m_rect
.height
> data
.m_maxSize
.y
)
470 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
471 data
.m_rect
.y
-= data
.m_minSize
.y
- data
.m_rect
.height
;
472 data
.m_rect
.height
= data
.m_maxSize
.y
;
476 void wxInteractiveMoveHandler::OnMouseMove(wxMouseEvent
& event
)
478 if ( m_data
.m_flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
481 else if ( m_data
.m_flags
& wxINTERACTIVE_MOVE
)
483 wxPoint diff
= wxGetMousePosition() - m_data
.m_pos
;
484 m_data
.m_rect
= m_data
.m_rectOrig
;
485 m_data
.m_rect
.Offset(diff
);
486 m_data
.m_window
->Move(m_data
.m_rect
.GetPosition());
489 else if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE
)
491 wxPoint diff
= wxGetMousePosition() - m_data
.m_pos
;
492 m_data
.m_rect
= m_data
.m_rectOrig
;
493 wxApplyResize(m_data
, diff
);
494 m_data
.m_window
->SetSize(m_data
.m_rect
);
498 void wxInteractiveMoveHandler::OnMouseDown(wxMouseEvent
& WXUNUSED(event
))
500 if ( m_data
.m_flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
502 m_data
.m_evtLoop
->Exit();
506 void wxInteractiveMoveHandler::OnKeyDown(wxKeyEvent
& event
)
508 wxPoint
diff(wxDefaultCoord
,wxDefaultCoord
);
510 switch ( event
.GetKeyCode() )
512 case WXK_UP
: diff
= wxPoint(0, -16); break;
513 case WXK_DOWN
: diff
= wxPoint(0, 16); break;
514 case WXK_LEFT
: diff
= wxPoint(-16, 0); break;
515 case WXK_RIGHT
: diff
= wxPoint(16, 0); break;
517 m_data
.m_window
->SetSize(m_data
.m_rectOrig
);
518 m_data
.m_evtLoop
->Exit();
521 m_data
.m_evtLoop
->Exit();
525 if ( diff
.x
!= wxDefaultCoord
)
527 if ( m_data
.m_flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
529 m_data
.m_flags
&= ~wxINTERACTIVE_WAIT_FOR_INPUT
;
530 if ( m_data
.m_sizingCursor
)
533 m_data
.m_sizingCursor
= false;
536 if ( m_data
.m_flags
& wxINTERACTIVE_MOVE
)
538 m_data
.m_pos
= m_data
.m_window
->GetPosition() +
539 wxPoint(m_data
.m_window
->GetSize().x
/2, 8);
544 bool changeCur
= false;
546 if ( m_data
.m_flags
& wxINTERACTIVE_MOVE
)
548 m_data
.m_rect
.Offset(diff
);
549 m_data
.m_window
->Move(m_data
.m_rect
.GetPosition());
550 warp
= wxPoint(m_data
.m_window
->GetSize().x
/2, 8);
552 else /* wxINTERACTIVE_RESIZE */
554 if ( !(m_data
.m_flags
&
555 (wxINTERACTIVE_RESIZE_N
| wxINTERACTIVE_RESIZE_S
)) )
559 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_N
;
560 m_data
.m_pos
.y
= m_data
.m_window
->GetPosition().y
;
563 else if ( diff
.y
> 0 )
565 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_S
;
566 m_data
.m_pos
.y
= m_data
.m_window
->GetPosition().y
+
567 m_data
.m_window
->GetSize().y
;
571 if ( !(m_data
.m_flags
&
572 (wxINTERACTIVE_RESIZE_W
| wxINTERACTIVE_RESIZE_E
)) )
576 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_W
;
577 m_data
.m_pos
.x
= m_data
.m_window
->GetPosition().x
;
580 else if ( diff
.x
> 0 )
582 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_E
;
583 m_data
.m_pos
.x
= m_data
.m_window
->GetPosition().x
+
584 m_data
.m_window
->GetSize().x
;
589 wxApplyResize(m_data
, diff
);
590 m_data
.m_window
->SetSize(m_data
.m_rect
);
592 if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
594 else if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_E
)
595 warp
.x
= m_data
.m_window
->GetSize().x
-1;
597 warp
.x
= wxGetMousePosition().x
- m_data
.m_window
->GetPosition().x
;
599 if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
601 else if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_S
)
602 warp
.y
= m_data
.m_window
->GetSize().y
-1;
604 warp
.y
= wxGetMousePosition().y
- m_data
.m_window
->GetPosition().y
;
607 warp
-= m_data
.m_window
->GetClientAreaOrigin();
608 m_data
.m_window
->WarpPointer(warp
.x
, warp
.y
);
612 long hit
= m_data
.m_window
->HitTest(warp
);
614 if ( wxGetResizingCursor(hit
, cur
) )
616 if ( m_data
.m_sizingCursor
)
618 wxBeginBusyCursor(&cur
);
619 m_data
.m_sizingCursor
= true;
625 void wxInteractiveMoveHandler::OnMouseUp(wxMouseEvent
& WXUNUSED(event
))
627 m_data
.m_evtLoop
->Exit();
631 void wxTopLevelWindow::InteractiveMove(int flags
)
633 wxASSERT_MSG( !((flags
& wxINTERACTIVE_MOVE
) && (flags
& wxINTERACTIVE_RESIZE
)),
634 wxT("can't move and resize window at the same time") );
636 wxASSERT_MSG( !(flags
& wxINTERACTIVE_RESIZE
) ||
637 (flags
& wxINTERACTIVE_WAIT_FOR_INPUT
) ||
638 (flags
& wxINTERACTIVE_RESIZE_DIR
),
639 wxT("direction of resizing not specified") );
641 wxInteractiveMoveData data
;
647 if ( flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
649 wxCursor
sizingCursor(wxCURSOR_SIZING
);
650 wxBeginBusyCursor(&sizingCursor
);
651 data
.m_sizingCursor
= true;
655 data
.m_sizingCursor
= false;
657 data
.m_window
= this;
658 data
.m_evtLoop
= &loop
;
659 data
.m_flags
= flags
;
660 data
.m_rect
= data
.m_rectOrig
= GetRect();
661 data
.m_pos
= wxGetMousePosition();
662 data
.m_minSize
= wxSize(GetMinWidth(), GetMinHeight());
663 data
.m_maxSize
= wxSize(GetMaxWidth(), GetMaxHeight());
665 wxEvtHandler
*handler
= new wxInteractiveMoveHandler(data
);
666 this->PushEventHandler(handler
);
672 this->RemoveEventHandler(handler
);
675 if ( data
.m_sizingCursor
)
679 // ----------------------------------------------------------------------------
681 // ----------------------------------------------------------------------------
683 void wxTopLevelWindow::ClickTitleBarButton(long button
)
687 case wxTOPLEVEL_BUTTON_CLOSE
:
691 case wxTOPLEVEL_BUTTON_ICONIZE
:
695 case wxTOPLEVEL_BUTTON_MAXIMIZE
:
699 case wxTOPLEVEL_BUTTON_RESTORE
:
703 case wxTOPLEVEL_BUTTON_HELP
:
706 wxContextHelp
contextHelp(this);
712 wxFAIL_MSG(wxT("incorrect button specification"));
716 bool wxTopLevelWindow::PerformAction(const wxControlAction
& action
,
718 const wxString
& WXUNUSED(strArg
))
720 bool isActive
= numArg
!= 0;
722 if ( action
== wxACTION_TOPLEVEL_ACTIVATE
)
724 if ( m_isActive
!= isActive
)
726 m_isActive
= isActive
;
732 else if ( action
== wxACTION_TOPLEVEL_BUTTON_PRESS
)
734 m_pressedButton
= numArg
;
739 else if ( action
== wxACTION_TOPLEVEL_BUTTON_RELEASE
)
746 else if ( action
== wxACTION_TOPLEVEL_BUTTON_CLICK
)
750 ClickTitleBarButton(numArg
);
754 else if ( action
== wxACTION_TOPLEVEL_MOVE
)
756 InteractiveMove(wxINTERACTIVE_MOVE
);
760 else if ( action
== wxACTION_TOPLEVEL_RESIZE
)
762 int flags
= wxINTERACTIVE_RESIZE
;
763 if ( numArg
& wxHT_TOPLEVEL_BORDER_N
)
764 flags
|= wxINTERACTIVE_RESIZE_N
;
765 if ( numArg
& wxHT_TOPLEVEL_BORDER_S
)
766 flags
|= wxINTERACTIVE_RESIZE_S
;
767 if ( numArg
& wxHT_TOPLEVEL_BORDER_W
)
768 flags
|= wxINTERACTIVE_RESIZE_W
;
769 if ( numArg
& wxHT_TOPLEVEL_BORDER_E
)
770 flags
|= wxINTERACTIVE_RESIZE_E
;
771 InteractiveMove(flags
);
779 void wxTopLevelWindow::OnSystemMenu(wxCommandEvent
& event
)
783 switch (event
.GetId())
785 case wxID_CLOSE_FRAME
:
786 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
787 wxTOPLEVEL_BUTTON_CLOSE
);
789 case wxID_MOVE_FRAME
:
790 InteractiveMove(wxINTERACTIVE_MOVE
| wxINTERACTIVE_WAIT_FOR_INPUT
);
792 case wxID_RESIZE_FRAME
:
793 InteractiveMove(wxINTERACTIVE_RESIZE
| wxINTERACTIVE_WAIT_FOR_INPUT
);
795 case wxID_MAXIMIZE_FRAME
:
796 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
797 wxTOPLEVEL_BUTTON_MAXIMIZE
);
799 case wxID_ICONIZE_FRAME
:
800 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
801 wxTOPLEVEL_BUTTON_ICONIZE
);
803 case wxID_RESTORE_FRAME
:
804 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
805 wxTOPLEVEL_BUTTON_RESTORE
);
818 wxTopLevelWindow::GetStdInputHandler(wxInputHandler
*handlerDef
)
820 static wxStdTLWInputHandler
s_handler(handlerDef
);
825 // ============================================================================
826 // wxStdTLWInputHandler: handles focus, resizing and titlebar buttons clicks
827 // ============================================================================
829 wxStdTLWInputHandler::wxStdTLWInputHandler(wxInputHandler
*inphand
)
830 : wxStdInputHandler(inphand
)
835 m_borderCursorOn
= false;
838 bool wxStdTLWInputHandler::HandleMouse(wxInputConsumer
*consumer
,
839 const wxMouseEvent
& event
)
841 // the button has 2 states: pressed and normal with the following
842 // transitions between them:
844 // normal -> left down -> capture mouse and go to pressed state
845 // pressed -> left up inside -> generate click -> go to normal
846 // outside ------------------>
848 // the other mouse buttons are ignored
849 if ( event
.Button(1) )
851 if ( event
.ButtonDown(1) )
853 wxTopLevelWindow
*w
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
854 long hit
= w
->HitTest(event
.GetPosition());
856 if ( hit
& wxHT_TOPLEVEL_ANY_BUTTON
)
859 m_winCapture
->CaptureMouse();
862 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS
, m_winPressed
);
865 else if ( (hit
& wxHT_TOPLEVEL_TITLEBAR
) && !w
->IsMaximized() )
867 consumer
->PerformAction(wxACTION_TOPLEVEL_MOVE
);
870 else if ( (consumer
->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER
)
871 && (hit
& wxHT_TOPLEVEL_ANY_BORDER
) )
873 consumer
->PerformAction(wxACTION_TOPLEVEL_RESIZE
, hit
);
882 m_winCapture
->ReleaseMouse();
885 if ( m_winHitTest
== m_winPressed
)
887 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
, m_winPressed
);
891 //else: the mouse was released outside the window, this doesn't
896 return wxStdInputHandler::HandleMouse(consumer
, event
);
899 bool wxStdTLWInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
900 const wxMouseEvent
& event
)
902 if ( event
.GetEventObject() == m_winCapture
)
904 long hit
= m_winCapture
->HitTest(event
.GetPosition());
906 if ( hit
!= m_winHitTest
)
908 if ( hit
!= m_winPressed
)
909 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_RELEASE
, m_winPressed
);
911 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS
, m_winPressed
);
917 else if ( consumer
->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER
)
919 wxTopLevelWindow
*win
= wxStaticCast(consumer
->GetInputWindow(),
921 long hit
= win
->HitTest(event
.GetPosition());
923 if ( hit
!= m_winHitTest
)
927 if ( m_borderCursorOn
)
929 m_borderCursorOn
= false;
930 win
->SetCursor(m_origCursor
);
933 if ( hit
& wxHT_TOPLEVEL_ANY_BORDER
)
937 m_borderCursorOn
= wxGetResizingCursor(hit
, cur
);
938 if ( m_borderCursorOn
)
940 m_origCursor
= win
->GetCursor();
947 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
950 bool wxStdTLWInputHandler::HandleActivation(wxInputConsumer
*consumer
,
953 if ( m_borderCursorOn
)
955 consumer
->GetInputWindow()->SetCursor(m_origCursor
);
956 m_borderCursorOn
= false;
958 consumer
->PerformAction(wxACTION_TOPLEVEL_ACTIVATE
, activated
);