/* * QtObservedAtom.hpp * * Created on: Oct 28, 2015 * Author: heber */ #ifndef QTOBSERVEDATOM_HPP_ #define QTOBSERVEDATOM_HPP_ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include "CodePatterns/Observer/Observable.hpp" #include "CodePatterns/Observer/Observer.hpp" #include "LinearAlgebra/Vector.hpp" #include "UIElements/Qt4/InstanceBoard/ObservedValue_types.hpp" #include "UIElements/Qt4/InstanceBoard/ObservedValuesContainer.hpp" #include "types.hpp" class atom; class QtObservedInstanceBoard; /** This instance is the ObservedValue representation of a World's atom. * * Due to the signal/slot mechanism and its delays, lifetime of objects in the * World and their QtGui representation cannot directly be related (without * slowing down Actions just for having the representation up to speed). * Hence, the required information for displaying and representing these * objects must be contained in an extra instance. * * This is the instance for information about a particular atom. * * Essentially, this is the interface between molecuilder's World (and a * particular atom) and the QtGui part of the code. */ class QtObservedAtom : public QWidget, public Observer { Q_OBJECT public: //!> typedef for instance wrapped in shared ptr typedef boost::shared_ptr ptr; private: //!> ObservedValuesContainer needs to access private cstor and dstor friend class ObservedValuesContainer; //!> QtObservedInstanceBoard needs to access private cstor and dstor friend class QtObservedInstanceBoard; /** Cstor of QtObservedAtom. * * \param _id id of observed atom * \param _atom ref to observed atom * \param _board ref to InstanceBoard for callbacks on occasion of subjectKilled() * \param _parent Qt parent to automatically destroy when parent is destroyed */ QtObservedAtom( const atomId_t _id, const atom * const _atom, QtObservedInstanceBoard &_board, QWidget * _parent=0); public: /** Dstor of QtObservedAtom. * */ ~QtObservedAtom(); // Observer functions void update(Observable *publisher); void subjectKilled(Observable *publisher); void recieveNotification(Observable *publisher, Notification_ptr notification); /** Getter to atom index contained in \a ObservedValues. * * \return atom's index */ const atomId_t& getAtomIndex() const; //!> typedef for list of bonds, defined by pairs of atom ids typedef std::vector< std::pair > ListOfBonds_t; /** Getter to atom bonds contained in \a ObservedValues. * * \return atom's bonds */ const ListOfBonds_t& getAtomBonds() const; /** Getter to atom element contained in \a ObservedValues. * * \return atom's element */ const atomicNumber_t& getAtomElement() const; /** Getter to atom name contained in \a ObservedValues. * * \return atom's name */ const std::string& getAtomName() const; /** Getter to atom position contained in \a ObservedValues. * * \return atom's position */ const Vector& getAtomPosition() const; /** Getter to atom's molecule index contained in \a ObservedValues. * * \return atom's molecule index */ const moleculeId_t& getAtomMoleculeIndex() const; /** Getter to atom's selected status. * * \return true - atom selected, false - else */ const bool getAtomSelected() const; signals: void indexChanged(const atomId_t, const atomId_t); void bondsChanged(); void elementChanged(); void moleculeindexChanged(); void nameChanged(); void positionChanged(); void atomRemoved(); void selectedChanged(); //private slots: private: void activateObserver(); void deactivateObserver(); static const atom * const getAtomConst(const atomId_t _id); static atom * const getAtom(const atomId_t _id); private: static atomId_t updateIndex(); static ListOfBonds_t updateBonds( const boost::function &_getAtomIndex); static atomicNumber_t updateElement( const boost::function &_getAtomIndex); static moleculeId_t updateMoleculeIndex( const boost::function &_getAtomIndex); static std::string updateName( const boost::function &_getAtomIndex); static Vector updatePosition( const boost::function &_getAtomIndex); static bool updateSelected( const boost::function &_getAtomIndex); //!> enumeration of observed values to match with entries in ObservedValues enum ObservedTypes { //!> contains the current atom index AtomIndex, //!> contains the current set of bonds atoms for the atom AtomBonds, //!> contains the current atom element AtomElement, //!> contains the current atom's molecule index AtomMoleculeIndex, //!> contains the current atom position AtomName, //!> contains the current atom position AtomPosition, //!> contains the current atom's selection status AtomSelected, //!> gives the size of the enumeration MAX_ObservedTypes }; /** Initializes all \a ObservedValues entries. * * \param _ObservedValues vector of ObservedValue to be filled * \param _id atom id * \param _atomref reference to atom * \param _subjectKilled ref to function to call on subjectKilled() */ void initObservedValues( ObservedValues_t &_ObservedValues, const atomId_t _id, const atom * const _atomref, const boost::function &_subjectKilled); /** Destroys all \a ObservedValues entries. * * \param _ObservedValues vector of ObservedValue to be destroyed */ static void destroyObservedValues( std::vector &_ObservedValues); /** Function is called by InstanceBoard to inform about its destruction. * * \note callbacks must not be used after this */ void noteBoardIsGone() { BoardIsGone = true; } /** Counts the number of subject killed received from the observed values. * * \param _id id to check against ours */ void countValuesSubjectKilled(const atomId_t _id); //!> counts how many ObservedValues have already been subjectKilled() mutable size_t subjectKilledCount; /** Helper function to check that all subjectKilled have been received for both * this instance and all its internal observed values. * */ void checkForRemoval(); private: //!> list of channels when index needs to update static const Observable::channels_t AtomIndexChannels; //!> list of channels when bonds needs to update static const Observable::channels_t AtomBondsChannels; //!> list of channels when element needs to update static const Observable::channels_t AtomElementChannels; //!> list of channels when molecule index needs to update static const Observable::channels_t AtomMoleculeIndexChannels; //!> list of channels when name needs to update static const Observable::channels_t AtomNameChannels; //!> list of channels when position needs to update static const Observable::channels_t AtomPositionChannels; //!> list of channels when selection needs to update static const Observable::channels_t AtomSelectedChannels; //!> we get multiple subjectKilled(), count and call callback() only on last const unsigned int AllsignedOnChannels; unsigned int signedOffChannels; //!> the Observable we are signed on, also indicates whether we are sign on (not NULL) const Observable *owner; private: //!> contains still the old id after the index of the atom changed atomId_t oldId; //!> reference to InstanceBoard for callbacks on subjectKilled() QtObservedInstanceBoard & board; //!> is board still alive or not, impacts callbacks bool BoardIsGone; //!> internal reference to ObservedValues held by QtObservedInstanceBoard ObservedValues_t ObservedValues; }; #endif /* QTOBSERVEDATOM_HPP_ */