Merge branch 'sceneinput'

openmw-37
Marc Zinnschlag 9 years ago
commit 6ef2319eb8

@ -85,12 +85,12 @@ opencs_units (view/widget
opencs_units (view/render
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
previewwidget editmode
previewwidget editmode instancemode
)
opencs_units_noqt (view/render
lighting lightingday lightingnight
lightingbright object cell terrainstorage
lightingbright object cell terrainstorage tagbase
)
opencs_hdrs_noqt (view/render

@ -371,6 +371,57 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
"list go to the first/last item");
}
declareSection ("scene-input", "3D Scene Input");
{
QString left ("Left Mouse-Button");
QString cLeft ("Ctrl-Left Mouse-Button");
QString right ("Right Mouse-Button");
QString cRight ("Ctrl-Right Mouse-Button");
QString middle ("Middle Mouse-Button");
QString cMiddle ("Ctrl-Middle Mouse-Button");
QStringList values;
values << left << cLeft << right << cRight << middle << cMiddle;
Setting *primaryNavigation = createSetting (Type_ComboBox, "p-navi", "Primary Camera Navigation Button");
primaryNavigation->setDeclaredValues (values);
primaryNavigation->setDefaultValue (left);
Setting *secondaryNavigation = createSetting (Type_ComboBox, "s-navi", "Secondary Camera Navigation Button");
secondaryNavigation->setDeclaredValues (values);
secondaryNavigation->setDefaultValue (cLeft);
Setting *primaryEditing = createSetting (Type_ComboBox, "p-edit", "Primary Editing Button");
primaryEditing->setDeclaredValues (values);
primaryEditing->setDefaultValue (right);
Setting *secondaryEditing = createSetting (Type_ComboBox, "s-edit", "Secondary Editing Button");
secondaryEditing->setDeclaredValues (values);
secondaryEditing->setDefaultValue (cRight);
Setting *selection = createSetting (Type_ComboBox, "select", "Selection Button");
selection->setDeclaredValues (values);
selection->setDefaultValue (middle);
Setting *contextSensitive = createSetting (Type_CheckBox, "context-select", "Context Sensitive Selection");
contextSensitive->setDefaultValue ("false");
Setting *dragMouseSensitivity = createSetting (Type_DoubleSpinBox, "drag-factor",
"Mouse sensitivity during drag operations");
dragMouseSensitivity->setDefaultValue (1.0);
dragMouseSensitivity->setRange (0.001, 100.0);
Setting *dragWheelSensitivity = createSetting (Type_DoubleSpinBox, "drag-wheel-factor",
"Mouse wheel sensitivity during drag operations");
dragWheelSensitivity->setDefaultValue (1.0);
dragWheelSensitivity->setRange (0.001, 100.0);
Setting *dragShiftFactor = createSetting (Type_DoubleSpinBox, "drag-shift-factor",
"Acceleration factor during drag operations while holding down shift");
dragShiftFactor->setDefaultValue (4.0);
dragShiftFactor->setRange (0.001, 100.0);
}
{
/******************************************************************
* There are three types of values:

@ -211,3 +211,24 @@ bool CSVRender::Cell::referenceAdded (const QModelIndex& parent, int start, int
return addObjects (start, end);
}
void CSVRender::Cell::setSelection (int elementMask, Selection mode)
{
if (elementMask & Element_Reference)
{
for (std::map<std::string, Object *>::const_iterator iter (mObjects.begin());
iter!=mObjects.end(); ++iter)
{
bool selected = false;
switch (mode)
{
case Selection_Clear: selected = false; break;
case Selection_All: selected = true; break;
case Selection_Invert: selected = !iter->second->getSelected(); break;
}
iter->second->setSelected (selected);
}
}
}

@ -49,6 +49,15 @@ namespace CSVRender
/// \return Have any objects been added?
bool addObjects (int start, int end);
public:
enum Selection
{
Selection_Clear,
Selection_All,
Selection_Invert
};
public:
Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id);
@ -75,6 +84,8 @@ namespace CSVRender
/// \return Did this call result in a modification of the visual representation of
/// this cell?
bool referenceAdded (const QModelIndex& parent, int start, int end);
void setSelection (int elementMask, Selection mode);
};
}

@ -2,6 +2,11 @@
#include "worldspacewidget.hpp"
CSVRender::WorldspaceWidget& CSVRender::EditMode::getWorldspaceWidget()
{
return *mWorldspaceWidget;
}
CSVRender::EditMode::EditMode (WorldspaceWidget *worldspaceWidget, const QIcon& icon,
unsigned int mask, const QString& tooltip, QWidget *parent)
: ModeButton (icon, tooltip, parent), mWorldspaceWidget (worldspaceWidget), mMask (mask)
@ -15,4 +20,44 @@ unsigned int CSVRender::EditMode::getInteractionMask() const
void CSVRender::EditMode::activate (CSVWidget::SceneToolbar *toolbar)
{
mWorldspaceWidget->setInteractionMask (mMask);
mWorldspaceWidget->clearSelection (~mMask);
}
void CSVRender::EditMode::updateUserSetting (const QString& name, const QStringList& value)
{
}
void CSVRender::EditMode::setEditLock (bool locked)
{
}
void CSVRender::EditMode::primaryEditPressed (osg::ref_ptr<TagBase> tag) {}
void CSVRender::EditMode::secondaryEditPressed (osg::ref_ptr<TagBase> tag) {}
void CSVRender::EditMode::selectPressed (osg::ref_ptr<TagBase> tag) {}
bool CSVRender::EditMode::primaryEditStartDrag (osg::ref_ptr<TagBase> tag)
{
return false;
}
bool CSVRender::EditMode::secondaryEditStartDrag (osg::ref_ptr<TagBase> tag)
{
return false;
}
bool CSVRender::EditMode::selectStartDrag (osg::ref_ptr<TagBase> tag)
{
return false;
}
void CSVRender::EditMode::drag (int diffX, int diffY, double speedFactor) {}
void CSVRender::EditMode::dragCompleted() {}
void CSVRender::EditMode::dragAborted() {}
void CSVRender::EditMode::dragWheel (int diff, double speedFactor) {}

@ -1,11 +1,14 @@
#ifndef CSV_RENDER_EDITMODE_H
#define CSV_RENDER_EDITMODE_H
#include <osg/ref_ptr>
#include "../widget/modebutton.hpp"
namespace CSVRender
{
class WorldspaceWidget;
class TagBase;
class EditMode : public CSVWidget::ModeButton
{
@ -14,6 +17,10 @@ namespace CSVRender
WorldspaceWidget *mWorldspaceWidget;
unsigned int mMask;
protected:
WorldspaceWidget& getWorldspaceWidget();
public:
EditMode (WorldspaceWidget *worldspaceWidget, const QIcon& icon, unsigned int mask,
@ -22,6 +29,51 @@ namespace CSVRender
unsigned int getInteractionMask() const;
virtual void activate (CSVWidget::SceneToolbar *toolbar);
/// Default-implementation: Do nothing.
virtual void updateUserSetting (const QString& name, const QStringList& value);
/// Default-implementation: Ignored.
virtual void setEditLock (bool locked);
/// Default-implementation: Ignored.
virtual void primaryEditPressed (osg::ref_ptr<TagBase> tag);
/// Default-implementation: Ignored.
virtual void secondaryEditPressed (osg::ref_ptr<TagBase> tag);
/// Default-implementation: Ignored.
virtual void selectPressed (osg::ref_ptr<TagBase> tag);
/// Default-implementation: ignore and return false
///
/// \return Drag accepted?
virtual bool primaryEditStartDrag (osg::ref_ptr<TagBase> tag);
/// Default-implementation: ignore and return false
///
/// \return Drag accepted?
virtual bool secondaryEditStartDrag (osg::ref_ptr<TagBase> tag);
/// Default-implementation: ignore and return false
///
/// \return Drag accepted?
virtual bool selectStartDrag (osg::ref_ptr<TagBase> tag);
/// Default-implementation: ignored
virtual void drag (int diffX, int diffY, double speedFactor);
/// Default-implementation: ignored
virtual void dragCompleted();
/// Default-implementation: ignored
///
/// \note dragAborted will not be called, if the drag is aborted via changing
/// editing mode
virtual void dragAborted();
/// Default-implementation: ignored
virtual void dragWheel (int diff, double speedFactor);
};
}

@ -0,0 +1,56 @@
#include "instancemode.hpp"
#include "../../model/settings/usersettings.hpp"
#include "elements.hpp"
#include "object.hpp"
#include "worldspacewidget.hpp"
CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent)
: EditMode (worldspaceWidget, QIcon (":placeholder"), Element_Reference, "Instance editing",
parent), mContextSelect (false)
{
}
void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar)
{
EditMode::activate (toolbar);
mContextSelect = CSMSettings::UserSettings::instance().setting ("scene-input/context-select")=="true";
}
void CSVRender::InstanceMode::updateUserSetting (const QString& name, const QStringList& value)
{
if (name=="scene-input/context-select")
mContextSelect = value.at (0)=="true";
}
void CSVRender::InstanceMode::primaryEditPressed (osg::ref_ptr<TagBase> tag)
{
if (mContextSelect)
selectPressed (tag);
}
void CSVRender::InstanceMode::secondaryEditPressed (osg::ref_ptr<TagBase> tag)
{
if (mContextSelect)
selectPressed (tag);
}
void CSVRender::InstanceMode::selectPressed (osg::ref_ptr<TagBase> tag)
{
if (tag)
{
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (tag.get()))
{
// hit an Object, toggle its selection state
CSVRender::Object* object = objectTag->mObject;
object->setSelected (!object->getSelected());
return;
}
}
getWorldspaceWidget().clearSelection (Element_Reference);
}

@ -0,0 +1,30 @@
#ifndef CSV_RENDER_INSTANCEMODE_H
#define CSV_RENDER_INSTANCEMODE_H
#include "editmode.hpp"
namespace CSVRender
{
class InstanceMode : public EditMode
{
Q_OBJECT
bool mContextSelect;
public:
InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent = 0);
virtual void activate (CSVWidget::SceneToolbar *toolbar);
virtual void updateUserSetting (const QString& name, const QStringList& value);
virtual void primaryEditPressed (osg::ref_ptr<TagBase> tag);
virtual void secondaryEditPressed (osg::ref_ptr<TagBase> tag);
virtual void selectPressed (osg::ref_ptr<TagBase> tag);
};
}
#endif

@ -38,6 +38,11 @@ namespace
}
CSVRender::ObjectTag::ObjectTag (Object* object)
: TagBase (Element_Reference), mObject (object)
{}
void CSVRender::Object::clear()
{
}
@ -124,7 +129,7 @@ CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode,
mOutline = new osgFX::Scribe;
mOutline->addChild(mBaseNode);
mBaseNode->setUserData(new ObjectHolder(this));
mBaseNode->setUserData(new ObjectTag(this));
parentNode->addChild(mBaseNode);

@ -8,8 +8,9 @@
#include <osg/ref_ptr>
#include <osg/Referenced>
class QModelIndex;
#include "tagbase.hpp"
class QModelIndex;
namespace osg
{
@ -35,21 +36,19 @@ namespace CSMWorld
namespace CSVRender
{
class Object;
// An object to attach as user data to the osg::Node, allows us to get an Object back from a Node when we are doing a ray query
class ObjectHolder : public osg::Referenced
class ObjectTag : public TagBase
{
public:
ObjectHolder(Object* obj)
: mObject(obj)
{
}
public:
ObjectTag (Object* object);
Object* mObject;
Object* mObject;
};
class Object
{
const CSMWorld::Data& mData;

@ -314,6 +314,15 @@ unsigned int CSVRender::PagedWorldspaceWidget::getVisibilityMask() const
return WorldspaceWidget::getVisibilityMask() | mControlElements->getSelection();
}
void CSVRender::PagedWorldspaceWidget::clearSelection (int elementMask)
{
for (std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter = mCells.begin();
iter!=mCells.end(); ++iter)
iter->second->setSelection (elementMask, Cell::Selection_Clear);
flagAsModified();
}
CSVWidget::SceneToolToggle *CSVRender::PagedWorldspaceWidget::makeControlVisibilitySelector (
CSVWidget::SceneToolbar *parent)
{

@ -79,6 +79,9 @@ namespace CSVRender
virtual unsigned int getVisibilityMask() const;
/// \param elementMask Elements to be affected by the clear operation
virtual void clearSelection (int elementMask);
protected:
virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool);

@ -110,6 +110,8 @@ bool RenderWidget::eventFilter(QObject* obj, QEvent* event)
keyPressEvent(static_cast<QKeyEvent*>(event));
if (event->type() == QEvent::KeyRelease)
keyReleaseEvent(static_cast<QKeyEvent*>(event));
if (event->type() == QEvent::Wheel)
wheelEvent(static_cast<QWheelEvent *>(event));
// Always pass the event on to GLWidget, i.e. to OSG event queue
return QObject::eventFilter(obj, event);

@ -0,0 +1,9 @@
#include "tagbase.hpp"
CSVRender::TagBase::TagBase (Elements element) : mElement (element) {}
CSVRender::Elements CSVRender::TagBase::getElement() const
{
return mElement;
}

@ -0,0 +1,22 @@
#ifndef OPENCS_VIEW_TAGBASE_H
#define OPENCS_VIEW_TAGBASE_H
#include <osg/Referenced>
#include "elements.hpp"
namespace CSVRender
{
class TagBase : public osg::Referenced
{
Elements mElement;
public:
TagBase (Elements element);
Elements getElement() const;
};
}
#endif

@ -102,6 +102,12 @@ bool CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vector<CSMWorld:
return true;
}
void CSVRender::UnpagedWorldspaceWidget::clearSelection (int elementMask)
{
mCell->setSelection (elementMask, Cell::Selection_Clear);
flagAsModified();
}
void CSVRender::UnpagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft,
const QModelIndex& bottomRight)
{

@ -43,6 +43,9 @@ namespace CSVRender
virtual bool handleDrop (const std::vector<CSMWorld::UniversalId>& data,
DropType type);
/// \param elementMask Elements to be affected by the clear operation
virtual void clearSelection (int elementMask);
private:
virtual void referenceableDataChanged (const QModelIndex& topLeft,

@ -9,6 +9,7 @@
#include <QDropEvent>
#include <QMouseEvent>
#include <QKeyEvent>
#include <QApplication>
#include <osgGA/TrackballManipulator>
#include <osgGA/FirstPersonManipulator>
@ -18,6 +19,8 @@
#include "../../model/world/universalid.hpp"
#include "../../model/world/idtable.hpp"
#include "../../model/settings/usersettings.hpp"
#include "../widget/scenetoolmode.hpp"
#include "../widget/scenetooltoggle2.hpp"
#include "../widget/scenetoolrun.hpp"
@ -25,10 +28,22 @@
#include "object.hpp"
#include "elements.hpp"
#include "editmode.hpp"
#include "instancemode.hpp"
namespace
{
static const char * const sMappingSettings[] =
{
"p-navi", "s-navi",
"p-edit", "s-edit",
"select",
0
};
}
CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent)
: SceneWidget (document.getData().getResourceSystem(), parent), mSceneElements(0), mRun(0), mDocument(document),
mInteractionMask (0)
mInteractionMask (0), mEditMode (0), mLocked (false), mDragging (false)
{
setAcceptDrops(true);
@ -59,6 +74,17 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg
this, SLOT (debugProfileDataChanged (const QModelIndex&, const QModelIndex&)));
connect (debugProfiles, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
this, SLOT (debugProfileAboutToBeRemoved (const QModelIndex&, int, int)));
for (int i=0; sMappingSettings[i]; ++i)
{
QString key ("scene-input/");
key += sMappingSettings[i];
storeMappingSetting (key, CSMSettings::UserSettings::instance().settingValue (key));
}
mDragFactor = CSMSettings::UserSettings::instance().settingValue ("scene-input/drag-factor").toDouble();
mDragWheelFactor = CSMSettings::UserSettings::instance().settingValue ("scene-input/drag-wheel-factor").toDouble();
mDragShiftFactor = CSMSettings::UserSettings::instance().settingValue ("scene-input/drag-shift-factor").toDouble();
}
CSVRender::WorldspaceWidget::~WorldspaceWidget ()
@ -178,11 +204,14 @@ CSVWidget::SceneToolRun *CSVRender::WorldspaceWidget::makeRunTool (
CSVWidget::SceneToolMode *CSVRender::WorldspaceWidget::makeEditModeSelector (
CSVWidget::SceneToolbar *parent)
{
CSVWidget::SceneToolMode *tool = new CSVWidget::SceneToolMode (parent, "Edit Mode");
mEditMode = new CSVWidget::SceneToolMode (parent, "Edit Mode");
addEditModeSelectorButtons (tool);
addEditModeSelectorButtons (mEditMode);
return tool;
connect (mEditMode, SIGNAL (modeChanged (const std::string&)),
this, SLOT (editModeChanged (const std::string&)));
return mEditMode;
}
CSVRender::WorldspaceWidget::DropType CSVRender::WorldspaceWidget::getDropType (
@ -254,6 +283,26 @@ unsigned int CSVRender::WorldspaceWidget::getInteractionMask() const
return mInteractionMask & getVisibilityMask();
}
void CSVRender::WorldspaceWidget::updateUserSetting (const QString& name, const QStringList& value)
{
if (!value.isEmpty() && storeMappingSetting (name, value.first()))
return;
if (name=="scene-input/drag-factor")
mDragFactor = value.at (0).toDouble();
else if (name=="scene-input/drag-wheel-factor")
mDragWheelFactor = value.at (0).toDouble();
else if (name=="scene-input/drag-shift-factor")
mDragShiftFactor = value.at (0).toDouble();
else
dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent()).updateUserSetting (name, value);
}
void CSVRender::WorldspaceWidget::setEditLock (bool locked)
{
dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent()).setEditLock (locked);
}
void CSVRender::WorldspaceWidget::addVisibilitySelectorButtons (
CSVWidget::SceneToolToggle2 *tool)
{
@ -265,9 +314,7 @@ void CSVRender::WorldspaceWidget::addVisibilitySelectorButtons (
void CSVRender::WorldspaceWidget::addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool)
{
/// \todo replace EditMode with suitable subclasses
tool->addButton (
new EditMode (this, QIcon (":placeholder"), Element_Reference, "Instance editing"),
"object");
tool->addButton (new InstanceMode (this, tool), "object");
tool->addButton (
new EditMode (this, QIcon (":placeholder"), Element_Pathgrid, "Pathgrid editing"),
"pathgrid");
@ -288,6 +335,95 @@ void CSVRender::WorldspaceWidget::dragMoveEvent(QDragMoveEvent *event)
event->accept();
}
bool CSVRender::WorldspaceWidget::storeMappingSetting (const QString& key, const QString& value)
{
const QString prefix = "scene-input/";
if (key.startsWith (prefix))
{
QString key2 (key.mid (prefix.length()));
for (int i=0; sMappingSettings[i]; ++i)
if (key2==sMappingSettings[i])
{
Qt::MouseButton button = Qt::NoButton;
if (value.endsWith ("Left Mouse-Button"))
button = Qt::LeftButton;
else if (value.endsWith ("Right Mouse-Button"))
button = Qt::RightButton;
else if (value.endsWith ("Middle Mouse-Button"))
button = Qt::MiddleButton;
else
return false;
bool ctrl = value.startsWith ("Ctrl-");
mButtonMapping[std::make_pair (button, ctrl)] = sMappingSettings[i];
return true;
}
}
return false;
}
osg::ref_ptr<CSVRender::TagBase> CSVRender::WorldspaceWidget::mousePick (QMouseEvent *event)
{
// (0,0) is considered the lower left corner of an OpenGL window
int x = event->x();
int y = height() - event->y();
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector (new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, x, y));
intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT);
osgUtil::IntersectionVisitor visitor(intersector);
visitor.setTraversalMask(getInteractionMask() << 1);
mView->getCamera()->accept(visitor);
for (osgUtil::LineSegmentIntersector::Intersections::iterator it = intersector->getIntersections().begin();
it != intersector->getIntersections().end(); ++it)
{
osgUtil::LineSegmentIntersector::Intersection intersection = *it;
// reject back-facing polygons
osg::Vec3f normal = intersection.getWorldIntersectNormal();
normal = osg::Matrix::transform3x3(normal, mView->getCamera()->getViewMatrix());
if (normal.z() < 0)
continue;
for (std::vector<osg::Node*>::iterator it = intersection.nodePath.begin(); it != intersection.nodePath.end(); ++it)
{
osg::Node* node = *it;
if (osg::ref_ptr<CSVRender::TagBase> tag = dynamic_cast<CSVRender::TagBase *>(node->getUserData()))
return tag;
}
// ignoring terrain for now
// must be terrain, report coordinates
// std::cout << "Terrain hit at " << intersection.getWorldIntersectPoint().x() << " " << intersection.getWorldIntersectPoint().y() << std::endl;
// return;
}
return osg::ref_ptr<CSVRender::TagBase>();
}
std::string CSVRender::WorldspaceWidget::mapButton (QMouseEvent *event)
{
std::pair<Qt::MouseButton, bool> phyiscal (
event->button(), QApplication::keyboardModifiers() & Qt::ControlModifier);
std::map<std::pair<Qt::MouseButton, bool>, std::string>::const_iterator iter =
mButtonMapping.find (phyiscal);
if (iter!=mButtonMapping.end())
return iter->second;
return "";
}
void CSVRender::WorldspaceWidget::dropEvent (QDropEvent* event)
{
const CSMWorld::TableMimeData* mime = dynamic_cast<const CSMWorld::TableMimeData*> (event->mimeData());
@ -352,6 +488,12 @@ void CSVRender::WorldspaceWidget::debugProfileAboutToBeRemoved (const QModelInde
}
}
void CSVRender::WorldspaceWidget::editModeChanged (const std::string& id)
{
dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent()).setEditLock (mLocked);
mDragging = false;
}
void CSVRender::WorldspaceWidget::elementSelectionChanged()
{
setVisibilityMask (getVisibilityMask());
@ -365,73 +507,100 @@ void CSVRender::WorldspaceWidget::updateOverlay()
void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event)
{
if(event->buttons() & Qt::RightButton)
if (!mDragging)
{
//mMouse->mouseMoveEvent(event);
if (mDragMode=="p-navi" || mDragMode=="s-navi")
{
}
else if (mDragMode=="p-edit" || mDragMode=="s-edit" || mDragMode=="select")
{
osg::ref_ptr<TagBase> tag = mousePick (event);
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
if (mDragMode=="p-edit")
mDragging = editMode.primaryEditStartDrag (tag);
else if (mDragMode=="s-edit")
mDragging = editMode.secondaryEditStartDrag (tag);
else if (mDragMode=="select")
mDragging = editMode.selectStartDrag (tag);
if (mDragging)
{
mDragX = event->posF().x();
mDragY = height() - event->posF().y();
}
}
}
RenderWidget::mouseMoveEvent(event);
}
else
{
int diffX = event->x() - mDragX;
int diffY = (height() - event->y()) - mDragY;
void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event)
{
if (event->button() != Qt::RightButton)
return;
mDragX = event->x();
mDragY = height() - event->y();
// (0,0) is considered the lower left corner of an OpenGL window
int x = event->x();
int y = height() - event->y();
double factor = mDragFactor;
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector (new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, x, y));
if (QApplication::keyboardModifiers() & Qt::ShiftModifier)
factor *= mDragShiftFactor;
intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT);
osgUtil::IntersectionVisitor visitor(intersector);
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
visitor.setTraversalMask(getInteractionMask() << 1);
editMode.drag (diffX, diffY, factor);
}
mView->getCamera()->accept(visitor);
RenderWidget::mouseMoveEvent(event);
}
for (osgUtil::LineSegmentIntersector::Intersections::iterator it = intersector->getIntersections().begin();
it != intersector->getIntersections().end(); ++it)
void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event)
{
std::string button = mapButton (event);
if (!mDragging)
mDragMode = button;
if (button=="p-navi" || button=="s-navi")
{
osgUtil::LineSegmentIntersector::Intersection intersection = *it;
// reject back-facing polygons
osg::Vec3f normal = intersection.getWorldIntersectNormal();
normal = osg::Matrix::transform3x3(normal, mView->getCamera()->getViewMatrix());
if (normal.z() < 0)
continue;
}
else if (button=="p-edit" || button=="s-edit" || button=="select")
{
osg::ref_ptr<TagBase> tag = mousePick (event);
for (std::vector<osg::Node*>::iterator it = intersection.nodePath.begin(); it != intersection.nodePath.end(); ++it)
{
osg::Node* node = *it;
if (CSVRender::ObjectHolder* holder = dynamic_cast<CSVRender::ObjectHolder*>(node->getUserData()))
{
// hit an Object, toggle its selection state
CSVRender::Object* obj = holder->mObject;
obj->setSelected(!obj->getSelected());
return;
}
}
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
// must be terrain, report coordinates
std::cout << "Terrain hit at " << intersection.getWorldIntersectPoint().x() << " " << intersection.getWorldIntersectPoint().y() << std::endl;
return;
if (button=="p-edit")
editMode.primaryEditPressed (tag);
else if (button=="s-edit")
editMode.secondaryEditPressed (tag);
else if (button=="select")
editMode.selectPressed (tag);
}
}
void CSVRender::WorldspaceWidget::mouseReleaseEvent (QMouseEvent *event)
{
if(event->button() == Qt::RightButton)
if (mDragging)
{
/*
if(!getViewport())
std::string button = mapButton (event);
if (mDragMode=="p-navi" || mDragMode=="s-navi")
{
SceneWidget::mouseReleaseEvent(event);
return;
}
else if (mDragMode=="p-edit" || mDragMode=="s-edit" || mDragMode=="select")
{
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
editMode.dragCompleted();
mDragging = false;
}
*/
//mMouse->mouseReleaseEvent(event);
}
mDragMode.clear();
RenderWidget::mouseReleaseEvent(event);
}
@ -446,15 +615,32 @@ void CSVRender::WorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event)
void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event)
{
//if(!mMouse->wheelEvent(event))
RenderWidget::wheelEvent(event);
if (mDragging)
{
double factor = mDragWheelFactor;
if (QApplication::keyboardModifiers() & Qt::ShiftModifier)
factor *= mDragShiftFactor;
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
editMode.dragWheel (event->delta(), factor);
}
RenderWidget::wheelEvent(event);
}
void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event)
{
if(event->key() == Qt::Key_Escape)
{
//mMouse->cancelDrag();
if (mDragging)
{
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
editMode.dragAborted();
mDragging = false;
}
}
else
RenderWidget::keyPressEvent(event);

@ -1,12 +1,15 @@
#ifndef OPENCS_VIEW_WORLDSPACEWIDGET_H
#define OPENCS_VIEW_WORLDSPACEWIDGET_H
#include <map>
#include <boost/shared_ptr.hpp>
#include "scenewidget.hpp"
#include "../../model/doc/document.hpp"
#include "../../model/world/tablemimedata.hpp"
#include <apps/opencs/model/doc/document.hpp>
#include <apps/opencs/model/world/tablemimedata.hpp>
#include "scenewidget.hpp"
#include "elements.hpp"
namespace CSMWorld
{
@ -23,6 +26,8 @@ namespace CSVWidget
namespace CSVRender
{
class TagBase;
class WorldspaceWidget : public SceneWidget
{
Q_OBJECT
@ -31,6 +36,16 @@ namespace CSVRender
CSVWidget::SceneToolRun *mRun;
CSMDoc::Document& mDocument;
unsigned int mInteractionMask;
std::map<std::pair<Qt::MouseButton, bool>, std::string> mButtonMapping;
CSVWidget::SceneToolMode *mEditMode;
bool mLocked;
std::string mDragMode;
bool mDragging;
int mDragX;
int mDragY;
double mDragFactor;
double mDragWheelFactor;
double mDragShiftFactor;
public:
@ -93,14 +108,21 @@ namespace CSVRender
/// marked for interaction.
unsigned int getInteractionMask() const;
virtual void updateUserSetting (const QString& name, const QStringList& value);
virtual void setEditLock (bool locked);
CSMDoc::Document& getDocument();
/// \param elementMask Elements to be affected by the clear operation
virtual void clearSelection (int elementMask) = 0;
protected:
virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool);
virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool);
CSMDoc::Document& getDocument();
virtual void updateOverlay();
virtual void mouseMoveEvent (QMouseEvent *event);
@ -118,6 +140,13 @@ namespace CSVRender
void dragMoveEvent(QDragMoveEvent *event);
/// \return Is \a key a button mapping setting? (ignored otherwise)
bool storeMappingSetting (const QString& key, const QString& value);
osg::ref_ptr<TagBase> mousePick (QMouseEvent *event);
std::string mapButton (QMouseEvent *event);
virtual std::string getStartupInstruction() = 0;
private slots:
@ -144,6 +173,7 @@ namespace CSVRender
void debugProfileAboutToBeRemoved (const QModelIndex& parent, int start, int end);
void editModeChanged (const std::string& id);
protected slots:

@ -71,6 +71,11 @@ void CSVWidget::SceneToolMode::addButton (ModeButton *button, const std::string&
}
}
CSVWidget::ModeButton *CSVWidget::SceneToolMode::getCurrent()
{
return mCurrent;
}
void CSVWidget::SceneToolMode::selected()
{
std::map<ModeButton *, std::string>::const_iterator iter =

@ -41,6 +41,9 @@ namespace CSVWidget
/// The ownership of \a button is transferred to *this.
void addButton (ModeButton *button, const std::string& id);
/// Will return a 0-pointer only if the mode does not have any buttons yet.
ModeButton *getCurrent();
signals:
void modeChanged (const std::string& id);

@ -15,6 +15,7 @@
#include "../render/pagedworldspacewidget.hpp"
#include "../render/unpagedworldspacewidget.hpp"
#include "../render/editmode.hpp"
#include "../widget/scenetoolbar.hpp"
#include "../widget/scenetoolmode.hpp"
@ -121,15 +122,14 @@ CSVWidget::SceneToolbar* CSVWorld::SceneSubView::makeToolbar (CSVRender::Worldsp
CSVWidget::SceneToolRun *runTool = widget->makeRunTool (toolbar);
toolbar->addTool (runTool);
CSVWidget::SceneToolMode *editModeTool = widget->makeEditModeSelector (toolbar);
toolbar->addTool (editModeTool);
toolbar->addTool (widget->makeEditModeSelector (toolbar));
return toolbar;
}
void CSVWorld::SceneSubView::setEditLock (bool locked)
{
mScene->setEditLock (locked);
}
void CSVWorld::SceneSubView::setStatusBar (bool show)
@ -147,6 +147,12 @@ std::string CSVWorld::SceneSubView::getTitle() const
return mTitle;
}
void CSVWorld::SceneSubView::updateUserSetting (const QString& name, const QStringList& value)
{
mScene->updateUserSetting (name, value);
CSVDoc::SubView::updateUserSetting (name, value);
}
void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::UniversalId& id)
{
setUniversalId(id);

@ -27,6 +27,7 @@ namespace CSVRender
namespace CSVWidget
{
class SceneToolbar;
class SceneToolMode;
}
namespace CSVWorld
@ -58,6 +59,8 @@ namespace CSVWorld
virtual std::string getTitle() const;
virtual void updateUserSetting (const QString& name, const QStringList& value);
private:
void makeConnections(CSVRender::PagedWorldspaceWidget* widget);

Loading…
Cancel
Save