diff --git a/src/Gui/Quarter/Basic.h b/src/Gui/Quarter/Basic.h new file mode 100644 index 000000000..ab7a97d57 --- /dev/null +++ b/src/Gui/Quarter/Basic.h @@ -0,0 +1,77 @@ +#ifndef QUARTER_BASIC_H +#define QUARTER_BASIC_H + +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +/* + See Coin's Inventor/C/basic.h for an explanation to the below #define + setup. +*/ + +#ifdef QUARTER_DLL_API +#error Leave the QUARTER_DLL_API define alone +#endif // QUARTER_MAKE_DLL + +#ifdef QUARTER_INTERNAL +# ifdef QUARTER_NOT_DLL +# error The QUARTER_DLL define should not be used when building the library - only when building win32 applications. +# endif // QUARTER_NOT_DLL +# ifdef QUARTER_DLL +# error The QUARTER_NOT_DLL define should not be used when building the library - only when building win32 applications. +# endif // QUARTER_DLL +#endif // QUARTER_INTERNAL + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) +# ifdef QUARTER_INTERNAL +# ifdef QUARTER_MAKE_DLL +# define QUARTER_DLL_API __declspec(dllexport) +# endif // QUARTER_MAKE_DLL +# else // !QUARTER_INTERNAL +# ifdef QUARTER_DLL +# ifdef QUARTER_NOT_DLL +# error Define _either_ QUARTER_DLL or QUARTER_NOT_DLL as appropriate for your linkage -- not both at the same time! See the Coin Inventor/C/basic.h for further instructions. +# endif // QUARTER_NOT_DLL +# define QUARTER_DLL_API __declspec(dllimport) +# else // !QUARTER_DLL +# ifndef QUARTER_NOT_DLL +# error Define either QUARTER_DLL or QUARTER_NOT_DLL as appropriate for your linkage. See the Coin Inventor/C/basic.h for further instructions. +# endif // !QUARTER_NOT_DLL +# endif // !QUARTER_DLL +# endif // !QUARTER_INTERNAL +#endif // Microsoft Windows + +#ifndef QUARTER_DLL_API +# define QUARTER_DLL_API +#endif // !QUARTER_DLL_API + +#endif // !QUARTER_BASIC_H diff --git a/src/Gui/Quarter/CMakeLists.txt b/src/Gui/Quarter/CMakeLists.txt new file mode 100644 index 000000000..45ee147fd --- /dev/null +++ b/src/Gui/Quarter/CMakeLists.txt @@ -0,0 +1,85 @@ +INCLUDE(SimQtMacros) + +SET(Library Quarter) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) + +# We R internal +ADD_DEFINITIONS(-DQUARTER_INTERNAL) + +FILE(GLOB CMakeCache RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_BINARY_DIR}/CMakeCache.txt) + +# Generate list of sources and headers for compilation +FILE(GLOB_RECURSE Sources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) +FILE(GLOB_RECURSE PublicHeaders RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h) +FILE(GLOB_RECURSE PrivateHeaders RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ../../include/Quarter/*.h) + +# Find the headers that should be Moc'ed +FILE(GLOB_RECURSE MocPrivateHeaders RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h) +FILE(GLOB_RECURSE MocPublicHeaders RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ../../include/Quarter/*.h) + +# Moc both the public and private headers +SIM_QT4_AUTO_WRAP_CPP(MocPrivateSources ${MocPrivateHeaders}) +SIM_QT4_AUTO_WRAP_CPP(MocPublicSources ${MocPublicHeaders}) + +# Some convenient variables. The inclusion of the headers in the source variable is to force CMake to include the headers in VS project generation. +SET(AllSources ${Sources} ${MocPublicSources} ${MocPrivateSources} ${PublicHeaders} ${PrivateHeaders} ${CMakeCache}) + + +IF (Spacenav_FOUND) + SET(Extra_libraries ${Spacenav_LIBRARIES} ${Spacenav_LIBRARY}) +ENDIF(Spacenav_FOUND) + + +SET(AllLibs ${Coin_LIBRARY} ${QT_LIBRARIES} ${OPENGL_LIBRARY} ${Extra_libraries}) + + + +# Ensure export of DLL definitions on Windows +IF(WIN32 AND NOT Quarter_BUILD_STATIC_LIBRARY) + ADD_DEFINITIONS(-DQUARTER_MAKE_DLL) +ENDIF(WIN32 AND NOT Quarter_BUILD_STATIC_LIBRARY) + +# Add some files and filters to make the VS project more hierarchical and practical to work with +IF(MSVC_IDE) + FILE(GLOB DeviceSources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} devices/*.cpp) + FILE(GLOB DeviceHeaders RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} devices/*.h) + FILE(GLOB PrivateDeviceHeaders RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ../../include/Quarter/devices/*.h) + + FILE(GLOB EventHandlerSources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} eventhandlers/*.cpp) + FILE(GLOB EventHandlerHeaders RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} eventhandlers/*.h) + FILE(GLOB PrivateEventHandlerHeaders RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ../../include/Quarter/eventhandlers/*.h) + + SIM_VS_GENERATE_BASIC_TREE() + SOURCE_GROUP("Source\\Devices" FILES ${DeviceSources}) + SOURCE_GROUP("Source\\EventHandlers" FILES ${EventHandlerSources}) + SOURCE_GROUP("Headers\\Devices" FILES ${DeviceHeaders}) + SOURCE_GROUP("Headers\\Devices" FILES ${PrivateDeviceHeaders}) + SOURCE_GROUP("Headers\\EventHandlers" FILES ${EventHandlerHeaders}) + SOURCE_GROUP("Headers\\EventHandlers" FILES ${PrivateEventHandlerHeaders}) +ENDIF(MSVC_IDE) + +# Create the library +# FIXME: Support building as a framework on Mac OS X. kintel 20080707. +IF(Quarter_BUILD_STATIC_LIBRARY) + ADD_LIBRARY(${Library} STATIC ${AllSources}) +ELSE(Quarter_BUILD_STATIC_LIBRARY) + ADD_LIBRARY(${Library} SHARED ${AllSources}) + TARGET_LINK_LIBRARIES(${Library} ${AllLibs}) +ENDIF(Quarter_BUILD_STATIC_LIBRARY) + +# Install configuration +# +# Quarter will be installed into the directory configured by CMAKE_INSTALL_PREFIX. This +# defaults to /usr/local/ on UNIX and c:/Program Files/Quarter on Windows. +# +# On Windows, the namimg convention is as follows (ripped from the "Coin" way of doing stuff): +# Dynamic Release: Quarter.dll and Quarter.lib +# Dynamic Debug: Quarterd.dll and Quarterd.lib +# Static Release: Quarters.lib +# Static Debug: Quartersd.lib + +INSTALL(TARGETS ${Library} + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) diff --git a/src/Gui/Quarter/ContextMenu.cpp b/src/Gui/Quarter/ContextMenu.cpp new file mode 100644 index 000000000..ce17050b9 --- /dev/null +++ b/src/Gui/Quarter/ContextMenu.cpp @@ -0,0 +1,174 @@ + +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include "ContextMenu.h" + +#include + +#include +#include + +#include + +using namespace SIM::Coin3D::Quarter; + +ContextMenu::ContextMenu(QuarterWidget * quarterwidget) + : quarterwidget(quarterwidget) +{ + this->contextmenu = new QMenu; + this->functionsmenu = new QMenu("Functions"); + this->rendermenu = new QMenu("Render Mode"); + this->stereomenu = new QMenu("Stereo Mode"); + this->transparencymenu = new QMenu("Transparency Type"); + + this->contextmenu->addMenu(functionsmenu); + this->contextmenu->addMenu(rendermenu); + this->contextmenu->addMenu(stereomenu); + this->contextmenu->addMenu(transparencymenu); + + SoRenderManager * sorendermanager = quarterwidget->getSoRenderManager(); + + QActionGroup * rendermodegroup = NULL; + QActionGroup * stereomodegroup = NULL; + QActionGroup * transparencytypegroup = NULL; + + foreach (QAction * action, quarterwidget->renderModeActions()) { + if (!rendermodegroup) { + rendermodegroup = action->actionGroup(); + } else { + assert(rendermodegroup && rendermodegroup == action->actionGroup()); + } + + int rendermode = static_cast(sorendermanager->getRenderMode()); + int data = static_cast(action->data().toInt()); + action->setChecked(rendermode == data); + rendermenu->addAction(action); + } + + foreach (QAction * action, quarterwidget->stereoModeActions()) { + if (!stereomodegroup) { + stereomodegroup = action->actionGroup(); + } else { + assert(stereomodegroup && stereomodegroup == action->actionGroup()); + } + + int stereomode = static_cast(sorendermanager->getStereoMode()); + int data = static_cast(action->data().toInt()); + action->setChecked(stereomode == data); + stereomenu->addAction(action); + } + + foreach (QAction * action, quarterwidget->transparencyTypeActions()) { + if (!transparencytypegroup) { + transparencytypegroup = action->actionGroup(); + } else { + assert(transparencytypegroup && transparencytypegroup == action->actionGroup()); + } + + SoGLRenderAction * renderaction = sorendermanager->getGLRenderAction(); + int transparencytype = static_cast(renderaction->getTransparencyType()); + int data = static_cast(action->data().toInt()); + action->setChecked(transparencytype == data); + transparencymenu->addAction(action); + } + + QAction * viewall = new QAction("View All", quarterwidget); + QAction * seek = new QAction("Seek", quarterwidget); + functionsmenu->addAction(viewall); + functionsmenu->addAction(seek); + + QObject::connect(seek, SIGNAL(triggered()), + this->quarterwidget, SLOT(seek())); + + QObject::connect(viewall, SIGNAL(triggered()), + this->quarterwidget, SLOT(viewAll())); + + // FIXME: It would be ideal to expose these actiongroups to Qt + // Designer and be able to connect them to the appropriate slots on + // QuarterWidget, but this is not possible in Qt. Exposing every + // single action is supposed to work, but it doesn't at the + // moment. (20081215 frodo) + QObject::connect(rendermodegroup, SIGNAL(triggered(QAction *)), + this, SLOT(changeRenderMode(QAction *))); + + QObject::connect(stereomodegroup, SIGNAL(triggered(QAction *)), + this, SLOT(changeStereoMode(QAction *))); + + QObject::connect(transparencytypegroup, SIGNAL(triggered(QAction *)), + this, SLOT(changeTransparencyType(QAction *))); +} + +ContextMenu::~ContextMenu() +{ + delete this->functionsmenu; + delete this->rendermenu; + delete this->stereomenu; + delete this->transparencymenu; + delete this->contextmenu; +} + +QMenu * +ContextMenu::getMenu(void) const +{ + return this->contextmenu; +} + +void +ContextMenu::changeRenderMode(QAction * action) +{ + QuarterWidget::RenderMode mode = + static_cast(action->data().toInt()); + + this->quarterwidget->setRenderMode(mode); + this->quarterwidget->getSoRenderManager()->scheduleRedraw(); +} + +void +ContextMenu::changeStereoMode(QAction * action) +{ + QuarterWidget::StereoMode mode = + static_cast(action->data().toInt()); + + this->quarterwidget->setStereoMode(mode); + this->quarterwidget->getSoRenderManager()->scheduleRedraw(); +} + +void +ContextMenu::changeTransparencyType(QAction * action) +{ + QuarterWidget::TransparencyType type = + static_cast(action->data().toInt()); + + this->quarterwidget->setTransparencyType(type); + this->quarterwidget->getSoRenderManager()->scheduleRedraw(); +} diff --git a/src/Gui/Quarter/ContextMenu.h b/src/Gui/Quarter/ContextMenu.h new file mode 100644 index 000000000..ac44f98dd --- /dev/null +++ b/src/Gui/Quarter/ContextMenu.h @@ -0,0 +1,70 @@ +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#ifndef QUARTER_CONTEXTMENUHANDLERP_H +#define QUARTER_CONTEXTMENUHANDLERP_H + +#include + +class QMenu; +class QAction; + +namespace SIM { namespace Coin3D { namespace Quarter { + +class QuarterWidget; + +class ContextMenu : public QObject { + Q_OBJECT +public: + ContextMenu(QuarterWidget * quarterwidget); + ~ContextMenu(); + + QMenu * getMenu(void) const; + +public slots: + void changeRenderMode(QAction * action); + void changeStereoMode(QAction * action); + void changeTransparencyType(QAction * action); + +private: + QuarterWidget * quarterwidget; + + QMenu * contextmenu; + QMenu * rendermenu; + QMenu * stereomenu; + QMenu * functionsmenu; + QMenu * transparencymenu; +}; + +}}} // namespace + +#endif // QUARTER_CONTEXTMENUHANDLERP_H diff --git a/src/Gui/Quarter/DragDropHandler.cpp b/src/Gui/Quarter/DragDropHandler.cpp new file mode 100644 index 000000000..8976e953c --- /dev/null +++ b/src/Gui/Quarter/DragDropHandler.cpp @@ -0,0 +1,162 @@ +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +/*! + \class SIM::Coin3D::Quarter::DragDropHandler DragDropHandler.h Quarter/devices/DragDropHandler.h + + \brief The DragDropHandler event filter provides drag and drop + functionality to the QuarterWidget. +*/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +namespace SIM { namespace Coin3D { namespace Quarter { + +class DragDropHandlerP { +public: + DragDropHandlerP(DragDropHandler * master) { + this->master = master; + } + void dragEnterEvent(QDragEnterEvent * event); + void dropEvent(QDropEvent * event); + + QStringList suffixes; + DragDropHandler * master; + QuarterWidget * quarterwidget; +}; + +}}} // namespace + +#define PRIVATE(obj) obj->pimpl +#define PUBLIC(obj) obj->master + +using namespace SIM::Coin3D::Quarter; + +/*! + Constructor + + \sa QObject::QObject(QObject *) +*/ +DragDropHandler::DragDropHandler(QuarterWidget * parent) + : QObject(parent) +{ + PRIVATE(this) = new DragDropHandlerP(this); + PRIVATE(this)->quarterwidget = parent; + assert(PRIVATE(this)->quarterwidget); + PRIVATE(this)->suffixes << "iv" << "wrl"; +} + +DragDropHandler::~DragDropHandler() +{ + delete PRIVATE(this); +} + +/*! + Detects a QDragEnterEvent and if the event is the dropping of a + valid Inventor or VRML it opens the file, reads in the scenegraph + and calls setSceneGraph on the QuarterWidget + */ +bool +DragDropHandler::eventFilter(QObject *, QEvent * event) +{ + switch (event->type()) { + case QEvent::DragEnter: + PRIVATE(this)->dragEnterEvent(dynamic_cast(event)); + return true; + case QEvent::Drop: + PRIVATE(this)->dropEvent(dynamic_cast(event)); + return true; + default: + return false; + } +} + +void +DragDropHandlerP::dragEnterEvent(QDragEnterEvent * event) +{ + const QMimeData * mimedata = event->mimeData(); + if (!mimedata->hasUrls() && !mimedata->hasText()) return; + + if (mimedata->hasUrls()) { + QFileInfo fileinfo(mimedata->urls().takeFirst().path()); + QString suffix = fileinfo.suffix().toLower(); + if (!this->suffixes.contains(suffix)) { return; } + } + + event->acceptProposedAction(); +} + +void +DragDropHandlerP::dropEvent(QDropEvent * event) +{ + const QMimeData * mimedata = event->mimeData(); + + SoSeparator * root; + SoInput in; + QByteArray bytes; + + if (mimedata->hasUrls()) { + QUrl url = mimedata->urls().takeFirst(); + if (url.scheme().isEmpty() || url.scheme().toLower() == QString("file") ) { + // attempt to open file + if (!in.openFile(url.toLocalFile().toLatin1().constData())) return; + } + } else if (mimedata->hasText()) { + /* FIXME 2007-11-09 preng: dropping text buffer does not work on Windows Vista. */ + bytes = mimedata->text().toUtf8(); + in.setBuffer((void *) bytes.constData(), bytes.size()); + if (!in.isValidBuffer()) return; + } + + // attempt to import it + root = SoDB::readAll(&in); + if (root == NULL) return; + + // set new scenegraph + this->quarterwidget->setSceneGraph(root); + this->quarterwidget->updateGL(); +} + +#undef PRIVATE +#undef PUBLIC diff --git a/src/Gui/Quarter/EventFilter.cpp b/src/Gui/Quarter/EventFilter.cpp new file mode 100644 index 000000000..6bd9bf94d --- /dev/null +++ b/src/Gui/Quarter/EventFilter.cpp @@ -0,0 +1,180 @@ +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +/*! \class SIM::Coin3D::Quarter::EventFilter EventFilter.h Quarter/eventhandlers/EventFilter.h + +*/ + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +namespace SIM { namespace Coin3D { namespace Quarter { + +class EventFilterP { +public: + QList devices; + QuarterWidget * quarterwidget; + QPoint globalmousepos; + SbVec2s windowsize; + + void trackWindowSize(QResizeEvent * event) + { + this->windowsize = SbVec2s(event->size().width(), + event->size().height()); + + foreach(InputDevice * device, this->devices) { + device->setWindowSize(this->windowsize); + } + } + + void trackPointerPosition(QMouseEvent * event) + { + assert(this->windowsize[1] != -1); + this->globalmousepos = event->globalPos(); + + SbVec2s mousepos(event->pos().x(), this->windowsize[1] - event->pos().y() - 1); + foreach(InputDevice * device, this->devices) { + device->setMousePosition(mousepos); + } + } + +}; + +#define PRIVATE(obj) obj->pimpl + +}}} // namespace + +using namespace SIM::Coin3D::Quarter; + +EventFilter::EventFilter(QObject * parent) + : QObject(parent) +{ + PRIVATE(this) = new EventFilterP; + + PRIVATE(this)->quarterwidget = dynamic_cast(parent); + assert(PRIVATE(this)->quarterwidget); + + PRIVATE(this)->windowsize = SbVec2s(PRIVATE(this)->quarterwidget->width(), + PRIVATE(this)->quarterwidget->height()); + + PRIVATE(this)->devices += new Mouse; + PRIVATE(this)->devices += new Keyboard; + +#ifdef HAVE_SPACENAV_LIB + PRIVATE(this)->devices += new SpaceNavigatorDevice; +#endif // HAVE_SPACENAV_LIB + +} + +EventFilter::~EventFilter() +{ + qDeleteAll(PRIVATE(this)->devices); + delete PRIVATE(this); +} + +/*! + Adds a device for event translation + */ +void +EventFilter::registerInputDevice(InputDevice * device) +{ + PRIVATE(this)->devices += device; +} + +/*! + Removes a device from event translation + */ +void +EventFilter::unregisterInputDevice(InputDevice * device) +{ + int i = PRIVATE(this)->devices.indexOf(device); + if (i != -1) { + PRIVATE(this)->devices.removeAt(i); + } +} + +/*! Translates Qt Events into Coin events and passes them on to the + event QuarterWidget for processing. If the event can not be + translated or processed, it is forwarded to Qt and the method + returns false. + */ +bool +EventFilter::eventFilter(QObject * obj, QEvent * qevent) +{ + // make sure every device has updated screen size and mouse position + // before translating events + switch (qevent->type()) { + case QEvent::MouseMove: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + PRIVATE(this)->trackPointerPosition(dynamic_cast(qevent)); + break; + case QEvent::Resize: + PRIVATE(this)->trackWindowSize(dynamic_cast(qevent)); + break; + default: + break; + } + + // translate QEvent into SoEvent and see if it is handled by scene + // graph + foreach(InputDevice * device, PRIVATE(this)->devices) { + const SoEvent * soevent = device->translateEvent(qevent); + if (soevent && PRIVATE(this)->quarterwidget->processSoEvent(soevent)) { + return true; + } + } + return false; +} + +/*! + Returns mouse position in global coordinates + */ +const QPoint & +EventFilter::globalMousePosition(void) const +{ + return PRIVATE(this)->globalmousepos; +} + +#undef PRIVATE diff --git a/src/Gui/Quarter/FocusHandler.cpp b/src/Gui/Quarter/FocusHandler.cpp new file mode 100644 index 000000000..febf9634e --- /dev/null +++ b/src/Gui/Quarter/FocusHandler.cpp @@ -0,0 +1,85 @@ +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +/*! + \class SIM::Coin3D::Quarter::FocusHandler FocusHandler.h Quarter/devices/FocusHandler.h + + \brief The FocusHandler eventfilter provides Coin with focus in and + focus out events, if installed on QuarterWidget. +*/ + +#include +#include +#include +#include +#include + +using namespace SIM::Coin3D::Quarter; + +FocusHandler::FocusHandler(QObject * parent) + : QObject(parent) +{ + this->quarterwidget = dynamic_cast(parent); +} + +FocusHandler::~FocusHandler() +{ + +} + +bool +FocusHandler::eventFilter(QObject * obj, QEvent * event) +{ + switch (event->type()) { + case QEvent::FocusIn: + this->focusEvent("sim.coin3d.coin.InputFocus.IN"); + break; + case QEvent::FocusOut: + this->focusEvent("sim.coin3d.coin.InputFocus.OUT"); + break; + } + return QObject::eventFilter(obj, event); +} + +void +FocusHandler::focusEvent(const SbName & focusevent) +{ + SoEventManager * eventmanager = this->quarterwidget->getSoEventManager(); + for (int c = 0; c < eventmanager->getNumSoScXMLStateMachines(); ++c) { + SoScXMLStateMachine * sostatemachine = + eventmanager->getSoScXMLStateMachine(c); + if (sostatemachine->isActive()) { + sostatemachine->queueEvent(focusevent); + sostatemachine->processEventQueue(); + } + } +} diff --git a/src/Gui/Quarter/ImageReader.cpp b/src/Gui/Quarter/ImageReader.cpp new file mode 100644 index 000000000..2f2ecae27 --- /dev/null +++ b/src/Gui/Quarter/ImageReader.cpp @@ -0,0 +1,80 @@ +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include "ImageReader.h" +#include +#include +#include + +#include + +using namespace SIM::Coin3D::Quarter; + +ImageReader::ImageReader(void) +{ + SbImage::addReadImageCB(ImageReader::readImageCB, this); +} + +ImageReader::~ImageReader(void) +{ + SbImage::removeReadImageCB(ImageReader::readImageCB, this); +} + +SbBool +ImageReader::readImage(const SbString & filename, SbImage & sbimage) const +{ + QImage image; + if (image.load(filename.getString())) { + int c; + int w = image.width(); + int h = image.height(); + + // Keep in 8-bits mode if that was what we read + if (image.depth() != 8 || !image.isGrayscale()) { + // FIXME: consider if we should detect allGrayscale() and alpha (c = 2) + image = image.convertToFormat(image.hasAlphaChannel() ? + QImage::Format_ARGB32 : QImage::Format_RGB32); + } + + QtCoinCompatibility::QImageToSbImage(image,sbimage); + return TRUE; + } + return FALSE; +} + + + +SbBool +ImageReader::readImageCB(const SbString & filename, SbImage * image, void * closure) +{ + return ((ImageReader*)closure)->readImage(filename, *image); +} diff --git a/src/Gui/Quarter/ImageReader.h b/src/Gui/Quarter/ImageReader.h new file mode 100644 index 000000000..a0da5ad52 --- /dev/null +++ b/src/Gui/Quarter/ImageReader.h @@ -0,0 +1,57 @@ +#ifndef QUARTER_IMAGELOADER_H +#define QUARTER_IMAGELOADER_H + +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include + +class SbImage; +class SbString; +class QImage; + +namespace SIM { namespace Coin3D { namespace Quarter { + +class ImageReader { +public: + ImageReader(void); + ~ImageReader(void); + + SbBool readImage(const SbString & filename, SbImage & image) const; + +private: + static SbBool readImageCB(const SbString & filename, SbImage * image, void * closure); +}; + +}}} // namespace + +#endif // QUARTER_IMAGELOADER_H diff --git a/src/Gui/Quarter/InputDevice.cpp b/src/Gui/Quarter/InputDevice.cpp new file mode 100644 index 000000000..6a074d1cc --- /dev/null +++ b/src/Gui/Quarter/InputDevice.cpp @@ -0,0 +1,107 @@ +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include +#include +#include + +using namespace SIM::Coin3D::Quarter; + +/*! + \class SIM::Coin3D::Quarter::InputDevice InputDevice.h Quarter/devices/InputDevice.h + + \brief The InputDevice class is the base class for devices such as + the Keyboard and Mouse. It can be subclassed to support other + devices. +*/ + +InputDevice::InputDevice(void) +{ + this->mousepos = SbVec2s(0, 0); +} + +/*! + Sets the mouseposition + + \param[in] pos position of mouse in pixelcoordinates +*/ +void +InputDevice::setMousePosition(const SbVec2s & pos) +{ + this->mousepos = pos; +} + +/*! + Sets the window size of the owning window + + \param[in] size in pixels +*/ +void +InputDevice::setWindowSize(const SbVec2s & size) +{ + this->windowsize = size; +} + +/*! + Transforms a qevent into an soevent + + \param[in,out] soevent the transformed event + \param[in] qevent incoming qevent +*/ +void +InputDevice::setModifiers(SoEvent * soevent, const QInputEvent * qevent) +{ + // FIXME: How do we get the time from the qevent? (20070306 frodo) + soevent->setTime(SbTime::getTimeOfDay()); + + // Note: On Mac OS X, the ControlModifier value corresponds to the + // Command keys on the Macintosh keyboard, and the MetaModifier + // value corresponds to the Control keys. + soevent->setShiftDown(qevent->modifiers() & Qt::ShiftModifier); + soevent->setAltDown(qevent->modifiers() & Qt::AltModifier); + soevent->setCtrlDown(qevent->modifiers() & Qt::ControlModifier); +} + +/*! + \var InputDevice::mousepos + + Holds the last known position of the mouse. This should be set even + for a keyboard event. +*/ + +/*! + \var InputDevice::windowsize + + Holds the size of the owning window +*/ + +#undef PRIVATE diff --git a/src/Gui/Quarter/InteractionMode.cpp b/src/Gui/Quarter/InteractionMode.cpp new file mode 100644 index 000000000..6f9a3be69 --- /dev/null +++ b/src/Gui/Quarter/InteractionMode.cpp @@ -0,0 +1,130 @@ +#include "InteractionMode.h" +#include +#include +#include +#include + +/* + Adjust how QuarterWidget reacts to alt key events + */ + +using namespace SIM::Coin3D::Quarter; + +InteractionMode::InteractionMode(QuarterWidget * quarterwidget) + : QObject(quarterwidget) +{ + this->quarterwidget = quarterwidget; + this->altkeydown = false; + this->prevcursor = QCursor(); + this->prevnavstate = + this->quarterwidget->getSoEventManager()->getNavigationState(); + + this->isenabled = true; +} + +InteractionMode::~InteractionMode() +{ + +} + +void +InteractionMode::setEnabled(bool yes) +{ + this->isenabled = yes; +} + +bool +InteractionMode::enabled(void) const +{ + return this->isenabled; +} + +void +InteractionMode::setOn(bool on) +{ + if (!this->isenabled) { + return; + } + + SoEventManager * eventmanager = this->quarterwidget->getSoEventManager(); + + if (on) { + this->altkeydown = true; + this->prevnavstate = eventmanager->getNavigationState(); + this->prevcursor = this->quarterwidget->cursor(); + this->quarterwidget->setCursor(this->quarterwidget->stateCursor("interact")); + eventmanager->setNavigationState(SoEventManager::NO_NAVIGATION); + } else { + this->altkeydown = false; + this->quarterwidget->setCursor(this->prevcursor); + eventmanager->setNavigationState(this->prevnavstate); + } +} + +bool +InteractionMode::on(void) const +{ + return this->altkeydown; +} + +bool +InteractionMode::eventFilter(QObject * obj, QEvent * event) +{ + if (!this->isenabled) { + return false; + } + + assert(obj == this->quarterwidget); + + switch (event->type()) { + case QEvent::KeyPress: + return this->keyPressEvent(dynamic_cast(event)); + case QEvent::KeyRelease: + return this->keyReleaseEvent(dynamic_cast(event)); + case QEvent::FocusOut: + return this->focusOutEvent(dynamic_cast(event)); + default: + return QObject::eventFilter(obj, event); + } +} + +/* + when alt is pressed, override navigation and allow scenegraph to + process events so draggers and manipulators works + */ +bool +InteractionMode::keyPressEvent(QKeyEvent * event) +{ + if (!event || + !(event->key() == Qt::Key_Alt) || + !(event->modifiers() & Qt::AltModifier)) { + return false; + } + + this->setOn(true); + return true; +} + +bool +InteractionMode::keyReleaseEvent(QKeyEvent * event) +{ + if (!event || !(event->key() == Qt::Key_Alt)) { + return false; + } + + this->setOn(false); + return true; +} + +/* + if we lose focus while alt is down, send an alt-release event + */ +bool +InteractionMode::focusOutEvent(QFocusEvent * event) +{ + if (this->altkeydown) { + QKeyEvent keyevent(QEvent::KeyRelease, Qt::Key_Alt, Qt::NoModifier); + return QCoreApplication::sendEvent(this->quarterwidget, &keyevent); + } + return false; +} diff --git a/src/Gui/Quarter/InteractionMode.h b/src/Gui/Quarter/InteractionMode.h new file mode 100644 index 000000000..0397b3290 --- /dev/null +++ b/src/Gui/Quarter/InteractionMode.h @@ -0,0 +1,79 @@ +#ifndef QUARTER_INTERACTIONMODE_H +#define QUARTER_INTERACTIONMODE_H + +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include +#include +#include +#include + +class QEvent; +class SoEvent; +class QKeyEvent; +class QFocusEvent; + +namespace SIM { namespace Coin3D { namespace Quarter { + +class QuarterWidget; + +class QUARTER_DLL_API InteractionMode : public QObject { + Q_OBJECT +public: + InteractionMode(QuarterWidget * quarterwidget); + virtual ~InteractionMode(); + + void setEnabled(bool yes); + bool enabled(void) const; + + void setOn(bool on); + bool on(void) const; + +protected: + virtual bool eventFilter(QObject *, QEvent * event); + +private: + bool keyPressEvent(QKeyEvent * event); + bool keyReleaseEvent(QKeyEvent * event); + bool focusOutEvent(QFocusEvent * event); + + QCursor prevcursor; + QuarterWidget * quarterwidget; + bool altkeydown; + SoEventManager::NavigationState prevnavstate; + bool isenabled; +}; + +}}} // namespace + +#endif // QUARTER_INTERACTIONMODE_H diff --git a/src/Gui/Quarter/Keyboard.cpp b/src/Gui/Quarter/Keyboard.cpp new file mode 100644 index 000000000..f6b6f1a27 --- /dev/null +++ b/src/Gui/Quarter/Keyboard.cpp @@ -0,0 +1,78 @@ +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +/*! + \class SIM::Coin3D::Quarter::Keyboard Keyboard.h Quarter/devices/Keyboard.h + + \brief The Keyboard class provides translation of keyboard events on + the QuarterWidget. +*/ + + +#include + +#include +#include +#include +#include + +#include "KeyboardP.h" + +using namespace SIM::Coin3D::Quarter; + +#define PRIVATE(obj) obj->pimpl + +Keyboard::Keyboard(void) +{ + PRIVATE(this) = new KeyboardP(this); +} + +Keyboard::~Keyboard() +{ + delete PRIVATE(this); +} + +/*! Translates from QKeyEvents to SoKeyboardEvents + */ +const SoEvent * +Keyboard::translateEvent(QEvent * event) +{ + switch (event->type()) { + case QEvent::KeyPress: + case QEvent::KeyRelease: + return PRIVATE(this)->keyEvent((QKeyEvent *) event); + default: + return NULL; + } +} + +#undef PRIVATE diff --git a/src/Gui/Quarter/KeyboardP.cpp b/src/Gui/Quarter/KeyboardP.cpp new file mode 100644 index 000000000..e51e08e9b --- /dev/null +++ b/src/Gui/Quarter/KeyboardP.cpp @@ -0,0 +1,248 @@ +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include "KeyboardP.h" +#include +#include +#include + +using namespace SIM::Coin3D::Quarter; + +#define PUBLIC(obj) obj->publ + +KeyboardP::KeyboardP(Keyboard * publ) +{ + PUBLIC(this) = publ; + this->keyboard = new SoKeyboardEvent; + + if (keyboardmap == NULL) { + keyboardmap = new KeyMap; + keypadmap = new KeyMap; + this->initKeyMap(); + } +} + +KeyboardP::~KeyboardP() +{ + delete this->keyboard; +} + +bool +KeyboardP::debugKeyEvents(void) +{ + const char * env = coin_getenv("QUARTER_DEBUG_KEYEVENTS"); + return env && (atoi(env) > 0); +} + +const SoEvent * +KeyboardP::keyEvent(QKeyEvent * qevent) +{ + const Qt::KeyboardModifiers modifiers = qevent->modifiers(); + + this->keyboard->setPosition(PUBLIC(this)->mousepos); + PUBLIC(this)->setModifiers(this->keyboard, qevent); + + (qevent->type() == QEvent::KeyPress) ? + this->keyboard->setState(SoButtonEvent::DOWN): + this->keyboard->setState(SoButtonEvent::UP); + + Qt::Key qkey = (Qt::Key) qevent->key(); + + SoKeyboardEvent::Key sokey = (modifiers & Qt::KeypadModifier) ? + keypadmap->value(qkey, SoKeyboardEvent::ANY) : + keyboardmap->value(qkey, SoKeyboardEvent::ANY); + + //Need to use a temporary to avoid reference becoming deleted before + //we get a hold of it. + QByteArray tmp = qevent->text().toAscii(); + const char * printable = tmp.constData(); + this->keyboard->setPrintableCharacter(*printable); + this->keyboard->setKey(sokey); + +#if QUARTER_DEBUG + if (KeyboardP::debugKeyEvents()) { + SbString s; + this->keyboard->enumToString(this->keyboard->getKey(), s); + SoDebugError::postInfo("KeyboardP::keyEvent", + "enum: '%s', pos: <%i %i>, printable: '%s'", + s.getString(), + PUBLIC(this)->mousepos[0], + PUBLIC(this)->mousepos[1], + printable); + } +#endif + return this->keyboard; +} + +KeyboardP::KeyMap * KeyboardP::keyboardmap = NULL; +KeyboardP::KeyMap * KeyboardP::keypadmap = NULL; + +void +KeyboardP::initKeyMap(void) +{ + // keyboard + keyboardmap->insert(Qt::Key_Shift, SoKeyboardEvent::LEFT_SHIFT); + keyboardmap->insert(Qt::Key_Alt, SoKeyboardEvent::LEFT_ALT); + keyboardmap->insert(Qt::Key_Control, SoKeyboardEvent::LEFT_CONTROL); + keyboardmap->insert(Qt::Key_0, SoKeyboardEvent::NUMBER_0); + keyboardmap->insert(Qt::Key_1, SoKeyboardEvent::NUMBER_1); + keyboardmap->insert(Qt::Key_2, SoKeyboardEvent::NUMBER_2); + keyboardmap->insert(Qt::Key_3, SoKeyboardEvent::NUMBER_3); + keyboardmap->insert(Qt::Key_4, SoKeyboardEvent::NUMBER_4); + keyboardmap->insert(Qt::Key_5, SoKeyboardEvent::NUMBER_5); + keyboardmap->insert(Qt::Key_6, SoKeyboardEvent::NUMBER_6); + keyboardmap->insert(Qt::Key_7, SoKeyboardEvent::NUMBER_7); + keyboardmap->insert(Qt::Key_8, SoKeyboardEvent::NUMBER_8); + keyboardmap->insert(Qt::Key_9, SoKeyboardEvent::NUMBER_9); + + keyboardmap->insert(Qt::Key_A, SoKeyboardEvent::A); + keyboardmap->insert(Qt::Key_B, SoKeyboardEvent::B); + keyboardmap->insert(Qt::Key_C, SoKeyboardEvent::C); + keyboardmap->insert(Qt::Key_D, SoKeyboardEvent::D); + keyboardmap->insert(Qt::Key_E, SoKeyboardEvent::E); + keyboardmap->insert(Qt::Key_F, SoKeyboardEvent::F); + keyboardmap->insert(Qt::Key_G, SoKeyboardEvent::G); + keyboardmap->insert(Qt::Key_H, SoKeyboardEvent::H); + keyboardmap->insert(Qt::Key_I, SoKeyboardEvent::I); + keyboardmap->insert(Qt::Key_J, SoKeyboardEvent::J); + keyboardmap->insert(Qt::Key_K, SoKeyboardEvent::K); + keyboardmap->insert(Qt::Key_L, SoKeyboardEvent::L); + keyboardmap->insert(Qt::Key_M, SoKeyboardEvent::M); + keyboardmap->insert(Qt::Key_N, SoKeyboardEvent::N); + keyboardmap->insert(Qt::Key_O, SoKeyboardEvent::O); + keyboardmap->insert(Qt::Key_P, SoKeyboardEvent::P); + keyboardmap->insert(Qt::Key_Q, SoKeyboardEvent::Q); + keyboardmap->insert(Qt::Key_R, SoKeyboardEvent::R); + keyboardmap->insert(Qt::Key_S, SoKeyboardEvent::S); + keyboardmap->insert(Qt::Key_T, SoKeyboardEvent::T); + keyboardmap->insert(Qt::Key_U, SoKeyboardEvent::U); + keyboardmap->insert(Qt::Key_V, SoKeyboardEvent::V); + keyboardmap->insert(Qt::Key_W, SoKeyboardEvent::W); + keyboardmap->insert(Qt::Key_X, SoKeyboardEvent::X); + keyboardmap->insert(Qt::Key_Y, SoKeyboardEvent::Y); + keyboardmap->insert(Qt::Key_Z, SoKeyboardEvent::Z); + + keyboardmap->insert(Qt::Key_Home, SoKeyboardEvent::HOME); + keyboardmap->insert(Qt::Key_Left, SoKeyboardEvent::LEFT_ARROW); + keyboardmap->insert(Qt::Key_Up, SoKeyboardEvent::UP_ARROW); + keyboardmap->insert(Qt::Key_Right, SoKeyboardEvent::RIGHT_ARROW); + keyboardmap->insert(Qt::Key_Down, SoKeyboardEvent::DOWN_ARROW); + keyboardmap->insert(Qt::Key_PageUp, SoKeyboardEvent::PAGE_UP); + keyboardmap->insert(Qt::Key_PageDown, SoKeyboardEvent::PAGE_DOWN); + keyboardmap->insert(Qt::Key_End, SoKeyboardEvent::END); + + keyboardmap->insert(Qt::Key_F1, SoKeyboardEvent::F1); + keyboardmap->insert(Qt::Key_F2, SoKeyboardEvent::F2); + keyboardmap->insert(Qt::Key_F3, SoKeyboardEvent::F3); + keyboardmap->insert(Qt::Key_F4, SoKeyboardEvent::F4); + keyboardmap->insert(Qt::Key_F5, SoKeyboardEvent::F5); + keyboardmap->insert(Qt::Key_F6, SoKeyboardEvent::F6); + keyboardmap->insert(Qt::Key_F7, SoKeyboardEvent::F7); + keyboardmap->insert(Qt::Key_F8, SoKeyboardEvent::F8); + keyboardmap->insert(Qt::Key_F9, SoKeyboardEvent::F9); + keyboardmap->insert(Qt::Key_F10, SoKeyboardEvent::F10); + keyboardmap->insert(Qt::Key_F11, SoKeyboardEvent::F11); + keyboardmap->insert(Qt::Key_F12, SoKeyboardEvent::F12); + + keyboardmap->insert(Qt::Key_Backspace, SoKeyboardEvent::BACKSPACE); + keyboardmap->insert(Qt::Key_Tab, SoKeyboardEvent::TAB); + keyboardmap->insert(Qt::Key_Return, SoKeyboardEvent::RETURN); + keyboardmap->insert(Qt::Key_Enter, SoKeyboardEvent::ENTER); + keyboardmap->insert(Qt::Key_Pause, SoKeyboardEvent::PAUSE); + keyboardmap->insert(Qt::Key_ScrollLock, SoKeyboardEvent::SCROLL_LOCK); + keyboardmap->insert(Qt::Key_Escape, SoKeyboardEvent::ESCAPE); + keyboardmap->insert(Qt::Key_Delete, SoKeyboardEvent::DELETE); + keyboardmap->insert(Qt::Key_Print, SoKeyboardEvent::PRINT); + keyboardmap->insert(Qt::Key_Insert, SoKeyboardEvent::INSERT); + keyboardmap->insert(Qt::Key_NumLock, SoKeyboardEvent::NUM_LOCK); + keyboardmap->insert(Qt::Key_CapsLock, SoKeyboardEvent::CAPS_LOCK); + + keyboardmap->insert(Qt::Key_Space, SoKeyboardEvent::SPACE); + keyboardmap->insert(Qt::Key_Apostrophe, SoKeyboardEvent::APOSTROPHE); + keyboardmap->insert(Qt::Key_Comma, SoKeyboardEvent::COMMA); + keyboardmap->insert(Qt::Key_Minus, SoKeyboardEvent::MINUS); + keyboardmap->insert(Qt::Key_Period, SoKeyboardEvent::PERIOD); + keyboardmap->insert(Qt::Key_Slash, SoKeyboardEvent::SLASH); + keyboardmap->insert(Qt::Key_Semicolon, SoKeyboardEvent::SEMICOLON); + keyboardmap->insert(Qt::Key_Equal, SoKeyboardEvent::EQUAL); + keyboardmap->insert(Qt::Key_BracketLeft, SoKeyboardEvent::BRACKETLEFT); + keyboardmap->insert(Qt::Key_BracketRight, SoKeyboardEvent::BRACKETRIGHT); + keyboardmap->insert(Qt::Key_Backslash, SoKeyboardEvent::BACKSLASH); + keyboardmap->insert(Qt::Key_Agrave, SoKeyboardEvent::GRAVE); + + // keypad + + // on Mac OS X, the keypad modifier will also be set when an arrow + // key is pressed as the arrow keys are considered part of the + // keypad + keypadmap->insert(Qt::Key_Left, SoKeyboardEvent::LEFT_ARROW); + keypadmap->insert(Qt::Key_Up, SoKeyboardEvent::UP_ARROW); + keypadmap->insert(Qt::Key_Right, SoKeyboardEvent::RIGHT_ARROW); + keypadmap->insert(Qt::Key_Down, SoKeyboardEvent::DOWN_ARROW); + + keypadmap->insert(Qt::Key_Enter, SoKeyboardEvent::PAD_ENTER); + keypadmap->insert(Qt::Key_F1, SoKeyboardEvent::PAD_F1); + keypadmap->insert(Qt::Key_F2, SoKeyboardEvent::PAD_F2); + keypadmap->insert(Qt::Key_F3, SoKeyboardEvent::PAD_F3); + keypadmap->insert(Qt::Key_F4, SoKeyboardEvent::PAD_F4); + keypadmap->insert(Qt::Key_0, SoKeyboardEvent::PAD_0); + keypadmap->insert(Qt::Key_1, SoKeyboardEvent::PAD_1); + keypadmap->insert(Qt::Key_2, SoKeyboardEvent::PAD_2); + keypadmap->insert(Qt::Key_3, SoKeyboardEvent::PAD_3); + keypadmap->insert(Qt::Key_4, SoKeyboardEvent::PAD_4); + keypadmap->insert(Qt::Key_5, SoKeyboardEvent::PAD_5); + keypadmap->insert(Qt::Key_6, SoKeyboardEvent::PAD_6); + keypadmap->insert(Qt::Key_7, SoKeyboardEvent::PAD_7); + keypadmap->insert(Qt::Key_8, SoKeyboardEvent::PAD_8); + keypadmap->insert(Qt::Key_9, SoKeyboardEvent::PAD_9); + keypadmap->insert(Qt::Key_Plus, SoKeyboardEvent::PAD_ADD); + keypadmap->insert(Qt::Key_Minus, SoKeyboardEvent::PAD_SUBTRACT); + keypadmap->insert(Qt::Key_multiply, SoKeyboardEvent::PAD_MULTIPLY); + keypadmap->insert(Qt::Key_division, SoKeyboardEvent::PAD_DIVIDE); + keypadmap->insert(Qt::Key_Tab, SoKeyboardEvent::PAD_TAB); + keypadmap->insert(Qt::Key_Space, SoKeyboardEvent::PAD_SPACE); + keypadmap->insert(Qt::Key_Insert, SoKeyboardEvent::PAD_INSERT); + keypadmap->insert(Qt::Key_Delete, SoKeyboardEvent::PAD_DELETE); + keypadmap->insert(Qt::Key_Period, SoKeyboardEvent::PAD_PERIOD); + + +#if 0 // FIXME: don't know what to do with these (20070306 frodo) + keyboardmap->insert(Qt::, SoKeyboardEvent::RIGHT_SHIFT); + keyboardmap->insert(Qt::, SoKeyboardEvent::RIGHT_CONTROL); + keyboardmap->insert(Qt::, SoKeyboardEvent::RIGHT_ALT); + keyboardmap->insert(Qt::, SoKeyboardEvent::PRIOR); + keyboardmap->insert(Qt::, SoKeyboardEvent::NEXT); + keyboardmap->insert(Qt::, SoKeyboardEvent::SHIFT_LOCK); +#endif +} + +#undef PUBLIC diff --git a/src/Gui/Quarter/KeyboardP.h b/src/Gui/Quarter/KeyboardP.h new file mode 100644 index 000000000..e5dfe6a99 --- /dev/null +++ b/src/Gui/Quarter/KeyboardP.h @@ -0,0 +1,65 @@ +#ifndef QUARTER_KEYBOARDHANDLERP_H +#define QUARTER_KEYBOARDHANDLERP_H + +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include +#include + +class SoEvent; +template class QMap; + +namespace SIM { namespace Coin3D { namespace Quarter { + +class Keyboard; + +class KeyboardP { +public: + KeyboardP(Keyboard * publ); + ~KeyboardP(); + + const SoEvent * keyEvent(QKeyEvent * event); + void initKeyMap(void); + static bool debugKeyEvents(void); + + typedef QMap KeyMap; + static KeyMap * keyboardmap; + static KeyMap * keypadmap; + + SoKeyboardEvent * keyboard; + Keyboard * publ; +}; + +}}} // namespace + +#endif // QUARTER_KEYBOARDHANDLERP_H diff --git a/src/Gui/Quarter/Mouse.cpp b/src/Gui/Quarter/Mouse.cpp new file mode 100644 index 000000000..b77b494be --- /dev/null +++ b/src/Gui/Quarter/Mouse.cpp @@ -0,0 +1,194 @@ +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +/*! + \class SIM::Coin3D::Quarter::Mouse Mouse.h Quarter/devices/Mouse.h + + \brief The Mouse class provides translation of mouse events on the + QuarterWidget. +*/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +namespace SIM { namespace Coin3D { namespace Quarter { + +class MouseP { +public: + MouseP(Mouse * publ) { + this->publ = publ; + this->location2 = new SoLocation2Event; + this->mousebutton = new SoMouseButtonEvent; + } + + ~MouseP() { + delete this->location2; + delete this->mousebutton; + } + + const SoEvent * mouseMoveEvent(QMouseEvent * event); + const SoEvent * mouseWheelEvent(QWheelEvent * event); + const SoEvent * mouseButtonEvent(QMouseEvent * event); + + void resizeEvent(QResizeEvent * event); + + class SoLocation2Event * location2; + class SoMouseButtonEvent * mousebutton; + SbVec2s windowsize; + Mouse * publ; +}; + +}}} // namespace + +using namespace SIM::Coin3D::Quarter; + +#define PRIVATE(obj) obj->pimpl +#define PUBLIC(obj) obj->publ + +Mouse::Mouse(void) +{ + PRIVATE(this) = new MouseP(this); +} + +Mouse::~Mouse() +{ + delete PRIVATE(this); +} + +/*! Translates from QMouseEvents to SoLocation2Events and + SoMouseButtonEvents + */ +const SoEvent * +Mouse::translateEvent(QEvent * event) +{ + switch (event->type()) { + case QEvent::MouseMove: + return PRIVATE(this)->mouseMoveEvent((QMouseEvent *) event); + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + // a dblclick event comes in a series of press, release, dblclick, + // release, so we can simply treat it as an ordinary press event. + // -mortene. + case QEvent::MouseButtonDblClick: + return PRIVATE(this)->mouseButtonEvent((QMouseEvent *) event); + case QEvent::Wheel: + return PRIVATE(this)->mouseWheelEvent((QWheelEvent *) event); + case QEvent::Resize: + PRIVATE(this)->resizeEvent((QResizeEvent *) event); + return NULL; + default: + return NULL; + } +} + +void +MouseP::resizeEvent(QResizeEvent * event) +{ + this->windowsize = SbVec2s(event->size().width(), + event->size().height()); +} + +const SoEvent * +MouseP::mouseMoveEvent(QMouseEvent * event) +{ + PUBLIC(this)->setModifiers(this->location2, event); + + assert(this->windowsize[1] != -1); + SbVec2s pos(event->pos().x(), this->windowsize[1] - event->pos().y() - 1); + this->location2->setPosition(pos); + this->mousebutton->setPosition(pos); + return this->location2; +} + +const SoEvent * +MouseP::mouseWheelEvent(QWheelEvent * event) +{ + PUBLIC(this)->setModifiers(this->mousebutton, event); + SbVec2s pos(event->pos().x(), PUBLIC(this)->windowsize[1] - event->pos().y() - 1); + this->location2->setPosition(pos); + this->mousebutton->setPosition(pos); + + // QWheelEvent::delta() returns the distance that the wheel is + // rotated, in eights of a degree. A positive value indicates that + // the wheel was rotated forwards away from the user; a negative + // value indicates that the wheel was rotated backwards toward the + // user. + (event->delta() > 0) ? + this->mousebutton->setButton(SoMouseButtonEvent::BUTTON4) : + this->mousebutton->setButton(SoMouseButtonEvent::BUTTON5); + + this->mousebutton->setState(SoButtonEvent::DOWN); + return this->mousebutton; +} + +const SoEvent * +MouseP::mouseButtonEvent(QMouseEvent * event) +{ + PUBLIC(this)->setModifiers(this->mousebutton, event); + SbVec2s pos(event->pos().x(), PUBLIC(this)->windowsize[1] - event->pos().y() - 1); + this->location2->setPosition(pos); + this->mousebutton->setPosition(pos); + + ((event->type() == QEvent::MouseButtonPress) || + (event->type() == QEvent::MouseButtonDblClick)) ? + this->mousebutton->setState(SoButtonEvent::DOWN): + this->mousebutton->setState(SoButtonEvent::UP); + + switch (event->button()) { + case Qt::LeftButton: + this->mousebutton->setButton(SoMouseButtonEvent::BUTTON1); + break; + case Qt::RightButton: + this->mousebutton->setButton(SoMouseButtonEvent::BUTTON2); + break; + case Qt::MidButton: + this->mousebutton->setButton(SoMouseButtonEvent::BUTTON3); + break; + default: + this->mousebutton->setButton(SoMouseButtonEvent::ANY); + SoDebugError::postInfo("Mouse::mouseButtonEvent", + "Unhandled ButtonState = %x", event->button()); + break; + } + return this->mousebutton; +} + +#undef PRIVATE +#undef PUBLIC diff --git a/src/Gui/Quarter/NativeEvent.cpp b/src/Gui/Quarter/NativeEvent.cpp new file mode 100644 index 000000000..def9b09c0 --- /dev/null +++ b/src/Gui/Quarter/NativeEvent.cpp @@ -0,0 +1,70 @@ +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + + +#include "NativeEvent.h" + +using namespace SIM::Coin3D::Quarter; + +#ifdef HAVE_SPACENAV_LIB +NativeEvent::NativeEvent(XEvent * nativeevent) + : QEvent(QEvent::User) +{ + this->rawevent = nativeevent; +} + + +XEvent * +NativeEvent::getEvent() const +{ + return static_cast(this->rawevent); +} + +#else // !HAVE_SPACENAV_LIB + +// Dummy constructor when Spacenav is not available. +NativeEvent::NativeEvent() + : QEvent(QEvent::User) +{ + this->rawevent = NULL; +} + +#endif // !HAVE_SPACENAV_LIB + + +NativeEvent::~NativeEvent() +{ +#ifdef HAVE_SPACENAV_LIB + delete (XEvent *) this->rawevent; +#endif // HAVE_SPACENAV_LIB +} + diff --git a/src/Gui/Quarter/NativeEvent.h b/src/Gui/Quarter/NativeEvent.h new file mode 100644 index 000000000..e6d20d691 --- /dev/null +++ b/src/Gui/Quarter/NativeEvent.h @@ -0,0 +1,62 @@ +#ifndef QUARTER_NATIVEEVENT_H +#define QUARTER_NATIVEEVENT_H + +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include +#include + +#ifdef HAVE_SPACENAV_LIB +#include +#endif + +namespace SIM { namespace Coin3D { namespace Quarter { + +class NativeEvent : public QEvent { +public: +#ifdef HAVE_SPACENAV_LIB + NativeEvent(XEvent * nativeevent); + XEvent * getEvent() const; +#else // !HAVE_SPACENAV_LIB + NativeEvent(); +#endif // !HAVE_SPACENAV_LIB + + virtual ~NativeEvent(); + +private: + void * rawevent; +}; + +}}} + +#endif // !QUARTER_NATIVEEVENT_H diff --git a/src/Gui/Quarter/QtCoinCompatibility.cpp b/src/Gui/Quarter/QtCoinCompatibility.cpp new file mode 100644 index 000000000..542c35b96 --- /dev/null +++ b/src/Gui/Quarter/QtCoinCompatibility.cpp @@ -0,0 +1,122 @@ +#include +#include +#include +#include + +using namespace SIM::Coin3D::Quarter; + +void +QtCoinCompatibility::QImageToSbImage(const QImage & image, SbImage & sbimage) +{ + int w = image.width(); + int h = image.height(); + int c; + + // Keep in 8-bits mode if that was what we read + if (image.depth() == 8 && image.isGrayscale()) { + c = 1; + } + else { + // FIXME: consider if we should detect allGrayscale() and alpha (c = 2) + c = image.hasAlphaChannel() ? 4 : 3; + } + + SbVec2s size((short) w, (short) h); + sbimage.setValue(size, c, NULL); + unsigned char * buffer = sbimage.getValue(size, c); + + if (c == 1) { + for (int i = 0; i < h; i++) { + memcpy(buffer + i*w, image.scanLine(h-(i+1)), w); + } + } + else { // (c == 3 || c == 4) + QRgb * bits = (QRgb*) image.bits(); + for (int y = 0; y < h; y++) { + unsigned char * line = &buffer[c*w*(h-(y+1))]; + for (int x = 0; x < w; x++) { + *line++ = qRed(*bits); + *line++ = qGreen(*bits); + *line++ = qBlue(*bits); + if (c == 4) { + *line++ = qAlpha(*bits); + } + bits++; + } + } + } +} + +void +QtCoinCompatibility::SbImageToQImage(const SbImage & sbimage, QImage & img) +{ + SbVec2s ivsize; + int nc; + const unsigned char* src = sbimage.getValue (ivsize, nc); + QSize size(ivsize[0],ivsize[1]); + assert(src && "Empty image"); + if (nc!=3&&nc!=1&&nc!=4) { + SoDebugError::postWarning("QtCoinCompatibility::SbImageToQImage", + "Implementation not tested for 3 colors or more" + ); + } + QImage::Format format; + if (nc==3||nc==4) { + format=QImage::Format_RGB32; + } + else if (nc==1) { + QVector clut; + for (int i=0;i<256;++i) { + clut.append(qRgb(i,i,i)); + } + format=QImage::Format_Indexed8; + } + img = QImage(size,format); + assert(img.size()==size); + if (nc==1) { + QVector clut; + for (int i=0;i<256;++i) { + clut.append(qRgb(i,i,i)); + } + img.setColorTable(clut); + } + + for (int y = 0; y < size.height(); ++y) { + QRgb * bits = reinterpret_cast(img.scanLine(size.height() - (y+1))); + for (int x = 0; x < size.width(); ++x) { + switch (nc) { + default: + case 1: + { + img.setPixel(x,size.height()-(y+1),*src++); + } + break; + case 2: + { + unsigned char red=*src++; + unsigned char alpha=*src++; + *bits=qRgba(red,red,red,alpha); + } + break; + case 3: + { + unsigned char red=*src++; + unsigned char green=*src++; + unsigned char blue=*src++; + *bits=qRgb(red,green,blue); + } + break; + case 4: + { + unsigned char red=*src++; + unsigned char green=*src++; + unsigned char blue=*src++; + unsigned char alpha=*src++; + *bits=qRgba(red,green,blue,alpha); + } + break; + } + ++bits; + } + } +} diff --git a/src/Gui/Quarter/QtCoinCompatibility.h b/src/Gui/Quarter/QtCoinCompatibility.h new file mode 100644 index 000000000..1a841f29b --- /dev/null +++ b/src/Gui/Quarter/QtCoinCompatibility.h @@ -0,0 +1,50 @@ +#ifndef QUARTER_QTCOINCOMPATIBILITY_H +#define QUARTER_QTCOINCOMPATIBILITY_H + +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +class QImage; +class SbImage; + +#include + +namespace SIM { namespace Coin3D { namespace Quarter { + +namespace QtCoinCompatibility { + void QUARTER_DLL_API QImageToSbImage(const QImage &, SbImage & ); + void QUARTER_DLL_API SbImageToQImage(const SbImage &, QImage & ); +} + +}}} // namespace + +#endif // QUARTER_QTCOINCOMPATIBILITY_H diff --git a/src/Gui/Quarter/Quarter.cpp b/src/Gui/Quarter/Quarter.cpp new file mode 100644 index 000000000..9c789d11f --- /dev/null +++ b/src/Gui/Quarter/Quarter.cpp @@ -0,0 +1,213 @@ +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +/*! \mainpage + + Quarter is a light-weight glue library that provides seamless + integration between Systems in Motions's \COIN high-level 3D + visualization library and Trolltech's \QT 2D user interface + library. + + \QT and \COIN is a perfect match since they are both open source, + widely portable and easy to use. Quarter has evolved from Systems in + Motion's own experiences using \COIN and \QT together in our + applications. + + The functionality in Quarter revolves around QuarterWidget, a + subclass of QGLWidget. This widget provides functionality for + rendering of Coin scenegraphs and translation of QEvents into + SoEvents. Using this widget is as easy as using any other QWidget. + + \subpage QuarterWidgetPlugin + + Quarter also comes with a plugin for Qt Designer, Trolltech's tool + for designing and building GUIs. Once you install Quarter, the + QuarterWidget becomes accessible in Qt Designer, and you can include + it in the user interfaces you create. The plugin facility also + provides you with the capability of dynamically loading ui files + containing a QuarterWidget in your application. + + By using \COIN, \QT and Quarter to build your 3D graphics + applications, you have the power to write software that is portable + across the whole range of UNIX, Linux, Microsoft Windows and Mac OS + X operating systems, from a 100% common codebase. + + For a small, completely stand-alone usage example on how to + initialize the library and set up a viewer instance window, see the + following code: + + \code + #include + + #include + #include + #include + + #include + #include + + using namespace SIM::Coin3D::Quarter; + + int + main(int argc, char ** argv) + { + QApplication app(argc, argv); + // Initializes Quarter library (and implicitly also the Coin and Qt + // libraries). + Quarter::init(); + + // Make a dead simple scene graph by using the Coin library, only + // containing a single yellow cone under the scenegraph root. + SoSeparator * root = new SoSeparator; + root->ref(); + + SoBaseColor * col = new SoBaseColor; + col->rgb = SbColor(1, 1, 0); + root->addChild(col); + + root->addChild(new SoCone); + + // Create a QuarterWidget for displaying a Coin scene graph + QuarterWidget * viewer = new QuarterWidget; + viewer->setSceneGraph(root); + + // make the viewer react to input events similar to the good old + // ExaminerViewer + viewer->setNavigationModeFile(QUrl("coin:///scxml/navigation/examiner.xml")); + + // Pop up the QuarterWidget + viewer->show(); + // Loop until exit. + app.exec(); + // Clean up resources. + root->unref(); + delete viewer; + + Quarter::clean(); + + return 0; + } + \endcode + + \subpage examples +*/ + +/*! + \page examples More Examples + + The examples code is included in Quarter and can be found in the + src/examples subdirectory. + + \subpage directui + + \subpage dynamicui + + \subpage inheritui + + \subpage mdi + + \subpage examiner +*/ + +#include +#include +#include +#include + +#include +#include "SensorManager.h" + +#include "QuarterP.h" + +using namespace SIM::Coin3D::Quarter; + +static QuarterP * self = NULL; + +/*! + initialize Quarter, and implicitly Coin + */ +void +Quarter::init(bool initCoin) +{ + COMPILE_ONLY_BEFORE(2,0,0,"Should not be encapsulated in double Quarter namespace"); + if (self) { + // FIXME: Use SoDebugError + fprintf(stderr, "Quarter is already initialized\n"); + return; + } + + if (initCoin) { + SoDB::init(); + SoNodeKit::init(); + SoInteraction::init(); + } + + self = new QuarterP; + self->initCoin = initCoin; + +} + +/*! + clean up resources + */ +void +Quarter::clean(void) +{ + COMPILE_ONLY_BEFORE(2,0,0,"Should not be encapsulated in double Quarter namespace"); + assert(self); + bool initCoin = self->initCoin; + + delete self; + self = NULL; + + if (initCoin) { + // SoDB::finish() will clean up everything that has been + // initialized. There's no need to add SoNodeKit::finish() and + // SoInteraction::finish() like in TGS Inventor + SoDB::finish(); + } +} + +/*! + override lower refresh rate limit + */ +void +Quarter::setTimerEpsilon(double sec) +{ + COMPILE_ONLY_BEFORE(2,0,0,"Should not be encapsulated in double Quarter namespace"); + if (!self) { + fprintf(stderr, "Quarter is not initialized!\n"); + return; + } + + self->sensormanager->setTimerEpsilon(sec); +} diff --git a/src/Gui/Quarter/Quarter.h b/src/Gui/Quarter/Quarter.h new file mode 100644 index 000000000..07a175123 --- /dev/null +++ b/src/Gui/Quarter/Quarter.h @@ -0,0 +1,48 @@ +#ifndef QUARTER_QUARTER_H +#define QUARTER_QUARTER_H + +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include + +namespace SIM { namespace Coin3D { namespace Quarter { + +namespace Quarter { + void QUARTER_DLL_API init(bool initCoin = true); + void QUARTER_DLL_API clean(void); + void QUARTER_DLL_API setTimerEpsilon(double sec); +}; + +}}} // namespace + +#endif // QUARTER_QUARTER_H diff --git a/src/Gui/Quarter/QuarterP.cpp b/src/Gui/Quarter/QuarterP.cpp new file mode 100644 index 000000000..fbfd30e38 --- /dev/null +++ b/src/Gui/Quarter/QuarterP.cpp @@ -0,0 +1,37 @@ +#include "QuarterP.h" +#include "SensorManager.h" +#include "ImageReader.h" +#include "KeyboardP.h" + +using namespace SIM::Coin3D::Quarter; +QuarterP::StateCursorMap * QuarterP::statecursormap = NULL; + +QuarterP::QuarterP(void) +{ + this->sensormanager = new SensorManager; + this->imagereader = new ImageReader; + assert(QuarterP::statecursormap == NULL); + QuarterP::statecursormap = new StateCursorMap; + +} + +QuarterP::~QuarterP() +{ + delete this->imagereader; + delete this->sensormanager; + + assert(QuarterP::statecursormap != NULL); + delete QuarterP::statecursormap; + + // FIXME: Why not use an atexit mechanism for this? + if (KeyboardP::keyboardmap != NULL) { + KeyboardP::keyboardmap->clear(); + KeyboardP::keypadmap->clear(); + delete KeyboardP::keyboardmap; + delete KeyboardP::keypadmap; + KeyboardP::keyboardmap = NULL; + KeyboardP::keypadmap = NULL; + } + + +} diff --git a/src/Gui/Quarter/QuarterP.h b/src/Gui/Quarter/QuarterP.h new file mode 100644 index 000000000..ac9f22c98 --- /dev/null +++ b/src/Gui/Quarter/QuarterP.h @@ -0,0 +1,33 @@ +#ifndef QUARTER_QUARTERP_H +#define QUARTER_QUARTERP_H +#include +#include +#include + +template class QMap; + +namespace SIM { namespace Coin3D { namespace Quarter { + +class QuarterP { + public: + QuarterP(); + ~QuarterP(); + + class SensorManager * sensormanager; + class ImageReader * imagereader; + + typedef QMap StateCursorMap; + static StateCursorMap * statecursormap; + + bool initCoin; +}; + +}}}; + +#define COIN_CT_ASSERT(expr) \ + do { switch ( 0 ) { case 0: case (expr): break; } } while ( 0 ) + +#define COMPILE_ONLY_BEFORE(MAJOR,MINOR,MICRO,REASON) \ + COIN_CT_ASSERT( (QUARTER_MAJOR_VERSION < MAJOR) || (QUARTER_MAJOR_VERSION == MAJOR && ((QUARTER_MINOR_VERSION < MINOR) || ( QUARTER_MINOR_VERSION == MINOR && (QUARTER_MICRO_VERSION < MICRO ))))) + +#endif //QUARTER_QUARTERP_H diff --git a/src/Gui/Quarter/QuarterWidget.cpp b/src/Gui/Quarter/QuarterWidget.cpp new file mode 100644 index 000000000..64f60c556 --- /dev/null +++ b/src/Gui/Quarter/QuarterWidget.cpp @@ -0,0 +1,1029 @@ +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +/*! + \class SIM::Coin3D::Quarter::QuarterWidget QuarterWidget.h Quarter/QuarterWidget.h + + \brief The QuarterWidget class is the main class in Quarter. It + provides a widget for Coin rendering. It provides scenegraph + management and event handling. + + If you want to modify the GL format for an existing QuarterWidget, you can + set up a new GL context for the widget, e.g.: + + \code + QGLContext * context = new QGLContext(QGLFormat(QGL::SampleBuffers), viewer); + if (context->create()) { + viewer->setContext(context); + } + \endcode +*/ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "InteractionMode.h" +#include "QuarterWidgetP.h" +#include "QuarterP.h" + +using namespace SIM::Coin3D::Quarter; + +/*! + \enum SIM::Coin3D::Quarter::QuarterWidget::TransparencyType + + Various settings for how to do rendering of transparent objects in + the scene. Some of the settings will provide faster rendering, while + others gives you better quality rendering. + + See \ref SoGLRenderAction::TransparencyType for a full descrition of the modes +*/ + +/*! + \enum SIM::Coin3D::Quarter::QuarterWidget::RenderMode + + Sets how rendering of primitives is done. + + See \ref SoRenderManager::RenderMode for a full descrition of the modes +*/ + +/*! + \enum SIM::Coin3D::Quarter::QuarterWidget::StereoMode + + Sets how stereo rendering is performed. + + See \ref SoRenderManager::StereoMode for a full descrition of the modes +*/ + + enum StereoMode { + MONO = SoRenderManager::MONO, + ANAGLYPH = SoRenderManager::ANAGLYPH, + QUAD_BUFFER = SoRenderManager::QUAD_BUFFER, + INTERLEAVED_ROWS = SoRenderManager::INTERLEAVED_ROWS, + INTERLEAVED_COLUMNS = SoRenderManager::INTERLEAVED_COLUMNS + }; + +#define PRIVATE(obj) obj->pimpl + +/*! constructor */ +QuarterWidget::QuarterWidget(const QGLFormat & format, QWidget * parent, const QGLWidget * sharewidget, Qt::WindowFlags f) + : inherited(format, parent, sharewidget, f) +{ + this->constructor(sharewidget); +} + +/*! constructor */ +QuarterWidget::QuarterWidget(QWidget * parent, const QGLWidget * sharewidget, Qt::WindowFlags f) + : inherited(parent, sharewidget, f) +{ + this->constructor(sharewidget); +} + +/*! constructor */ +QuarterWidget::QuarterWidget(QGLContext * context, QWidget * parent, const QGLWidget * sharewidget, Qt::WindowFlags f) + : inherited(context, parent, sharewidget, f) +{ + this->constructor(sharewidget); +} + +void +QuarterWidget::constructor(const QGLWidget * sharewidget) +{ + PRIVATE(this) = new QuarterWidgetP(this, sharewidget); + + PRIVATE(this)->sorendermanager = new SoRenderManager; + PRIVATE(this)->initialsorendermanager = true; + PRIVATE(this)->soeventmanager = new SoEventManager; + PRIVATE(this)->initialsoeventmanager = true; + PRIVATE(this)->processdelayqueue = true; + + //Mind the order of initialization as the XML state machine uses + //callbacks which depends on other state being initialized + PRIVATE(this)->eventfilter = new EventFilter(this); + PRIVATE(this)->interactionmode = new InteractionMode(this); + + PRIVATE(this)->currentStateMachine = NULL; + + PRIVATE(this)->headlight = new SoDirectionalLight; + PRIVATE(this)->headlight->ref(); + + PRIVATE(this)->sorendermanager->setAutoClipping(SoRenderManager::VARIABLE_NEAR_PLANE); + PRIVATE(this)->sorendermanager->setRenderCallback(QuarterWidgetP::rendercb, this); + PRIVATE(this)->sorendermanager->setBackgroundColor(SbColor4f(0.0f, 0.0f, 0.0f, 0.0f)); + PRIVATE(this)->sorendermanager->activate(); + PRIVATE(this)->sorendermanager->addPreRenderCallback(QuarterWidgetP::prerendercb, PRIVATE(this)); + PRIVATE(this)->sorendermanager->addPostRenderCallback(QuarterWidgetP::postrendercb, PRIVATE(this)); + + PRIVATE(this)->soeventmanager->setNavigationState(SoEventManager::MIXED_NAVIGATION); + + // set up a cache context for the default SoGLRenderAction + PRIVATE(this)->sorendermanager->getGLRenderAction()->setCacheContext(this->getCacheContextId()); + + this->setMouseTracking(TRUE); + + // Qt::StrongFocus means the widget will accept keyboard focus by + // both tabbing and clicking + this->setFocusPolicy(Qt::StrongFocus); + + this->installEventFilter(PRIVATE(this)->eventfilter); + this->installEventFilter(PRIVATE(this)->interactionmode); +} + +/*! destructor */ +QuarterWidget::~QuarterWidget() +{ + if (PRIVATE(this)->currentStateMachine) { + this->removeStateMachine(PRIVATE(this)->currentStateMachine); + delete PRIVATE(this)->currentStateMachine; + } + PRIVATE(this)->headlight->unref(); + PRIVATE(this)->headlight = NULL; + this->setSceneGraph(NULL); + this->setSoRenderManager(NULL); + this->setSoEventManager(NULL); + delete PRIVATE(this)->eventfilter; + delete PRIVATE(this); +} + +/*! + You can set the cursor you want to use for a given navigation + state. See the Coin documentation on navigation for information + about available states +*/ +void +QuarterWidget::setStateCursor(const SbName & state, const QCursor & cursor) +{ + assert(QuarterP::statecursormap); + // will overwrite the value of an existing item + QuarterP::statecursormap->insert(state, cursor); +} + +/*! + Maps a state to a cursor + + \param[in] state Named state in the statemachine + \retval Cursor corresponding to the given state +*/ +QCursor +QuarterWidget::stateCursor(const SbName & state) +{ + assert(QuarterP::statecursormap); + return QuarterP::statecursormap->value(state); +} + +/*! + \property QuarterWidget::headlightEnabled + + \copydetails QuarterWidget::setHeadlightEnabled +*/ + +/*! + Enable/disable the headlight. This wille toggle the SoDirectionalLight::on + field (returned from getHeadlight()). +*/ +void +QuarterWidget::setHeadlightEnabled(bool onoff) +{ + PRIVATE(this)->headlight->on = onoff; +} + +/*! + Returns true if the headlight is on, false if it is off +*/ +bool +QuarterWidget::headlightEnabled(void) const +{ + return PRIVATE(this)->headlight->on.getValue(); +} + +/*! + Returns the light used for the headlight. +*/ +SoDirectionalLight * +QuarterWidget::getHeadlight(void) +{ + return PRIVATE(this)->headlight; +} + +/*! + \property QuarterWidget::clearZBuffer + + \copydetails QuarterWidget::setClearZBuffer +*/ + +/*! + Specify if you want the z buffer to be cleared before + redraw. This is on by default. +*/ +void +QuarterWidget::setClearZBuffer(bool onoff) +{ + PRIVATE(this)->clearzbuffer = onoff; +} + +/*! + Returns true if the z buffer is cleared before rendering. +*/ +bool +QuarterWidget::clearZBuffer(void) const +{ + return PRIVATE(this)->clearzbuffer; +} + +/*! + \property QuarterWidget::clearWindow + + \copydetails QuarterWidget::setClearWindow +*/ + +/*! + Specify if you want the rendering buffer to be cleared before + rendering. This is on by default. + */ +void +QuarterWidget::setClearWindow(bool onoff) +{ + PRIVATE(this)->clearwindow = onoff; +} + +/*! + Returns true if the rendering buffer is cleared before rendering. +*/ +bool +QuarterWidget::clearWindow(void) const +{ + return PRIVATE(this)->clearwindow; +} + +/*! + \property QuarterWidget::interactionModeEnabled + + \copydetails QuarterWidget::setInteractionModeEnabled +*/ + +/*! + Enable/disable interaction mode. + + Specifies wether you may use the alt-key to enter interaction mode. +*/ +void +QuarterWidget::setInteractionModeEnabled(bool onoff) +{ + PRIVATE(this)->interactionmode->setEnabled(onoff); +} + +/*! + Returns true if interaction mode is enabled, false otherwise. + */ +bool +QuarterWidget::interactionModeEnabled(void) const +{ + return PRIVATE(this)->interactionmode->enabled(); +} + +/*! + \property QuarterWidget::interactionModeOn + + \copydetails QuarterWidget::setInteractionModeOn +*/ + +/*! + Turn interaction mode on or off. +*/ +void +QuarterWidget::setInteractionModeOn(bool onoff) +{ + PRIVATE(this)->interactionmode->setOn(onoff); +} + +/*! + Returns true if interaction mode is on. + */ +bool +QuarterWidget::interactionModeOn(void) const +{ + return PRIVATE(this)->interactionmode->on(); +} + +/*! + Returns the Coin cache context id for this widget. +*/ +uint32_t +QuarterWidget::getCacheContextId(void) const +{ + return PRIVATE(this)->getCacheContextId(); +} + +/*! + \property QuarterWidget::transparencyType + + \copydetails QuarterWidget::setTransparencyType +*/ + +/*! + Sets the transparency type to be used for the scene. +*/ +void +QuarterWidget::setTransparencyType(TransparencyType type) +{ + assert(PRIVATE(this)->sorendermanager); + PRIVATE(this)->sorendermanager->getGLRenderAction()->setTransparencyType((SoGLRenderAction::TransparencyType)type); + PRIVATE(this)->sorendermanager->scheduleRedraw(); +} + +/*! + \retval The current \ref TransparencyType +*/ +QuarterWidget::TransparencyType +QuarterWidget::transparencyType(void) const +{ + assert(PRIVATE(this)->sorendermanager); + SoGLRenderAction * action = PRIVATE(this)->sorendermanager->getGLRenderAction(); + return static_cast(action->getTransparencyType()); +} + +/*! + \property QuarterWidget::renderMode + + \copydetails QuarterWidget::setRenderMode +*/ + +/*! + \copydoc RenderMode +*/ +void +QuarterWidget::setRenderMode(RenderMode mode) +{ + assert(PRIVATE(this)->sorendermanager); + PRIVATE(this)->sorendermanager->setRenderMode(static_cast(mode)); + PRIVATE(this)->sorendermanager->scheduleRedraw(); +} + +/*! + \retval The current \ref RenderMode +*/ +QuarterWidget::RenderMode +QuarterWidget::renderMode(void) const +{ + assert(PRIVATE(this)->sorendermanager); + return static_cast(PRIVATE(this)->sorendermanager->getRenderMode()); +} + +/*! + \property QuarterWidget::stereoMode + + \copydetails QuarterWidget::setStereoMode +*/ + +/*! + \copydoc StereoMode +*/ +void +QuarterWidget::setStereoMode(StereoMode mode) +{ + assert(PRIVATE(this)->sorendermanager); + PRIVATE(this)->sorendermanager->setStereoMode(static_cast(mode)); + PRIVATE(this)->sorendermanager->scheduleRedraw(); +} + + +/*! + \retval The current \ref StereoMode +*/ +QuarterWidget::StereoMode +QuarterWidget::stereoMode(void) const +{ + assert(PRIVATE(this)->sorendermanager); + return static_cast(PRIVATE(this)->sorendermanager->getStereoMode()); +} + +/*! + Sets the Inventor scenegraph to be rendered + */ +void +QuarterWidget::setSceneGraph(SoNode * node) +{ + if (node == PRIVATE(this)->scene) { + return; + } + + if (PRIVATE(this)->scene) { + PRIVATE(this)->scene->unref(); + PRIVATE(this)->scene = NULL; + } + + SoCamera * camera = NULL; + SoSeparator * superscene = NULL; + bool viewall = false; + + if (node) { + PRIVATE(this)->scene = node; + PRIVATE(this)->scene->ref(); + + superscene = new SoSeparator; + superscene->addChild(PRIVATE(this)->headlight); + + // if the scene does not contain a camera, add one + if (!(camera = PRIVATE(this)->searchForCamera(node))) { + camera = new SoPerspectiveCamera; + superscene->addChild(camera); + viewall = true; + } + + superscene->addChild(node); + } + + PRIVATE(this)->soeventmanager->setCamera(camera); + PRIVATE(this)->sorendermanager->setCamera(camera); + PRIVATE(this)->soeventmanager->setSceneGraph(superscene); + PRIVATE(this)->sorendermanager->setSceneGraph(superscene); + + if (viewall) { this->viewAll(); } + if (superscene) { superscene->touch(); } +} + +/*! + Returns pointer to root of scene graph +*/ +SoNode * +QuarterWidget::getSceneGraph(void) const +{ + return PRIVATE(this)->scene; +} + +/*! + Set the render manager for the widget. +*/ +void +QuarterWidget::setSoRenderManager(SoRenderManager * manager) +{ + bool carrydata = false; + SoNode * scene = NULL; + SoCamera * camera = NULL; + SbViewportRegion vp; + if (PRIVATE(this)->sorendermanager && (manager != NULL)) { + scene = PRIVATE(this)->sorendermanager->getSceneGraph(); + camera = PRIVATE(this)->sorendermanager->getCamera(); + vp = PRIVATE(this)->sorendermanager->getViewportRegion(); + carrydata = true; + } + + // ref before deleting the old scene manager to avoid that the nodes are deleted + if (scene) scene->ref(); + if (camera) camera->ref(); + + if (PRIVATE(this)->initialsorendermanager) { + delete PRIVATE(this)->sorendermanager; + PRIVATE(this)->initialsorendermanager = false; + } + PRIVATE(this)->sorendermanager = manager; + if (carrydata) { + PRIVATE(this)->sorendermanager->setSceneGraph(scene); + PRIVATE(this)->sorendermanager->setCamera(camera); + PRIVATE(this)->sorendermanager->setViewportRegion(vp); + } + + if (scene) scene->unref(); + if (camera) camera->unref(); +} + +/*! + Returns a pointer to the render manager. +*/ +SoRenderManager * +QuarterWidget::getSoRenderManager(void) const +{ + return PRIVATE(this)->sorendermanager; +} + +/*! + Set the Coin event manager for the widget. +*/ +void +QuarterWidget::setSoEventManager(SoEventManager * manager) +{ + bool carrydata = false; + SoNode * scene = NULL; + SoCamera * camera = NULL; + SbViewportRegion vp; + if (PRIVATE(this)->soeventmanager && (manager != NULL)) { + scene = PRIVATE(this)->soeventmanager->getSceneGraph(); + camera = PRIVATE(this)->soeventmanager->getCamera(); + vp = PRIVATE(this)->soeventmanager->getViewportRegion(); + carrydata = true; + } + + // ref before deleting the old scene manager to avoid that the nodes are deleted + if (scene) scene->ref(); + if (camera) camera->ref(); + + if (PRIVATE(this)->initialsoeventmanager) { + delete PRIVATE(this)->soeventmanager; + PRIVATE(this)->initialsoeventmanager = false; + } + PRIVATE(this)->soeventmanager = manager; + if (carrydata) { + PRIVATE(this)->soeventmanager->setSceneGraph(scene); + PRIVATE(this)->soeventmanager->setCamera(camera); + PRIVATE(this)->soeventmanager->setViewportRegion(vp); + } + + if (scene) scene->unref(); + if (camera) camera->unref(); +} + +/*! + Returns a pointer to the event manager +*/ +SoEventManager * +QuarterWidget::getSoEventManager(void) const +{ + return PRIVATE(this)->soeventmanager; +} + +/*! + Returns a pointer to the event filter + */ +EventFilter * +QuarterWidget::getEventFilter(void) const +{ + return PRIVATE(this)->eventfilter; +} + +/*! + Reposition the current camera to display the entire scene + */ +void +QuarterWidget::viewAll(void) +{ + const SbName viewallevent("sim.coin3d.coin.navigation.ViewAll"); + for (int c = 0; c < PRIVATE(this)->soeventmanager->getNumSoScXMLStateMachines(); ++c) { + SoScXMLStateMachine * sostatemachine = + PRIVATE(this)->soeventmanager->getSoScXMLStateMachine(c); + if (sostatemachine->isActive()) { + sostatemachine->queueEvent(viewallevent); + sostatemachine->processEventQueue(); + } + } +} + +/*! + Sets the current camera in seekmode, if supported by the underlying navigation system. + Camera typically seeks towards what the mouse is pointing at. +*/ +void +QuarterWidget::seek(void) +{ + const SbName seekevent("sim.coin3d.coin.navigation.Seek"); + for (int c = 0; c < PRIVATE(this)->soeventmanager->getNumSoScXMLStateMachines(); ++c) { + SoScXMLStateMachine * sostatemachine = + PRIVATE(this)->soeventmanager->getSoScXMLStateMachine(c); + if (sostatemachine->isActive()) { + sostatemachine->queueEvent(seekevent); + sostatemachine->processEventQueue(); + } + } +} + +/*! + This function will be called whenever the GLContext changes, + for instance when the widget is reparented. + + Overridden from QGLWidget to enable OpenGL depth buffer + and reinitialize the SoRenderManager. + */ +void +QuarterWidget::initializeGL(void) +{ + glEnable(GL_DEPTH_TEST); + this->getSoRenderManager()->reinitialize(); +} + +/*! + Overridden from QGLWidget to resize the Coin scenegraph + */ +void +QuarterWidget::resizeGL(int width, int height) +{ + SbViewportRegion vp(width, height); + PRIVATE(this)->sorendermanager->setViewportRegion(vp); + PRIVATE(this)->soeventmanager->setViewportRegion(vp); +} + +/*! + Overridden from QGLWidget to render the scenegraph +*/ +void +QuarterWidget::paintGL(void) +{ + assert(this->isValid() && "No valid GL context found!"); + // We might have to process the delay queue here since we don't know + // if paintGL() is called from Qt, and we might have some sensors + // waiting to trigger (the redraw sensor has a lower priority than a + // normal field sensor to guarantee that your sensor is processed + // before the next redraw). Disable autorendering while we do this + // to avoid recursive redraws. + + // We set the PRIVATE(this)->processdelayqueue = false in redraw() + // to avoid processing the delay queue when paintGL() is triggered + // by us, and we don't want to process the delay queue in those + // cases + + PRIVATE(this)->autoredrawenabled = false; + if (PRIVATE(this)->processdelayqueue && SoDB::getSensorManager()->isDelaySensorPending()) { + // processing the sensors might trigger a redraw in another + // context. Release this context temporarily + this->doneCurrent(); + SoDB::getSensorManager()->processDelayQueue(FALSE); + this->makeCurrent(); + } + assert(this->isValid() && "No valid GL context found!"); + // we need to render immediately here, and not do scheduleRedraw() + // since Qt will swap the GL buffers after calling paintGL(). + this->actualRedraw(); + PRIVATE(this)->autoredrawenabled = true; + + // process the delay queue the next time we enter this function, + // unless we get here after a call to redraw(). + PRIVATE(this)->processdelayqueue = true; +} + +/*! + Used for rendering the scene. Usually Coin/Quarter will automatically redraw + the scene graph at regular intervals, after the scene is modified. + + However, if you want to disable this functionality and gain full control over + when the scene is rendered yourself, you can turn off autoredraw in the + render manager and render the scene by calling this method. +*/ +void +QuarterWidget::redraw(void) +{ + // we're triggering the next paintGL(). Set a flag to remember this + // to avoid that we process the delay queue in paintGL() + PRIVATE(this)->processdelayqueue = false; + this->updateGL(); +} + +/*! + Overridden from QGLWidget to render the scenegraph + */ +void +QuarterWidget::actualRedraw(void) +{ + PRIVATE(this)->sorendermanager->render(PRIVATE(this)->clearwindow, + PRIVATE(this)->clearzbuffer); +} + + +/*! + Passes an event to the eventmanager. + + \param[in] event to pass + \retval Returns true if the event was successfully processed +*/ +bool +QuarterWidget::processSoEvent(const SoEvent * event) +{ + return + event && + PRIVATE(this)->soeventmanager && + PRIVATE(this)->soeventmanager->processEvent(event); +} + +/*! + \property QuarterWidget::backgroundColor + \copydoc QuarterWidget::setBackgroundColor +*/ + +/*! + Set backgroundcolor to a given QColor + + Remember that QColors are given in integers between 0 and 255, as + opposed to SbColor4f which is in [0 ,1]. The default alpha value for + a QColor is 255, but you'll probably want to set it to zero before + using it as an OpenGL clear color. + */ +void +QuarterWidget::setBackgroundColor(const QColor & color) +{ + SbColor4f bgcolor(SbClamp(color.red() / 255.0, 0.0, 1.0), + SbClamp(color.green() / 255.0, 0.0, 1.0), + SbClamp(color.blue() / 255.0, 0.0, 1.0), + SbClamp(color.alpha() / 255.0, 0.0, 1.0)); + + PRIVATE(this)->sorendermanager->setBackgroundColor(bgcolor); + PRIVATE(this)->sorendermanager->scheduleRedraw(); +} + +/*! + Returns color used for clearing the rendering area before + rendering the scene. + */ +QColor +QuarterWidget::backgroundColor(void) const +{ + SbColor4f bg = PRIVATE(this)->sorendermanager->getBackgroundColor(); + + return QColor(SbClamp(int(bg[0] * 255.0), 0, 255), + SbClamp(int(bg[1] * 255.0), 0, 255), + SbClamp(int(bg[2] * 255.0), 0, 255), + SbClamp(int(bg[3] * 255.0), 0, 255)); +} + +/*! + Returns the context menu used by the widget. +*/ +QMenu * +QuarterWidget::getContextMenu(void) const +{ + return PRIVATE(this)->contextMenu(); +} + +/*! + \retval Is context menu enabled? +*/ +bool +QuarterWidget::contextMenuEnabled(void) const +{ + return PRIVATE(this)->contextmenuenabled; +} + +/*! + \property QuarterWidget::contextMenuEnabled + + \copydetails QuarterWidget::setContextMenuEnabled +*/ + +/*! + Controls the display of the contextmenu + + \param[in] yes Context menu on? +*/ +void +QuarterWidget::setContextMenuEnabled(bool yes) +{ + PRIVATE(this)->contextmenuenabled = yes; +} + +/*! + Convenience method that adds a state machine to the current + SoEventManager. It also initializes the scene graph + root and active camera for the state machine, and finally it sets + up the default Quarter cursor handling. + + \sa removeStateMachine +*/ +void +QuarterWidget::addStateMachine(SoScXMLStateMachine * statemachine) +{ + SoEventManager * em = this->getSoEventManager(); + em->addSoScXMLStateMachine(statemachine); + statemachine->setSceneGraphRoot(this->getSoRenderManager()->getSceneGraph()); + statemachine->setActiveCamera(this->getSoRenderManager()->getCamera()); + statemachine->addStateChangeCallback(QuarterWidgetP::statechangecb, PRIVATE(this)); +} + +/*! + Convenience method that removes a state machine to the current + SoEventManager. + + \sa addStateMachine +*/ +void +QuarterWidget::removeStateMachine(SoScXMLStateMachine * statemachine) +{ + SoEventManager * em = this->getSoEventManager(); + statemachine->setSceneGraphRoot(NULL); + statemachine->setActiveCamera(NULL); + em->removeSoScXMLStateMachine(statemachine); +} + +/*! + See \ref QWidget::minimumSizeHint + */ +QSize +QuarterWidget::minimumSizeHint(void) const +{ + return QSize(50, 50); +} + +/*! Returns a list of grouped actions that corresponds to the + TransparencyType enum. If you want to create a menu in your + application that controls the transparency type used in + QuarterWidget, add these actions to the menu. + */ +QList +QuarterWidget::transparencyTypeActions(void) const +{ + return PRIVATE(this)->transparencyTypeActions(); +} + +/*! Returns a list of grouped actions that corresponds to the + StereoMode enum. If you want to create a menu in your + application that controls the stereo mode used in + QuarterWidget, add these actions to the menu. + */ +QList +QuarterWidget::stereoModeActions(void) const +{ + return PRIVATE(this)->stereoModeActions(); +} + +/*! Returns a list of grouped actions that corresponds to the + RenderMode enum. If you want to create a menu in your + application that controls the render mode type used in + QuarterWidget, add these actions to the menu. + */ +QList +QuarterWidget::renderModeActions(void) const +{ + return PRIVATE(this)->renderModeActions(); +} + +/*! + \property QuarterWidget::navigationModeFile + + An url to a navigation mode file which is a scxml file which defines + the possible states for the Coin navigation system + + Supports: + \li \b coin for internal coinresources + \li \b file for filesystem path to resources + + \sa scxml +*/ + +/*! + Removes any navigationModeFile set. +*/ +void +QuarterWidget::resetNavigationModeFile(void) { + this->setNavigationModeFile(QUrl()); +} + +/*! + Sets a navigation mode file. Supports the schemes "coin" and "file" + + \param[in] url Url to the resource +*/ +void +QuarterWidget::setNavigationModeFile(const QUrl & url) +{ + QString filename; + + if (url.scheme()=="coin") { + filename = url.path(); + //FIXME: This conditional needs to be implemented when the + //CoinResources systems if working +#if 0 + //#if (COIN_MAJOR_VERSION==3) && (COIN_MINOR_VERSION==0) +#endif + //Workaround for differences between url scheme, and Coin internal + //scheme in Coin 3.0. + if (filename[0]=='/') { + filename.remove(0,1); + } +#if 0 + //#endif +#endif + filename = url.scheme()+':'+filename; + } + else if (url.scheme()=="file") + filename = url.toLocalFile(); + else if (url.isEmpty()) { + if (PRIVATE(this)->currentStateMachine) { + this->removeStateMachine(PRIVATE(this)->currentStateMachine); + delete PRIVATE(this)->currentStateMachine; + PRIVATE(this)->currentStateMachine = NULL; + PRIVATE(this)->navigationModeFile = url; + } + return; + } + else { + qDebug()<isOfType(SoScXMLStateMachine::getClassTypeId())) { + SoScXMLStateMachine * newsm = + static_cast(stateMachine); + if (PRIVATE(this)->currentStateMachine) { + this->removeStateMachine(PRIVATE(this)->currentStateMachine); + delete PRIVATE(this)->currentStateMachine; + } + this->addStateMachine(newsm); + newsm->initialize(); + PRIVATE(this)->currentStateMachine = newsm; + } + else { + if (stateMachine) + delete stateMachine; + qDebug()<navigationModeFile = url; + + if (QUrl(DEFAULT_NAVIGATIONFILE) == PRIVATE(this)->navigationModeFile ) { + + // set up default cursors for the examiner navigation states + //FIXME: It may be overly restrictive to not do this for arbitrary + //navigation systems? - BFG 20090117 + this->setStateCursor("interact", Qt::ArrowCursor); + this->setStateCursor("idle", Qt::OpenHandCursor); +#if QT_VERSION >= 0x040200 + this->setStateCursor("rotate", Qt::ClosedHandCursor); +#endif + this->setStateCursor("pan", Qt::SizeAllCursor); + this->setStateCursor("zoom", Qt::SizeVerCursor); + this->setStateCursor("dolly", Qt::SizeVerCursor); + this->setStateCursor("seek", Qt::CrossCursor); + this->setStateCursor("spin", Qt::OpenHandCursor); + } +} + +/*! + \retval The current navigationModeFile +*/ +const QUrl & +QuarterWidget::navigationModeFile(void) const +{ + return PRIVATE(this)->navigationModeFile; +} + +#undef PRIVATE diff --git a/src/Gui/Quarter/QuarterWidget.h b/src/Gui/Quarter/QuarterWidget.h new file mode 100644 index 000000000..f593fa8a7 --- /dev/null +++ b/src/Gui/Quarter/QuarterWidget.h @@ -0,0 +1,199 @@ +#ifndef QUARTER_QUARTERWIDGET_H +#define QUARTER_QUARTERWIDGET_H + +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include + +class QMenu; +class SoNode; +class SoEvent; +class SoCamera; +class SoEventManager; +class SoRenderManager; +class SoDirectionalLight; +class SoScXMLStateMachine; + +namespace SIM { namespace Coin3D { namespace Quarter { + +class EventFilter; +const char DEFAULT_NAVIGATIONFILE [] = "coin:///scxml/navigation/examiner.xml"; + +class QUARTER_DLL_API QuarterWidget : public QGLWidget { + typedef QGLWidget inherited; + Q_OBJECT + + Q_PROPERTY(QUrl navigationModeFile READ navigationModeFile WRITE setNavigationModeFile RESET resetNavigationModeFile) + Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) + Q_PROPERTY(bool contextMenuEnabled READ contextMenuEnabled WRITE setContextMenuEnabled) + Q_PROPERTY(bool headlightEnabled READ headlightEnabled WRITE setHeadlightEnabled) + Q_PROPERTY(bool clearZBuffer READ clearZBuffer WRITE setClearZBuffer) + Q_PROPERTY(bool clearWindow READ clearWindow WRITE setClearWindow) + Q_PROPERTY(bool interactionModeEnabled READ interactionModeEnabled WRITE setInteractionModeEnabled) + Q_PROPERTY(bool interactionModeOn READ interactionModeOn WRITE setInteractionModeOn) + + Q_PROPERTY(TransparencyType transparencyType READ transparencyType WRITE setTransparencyType) + Q_PROPERTY(RenderMode renderMode READ renderMode WRITE setRenderMode) + Q_PROPERTY(StereoMode stereoMode READ stereoMode WRITE setStereoMode) + + Q_ENUMS(TransparencyType) + Q_ENUMS(RenderMode) + Q_ENUMS(StereoMode) + + +public: + explicit QuarterWidget(QWidget * parent = 0, const QGLWidget * sharewidget = 0, Qt::WindowFlags f = 0); + explicit QuarterWidget(QGLContext * context, QWidget * parent = 0, const QGLWidget * sharewidget = 0, Qt::WindowFlags f = 0); + explicit QuarterWidget(const QGLFormat & format, QWidget * parent = 0, const QGLWidget * shareWidget = 0, Qt::WindowFlags f = 0); + virtual ~QuarterWidget(); + + enum TransparencyType { + SCREEN_DOOR = SoGLRenderAction::SCREEN_DOOR, + ADD = SoGLRenderAction::ADD, + DELAYED_ADD = SoGLRenderAction::DELAYED_ADD, + SORTED_OBJECT_ADD = SoGLRenderAction::SORTED_OBJECT_ADD, + BLEND = SoGLRenderAction::BLEND, + DELAYED_BLEND = SoGLRenderAction::DELAYED_BLEND, + SORTED_OBJECT_BLEND = SoGLRenderAction::SORTED_OBJECT_BLEND, + SORTED_OBJECT_SORTED_TRIANGLE_ADD = SoGLRenderAction::SORTED_OBJECT_SORTED_TRIANGLE_ADD, + SORTED_OBJECT_SORTED_TRIANGLE_BLEND = SoGLRenderAction::SORTED_OBJECT_SORTED_TRIANGLE_BLEND, + NONE = SoGLRenderAction::NONE, + SORTED_LAYERS_BLEND = SoGLRenderAction::SORTED_LAYERS_BLEND + }; + + enum RenderMode { + AS_IS = SoRenderManager::AS_IS, + WIREFRAME = SoRenderManager::WIREFRAME, + WIREFRAME_OVERLAY = SoRenderManager::WIREFRAME_OVERLAY, + POINTS = SoRenderManager::POINTS, + HIDDEN_LINE = SoRenderManager::HIDDEN_LINE, + BOUNDING_BOX = SoRenderManager::BOUNDING_BOX + }; + + enum StereoMode { + MONO = SoRenderManager::MONO, + ANAGLYPH = SoRenderManager::ANAGLYPH, + QUAD_BUFFER = SoRenderManager::QUAD_BUFFER, + INTERLEAVED_ROWS = SoRenderManager::INTERLEAVED_ROWS, + INTERLEAVED_COLUMNS = SoRenderManager::INTERLEAVED_COLUMNS + }; + + TransparencyType transparencyType(void) const; + RenderMode renderMode(void) const; + StereoMode stereoMode(void) const; + + void setBackgroundColor(const QColor & color); + QColor backgroundColor(void) const; + + void resetNavigationModeFile(void); + void setNavigationModeFile(const QUrl & url = QUrl(DEFAULT_NAVIGATIONFILE)); + const QUrl & navigationModeFile(void) const; + + void setContextMenuEnabled(bool yes); + bool contextMenuEnabled(void) const; + QMenu * getContextMenu(void) const; + + bool headlightEnabled(void) const; + void setHeadlightEnabled(bool onoff); + SoDirectionalLight * getHeadlight(void); + + bool clearZBuffer(void) const; + void setClearZBuffer(bool onoff); + + bool clearWindow(void) const; + void setClearWindow(bool onoff); + + bool interactionModeEnabled(void) const; + void setInteractionModeEnabled(bool onoff); + + bool interactionModeOn(void) const; + void setInteractionModeOn(bool onoff); + + void setStateCursor(const SbName & state, const QCursor & cursor); + QCursor stateCursor(const SbName & state); + + uint32_t getCacheContextId(void) const; + + virtual void setSceneGraph(SoNode * root); + virtual SoNode * getSceneGraph(void) const; + + void setSoEventManager(SoEventManager * manager); + SoEventManager * getSoEventManager(void) const; + + void setSoRenderManager(SoRenderManager * manager); + SoRenderManager * getSoRenderManager(void) const; + + EventFilter * getEventFilter(void) const; + + void addStateMachine(SoScXMLStateMachine * statemachine); + void removeStateMachine(SoScXMLStateMachine * statemachine); + + virtual bool processSoEvent(const SoEvent * event); + virtual QSize minimumSizeHint(void) const; + + QList transparencyTypeActions(void) const; + QList stereoModeActions(void) const; + QList renderModeActions(void) const; + +public slots: + virtual void viewAll(void); + virtual void seek(void); + + void redraw(void); + + void setRenderMode(RenderMode mode); + void setStereoMode(StereoMode mode); + void setTransparencyType(TransparencyType type); + +protected: + virtual void resizeGL(int width, int height); + virtual void initializeGL(void); + virtual void paintGL(void); + virtual void actualRedraw(void); + +private: + void constructor(const QGLWidget * sharewidget); + friend class QuarterWidgetP; + class QuarterWidgetP * pimpl; +}; + +}}} // namespace + +#endif // QUARTER_QUARTERWIDGET_H diff --git a/src/Gui/Quarter/QuarterWidgetP.cpp b/src/Gui/Quarter/QuarterWidgetP.cpp new file mode 100644 index 000000000..79ac6fa5a --- /dev/null +++ b/src/Gui/Quarter/QuarterWidgetP.cpp @@ -0,0 +1,325 @@ +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include "QuarterWidgetP.h" +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "NativeEvent.h" +#include "ContextMenu.h" +#include "QuarterP.h" + +#include + +using namespace SIM::Coin3D::Quarter; + +class QuarterWidgetP_cachecontext { +public: + uint32_t id; + SbList widgetlist; +}; + +static SbList * cachecontext_list = NULL; + +QuarterWidgetP::QuarterWidgetP(QuarterWidget * masterptr, const QGLWidget * sharewidget) +: master(masterptr), + scene(NULL), + eventfilter(NULL), + interactionmode(NULL), + sorendermanager(NULL), + soeventmanager(NULL), + initialsorendermanager(false), + initialsoeventmanager(false), + headlight(NULL), + cachecontext(NULL), + contextmenu(NULL), + contextmenuenabled(true), + autoredrawenabled(true), + interactionmodeenabled(false), + clearzbuffer(true), + clearwindow(true), + addactions(true) +{ + this->cachecontext = findCacheContext(masterptr, sharewidget); + + // FIXME: Centralize this as only one custom event filter can be + // added to an application. (20101019 handegar) + qApp->setEventFilter(QuarterWidgetP::nativeEventFilter); +} + +QuarterWidgetP::~QuarterWidgetP() +{ + removeFromCacheContext(this->cachecontext, this->master); + if (this->contextmenu) { + delete this->contextmenu; + } +} + +SoCamera * +QuarterWidgetP::searchForCamera(SoNode * root) +{ + SoSearchAction sa; + sa.setInterest(SoSearchAction::FIRST); + sa.setType(SoCamera::getClassTypeId()); + sa.apply(root); + + if (sa.getPath()) { + SoNode * node = sa.getPath()->getTail(); + if (node && node->isOfType(SoCamera::getClassTypeId())) { + return (SoCamera *) node; + } + } + return NULL; +} + +uint32_t +QuarterWidgetP::getCacheContextId(void) const +{ + return this->cachecontext->id; +} + +QuarterWidgetP_cachecontext * +QuarterWidgetP::findCacheContext(QuarterWidget * widget, const QGLWidget * sharewidget) +{ + if (cachecontext_list == NULL) { + // FIXME: static memory leak + cachecontext_list = new SbList ; + } + for (int i = 0; i < cachecontext_list->getLength(); i++) { + QuarterWidgetP_cachecontext * cachecontext = (*cachecontext_list)[i]; + + for (int j = 0; j < cachecontext->widgetlist.getLength(); j++) { + if (cachecontext->widgetlist[j] == sharewidget) { + cachecontext->widgetlist.append((const QGLWidget*) widget); + return cachecontext; + } + } + } + QuarterWidgetP_cachecontext * cachecontext = new QuarterWidgetP_cachecontext; + cachecontext->id = SoGLCacheContextElement::getUniqueCacheContext(); + cachecontext->widgetlist.append((const QGLWidget*) widget); + cachecontext_list->append(cachecontext); + + return cachecontext; +} + +void +QuarterWidgetP::removeFromCacheContext(QuarterWidgetP_cachecontext * context, const QGLWidget * widget) +{ + context->widgetlist.removeItem((const QGLWidget*) widget); + + if (context->widgetlist.getLength() == 0) { // last context in this share group? + assert(cachecontext_list); + + for (int i = 0; i < cachecontext_list->getLength(); i++) { + if ((*cachecontext_list)[i] == context) { + // set the context while calling destructingContext() (might trigger OpenGL calls) + const_cast (widget)->makeCurrent(); + // fetch the cc_glglue context instance as a workaround for a bug fixed in Coin r12818 + (void) cc_glglue_instance(context->id); + cachecontext_list->removeFast(i); + SoContextHandler::destructingContext(context->id); + const_cast (widget)->doneCurrent(); + delete context; + return; + } + } + } +} + +/*! + + */ +void +QuarterWidgetP::rendercb(void * userdata, SoRenderManager *) +{ + QuarterWidget * thisp = static_cast(userdata); + + if (thisp->pimpl->autoredrawenabled) { + thisp->redraw(); + } +} + +void +QuarterWidgetP::prerendercb(void * userdata, SoRenderManager * manager) +{ + QuarterWidgetP * thisp = static_cast(userdata); + SoEventManager * evman = thisp->soeventmanager; + assert(evman); + for (int c = 0; c < evman->getNumSoScXMLStateMachines(); ++c) { + SoScXMLStateMachine * statemachine = evman->getSoScXMLStateMachine(c); + statemachine->preGLRender(); + } +} + +void +QuarterWidgetP::postrendercb(void * userdata, SoRenderManager * manager) +{ + QuarterWidgetP * thisp = static_cast(userdata); + SoEventManager * evman = thisp->soeventmanager; + assert(evman); + for (int c = 0; c < evman->getNumSoScXMLStateMachines(); ++c) { + SoScXMLStateMachine * statemachine = evman->getSoScXMLStateMachine(c); + statemachine->postGLRender(); + } +} + +void +QuarterWidgetP::statechangecb(void * userdata, ScXMLStateMachine * statemachine, const char * stateid, SbBool enter, SbBool) +{ + static const SbName contextmenurequest("contextmenurequest"); + QuarterWidgetP * thisp = static_cast(userdata); + assert(thisp && thisp->master); + if (enter) { + SbName state(stateid); + if (thisp->contextmenuenabled && state == contextmenurequest) { + thisp->contextMenu()->exec(thisp->eventfilter->globalMousePosition()); + } + if (QuarterP::statecursormap->contains(state)) { + QCursor cursor = QuarterP::statecursormap->value(state); + thisp->master->setCursor(cursor); + } + } +} + +#define ADD_ACTION(enum, text, group, parent, list) \ + do { \ + QAction * action = new QAction(text, parent); \ + action->setCheckable(true); \ + action->setData(enum); \ + action->setObjectName(text); \ + action->setActionGroup(group); \ + list.append(action); \ + } while (0) + + +QList +QuarterWidgetP::transparencyTypeActions(void) const +{ + if (this->transparencytypeactions.isEmpty()) { + this->transparencytypegroup = new QActionGroup(this->master); + ADD_ACTION(QuarterWidget::NONE, "none", transparencytypegroup, this->master, this->transparencytypeactions); + ADD_ACTION(QuarterWidget::SCREEN_DOOR, "screen door", transparencytypegroup, this->master, this->transparencytypeactions); + ADD_ACTION(QuarterWidget::ADD, "add", transparencytypegroup, this->master, this->transparencytypeactions); + ADD_ACTION(QuarterWidget::DELAYED_ADD, "delayed add", transparencytypegroup, this->master, this->transparencytypeactions); + ADD_ACTION(QuarterWidget::SORTED_OBJECT_ADD, "sorted object add", transparencytypegroup, this->master, this->transparencytypeactions); + ADD_ACTION(QuarterWidget::BLEND, "blend", transparencytypegroup, this->master, this->transparencytypeactions); + ADD_ACTION(QuarterWidget::DELAYED_BLEND, "delayed blend", transparencytypegroup, this->master, this->transparencytypeactions); + ADD_ACTION(QuarterWidget::SORTED_OBJECT_BLEND, "sorted object blend", transparencytypegroup, this->master, this->transparencytypeactions); + ADD_ACTION(QuarterWidget::SORTED_OBJECT_SORTED_TRIANGLE_ADD, "sorted object sorted triangle add", transparencytypegroup, this->master, this->transparencytypeactions); + ADD_ACTION(QuarterWidget::SORTED_OBJECT_SORTED_TRIANGLE_BLEND, "sorted object sorted triangle blend", transparencytypegroup, this->master, this->transparencytypeactions); + ADD_ACTION(QuarterWidget::SORTED_LAYERS_BLEND, "sorted layers blend", transparencytypegroup, this->master, this->transparencytypeactions); + } + return this->transparencytypeactions; +} + +QList +QuarterWidgetP::stereoModeActions(void) const +{ + if (this->stereomodeactions.isEmpty()) { + this->stereomodegroup = new QActionGroup(this->master); + ADD_ACTION(QuarterWidget::MONO, "mono", stereomodegroup, this->master, stereomodeactions); + ADD_ACTION(QuarterWidget::ANAGLYPH, "anaglyph", stereomodegroup, this->master, stereomodeactions); + ADD_ACTION(QuarterWidget::QUAD_BUFFER, "quad buffer", stereomodegroup, this->master, stereomodeactions); + ADD_ACTION(QuarterWidget::INTERLEAVED_ROWS, "interleaved rows", stereomodegroup, this->master, stereomodeactions); + ADD_ACTION(QuarterWidget::INTERLEAVED_COLUMNS, "interleaved columns", stereomodegroup, this->master, stereomodeactions); + } + return this->stereomodeactions; +} + +QList +QuarterWidgetP::renderModeActions(void) const +{ + if (this->rendermodeactions.isEmpty()) { + this->rendermodegroup = new QActionGroup(this->master); + ADD_ACTION(QuarterWidget::AS_IS, "as is", rendermodegroup, this->master, rendermodeactions); + ADD_ACTION(QuarterWidget::WIREFRAME, "wireframe", rendermodegroup, this->master, rendermodeactions); + ADD_ACTION(QuarterWidget::WIREFRAME_OVERLAY, "wireframe overlay", rendermodegroup, this->master, rendermodeactions); + ADD_ACTION(QuarterWidget::POINTS, "points", rendermodegroup, this->master, rendermodeactions); + ADD_ACTION(QuarterWidget::HIDDEN_LINE, "hidden line", rendermodegroup, this->master, rendermodeactions); + ADD_ACTION(QuarterWidget::BOUNDING_BOX, "bounding box", rendermodegroup, this->master, rendermodeactions); + } + return this->rendermodeactions; +} + +#undef ADD_ACTION + +QMenu * +QuarterWidgetP::contextMenu(void) +{ + if (!this->contextmenu) { + this->contextmenu = new ContextMenu(this->master); + } + + return this->contextmenu->getMenu(); +} + + +bool +QuarterWidgetP::nativeEventFilter(void * message, long * result) +{ +#ifdef HAVE_SPACENAV_LIB + XEvent * event = (XEvent *) message; + if (event->type == ClientMessage) { + // FIXME: I dont really like this, but the original XEvent will + // die before reaching the destination within the Qt system. To + // avoid this, we'll have to make a copy. We should try to find a + // workaround for this. (20101020 handegar) + + // The copy will automatically be deleted when the NativeEvent dies. + XEvent * copy = (XEvent *) malloc(sizeof(XEvent)); + memcpy(copy, event, sizeof(XEvent)); + NativeEvent * ne = new NativeEvent(copy); + + qApp->postEvent(QApplication::focusWidget(), ne); + return true; + } +#endif // HAVE_SPACENAV_LIB + + return false; +} + diff --git a/src/Gui/Quarter/QuarterWidgetP.h b/src/Gui/Quarter/QuarterWidgetP.h new file mode 100644 index 000000000..1f6aeb0e6 --- /dev/null +++ b/src/Gui/Quarter/QuarterWidgetP.h @@ -0,0 +1,120 @@ +#ifndef QUARTER_QUARTERWIDGETP_H +#define QUARTER_QUARTERWIDGETP_H + +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include +#include +#include +#include +#include + +class SoNode; +class SoCamera; +class SoRenderManager; +class SoEventManager; +class SoDirectionalLight; +class QuarterWidgetP_cachecontext; +class QGLWidget; +class QAction; +class QActionGroup; +class QMenu; +class ScXMLStateMachine; +class SoScXMLStateMachine; +template class QMap; + +namespace SIM { namespace Coin3D { namespace Quarter { + +class EventFilter; +class InteractionMode; +class ContextMenu; + +class QuarterWidgetP { +public: + + QuarterWidgetP(class QuarterWidget * master, const QGLWidget * sharewidget); + ~QuarterWidgetP(); + + SoCamera * searchForCamera(SoNode * root); + uint32_t getCacheContextId(void) const; + QMenu * contextMenu(void); + + QList transparencyTypeActions(void) const; + QList renderModeActions(void) const; + QList stereoModeActions(void) const; + + QuarterWidget * const master; + SoNode * scene; + EventFilter * eventfilter; + InteractionMode * interactionmode; + SoRenderManager * sorendermanager; + SoEventManager * soeventmanager; + bool initialsorendermanager; + bool initialsoeventmanager; + SoDirectionalLight * headlight; + QuarterWidgetP_cachecontext * cachecontext; + bool contextmenuenabled; + bool autoredrawenabled; + bool interactionmodeenabled; + bool clearzbuffer; + bool clearwindow; + bool addactions; + bool processdelayqueue; + QUrl navigationModeFile; + SoScXMLStateMachine * currentStateMachine; + + static void rendercb(void * userdata, SoRenderManager *); + static void prerendercb(void * userdata, SoRenderManager * manager); + static void postrendercb(void * userdata, SoRenderManager * manager); + static void statechangecb(void * userdata, ScXMLStateMachine * statemachine, const char * stateid, SbBool enter, SbBool success); + + mutable QList transparencytypeactions; + mutable QList rendermodeactions; + mutable QList stereomodeactions; + + mutable QActionGroup * transparencytypegroup; + mutable QActionGroup * stereomodegroup; + mutable QActionGroup * rendermodegroup; + + mutable ContextMenu * contextmenu; + + static bool nativeEventFilter(void * message, long * result); + + private: + QuarterWidgetP_cachecontext * findCacheContext(QuarterWidget * widget, const QGLWidget * sharewidget); + static void removeFromCacheContext(QuarterWidgetP_cachecontext * context, const QGLWidget * widget); +}; + +#endif // QUARTER_QUARTERWIDGETP_H + +}}} // namespace diff --git a/src/Gui/Quarter/SensorManager.cpp b/src/Gui/Quarter/SensorManager.cpp new file mode 100644 index 000000000..e2fd5ae34 --- /dev/null +++ b/src/Gui/Quarter/SensorManager.cpp @@ -0,0 +1,173 @@ +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include "SensorManager.h" + +#include + +#include +#include +#include +#include +#include +#include "SignalThread.h" + +using namespace SIM::Coin3D::Quarter; + +SensorManager::SensorManager(void) + : inherited() +{ + this->mainthreadid = cc_thread_id(); + this->signalthread = new SignalThread(); + + QObject::connect(this->signalthread, SIGNAL(triggerSignal()), + this, SLOT(sensorQueueChanged())); + + this->idletimer = new QTimer; + this->delaytimer = new QTimer; + this->timerqueuetimer = new QTimer; + + this->idletimer->setSingleShot(true); + this->delaytimer->setSingleShot(true); + this->timerqueuetimer->setSingleShot(true); + + this->connect(this->idletimer, SIGNAL(timeout(void)), this, SLOT(idleTimeout())); + this->connect(this->delaytimer, SIGNAL(timeout(void)), this, SLOT(delayTimeout())); + this->connect(this->timerqueuetimer, SIGNAL(timeout(void)), this, SLOT(timerQueueTimeout())); + + SoDB::getSensorManager()->setChangedCallback(SensorManager::sensorQueueChangedCB, this); + this->timerEpsilon = 1.0 / 5000.0; + + SoDB::setRealTimeInterval(1.0 / 25.0); + SoRenderManager::enableRealTimeUpdate(FALSE); +} + +SensorManager::~SensorManager() +{ + // remove the Coin callback before shutting down + SoDB::getSensorManager()->setChangedCallback(NULL, NULL); + + if (this->signalthread->isRunning()) { + this->signalthread->stopThread(); + this->signalthread->wait(); + } + delete this->signalthread; + delete this->idletimer; + delete this->delaytimer; + delete this->timerqueuetimer; +} + +void +SensorManager::sensorQueueChangedCB(void * closure) +{ + SensorManager * thisp = (SensorManager * ) closure; + + // if we get a callback from another thread, route the callback + // through SignalThread so that we receive the callback in the + // QApplication thread (needed since QTimer isn't thread safe) + if (cc_thread_id() != thisp->mainthreadid) { + if (!thisp->signalthread->isRunning()) thisp->signalthread->start(); + thisp->signalthread->trigger(); + } + else { + thisp->sensorQueueChanged(); + } +} + +void +SensorManager::sensorQueueChanged(void) +{ + SoSensorManager * sensormanager = SoDB::getSensorManager(); + assert(sensormanager); + + SbTime interval; + if (sensormanager->isTimerSensorPending(interval)) { + interval -= SbTime::getTimeOfDay(); + if (interval.getValue() < this->timerEpsilon) { + interval.setValue(this->timerEpsilon); + } + if (!this->timerqueuetimer->isActive()) { + this->timerqueuetimer->start(interval.getMsecValue()); + } else { + this->timerqueuetimer->setInterval(interval.getMsecValue()); + } + } else if (this->timerqueuetimer->isActive()) { + this->timerqueuetimer->stop(); + } + + if (sensormanager->isDelaySensorPending()) { + this->idletimer->start(0); + + if (!this->delaytimer->isActive()) { + SbTime time = SoDB::getDelaySensorTimeout(); + if (time != SbTime::zero()) { + this->delaytimer->start(time.getMsecValue()); + } + } + } else { + if (this->idletimer->isActive()) { + this->idletimer->stop(); + } + if (this->delaytimer->isActive()) { + this->delaytimer->stop(); + } + } +} + +void +SensorManager::idleTimeout(void) +{ + SoDB::getSensorManager()->processTimerQueue(); + SoDB::getSensorManager()->processDelayQueue(TRUE); + this->sensorQueueChanged(); +} + +void +SensorManager::timerQueueTimeout(void) +{ + SoDB::getSensorManager()->processTimerQueue(); + this->sensorQueueChanged(); +} + +void +SensorManager::delayTimeout(void) +{ + SoDB::getSensorManager()->processTimerQueue(); + SoDB::getSensorManager()->processDelayQueue(FALSE); + this->sensorQueueChanged(); +} + +void +SensorManager::setTimerEpsilon(double sec) +{ + this->timerEpsilon = sec; +} diff --git a/src/Gui/Quarter/SensorManager.h b/src/Gui/Quarter/SensorManager.h new file mode 100644 index 000000000..4b3fb7d0d --- /dev/null +++ b/src/Gui/Quarter/SensorManager.h @@ -0,0 +1,70 @@ +#ifndef QUARTER_SENSORMANAGER_H +#define QUARTER_SENSORMANAGER_H + +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include + +class QTimer; + +namespace SIM { namespace Coin3D { namespace Quarter { + +class SignalThread; + +class SensorManager : public QObject { + Q_OBJECT + typedef QObject inherited; +public: + SensorManager(void); + ~SensorManager(); + +public slots: + void idleTimeout(void); + void delayTimeout(void); + void timerQueueTimeout(void); + void sensorQueueChanged(void); + void setTimerEpsilon(double sec); + +private: + static void sensorQueueChangedCB(void * closure); + QTimer * idletimer; + QTimer * delaytimer; + QTimer * timerqueuetimer; + unsigned long mainthreadid; + SignalThread * signalthread; + double timerEpsilon; +}; + +}}} // namespace + +#endif // QUARTER_SENSORMANAGER_H diff --git a/src/Gui/Quarter/SignalThread.cpp b/src/Gui/Quarter/SignalThread.cpp new file mode 100644 index 000000000..bcd9b78c6 --- /dev/null +++ b/src/Gui/Quarter/SignalThread.cpp @@ -0,0 +1,77 @@ +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include "SignalThread.h" + +using namespace SIM::Coin3D::Quarter; + +SignalThread::SignalThread(void) + : isstopped(false) +{ +} + +SignalThread::~SignalThread() +{ +} + +void +SignalThread::trigger(void) +{ + // lock first to make sure the QThread is actually waiting for a signal + this->mutex.lock(); + this->waitcond.wakeOne(); + this->mutex.unlock(); +} + +void +SignalThread::stopThread(void) +{ + this->mutex.lock(); + this->isstopped = true; + this->waitcond.wakeOne(); + this->mutex.unlock(); +} + + +void +SignalThread::run(void) +{ + this->mutex.lock(); + while (!this->isstopped) { + // just wait, and trigger every time we receive a signal + this->waitcond.wait(&this->mutex); + if (!this->isstopped) { + emit triggerSignal(); + } + } + this->mutex.unlock(); +} diff --git a/src/Gui/Quarter/SignalThread.h b/src/Gui/Quarter/SignalThread.h new file mode 100644 index 000000000..fcaedca33 --- /dev/null +++ b/src/Gui/Quarter/SignalThread.h @@ -0,0 +1,66 @@ +#ifndef QUARTER_SIGNALTHREAD_H +#define QUARTER_SIGNALTHREAD_H + +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include +#include +#include + +class SoQtP; + +namespace SIM { namespace Coin3D { namespace Quarter { + +class SignalThread : public QThread { + Q_OBJECT +public: + SignalThread(void); + virtual ~SignalThread(); + + virtual void run(void); + void trigger(void); + void stopThread(void); + +signals: + + void triggerSignal(void); + +private: + QWaitCondition waitcond; + QMutex mutex; + bool isstopped; +}; + +}}} // namespace + +#endif // QUARTER_SIGNALTHREAD_H diff --git a/src/Gui/Quarter/SpaceNavigatorDevice.cpp b/src/Gui/Quarter/SpaceNavigatorDevice.cpp new file mode 100644 index 000000000..e207ba503 --- /dev/null +++ b/src/Gui/Quarter/SpaceNavigatorDevice.cpp @@ -0,0 +1,186 @@ +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "NativeEvent.h" + +#ifdef HAVE_SPACENAV_LIB +#include +#include +#endif //HAVE_SPACENAV_LIB + +#include + + +namespace SIM { namespace Coin3D { namespace Quarter { +class SpaceNavigatorDeviceP { +public: + SpaceNavigatorDeviceP(SpaceNavigatorDevice * master) { + this->master = master; + this->hasdevice = false; + this->windowid = 0; + this->motionevent = new SoMotion3Event; + this->buttonevent = new SoSpaceballButtonEvent; + } + ~SpaceNavigatorDeviceP() { + delete this->motionevent; + delete this->buttonevent; + } + + static bool customEventFilter(void * message, long * result); + + SpaceNavigatorDevice * master; + bool hasdevice; + WId windowid; + + SoMotion3Event * motionevent; + SoSpaceballButtonEvent * buttonevent; + +}; +}}} + + +#define PRIVATE(obj) obj->pimpl +using namespace SIM::Coin3D::Quarter; + +SpaceNavigatorDevice::SpaceNavigatorDevice() +{ + PRIVATE(this) = new SpaceNavigatorDeviceP(this); + +#ifdef HAVE_SPACENAV_LIB + PRIVATE(this)->hasdevice = + spnav_x11_open(QX11Info::display(), PRIVATE(this)->windowid) == -1 ? false : true; + + // FIXME: Use a debugmessage mechanism instead? (20101020 handegar) + if (!PRIVATE(this)->hasdevice) { + fprintf(stderr, "Quarter:: Could not hook up to Spacenav device.\n"); + } + +#endif // HAVE_SPACENAV_LIB +} + + +SpaceNavigatorDevice::~SpaceNavigatorDevice() +{ + delete PRIVATE(this); +} + + +const SoEvent * +SpaceNavigatorDevice::translateEvent(QEvent * event) +{ + SoEvent * ret = NULL; + +#ifdef HAVE_SPACENAV_LIB + NativeEvent * ce = dynamic_cast(event); + if (ce && ce->getEvent()) { + XEvent * xev = ce->getEvent(); + + spnav_event spev; + if(spnav_x11_event(xev, &spev)) { + if(spev.type == SPNAV_EVENT_MOTION) { + // Add rotation + const float axislen = sqrt(spev.motion.rx*spev.motion.rx + + spev.motion.ry*spev.motion.ry + + spev.motion.rz*spev.motion.rz); + + const float half_angle = axislen * 0.5 * 0.001; + const float sin_half = sin(half_angle); + SbRotation rot((spev.motion.rx / axislen) * sin_half, + (spev.motion.ry / axislen) * sin_half, + (spev.motion.rz / axislen) * sin_half, + cos(half_angle)); + PRIVATE(this)->motionevent->setRotation(rot); + + // Add translation + SbVec3f pos(spev.motion.x * 0.001, + spev.motion.y * 0.001, + spev.motion.z * 0.001); + PRIVATE(this)->motionevent->setTranslation(pos); + + ret = PRIVATE(this)->motionevent; + } + else if (spev.type == SPNAV_EVENT_BUTTON){ + if(spev.button.press) { + PRIVATE(this)->buttonevent->setState(SoButtonEvent::DOWN); + switch(spev.button.bnum) { + case 0: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON1); + break; + case 1: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON2); + break; + case 2: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON3); + break; + case 3: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON4); + break; + case 4: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON5); + break; + case 5: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON6); + break; + case 6: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON7); + break; + case 7: PRIVATE(this)->buttonevent->setButton(SoSpaceballButtonEvent::BUTTON8); + break; + default: + // FIXME: Which button corresponds to the + // SoSpaceballButtonEvent::PICK enum? (20101020 handegar) + break; + } + } + else { + PRIVATE(this)->buttonevent->setState(SoButtonEvent::UP); + } + + ret = PRIVATE(this)->buttonevent; + } + else { + // Unknown Spacenav event. + assert(0 && "Unknown event type"); + } + } + } +#endif // HAVE_SPACENAV_LIB + + return ret; +} + + +#undef PRIVATE +#undef PUBLIC diff --git a/src/Gui/Quarter/devices/InputDevice.h b/src/Gui/Quarter/devices/InputDevice.h new file mode 100644 index 000000000..9e7d1eb46 --- /dev/null +++ b/src/Gui/Quarter/devices/InputDevice.h @@ -0,0 +1,67 @@ +#ifndef QUARTER_INPUTDEVICE_H +#define QUARTER_INPUTDEVICE_H + +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include +#include + +class QEvent; +class SoEvent; +class QInputEvent; + +namespace SIM { namespace Coin3D { namespace Quarter { + +class QUARTER_DLL_API InputDevice { +public: + InputDevice(void); + virtual ~InputDevice() {} + + /*! + Subclasses must override this method to provide custom event + handling + */ + virtual const SoEvent * translateEvent(QEvent * event) = 0; + + void setMousePosition(const SbVec2s & pos); + void setWindowSize(const SbVec2s & size); + void setModifiers(SoEvent * soevent, const QInputEvent * qevent); + +protected: + SbVec2s mousepos; + SbVec2s windowsize; +}; + +}}} // namespace + +#endif // QUARTER_INPUTDEVICE_H diff --git a/src/Gui/Quarter/devices/Keyboard.h b/src/Gui/Quarter/devices/Keyboard.h new file mode 100644 index 000000000..f00b371be --- /dev/null +++ b/src/Gui/Quarter/devices/Keyboard.h @@ -0,0 +1,58 @@ +#ifndef QUARTER_KEYBOARD_H +#define QUARTER_KEYBOARD_H + +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include +#include + +class QEvent; +class SoEvent; + +namespace SIM { namespace Coin3D { namespace Quarter { + +class QUARTER_DLL_API Keyboard : public InputDevice { +public: + Keyboard(void); + virtual ~Keyboard(); + + virtual const SoEvent * translateEvent(QEvent * event); + +private: + friend class KeyboardP; + class KeyboardP * pimpl; +}; + +}}} // namespace + +#endif // QUARTER_KEYBOARD_H diff --git a/src/Gui/Quarter/devices/Mouse.h b/src/Gui/Quarter/devices/Mouse.h new file mode 100644 index 000000000..0308694fb --- /dev/null +++ b/src/Gui/Quarter/devices/Mouse.h @@ -0,0 +1,58 @@ +#ifndef QUARTER_MOUSE_H +#define QUARTER_MOUSE_H + +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include +#include + +class QEvent; +class SoEvent; + +namespace SIM { namespace Coin3D { namespace Quarter { + +class QUARTER_DLL_API Mouse : public InputDevice { +public: + Mouse(void); + virtual ~Mouse(); + + virtual const SoEvent * translateEvent(QEvent * event); + +private: + friend class MouseP; + class MouseP * pimpl; +}; + +}}} // namespace + +#endif // QUARTER_MOUSEHANDLER_H diff --git a/src/Gui/Quarter/devices/SpaceNavigatorDevice.h b/src/Gui/Quarter/devices/SpaceNavigatorDevice.h new file mode 100644 index 000000000..ac4b88ffc --- /dev/null +++ b/src/Gui/Quarter/devices/SpaceNavigatorDevice.h @@ -0,0 +1,55 @@ +#ifndef QUARTER_SPACENAVIGATORDEVICE_H +#define QUARTER_SPACENAVIGATORDEVICE_H + +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include + +class SoEvent; +class QEvent; + +namespace SIM { namespace Coin3D { namespace Quarter { + +class QUARTER_DLL_API SpaceNavigatorDevice : public InputDevice { + public: + SpaceNavigatorDevice(void); + virtual ~SpaceNavigatorDevice(); + virtual const SoEvent * translateEvent(QEvent * event); + + private: + class SpaceNavigatorDeviceP * pimpl; + friend class SpaceNavigatorDeviceP; +}; + +}}} +#endif // !QUARTER_SPACENAVIGATORDEVICE_H diff --git a/src/Gui/Quarter/eventhandlers/DragDropHandler.h b/src/Gui/Quarter/eventhandlers/DragDropHandler.h new file mode 100644 index 000000000..83d439c26 --- /dev/null +++ b/src/Gui/Quarter/eventhandlers/DragDropHandler.h @@ -0,0 +1,62 @@ +#ifndef QUARTER_DRAGDROPHANDLER_H +#define QUARTER_DRAGDROPHANDLER_H + +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include +#include + +class QEvent; +class SoEvent; + +namespace SIM { namespace Coin3D { namespace Quarter { + +class QuarterWidget; + +class QUARTER_DLL_API DragDropHandler : public QObject { + Q_OBJECT +public: + DragDropHandler(QuarterWidget * parent); + virtual ~DragDropHandler(); + +protected: + virtual bool eventFilter(QObject *, QEvent * event); + +private: + friend class DragDropHandlerP; + class DragDropHandlerP * pimpl; +}; + +}}} // namespace + +#endif // QUARTER_DRAGDROPHANDLER_H diff --git a/src/Gui/Quarter/eventhandlers/EventFilter.h b/src/Gui/Quarter/eventhandlers/EventFilter.h new file mode 100644 index 000000000..68c7cbdf0 --- /dev/null +++ b/src/Gui/Quarter/eventhandlers/EventFilter.h @@ -0,0 +1,67 @@ +#ifndef QUARTER_EVENTFILTER_H +#define QUARTER_EVENTFILTER_H + +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include +#include + +class QEvent; +class QPoint; + +namespace SIM { namespace Coin3D { namespace Quarter { + +class InputDevice; + +class QUARTER_DLL_API EventFilter : public QObject { + Q_OBJECT + +public: + EventFilter(QObject * parent); + ~EventFilter(); + + void registerInputDevice(InputDevice * device); + void unregisterInputDevice(InputDevice * device); + + const QPoint & globalMousePosition(void) const; + +protected: + bool eventFilter(QObject * obj, QEvent * event); + +private: + class EventFilterP * pimpl; +}; + +}}} // namespace + +#endif // QUARTER_EVENTFILTER_H diff --git a/src/Gui/Quarter/eventhandlers/FocusHandler.h b/src/Gui/Quarter/eventhandlers/FocusHandler.h new file mode 100644 index 000000000..20edca610 --- /dev/null +++ b/src/Gui/Quarter/eventhandlers/FocusHandler.h @@ -0,0 +1,61 @@ +#ifndef QUARTER_FOCUSHANDLER_H +#define QUARTER_FOCUSHANDLER_H + +/**************************************************************************\ + * Copyright (c) Kongsberg Oil & Gas Technologies AS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * HOLDER 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. +\**************************************************************************/ + +#include +#include + +class QEvent; + +namespace SIM { namespace Coin3D { namespace Quarter { + +class QuarterWidget; + +class FocusHandler : public QObject { + Q_OBJECT +public: + FocusHandler(QObject * parent); + virtual ~FocusHandler(); + +protected: + virtual bool eventFilter(QObject *, QEvent * event); + +private: + void focusEvent(const SbName & focusevent); + QuarterWidget * quarterwidget; +}; + +}}} // namespace + +#endif // QUARTER_FOCUSHANDLER_H diff --git a/src/Gui/View3DInventorViewer.h b/src/Gui/View3DInventorViewer.h index 733059a38..f5cedee98 100644 --- a/src/Gui/View3DInventorViewer.h +++ b/src/Gui/View3DInventorViewer.h @@ -30,13 +30,13 @@ #include #include -#include #include -#include +#include #include #include +namespace Quarter = SIM::Coin3D::Quarter; class SoSeparator; class SoShapeHints; @@ -64,7 +64,7 @@ class SoShapeScale; /** GUI view into a 3D scene provided by View3DInventor * */ -class GuiExport View3DInventorViewer : public SoQtViewer, public Gui::SelectionSingleton::ObserverType +class GuiExport View3DInventorViewer : public Quarter::QuarterWidget, public Gui::SelectionSingleton::ObserverType { SOQT_OBJECT_ABSTRACT_HEADER(View3DInventorViewer, SoQtViewer);