Merge branch 'gesture-events'
Integrate GSoC 2017 work by Prashant Kumar implementing support for gesture events. Closes https://github.com/wxWidgets/wxWidgets/pull/551 Closes https://github.com/wxWidgets/wxWidgets/pull/565
This commit is contained in:
@@ -49,7 +49,8 @@ EVENT_CXXFLAGS = -D__WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) \
|
||||
$(SAMPLES_CXXFLAGS) $(CPPFLAGS) $(CXXFLAGS)
|
||||
EVENT_OBJECTS = \
|
||||
$(__event___win32rc) \
|
||||
event_event.o
|
||||
event_event.o \
|
||||
event_gestures.o
|
||||
|
||||
### Conditionally set variables: ###
|
||||
|
||||
@@ -177,6 +178,8 @@ event_sample_rc.o: $(srcdir)/../../samples/sample.rc
|
||||
event_event.o: $(srcdir)/event.cpp
|
||||
$(CXXC) -c -o $@ $(EVENT_CXXFLAGS) $(srcdir)/event.cpp
|
||||
|
||||
event_gestures.o: $(srcdir)/gestures.cpp
|
||||
$(CXXC) -c -o $@ $(EVENT_CXXFLAGS) $(srcdir)/gestures.cpp
|
||||
|
||||
# Include dependency info, if present:
|
||||
@IF_GNU_MAKE@-include ./.deps/*.d
|
||||
|
@@ -4,7 +4,8 @@
|
||||
<include file="../../build/bakefiles/common_samples.bkl"/>
|
||||
|
||||
<exe id="event" template="wx_sample" template_append="wx_append">
|
||||
<sources>event.cpp</sources>
|
||||
<sources> event.cpp gestures.cpp </sources>
|
||||
<headers> gestures.h </headers>
|
||||
<wx-lib>core</wx-lib>
|
||||
<wx-lib>base</wx-lib>
|
||||
</exe>
|
||||
|
@@ -35,6 +35,7 @@
|
||||
|
||||
#include <wx/statline.h>
|
||||
#include <wx/log.h>
|
||||
#include "gestures.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// event constants
|
||||
@@ -144,6 +145,9 @@ public:
|
||||
void OnClickDynamicHandlerButton(wxCommandEvent& event);
|
||||
void OnClickStaticHandlerFrame(wxCommandEvent& event);
|
||||
|
||||
// Gesture
|
||||
void OnGesture(wxCommandEvent& event);
|
||||
|
||||
private:
|
||||
// symbolic names for the status bar fields
|
||||
enum
|
||||
@@ -178,6 +182,8 @@ private:
|
||||
// the button used to highlight the event handlers execution order
|
||||
MyEvtTestButton *m_testBtn;
|
||||
|
||||
wxWindowRef m_gestureFrame;
|
||||
|
||||
|
||||
// any class wishing to process wxWidgets events must use this macro
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
@@ -220,7 +226,8 @@ enum
|
||||
Event_Push,
|
||||
Event_Pop,
|
||||
Event_Custom,
|
||||
Event_Test
|
||||
Event_Test,
|
||||
Event_Gesture
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -252,6 +259,7 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
||||
EVT_MENU(Event_Test, MyFrame::OnTest)
|
||||
EVT_MENU(Event_Push, MyFrame::OnPushEventHandler)
|
||||
EVT_MENU(Event_Pop, MyFrame::OnPopEventHandler)
|
||||
EVT_MENU(Event_Gesture, MyFrame::OnGesture)
|
||||
|
||||
EVT_UPDATE_UI(Event_Pop, MyFrame::OnUpdateUIPop)
|
||||
|
||||
@@ -381,6 +389,8 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
|
||||
menuEvent->AppendSeparator();
|
||||
menuEvent->Append(Event_Custom, wxT("Fire c&ustom event\tCtrl-U"),
|
||||
wxT("Generate a custom event"));
|
||||
menuEvent->Append(Event_Gesture, wxT("&Gesture events\tCtrl-G"),
|
||||
wxT("Gesture event"));
|
||||
|
||||
// now append the freshly created menu to the menu bar...
|
||||
wxMenuBar *menuBar = new wxMenuBar();
|
||||
@@ -447,7 +457,8 @@ MyFrame::~MyFrame()
|
||||
|
||||
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
// true is to force the frame to close
|
||||
if ( m_gestureFrame )
|
||||
m_gestureFrame->Close(true);
|
||||
Close(true);
|
||||
}
|
||||
|
||||
@@ -577,6 +588,19 @@ void MyFrame::OnPopEventHandler(wxCommandEvent& WXUNUSED(event))
|
||||
#endif // wxUSE_STATUSBAR
|
||||
}
|
||||
|
||||
void MyFrame::OnGesture(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
if ( m_gestureFrame )
|
||||
{
|
||||
m_gestureFrame->Raise();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_gestureFrame = new MyGestureFrame();
|
||||
m_gestureFrame->Show(true);
|
||||
}
|
||||
}
|
||||
|
||||
void MyFrame::OnTest(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
wxLogMessage(wxT("This is the test event handler in the main frame"));
|
||||
@@ -602,4 +626,3 @@ void MyFrame::OnProcessCustom(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
wxLogMessage(wxT("Got a custom event!"));
|
||||
}
|
||||
|
||||
|
@@ -286,6 +286,17 @@
|
||||
<File
|
||||
RelativePath=".\event.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\gestures.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
<File
|
||||
RelativePath=".\gestures.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
|
@@ -810,6 +810,20 @@
|
||||
RelativePath=".\event.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\gestures.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\gestures.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
|
@@ -782,6 +782,20 @@
|
||||
RelativePath=".\event.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\gestures.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\gestures.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
|
221
samples/event/gestures.cpp
Normal file
221
samples/event/gestures.cpp
Normal file
@@ -0,0 +1,221 @@
|
||||
#include "gestures.h"
|
||||
#include "wx/dcgraph.h"
|
||||
|
||||
#include "../image/horse.xpm"
|
||||
|
||||
MyGestureFrame::MyGestureFrame()
|
||||
: wxFrame(NULL, wxID_ANY, "Multi-touch Gestures", wxDefaultPosition, wxSize(800, 600))
|
||||
{
|
||||
// Create controls
|
||||
MyGesturePanel *myPanel = new MyGesturePanel(this);
|
||||
m_logText = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
|
||||
wxSize(wxDefaultCoord, 100), wxTE_MULTILINE|wxTE_READONLY|wxTE_RICH);
|
||||
|
||||
// Add controls to sizer
|
||||
wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
|
||||
sizer->Add(myPanel, wxSizerFlags(1).Expand());
|
||||
sizer->Add(m_logText, wxSizerFlags().Expand());
|
||||
SetSizer(sizer);
|
||||
|
||||
// Log to the text control
|
||||
delete wxLog::SetActiveTarget(new wxLogTextCtrl(m_logText));
|
||||
|
||||
// Bind all gestures to the same event handler, which must run before
|
||||
// the other handlers, to clear the log window
|
||||
myPanel->Bind(wxEVT_GESTURE_PAN, &MyGestureFrame::OnGesture, this);
|
||||
myPanel->Bind(wxEVT_GESTURE_ZOOM, &MyGestureFrame::OnGesture, this);
|
||||
myPanel->Bind(wxEVT_GESTURE_ROTATE, &MyGestureFrame::OnGesture, this);
|
||||
myPanel->Bind(wxEVT_TWO_FINGER_TAP, &MyGestureFrame::OnGesture, this);
|
||||
myPanel->Bind(wxEVT_LONG_PRESS, &MyGestureFrame::OnGesture, this);
|
||||
myPanel->Bind(wxEVT_PRESS_AND_TAP, &MyGestureFrame::OnGesture, this);
|
||||
|
||||
Bind(wxEVT_CLOSE_WINDOW, &MyGestureFrame::OnQuit, this);
|
||||
}
|
||||
|
||||
MyGesturePanel::MyGesturePanel(MyGestureFrame *parent)
|
||||
: wxPanel(parent, wxID_ANY),
|
||||
m_bitmap(horse_xpm)
|
||||
{
|
||||
Bind(wxEVT_PAINT, &MyGesturePanel::OnPaint, this);
|
||||
|
||||
if ( !EnableTouchEvents(wxTOUCH_ALL_GESTURES) )
|
||||
{
|
||||
wxLogError("Failed to enable touch events");
|
||||
|
||||
// Still bind event handlers just in case they still work?
|
||||
}
|
||||
|
||||
// Event handlers
|
||||
Bind(wxEVT_GESTURE_PAN, &MyGesturePanel::OnPan, this);
|
||||
Bind(wxEVT_GESTURE_ZOOM, &MyGesturePanel::OnZoom, this);
|
||||
Bind(wxEVT_GESTURE_ROTATE, &MyGesturePanel::OnRotate, this);
|
||||
Bind(wxEVT_TWO_FINGER_TAP, &MyGesturePanel::OnTwoFingerTap, this);
|
||||
Bind(wxEVT_LONG_PRESS, &MyGesturePanel::OnLongPress, this);
|
||||
Bind(wxEVT_PRESS_AND_TAP, &MyGesturePanel::OnPressAndTap, this);
|
||||
|
||||
m_lastZoomFactor = 1.0;
|
||||
}
|
||||
|
||||
void MyGestureFrame::OnQuit(wxCloseEvent& WXUNUSED(event))
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void MyGestureFrame::OnGesture(wxGestureEvent& event)
|
||||
{
|
||||
if ( event.IsGestureStart() )
|
||||
m_logText->Clear();
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void MyGesturePanel::OnPaint(wxPaintEvent& WXUNUSED(event))
|
||||
{
|
||||
wxPaintDC paintDC(this);
|
||||
|
||||
wxGCDC dc(paintDC);
|
||||
|
||||
dc.Clear();
|
||||
|
||||
dc.SetTransformMatrix(m_affineMatrix);
|
||||
dc.DrawBitmap(m_bitmap, wxRound(m_translateDistance.m_x), wxRound(m_translateDistance.m_y));
|
||||
}
|
||||
|
||||
void MyGesturePanel::OnPan(wxPanGestureEvent& event)
|
||||
{
|
||||
if ( event.IsGestureStart() )
|
||||
{
|
||||
wxLogMessage("Pan gesture started\n");
|
||||
}
|
||||
|
||||
const wxPoint delta = event.GetDelta();
|
||||
wxLogMessage("Pan gesture performed with delta = (%d,%d), "
|
||||
"with current position (%d,%d)",
|
||||
delta.x, delta.y,
|
||||
event.GetPosition().x, event.GetPosition().y);
|
||||
|
||||
// Transform the distance using the transpose of the matrix,
|
||||
// in order to translate the image to match the screen coordinates
|
||||
wxMatrix2D m;
|
||||
m_affineMatrix.Get(&m, NULL);
|
||||
|
||||
wxPoint2DDouble deltaD(m.m_11 * delta.x + m.m_12 * delta.y,
|
||||
m.m_21 * delta.x + m.m_22 * delta.y);
|
||||
|
||||
// Add it to the total translation
|
||||
m_translateDistance += deltaD;
|
||||
|
||||
if ( event.IsGestureEnd() )
|
||||
{
|
||||
wxLogMessage("Pan gesture Ended\n");
|
||||
}
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void MyGesturePanel::OnZoom(wxZoomGestureEvent& event)
|
||||
{
|
||||
if ( event.IsGestureStart() )
|
||||
{
|
||||
wxLogMessage("Zoom gesture started\n");
|
||||
|
||||
m_lastZoomFactor = 1.0;
|
||||
}
|
||||
|
||||
wxLogMessage("Zoom gesture performed with zoom center at (%d, %d) and zoom Factor = %f\n",
|
||||
event.GetPosition().x, event.GetPosition().y, event.GetZoomFactor());
|
||||
|
||||
const wxPoint& zoomCenter = event.GetPosition();
|
||||
|
||||
// Translate to zoom center
|
||||
m_affineMatrix.Translate(zoomCenter.x, zoomCenter.y);
|
||||
// Scale
|
||||
m_affineMatrix.Scale(event.GetZoomFactor() / m_lastZoomFactor, event.GetZoomFactor() / m_lastZoomFactor);
|
||||
// Translate back
|
||||
m_affineMatrix.Translate(-zoomCenter.x, -zoomCenter.y);
|
||||
|
||||
if ( event.IsGestureEnd() )
|
||||
{
|
||||
wxLogMessage("Zoom gesture Ended\n");
|
||||
}
|
||||
|
||||
m_lastZoomFactor = event.GetZoomFactor();
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void MyGesturePanel::OnRotate(wxRotateGestureEvent& event)
|
||||
{
|
||||
if ( event.IsGestureStart() )
|
||||
{
|
||||
wxLogMessage("Rotate gesture started\n");
|
||||
|
||||
m_lastRotationAngle = 0.0;
|
||||
}
|
||||
|
||||
wxLogMessage("Rotate gesture performed with rotation center at (%d, %d) and cumulative rotation angle = %f\n",
|
||||
event.GetPosition().x, event.GetPosition().y, event.GetRotationAngle());
|
||||
|
||||
const wxPoint& rotationCenter = event.GetPosition();
|
||||
|
||||
// Translate to rotation center
|
||||
m_affineMatrix.Translate(rotationCenter.x, rotationCenter.y);
|
||||
// Rotate
|
||||
m_affineMatrix.Rotate(event.GetRotationAngle() - m_lastRotationAngle);
|
||||
// Translate back
|
||||
m_affineMatrix.Translate(-rotationCenter.x, -rotationCenter.y);
|
||||
|
||||
if ( event.IsGestureEnd() )
|
||||
{
|
||||
wxLogMessage("Rotate gesture Ended\n");
|
||||
}
|
||||
|
||||
m_lastRotationAngle = event.GetRotationAngle();
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void MyGesturePanel::OnTwoFingerTap(wxTwoFingerTapEvent& event)
|
||||
{
|
||||
if ( event.IsGestureStart() )
|
||||
{
|
||||
wxLogMessage("Two Finger Tap gesture gesture started\n");
|
||||
}
|
||||
|
||||
wxLogMessage("Two Finger Tap gesture performed at (%d, %d)\n", event.GetPosition().x, event.GetPosition().y);
|
||||
|
||||
if ( event.IsGestureEnd() )
|
||||
{
|
||||
wxLogMessage("Two Finger Tap gesture Ended\n");
|
||||
}
|
||||
}
|
||||
|
||||
void MyGesturePanel::OnLongPress(wxLongPressEvent& event)
|
||||
{
|
||||
if ( event.IsGestureStart() )
|
||||
{
|
||||
wxLogMessage("Long Press gesture started\n");
|
||||
}
|
||||
|
||||
wxLogMessage("Long Press gesture performed at (%d,%d)\n", event.GetPosition().x, event.GetPosition().y);
|
||||
|
||||
if ( event.IsGestureEnd() )
|
||||
{
|
||||
wxLogMessage("Long Press gesture Ended\n");
|
||||
}
|
||||
}
|
||||
|
||||
void MyGesturePanel::OnPressAndTap(wxPressAndTapEvent& event)
|
||||
{
|
||||
if ( event.IsGestureStart() )
|
||||
{
|
||||
wxLogMessage("Press and Tap gesture started\n");
|
||||
}
|
||||
|
||||
wxLogMessage("Press and Tap gesture performed at (%d,%d)\n", event.GetPosition().x, event.GetPosition().y);
|
||||
|
||||
if ( event.IsGestureEnd() )
|
||||
{
|
||||
wxLogMessage("Press and Tap gesture Ended\n");
|
||||
}
|
||||
}
|
39
samples/event/gestures.h
Normal file
39
samples/event/gestures.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef _WX_GESTURES_H_
|
||||
#define _WX_GESTURES_H_
|
||||
|
||||
#include "wx/wx.h"
|
||||
|
||||
class MyGestureFrame : public wxFrame
|
||||
{
|
||||
public:
|
||||
MyGestureFrame();
|
||||
|
||||
void OnGesture(wxGestureEvent& event);
|
||||
void OnQuit(wxCloseEvent& event);
|
||||
|
||||
private:
|
||||
wxTextCtrl *m_logText;
|
||||
};
|
||||
|
||||
class MyGesturePanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
MyGesturePanel(MyGestureFrame* parent);
|
||||
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
void OnPan(wxPanGestureEvent& event);
|
||||
void OnZoom(wxZoomGestureEvent& event);
|
||||
void OnRotate(wxRotateGestureEvent& event);
|
||||
void OnTwoFingerTap(wxTwoFingerTapEvent& event);
|
||||
void OnLongPress(wxLongPressEvent& event);
|
||||
void OnPressAndTap(wxPressAndTapEvent& event);
|
||||
|
||||
private:
|
||||
wxBitmap m_bitmap;
|
||||
wxPoint2DDouble m_translateDistance;
|
||||
wxAffineMatrix2D m_affineMatrix;
|
||||
double m_lastZoomFactor;
|
||||
double m_lastRotationAngle;
|
||||
};
|
||||
|
||||
#endif // _WX_GESTURES_H_
|
@@ -36,7 +36,8 @@ EVENT_CXXFLAGS = $(__RUNTIME_LIBS_7) -I$(BCCDIR)\include $(__DEBUGINFO) \
|
||||
-I$(SETUPHDIR) -I.\..\..\include $(____CAIRO_INCLUDEDIR_FILENAMES_p) -I. \
|
||||
$(__DLLFLAG_p) -I.\..\..\samples -DNOPCH $(CPPFLAGS) $(CXXFLAGS)
|
||||
EVENT_OBJECTS = \
|
||||
$(OBJS)\event_event.obj
|
||||
$(OBJS)\event_event.obj \
|
||||
$(OBJS)\event_gestures.obj
|
||||
|
||||
### Conditionally set variables: ###
|
||||
|
||||
@@ -237,3 +238,5 @@ $(OBJS)\event_sample.res: .\..\..\samples\sample.rc
|
||||
$(OBJS)\event_event.obj: .\event.cpp
|
||||
$(CXX) -q -c -P -o$@ $(EVENT_CXXFLAGS) .\event.cpp
|
||||
|
||||
$(OBJS)\event_gestures.obj: .\gestures.cpp
|
||||
$(CXX) -q -c -P -o$@ $(EVENT_CXXFLAGS) .\gestures.cpp
|
||||
|
@@ -30,7 +30,8 @@ EVENT_CXXFLAGS = $(__DEBUGINFO) $(__OPTIMIZEFLAG_2) $(__THREADSFLAG) \
|
||||
$(__EXCEPTIONSFLAG_6) -Wno-ctor-dtor-privacy $(CPPFLAGS) $(CXXFLAGS)
|
||||
EVENT_OBJECTS = \
|
||||
$(OBJS)\event_sample_rc.o \
|
||||
$(OBJS)\event_event.o
|
||||
$(OBJS)\event_event.o \
|
||||
$(OBJS)\event_gestures.o
|
||||
|
||||
### Conditionally set variables: ###
|
||||
|
||||
@@ -226,6 +227,9 @@ $(OBJS)\event_sample_rc.o: ./../../samples/sample.rc
|
||||
$(OBJS)\event_event.o: ./event.cpp
|
||||
$(CXX) -c -o $@ $(EVENT_CXXFLAGS) $(CPPDEPS) $<
|
||||
|
||||
$(OBJS)\event_gestures.o: ./gestures.cpp
|
||||
$(CXX) -c -o $@ $(EVENT_CXXFLAGS) $(CPPDEPS) $<
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
|
||||
|
@@ -31,7 +31,8 @@ EVENT_CXXFLAGS = /M$(__RUNTIME_LIBS_10)$(__DEBUGRUNTIME_4) /DWIN32 \
|
||||
/I.\..\..\samples /DNOPCH $(__RTTIFLAG_11) $(__EXCEPTIONSFLAG_12) \
|
||||
$(CPPFLAGS) $(CXXFLAGS)
|
||||
EVENT_OBJECTS = \
|
||||
$(OBJS)\event_event.obj
|
||||
$(OBJS)\event_event.obj \
|
||||
$(OBJS)\event_gestures.obj
|
||||
EVENT_RESOURCES = \
|
||||
$(OBJS)\event_sample.res
|
||||
|
||||
@@ -360,3 +361,5 @@ $(OBJS)\event_sample.res: .\..\..\samples\sample.rc
|
||||
$(OBJS)\event_event.obj: .\event.cpp
|
||||
$(CXX) /c /nologo /TP /Fo$@ $(EVENT_CXXFLAGS) .\event.cpp
|
||||
|
||||
$(OBJS)\event_gestures.obj: .\gestures.cpp
|
||||
$(CXX) /c /nologo /TP /Fo$@ $(EVENT_CXXFLAGS) .\gestures.cpp
|
||||
|
Reference in New Issue
Block a user