forked from mirror/openmw-tes3mp
Merge branch 'sceneinput'
This commit is contained in:
commit
6ef2319eb8
23 changed files with 632 additions and 75 deletions
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
56
apps/opencs/view/render/instancemode.cpp
Normal file
56
apps/opencs/view/render/instancemode.cpp
Normal file
|
@ -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);
|
||||
}
|
30
apps/opencs/view/render/instancemode.hpp
Normal file
30
apps/opencs/view/render/instancemode.hpp
Normal file
|
@ -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:
|
||||
|
||||
Object* mObject;
|
||||
ObjectTag (Object* object);
|
||||
|
||||
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);
|
||||
|
|
9
apps/opencs/view/render/tagbase.cpp
Normal file
9
apps/opencs/view/render/tagbase.cpp
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
#include "tagbase.hpp"
|
||||
|
||||
CSVRender::TagBase::TagBase (Elements element) : mElement (element) {}
|
||||
|
||||
CSVRender::Elements CSVRender::TagBase::getElement() const
|
||||
{
|
||||
return mElement;
|
||||
}
|
22
apps/opencs/view/render/tagbase.hpp
Normal file
22
apps/opencs/view/render/tagbase.hpp
Normal file
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int diffX = event->x() - mDragX;
|
||||
int diffY = (height() - event->y()) - mDragY;
|
||||
|
||||
mDragX = event->x();
|
||||
mDragY = height() - event->y();
|
||||
|
||||
double factor = mDragFactor;
|
||||
|
||||
if (QApplication::keyboardModifiers() & Qt::ShiftModifier)
|
||||
factor *= mDragShiftFactor;
|
||||
|
||||
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
|
||||
|
||||
editMode.drag (diffX, diffY, factor);
|
||||
}
|
||||
|
||||
RenderWidget::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event)
|
||||
{
|
||||
if (event->button() != Qt::RightButton)
|
||||
return;
|
||||
std::string button = mapButton (event);
|
||||
|
||||
// (0,0) is considered the lower left corner of an OpenGL window
|
||||
int x = event->x();
|
||||
int y = height() - event->y();
|
||||
if (!mDragging)
|
||||
mDragMode = button;
|
||||
|
||||
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)
|
||||
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…
Reference in a new issue