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"
32 #include "wx/univ/renderer.h"
34 #include "wx/cshelp.h"
35 #include "wx/evtloop.h"
38 // ----------------------------------------------------------------------------
40 // ----------------------------------------------------------------------------
42 BEGIN_EVENT_TABLE(wxTopLevelWindow
, wxTopLevelWindowNative
)
43 WX_EVENT_TABLE_INPUT_CONSUMER(wxTopLevelWindow
)
44 EVT_NC_PAINT(wxTopLevelWindow::OnNcPaint
)
45 EVT_MENU_RANGE(wxID_CLOSE_FRAME
, wxID_RESTORE_FRAME
, wxTopLevelWindow::OnSystemMenu
)
48 WX_FORWARD_TO_INPUT_CONSUMER(wxTopLevelWindow
)
50 // ============================================================================
52 // ============================================================================
54 int wxTopLevelWindow::ms_drawDecorations
= -1;
55 int wxTopLevelWindow::ms_canIconize
= -1;
57 void wxTopLevelWindow::Init()
64 bool wxTopLevelWindow::Create(wxWindow
*parent
,
66 const wxString
& title
,
72 // init them to avoid compiler warnings
76 if ( ms_drawDecorations
== -1 )
79 !wxSystemSettings::HasFeature(wxSYS_CAN_DRAW_FRAME_DECORATIONS
)
80 || wxGetEnv(wxT("WXDECOR"), NULL
);
81 // FIXME -- wxUniv should provide a way to force non-native decorations!
82 // $WXDECOR is just a hack in absence of better wxUniv solution
85 if ( ms_canIconize
== -1 )
87 ms_canIconize
= wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME
);
90 if ( ms_drawDecorations
)
92 CreateInputHandler(wxINP_HANDLER_TOPLEVEL
);
95 exstyleOrig
= GetExtraStyle();
96 style
&= ~(wxCAPTION
| wxMINIMIZE_BOX
| wxMAXIMIZE_BOX
|
97 wxSYSTEM_MENU
| wxRESIZE_BORDER
| wxFRAME_TOOL_WINDOW
|
99 style
|= wxSIMPLE_BORDER
;
100 SetExtraStyle(exstyleOrig
&
101 ~(wxFRAME_EX_CONTEXTHELP
| wxDIALOG_EX_CONTEXTHELP
));
104 if ( !wxTopLevelWindowNative::Create(parent
, id
, title
, pos
,
108 if ( ms_drawDecorations
)
110 m_windowStyle
= styleOrig
;
111 m_exStyle
= exstyleOrig
;
117 bool wxTopLevelWindow::ShowFullScreen(bool show
, long style
)
119 if ( show
== IsFullScreen() ) return false;
121 if ( ms_drawDecorations
)
125 m_fsSavedStyle
= m_windowStyle
;
126 if ( style
& wxFULLSCREEN_NOBORDER
)
127 m_windowStyle
|= wxSIMPLE_BORDER
;
128 if ( style
& wxFULLSCREEN_NOCAPTION
)
129 m_windowStyle
&= ~wxCAPTION
;
133 m_windowStyle
= m_fsSavedStyle
;
137 return wxTopLevelWindowNative::ShowFullScreen(show
, style
);
140 long wxTopLevelWindow::GetDecorationsStyle() const
144 if ( m_windowStyle
& wxCAPTION
)
146 style
|= wxTOPLEVEL_TITLEBAR
| wxTOPLEVEL_BUTTON_CLOSE
;
147 if ( (m_windowStyle
& wxMINIMIZE_BOX
) && ms_canIconize
)
148 style
|= wxTOPLEVEL_BUTTON_ICONIZE
;
149 if ( m_windowStyle
& wxMAXIMIZE_BOX
)
152 style
|= wxTOPLEVEL_BUTTON_RESTORE
;
154 style
|= wxTOPLEVEL_BUTTON_MAXIMIZE
;
157 if ( m_exStyle
& (wxFRAME_EX_CONTEXTHELP
| wxDIALOG_EX_CONTEXTHELP
))
158 style
|= wxTOPLEVEL_BUTTON_HELP
;
161 if ( (m_windowStyle
& (wxSIMPLE_BORDER
| wxNO_BORDER
)) == 0 )
162 style
|= wxTOPLEVEL_BORDER
;
163 if ( m_windowStyle
& (wxRESIZE_BORDER
| wxRESIZE_BORDER
) )
164 style
|= wxTOPLEVEL_RESIZEABLE
;
167 style
|= wxTOPLEVEL_MAXIMIZED
;
168 if ( GetIcon().Ok() )
169 style
|= wxTOPLEVEL_ICON
;
171 style
|= wxTOPLEVEL_ACTIVE
;
176 void wxTopLevelWindow::RefreshTitleBar()
178 wxNcPaintEvent
event(GetId());
179 event
.SetEventObject(this);
180 GetEventHandler()->ProcessEvent(event
);
183 // ----------------------------------------------------------------------------
184 // client area handling
185 // ----------------------------------------------------------------------------
187 wxPoint
wxTopLevelWindow::GetClientAreaOrigin() const
189 if ( ms_drawDecorations
)
192 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
193 wxRect rect
= wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
195 rect
= m_renderer
->GetFrameClientArea(rect
,
196 GetDecorationsStyle());
197 return rect
.GetPosition();
201 return wxTopLevelWindowNative::GetClientAreaOrigin();
205 void wxTopLevelWindow::DoGetClientSize(int *width
, int *height
) const
207 if ( ms_drawDecorations
)
210 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
211 wxRect rect
= wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(),
213 rect
= m_renderer
->GetFrameClientArea(rect
,
214 GetDecorationsStyle());
218 *height
= rect
.height
;
221 wxTopLevelWindowNative::DoGetClientSize(width
, height
);
224 void wxTopLevelWindow::DoSetClientSize(int width
, int height
)
226 if ( ms_drawDecorations
)
228 wxSize size
= m_renderer
->GetFrameTotalSize(wxSize(width
, height
),
229 GetDecorationsStyle());
230 wxTopLevelWindowNative::DoSetClientSize(size
.x
, size
.y
);
233 wxTopLevelWindowNative::DoSetClientSize(width
, height
);
236 void wxTopLevelWindow::OnNcPaint(wxNcPaintEvent
& event
)
238 if ( !ms_drawDecorations
|| !m_renderer
)
242 // get the window rect
243 wxRect
rect(GetSize());
246 m_renderer
->DrawFrameTitleBar(dc
, rect
,
247 GetTitle(), m_titlebarIcon
,
248 GetDecorationsStyle(),
254 long wxTopLevelWindow::HitTest(const wxPoint
& pt
) const
257 wxTopLevelWindowNative::DoGetClientSize(&w
, &h
);
258 wxRect
rect(wxTopLevelWindowNative::GetClientAreaOrigin(), wxSize(w
, h
));
260 return m_renderer
->HitTestFrame(rect
, pt
+GetClientAreaOrigin(), GetDecorationsStyle());
263 int wxTopLevelWindow::GetMinWidth() const
265 if ( ms_drawDecorations
)
267 return wxMax(wxTopLevelWindowNative::GetMinWidth(),
268 m_renderer
->GetFrameMinSize(GetDecorationsStyle()).x
);
271 return wxTopLevelWindowNative::GetMinWidth();
274 int wxTopLevelWindow::GetMinHeight() const
276 if ( ms_drawDecorations
)
278 return wxMax(wxTopLevelWindowNative::GetMinHeight(),
279 m_renderer
->GetFrameMinSize(GetDecorationsStyle()).y
);
282 return wxTopLevelWindowNative::GetMinHeight();
285 // ----------------------------------------------------------------------------
287 // ----------------------------------------------------------------------------
289 void wxTopLevelWindow::SetIcons(const wxIconBundle
& icons
)
291 wxTopLevelWindowNative::SetIcons(icons
);
293 if ( ms_drawDecorations
&& m_renderer
)
295 wxSize size
= m_renderer
->GetFrameIconSize();
296 const wxIcon
& icon
= icons
.GetIcon( size
);
298 if ( !icon
.Ok() || size
.x
== wxDefaultCoord
)
299 m_titlebarIcon
= icon
;
303 bmp1
.CopyFromIcon(icon
);
305 m_titlebarIcon
= wxNullIcon
;
306 else if ( bmp1
.GetWidth() == size
.x
&& bmp1
.GetHeight() == size
.y
)
307 m_titlebarIcon
= icon
;
311 wxImage img
= bmp1
.ConvertToImage();
312 img
.Rescale(size
.x
, size
.y
);
313 m_titlebarIcon
.CopyFromBitmap(wxBitmap(img
));
315 #endif // wxUSE_IMAGE
320 // ----------------------------------------------------------------------------
321 // interactive manipulation
322 // ----------------------------------------------------------------------------
325 static bool wxGetResizingCursor(long hitTestResult
, wxCursor
& cursor
)
327 if ( hitTestResult
& wxHT_TOPLEVEL_ANY_BORDER
)
329 switch (hitTestResult
)
331 case wxHT_TOPLEVEL_BORDER_N
:
332 case wxHT_TOPLEVEL_BORDER_S
:
333 cursor
= wxCursor(wxCURSOR_SIZENS
);
335 case wxHT_TOPLEVEL_BORDER_W
:
336 case wxHT_TOPLEVEL_BORDER_E
:
337 cursor
= wxCursor(wxCURSOR_SIZEWE
);
339 case wxHT_TOPLEVEL_BORDER_NE
:
340 case wxHT_TOPLEVEL_BORDER_SW
:
341 cursor
= wxCursor(wxCURSOR_SIZENESW
);
343 case wxHT_TOPLEVEL_BORDER_NW
:
344 case wxHT_TOPLEVEL_BORDER_SE
:
345 cursor
= wxCursor(wxCURSOR_SIZENWSE
);
356 #define wxINTERACTIVE_RESIZE_DIR \
357 (wxINTERACTIVE_RESIZE_W | wxINTERACTIVE_RESIZE_E | \
358 wxINTERACTIVE_RESIZE_S | wxINTERACTIVE_RESIZE_N)
360 struct wxInteractiveMoveData
362 wxTopLevelWindow
*m_window
;
363 wxEventLoop
*m_evtLoop
;
368 wxSize m_minSize
, m_maxSize
;
372 class wxInteractiveMoveHandler
: public wxEvtHandler
375 wxInteractiveMoveHandler(wxInteractiveMoveData
& data
) : m_data(data
) {}
378 DECLARE_EVENT_TABLE()
379 void OnMouseMove(wxMouseEvent
& event
);
380 void OnMouseDown(wxMouseEvent
& event
);
381 void OnMouseUp(wxMouseEvent
& event
);
382 void OnKeyDown(wxKeyEvent
& event
);
384 wxInteractiveMoveData
& m_data
;
387 BEGIN_EVENT_TABLE(wxInteractiveMoveHandler
, wxEvtHandler
)
388 EVT_MOTION(wxInteractiveMoveHandler::OnMouseMove
)
389 EVT_LEFT_DOWN(wxInteractiveMoveHandler::OnMouseDown
)
390 EVT_LEFT_UP(wxInteractiveMoveHandler::OnMouseUp
)
391 EVT_KEY_DOWN(wxInteractiveMoveHandler::OnKeyDown
)
395 static inline LINKAGEMODE
396 void wxApplyResize(wxInteractiveMoveData
& data
, const wxPoint
& diff
)
398 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
400 data
.m_rect
.x
+= diff
.x
;
401 data
.m_rect
.width
-= diff
.x
;
403 else if ( data
.m_flags
& wxINTERACTIVE_RESIZE_E
)
405 data
.m_rect
.width
+= diff
.x
;
407 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
409 data
.m_rect
.y
+= diff
.y
;
410 data
.m_rect
.height
-= diff
.y
;
412 else if ( data
.m_flags
& wxINTERACTIVE_RESIZE_S
)
414 data
.m_rect
.height
+= diff
.y
;
417 if ( data
.m_minSize
.x
!= wxDefaultCoord
&& data
.m_rect
.width
< data
.m_minSize
.x
)
419 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
420 data
.m_rect
.x
-= data
.m_minSize
.x
- data
.m_rect
.width
;
421 data
.m_rect
.width
= data
.m_minSize
.x
;
423 if ( data
.m_maxSize
.x
!= wxDefaultCoord
&& data
.m_rect
.width
> data
.m_maxSize
.x
)
425 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
426 data
.m_rect
.x
-= data
.m_minSize
.x
- data
.m_rect
.width
;
427 data
.m_rect
.width
= data
.m_maxSize
.x
;
429 if ( data
.m_minSize
.y
!= wxDefaultCoord
&& data
.m_rect
.height
< data
.m_minSize
.y
)
431 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
432 data
.m_rect
.y
-= data
.m_minSize
.y
- data
.m_rect
.height
;
433 data
.m_rect
.height
= data
.m_minSize
.y
;
435 if ( data
.m_maxSize
.y
!= wxDefaultCoord
&& data
.m_rect
.height
> data
.m_maxSize
.y
)
437 if ( data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
438 data
.m_rect
.y
-= data
.m_minSize
.y
- data
.m_rect
.height
;
439 data
.m_rect
.height
= data
.m_maxSize
.y
;
443 void wxInteractiveMoveHandler::OnMouseMove(wxMouseEvent
& event
)
445 if ( m_data
.m_flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
448 else if ( m_data
.m_flags
& wxINTERACTIVE_MOVE
)
450 wxPoint diff
= wxGetMousePosition() - m_data
.m_pos
;
451 m_data
.m_rect
= m_data
.m_rectOrig
;
452 m_data
.m_rect
.Offset(diff
);
453 m_data
.m_window
->Move(m_data
.m_rect
.GetPosition());
456 else if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE
)
458 wxPoint diff
= wxGetMousePosition() - m_data
.m_pos
;
459 m_data
.m_rect
= m_data
.m_rectOrig
;
460 wxApplyResize(m_data
, diff
);
461 m_data
.m_window
->SetSize(m_data
.m_rect
);
465 void wxInteractiveMoveHandler::OnMouseDown(wxMouseEvent
& WXUNUSED(event
))
467 if ( m_data
.m_flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
469 m_data
.m_evtLoop
->Exit();
473 void wxInteractiveMoveHandler::OnKeyDown(wxKeyEvent
& event
)
475 wxPoint
diff(wxDefaultCoord
,wxDefaultCoord
);
477 switch ( event
.GetKeyCode() )
479 case WXK_UP
: diff
= wxPoint(0, -16); break;
480 case WXK_DOWN
: diff
= wxPoint(0, 16); break;
481 case WXK_LEFT
: diff
= wxPoint(-16, 0); break;
482 case WXK_RIGHT
: diff
= wxPoint(16, 0); break;
484 m_data
.m_window
->SetSize(m_data
.m_rectOrig
);
485 m_data
.m_evtLoop
->Exit();
488 m_data
.m_evtLoop
->Exit();
492 if ( diff
.x
!= wxDefaultCoord
)
494 if ( m_data
.m_flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
496 m_data
.m_flags
&= ~wxINTERACTIVE_WAIT_FOR_INPUT
;
497 if ( m_data
.m_sizingCursor
)
500 m_data
.m_sizingCursor
= false;
503 if ( m_data
.m_flags
& wxINTERACTIVE_MOVE
)
505 m_data
.m_pos
= m_data
.m_window
->GetPosition() +
506 wxPoint(m_data
.m_window
->GetSize().x
/2, 8);
511 bool changeCur
= false;
513 if ( m_data
.m_flags
& wxINTERACTIVE_MOVE
)
515 m_data
.m_rect
.Offset(diff
);
516 m_data
.m_window
->Move(m_data
.m_rect
.GetPosition());
517 warp
= wxPoint(m_data
.m_window
->GetSize().x
/2, 8);
519 else /* wxINTERACTIVE_RESIZE */
521 if ( !(m_data
.m_flags
&
522 (wxINTERACTIVE_RESIZE_N
| wxINTERACTIVE_RESIZE_S
)) )
526 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_N
;
527 m_data
.m_pos
.y
= m_data
.m_window
->GetPosition().y
;
530 else if ( diff
.y
> 0 )
532 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_S
;
533 m_data
.m_pos
.y
= m_data
.m_window
->GetPosition().y
+
534 m_data
.m_window
->GetSize().y
;
538 if ( !(m_data
.m_flags
&
539 (wxINTERACTIVE_RESIZE_W
| wxINTERACTIVE_RESIZE_E
)) )
543 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_W
;
544 m_data
.m_pos
.x
= m_data
.m_window
->GetPosition().x
;
547 else if ( diff
.x
> 0 )
549 m_data
.m_flags
|= wxINTERACTIVE_RESIZE_E
;
550 m_data
.m_pos
.x
= m_data
.m_window
->GetPosition().x
+
551 m_data
.m_window
->GetSize().x
;
556 wxApplyResize(m_data
, diff
);
557 m_data
.m_window
->SetSize(m_data
.m_rect
);
559 if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_W
)
561 else if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_E
)
562 warp
.x
= m_data
.m_window
->GetSize().x
-1;
564 warp
.x
= wxGetMousePosition().x
- m_data
.m_window
->GetPosition().x
;
566 if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_N
)
568 else if ( m_data
.m_flags
& wxINTERACTIVE_RESIZE_S
)
569 warp
.y
= m_data
.m_window
->GetSize().y
-1;
571 warp
.y
= wxGetMousePosition().y
- m_data
.m_window
->GetPosition().y
;
574 warp
-= m_data
.m_window
->GetClientAreaOrigin();
575 m_data
.m_window
->WarpPointer(warp
.x
, warp
.y
);
579 long hit
= m_data
.m_window
->HitTest(warp
);
581 if ( wxGetResizingCursor(hit
, cur
) )
583 if ( m_data
.m_sizingCursor
)
585 wxBeginBusyCursor(&cur
);
586 m_data
.m_sizingCursor
= true;
592 void wxInteractiveMoveHandler::OnMouseUp(wxMouseEvent
& WXUNUSED(event
))
594 m_data
.m_evtLoop
->Exit();
598 void wxTopLevelWindow::InteractiveMove(int flags
)
600 wxASSERT_MSG( !((flags
& wxINTERACTIVE_MOVE
) && (flags
& wxINTERACTIVE_RESIZE
)),
601 wxT("can't move and resize window at the same time") );
603 wxASSERT_MSG( !(flags
& wxINTERACTIVE_RESIZE
) ||
604 (flags
& wxINTERACTIVE_WAIT_FOR_INPUT
) ||
605 (flags
& wxINTERACTIVE_RESIZE_DIR
),
606 wxT("direction of resizing not specified") );
608 wxInteractiveMoveData data
;
614 if ( flags
& wxINTERACTIVE_WAIT_FOR_INPUT
)
616 wxCursor
sizingCursor(wxCURSOR_SIZING
);
617 wxBeginBusyCursor(&sizingCursor
);
618 data
.m_sizingCursor
= true;
622 data
.m_sizingCursor
= false;
624 data
.m_window
= this;
625 data
.m_evtLoop
= &loop
;
626 data
.m_flags
= flags
;
627 data
.m_rect
= data
.m_rectOrig
= GetRect();
628 data
.m_pos
= wxGetMousePosition();
629 data
.m_minSize
= wxSize(GetMinWidth(), GetMinHeight());
630 data
.m_maxSize
= wxSize(GetMaxWidth(), GetMaxHeight());
632 wxEvtHandler
*handler
= new wxInteractiveMoveHandler(data
);
633 this->PushEventHandler(handler
);
639 this->RemoveEventHandler(handler
);
642 if ( data
.m_sizingCursor
)
646 // ----------------------------------------------------------------------------
648 // ----------------------------------------------------------------------------
650 void wxTopLevelWindow::ClickTitleBarButton(long button
)
654 case wxTOPLEVEL_BUTTON_CLOSE
:
658 case wxTOPLEVEL_BUTTON_ICONIZE
:
662 case wxTOPLEVEL_BUTTON_MAXIMIZE
:
666 case wxTOPLEVEL_BUTTON_RESTORE
:
670 case wxTOPLEVEL_BUTTON_HELP
:
673 wxContextHelp
contextHelp(this);
679 wxFAIL_MSG(wxT("incorrect button specification"));
683 bool wxTopLevelWindow::PerformAction(const wxControlAction
& action
,
685 const wxString
& WXUNUSED(strArg
))
687 bool isActive
= numArg
!= 0;
689 if ( action
== wxACTION_TOPLEVEL_ACTIVATE
)
691 if ( m_isActive
!= isActive
)
693 m_isActive
= isActive
;
699 else if ( action
== wxACTION_TOPLEVEL_BUTTON_PRESS
)
701 m_pressedButton
= numArg
;
706 else if ( action
== wxACTION_TOPLEVEL_BUTTON_RELEASE
)
713 else if ( action
== wxACTION_TOPLEVEL_BUTTON_CLICK
)
717 ClickTitleBarButton(numArg
);
721 else if ( action
== wxACTION_TOPLEVEL_MOVE
)
723 InteractiveMove(wxINTERACTIVE_MOVE
);
727 else if ( action
== wxACTION_TOPLEVEL_RESIZE
)
729 int flags
= wxINTERACTIVE_RESIZE
;
730 if ( numArg
& wxHT_TOPLEVEL_BORDER_N
)
731 flags
|= wxINTERACTIVE_RESIZE_N
;
732 if ( numArg
& wxHT_TOPLEVEL_BORDER_S
)
733 flags
|= wxINTERACTIVE_RESIZE_S
;
734 if ( numArg
& wxHT_TOPLEVEL_BORDER_W
)
735 flags
|= wxINTERACTIVE_RESIZE_W
;
736 if ( numArg
& wxHT_TOPLEVEL_BORDER_E
)
737 flags
|= wxINTERACTIVE_RESIZE_E
;
738 InteractiveMove(flags
);
746 void wxTopLevelWindow::OnSystemMenu(wxCommandEvent
& event
)
750 switch (event
.GetId())
752 case wxID_CLOSE_FRAME
:
753 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
754 wxTOPLEVEL_BUTTON_CLOSE
);
756 case wxID_MOVE_FRAME
:
757 InteractiveMove(wxINTERACTIVE_MOVE
| wxINTERACTIVE_WAIT_FOR_INPUT
);
759 case wxID_RESIZE_FRAME
:
760 InteractiveMove(wxINTERACTIVE_RESIZE
| wxINTERACTIVE_WAIT_FOR_INPUT
);
762 case wxID_MAXIMIZE_FRAME
:
763 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
764 wxTOPLEVEL_BUTTON_MAXIMIZE
);
766 case wxID_ICONIZE_FRAME
:
767 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
768 wxTOPLEVEL_BUTTON_ICONIZE
);
770 case wxID_RESTORE_FRAME
:
771 ret
= PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
,
772 wxTOPLEVEL_BUTTON_RESTORE
);
784 // ============================================================================
785 // wxStdFrameInputHandler: handles focus, resizing and titlebar buttons clicks
786 // ============================================================================
788 wxStdFrameInputHandler::wxStdFrameInputHandler(wxInputHandler
*inphand
)
789 : wxStdInputHandler(inphand
)
794 m_borderCursorOn
= false;
797 bool wxStdFrameInputHandler::HandleMouse(wxInputConsumer
*consumer
,
798 const wxMouseEvent
& event
)
800 // the button has 2 states: pressed and normal with the following
801 // transitions between them:
803 // normal -> left down -> capture mouse and go to pressed state
804 // pressed -> left up inside -> generate click -> go to normal
805 // outside ------------------>
807 // the other mouse buttons are ignored
808 if ( event
.Button(1) )
810 if ( event
.ButtonDown(1) )
812 wxTopLevelWindow
*w
= wxStaticCast(consumer
->GetInputWindow(), wxTopLevelWindow
);
813 long hit
= w
->HitTest(event
.GetPosition());
815 if ( hit
& wxHT_TOPLEVEL_ANY_BUTTON
)
818 m_winCapture
->CaptureMouse();
821 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS
, m_winPressed
);
824 else if ( (hit
& wxHT_TOPLEVEL_TITLEBAR
) && !w
->IsMaximized() )
826 consumer
->PerformAction(wxACTION_TOPLEVEL_MOVE
);
829 else if ( (consumer
->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER
)
830 && (hit
& wxHT_TOPLEVEL_ANY_BORDER
) )
832 consumer
->PerformAction(wxACTION_TOPLEVEL_RESIZE
, hit
);
841 m_winCapture
->ReleaseMouse();
844 if ( m_winHitTest
== m_winPressed
)
846 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK
, m_winPressed
);
850 //else: the mouse was released outside the window, this doesn't
855 return wxStdInputHandler::HandleMouse(consumer
, event
);
858 bool wxStdFrameInputHandler::HandleMouseMove(wxInputConsumer
*consumer
,
859 const wxMouseEvent
& event
)
861 if ( event
.GetEventObject() == m_winCapture
)
863 long hit
= m_winCapture
->HitTest(event
.GetPosition());
865 if ( hit
!= m_winHitTest
)
867 if ( hit
!= m_winPressed
)
868 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_RELEASE
, m_winPressed
);
870 consumer
->PerformAction(wxACTION_TOPLEVEL_BUTTON_PRESS
, m_winPressed
);
876 else if ( consumer
->GetInputWindow()->GetWindowStyle() & wxRESIZE_BORDER
)
878 wxTopLevelWindow
*win
= wxStaticCast(consumer
->GetInputWindow(),
880 long hit
= win
->HitTest(event
.GetPosition());
882 if ( hit
!= m_winHitTest
)
886 if ( m_borderCursorOn
)
888 m_borderCursorOn
= false;
889 win
->SetCursor(m_origCursor
);
892 if ( hit
& wxHT_TOPLEVEL_ANY_BORDER
)
896 m_borderCursorOn
= wxGetResizingCursor(hit
, cur
);
897 if ( m_borderCursorOn
)
899 m_origCursor
= win
->GetCursor();
906 return wxStdInputHandler::HandleMouseMove(consumer
, event
);
909 bool wxStdFrameInputHandler::HandleActivation(wxInputConsumer
*consumer
,
912 if ( m_borderCursorOn
)
914 consumer
->GetInputWindow()->SetCursor(m_origCursor
);
915 m_borderCursorOn
= false;
917 consumer
->PerformAction(wxACTION_TOPLEVEL_ACTIVATE
, activated
);