Pass more mouse pick information in scene view editor.

This commit is contained in:
Aesylwinn 2016-05-12 18:21:43 -04:00
parent fcbcc004a3
commit 9645d0cc8a
8 changed files with 92 additions and 65 deletions

View file

@ -29,30 +29,30 @@ void CSVRender::EditMode::setEditLock (bool locked)
} }
void CSVRender::EditMode::primaryEditPressed (osg::ref_ptr<TagBase> tag) {} void CSVRender::EditMode::primaryEditPressed (const WorldspaceHitResult& hit) {}
void CSVRender::EditMode::secondaryEditPressed (osg::ref_ptr<TagBase> tag) {} void CSVRender::EditMode::secondaryEditPressed (const WorldspaceHitResult& hit) {}
void CSVRender::EditMode::primarySelectPressed (osg::ref_ptr<TagBase> tag) {} void CSVRender::EditMode::primarySelectPressed (const WorldspaceHitResult& hit) {}
void CSVRender::EditMode::secondarySelectPressed (osg::ref_ptr<TagBase> tag) {} void CSVRender::EditMode::secondarySelectPressed (const WorldspaceHitResult& hit) {}
bool CSVRender::EditMode::primaryEditStartDrag (osg::ref_ptr<TagBase> tag) bool CSVRender::EditMode::primaryEditStartDrag (const WorldspaceHitResult& hit)
{ {
return false; return false;
} }
bool CSVRender::EditMode::secondaryEditStartDrag (osg::ref_ptr<TagBase> tag) bool CSVRender::EditMode::secondaryEditStartDrag (const WorldspaceHitResult& hit)
{ {
return false; return false;
} }
bool CSVRender::EditMode::primarySelectStartDrag (osg::ref_ptr<TagBase> tag) bool CSVRender::EditMode::primarySelectStartDrag (const WorldspaceHitResult& hit)
{ {
return false; return false;
} }
bool CSVRender::EditMode::secondarySelectStartDrag (osg::ref_ptr<TagBase> tag) bool CSVRender::EditMode::secondarySelectStartDrag (const WorldspaceHitResult& hit)
{ {
return false; return false;
} }

View file

