diff --git a/src/Gui/SoFCSelectionAction.cpp b/src/Gui/SoFCSelectionAction.cpp index fad3158e8c..382195f979 100644 --- a/src/Gui/SoFCSelectionAction.cpp +++ b/src/Gui/SoFCSelectionAction.cpp @@ -54,6 +54,7 @@ #include "SoFCSelectionAction.h" #include "SoFCSelection.h" +#include "SoFCUnifiedSelection.h" #include #include #include "Selection.h" @@ -1235,6 +1236,20 @@ SoBoxSelectionRenderAction::apply(SoNode * node) } } PRIVATE(this)->searchaction->reset(); + + // Search for selections of SoFCUnifiedSelection + PRIVATE(this)->searchaction->setType(SoFCUnifiedSelection::getClassTypeId()); + PRIVATE(this)->searchaction->setInterest(SoSearchAction::FIRST); + PRIVATE(this)->searchaction->apply(node); + SoFullPath * path = static_cast(PRIVATE(this)->searchaction->getPath()); + if (path) { + SoFCUnifiedSelection * selection = static_cast(path->getTail()); + if (selection->getNumSelected()) { + PRIVATE(this)->basecolor->rgb.setValue(selection->colorSelection.getValue()); + this->drawBoxes(path, selection->getList()); + } + } + PRIVATE(this)->searchaction->reset(); } } diff --git a/src/Gui/SoFCUnifiedSelection.cpp b/src/Gui/SoFCUnifiedSelection.cpp index d6a18efba1..a3065fc10d 100644 --- a/src/Gui/SoFCUnifiedSelection.cpp +++ b/src/Gui/SoFCUnifiedSelection.cpp @@ -197,6 +197,101 @@ void SoFCUnifiedSelection::write(SoWriteAction * action) } } +int SoFCUnifiedSelection::getNumSelected(void) const +{ + return this->selectionList.getLength(); +} + +const SoPathList* SoFCUnifiedSelection::getList(void) const +{ + return &this->selectionList; +} + +void SoFCUnifiedSelection::addPath(SoPath * path) +{ + this->selectionList.append(path); +} + +void SoFCUnifiedSelection::removePath(const int which) +{ + SoPath * path = this->selectionList[which]; + path->ref(); + this->selectionList.remove(which); + path->unref(); +} + +SoPath * SoFCUnifiedSelection::copyFromThis(const SoPath * path) const +{ + SoPath * newpath = NULL; + path->ref(); + int i = path->findNode(this); + if (i >= 0) { + newpath = path->copy(i); + } + path->unrefNoDelete(); + return newpath; +} + +int SoFCUnifiedSelection::findPath(const SoPath * path) const +{ + int idx = -1; + + // make copy only if necessary + if (path->getHead() != this) { + SoPath * newpath = this->copyFromThis(path); + if (newpath) { + newpath->ref(); + idx = this->selectionList.findPath(*newpath); + newpath->unref(); + } + else { + idx = -1; + } + } + else { + idx = this->selectionList.findPath(*path); + } + return idx; +} + +SoPath * SoFCUnifiedSelection::searchNode(SoNode * node) const +{ + SoSearchAction sa; + sa.setNode(node); + sa.apply(const_cast(this)); + SoPath * path = sa.getPath(); + if (path) + path->ref(); + return path; +} + +void SoFCUnifiedSelection::select(SoNode * node) +{ + SoPath * path = this->searchNode(node); + if (path) { + // don't ref() the path. searchNode() will ref it before returning + if (this->findPath(path) < 0) + this->addPath(path); + path->unref(); + } +} + +void SoFCUnifiedSelection::deselect(const SoPath * path) +{ + int idx = this->findPath(path); + if (idx >= 0) this->removePath(idx); +} + +void SoFCUnifiedSelection::deselect(SoNode * node) +{ + SoPath * path = this->searchNode(node); + if (path) { + // don't ref() the path. searchNode() will ref it before returning + this->deselect(path); + path->unref(); + } +} + int SoFCUnifiedSelection::getPriority(const SoPickedPoint* p) { const SoDetail* detail = p->getDetail(); @@ -306,7 +401,7 @@ void SoFCUnifiedSelection::doAction(SoAction *action) type = SoSelectionElementAction::None; } - if(checkSelectionStyle(type,vp)) { + if (checkSelectionStyle(type,vp)) { SoSelectionElementAction action(type); action.setColor(this->colorSelection.getValue()); action.setElement(detail); @@ -328,7 +423,7 @@ void SoFCUnifiedSelection::doAction(SoAction *action) type = SoSelectionElementAction::All; else type = SoSelectionElementAction::None; - if(checkSelectionStyle(type,vpd)) { + if (checkSelectionStyle(type, vpd)) { SoSelectionElementAction action(type); action.setColor(this->colorSelection.getValue()); action.apply(vpd->getRoot()); @@ -553,7 +648,7 @@ SoFCUnifiedSelection::handleEvent(SoHandleEventAction * action) } action->setHandled(); - if (currenthighlight && checkSelectionStyle(type,vpd)) { + if (currenthighlight && checkSelectionStyle(type, vpd)) { SoSelectionElementAction action(type); action.setColor(this->colorSelection.getValue()); action.setElement(pp ? pp->getDetail() : 0); @@ -576,15 +671,27 @@ SoFCUnifiedSelection::handleEvent(SoHandleEventAction * action) inherited::handleEvent(action); } -bool SoFCUnifiedSelection::checkSelectionStyle(int type, ViewProvider *vp) { - if((type == SoSelectionElementAction::All || - type == SoSelectionElementAction::None) && +bool SoFCUnifiedSelection::checkSelectionStyle(int type, ViewProvider *vp) +{ + if ((type == SoSelectionElementAction::All || type == SoSelectionElementAction::None) && vp->isDerivedFrom(ViewProviderGeometryObject::getClassTypeId()) && - static_cast(vp)->SelectionStyle.getValue()==1) + static_cast(vp)->SelectionStyle.getValue() == 1) { - bool selected = type==SoSelectionElementAction::All; - static_cast(vp)->showBoundingBox(selected); - if(selected) return false; + bool selected = (type == SoSelectionElementAction::All); + int numSelected = getNumSelected(); + if (selected) { + select(vp->getRoot()); + } + else { + deselect(vp->getRoot()); + } + + if (numSelected != getNumSelected()) + this->touch(); + + if (selected) { + return false; + } } return true; } diff --git a/src/Gui/SoFCUnifiedSelection.h b/src/Gui/SoFCUnifiedSelection.h index 438c0f6320..6e564cbdb7 100644 --- a/src/Gui/SoFCUnifiedSelection.h +++ b/src/Gui/SoFCUnifiedSelection.h @@ -30,6 +30,7 @@ #include #include #include +#include #include "View3DInventorViewer.h" #include @@ -66,6 +67,8 @@ public: const char* getFileFormatName(void) const; void write(SoWriteAction * action); + int getNumSelected(void) const; + const SoPathList* getList(void) const; SoSFColor colorHighlight; SoSFColor colorSelection; @@ -84,11 +87,27 @@ public: bool checkSelectionStyle(int type, ViewProvider *vp); friend class View3DInventorViewer; + protected: virtual ~SoFCUnifiedSelection(); //virtual void redrawHighlighted(SoAction * act, SbBool flag); //virtual SbBool readInstance(SoInput * in, unsigned short flags); + /** @name Nodes selection. + * The SoBoxSelectionRenderAction uses these nodes to draw a + * bounding box. + */ + //@{ + void addPath(SoPath * path); + void removePath(const int which); + SoPath * copyFromThis(const SoPath * path) const; + SoPath * searchNode(SoNode * node) const; + int findPath(const SoPath * path) const; + void select(SoNode * node); + void deselect(const SoPath * path); + void deselect(SoNode * node); + //@} + private: //static void turnoffcurrent(SoAction * action); //void setOverride(SoGLRenderAction * action); @@ -99,6 +118,7 @@ private: Gui::Document *pcDocument; static SoFullPath * currenthighlight; + SoPathList selectionList; SbBool highlighted; SbBool setPreSelection; diff --git a/src/Gui/ViewProviderGeometryObject.cpp b/src/Gui/ViewProviderGeometryObject.cpp index 40dfc06831..7f94d408f5 100644 --- a/src/Gui/ViewProviderGeometryObject.cpp +++ b/src/Gui/ViewProviderGeometryObject.cpp @@ -74,13 +74,15 @@ PROPERTY_SOURCE(Gui::ViewProviderGeometryObject, Gui::ViewProviderDragger) const App::PropertyIntegerConstraint::Constraints intPercent = {0,100,1}; -ViewProviderGeometryObject::ViewProviderGeometryObject() : pcBoundSwitch(0),pcBoundColor(0) +ViewProviderGeometryObject::ViewProviderGeometryObject() + : pcBoundSwitch(0) + , pcBoundColor(0) { ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View"); bool randomColor = hGrp->GetBool("RandomColor", false); float r,g,b; - if(randomColor){ + if (randomColor){ float fMax = (float)RAND_MAX; r = (float)rand()/fMax; g = (float)rand()/fMax; @@ -115,6 +117,10 @@ ViewProviderGeometryObject::ViewProviderGeometryObject() : pcBoundSwitch(0),pcBo pcBoundingBox = new Gui::SoFCBoundingBox; pcBoundingBox->ref(); + + pcBoundColor = new SoBaseColor(); + pcBoundColor->ref(); + sPixmap = "Feature"; } @@ -122,6 +128,7 @@ ViewProviderGeometryObject::~ViewProviderGeometryObject() { pcShapeMaterial->unref(); pcBoundingBox->unref(); + pcBoundColor->unref(); } void ViewProviderGeometryObject::onChanged(const App::Property* prop) @@ -163,10 +170,8 @@ void ViewProviderGeometryObject::onChanged(const App::Property* prop) pcShapeMaterial->shininess.setValue(Mat.shininess); pcShapeMaterial->transparency.setValue(Mat.transparency); } - else if (prop == &BoundingBox || prop == &SelectionStyle) { - applyBoundColor(); - if(SelectionStyle.getValue()==0 || !Selectable.getValue()) - showBoundingBox( BoundingBox.getValue() ); + else if (prop == &BoundingBox) { + showBoundingBox(BoundingBox.getValue()); } ViewProviderDragger::onChanged(prop); @@ -230,35 +235,28 @@ SoPickedPoint* ViewProviderGeometryObject::getPickedPoint(const SbVec2s& pos, co return (pick ? new SoPickedPoint(*pick) : 0); } -unsigned long ViewProviderGeometryObject::getBoundColor() const { +unsigned long ViewProviderGeometryObject::getBoundColor() const +{ ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View"); - if(SelectionStyle.getValue() == 0 || !Selectable.getValue() || !hGrp->GetBool("EnableSelection", true)) - return hGrp->GetUnsigned("BoundingBoxColor",4294967295UL); // white (255,255,255) - else - return hGrp->GetUnsigned("SelectionColor",0x00CD00UL); // rgb(0,205,0) -} - -void ViewProviderGeometryObject::applyBoundColor() { - if(!pcBoundColor) return; - - unsigned long bbcol = getBoundColor(); - float r,g,b; - r = ((bbcol >> 24) & 0xff) / 255.0; g = ((bbcol >> 16) & 0xff) / 255.0; b = ((bbcol >> 8) & 0xff) / 255.0; - pcBoundColor->rgb.setValue(r, g, b); + unsigned long bbcol = hGrp->GetUnsigned("BoundingBoxColor",4294967295UL); // white (255,255,255) + return bbcol; } void ViewProviderGeometryObject::showBoundingBox(bool show) { if (!pcBoundSwitch && show) { + unsigned long bbcol = getBoundColor(); + float r,g,b; + r = ((bbcol >> 24) & 0xff) / 255.0; g = ((bbcol >> 16) & 0xff) / 255.0; b = ((bbcol >> 8) & 0xff) / 255.0; + pcBoundSwitch = new SoSwitch(); SoSeparator* pBoundingSep = new SoSeparator(); SoDrawStyle* lineStyle = new SoDrawStyle; lineStyle->lineWidth = 2.0f; pBoundingSep->addChild(lineStyle); - pcBoundColor = new SoBaseColor(); + pcBoundColor->rgb.setValue(r, g, b); pBoundingSep->addChild(pcBoundColor); - applyBoundColor(); pBoundingSep->addChild(new SoResetTransform()); pBoundingSep->addChild(pcBoundingBox); @@ -267,7 +265,7 @@ void ViewProviderGeometryObject::showBoundingBox(bool show) // add to the highlight node pcBoundSwitch->addChild(pBoundingSep); - pcRoot->insertChild(pcBoundSwitch,pcRoot->findChild(pcModeSwitch)); + pcRoot->addChild(pcBoundSwitch); } if (pcBoundSwitch) { @@ -277,12 +275,6 @@ void ViewProviderGeometryObject::showBoundingBox(bool show) void ViewProviderGeometryObject::setSelectable(bool selectable) { - if(SelectionStyle.getValue()) { - applyBoundColor(); - if(!selectable) - showBoundingBox(false); - } - SoSearchAction sa; sa.setInterest(SoSearchAction::ALL); sa.setSearchingAll(true); diff --git a/src/Gui/ViewProviderGeometryObject.h b/src/Gui/ViewProviderGeometryObject.h index de5db5cc34..5540599064 100644 --- a/src/Gui/ViewProviderGeometryObject.h +++ b/src/Gui/ViewProviderGeometryObject.h @@ -94,7 +94,6 @@ protected: void setSelectable(bool Selectable=true); virtual unsigned long getBoundColor() const; - void applyBoundColor(); protected: SoMaterial * pcShapeMaterial;