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"
25 #include "wx/dcclient.h"
26 #include "wx/settings.h"
29 #include "wx/toplevel.h"
30 #include "wx/univ/renderer.h"
31 #include "wx/bitmap.h"
33 #include "wx/cshelp.h"
34 #include "wx/evtloop.h"
37 // ----------------------------------------------------------------------------
39 // ----------------------------------------------------------------------------
41 BEGIN_EVENT_TABLE(wxTopLevelWindow
, wxTopLevelWindowNative
)
42 WX_EVENT_TABLE_INPUT_CONSUMER(wxTopLevelWindow
)
43 EVT_NC_PAINT(wxTopLevelWindow::OnNcPaint
)
44 EVT_MENU_RANGE(wxID_CLOSE_FRAME
, wxID_RESTORE_FRAME
, wxTopLevelWindow::OnSystemMenu
)
47 WX_FORWARD_TO_INPUT_CONSUMER(wxTopLevelWindow
)
49 // ============================================================================
51 // ============================================================================
53 int wxTopLevelWindow::ms_drawDecorations
= -1;
54 int wxTopLevelWindow::ms_canIconize
= -1;
56 void wxTopLevelWindow::Init()
63 bool wxTopLevelWindow::Create(wxWindow
*parent
,
65 const wxString
& title
,
71 // init them to avoid compiler warnings
75 if ( ms_drawDecorations
== -1 )
78 !wxSystemSettings::HasFeature(wxSYS_CAN_DRAW_FRAME_DECORATIONS
)
79 || wxGetEnv(wxT("WXDECOR"), NULL
);
80 // FIXME -- wxUniv should provide a way to force non-native decorations!
81 // $WXDECOR is just a hack in absence of better wxUniv solution
84 if ( ms_canIconize
== -1 )
86 ms_canIconize
= wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
);
89 if ( ms_drawDecorations
)
91 CreateInputHandler(wxINP_HANDLER_TOPLEVEL
);
94 exstyleOrig
= GetExtraStyle();
95 style
&= ~(wxCAPTION
| wxMINIMIZE_BOX
| wxMAXIMIZE_BOX
|
96 wxSYSTEM_MENU
| wxRESIZE_BORDER
| wxFRAME_TOOL_WINDOW
|
98 style
|= wxSIMPLE_BORDER
;
99 SetExtraStyle(exstyleOrig
&
100 ~(wxFRAME_EX_CONTEXTHELP
| wxDIALOG_EX_CONTEXTHELP
));
103 if ( !wxTopLevelWindowNative::Create(parent
, id
, title
, pos
,
107 if ( ms_drawDecorations
)
109 m_windowStyle
= styleOrig
;
110 m_exStyle
= exstyleOrig
;
116 bool wxTopLevelWindow::ShowFullScreen(bool show
, long style
)
118 if ( show
== IsFullScreen() ) return false;
120 if ( ms_drawDecorations
)
124 m_fsSavedStyle
= m_windowStyle
;
125 if ( style
& wxFULLSCREEN_NOBORDER
)
126 m_windowStyle
|= wxSIMPLE_BORDER
;
127 if ( style
& wxFULLSCREEN_NOCAPTION
)
128 m_windowStyle
&= ~wxCAPTION
;
132 m_windowStyle
= m_fsSavedStyle
;
136 return wxTopLevelWindowNative::ShowFullScreen(show
, style
);
139 long wxTopLevelWindow::GetDecorationsStyle() const
143 if ( m_windowStyle
& wxCAPTION
)
145 style
|= wxTOPLEVEL_TITLEBAR
| wxTOPLEVEL_BUTTON_CLOSE
;
146 if ( (m_windowStyle
& wxMINIMIZE_BOX
) && ms_canIconize
)
147 style
|= wxTOPLEVEL_BUTTON_ICONIZE
;
148 if ( m_windowStyle
& wxMAXIMIZE_BOX
)
151 style
|= wxTOPLEVEL_BUTTON_RESTORE
;
153 style
|= wxTOPLEVEL_BUTTON_MAXIMIZE
;
156 if ( m_exStyle
& (wxFRAME_EX_CONTEXTHELP
| wxDIALOG_EX_CONTEXTHELP
))
157 style
|= wxTOPLEVEL_BUTTON_HELP
;
160 if ( (m_windowStyle
& (wxSIMPLE_BORDER
| wxNO_BORDER
)) == 0 )
161 style
|= wxTOPLEVEL_BORDER
;
162 if ( m_windowStyle
& (wxRESIZE_BORDER
| wxRESIZE_BORDER
) )
163 style
|= wxTOPLEVEL_RESIZEABLE
;
166 style
|= wxTOPLEVEL_MAXIMIZED
;
167 if ( GetIcon().Ok() )
168 style
|= wxTOPLEVEL_ICON
;
170 style
|= wxTOPLEVEL_ACTIVE
;
175 void wxTopLevelWindow::RefreshTitleBar()
177 wxNcPaintEvent
event(GetId());
178 event
.SetEventObject(this);
179 GetEventHandler()->ProcessEvent(event
);
182 // ----------------------------------------------------------------------------
183 // client area handling
184 // ----------------------------------------------------------------------------
186 wxPoint
wxTopLevelWindow::GetClientAreaOrigin() const
188 if ( ms_drawDecorations
)
191 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
192 wxRect rect
= wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
194 rect
= m_renderer
->GetFrameClientArea(rect
,
195 GetDecorationsStyle());
196 return rect
.GetPosition();
200 return wxTopLevelWindowNative::GetClientAreaOrigin();
204 void wxTopLevelWindow::DoGetClientSize(int *width
, int *height
) const
206 if ( ms_drawDecorations
)
209 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
210 wxRect rect
= wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
212 rect
= m_renderer
->GetFrameClientArea(rect
,
213 GetDecorationsStyle());
217 *height
= rect
.height
;
220 wxTopLevelWindowNative::DoGetClientSize(width
, height
);
223 void wxTopLevelWindow::DoSetClientSize(int width
, int height
)
225 if ( ms_drawDecorations
)
227 wxSize size
= m_renderer
->GetFrameTotalSize(wxSize(width
, height
),
228 GetDecorationsStyle());
229 wxTopLevelWindowNative::DoSetClientSize(size
.x
, size
.y
);
232 wxTopLevelWindowNative::DoSetClientSize(width
, height
);
235 void wxTopLevelWindow::OnNcPaint(wxNcPaintEvent
& event
)
237 if ( !ms_drawDecorations
|| !m_renderer
)
241 // get the window rect
243 wxSize size
= GetSize();
247 rect
.height
= size
.y
;
250 m_renderer
->DrawFrameTitleBar(dc
, rect
,
251 GetTitle(), m_titlebarIcon
,
252 GetDecorationsStyle(),
258 long wxTopLevelWindow::HitTest(const wxPoint
& pt
) const
261 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
262 wxRect
rect(wxTopLevelWindowNative::GetClientAreaOrigin(), wxSize(w
, h
));
264 return m_renderer
->HitTestFrame(rect
, pt
+GetClientAreaOrigin(), GetDecorationsStyle());
267 int wxTopLevelWindow::GetMinWidth() const
269 if ( ms_drawDecorations
)
271 return wxMax(wxTopLevelWindowNative::GetMinWidth(),
272 m_renderer
->GetFrameMinSize(GetDecorationsStyle()).x
);
275 return wxTopLevelWindowNative::GetMinWidth();
278 int wxTopLevelWindow::GetMinHeight() const
280 if ( ms_drawDecorations
)
282 return wxMax(wxTopLevelWindowNative::GetMinHeight(),
283 m_renderer
->GetFrameMinSize(GetDecorationsStyle()).y
);
286 return wxTopLevelWindowNative::GetMinHeight();
289 // ----------------------------------------------------------------------------
291 // ----------------------------------------------------------------------------
293 void wxTopLevelWindow::SetIcons(const wxIconBundle
& icons
)
295 wxTopLevelWindowNative::SetIcons(icons
);
297 if ( ms_drawDecorations
&& m_renderer
)
299 wxSize size
= m_renderer
->GetFrameIconSize();
300 const wxIcon
& icon
= icons
.GetIcon( size
);
302 if ( !icon
.Ok() || size
.x
== wxDefaultCoord
)
303 m_titlebarIcon
= icon
;
307 bmp1
.CopyFromIcon(icon
);
309 m_titlebarIcon
= wxNullIcon
;
310 else if ( bmp1
.GetWidth() == size
.x
&& bmp1
.GetHeight() == size
.y
)
311 m_titlebarIcon
= icon
;
314 wxImage img
= bmp1
.ConvertToImage();
315 img
.Rescale(size
.x
, size
.y
);
316 m_titlebarIcon
.CopyFromBitmap(wxBitmap(img
));
322 // ----------------------------------------------------------------------------
323 // interactive manipulation
324 // ----------------------------------------------------------------------------
327 static bool wxGetResizingCursor(long hitTestResult
, wxCursor
& cursor
)
329 if ( hitTestResult
& wxHT_TOPLEVEL_ANY_BORDER
)
331 switch (hitTestResult
)
333 case wxHT_TOPLEVEL_BORDER_N
:
334 case wxHT_TOPLEVEL_BORDER_S
:
335 cursor
= wxCursor(wxCURSOR_SIZENS
);
337 case wxHT_TOPLEVEL_BORDER_W
:
338 case wxHT_TOPLEVEL_BORDER_E
:
339 cursor
= wxCursor(wxCURSOR_SIZEWE
);
341 case wxHT_TOPLEVEL_BORDER_NE
:
342 case wxHT_TOPLEVEL_BORDER_SW
:
343 cursor
= wxCursor(wxCURSOR_SIZENESW
);
345 case wxHT_TOPLEVEL_BORDER_NW
:
346 case wxHT_TOPLEVEL_BORDER_SE
:
347 cursor
= wxCursor(wxCURSOR_SIZENWSE
);
358 #define wxINTERACTIVE_RESIZE_DIR \
359 (wxINTERACTIVE_RESIZE_W | wxINTERACTIVE_RESIZE_E | \
360 wxINTERACTIVE_RESIZE_S | wxINTERACTIVE_RESIZE_N)
362 struct wxInteractiveMoveData
364 wxTopLevelWindow
*m_window
;
365 wxEventLoop
*m_evtLoop
;
370 wxSize m_minSize
, m_maxSize
;
374 class wxInteractiveMoveHandler
: public wxEvtHandler
377 wxInteractiveMoveHandler(wxInteractiveMoveData
& data
) : m_data(data
) {}
380 DECLARE_EVENT_TABLE()
381 void OnMouseMove(wxMouseEvent
& event
);
382 void OnMouseDown(wxMouseEvent
& event
);
383 void OnMouseUp(wxMouseEvent
& event
);
384 void OnKeyDown(wxKeyEvent
& event
);
386 wxInteractiveMoveData
& m_data
;
389 BEGIN_EVENT_TABLE(wxInteractiveMoveHandler
, wxEvtHandler
)
390 EVT_MOTION(wxInteractiveMoveHandler::OnMouseMove
)
391 EVT_LEFT_DOWN(wxInteractiveMoveHandler::OnMouseDown
)
392 EVT_LEFT_UP(wxInteractiveMoveHandler::OnMouseUp
)
393 EVT_KEY_DOWN(wxInteractiveMoveHandler::OnKeyDown
)
397 static inline LINKAGEMODE
398 void wxApplyResize(wxInteractiveMoveData
& data
, const wxPoint
& diff
)
400 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
402 data
.m_rect
.x
+= diff
.x
;
403 data
.m_rect
.width
-= diff
.x
;
405 else if ( data
.m_flags
& wxINTERACTIVE_RESIZE_E
)
407 data
.m_rect
.width
+= diff
.x
;
409 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
411 data
.m_rect
.y
+= diff
.y
;
412 data
.m_rect
.height
-= diff
.y
;
414 else if ( data
.m_flags
& wxINTERACTIVE_RESIZE_S
)
416 data
.m_rect
.height
+= diff
.y
;
419 if ( data
.m_minSize
.x
!= wxDefaultCoord
&& data
.m_rect
.width
< data
.m_minSize
.x
)
421 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
422 data
.m_rect
.x
-= data
.m_minSize
.x
- data
.m_rect
.width
;
423 data
.m_rect
.width
= data
.m_minSize
.x
;
425 if ( data
.m_maxSize
.x
!= wxDefaultCoord
&& data
.m_rect
.width
> data
.m_maxSize
.x
)
427 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
428 data
.m_rect
.x
-= data
.m_minSize
.x
- data
.m_rect
.width
;
429 data
.m_rect
.width
= data
.m_maxSize
.x
;
431 if ( data
.m_minSize
.y
!= wxDefaultCoord
&& data
.m_rect
.height
< data
.m_minSize
.y
)
433 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
434 data
.m_rect
.y
-= data
.m_minSize
.y
- data
.m_rect
.height
;
435 data
.m_rect
.height
= data
.m_minSize
.y
;
437 if ( data
.m_maxSize
.y
!= wxDefaultCoord
&& data
.m_rect
.height
> data
.m_maxSize
.y
)
439 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
440 data
.m_rect
.y
-= data
.m_minSize
.y
- data
.m_rect
.height
;
441 data
.m_rect
.height
= data
.m_maxSize
.y
;
445 void wxInteractiveMoveHandler::OnMouseMove(wxMouseEvent
& event
)
447 if ( m_data
.m_flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
450 else if ( m_data
.m_flags
& wxINTERACTIVE_MOVE
)
452 wxPoint diff
= wxGetMousePosition() - m_data
.m_pos
;
453 m_data
.m_rect
= m_data
.m_rectOrig
;
454 m_data
.m_rect
.Offset(diff
);
455 m_data
.m_window
->Move(m_data
.m_rect
.GetPosition());
458 else if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE
)
460 wxPoint diff
= wxGetMousePosition() - m_data
.m_pos
;
461 m_data
.m_rect
= m_data
.m_rectOrig
;
462 wxApplyResize(m_data
, diff
);
463 m_data
.m_window
->SetSize(m_data
.m_rect
);
467 void wxInteractiveMoveHandler::OnMouseDown(wxMouseEvent
& WXUNUSED(event
))
469 if ( m_data
.m_flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
471 m_data
.m_evtLoop
->Exit();
475 void wxInteractiveMoveHandler::OnKeyDown(wxKeyEvent
& event
)
477 wxPoint
diff(wxDefaultCoord
,wxDefaultCoord
);
479 switch ( event
.GetKeyCode() )
481 case WXK_UP
: diff
= wxPoint(0, -16); break;
482 case WXK_DOWN
: diff
= wxPoint(0, 16); break;
483 case WXK_LEFT
: diff
= wxPoint(-16, 0); break;
484 case WXK_RIGHT
: diff
= wxPoint(16, 0); break;
486 m_data
.m_window
->SetSize(m_data
.m_rectOrig
);
487 m_data
.m_evtLoop
->Exit();
490 m_data
.m_evtLoop
->Exit();
494 if ( diff
.x
!= wxDefaultCoord
)
496 if ( m_data
.m_flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
498 m_data
.m_flags
&= ~wxINTERACTIVE_WAIT_FOR_INPUT
;
499 if ( m_data
.m_sizingCursor
)
502 m_data
.m_sizingCursor
= false;
505 if ( m_data
.m_flags
& wxINTERACTIVE_MOVE
)
507 m_data
.m_pos
= m_data
.m_window
->GetPosition() +
508 wxPoint(m_data
.m_window
->GetSize().x
/2, 8);
513 bool changeCur
= false;
515 if ( m_data
.m_flags
& wxINTERACTIVE_MOVE
)
517 m_data
.m_rect
.Offset(diff
);
518 m_data
.m_window
->Move(m_data
.m_rect
.GetPosition());
519 warp
= wxPoint(m_data
.m_window
->GetSize().x
/2, 8);
521 else /* wxINTERACTIVE_RESIZE */
523 if ( !(m_data
.m_flags
&
524 (wxINTERACTIVE_RESIZE_N
| wxINTERACTIVE_RESIZE_S
)) )
528 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_N
;
529 m_data
.m_pos
.y
= m_data
.m_window
->GetPosition().y
;
532 else if ( diff
.y
> 0 )
534 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_S
;
535 m_data
.m_pos
.y
= m_data
.m_window
->GetPosition().y
+
536 m_data
.m_window
->GetSize().y
;
540 if ( !(m_data
.m_flags
&
541 (wxINTERACTIVE_RESIZE_W
| wxINTERACTIVE_RESIZE_E
)) )
545 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_W
;
546 m_data
.m_pos
.x
= m_data
.m_window
->GetPosition().x
;
549 else if ( diff
.x
> 0 )
551 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_E
;
552 m_data
.m_pos
.x
= m_data
.m_window
->GetPosition().x
+
553 m_data
.m_window
->GetSize().x
;
558 wxApplyResize(m_data
, diff
);
559 m_data
.m_window
->SetSize(m_data
.m_rect
);
561 if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
563 else if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_E
)
564 warp
.x
= m_data
.m_window
->GetSize().x
-1;
566 warp
.x
= wxGetMousePosition().x
- m_data
.m_window
->GetPosition().x
;
568 if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
570 else if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_S
)
571 warp
.y
= m_data
.m_window
->GetSize().y
-1;
573 warp
.y
= wxGetMousePosition().y
- m_data
.m_window
->GetPosition().y
;
576 warp
-= m_data
.m_window
->GetClientAreaOrigin();
577 m_data
.m_window
->WarpPointer(warp
.x
, warp
.y
);
581 long hit
= m_data
.m_window
->HitTest(warp
);
583 if ( wxGetResizingCursor(hit
, cur
) )
585 if ( m_data
.m_sizingCursor
)
587 wxBeginBusyCursor(&cur
);
588 m_data
.m_sizingCursor
= true;
594 void wxInteractiveMoveHandler::OnMouseUp(wxMouseEvent
& WXUNUSED(event
))
596 m_data
.m_evtLoop
->Exit();
600 void wxTopLevelWindow::InteractiveMove(int flags
)
602 wxASSERT_MSG( !((flags
& wxINTERACTIVE_MOVE
) && (flags
& wxINTERACTIVE_RESIZE
)),
603 wxT("can't move and resize window at the same time") );
605 wxASSERT_MSG( !(flags
& wxINTERACTIVE_RESIZE
) ||
606 (flags
& wxINTERACTIVE_WAIT_FOR_INPUT
) ||
607 (flags
& wxINTERACTIVE_RESIZE_DIR
),
608 wxT("direction of resizing not specified") );
610 wxInteractiveMoveData data
;
616 if ( flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
618 wxCursor
sizingCursor(wxCURSOR_SIZING
);
619 wxBeginBusyCursor(&sizingCursor
);
620 data
.m_sizingCursor
= true;
624 data
.m_sizingCursor
= false;
626 data
.m_window
= this;
627 data
.m_evtLoop
= &loop
;
628 data
.m_flags
= flags
;
629 data
.m_rect
= data
.m_rectOrig
= GetRect();
630 data
.m_pos
= wxGetMousePosition();
631 data
.m_minSize
= wxSize(GetMinWidth(), GetMinHeight());
632 data
.m_maxSize
= wxSize(GetMaxWidth(), GetMaxHeight());
634 wxEvtHandler
*handler
= new wxInteractiveMoveHandler(data
);
635 this->PushEventHandler(handler
);
641 this->RemoveEventHandler(handler
);
644 if ( data
.m_sizingCursor
)
648 // ----------------------------------------------------------------------------
650 // ----------------------------------------------------------------------------
652 void wxTopLevelWindow::ClickTitleBarButton(long button
)
656 case wxTOPLEVEL_BUTTON_CLOSE
:
660 case wxTOPLEVEL_BUTTON_ICONIZE
:
664 case wxTOPLEVEL_BUTTON_MAXIMIZE
:
668 case wxTOPLEVEL_BUTTON_RESTORE
:
672 case wxTOPLEVEL_BUTTON_HELP
:
675 wxContextHelp
contextHelp(this);
681 wxFAIL_MSG(wxT("incorrect button specification"));
685 bool wxTopLevelWindow::PerformAction(const wxControlAction
& action
,
687 const wxString
& WXUNUSED(strArg
))
689 bool isActive
= numArg
!= 0;
691 if ( action
== wxACTION_TOPLEVEL_ACTIVATE
)
693 if ( m_isActive
!= isActive
)
695 m_isActive
= isActive
;
701 else if ( action
== wxACTION_TOPLEVEL_BUTTON_PRESS
)
703 m_pressedButton
= numArg
;
708 else if ( action
== wxACTION_TOPLEVEL_BUTTON_RELEASE
)
715 else if ( action
== wxACTION_TOPLEVEL_BUTTON_CLICK
)
719 ClickTitleBarButton(numArg
);
723 else if ( action
== wxACTION_TOPLEVEL_MOVE
)
725 InteractiveMove(wxINTERACTIVE_MOVE
);
729 else if ( action
== wxACTION_TOPLEVEL_RESIZE
)
731 int flags
= wxINTERACTIVE_RESIZE
;
732 if ( numArg
& wxHT_TOPLEVEL_BORDER_N
)
733 flags
|= wxINTERACTIVE_RESIZE_N
;
734 if ( numArg
& wxHT_TOPLEVEL_BORDER_S
)
735 flags
|= wxINTERACTIVE_RESIZE_S
;
736 if ( numArg
& wxHT_TOPLEVEL_BORDER_W
)
737 flags
|= wxINTERACTIVE_RESIZE_W
;
738 if ( numArg
& wxHT_TOPLEVEL_BORDER_E
)
739 flags
|= wxINTERACTIVE_RESIZE_E
;
740 InteractiveMove(flags
);
748 void wxTopLevelWindow::OnSystemMenu(wxCommandEvent
& event
)
752 switch (event
.GetId())
754 case wxID_CLOSE_FRAME
:
755 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
756 wxTOPLEVEL_BUTTON_CLOSE
);
758 case wxID_MOVE_FRAME
:
759 InteractiveMove(wxINTERACTIVE_MOVE
| wxINTERACTIVE_WAIT_FOR_INPUT
);
761 case wxID_RESIZE_FRAME
:
762 InteractiveMove(wxINTERACTIVE_RESIZE
| wxINTERACTIVE_WAIT_FOR_INPUT
);
764 case wxID_MAXIMIZE_FRAME
:
765 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
766 wxTOPLEVEL_BUTTON_MAXIMIZE
);
768 case wxID_ICONIZE_FRAME
:
769 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
770 wxTOPLEVEL_BUTTON_ICONIZE
);
772 case wxID_RESTORE_FRAME
:
773 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
774 wxTOPLEVEL_BUTTON_RESTORE
);
786 // ============================================================================
787 // wxStdFrameInputHandler: handles focus, resizing and titlebar buttons clicks
788 // ============================================================================
790 wxStdFrameInputHandler::wxStdFrameInputHandler(wxInputHandler
*inphand
)
791 : wxStdInputHandler(inphand
)
796 m_borderCursorOn
= false;
799 bool wxStdFrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
800 const wxMouseEvent
& event
)
802 // the button has 2 states: pressed and normal with the following
803 // transitions between them:
805 // normal -> left down -> capture mouse and go to pressed state
806 // pressed -> left up inside -> generate click -> go to normal
807 // outside ------------------>
809 // the other mouse buttons are ignored
810 if ( event
.Button(1) )
812 if ( event
.ButtonDown(1) )
814 wxTopLevelWindow
*w
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
815 long hit
= w
->HitTest(event
.GetPosition());
817 if ( hit
& wxHT_TOPLEVEL_ANY_BUTTON
)
820 m_winCapture
->CaptureMouse();
823 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS
, m_winPressed
);
826 else if ( (hit
& wxHT_TOPLEVEL_TITLEBAR
) && !w
->IsMaximized() )
828 consumer
->PerformAction(wxACTION_TOPLEVEL_MOVE
);
831 else if ( (consumer
->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER
)
832 && (hit
& wxHT_TOPLEVEL_ANY_BORDER
) )
834 consumer
->PerformAction(wxACTION_TOPLEVEL_RESIZE
, hit
);
843 m_winCapture
->ReleaseMouse();
846 if ( m_winHitTest
== m_winPressed
)
848 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
, m_winPressed
);
852 //else: the mouse was released outside the window, this doesn't
857 return wxStdInputHandler::HandleMouse(consumer
, event
);
860 bool wxStdFrameInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
861 const wxMouseEvent
& event
)
863 if ( event
.GetEventObject() == m_winCapture
)
865 long hit
= m_winCapture
->HitTest(event
.GetPosition());
867 if ( hit
!= m_winHitTest
)
869 if ( hit
!= m_winPressed
)
870 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_RELEASE
, m_winPressed
);
872 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS
, m_winPressed
);
878 else if ( consumer
->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER
)
880 wxTopLevelWindow
*win
= wxStaticCast(consumer
->GetInputWindow(),
882 long hit
= win
->HitTest(event
.GetPosition());
884 if ( hit
!= m_winHitTest
)
888 if ( m_borderCursorOn
)
890 m_borderCursorOn
= false;
891 win
->SetCursor(m_origCursor
);
894 if ( hit
& wxHT_TOPLEVEL_ANY_BORDER
)
898 m_borderCursorOn
= wxGetResizingCursor(hit
, cur
);
899 if ( m_borderCursorOn
)
901 m_origCursor
= win
->GetCursor();
908 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
911 bool wxStdFrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
914 if ( m_borderCursorOn
)
916 consumer
->GetInputWindow()->SetCursor(m_origCursor
);
917 m_borderCursorOn
= false;
919 consumer
->PerformAction(wxACTION_TOPLEVEL_ACTIVATE
, activated
);