@ -12,6 +12,7 @@ class QDragMoveEvent;
namespace CSVRender namespace CSVRender
{ {
class WorldspaceWidget; class WorldspaceWidget;
struct WorldspaceHitResult;
class TagBase; class TagBase;
class EditMode : public CSVWidget::ModeButton class EditMode : public CSVWidget::ModeButton
@ -38,36 +39,36 @@ namespace CSVRender
virtual void setEditLock (bool locked); virtual void setEditLock (bool locked);
/// Default-implementation: Ignored. /// Default-implementation: Ignored.
virtual void primaryEditPressed (osg::ref_ptr<TagBase> tag); virtual void primaryEditPressed (const WorldspaceHitResult& hit);
/// Default-implementation: Ignored. /// Default-implementation: Ignored.
virtual void secondaryEditPressed (osg::ref_ptr<TagBase> tag); virtual void secondaryEditPressed (const WorldspaceHitResult& hit);
/// Default-implementation: Ignored. /// Default-implementation: Ignored.
virtual void primarySelectPressed (osg::ref_ptr<TagBase> tag); virtual void primarySelectPressed (const WorldspaceHitResult& hit);
/// Default-implementation: Ignored. /// Default-implementation: Ignored.
virtual void secondarySelectPressed (osg::ref_ptr<TagBase> tag); virtual void secondarySelectPressed (const WorldspaceHitResult& hit);
/// Default-implementation: ignore and return false /// Default-implementation: ignore and return false
/// ///
/// \return Drag accepted? /// \return Drag accepted?
virtual bool primaryEditStartDrag (osg::ref_ptr<TagBase> tag); virtual bool primaryEditStartDrag (const WorldspaceHitResult& hit);
/// Default-implementation: ignore and return false /// Default-implementation: ignore and return false
/// ///
/// \return Drag accepted? /// \return Drag accepted?
virtual bool secondaryEditStartDrag (osg::ref_ptr<TagBase> tag); virtual bool secondaryEditStartDrag (const WorldspaceHitResult& hit);
/// Default-implementation: ignore and return false /// Default-implementation: ignore and return false
/// ///
/// \return Drag accepted? /// \return Drag accepted?
virtual bool primarySelectStartDrag (osg::ref_ptr<TagBase> tag); virtual bool primarySelectStartDrag (const WorldspaceHitResult& hit);
/// Default-implementation: ignore and return false /// Default-implementation: ignore and return false
/// ///
/// \return Drag accepted? /// \return Drag accepted?
virtual bool secondarySelectStartDrag (osg::ref_ptr<TagBase> tag); virtual bool secondarySelectStartDrag (const WorldspaceHitResult& hit);
/// Default-implementation: ignored /// Default-implementation: ignored
virtual void drag (int diffX, int diffY, double speedFactor); virtual void drag (int diffX, int diffY, double speedFactor);

View file

@ -103,25 +103,25 @@ void CSVRender::InstanceMode::setEditLock (bool locked)
getWorldspaceWidget().abortDrag(); getWorldspaceWidget().abortDrag();
} }
void CSVRender::InstanceMode::primaryEditPressed (osg::ref_ptr<TagBase> tag) void CSVRender::InstanceMode::primaryEditPressed (const WorldspaceHitResult& hit)
{ {
if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue()) if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue())
primarySelectPressed (tag); primarySelectPressed (hit);
} }
void CSVRender::InstanceMode::secondaryEditPressed (osg::ref_ptr<TagBase> tag) void CSVRender::InstanceMode::secondaryEditPressed (const WorldspaceHitResult& hit)
{ {
if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue()) if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue())
secondarySelectPressed (tag); secondarySelectPressed (hit);
} }
void CSVRender::InstanceMode::primarySelectPressed (osg::ref_ptr<TagBase> tag) void CSVRender::InstanceMode::primarySelectPressed (const WorldspaceHitResult& hit)
{ {
getWorldspaceWidget().clearSelection (Mask_Reference); getWorldspaceWidget().clearSelection (Mask_Reference);
if (tag) if (hit.tag)
{ {
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (tag.get())) if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (hit.tag.get()))
{ {
// hit an Object, select it // hit an Object, select it
CSVRender::Object* object = objectTag->mObject; CSVRender::Object* object = objectTag->mObject;
@ -131,11 +131,11 @@ void CSVRender::InstanceMode::primarySelectPressed (osg::ref_ptr<TagBase> tag)
} }
} }
void CSVRender::InstanceMode::secondarySelectPressed (osg::ref_ptr<TagBase> tag) void CSVRender::InstanceMode::secondarySelectPressed (const WorldspaceHitResult& hit)
{ {
if (tag) if (hit.tag)
{ {
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (tag.get())) if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (hit.tag.get()))
{ {
// hit an Object, toggle its selection state // hit an Object, toggle its selection state
CSVRender::Object* object = objectTag->mObject; CSVRender::Object* object = objectTag->mObject;
@ -145,15 +145,15 @@ void CSVRender::InstanceMode::secondarySelectPressed (osg::ref_ptr<TagBase> tag)
} }
} }
bool CSVRender::InstanceMode::primaryEditStartDrag (osg::ref_ptr<TagBase> tag) bool CSVRender::InstanceMode::primaryEditStartDrag (const WorldspaceHitResult& hit)
{ {
if (mDragMode!=DragMode_None || mLocked) if (mDragMode!=DragMode_None || mLocked)
return false; return false;
if (tag && CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue()) if (hit.tag && CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue())
{ {
getWorldspaceWidget().clearSelection (Mask_Reference); getWorldspaceWidget().clearSelection (Mask_Reference);
if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (tag.get())) if (CSVRender::ObjectTag *objectTag = dynamic_cast<CSVRender::ObjectTag *> (hit.tag.get()))
{ {
CSVRender::Object* object = objectTag->mObject; CSVRender::Object* object = objectTag->mObject;
object->setSelected (true); object->setSelected (true);
@ -177,7 +177,7 @@ bool CSVRender::InstanceMode::primaryEditStartDrag (osg::ref_ptr<TagBase> tag)
// \todo check for sub-mode // \todo check for sub-mode
if (CSVRender::ObjectMarkerTag *objectTag = dynamic_cast<CSVRender::ObjectMarkerTag *> (tag.get())) if (CSVRender::ObjectMarkerTag *objectTag = dynamic_cast<CSVRender::ObjectMarkerTag *> (hit.tag.get()))
{ {
mDragAxis = objectTag->mAxis; mDragAxis = objectTag->mAxis;
} }
@ -189,7 +189,7 @@ bool CSVRender::InstanceMode::primaryEditStartDrag (osg::ref_ptr<TagBase> tag)
return true; return true;
} }
bool CSVRender::InstanceMode::secondaryEditStartDrag (osg::ref_ptr<TagBase> tag) bool CSVRender::InstanceMode::secondaryEditStartDrag (const WorldspaceHitResult& hit)
{ {
if (mLocked) if (mLocked)
return false; return false;

View file

@ -41,17 +41,17 @@ namespace CSVRender
virtual void setEditLock (bool locked); virtual void setEditLock (bool locked);
virtual void primaryEditPressed (osg::ref_ptr<TagBase> tag); virtual void primaryEditPressed (const WorldspaceHitResult& hit);
virtual void secondaryEditPressed (osg::ref_ptr<TagBase> tag); virtual void secondaryEditPressed (const WorldspaceHitResult& hit);
virtual void primarySelectPressed (osg::ref_ptr<TagBase> tag); virtual void primarySelectPressed (const WorldspaceHitResult& hit);
virtual void secondarySelectPressed (osg::ref_ptr<TagBase> tag); virtual void secondarySelectPressed (const WorldspaceHitResult& hit);
virtual bool primaryEditStartDrag (osg::ref_ptr<TagBase> tag); virtual bool primaryEditStartDrag (const WorldspaceHitResult& hit);
virtual bool secondaryEditStartDrag (osg::ref_ptr<TagBase> tag); virtual bool secondaryEditStartDrag (const WorldspaceHitResult& hit);
virtual void drag (int diffX, int diffY, double speedFactor); virtual void drag (int diffX, int diffY, double speedFactor);

View file

@ -142,14 +142,15 @@ void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons (
"terrain-move"); "terrain-move");
} }
void CSVRender::PagedWorldspaceWidget::handleMouseClick (osg::ref_ptr<TagBase> tag, const std::string& button, bool shift) void CSVRender::PagedWorldspaceWidget::handleMouseClick (const WorldspaceHitResult& hit, const std::string& button,
bool shift)
{ {
if (tag && tag->getMask()==Mask_CellArrow) if (hit.tag && hit.tag->getMask()==Mask_CellArrow)
{ {
if (button=="p-edit" || button=="s-edit") if (button=="p-edit" || button=="s-edit")
{ {
if (CellArrowTag *cellArrowTag = if (CellArrowTag *cellArrowTag =
dynamic_cast<CSVRender::CellArrowTag *> (tag.get())) dynamic_cast<CSVRender::CellArrowTag *> (hit.tag.get()))
{ {
CellArrow *arrow = cellArrowTag->getCellArrow(); CellArrow *arrow = cellArrowTag->getCellArrow();
@ -209,7 +210,7 @@ void CSVRender::PagedWorldspaceWidget::handleMouseClick (osg::ref_ptr<TagBase> t
} }
} }
WorldspaceWidget::handleMouseClick (tag, button, shift); WorldspaceWidget::handleMouseClick (hit, button, shift);
} }
void CSVRender::PagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft, void CSVRender::PagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft,

View file

@ -135,7 +135,7 @@ namespace CSVRender
virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool); virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool);
virtual void handleMouseClick (osg::ref_ptr<TagBase> tag, const std::string& button, bool shift); virtual void handleMouseClick (const WorldspaceHitResult& hit, const std::string& button, bool shift);
signals: signals:

View file

@ -469,7 +469,7 @@ bool CSVRender::WorldspaceWidget::storeMappingSetting (const CSMPrefs::Setting *
return SceneWidget::storeMappingSetting(setting); return SceneWidget::storeMappingSetting(setting);
} }
osg::ref_ptr<CSVRender::TagBase> CSVRender::WorldspaceWidget::mousePick (const QPoint& localPos) CSVRender::WorldspaceHitResult CSVRender::WorldspaceWidget::mousePick (const QPoint& localPos)
{ {
// (0,0) is considered the lower left corner of an OpenGL window // (0,0) is considered the lower left corner of an OpenGL window
int x = localPos.x(); int x = localPos.x();
@ -499,16 +499,31 @@ osg::ref_ptr<CSVRender::TagBase> CSVRender::WorldspaceWidget::mousePick (const Q
{ {
osg::Node* node = *it; osg::Node* node = *it;
if (osg::ref_ptr<CSVRender::TagBase> tag = dynamic_cast<CSVRender::TagBase *>(node->getUserData())) if (osg::ref_ptr<CSVRender::TagBase> tag = dynamic_cast<CSVRender::TagBase *>(node->getUserData()))
return tag; {
WorldspaceHitResult hit = { true, tag, 0, 0, 0, intersection.getWorldIntersectPoint() };
if (intersection.indexList.size() >= 3)
{
hit.i0 = intersection.indexList[0];
hit.i1 = intersection.indexList[1];
hit.i2 = intersection.indexList[2];
}
return hit;
}
} }
// ignoring terrain for now // Something untagged, probably terrain
// must be terrain, report coordinates WorldspaceHitResult hit = { true, 0, 0, 0, 0, intersection.getWorldIntersectPoint() };
// std::cout << "Terrain hit at " << intersection.getWorldIntersectPoint().x() << " " << intersection.getWorldIntersectPoint().y() << std::endl; if (intersection.indexList.size() >= 3)
// return; {
hit.i0 = intersection.indexList[0];
hit.i1 = intersection.indexList[1];
hit.i2 = intersection.indexList[2];
}
return hit;
} }
return osg::ref_ptr<CSVRender::TagBase>(); WorldspaceHitResult hit = { false, 0, 0, 0, 0, osg::Vec3d() };
return hit;
} }
void CSVRender::WorldspaceWidget::dropEvent (QDropEvent* event) void CSVRender::WorldspaceWidget::dropEvent (QDropEvent* event)
@ -595,10 +610,11 @@ void CSVRender::WorldspaceWidget::showToolTip()
{ {
QPoint pos = QCursor::pos(); QPoint pos = QCursor::pos();
if (osg::ref_ptr<TagBase> tag = mousePick (mapFromGlobal (pos))) WorldspaceHitResult hit = mousePick (mapFromGlobal (pos));
if (hit.tag)
{ {
bool hideBasics = CSMPrefs::get()["Tooltips"]["scene-hide-basic"].isTrue(); bool hideBasics = CSMPrefs::get()["Tooltips"]["scene-hide-basic"].isTrue();
QToolTip::showText (pos, tag->getToolTip (hideBasics), this); QToolTip::showText (pos, hit.tag->getToolTip (hideBasics), this);
} }
} }
} }
@ -635,18 +651,18 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event)
} }
else if (mDragMode=="p-edit" || mDragMode=="s-edit" || mDragMode=="p-select" || mDragMode=="s-select") else if (mDragMode=="p-edit" || mDragMode=="s-edit" || mDragMode=="p-select" || mDragMode=="s-select")
{ {
osg::ref_ptr<TagBase> tag = mousePick (event->pos()); WorldspaceHitResult hit = mousePick (event->pos());
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent()); EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
if (mDragMode=="p-edit") if (mDragMode=="p-edit")
mDragging = editMode.primaryEditStartDrag (tag); mDragging = editMode.primaryEditStartDrag (hit);
else if (mDragMode=="s-edit") else if (mDragMode=="s-edit")
mDragging = editMode.secondaryEditStartDrag (tag); mDragging = editMode.secondaryEditStartDrag (hit);
else if (mDragMode=="p-select") else if (mDragMode=="p-select")
mDragging = editMode.primarySelectStartDrag (tag); mDragging = editMode.primarySelectStartDrag (hit);
else if (mDragMode=="s-select") else if (mDragMode=="s-select")
mDragging = editMode.secondarySelectStartDrag (tag); mDragging = editMode.secondarySelectStartDrag (hit);
if (mDragging) if (mDragging)
{ {
@ -704,9 +720,9 @@ void CSVRender::WorldspaceWidget::mouseReleaseEvent (QMouseEvent *event)
} }
else else
{ {
osg::ref_ptr<TagBase> tag = mousePick (event->pos()); WorldspaceHitResult hit = mousePick (event->pos());
handleMouseClick (tag, button, event->modifiers() & Qt::ShiftModifier); handleMouseClick (hit, button, event->modifiers() & Qt::ShiftModifier);
} }
} }
else else
@ -740,18 +756,18 @@ void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event)
SceneWidget::keyPressEvent(event); SceneWidget::keyPressEvent(event);
} }
void CSVRender::WorldspaceWidget::handleMouseClick (osg::ref_ptr<TagBase> tag, const std::string& button, bool shift) void CSVRender::WorldspaceWidget::handleMouseClick (const WorldspaceHitResult& hit, const std::string& button, bool shift)
{ {
EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent()); EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent());
if (button=="p-edit") if (button=="p-edit")
editMode.primaryEditPressed (tag); editMode.primaryEditPressed (hit);
else if (button=="s-edit") else if (button=="s-edit")
editMode.secondaryEditPressed (tag); editMode.secondaryEditPressed (hit);
else if (button=="p-select") else if (button=="p-select")
editMode.primarySelectPressed (tag); editMode.primarySelectPressed (hit);
else if (button=="s-select") else if (button=="s-select")
editMode.secondarySelectPressed (tag); editMode.secondarySelectPressed (hit);
} }
CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode() CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode()

