Add mouse events tests to event sample Make it possible to easily see the events generated by (double) clicking various mouse buttons. Co-authored-by: Vadim Zeitlin <va...@wxwidgets.org>
Make mouse click event generation in wxOSX consistent with wxMSW Synthesize RIGHT/LEFT_DOWN events before the corresponding DCLICK events in wxOSX to make the behaviour the same as in wxMSW, where Windows does this automatically.
Toggle wxGenericTreeCtrl branches on single and double clicks This ensures that quickly clicking, possibly multiple times, on the expanded buttons in the generic tree control, always expands the button instead of only doing it for odd-numbered clicks (as even-numbered are converted to double clicks).
Merge branch 'osx_dclick_fix' Make wxOSX mouse event generation consistent with wxMSW and fix clicks handling in wxGenericTreeCtrl. Closes #25886.
Show time taken by the tests in Cirrus CI Try to understand how much time do wxFileSystemWatcher tests take there.
... | ... | @@ -82,7 +82,7 @@ task: |
82 | 82 | |
83 | 83 | test_script: |
|
84 | 84 | cd tests
|
85 | - WX_TEST_WEBREQUEST_URL="0" ./test
|
|
85 | + WX_TEST_WEBREQUEST_URL="0" ./test -d 1
|
|
86 | 86 | |
87 | 87 | build_samples_script: |
|
88 | 88 | make -k -C samples $wxBUILD_ARGS
|
... | ... | @@ -259,6 +259,8 @@ protected: |
259 | 259 | |
260 | 260 | NSEvent* m_lastKeyDownEvent;
|
261 | 261 | bool m_lastKeyDownWXSent;
|
262 | + bool m_lastLeftDownWasDClick;
|
|
263 | + bool m_lastRightDownWasDClick;
|
|
262 | 264 | #if !wxOSX_USE_NATIVE_FLIPPED
|
263 | 265 | bool m_isFlipped;
|
264 | 266 | #endif
|
... | ... | @@ -141,6 +141,9 @@ public: |
141 | 141 | void OnClickDynamicHandlerButton(wxCommandEvent& event);
|
142 | 142 | void OnClickStaticHandlerFrame(wxCommandEvent& event);
|
143 | 143 | |
144 | + // Mouse
|
|
145 | + void OnMouseEvents(wxCommandEvent& event);
|
|
146 | + |
|
144 | 147 | // Gesture
|
145 | 148 | void OnGesture(wxCommandEvent& event);
|
146 | 149 | |
... | ... | @@ -182,6 +185,7 @@ private: |
182 | 185 | MyEvtTestButton *m_testBtn;
|
183 | 186 | |
184 | 187 | wxWindowRef m_gestureFrame;
|
188 | + wxWindowRef m_mouseFrame;
|
|
185 | 189 | |
186 | 190 | |
187 | 191 | // any class wishing to process wxWidgets events must use this macro
|
... | ... | @@ -227,6 +231,7 @@ enum |
227 | 231 | Event_Custom,
|
228 | 232 | Event_Test,
|
229 | 233 | Event_Gesture,
|
234 | + Event_Mouse,
|
|
230 | 235 | Event_NewEventClass
|
231 | 236 | };
|
232 | 237 | |
... | ... | @@ -260,6 +265,7 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) |
260 | 265 | EVT_MENU(Event_Push, MyFrame::OnPushEventHandler)
|
261 | 266 | EVT_MENU(Event_Pop, MyFrame::OnPopEventHandler)
|
262 | 267 | EVT_MENU(Event_Gesture, MyFrame::OnGesture)
|
268 | + EVT_MENU(Event_Mouse, MyFrame::OnMouseEvents)
|
|
263 | 269 | EVT_MENU(Event_NewEventClass, MyFrame::OnNewEventClass)
|
264 | 270 | |
265 | 271 | EVT_UPDATE_UI(Event_Pop, MyFrame::OnUpdateUIPop)
|
... | ... | @@ -392,6 +398,8 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) |
392 | 398 | "Generate a custom event");
|
393 | 399 | menuEvent->Append(Event_Gesture, "&Gesture events\tCtrl-G",
|
394 | 400 | "Gesture event");
|
401 | + menuEvent->Append(Event_Mouse, "&Mouse events\tCtrl-M",
|
|
402 | + "Mouse event");
|
|
395 | 403 | menuEvent->Append(Event_NewEventClass, "&New wxEvent class demo\tCtrl-N",
|
396 | 404 | "Demonstrates a new wxEvent-derived class");
|
397 | 405 | |
... | ... | @@ -459,6 +467,10 @@ void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) |
459 | 467 | {
|
460 | 468 | if ( m_gestureFrame )
|
461 | 469 | m_gestureFrame->Close(true);
|
470 | + |
|
471 | + if ( m_mouseFrame )
|
|
472 | + m_mouseFrame->Close(true);
|
|
473 | + |
|
462 | 474 | Close(true);
|
463 | 475 | }
|
464 | 476 | |
... | ... | @@ -595,6 +607,19 @@ void MyFrame::OnGesture(wxCommandEvent& WXUNUSED(event)) |
595 | 607 | }
|
596 | 608 | }
|
597 | 609 | |
610 | +void MyFrame::OnMouseEvents(wxCommandEvent& WXUNUSED(event))
|
|
611 | +{
|
|
612 | + if ( m_mouseFrame )
|
|
613 | + {
|
|
614 | + m_mouseFrame->Raise();
|
|
615 | + }
|
|
616 | + else
|
|
617 | + {
|
|
618 | + m_mouseFrame = new MyMouseFrame();
|
|
619 | + m_mouseFrame->Show(true);
|
|
620 | + }
|
|
621 | +}
|
|
622 | + |
|
598 | 623 | void MyFrame::OnNewEventClass(wxCommandEvent& WXUNUSED(event))
|
599 | 624 | {
|
600 | 625 | MyChessBoardDialog dlg(this);
|
... | ... | @@ -4,6 +4,116 @@ |
4 | 4 | |
5 | 5 | #include "../image/horse.xpm"
|
6 | 6 | |
7 | + |
|
8 | + |
|
9 | + |
|
10 | +MyMouseFrame::MyMouseFrame()
|
|
11 | + : wxFrame(nullptr, wxID_ANY, "Mouse events")
|
|
12 | +{
|
|
13 | + // Create controls
|
|
14 | + MyMousePanel* myPanel = new MyMousePanel(this);
|
|
15 | + myPanel->SetMinSize(FromDIP(wxSize(100, 200)));
|
|
16 | + myPanel->SetBackgroundColour( *wxLIGHT_GREY );
|
|
17 | + m_logText = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
|
|
18 | + wxDefaultPosition, wxDefaultSize,
|
|
19 | + wxTE_MULTILINE|wxTE_READONLY|wxTE_RICH);
|
|
20 | + |
|
21 | + // Add controls to sizer
|
|
22 | + wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
|
|
23 | + sizer->Add(myPanel, wxSizerFlags().Expand());
|
|
24 | + sizer->Add(m_logText, wxSizerFlags(1).Expand());
|
|
25 | + SetSizer(sizer);
|
|
26 | + |
|
27 | + // Log to the text control
|
|
28 | + m_logOld = wxLog::SetActiveTarget(new wxLogTextCtrl(m_logText));
|
|
29 | + |
|
30 | + SetClientSize(FromDIP(wxSize(600, 800)));
|
|
31 | + |
|
32 | + Bind(wxEVT_CLOSE_WINDOW, &MyMouseFrame::OnQuit, this);
|
|
33 | +}
|
|
34 | + |
|
35 | +void MyMouseFrame::OnQuit(wxCloseEvent& WXUNUSED(event))
|
|
36 | +{
|
|
37 | + delete wxLog::SetActiveTarget(m_logOld);
|
|
38 | + Destroy();
|
|
39 | +}
|
|
40 | + |
|
41 | +MyMousePanel::MyMousePanel(MyMouseFrame *parent)
|
|
42 | + : wxPanel(parent, wxID_ANY)
|
|
43 | +{
|
|
44 | + // Event handlers
|
|
45 | + Bind(wxEVT_LEFT_DOWN, &MyMousePanel::OnLeftDown, this);
|
|
46 | + Bind(wxEVT_LEFT_UP, &MyMousePanel::OnLeftUp, this);
|
|
47 | + Bind(wxEVT_LEFT_DCLICK, &MyMousePanel::OnLeftDClick, this);
|
|
48 | + Bind(wxEVT_RIGHT_DOWN, &MyMousePanel::OnRightDown, this);
|
|
49 | + Bind(wxEVT_RIGHT_UP, &MyMousePanel::OnRightUp, this);
|
|
50 | + Bind(wxEVT_RIGHT_DCLICK, &MyMousePanel::OnRightDClick, this);
|
|
51 | + Bind(wxEVT_ENTER_WINDOW, &MyMousePanel::OnEnter, this);
|
|
52 | + Bind(wxEVT_LEAVE_WINDOW, &MyMousePanel::OnLeave, this);
|
|
53 | +}
|
|
54 | + |
|
55 | +void
|
|
56 | +MyMousePanel::DoLogMouseEvent(const wxMouseEvent& event,
|
|
57 | + const wxString& eventName)
|
|
58 | +{
|
|
59 | + wxString msg = eventName;
|
|
60 | + |
|
61 | + wxString down;
|
|
62 | + if (event.LeftIsDown())
|
|
63 | + down += " left";
|
|
64 | + if (event.MiddleIsDown())
|
|
65 | + down += " middle";
|
|
66 | + if (event.RightIsDown())
|
|
67 | + down += " right";
|
|
68 | + |
|
69 | + if (down.empty())
|
|
70 | + down = " none";
|
|
71 | + |
|
72 | + wxLogMessage("%s (buttons down:%s)", msg, down);
|
|
73 | +}
|
|
74 | + |
|
75 | +void MyMousePanel::OnLeftDown(wxMouseEvent& event)
|
|
76 | +{
|
|
77 | + DoLogMouseEvent(event, "wxEVT_LEFT_DOWN");
|
|
78 | +}
|
|
79 | + |
|
80 | +void MyMousePanel::OnLeftUp(wxMouseEvent& event)
|
|
81 | +{
|
|
82 | + DoLogMouseEvent(event, "wxEVT_LEFT_UP");
|
|
83 | +}
|
|
84 | + |
|
85 | +void MyMousePanel::OnRightDown(wxMouseEvent& event)
|
|
86 | +{
|
|
87 | + DoLogMouseEvent(event, "wxEVT_RIGHT_DOWN");
|
|
88 | +}
|
|
89 | + |
|
90 | +void MyMousePanel::OnRightUp(wxMouseEvent& event)
|
|
91 | +{
|
|
92 | + DoLogMouseEvent(event, "wxEVT_RIGHT_UP");
|
|
93 | +}
|
|
94 | + |
|
95 | +void MyMousePanel::OnLeftDClick(wxMouseEvent& event)
|
|
96 | +{
|
|
97 | + DoLogMouseEvent(event, "wxEVT_LEFT_DCLICK");
|
|
98 | +}
|
|
99 | + |
|
100 | +void MyMousePanel::OnRightDClick(wxMouseEvent& event)
|
|
101 | +{
|
|
102 | + DoLogMouseEvent(event, "wxEVT_RIGHT_DCLICK");
|
|
103 | +}
|
|
104 | + |
|
105 | +void MyMousePanel::OnEnter(wxMouseEvent& event)
|
|
106 | +{
|
|
107 | + DoLogMouseEvent(event, "wxEVT_ENTER_WINDDOW");
|
|
108 | +}
|
|
109 | + |
|
110 | +void MyMousePanel::OnLeave(wxMouseEvent& event)
|
|
111 | +{
|
|
112 | + DoLogMouseEvent(event, "wxEVT_LEAVE_WINDDOW");
|
|
113 | +}
|
|
114 | + |
|
115 | +// --------------------------------------------------------------------
|
|
116 | + |
|
7 | 117 | MyGestureFrame::MyGestureFrame()
|
8 | 118 | : wxFrame(nullptr, wxID_ANY, "Multi-touch Gestures", wxDefaultPosition, wxSize(800, 600))
|
9 | 119 | {
|
... | ... | @@ -38,4 +38,37 @@ private: |
38 | 38 | wxPoint m_lastGesturePos;
|
39 | 39 | };
|
40 | 40 | |
41 | +class MyMouseFrame : public wxFrame
|
|
42 | +{
|
|
43 | +public:
|
|
44 | + MyMouseFrame();
|
|
45 | + |
|
46 | + void OnQuit(wxCloseEvent& event);
|
|
47 | + |
|
48 | +private:
|
|
49 | + wxLog *m_logOld;
|
|
50 | + wxTextCtrl *m_logText;
|
|
51 | +};
|
|
52 | + |
|
53 | +class MyMousePanel : public wxPanel
|
|
54 | +{
|
|
55 | +public:
|
|
56 | + MyMousePanel(MyMouseFrame* parent);
|
|
57 | + |
|
58 | +private:
|
|
59 | + void DoLogMouseEvent(const wxMouseEvent& event, const wxString& eventName);
|
|
60 | + |
|
61 | + void OnLeftDown(wxMouseEvent& event);
|
|
62 | + void OnLeftUp(wxMouseEvent& event);
|
|
63 | + void OnRightDown(wxMouseEvent& event);
|
|
64 | + void OnRightUp(wxMouseEvent& event);
|
|
65 | + void OnLeftDClick(wxMouseEvent& event);
|
|
66 | + void OnRightDClick(wxMouseEvent& event);
|
|
67 | + void OnEnter(wxMouseEvent& event);
|
|
68 | + void OnLeave(wxMouseEvent& event);
|
|
69 | + |
|
70 | +};
|
|
71 | + |
|
72 | + |
|
73 | + |
|
41 | 74 | #endif // _WX_GESTURES_H_ |
... | ... | @@ -3901,9 +3901,8 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) |
3901 | 3901 | |
3902 | 3902 | if ( flags & wxTREE_HITTEST_ONITEMBUTTON )
|
3903 | 3903 | {
|
3904 | - // only toggle the item for a single click, double click on
|
|
3905 | - // the button doesn't do anything (it toggles the item twice)
|
|
3906 | - if ( event.LeftDown() )
|
|
3904 | + // toggle the item for both single clicks and double clicks
|
|
3905 | + if ( event.LeftDown() || event.LeftDClick() )
|
|
3907 | 3906 | {
|
3908 | 3907 | Toggle( item );
|
3909 | 3908 | }
|
... | ... | @@ -2754,6 +2754,8 @@ void wxWidgetCocoaImpl::Init() |
2754 | 2754 | m_lastKeyDownEvent = nil;
|
2755 | 2755 | m_lastKeyDownWXSent = false;
|
2756 | 2756 | m_hasEditor = false;
|
2757 | + m_lastLeftDownWasDClick = false;
|
|
2758 | + m_lastRightDownWasDClick = false;
|
|
2757 | 2759 | }
|
2758 | 2760 | |
2759 | 2761 | wxWidgetCocoaImpl::~wxWidgetCocoaImpl()
|
... | ... | @@ -4114,6 +4116,41 @@ bool wxWidgetCocoaImpl::DoHandleMouseEvent(NSEvent *event) |
4114 | 4116 | bool processed = false;
|
4115 | 4117 | for ( auto& wxevent : TranslateMouseEvent(event) )
|
4116 | 4118 | {
|
4119 | + if (wxevent.GetEventType() == wxEVT_LEFT_DOWN)
|
|
4120 | + {
|
|
4121 | + m_lastLeftDownWasDClick = false;
|
|
4122 | + }
|
|
4123 | + else if (wxevent.GetEventType() == wxEVT_LEFT_DCLICK)
|
|
4124 | + {
|
|
4125 | + if (m_lastLeftDownWasDClick)
|
|
4126 | + {
|
|
4127 | + // synthesize LEFT_DOWN event from second, fourth etc. DCLICK event
|
|
4128 | + wxevent.SetEventType( wxEVT_LEFT_DOWN );
|
|
4129 | + m_lastLeftDownWasDClick = false;
|
|
4130 | + }
|
|
4131 | + else
|
|
4132 | + {
|
|
4133 | + m_lastLeftDownWasDClick = true;
|
|
4134 | + }
|
|
4135 | + }
|
|
4136 | + else if (wxevent.GetEventType() == wxEVT_RIGHT_DOWN)
|
|
4137 | + {
|
|
4138 | + m_lastRightDownWasDClick = false;
|
|
4139 | + }
|
|
4140 | + else if (wxevent.GetEventType() == wxEVT_RIGHT_DCLICK)
|
|
4141 | + {
|
|
4142 | + if (m_lastRightDownWasDClick)
|
|
4143 | + {
|
|
4144 | + // synthesize RIGHT_DOWN event from second, fourth etc. DCLICK event
|
|
4145 | + wxevent.SetEventType( wxEVT_RIGHT_DOWN );
|
|
4146 | + m_lastRightDownWasDClick = false;
|
|
4147 | + }
|
|
4148 | + else
|
|
4149 | + {
|
|
4150 | + m_lastRightDownWasDClick = true;
|
|
4151 | + }
|
|
4152 | + }
|
|
4153 | + |
|
4117 | 4154 | // Even if this event was processed, still continue with the other
|
4118 | 4155 | // events, if any.
|
4119 | 4156 | if ( GetWXPeer()->HandleWindowEvent(wxevent) )
|
—
View it on GitLab.
You're receiving this email because of your account on gitlab.com. Manage all notifications · Help