void SignalGrabStrategy::
objectsReleased(const std::vector<SceneObjectPtr>& objs)
{
   std::vector<SceneObjectPtr>::const_iterator o;
   for ( o = objs.begin(); o != objs.end(); ++o )
   {
      mGrabbedObjects.erase(std::remove(mGrabbedObjects.begin(),
                                        mGrabbedObjects.end(), *o),
                            mGrabbedObjects.end());
   }

   mGrabbing = ! mGrabbedObjects.empty();
   mReleaseCallback(objs);
}
Esempio n. 2
0
	void base::IManaged::release()
	{
		mRefCounter--;

#ifdef _DEBUG
		if (mReleaseCallback)
		{
			mReleaseCallback(this);
		}
#endif
		if (mRefCounter <= 0)
		{
			delete this;
		}
	}
void MultiObjectGrabStrategy::grabbableObjStateChanged(SceneObjectPtr obj)
{
   // If mChosenObjects is not empty, then we have a collection of objects to
   // grab that have not yet been grabbed. obj may be in mChosenObjects, and
   // if it is not grabbable, then it must be removed.
   if ( ! mChosenObjects.empty() )
   {
      std::vector<SceneObjectPtr>::iterator o =
         std::find(mChosenObjects.begin(), mChosenObjects.end(), obj);

      if ( o != mChosenObjects.end() && ! (*o)->isGrabbable() )
      {
         mObjConnections[*o].disconnect();
         mObjConnections.erase(*o);

         std::vector<SceneObjectPtr> objs(1, *o);
         mEventData->selectionListReduced(objs);

         mChosenObjects.erase(o);
      }
   }
   // If mGrabbedObjects is not empty, then we have grabbed objects, and obj
   // may be in that collection. If obj is no longer grabbable, it must be
   // removed from mGrabbedObjects.
   else if ( ! mGrabbedObjects.empty() )
   {
      std::vector<SceneObjectPtr>::iterator o =
         std::find(mGrabbedObjects.begin(), mGrabbedObjects.end(), obj);

      if ( o != mGrabbedObjects.end() && ! (*o)->isGrabbable() )
      {
         mObjConnections[*o].disconnect();
         mObjConnections.erase(*o);

         // Inform the code that is using us that we have released a grabbed
         // object.
         mReleaseCallback(std::vector<SceneObjectPtr>(1, *o));

         mGrabbedObjects.erase(o);

         // Keep the grabbing state up to date now that mGrabbedObjects has
         // changed.
         mGrabbing = ! mGrabbedObjects.empty();
      }
   }
}
void SignalGrabStrategy::release()
{
   // Emit the grab signal and get the collection of released objects.
   std::vector<SceneObjectPtr> released_objs;
   mGrabSignalData->release(released_objs);

   if ( ! released_objs.empty() )
   {
      std::vector<SceneObjectPtr>::iterator o;
      for ( o = released_objs.begin(); o != released_objs.end(); ++o )
      {
         mGrabbedObjects.erase(std::remove(mGrabbedObjects.begin(),
                                        mGrabbedObjects.end(), *o),
                               mGrabbedObjects.end());
      }

      mGrabbing = ! mGrabbedObjects.empty();
      mReleaseCallback(released_objs);
   }
}
void MultiObjectGrabStrategy::update(ViewerPtr viewer)
{
   if ( ! mGrabbing )
   {
      // The user has requested to add mCurIsectObject to the collection of
      // objects selected for later grabbing.
      if ( mCurIsectObject && mCurIsectObject->isGrabbable() && mChooseBtn() )
      {
         std::vector<SceneObjectPtr>::iterator o =
            std::find(mChosenObjects.begin(), mChosenObjects.end(),
                      mCurIsectObject);

         // Only choose mCurIsectObject for grabbing if it is not already in
         // mChosenObjcts.
         if ( o == mChosenObjects.end() )
         {
            mChosenObjects.push_back(mCurIsectObject);

            // Connect the grabbable object state change signal to our slot.
            mObjConnections[mCurIsectObject] =
               mCurIsectObject->grabbableStateChanged().connect(
                  boost::bind(
                     &MultiObjectGrabStrategy::grabbableObjStateChanged,
                     this, _1
                  )
               );

            std::vector<SceneObjectPtr> objs(1, mCurIsectObject);
            mEventData->selectionListExpanded(objs);

            // Use the intersection point of the most recently chosen object.
            mIntersectPoint = mCurIntersectPoint;
         }
      }
      // The user has requested to grab all the selected objects (those in
      // mChosenObjects).
      else if ( mGrabBtn() )
      {
         // If mChosenObjects is not empty, those objects are the ones that
         // we will grab.
         if ( ! mChosenObjects.empty() )
         {
            mGrabbedObjects = mChosenObjects;
            mChosenObjects.clear();
            mGrabbing = true;
         }
         // If mChosenObjects is empty but we are intersecting an object,
         // then that will be the one that we grab.
         else if ( mCurIsectObject )
         {
            mGrabbedObjects.resize(1);
            mGrabbedObjects[0] = mCurIsectObject;
            mGrabbing = true;
         }

         // If mGrabbing is false at this point, then there is nothing to
         // grab. Otherwise, invoke mGrabCallback to indicate that one or more
         // objects are now grabbed.
         if ( mGrabbing )
         {
            mGrabCallback(mGrabbedObjects, mIntersectPoint);
         }
      }
   }
   // If we are grabbing an object and the release button has just been
   // pressed, then release the grabbed object.
   else if ( mGrabbing && mReleaseBtn() )
   {
      // We no longer care about grabbable state changes because
      // mGrabbedObjects is about to be emptied.
      std::for_each(
         mObjConnections.begin(), mObjConnections.end(),
         boost::bind(&boost::signals::connection::disconnect,
                     boost::bind(&obj_conn_map_t::value_type::second, _1))
      );

      // Update our state to reflect that we are no longer grabbing an object.
      mGrabbing = false;
      mReleaseCallback(mGrabbedObjects);
      mGrabbedObjects.clear();
   }
}