View file

@ -4,6 +4,7 @@
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <QTimer> #include <QTimer>
#include <osg/Vec3>
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#include "../../model/world/tablemimedata.hpp" #include "../../model/world/tablemimedata.hpp"
@ -35,6 +36,14 @@ namespace CSVRender
class CellArrow; class CellArrow;
class EditMode; class EditMode;
struct WorldspaceHitResult
{
bool hit;
osg::ref_ptr<TagBase> tag;
unsigned int i0, i1, i2;
osg::Vec3d worldPos;
};
class WorldspaceWidget : public SceneWidget class WorldspaceWidget : public SceneWidget
{ {
Q_OBJECT Q_OBJECT
@ -191,7 +200,7 @@ namespace CSVRender
virtual void wheelEvent (QWheelEvent *event); virtual void wheelEvent (QWheelEvent *event);
virtual void keyPressEvent (QKeyEvent *event); virtual void keyPressEvent (QKeyEvent *event);
virtual void handleMouseClick (osg::ref_ptr<TagBase> tag, const std::string& button, virtual void handleMouseClick (const WorldspaceHitResult& hit, const std::string& button,
bool shift); bool shift);
/// \return Is \a key a button mapping setting? (ignored otherwise) /// \return Is \a key a button mapping setting? (ignored otherwise)
@ -209,7 +218,7 @@ namespace CSVRender
void dragMoveEvent(QDragMoveEvent *event); void dragMoveEvent(QDragMoveEvent *event);
osg::ref_ptr<TagBase> mousePick (const QPoint& localPos); WorldspaceHitResult mousePick (const QPoint& localPos);
virtual std::string getStartupInstruction() = 0; virtual std::string getStartupInstruction() = 0;