Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

ToggleControl.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_ToggleControl_h_
00003 #define INCLUDED_ToggleControl_h_
00004 
00005 #include "NullControl.h"
00006 #include "Shared/ReferenceCounter.h"
00007 
00008 //! a simple control for turning things on and off
00009 /*! Can also be used for radio buttons - select one of a group
00010  *
00011  *  By using the #externalStore (setStore()/getStore()), you can use
00012  *  this instead of a ValueEditControl<bool> */
00013 class ToggleControl : public NullControl {
00014 public:
00015   //! a little class for managing the currently active ToggleControl to allow radio buttons
00016   class RadioGroup : public ReferenceCounter {
00017   public:
00018     //! constructor
00019     explicit RadioGroup(bool must_have_one=true) : ReferenceCounter(), cur(NULL), enforced(must_have_one) {}
00020     //! call this when a different ToggleControl wants to take over
00021     /*! implementation is trickier than you might think! */
00022     virtual void activate(ToggleControl * next) {
00023       bool was_enforced=enforced; //turn off enforcing so current control can turn off...
00024       enforced=false;
00025       if(cur!=NULL) {
00026         ToggleControl * tmp=cur;
00027         cur=NULL; // set this to NULL first to prevent infinite recursion
00028         tmp->setStatus(false);
00029       }
00030       enforced=was_enforced;
00031       cur=next;
00032     }
00033     //! returns the currently active control
00034     virtual ToggleControl * getActive() const { return cur; }
00035     //! can change the "must have one" setting (#enforced)
00036     virtual void setEnforced(bool must_have_one) { enforced=must_have_one; }
00037     //! returns the "must have one" setting (#enforced)
00038     virtual bool getEnforced() const { return enforced; }
00039   protected:
00040     ToggleControl * cur; //!< the currently active control, or NULL
00041     bool enforced; //!< if true, the current control cannot turn off, a new one must be activated
00042   private:
00043     RadioGroup(const RadioGroup& ); //!< don't call
00044     RadioGroup& operator=(const RadioGroup& ); //!< don't call
00045   };
00046 
00047   //!@name Constructors
00048   //!
00049   ToggleControl() : NullControl("[ ] "), rg(NULL), externalStore(NULL) {}
00050   ToggleControl(const std::string& n, RadioGroup * rad=NULL) : NullControl("[ ] "+n), rg(NULL), externalStore(NULL) { setRadioGroup(rad); }
00051   ToggleControl(const std::string& n, const std::string& d, RadioGroup * rad=NULL) : NullControl("[ ] "+n,d), rg(NULL), externalStore(NULL) { setRadioGroup(rad); }
00052   //@}
00053   ~ToggleControl() { setRadioGroup(NULL); } //!< destructor
00054 
00055   virtual ControlBase * activate(MC_ID mcid, Socket * disp) { toggleStatus(); return NullControl::activate(mcid,disp); }
00056   virtual ControlBase * doSelect() { toggleStatus(); return NullControl::doSelect(); }
00057 
00058   virtual ControlBase& setName(const std::string& n) { name=std::string("[")+name.substr(1,1)+std::string("] ")+n; return *this; }
00059 
00060   //! calls setStatus() with the not of getStatus()
00061   virtual void toggleStatus() {
00062     setStatus(!getStatus());
00063   }
00064 
00065   //! if status is a ' ', it'll be replaced with @a c, otherwise a space.
00066   virtual void toggleStatus(char c) {
00067     if(getStatus())
00068       setStatus(false);
00069     else
00070       setStatus(c);
00071   }
00072 
00073   //! status will toggle between the two arguments; if current status is neither, the first is used
00074   virtual void toggleStatus(char c1,char c2) {
00075     if(getStatusChar()==c1)
00076       setStatus(c2);
00077     else
00078       setStatus(c1);
00079   }
00080 
00081   //! a true will put a 'X' for the status; false shows ' '
00082   virtual void setStatus(bool check) {
00083     setStatus(check?'X':' ');
00084   }
00085   
00086   //! pass the character to put as the status
00087   virtual void setStatus(char c) {
00088     if(rg!=NULL) {
00089       if(c==' ') {
00090         if(rg->getEnforced())
00091           return;
00092         rg->activate(NULL);
00093       } else {
00094         rg->activate(this);
00095       }
00096     }
00097     name[1]=c;
00098     if(externalStore!=NULL)
00099       *externalStore=getStatus();
00100   }
00101 
00102   //! returns true if there's a non-space as the status
00103   virtual bool getStatus() const {
00104     return getStatusChar()!=' ';
00105   }
00106 
00107   //! returns the current status char
00108   virtual char getStatusChar() const {
00109     return name[1];
00110   }
00111 
00112   //! removes itself from current RadioGroup, and adds itself to @a rad if non-NULL
00113   virtual void setRadioGroup(RadioGroup * rad) {
00114     if(rg!=NULL)
00115       rg->removeReference();
00116     if(rad!=NULL)
00117       rad->addReference();
00118     rg=rad;
00119     if(getStatus() && rg!=NULL)
00120       rg->activate(this);
00121   }
00122 
00123   //! returns the current RadioGroup
00124   virtual RadioGroup * getRadioGroup() const { return rg; }
00125 
00126   virtual void setStore(bool * s) { externalStore=s; *s=getStatus(); }  //!< sets #externalStore (and updates its current setting)
00127   virtual bool * getStore() const { return externalStore; } //!< returns #externalStore
00128 
00129 protected:
00130   RadioGroup * rg; //!< pointer to an optional radio group to allow one-of-many selections
00131   
00132   bool * externalStore; //!< an external bit which should be kept in sync with current setting
00133 
00134 private:
00135   ToggleControl(const ToggleControl& ); //!< don't call
00136   ToggleControl& operator=(const ToggleControl& ); //!< don't call
00137 };
00138 
00139 /*! @file
00140  * @brief 
00141  * @author ejt (Creator)
00142  */
00143 
00144 #endif

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:52 2016 by Doxygen 1.6.3