From bf6b4541bffc9e47f449eb5c11809d6ffc9a3374 Mon Sep 17 00:00:00 2001 From: Raphael Dumusc Date: Fri, 3 Nov 2017 11:54:57 +0100 Subject: [PATCH] Replace TUIO subproject with Qt's TuioTouch plugin (Qt >= 5.6) --- .gitignore | 1 - .gitsubprojects | 1 - CMakeLists.txt | 19 +-- apps/TideMaster/main.cpp | 11 +- apps/tide | 4 +- doc/Building.md | 1 - doc/Changelog.md | 7 + doc/UserGuide.md | 2 +- tide/config.h.in | 1 - tide/core/log.cpp | 5 - tide/core/log.h | 3 - tide/master/CMakeLists.txt | 6 - tide/master/MasterApplication.cpp | 222 +++++++++++++++-------------- tide/master/MasterApplication.h | 23 ++- tide/master/MultitouchListener.cpp | 88 ------------ tide/master/MultitouchListener.h | 79 ---------- tide/master/PlanarController.h | 8 +- tide/master/ui/MasterQuickView.cpp | 16 +++ tide/master/ui/MasterQuickView.h | 1 + 19 files changed, 167 insertions(+), 331 deletions(-) delete mode 100644 tide/master/MultitouchListener.cpp delete mode 100644 tide/master/MultitouchListener.h diff --git a/.gitignore b/.gitignore index 9df6806d..5bcced2f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,5 @@ CMakeLists.txt.user* build/ Deflect/ Servus/ -TUIO/ VirtualKeyboard/ ZeroEQ/ diff --git a/.gitsubprojects b/.gitsubprojects index 6d888298..99cdc94b 100644 --- a/.gitsubprojects +++ b/.gitsubprojects @@ -1,5 +1,4 @@ # -*- mode: cmake -*- git_subproject(ZeroEQ https://github.com/HBPVIS/ZeroEQ.git 1e66ee3) git_subproject(Deflect https://github.com/BlueBrain/Deflect.git cc4c732) -git_subproject(TUIO https://github.com/BlueBrain/TUIO.git 52afa43) git_subproject(VirtualKeyboard https://github.com/BlueBrain/QtFreeVirtualKeyboard.git d026536) diff --git a/CMakeLists.txt b/CMakeLists.txt index 839e2d9d..b81a0218 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ # Raphael Dumusc cmake_minimum_required(VERSION 3.1 FATAL_ERROR) -project(Tide VERSION 1.4.0) +project(Tide VERSION 1.5.0) set(Tide_VERSION_ABI 1) list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake/common) @@ -33,6 +33,9 @@ common_find_package(MPI REQUIRED) common_find_package(Qt5Concurrent REQUIRED) common_find_package(Qt5Core REQUIRED) common_find_package(Qt5Gui REQUIRED COMPONENTS Private) +if(NOT TARGET Qt5::QTuioTouchPlugin) + message(WARNING "Qt5::QTuioTouchPlugin not found, touch may be unavailable") +endif() common_find_package(Qt5Network REQUIRED) common_find_package(Qt5Qml REQUIRED) common_find_package(Qt5Quick 5.4 REQUIRED) @@ -54,6 +57,7 @@ common_find_package(RSVG MODULE librsvg-2.0 2.36.2) common_find_package(Threads REQUIRED) common_find_package(TIFF) common_find_package(VirtualKeyboard) +common_find_package(X11) # for webbrowser and swap sync unit tests common_find_package(FFMPEG) if(FFMPEG_FOUND) @@ -71,16 +75,6 @@ else() endif() endif() -common_find_package(TUIO 1.4 SYSTEM) -if(TUIO_FOUND) - option(TIDE_ENABLE_TUIO_TOUCH_LISTENER "Enable TUIO touch listener for multi-touch events" ON) -endif() -if(TIDE_ENABLE_TUIO_TOUCH_LISTENER) - common_find_package(X11 REQUIRED) -else() - common_find_package(X11) # for webbrowser unit tests -endif() - common_find_package(ZeroEQ) if(TARGET ZeroEQHTTP) option(TIDE_ENABLE_REST_INTERFACE "Enable REST interface using ZeroEQ" ON) @@ -107,9 +101,6 @@ if(Deflect_IS_SUBPROJECT) set(_deflect_deb qtbase5-dev libturbojpeg) set(TIDE_PACKAGE_REPLACES desktopstreamer) endif() -if(TUIO_IS_SUBPROJECT) - set(TIDE_PACKAGE_CONFLICTS liboscpack-dev liboscpack1) -endif() if(ZeroEQ_IS_SUBPROJECT) set(_cppnetlib_deb libboost-atomic-dev libboost-chrono-dev libboost-date-time-dev libboost-filesystem-dev libboost-program-options-dev diff --git a/apps/TideMaster/main.cpp b/apps/TideMaster/main.cpp index 9cae1591..b3fca0ee 100644 --- a/apps/TideMaster/main.cpp +++ b/apps/TideMaster/main.cpp @@ -1,8 +1,8 @@ /*********************************************************************/ -/* Copyright (c) 2011 - 2012, The University of Texas at Austin. */ +/* Copyright (c) 2011-2012, The University of Texas at Austin. */ /* Copyright (c) 2013-2017, EPFL/Blue Brain Project */ -/* Raphael.Dumusc@epfl.ch */ -/* Daniel.Nachbaur@epfl.ch */ +/* Raphael.Dumusc@epfl.ch */ +/* Daniel.Nachbaur@epfl.ch */ /* All rights reserved. */ /* */ /* Redistribution and use in source and binary forms, with or */ @@ -59,6 +59,11 @@ int main(int argc, char* argv[]) // Load virtualkeyboard input context plugin qputenv("QT_IM_MODULE", QByteArray("virtualkeyboard")); + // For TuioTouch plugin in headless mode + qputenv("QT_TUIOTOUCH_DELIVER_WITHOUT_FOCUS", QByteArray("1")); + // WAR bug in TuioTouch plugin with http_proxy in Qt 5.8.0 [QTBUG-58706] + if (QString(qVersion()) == "5.8.0") + qputenv("http_proxy", QByteArray()); { MPIChannelPtr worldChannel(new MPIChannel(argc, argv)); diff --git a/apps/tide b/apps/tide index 8792fd4b..619ea793 100755 --- a/apps/tide +++ b/apps/tide @@ -177,8 +177,10 @@ try: forker_host = host # forker goes at the end of the hostlist export_display = EXPORT_ENV_VAR.format('DISPLAY', display) + export_tuio = EXPORT_ENV_VAR.format('QT_QPA_GENERIC_PLUGINS', 'TuioTouch') environment = '%s %s %s' % (MPI_SPECIAL_FLAGS, export_display, node_host) - mastercmd = '%s -np 1 %s%s %s' % (environment, VGLRUN_BIN, TIDEMASTER_BIN, TIDE_PARAMS) + masterexec = '%s%s %s' % (VGLRUN_BIN, TIDEMASTER_BIN, TIDE_PARAMS) + mastercmd = '%s %s -np 1 %s' % (export_tuio, environment, masterexec) runcommands.append(mastercmd) # add a separate 'forker' process on the same host as the master process diff --git a/doc/Building.md b/doc/Building.md index 2b9afb0e..3dc2a91a 100644 --- a/doc/Building.md +++ b/doc/Building.md @@ -27,7 +27,6 @@ cloned by CMake during the configure step. They come with their own additional requirements: * Deflect: streaming of contents and applications - libjpeg-turbo -* TUIO: multitouch interface * VirtualKeyboard: on-screen virtual keyboard (Qml) * ZeroEQ: http / REST interface (technically optional, but needed to operate the on-screen Launcher panel) diff --git a/doc/Changelog.md b/doc/Changelog.md index 2ec93f58..81675949 100644 --- a/doc/Changelog.md +++ b/doc/Changelog.md @@ -1,6 +1,13 @@ Changelog {#changelog} ============ +# Release 1.5 (git master) + +* [211](https://github.com/BlueBrain/Tide/pull/211): + Qt's TuioTouch plugin replaces BlueBrain's TUIO subproject. Note: when not in + headless mode, the touch points can only be delivered when the main window's + Qml item has active focus. + # Release 1.4 (09-11-2017) * [203](https://github.com/BlueBrain/Tide/pull/203): diff --git a/doc/UserGuide.md b/doc/UserGuide.md index 80a974fb..797c3dee 100644 --- a/doc/UserGuide.md +++ b/doc/UserGuide.md @@ -54,7 +54,7 @@ stereo3d: side by side Tide listens on the following ports: * TCP port 1701 - incoming Deflect connections. -* UDP port 3333 - TUIO messages (if compiled with TUIO multitouch support). +* UDP port 3333 - TUIO messages (if using TuioTouch Qt plugin). * TCP port 8888 - REST interface (if compiled with ZeroEQ support), configurable. diff --git a/tide/config.h.in b/tide/config.h.in index 0006196c..43ed318e 100644 --- a/tide/config.h.in +++ b/tide/config.h.in @@ -5,7 +5,6 @@ #cmakedefine01 TIDE_ENABLE_PDF_SUPPORT #cmakedefine01 TIDE_ENABLE_PLANAR_CONTROLLER #cmakedefine01 TIDE_ENABLE_REST_INTERFACE -#cmakedefine01 TIDE_ENABLE_TUIO_TOUCH_LISTENER #cmakedefine01 TIDE_ENABLE_WEBBROWSER_SUPPORT #cmakedefine01 TIDE_IGNORE_MPI_THREADSAFETY diff --git a/tide/core/log.cpp b/tide/core/log.cpp index 9b506e67..5b93a0cb 100644 --- a/tide/core/log.cpp +++ b/tide/core/log.cpp @@ -204,8 +204,3 @@ void tiffMessageLoggerErr(const char* module, const char* fmt, va_list ap) vsnprintf(log_string, MAX_LOG_LENGTH, fmt, ap); put_log(LOG_ERROR, LOG_TIFF, "%s: '%s'", module, log_string); } - -void tuioMessageLogger(const int level, const std::string& message) -{ - put_log(level, LOG_TUIO, message.c_str()); -} diff --git a/tide/core/log.h b/tide/core/log.h index 9df389d7..ac0efc24 100644 --- a/tide/core/log.h +++ b/tide/core/log.h @@ -63,7 +63,6 @@ #define LOG_REST "REST" #define LOG_STREAM "STREAM" #define LOG_TIFF "TIFF" -#define LOG_TUIO "TUIO" extern std::string logger_id; extern void put_log(const int level, const std::string& facility, @@ -78,8 +77,6 @@ extern void tiffMessageLoggerWarn(const char* module, const char* fmt, extern void tiffMessageLoggerErr(const char* module, const char* fmt, va_list ap); -extern void tuioMessageLogger(int level, const std::string& message); - #ifdef _WIN32 #define print_log(l, facility, fmt, ...) \ put_log(l, facility, "%s: " fmt, __FUNCTION__, ##__VA_ARGS__) diff --git a/tide/master/CMakeLists.txt b/tide/master/CMakeLists.txt index f4c63551..22dba9ef 100644 --- a/tide/master/CMakeLists.txt +++ b/tide/master/CMakeLists.txt @@ -145,12 +145,6 @@ if(TIDE_ENABLE_PDF_SUPPORT) ) endif() -if(TIDE_ENABLE_TUIO_TOUCH_LISTENER) - list(APPEND TIDEMASTER_HEADERS MultitouchListener.h) - list(APPEND TIDEMASTER_SOURCES MultitouchListener.cpp) - list(APPEND TIDEMASTER_LINK_LIBRARIES TUIO ${X11_LIBRARIES}) -endif() - if(TIDE_ENABLE_PLANAR_CONTROLLER) list(APPEND TIDEMASTER_HEADERS PlanarController.h) list(APPEND TIDEMASTER_SOURCES PlanarController.cpp) diff --git a/tide/master/MasterApplication.cpp b/tide/master/MasterApplication.cpp index 7f0ece7b..af956c11 100644 --- a/tide/master/MasterApplication.cpp +++ b/tide/master/MasterApplication.cpp @@ -62,10 +62,6 @@ #include "ui/MasterQuickView.h" #include "ui/MasterWindow.h" -#if TIDE_ENABLE_TUIO_TOUCH_LISTENER -#include "MultitouchListener.h" -#endif - #if TIDE_ENABLE_WEBBROWSER_SUPPORT #include "scene/WebbrowserContent.h" #endif @@ -227,24 +223,13 @@ void MasterApplication::_init() _saveSessionCallback = nullptr; }); -#if TIDE_ENABLE_PLANAR_CONTROLLER - if (!_config->getPlanarSerialPort().isEmpty()) - { - _planarController.reset( - new PlanarController(_config->getPlanarSerialPort())); - - connect(_inactivityTimer.get(), &InactivityTimer::poweroff, [this]() { - _planarController->powerOff(); - print_log(LOG_INFO, LOG_POWER, - "Powering off the screens on inactivity timeout"); - }); - } -#endif - #if TIDE_ENABLE_REST_INTERFACE _initRestInterface(); #endif - +#if TIDE_ENABLE_PLANAR_CONTROLLER + if (!_config->getPlanarSerialPort().isEmpty()) + _initPlanarController(); +#endif _startDeflectServer(); _setupMPIConnections(); } @@ -275,13 +260,6 @@ void MasterApplication::_initMasterWindow() connect(view, &MasterQuickView::mouseReleased, [this](const QPointF) { _markers->removeMarker(MOUSE_MARKER_ID); }); -#if TIDE_ENABLE_TUIO_TOUCH_LISTENER - auto mapFunc = - std::bind(&MasterQuickView::mapToWallPos, view, std::placeholders::_1); - _touchInjector.reset(new deflect::qt::TouchInjector{*view, mapFunc}); - _initTouchListener(); -#endif - auto engine = view->engine(); auto item = view->wallItem(); _masterGroupRenderer.reset( @@ -300,11 +278,6 @@ void MasterApplication::_initOffscreenView() _offscreenQuickView->load(QML_OFFSCREEN_ROOT_COMPONENT).wait(); _offscreenQuickView->resize(_config->getTotalSize()); -#if TIDE_ENABLE_TUIO_TOUCH_LISTENER - _touchInjector = deflect::qt::TouchInjector::create(*_offscreenQuickView); - _initTouchListener(); -#endif - auto engine = _offscreenQuickView->getEngine(); auto item = _offscreenQuickView->getRootItem(); _masterGroupRenderer.reset( @@ -454,57 +427,6 @@ void MasterApplication::_setupMPIConnections() _mpiReceiveThread.start(); } -#if TIDE_ENABLE_TUIO_TOUCH_LISTENER -void MasterApplication::_initTouchListener() -{ - _touchListener.reset(new MultitouchListener()); - - connect(_touchListener.get(), &MultitouchListener::touchPointAdded, - _touchInjector.get(), &deflect::qt::TouchInjector::addTouchPoint); - connect(_touchListener.get(), &MultitouchListener::touchPointUpdated, - _touchInjector.get(), - &deflect::qt::TouchInjector::updateTouchPoint); - connect(_touchListener.get(), &MultitouchListener::touchPointRemoved, - _touchInjector.get(), - &deflect::qt::TouchInjector::removeTouchPoint); - connect(_touchListener.get(), &MultitouchListener::touchPointAdded, - _inactivityTimer.get(), &InactivityTimer::restart); - - const auto wallSize = _config->getTotalSize(); - auto getWallPos = [wallSize](const QPointF& normalizedPos) { - return QPointF{normalizedPos.x() * wallSize.width(), - normalizedPos.y() * wallSize.height()}; - }; - connect(_touchListener.get(), &MultitouchListener::touchPointAdded, - [this, getWallPos](const int id, const QPointF normalizedPos) { - _markers->addMarker(id, getWallPos(normalizedPos)); -#if TIDE_ENABLE_PLANAR_CONTROLLER - if (!_planarController || - _planarController->getState() != ScreenState::OFF) - { - return; - } - if (_planarController->powerOn()) - print_log(LOG_INFO, LOG_POWER, - "Powered on the screens by touching the " - "wall"); - else - print_log(LOG_ERROR, LOG_POWER, - "Could not power on the screens by " - "touching the wall"); -#endif - }); - connect(_touchListener.get(), &MultitouchListener::touchPointUpdated, - [this, getWallPos](const int id, const QPointF normalizedPos) { - _markers->updateMarker(id, getWallPos(normalizedPos)); - }); - connect(_touchListener.get(), &MultitouchListener::touchPointRemoved, - [this](const int id, const QPointF) { - _markers->removeMarker(id); - }); -} -#endif - #if TIDE_ENABLE_REST_INTERFACE void MasterApplication::_initRestInterface() { @@ -561,36 +483,42 @@ void MasterApplication::_initRestInterface() _masterToWallChannel->sendRequestScreenshot(); }); + connect(&appController, &AppController::powerOff, this, + &MasterApplication::_suspend); + connect(&appController, &AppController::exit, [this]() { exit(); }); +} +#endif #if TIDE_ENABLE_PLANAR_CONTROLLER - if (_planarController) - { - connect(_planarController.get(), &PlanarController::powerStateChanged, - _logger.get(), &LoggingUtility::logScreenStateChanged); - - connect(_planarController.get(), &PlanarController::powerStateChanged, - [this](const ScreenState state) { - if (state == ScreenState::ON) - _inactivityTimer->restart(); - else - _inactivityTimer->stop(); - }); - - connect(_planarController.get(), &PlanarController::powerStateChanged, - [this](const ScreenState state) { - if (state == ScreenState::OFF) - _lock->unlock(); - }); - - connect(&appController, &AppController::powerOff, [this]() { - if (_planarController->powerOff()) - DisplayGroupController(*_displayGroup).hidePanels(); - else - print_log(LOG_ERROR, LOG_POWER, - "Could not power off the screens"); - }); - } +void MasterApplication::_initPlanarController() +{ + _planarController.reset( + new PlanarController(_config->getPlanarSerialPort())); + + connect(_inactivityTimer.get(), &InactivityTimer::poweroff, [this]() { + _planarController->powerOff(); + print_log(LOG_INFO, LOG_POWER, + "Powering off the screens on inactivity timeout"); + }); + + connect(_planarController.get(), &PlanarController::powerStateChanged, + [this](const ScreenState state) { + if (state == ScreenState::ON) + _inactivityTimer->restart(); + else + _inactivityTimer->stop(); + }); + + connect(_planarController.get(), &PlanarController::powerStateChanged, + [this](const ScreenState state) { + if (state == ScreenState::OFF) + _lock->unlock(); + }); + +#if TIDE_ENABLE_REST_INTERFACE + connect(_planarController.get(), &PlanarController::powerStateChanged, + _logger.get(), &LoggingUtility::logScreenStateChanged); #endif } #endif @@ -609,6 +537,34 @@ void MasterApplication::_restoreBackground() } } +void MasterApplication::_suspend() +{ +#if TIDE_ENABLE_PLANAR_CONTROLLER + if (_planarController && _planarController->getState() == ScreenState::ON) + { + if (_planarController->powerOff()) + DisplayGroupController(*_displayGroup).hidePanels(); + else + print_log(LOG_ERROR, LOG_POWER, "Could not power off the screens"); + } +#endif +} + +void MasterApplication::_resume() +{ +#if TIDE_ENABLE_PLANAR_CONTROLLER + if (_planarController && _planarController->getState() == ScreenState::OFF) + { + if (_planarController->powerOn()) + print_log(LOG_INFO, LOG_POWER, + "Powered on the screens by touching the wall"); + else + print_log(LOG_ERROR, LOG_POWER, + "Could not power on the screens by touching the wall"); + } +#endif +} + void MasterApplication::_apply(DisplayGroupConstPtr group) { _displayGroup->setContentWindows(group->getContentWindows()); @@ -633,3 +589,51 @@ void MasterApplication::_deleteTempContentFile(ContentWindowPtr window) filename.toLocal8Bit().constData()); } } + +bool MasterApplication::notify(QObject* receiver, QEvent* event) +{ + switch (event->type()) + { + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + case QEvent::TouchCancel: + { + _handle(static_cast(event)); + } + default: + break; + } + return QApplication::notify(receiver, event); +} + +void MasterApplication::_handle(const QTouchEvent* event) +{ + _inactivityTimer->restart(); + _resume(); + + const auto wallSize = _config->getTotalSize(); + auto getWallPos = [wallSize](const QPointF& normalizedPos) { + return QPointF{normalizedPos.x() * wallSize.width(), + normalizedPos.y() * wallSize.height()}; + }; + + for (const auto& point : event->touchPoints()) + { + switch (point.state()) + { + case Qt::TouchPointPressed: + _markers->addMarker(point.id(), getWallPos(point.normalizedPos())); + break; + case Qt::TouchPointMoved: + _markers->updateMarker(point.id(), + getWallPos(point.normalizedPos())); + break; + case Qt::TouchPointReleased: + _markers->removeMarker(point.id()); + break; + case Qt::TouchPointStationary: + break; + } + } +} diff --git a/tide/master/MasterApplication.h b/tide/master/MasterApplication.h index eb4cfe8a..4470506e 100644 --- a/tide/master/MasterApplication.h +++ b/tide/master/MasterApplication.h @@ -44,9 +44,6 @@ #include "types.h" #include -#if TIDE_ENABLE_TUIO_TOUCH_LISTENER -#include -#endif #if TIDE_ENABLE_PLANAR_CONTROLLER #include "PlanarController.h" @@ -65,7 +62,6 @@ class MasterWindow; class PixelStreamerLauncher; class PixelStreamWindowManager; class MasterConfiguration; -class MultitouchListener; class RestInterface; class ScreenshotAssembler; class LoggingUtility; @@ -87,7 +83,7 @@ class MasterApplication : public QApplication * @param forkChannel The MPI channel for forking processes * @throw std::runtime_error if an error occured during initialization */ - MasterApplication(int &argc, char **argv, const QString &config, + MasterApplication(int& argc, char** argv, const QString& config, MPIChannelPtr worldChannel, MPIChannelPtr forkChannel); /** Destructor */ @@ -123,11 +119,6 @@ class MasterApplication : public QApplication std::unique_ptr _pixelStreamerLauncher; std::unique_ptr _pixelStreamWindowManager; -#if TIDE_ENABLE_TUIO_TOUCH_LISTENER - std::unique_ptr _touchListener; - std::unique_ptr _touchInjector; -#endif - #if TIDE_ENABLE_REST_INTERFACE std::unique_ptr _restInterface; std::unique_ptr _logger; @@ -153,16 +144,20 @@ class MasterApplication : public QApplication void _initOffscreenView(); void _startDeflectServer(); void _setupMPIConnections(); -#if TIDE_ENABLE_TUIO_TOUCH_LISTENER - using MapToSceneFunc = deflect::qt::TouchInjector::MapToSceneFunc; - void _initTouchListener(); -#endif #if TIDE_ENABLE_REST_INTERFACE void _initRestInterface(); +#endif +#if TIDE_ENABLE_PLANAR_CONTROLLER + void _initPlanarController(); #endif void _restoreBackground(); + void _suspend(); + void _resume(); void _apply(DisplayGroupConstPtr group); void _deleteTempContentFile(ContentWindowPtr window); + + bool notify(QObject* receiver, QEvent* event) final; + void _handle(const QTouchEvent* event); }; #endif diff --git a/tide/master/MultitouchListener.cpp b/tide/master/MultitouchListener.cpp deleted file mode 100644 index d5f400bd..00000000 --- a/tide/master/MultitouchListener.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/*********************************************************************/ -/* Copyright (c) 2013-2017, EPFL/Blue Brain Project */ -/* Daniel Nachbaur */ -/* Raphael Dumusc */ -/* All rights reserved. */ -/* */ -/* Redistribution and use in source and binary forms, with or */ -/* without modification, are permitted provided that the following */ -/* conditions are met: */ -/* */ -/* 1. Redistributions of source code must retain the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer. */ -/* */ -/* 2. Redistributions in binary form must reproduce the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer in the documentation and/or other materials */ -/* provided with the distribution. */ -/* */ -/* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF TEXAS AT */ -/* AUSTIN ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, */ -/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ -/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ -/* DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT */ -/* AUSTIN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ -/* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ -/* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE */ -/* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR */ -/* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */ -/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ -/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT */ -/* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* The views and conclusions contained in the software and */ -/* documentation are those of the authors and should not be */ -/* interpreted as representing official policies, either expressed */ -/* or implied, of Ecole polytechnique federale de Lausanne. */ -/*********************************************************************/ - -#include "MultitouchListener.h" - -#include "log.h" - -#include - -#include - -struct TuioLogInit -{ - TuioLogInit() { TUIO::setLogHandler(tuioMessageLogger); } -}; -static TuioLogInit instance; - -MultitouchListener::MultitouchListener() - : TUIO::TuioListener() -{ - if (!_client.socket) - throw std::runtime_error("TUIO could not start listening on UDP 3333"); - _client.addTuioListener(this); - _client.connect(); -} - -MultitouchListener::~MultitouchListener() -{ - _client.removeTuioListener(this); - _client.disconnect(); -} - -inline QPointF _getPos(TUIO::TuioCursor* tcur) -{ - return QPointF{tcur->getX(), tcur->getY()}; -} - -void MultitouchListener::addTuioCursor(TUIO::TuioCursor* tcur) -{ - emit touchPointAdded(tcur->getCursorID(), _getPos(tcur)); -} - -void MultitouchListener::updateTuioCursor(TUIO::TuioCursor* tcur) -{ - emit touchPointUpdated(tcur->getCursorID(), _getPos(tcur)); -} - -void MultitouchListener::removeTuioCursor(TUIO::TuioCursor* tcur) -{ - emit touchPointRemoved(tcur->getCursorID(), _getPos(tcur)); -} diff --git a/tide/master/MultitouchListener.h b/tide/master/MultitouchListener.h deleted file mode 100644 index d7ba2ffc..00000000 --- a/tide/master/MultitouchListener.h +++ /dev/null @@ -1,79 +0,0 @@ -/*********************************************************************/ -/* Copyright (c) 2013-2016, EPFL/Blue Brain Project */ -/* Daniel Nachbaur */ -/* Raphael Dumusc */ -/* All rights reserved. */ -/* */ -/* Redistribution and use in source and binary forms, with or */ -/* without modification, are permitted provided that the following */ -/* conditions are met: */ -/* */ -/* 1. Redistributions of source code must retain the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer. */ -/* */ -/* 2. Redistributions in binary form must reproduce the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer in the documentation and/or other materials */ -/* provided with the distribution. */ -/* */ -/* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF TEXAS AT */ -/* AUSTIN ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, */ -/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ -/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ -/* DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT */ -/* AUSTIN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ -/* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ -/* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE */ -/* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR */ -/* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */ -/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ -/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT */ -/* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ -/* POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/* The views and conclusions contained in the software and */ -/* documentation are those of the authors and should not be */ -/* interpreted as representing official policies, either expressed */ -/* or implied, of Ecole polytechnique federale de Lausanne. */ -/*********************************************************************/ - -#ifndef MULTITOUCHLISTENER_H -#define MULTITOUCHLISTENER_H - -#include -#include - -#include -#include - -/** - * Listen to TUIO touch events and emit corresponding QSignals. - */ -class MultitouchListener : public QObject, public TUIO::TuioListener -{ - Q_OBJECT - Q_DISABLE_COPY(MultitouchListener) - -public: - MultitouchListener(); - ~MultitouchListener(); - - void addTuioObject(TUIO::TuioObject*) override {} - void updateTuioObject(TUIO::TuioObject*) override {} - void removeTuioObject(TUIO::TuioObject*) override {} - void addTuioCursor(TUIO::TuioCursor* tcur) override; - void updateTuioCursor(TUIO::TuioCursor* tcur) override; - void removeTuioCursor(TUIO::TuioCursor* tcur) override; - - void refresh(TUIO::TuioTime) override {} -signals: - void touchPointAdded(int id, QPointF normalizedPos); - void touchPointUpdated(int id, QPointF normalizedPos); - void touchPointRemoved(int id, QPointF normalizedPos); - -private: - TUIO::TuioClient _client; -}; - -#endif diff --git a/tide/master/PlanarController.h b/tide/master/PlanarController.h index 8a7cc8d0..5165e2f9 100644 --- a/tide/master/PlanarController.h +++ b/tide/master/PlanarController.h @@ -68,12 +68,12 @@ class PlanarController : public QObject /** Refresh the power state of Planar displays */ void checkPowerState(); - /** Power off Planar displays */ - bool powerOff(); - - /** Power on Planar displays */ + /** Power on the displays. */ bool powerOn(); + /** Power off the displays. */ + bool powerOff(); + signals: /** Emitted when power state of Planar displays changes */ void powerStateChanged(ScreenState state); diff --git a/tide/master/ui/MasterQuickView.cpp b/tide/master/ui/MasterQuickView.cpp index ddf8e679..028781f7 100644 --- a/tide/master/ui/MasterQuickView.cpp +++ b/tide/master/ui/MasterQuickView.cpp @@ -136,8 +136,24 @@ bool MasterQuickView::event(QEvent* evt) emit mouseReleased(_wallItem->mapFromScene(e->localPos())); break; } + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + case QEvent::TouchCancel: + { + _mapTouchEvent(static_cast(evt)); + } default: break; } return QQuickView::event(evt); } + +void MasterQuickView::_mapTouchEvent(QTouchEvent* event) +{ + for (const auto& point : event->touchPoints()) + { + auto& p = const_cast(point); + p.setPos(mapToWallPos(point.normalizedPos())); + } +} diff --git a/tide/master/ui/MasterQuickView.h b/tide/master/ui/MasterQuickView.h index ab4828c0..e8b819c3 100644 --- a/tide/master/ui/MasterQuickView.h +++ b/tide/master/ui/MasterQuickView.h @@ -81,6 +81,7 @@ class MasterQuickView : public QQuickView private: /** Re-implement QWindow event to capture tab key. */ bool event(QEvent* event) final; + void _mapTouchEvent(QTouchEvent* event); QQuickItem* _wallItem = nullptr; };