]> git.saurik.com Git - wxWidgets.git/blame - src/common/mousemanager.cpp
Return NULL from wxWindow::GetCapture() when the capture is being lost.
[wxWidgets.git] / src / common / mousemanager.cpp
CommitLineData
bca8c756
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/common/mousemanager.cpp
3// Purpose: implementation of wxMouseEventsManager class
4// Author: Vadim Zeitlin
5// Created: 2009-04-21
bca8c756
VZ
6// Copyright: (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org>
7// Licence: wxWindows licence
8///////////////////////////////////////////////////////////////////////////////
9
10// ============================================================================
11// declarations
12// ============================================================================
13
14// ----------------------------------------------------------------------------
15// headers
16// ----------------------------------------------------------------------------
17
18// for compilers that support precompilation, includes "wx.h".
19#include "wx/wxprec.h"
20
21#ifdef __BORLANDC__
22 #pragma hdrstop
23#endif
24
25#ifndef WX_PRECOMP
1ba03676
VZ
26 #include "wx/settings.h"
27 #include "wx/window.h"
bca8c756
VZ
28#endif // WX_PRECOMP
29
30#include "wx/mousemanager.h"
31
32// ----------------------------------------------------------------------------
33// event tables
34// ----------------------------------------------------------------------------
35
36BEGIN_EVENT_TABLE(wxMouseEventsManager, wxEvtHandler)
37 EVT_MOUSE_CAPTURE_LOST(wxMouseEventsManager::OnCaptureLost)
38 EVT_LEFT_DOWN(wxMouseEventsManager::OnLeftDown)
39 EVT_LEFT_UP(wxMouseEventsManager::OnLeftUp)
40 EVT_MOTION(wxMouseEventsManager::OnMove)
41END_EVENT_TABLE()
42
43// ============================================================================
44// wxMouseEventsManager implementation
45// ============================================================================
46
4b14a2f7 47void wxMouseEventsManager::Init()
bca8c756 48{
4b14a2f7 49 m_win = NULL;
bca8c756
VZ
50 m_state = State_Normal;
51 m_item = wxNOT_FOUND;
4b14a2f7
VZ
52}
53
54bool wxMouseEventsManager::Create(wxWindow *win)
55{
56 wxASSERT_MSG( !m_win, "Create() must not be called twice" );
bca8c756 57
4b14a2f7 58 m_win = win;
bca8c756 59 win->PushEventHandler(this);
4b14a2f7
VZ
60
61 return true;
bca8c756
VZ
62}
63
64wxMouseEventsManager::~wxMouseEventsManager()
65{
4b14a2f7
VZ
66 if ( m_win )
67 m_win->RemoveEventHandler(this);
bca8c756
VZ
68}
69
70void wxMouseEventsManager::OnCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(event))
71{
72 switch ( m_state )
73 {
74 case State_Normal:
75 wxFAIL_MSG( "mouse shouldn't be captured in normal state" );
76 break;
77
78 case State_Pressed:
79 MouseClickCancelled(m_item);
80 break;
81
82 case State_Dragging:
83 MouseDragCancelled(m_item);
84 break;
85 }
86
87 m_state = State_Normal;
88 m_item = wxNOT_FOUND;
89}
90
91void wxMouseEventsManager::OnLeftDown(wxMouseEvent& event)
92{
93 wxASSERT_MSG( m_state == State_Normal,
94 "state hasn't been reset to normal somehow" );
95
96 m_posLast = event.GetPosition();
97 m_item = MouseHitTest(m_posLast);
98 if ( m_item == wxNOT_FOUND )
99 {
100 event.Skip();
101 return;
102 }
103
104 m_state = State_Pressed;
6de9def0 105 m_win->SetFocus();
bca8c756
VZ
106 m_win->CaptureMouse();
107 MouseClickBegin(m_item);
108}
109
110void wxMouseEventsManager::OnLeftUp(wxMouseEvent& event)
111{
112 switch ( m_state )
113 {
114 case State_Normal:
115 // ignore it, the mouse hasn't been pressed over any item initially
116 // so releasing it shouldn't do anything
117 event.Skip();
118
119 // skip releasing the capture below
120 return;
121
122 case State_Pressed:
123 if ( MouseHitTest(event.GetPosition()) == m_item )
124 {
125 // mouse released over the same item, so it was a click
126 MouseClicked(m_item);
127 }
128 break;
129
130 case State_Dragging:
131 MouseDragEnd(m_item, event.GetPosition());
132 break;
133 }
134
135 m_state = State_Normal;
136 m_item = wxNOT_FOUND;
137 m_win->ReleaseMouse();
138}
139
140void wxMouseEventsManager::OnMove(wxMouseEvent& event)
141{
142 switch ( m_state )
143 {
144 case State_Normal:
145 event.Skip();
146 break;
147
148 case State_Pressed:
149 wxASSERT_MSG( event.LeftIsDown(),
150 "should have detected mouse being released" );
151
152 {
153 // it's probably a bad idea to query the system for these
154 // values every time the mouse is moved so cache them on the
155 // assumption that they don't change -- which is wrong, of
156 // course, the user can change them but it doesn't happen often
157 static const int
158 dragMinX = wxSystemSettings::GetMetric(wxSYS_DRAG_X);
159 static const int
160 dragMinY = wxSystemSettings::GetMetric(wxSYS_DRAG_Y);
161
162 const wxPoint& pos = event.GetPosition();
163 const wxPoint ofs = pos - m_posLast;
164 if ( abs(ofs.x) > dragMinX || abs(ofs.y) > dragMinY )
165 {
166 // the mouse left the rectangle inside which its movements
167 // are considered to be too small to constitute a start of
168 // drag operation, do [attempt to] start it now
169 if ( MouseDragBegin(m_item, pos) )
170 {
171 m_state = State_Dragging;
172 }
173 }
174 else // still didn't move far enough away
175 {
176 event.Skip();
177 }
178 }
179 break;
180
181 case State_Dragging:
182 m_posLast = event.GetPosition();
183 MouseDragging(m_item, m_posLast);
184 break;
185 }
186}
187