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()
88 bool wxTopLevelWindow::Create(wxWindow
*parent
,
90 const wxString
& title
,
96 // init them to avoid compiler warnings
100 if ( ms_drawDecorations
== -1 )
103 !wxSystemSettings::HasFeature(wxSYS_CAN_DRAW_FRAME_DECORATIONS
)
104 || wxGetEnv(wxT("WXDECOR"), NULL
);
105 // FIXME -- wxUniv should provide a way to force non-native decorations!
106 // $WXDECOR is just a hack in absence of better wxUniv solution
109 if ( ms_canIconize
== -1 )
111 ms_canIconize
= wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
);
114 if ( ms_drawDecorations
)
116 CreateInputHandler(wxINP_HANDLER_TOPLEVEL
);
119 exstyleOrig
= GetExtraStyle();
120 style
&= ~(wxCAPTION
| wxMINIMIZE_BOX
| wxMAXIMIZE_BOX
|
121 wxSYSTEM_MENU
| wxRESIZE_BORDER
| wxFRAME_TOOL_WINDOW
|
123 style
|= wxSIMPLE_BORDER
;
124 SetExtraStyle(exstyleOrig
& ~wxWS_EX_CONTEXTHELP
);
127 if ( !wxTopLevelWindowNative::Create(parent
, id
, title
, pos
,
131 if ( ms_drawDecorations
)
133 m_windowStyle
= styleOrig
;
134 m_exStyle
= exstyleOrig
;
140 bool wxTopLevelWindow::ShowFullScreen(bool show
, long style
)
142 if ( show
== IsFullScreen() ) return false;
144 if ( ms_drawDecorations
)
148 m_fsSavedStyle
= m_windowStyle
;
149 if ( style
& wxFULLSCREEN_NOBORDER
)
150 m_windowStyle
|= wxSIMPLE_BORDER
;
151 if ( style
& wxFULLSCREEN_NOCAPTION
)
152 m_windowStyle
&= ~wxCAPTION
;
156 m_windowStyle
= m_fsSavedStyle
;
160 return wxTopLevelWindowNative::ShowFullScreen(show
, style
);
163 long wxTopLevelWindow::GetDecorationsStyle() const
167 if ( m_windowStyle
& wxCAPTION
)
169 style
|= wxTOPLEVEL_TITLEBAR
| wxTOPLEVEL_BUTTON_CLOSE
;
170 if ( (m_windowStyle
& wxMINIMIZE_BOX
) && ms_canIconize
)
171 style
|= wxTOPLEVEL_BUTTON_ICONIZE
;
172 if ( m_windowStyle
& wxMAXIMIZE_BOX
)
175 style
|= wxTOPLEVEL_BUTTON_RESTORE
;
177 style
|= wxTOPLEVEL_BUTTON_MAXIMIZE
;
180 if ( m_exStyle
& wxWS_EX_CONTEXTHELP
)
181 style
|= wxTOPLEVEL_BUTTON_HELP
;
184 if ( (m_windowStyle
& (wxSIMPLE_BORDER
| wxNO_BORDER
)) == 0 )
185 style
|= wxTOPLEVEL_BORDER
;
186 if ( m_windowStyle
& (wxRESIZE_BORDER
| wxRESIZE_BORDER
) )
187 style
|= wxTOPLEVEL_RESIZEABLE
;
190 style
|= wxTOPLEVEL_MAXIMIZED
;
191 if ( GetIcon().Ok() )
192 style
|= wxTOPLEVEL_ICON
;
194 style
|= wxTOPLEVEL_ACTIVE
;
199 void wxTopLevelWindow::RefreshTitleBar()
201 wxNcPaintEvent
event(GetId());
202 event
.SetEventObject(this);
203 GetEventHandler()->ProcessEvent(event
);
206 // ----------------------------------------------------------------------------
207 // client area handling
208 // ----------------------------------------------------------------------------
210 wxPoint
wxTopLevelWindow::GetClientAreaOrigin() const
212 if ( ms_drawDecorations
)
215 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
216 wxRect rect
= wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
218 rect
= m_renderer
->GetFrameClientArea(rect
,
219 GetDecorationsStyle());
220 return rect
.GetPosition();
224 return wxTopLevelWindowNative::GetClientAreaOrigin();
228 void wxTopLevelWindow::DoGetClientSize(int *width
, int *height
) const
230 if ( ms_drawDecorations
)
233 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
234 wxRect rect
= wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
236 rect
= m_renderer
->GetFrameClientArea(rect
,
237 GetDecorationsStyle());
241 *height
= rect
.height
;
244 wxTopLevelWindowNative::DoGetClientSize(width
, height
);
247 void wxTopLevelWindow::DoSetClientSize(int width
, int height
)
249 if ( ms_drawDecorations
)
251 wxSize size
= m_renderer
->GetFrameTotalSize(wxSize(width
, height
),
252 GetDecorationsStyle());
253 wxTopLevelWindowNative::DoSetClientSize(size
.x
, size
.y
);
256 wxTopLevelWindowNative::DoSetClientSize(width
, height
);
259 void wxTopLevelWindow::OnNcPaint(wxNcPaintEvent
& event
)
261 if ( !ms_drawDecorations
|| !m_renderer
)
265 // get the window rect
266 wxRect
rect(GetSize());
269 m_renderer
->DrawFrameTitleBar(dc
, rect
,
270 GetTitle(), m_titlebarIcon
,
271 GetDecorationsStyle(),
277 long wxTopLevelWindow::HitTest(const wxPoint
& pt
) const
280 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
281 wxRect
rect(wxTopLevelWindowNative::GetClientAreaOrigin(), wxSize(w
, h
));
283 return m_renderer
->HitTestFrame(rect
, pt
+GetClientAreaOrigin(), GetDecorationsStyle());
286 int wxTopLevelWindow::GetMinWidth() const
288 if ( ms_drawDecorations
)
290 return wxMax(wxTopLevelWindowNative::GetMinWidth(),
291 m_renderer
->GetFrameMinSize(GetDecorationsStyle()).x
);
294 return wxTopLevelWindowNative::GetMinWidth();
297 int wxTopLevelWindow::GetMinHeight() const
299 if ( ms_drawDecorations
)
301 return wxMax(wxTopLevelWindowNative::GetMinHeight(),
302 m_renderer
->GetFrameMinSize(GetDecorationsStyle()).y
);
305 return wxTopLevelWindowNative::GetMinHeight();
308 // ----------------------------------------------------------------------------
310 // ----------------------------------------------------------------------------
312 void wxTopLevelWindow::SetIcons(const wxIconBundle
& icons
)
314 wxTopLevelWindowNative::SetIcons(icons
);
316 if ( ms_drawDecorations
&& m_renderer
)
318 wxSize size
= m_renderer
->GetFrameIconSize();
319 const wxIcon
& icon
= icons
.GetIcon( size
);
321 if ( !icon
.Ok() || size
.x
== wxDefaultCoord
)
322 m_titlebarIcon
= icon
;
326 bmp1
.CopyFromIcon(icon
);
328 m_titlebarIcon
= wxNullIcon
;
329 else if ( bmp1
.GetWidth() == size
.x
&& bmp1
.GetHeight() == size
.y
)
330 m_titlebarIcon
= icon
;
334 wxImage img
= bmp1
.ConvertToImage();
335 img
.Rescale(size
.x
, size
.y
);
336 m_titlebarIcon
.CopyFromBitmap(wxBitmap(img
));
338 #endif // wxUSE_IMAGE
343 // ----------------------------------------------------------------------------
344 // interactive manipulation
345 // ----------------------------------------------------------------------------
348 static bool wxGetResizingCursor(long hitTestResult
, wxCursor
& cursor
)
350 if ( hitTestResult
& wxHT_TOPLEVEL_ANY_BORDER
)
352 switch (hitTestResult
)
354 case wxHT_TOPLEVEL_BORDER_N
:
355 case wxHT_TOPLEVEL_BORDER_S
:
356 cursor
= wxCursor(wxCURSOR_SIZENS
);
358 case wxHT_TOPLEVEL_BORDER_W
:
359 case wxHT_TOPLEVEL_BORDER_E
:
360 cursor
= wxCursor(wxCURSOR_SIZEWE
);
362 case wxHT_TOPLEVEL_BORDER_NE
:
363 case wxHT_TOPLEVEL_BORDER_SW
:
364 cursor
= wxCursor(wxCURSOR_SIZENESW
);
366 case wxHT_TOPLEVEL_BORDER_NW
:
367 case wxHT_TOPLEVEL_BORDER_SE
:
368 cursor
= wxCursor(wxCURSOR_SIZENWSE
);
379 #define wxINTERACTIVE_RESIZE_DIR \
380 (wxINTERACTIVE_RESIZE_W | wxINTERACTIVE_RESIZE_E | \
381 wxINTERACTIVE_RESIZE_S | wxINTERACTIVE_RESIZE_N)
383 struct wxInteractiveMoveData
385 wxTopLevelWindow
*m_window
;
386 wxEventLoop
*m_evtLoop
;
391 wxSize m_minSize
, m_maxSize
;
395 class wxInteractiveMoveHandler
: public wxEvtHandler
398 wxInteractiveMoveHandler(wxInteractiveMoveData
& data
) : m_data(data
) {}
401 DECLARE_EVENT_TABLE()
402 void OnMouseMove(wxMouseEvent
& event
);
403 void OnMouseDown(wxMouseEvent
& event
);
404 void OnMouseUp(wxMouseEvent
& event
);
405 void OnKeyDown(wxKeyEvent
& event
);
407 wxInteractiveMoveData
& m_data
;
410 BEGIN_EVENT_TABLE(wxInteractiveMoveHandler
, wxEvtHandler
)
411 EVT_MOTION(wxInteractiveMoveHandler::OnMouseMove
)
412 EVT_LEFT_DOWN(wxInteractiveMoveHandler::OnMouseDown
)
413 EVT_LEFT_UP(wxInteractiveMoveHandler::OnMouseUp
)
414 EVT_KEY_DOWN(wxInteractiveMoveHandler::OnKeyDown
)
418 static inline LINKAGEMODE
419 void wxApplyResize(wxInteractiveMoveData
& data
, const wxPoint
& diff
)
421 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
423 data
.m_rect
.x
+= diff
.x
;
424 data
.m_rect
.width
-= diff
.x
;
426 else if ( data
.m_flags
& wxINTERACTIVE_RESIZE_E
)
428 data
.m_rect
.width
+= diff
.x
;
430 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
432 data
.m_rect
.y
+= diff
.y
;
433 data
.m_rect
.height
-= diff
.y
;
435 else if ( data
.m_flags
& wxINTERACTIVE_RESIZE_S
)
437 data
.m_rect
.height
+= diff
.y
;
440 if ( data
.m_minSize
.x
!= wxDefaultCoord
&& data
.m_rect
.width
< data
.m_minSize
.x
)
442 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
443 data
.m_rect
.x
-= data
.m_minSize
.x
- data
.m_rect
.width
;
444 data
.m_rect
.width
= data
.m_minSize
.x
;
446 if ( data
.m_maxSize
.x
!= wxDefaultCoord
&& data
.m_rect
.width
> data
.m_maxSize
.x
)
448 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
449 data
.m_rect
.x
-= data
.m_minSize
.x
- data
.m_rect
.width
;
450 data
.m_rect
.width
= data
.m_maxSize
.x
;
452 if ( data
.m_minSize
.y
!= wxDefaultCoord
&& data
.m_rect
.height
< data
.m_minSize
.y
)
454 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
455 data
.m_rect
.y
-= data
.m_minSize
.y
- data
.m_rect
.height
;
456 data
.m_rect
.height
= data
.m_minSize
.y
;
458 if ( data
.m_maxSize
.y
!= wxDefaultCoord
&& data
.m_rect
.height
> data
.m_maxSize
.y
)
460 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
461 data
.m_rect
.y
-= data
.m_minSize
.y
- data
.m_rect
.height
;
462 data
.m_rect
.height
= data
.m_maxSize
.y
;
466 void wxInteractiveMoveHandler::OnMouseMove(wxMouseEvent
& event
)
468 if ( m_data
.m_flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
471 else if ( m_data
.m_flags
& wxINTERACTIVE_MOVE
)
473 wxPoint diff
= wxGetMousePosition() - m_data
.m_pos
;
474 m_data
.m_rect
= m_data
.m_rectOrig
;
475 m_data
.m_rect
.Offset(diff
);
476 m_data
.m_window
->Move(m_data
.m_rect
.GetPosition());
479 else if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE
)
481 wxPoint diff
= wxGetMousePosition() - m_data
.m_pos
;
482 m_data
.m_rect
= m_data
.m_rectOrig
;
483 wxApplyResize(m_data
, diff
);
484 m_data
.m_window
->SetSize(m_data
.m_rect
);
488 void wxInteractiveMoveHandler::OnMouseDown(wxMouseEvent
& WXUNUSED(event
))
490 if ( m_data
.m_flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
492 m_data
.m_evtLoop
->Exit();
496 void wxInteractiveMoveHandler::OnKeyDown(wxKeyEvent
& event
)
498 wxPoint
diff(wxDefaultCoord
,wxDefaultCoord
);
500 switch ( event
.GetKeyCode() )
502 case WXK_UP
: diff
= wxPoint(0, -16); break;
503 case WXK_DOWN
: diff
= wxPoint(0, 16); break;
504 case WXK_LEFT
: diff
= wxPoint(-16, 0); break;
505 case WXK_RIGHT
: diff
= wxPoint(16, 0); break;
507 m_data
.m_window
->SetSize(m_data
.m_rectOrig
);
508 m_data
.m_evtLoop
->Exit();
511 m_data
.m_evtLoop
->Exit();
515 if ( diff
.x
!= wxDefaultCoord
)
517 if ( m_data
.m_flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
519 m_data
.m_flags
&= ~wxINTERACTIVE_WAIT_FOR_INPUT
;
520 if ( m_data
.m_sizingCursor
)
523 m_data
.m_sizingCursor
= false;
526 if ( m_data
.m_flags
& wxINTERACTIVE_MOVE
)
528 m_data
.m_pos
= m_data
.m_window
->GetPosition() +
529 wxPoint(m_data
.m_window
->GetSize().x
/2, 8);
534 bool changeCur
= false;
536 if ( m_data
.m_flags
& wxINTERACTIVE_MOVE
)
538 m_data
.m_rect
.Offset(diff
);
539 m_data
.m_window
->Move(m_data
.m_rect
.GetPosition());
540 warp
= wxPoint(m_data
.m_window
->GetSize().x
/2, 8);
542 else /* wxINTERACTIVE_RESIZE */
544 if ( !(m_data
.m_flags
&
545 (wxINTERACTIVE_RESIZE_N
| wxINTERACTIVE_RESIZE_S
)) )
549 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_N
;
550 m_data
.m_pos
.y
= m_data
.m_window
->GetPosition().y
;
553 else if ( diff
.y
> 0 )
555 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_S
;
556 m_data
.m_pos
.y
= m_data
.m_window
->GetPosition().y
+
557 m_data
.m_window
->GetSize().y
;
561 if ( !(m_data
.m_flags
&
562 (wxINTERACTIVE_RESIZE_W
| wxINTERACTIVE_RESIZE_E
)) )
566 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_W
;
567 m_data
.m_pos
.x
= m_data
.m_window
->GetPosition().x
;
570 else if ( diff
.x
> 0 )
572 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_E
;
573 m_data
.m_pos
.x
= m_data
.m_window
->GetPosition().x
+
574 m_data
.m_window
->GetSize().x
;
579 wxApplyResize(m_data
, diff
);
580 m_data
.m_window
->SetSize(m_data
.m_rect
);
582 if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
584 else if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_E
)
585 warp
.x
= m_data
.m_window
->GetSize().x
-1;
587 warp
.x
= wxGetMousePosition().x
- m_data
.m_window
->GetPosition().x
;
589 if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
591 else if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_S
)
592 warp
.y
= m_data
.m_window
->GetSize().y
-1;
594 warp
.y
= wxGetMousePosition().y
- m_data
.m_window
->GetPosition().y
;
597 warp
-= m_data
.m_window
->GetClientAreaOrigin();
598 m_data
.m_window
->WarpPointer(warp
.x
, warp
.y
);
602 long hit
= m_data
.m_window
->HitTest(warp
);
604 if ( wxGetResizingCursor(hit
, cur
) )
606 if ( m_data
.m_sizingCursor
)
608 wxBeginBusyCursor(&cur
);
609 m_data
.m_sizingCursor
= true;
615 void wxInteractiveMoveHandler::OnMouseUp(wxMouseEvent
& WXUNUSED(event
))
617 m_data
.m_evtLoop
->Exit();
621 void wxTopLevelWindow::InteractiveMove(int flags
)
623 wxASSERT_MSG( !((flags
& wxINTERACTIVE_MOVE
) && (flags
& wxINTERACTIVE_RESIZE
)),
624 wxT("can't move and resize window at the same time") );
626 wxASSERT_MSG( !(flags
& wxINTERACTIVE_RESIZE
) ||
627 (flags
& wxINTERACTIVE_WAIT_FOR_INPUT
) ||
628 (flags
& wxINTERACTIVE_RESIZE_DIR
),
629 wxT("direction of resizing not specified") );
631 wxInteractiveMoveData data
;
637 if ( flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
639 wxCursor
sizingCursor(wxCURSOR_SIZING
);
640 wxBeginBusyCursor(&sizingCursor
);
641 data
.m_sizingCursor
= true;
645 data
.m_sizingCursor
= false;
647 data
.m_window
= this;
648 data
.m_evtLoop
= &loop
;
649 data
.m_flags
= flags
;
650 data
.m_rect
= data
.m_rectOrig
= GetRect();
651 data
.m_pos
= wxGetMousePosition();
652 data
.m_minSize
= wxSize(GetMinWidth(), GetMinHeight());
653 data
.m_maxSize
= wxSize(GetMaxWidth(), GetMaxHeight());
655 wxEvtHandler
*handler
= new wxInteractiveMoveHandler(data
);
656 this->PushEventHandler(handler
);
662 this->RemoveEventHandler(handler
);
665 if ( data
.m_sizingCursor
)
669 // ----------------------------------------------------------------------------
671 // ----------------------------------------------------------------------------
673 void wxTopLevelWindow::ClickTitleBarButton(long button
)
677 case wxTOPLEVEL_BUTTON_CLOSE
:
681 case wxTOPLEVEL_BUTTON_ICONIZE
:
685 case wxTOPLEVEL_BUTTON_MAXIMIZE
:
689 case wxTOPLEVEL_BUTTON_RESTORE
:
693 case wxTOPLEVEL_BUTTON_HELP
:
696 wxContextHelp
contextHelp(this);
702 wxFAIL_MSG(wxT("incorrect button specification"));
706 bool wxTopLevelWindow::PerformAction(const wxControlAction
& action
,
708 const wxString
& WXUNUSED(strArg
))
710 bool isActive
= numArg
!= 0;
712 if ( action
== wxACTION_TOPLEVEL_ACTIVATE
)
714 if ( m_isActive
!= isActive
)
716 m_isActive
= isActive
;
722 else if ( action
== wxACTION_TOPLEVEL_BUTTON_PRESS
)
724 m_pressedButton
= numArg
;
729 else if ( action
== wxACTION_TOPLEVEL_BUTTON_RELEASE
)
736 else if ( action
== wxACTION_TOPLEVEL_BUTTON_CLICK
)
740 ClickTitleBarButton(numArg
);
744 else if ( action
== wxACTION_TOPLEVEL_MOVE
)
746 InteractiveMove(wxINTERACTIVE_MOVE
);
750 else if ( action
== wxACTION_TOPLEVEL_RESIZE
)
752 int flags
= wxINTERACTIVE_RESIZE
;
753 if ( numArg
& wxHT_TOPLEVEL_BORDER_N
)
754 flags
|= wxINTERACTIVE_RESIZE_N
;
755 if ( numArg
& wxHT_TOPLEVEL_BORDER_S
)
756 flags
|= wxINTERACTIVE_RESIZE_S
;
757 if ( numArg
& wxHT_TOPLEVEL_BORDER_W
)
758 flags
|= wxINTERACTIVE_RESIZE_W
;
759 if ( numArg
& wxHT_TOPLEVEL_BORDER_E
)
760 flags
|= wxINTERACTIVE_RESIZE_E
;
761 InteractiveMove(flags
);
769 void wxTopLevelWindow::OnSystemMenu(wxCommandEvent
& event
)
773 switch (event
.GetId())
775 case wxID_CLOSE_FRAME
:
776 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
777 wxTOPLEVEL_BUTTON_CLOSE
);
779 case wxID_MOVE_FRAME
:
780 InteractiveMove(wxINTERACTIVE_MOVE
| wxINTERACTIVE_WAIT_FOR_INPUT
);
782 case wxID_RESIZE_FRAME
:
783 InteractiveMove(wxINTERACTIVE_RESIZE
| wxINTERACTIVE_WAIT_FOR_INPUT
);
785 case wxID_MAXIMIZE_FRAME
:
786 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
787 wxTOPLEVEL_BUTTON_MAXIMIZE
);
789 case wxID_ICONIZE_FRAME
:
790 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
791 wxTOPLEVEL_BUTTON_ICONIZE
);
793 case wxID_RESTORE_FRAME
:
794 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
795 wxTOPLEVEL_BUTTON_RESTORE
);
808 wxTopLevelWindow::GetStdInputHandler(wxInputHandler
*handlerDef
)
810 static wxStdTLWInputHandler
s_handler(handlerDef
);
815 // ============================================================================
816 // wxStdTLWInputHandler: handles focus, resizing and titlebar buttons clicks
817 // ============================================================================
819 wxStdTLWInputHandler::wxStdTLWInputHandler(wxInputHandler
*inphand
)
820 : wxStdInputHandler(inphand
)
825 m_borderCursorOn
= false;
828 bool wxStdTLWInputHandler::HandleMouse(wxInputConsumer
*consumer
,
829 const wxMouseEvent
& event
)
831 // the button has 2 states: pressed and normal with the following
832 // transitions between them:
834 // normal -> left down -> capture mouse and go to pressed state
835 // pressed -> left up inside -> generate click -> go to normal
836 // outside ------------------>
838 // the other mouse buttons are ignored
839 if ( event
.Button(1) )
841 if ( event
.ButtonDown(1) )
843 wxTopLevelWindow
*w
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
844 long hit
= w
->HitTest(event
.GetPosition());
846 if ( hit
& wxHT_TOPLEVEL_ANY_BUTTON
)
849 m_winCapture
->CaptureMouse();
852 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS
, m_winPressed
);
855 else if ( (hit
& wxHT_TOPLEVEL_TITLEBAR
) && !w
->IsMaximized() )
857 consumer
->PerformAction(wxACTION_TOPLEVEL_MOVE
);
860 else if ( (consumer
->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER
)
861 && (hit
& wxHT_TOPLEVEL_ANY_BORDER
) )
863 consumer
->PerformAction(wxACTION_TOPLEVEL_RESIZE
, hit
);
872 m_winCapture
->ReleaseMouse();
875 if ( m_winHitTest
== m_winPressed
)
877 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
, m_winPressed
);
881 //else: the mouse was released outside the window, this doesn't
886 return wxStdInputHandler::HandleMouse(consumer
, event
);
889 bool wxStdTLWInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
890 const wxMouseEvent
& event
)
892 if ( event
.GetEventObject() == m_winCapture
)
894 long hit
= m_winCapture
->HitTest(event
.GetPosition());
896 if ( hit
!= m_winHitTest
)
898 if ( hit
!= m_winPressed
)
899 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_RELEASE
, m_winPressed
);
901 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS
, m_winPressed
);
907 else if ( consumer
->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER
)
909 wxTopLevelWindow
*win
= wxStaticCast(consumer
->GetInputWindow(),
911 long hit
= win
->HitTest(event
.GetPosition());
913 if ( hit
!= m_winHitTest
)
917 if ( m_borderCursorOn
)
919 m_borderCursorOn
= false;
920 win
->SetCursor(m_origCursor
);
923 if ( hit
& wxHT_TOPLEVEL_ANY_BORDER
)
927 m_borderCursorOn
= wxGetResizingCursor(hit
, cur
);
928 if ( m_borderCursorOn
)
930 m_origCursor
= win
->GetCursor();
937 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
940 bool wxStdTLWInputHandler::HandleActivation(wxInputConsumer
*consumer
,
943 if ( m_borderCursorOn
)
945 consumer
->GetInputWindow()->SetCursor(m_origCursor
);
946 m_borderCursorOn
= false;
948 consumer
->PerformAction(wxACTION_TOPLEVEL_ACTIVATE
, activated
);