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
| wxRESIZE_BORDER
| wxFRAME_TOOL_WINDOW
|
118 style
|= wxBORDER_NONE
;
119 SetExtraStyle(exstyleOrig
& ~wxWS_EX_CONTEXTHELP
);
122 if ( !wxTopLevelWindowNative
::Create(parent
, id
, title
, pos
,
126 if ( !m_usingNativeDecorations
)
128 m_windowStyle
= styleOrig
;
129 m_exStyle
= exstyleOrig
;
135 bool wxTopLevelWindow
::ShowFullScreen(bool show
, long style
)
137 if ( show
== IsFullScreen() ) return false;
139 if ( !m_usingNativeDecorations
)
143 m_fsSavedStyle
= m_windowStyle
;
144 if ( style
& wxFULLSCREEN_NOBORDER
)
145 m_windowStyle
|= wxSIMPLE_BORDER
;
146 if ( style
& wxFULLSCREEN_NOCAPTION
)
147 m_windowStyle
&= ~wxCAPTION
;
151 m_windowStyle
= m_fsSavedStyle
;
155 return wxTopLevelWindowNative
::ShowFullScreen(show
, style
);
158 /* static */ wxTopLevelWindow
::UseNativeDecorationsByDefault(bool native
)
160 ms_drawDecorations
= !native
;
163 void wxTopLevelWindow
::UseNativeDecorations(bool native
)
165 wxASSERT_MSG( !m_windowStyle
, _T("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
| wxTOPLEVEL_BUTTON_CLOSE
;
187 if ( (m_windowStyle
& wxMINIMIZE_BOX
) && ms_canIconize
)
188 style
|= wxTOPLEVEL_BUTTON_ICONIZE
;
189 if ( m_windowStyle
& wxMAXIMIZE_BOX
)
192 style
|= wxTOPLEVEL_BUTTON_RESTORE
;
194 style
|= wxTOPLEVEL_BUTTON_MAXIMIZE
;
197 if ( m_exStyle
& wxWS_EX_CONTEXTHELP
)
198 style
|= wxTOPLEVEL_BUTTON_HELP
;
201 if ( (m_windowStyle
& (wxSIMPLE_BORDER
| wxNO_BORDER
)) == 0 )
202 style
|= wxTOPLEVEL_BORDER
;
203 if ( m_windowStyle
& (wxRESIZE_BORDER
| wxRESIZE_BORDER
) )
204 style
|= wxTOPLEVEL_RESIZEABLE
;
207 style
|= wxTOPLEVEL_MAXIMIZED
;
208 if ( GetIcon().Ok() )
209 style
|= wxTOPLEVEL_ICON
;
211 style
|= wxTOPLEVEL_ACTIVE
;
216 void wxTopLevelWindow
::RefreshTitleBar()
218 wxNcPaintEvent
event(GetId());
219 event
.SetEventObject(this);
220 GetEventHandler()->ProcessEvent(event
);
223 // ----------------------------------------------------------------------------
224 // client area handling
225 // ----------------------------------------------------------------------------
227 wxPoint wxTopLevelWindow
::GetClientAreaOrigin() const
229 if ( !m_usingNativeDecorations
)
232 wxTopLevelWindowNative
::DoGetClientSize(&w
, &h
);
233 wxRect rect
= wxRect(wxTopLevelWindowNative
::GetClientAreaOrigin(),
235 rect
= m_renderer
->GetFrameClientArea(rect
,
236 GetDecorationsStyle());
237 return rect
.GetPosition();
241 return wxTopLevelWindowNative
::GetClientAreaOrigin();
245 void wxTopLevelWindow
::DoGetClientSize(int *width
, int *height
) const
247 if ( !m_usingNativeDecorations
)
250 wxTopLevelWindowNative
::DoGetClientSize(&w
, &h
);
251 wxRect rect
= wxRect(wxTopLevelWindowNative
::GetClientAreaOrigin(),
253 rect
= m_renderer
->GetFrameClientArea(rect
,
254 GetDecorationsStyle());
258 *height
= rect
.height
;
261 wxTopLevelWindowNative
::DoGetClientSize(width
, height
);
264 void wxTopLevelWindow
::DoSetClientSize(int width
, int height
)
266 if ( !m_usingNativeDecorations
)
268 wxSize size
= m_renderer
->GetFrameTotalSize(wxSize(width
, height
),
269 GetDecorationsStyle());
270 wxTopLevelWindowNative
::DoSetClientSize(size
.x
, size
.y
);
273 wxTopLevelWindowNative
::DoSetClientSize(width
, height
);
276 void wxTopLevelWindow
::OnNcPaint(wxNcPaintEvent
& event
)
278 if ( m_usingNativeDecorations
|| !m_renderer
)
282 else // we're drawing the decorations ourselves
284 // get the window rect
285 wxRect
rect(GetSize());
288 m_renderer
->DrawFrameTitleBar(dc
, rect
,
289 GetTitle(), m_titlebarIcon
,
290 GetDecorationsStyle(),
296 long wxTopLevelWindow
::HitTest(const wxPoint
& pt
) const
299 wxTopLevelWindowNative
::DoGetClientSize(&w
, &h
);
300 wxRect
rect(wxTopLevelWindowNative
::GetClientAreaOrigin(), wxSize(w
, h
));
302 return m_renderer
->HitTestFrame(rect
, pt
+GetClientAreaOrigin(), GetDecorationsStyle());
305 int wxTopLevelWindow
::GetMinWidth() const
307 if ( !m_usingNativeDecorations
)
309 return wxMax(wxTopLevelWindowNative
::GetMinWidth(),
310 m_renderer
->GetFrameMinSize(GetDecorationsStyle()).x
);
313 return wxTopLevelWindowNative
::GetMinWidth();
316 int wxTopLevelWindow
::GetMinHeight() const
318 if ( !m_usingNativeDecorations
)
320 return wxMax(wxTopLevelWindowNative
::GetMinHeight(),
321 m_renderer
->GetFrameMinSize(GetDecorationsStyle()).y
);
324 return wxTopLevelWindowNative
::GetMinHeight();
327 // ----------------------------------------------------------------------------
329 // ----------------------------------------------------------------------------
331 void wxTopLevelWindow
::SetIcons(const wxIconBundle
& icons
)
333 wxTopLevelWindowNative
::SetIcons(icons
);
335 if ( !m_usingNativeDecorations
&& m_renderer
)
337 wxSize size
= m_renderer
->GetFrameIconSize();
338 const wxIcon
& icon
= icons
.GetIcon( size
);
340 if ( !icon
.Ok() || size
.x
== wxDefaultCoord
)
341 m_titlebarIcon
= icon
;
345 bmp1
.CopyFromIcon(icon
);
347 m_titlebarIcon
= wxNullIcon
;
348 else if ( bmp1
.GetWidth() == size
.x
&& bmp1
.GetHeight() == size
.y
)
349 m_titlebarIcon
= icon
;
353 wxImage img
= bmp1
.ConvertToImage();
354 img
.Rescale(size
.x
, size
.y
);
355 m_titlebarIcon
.CopyFromBitmap(wxBitmap(img
));
357 #endif // wxUSE_IMAGE
362 // ----------------------------------------------------------------------------
363 // interactive manipulation
364 // ----------------------------------------------------------------------------
367 static bool wxGetResizingCursor(long hitTestResult
, wxCursor
& cursor
)
369 if ( hitTestResult
& wxHT_TOPLEVEL_ANY_BORDER
)
371 switch (hitTestResult
)
373 case wxHT_TOPLEVEL_BORDER_N
:
374 case wxHT_TOPLEVEL_BORDER_S
:
375 cursor
= wxCursor(wxCURSOR_SIZENS
);
377 case wxHT_TOPLEVEL_BORDER_W
:
378 case wxHT_TOPLEVEL_BORDER_E
:
379 cursor
= wxCursor(wxCURSOR_SIZEWE
);
381 case wxHT_TOPLEVEL_BORDER_NE
:
382 case wxHT_TOPLEVEL_BORDER_SW
:
383 cursor
= wxCursor(wxCURSOR_SIZENESW
);
385 case wxHT_TOPLEVEL_BORDER_NW
:
386 case wxHT_TOPLEVEL_BORDER_SE
:
387 cursor
= wxCursor(wxCURSOR_SIZENWSE
);
398 #define wxINTERACTIVE_RESIZE_DIR \
399 (wxINTERACTIVE_RESIZE_W | wxINTERACTIVE_RESIZE_E | \
400 wxINTERACTIVE_RESIZE_S | wxINTERACTIVE_RESIZE_N)
402 struct wxInteractiveMoveData
404 wxTopLevelWindow
*m_window
;
405 wxEventLoop
*m_evtLoop
;
410 wxSize m_minSize
, m_maxSize
;
414 class wxInteractiveMoveHandler
: public wxEvtHandler
417 wxInteractiveMoveHandler(wxInteractiveMoveData
& data
) : m_data(data
) {}
420 DECLARE_EVENT_TABLE()
421 void OnMouseMove(wxMouseEvent
& event
);
422 void OnMouseDown(wxMouseEvent
& event
);
423 void OnMouseUp(wxMouseEvent
& event
);
424 void OnKeyDown(wxKeyEvent
& event
);
426 wxInteractiveMoveData
& m_data
;
429 BEGIN_EVENT_TABLE(wxInteractiveMoveHandler
, wxEvtHandler
)
430 EVT_MOTION(wxInteractiveMoveHandler
::OnMouseMove
)
431 EVT_LEFT_DOWN(wxInteractiveMoveHandler
::OnMouseDown
)
432 EVT_LEFT_UP(wxInteractiveMoveHandler
::OnMouseUp
)
433 EVT_KEY_DOWN(wxInteractiveMoveHandler
::OnKeyDown
)
437 static inline LINKAGEMODE
438 void wxApplyResize(wxInteractiveMoveData
& data
, const wxPoint
& diff
)
440 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
442 data
.m_rect
.x
+= diff
.x
;
443 data
.m_rect
.width
-= diff
.x
;
445 else if ( data
.m_flags
& wxINTERACTIVE_RESIZE_E
)
447 data
.m_rect
.width
+= diff
.x
;
449 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
451 data
.m_rect
.y
+= diff
.y
;
452 data
.m_rect
.height
-= diff
.y
;
454 else if ( data
.m_flags
& wxINTERACTIVE_RESIZE_S
)
456 data
.m_rect
.height
+= diff
.y
;
459 if ( data
.m_minSize
.x
!= wxDefaultCoord
&& data
.m_rect
.width
< data
.m_minSize
.x
)
461 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
462 data
.m_rect
.x
-= data
.m_minSize
.x
- data
.m_rect
.width
;
463 data
.m_rect
.width
= data
.m_minSize
.x
;
465 if ( data
.m_maxSize
.x
!= wxDefaultCoord
&& data
.m_rect
.width
> data
.m_maxSize
.x
)
467 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
468 data
.m_rect
.x
-= data
.m_minSize
.x
- data
.m_rect
.width
;
469 data
.m_rect
.width
= data
.m_maxSize
.x
;
471 if ( data
.m_minSize
.y
!= wxDefaultCoord
&& data
.m_rect
.height
< data
.m_minSize
.y
)
473 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
474 data
.m_rect
.y
-= data
.m_minSize
.y
- data
.m_rect
.height
;
475 data
.m_rect
.height
= data
.m_minSize
.y
;
477 if ( data
.m_maxSize
.y
!= wxDefaultCoord
&& data
.m_rect
.height
> data
.m_maxSize
.y
)
479 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
480 data
.m_rect
.y
-= data
.m_minSize
.y
- data
.m_rect
.height
;
481 data
.m_rect
.height
= data
.m_maxSize
.y
;
485 void wxInteractiveMoveHandler
::OnMouseMove(wxMouseEvent
& event
)
487 if ( m_data
.m_flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
490 else if ( m_data
.m_flags
& wxINTERACTIVE_MOVE
)
492 wxPoint diff
= wxGetMousePosition() - m_data
.m_pos
;
493 m_data
.m_rect
= m_data
.m_rectOrig
;
494 m_data
.m_rect
.Offset(diff
);
495 m_data
.m_window
->Move(m_data
.m_rect
.GetPosition());
498 else if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE
)
500 wxPoint diff
= wxGetMousePosition() - m_data
.m_pos
;
501 m_data
.m_rect
= m_data
.m_rectOrig
;
502 wxApplyResize(m_data
, diff
);
503 m_data
.m_window
->SetSize(m_data
.m_rect
);
507 void wxInteractiveMoveHandler
::OnMouseDown(wxMouseEvent
& WXUNUSED(event
))
509 if ( m_data
.m_flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
511 m_data
.m_evtLoop
->Exit();
515 void wxInteractiveMoveHandler
::OnKeyDown(wxKeyEvent
& event
)
517 wxPoint
diff(wxDefaultCoord
,wxDefaultCoord
);
519 switch ( event
.GetKeyCode() )
521 case WXK_UP
: diff
= wxPoint(0, -16); break;
522 case WXK_DOWN
: diff
= wxPoint(0, 16); break;
523 case WXK_LEFT
: diff
= wxPoint(-16, 0); break;
524 case WXK_RIGHT
: diff
= wxPoint(16, 0); break;
526 m_data
.m_window
->SetSize(m_data
.m_rectOrig
);
527 m_data
.m_evtLoop
->Exit();
530 m_data
.m_evtLoop
->Exit();
534 if ( diff
.x
!= wxDefaultCoord
)
536 if ( m_data
.m_flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
538 m_data
.m_flags
&= ~wxINTERACTIVE_WAIT_FOR_INPUT
;
539 if ( m_data
.m_sizingCursor
)
542 m_data
.m_sizingCursor
= false;
545 if ( m_data
.m_flags
& wxINTERACTIVE_MOVE
)
547 m_data
.m_pos
= m_data
.m_window
->GetPosition() +
548 wxPoint(m_data
.m_window
->GetSize().x
/2, 8);
553 bool changeCur
= false;
555 if ( m_data
.m_flags
& wxINTERACTIVE_MOVE
)
557 m_data
.m_rect
.Offset(diff
);
558 m_data
.m_window
->Move(m_data
.m_rect
.GetPosition());
559 warp
= wxPoint(m_data
.m_window
->GetSize().x
/2, 8);
561 else /* wxINTERACTIVE_RESIZE */
563 if ( !(m_data
.m_flags
&
564 (wxINTERACTIVE_RESIZE_N
| wxINTERACTIVE_RESIZE_S
)) )
568 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_N
;
569 m_data
.m_pos
.y
= m_data
.m_window
->GetPosition().y
;
572 else if ( diff
.y
> 0 )
574 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_S
;
575 m_data
.m_pos
.y
= m_data
.m_window
->GetPosition().y
+
576 m_data
.m_window
->GetSize().y
;
580 if ( !(m_data
.m_flags
&
581 (wxINTERACTIVE_RESIZE_W
| wxINTERACTIVE_RESIZE_E
)) )
585 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_W
;
586 m_data
.m_pos
.x
= m_data
.m_window
->GetPosition().x
;
589 else if ( diff
.x
> 0 )
591 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_E
;
592 m_data
.m_pos
.x
= m_data
.m_window
->GetPosition().x
+
593 m_data
.m_window
->GetSize().x
;
598 wxApplyResize(m_data
, diff
);
599 m_data
.m_window
->SetSize(m_data
.m_rect
);
601 if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
603 else if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_E
)
604 warp
.x
= m_data
.m_window
->GetSize().x
-1;
606 warp
.x
= wxGetMousePosition().x
- m_data
.m_window
->GetPosition().x
;
608 if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
610 else if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_S
)
611 warp
.y
= m_data
.m_window
->GetSize().y
-1;
613 warp
.y
= wxGetMousePosition().y
- m_data
.m_window
->GetPosition().y
;
616 warp
-= m_data
.m_window
->GetClientAreaOrigin();
617 m_data
.m_window
->WarpPointer(warp
.x
, warp
.y
);
621 long hit
= m_data
.m_window
->HitTest(warp
);
623 if ( wxGetResizingCursor(hit
, cur
) )
625 if ( m_data
.m_sizingCursor
)
627 wxBeginBusyCursor(&cur
);
628 m_data
.m_sizingCursor
= true;
634 void wxInteractiveMoveHandler
::OnMouseUp(wxMouseEvent
& WXUNUSED(event
))
636 m_data
.m_evtLoop
->Exit();
640 void wxTopLevelWindow
::InteractiveMove(int flags
)
642 wxASSERT_MSG( !((flags
& wxINTERACTIVE_MOVE
) && (flags
& wxINTERACTIVE_RESIZE
)),
643 wxT("can't move and resize window at the same time") );
645 wxASSERT_MSG( !(flags
& wxINTERACTIVE_RESIZE
) ||
646 (flags
& wxINTERACTIVE_WAIT_FOR_INPUT
) ||
647 (flags
& wxINTERACTIVE_RESIZE_DIR
),
648 wxT("direction of resizing not specified") );
650 wxInteractiveMoveData data
;
656 if ( flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
658 wxCursor
sizingCursor(wxCURSOR_SIZING
);
659 wxBeginBusyCursor(&sizingCursor
);
660 data
.m_sizingCursor
= true;
664 data
.m_sizingCursor
= false;
666 data
.m_window
= this;
667 data
.m_evtLoop
= &loop
;
668 data
.m_flags
= flags
;
669 data
.m_rect
= data
.m_rectOrig
= GetRect();
670 data
.m_pos
= wxGetMousePosition();
671 data
.m_minSize
= wxSize(GetMinWidth(), GetMinHeight());
672 data
.m_maxSize
= wxSize(GetMaxWidth(), GetMaxHeight());
674 wxEvtHandler
*handler
= new wxInteractiveMoveHandler(data
);
675 this->PushEventHandler(handler
);
681 this->RemoveEventHandler(handler
);
684 if ( data
.m_sizingCursor
)
688 // ----------------------------------------------------------------------------
690 // ----------------------------------------------------------------------------
692 void wxTopLevelWindow
::ClickTitleBarButton(long button
)
696 case wxTOPLEVEL_BUTTON_CLOSE
:
700 case wxTOPLEVEL_BUTTON_ICONIZE
:
704 case wxTOPLEVEL_BUTTON_MAXIMIZE
:
708 case wxTOPLEVEL_BUTTON_RESTORE
:
712 case wxTOPLEVEL_BUTTON_HELP
:
715 wxContextHelp
contextHelp(this);
721 wxFAIL_MSG(wxT("incorrect button specification"));
725 bool wxTopLevelWindow
::PerformAction(const wxControlAction
& action
,
727 const wxString
& WXUNUSED(strArg
))
729 bool isActive
= numArg
!= 0;
731 if ( action
== wxACTION_TOPLEVEL_ACTIVATE
)
733 if ( m_isActive
!= isActive
)
735 m_isActive
= isActive
;
741 else if ( action
== wxACTION_TOPLEVEL_BUTTON_PRESS
)
743 m_pressedButton
= numArg
;
748 else if ( action
== wxACTION_TOPLEVEL_BUTTON_RELEASE
)
755 else if ( action
== wxACTION_TOPLEVEL_BUTTON_CLICK
)
759 ClickTitleBarButton(numArg
);
763 else if ( action
== wxACTION_TOPLEVEL_MOVE
)
765 InteractiveMove(wxINTERACTIVE_MOVE
);
769 else if ( action
== wxACTION_TOPLEVEL_RESIZE
)
771 int flags
= wxINTERACTIVE_RESIZE
;
772 if ( numArg
& wxHT_TOPLEVEL_BORDER_N
)
773 flags
|= wxINTERACTIVE_RESIZE_N
;
774 if ( numArg
& wxHT_TOPLEVEL_BORDER_S
)
775 flags
|= wxINTERACTIVE_RESIZE_S
;
776 if ( numArg
& wxHT_TOPLEVEL_BORDER_W
)
777 flags
|= wxINTERACTIVE_RESIZE_W
;
778 if ( numArg
& wxHT_TOPLEVEL_BORDER_E
)
779 flags
|= wxINTERACTIVE_RESIZE_E
;
780 InteractiveMove(flags
);
788 void wxTopLevelWindow
::OnSystemMenu(wxCommandEvent
& event
)
792 switch (event
.GetId())
794 case wxID_CLOSE_FRAME
:
795 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
796 wxTOPLEVEL_BUTTON_CLOSE
);
798 case wxID_MOVE_FRAME
:
799 InteractiveMove(wxINTERACTIVE_MOVE
| wxINTERACTIVE_WAIT_FOR_INPUT
);
801 case wxID_RESIZE_FRAME
:
802 InteractiveMove(wxINTERACTIVE_RESIZE
| wxINTERACTIVE_WAIT_FOR_INPUT
);
804 case wxID_MAXIMIZE_FRAME
:
805 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
806 wxTOPLEVEL_BUTTON_MAXIMIZE
);
808 case wxID_ICONIZE_FRAME
:
809 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
810 wxTOPLEVEL_BUTTON_ICONIZE
);
812 case wxID_RESTORE_FRAME
:
813 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
814 wxTOPLEVEL_BUTTON_RESTORE
);
827 wxTopLevelWindow
::GetStdInputHandler(wxInputHandler
*handlerDef
)
829 static wxStdTLWInputHandler
s_handler(handlerDef
);
834 // ============================================================================
835 // wxStdTLWInputHandler: handles focus, resizing and titlebar buttons clicks
836 // ============================================================================
838 wxStdTLWInputHandler
::wxStdTLWInputHandler(wxInputHandler
*inphand
)
839 : wxStdInputHandler(inphand
)
844 m_borderCursorOn
= false;
847 bool wxStdTLWInputHandler
::HandleMouse(wxInputConsumer
*consumer
,
848 const wxMouseEvent
& event
)
850 // the button has 2 states: pressed and normal with the following
851 // transitions between them:
853 // normal -> left down -> capture mouse and go to pressed state
854 // pressed -> left up inside -> generate click -> go to normal
855 // outside ------------------>
857 // the other mouse buttons are ignored
858 if ( event
.Button(1) )
860 if ( event
.ButtonDown(1) )
862 wxTopLevelWindow
*w
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
863 long hit
= w
->HitTest(event
.GetPosition());
865 if ( hit
& wxHT_TOPLEVEL_ANY_BUTTON
)
868 m_winCapture
->CaptureMouse();
871 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS
, m_winPressed
);
874 else if ( (hit
& wxHT_TOPLEVEL_TITLEBAR
) && !w
->IsMaximized() )
876 consumer
->PerformAction(wxACTION_TOPLEVEL_MOVE
);
879 else if ( (consumer
->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER
)
880 && (hit
& wxHT_TOPLEVEL_ANY_BORDER
) )
882 consumer
->PerformAction(wxACTION_TOPLEVEL_RESIZE
, hit
);
891 m_winCapture
->ReleaseMouse();
894 if ( m_winHitTest
== m_winPressed
)
896 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
, m_winPressed
);
900 //else: the mouse was released outside the window, this doesn't
905 return wxStdInputHandler
::HandleMouse(consumer
, event
);
908 bool wxStdTLWInputHandler
::HandleMouseMove(wxInputConsumer
*consumer
,
909 const wxMouseEvent
& event
)
911 if ( event
.GetEventObject() == m_winCapture
)
913 long hit
= m_winCapture
->HitTest(event
.GetPosition());
915 if ( hit
!= m_winHitTest
)
917 if ( hit
!= m_winPressed
)
918 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_RELEASE
, m_winPressed
);
920 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS
, m_winPressed
);
926 else if ( consumer
->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER
)
928 wxTopLevelWindow
*win
= wxStaticCast(consumer
->GetInputWindow(),
930 long hit
= win
->HitTest(event
.GetPosition());
932 if ( hit
!= m_winHitTest
)
936 if ( m_borderCursorOn
)
938 m_borderCursorOn
= false;
939 win
->SetCursor(m_origCursor
);
942 if ( hit
& wxHT_TOPLEVEL_ANY_BORDER
)
946 m_borderCursorOn
= wxGetResizingCursor(hit
, cur
);
947 if ( m_borderCursorOn
)
949 m_origCursor
= win
->GetCursor();
956 return wxStdInputHandler
::HandleMouseMove(consumer
, event
);
959 bool wxStdTLWInputHandler
::HandleActivation(wxInputConsumer
*consumer
,
962 if ( m_borderCursorOn
)
964 consumer
->GetInputWindow()->SetCursor(m_origCursor
);
965 m_borderCursorOn
= false;
967 consumer
->PerformAction(wxACTION_TOPLEVEL_ACTIVATE
, activated
);