GG

Button.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /* GG is a GUI for SDL and OpenGL.
00003    Copyright (C) 2003-2008 T. Zachary Laine
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public License
00007    as published by the Free Software Foundation; either version 2.1
00008    of the License, or (at your option) any later version.
00009    
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014     
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with this library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA
00019 
00020    If you do not wish to comply with the terms of the LGPL please
00021    contact the author as other terms are available for a fee.
00022     
00023    Zach Laine
00024    whatwasthataddress@gmail.com */
00025 
00031 #ifndef _GG_Button_h_
00032 #define _GG_Button_h_
00033 
00034 #include <GG/ClrConstants.h>
00035 #include <GG/TextControl.h>
00036 
00037 #include <boost/serialization/version.hpp>
00038 
00039 
00040 namespace GG {
00041 
00049 class GG_API Button : public TextControl
00050 {
00051 public:
00053     enum ButtonState {
00054         BN_PRESSED,    
00055         BN_UNPRESSED,  
00056         BN_ROLLOVER    
00057     };
00058  
00060     typedef boost::signal<void ()> ClickedSignalType; 
00061 
00062  
00064     Button(X x, Y y, X w, Y h, const std::string& str, const boost::shared_ptr<Font>& font, Clr color,
00065            Clr text_color = CLR_BLACK, Flags<WndFlag> flags = INTERACTIVE); 
00066 
00067  
00069 
00070     ButtonState       State() const;
00071 
00072     const SubTexture& UnpressedGraphic() const; 
00073     const SubTexture& PressedGraphic() const;   
00074     const SubTexture& RolloverGraphic() const;  
00075 
00076     mutable ClickedSignalType ClickedSignal; 
00077 
00078  
00080     virtual void   Render();
00081 
00082     virtual void   SetColor(Clr c); 
00083 
00085     void           SetState(ButtonState state);
00086 
00087     void           SetUnpressedGraphic(const SubTexture& st); 
00088     void           SetPressedGraphic(const SubTexture& st);   
00089     void           SetRolloverGraphic(const SubTexture& st);  
00090 
00091     virtual void   DefineAttributes(WndEditor* editor);
00093 
00094 protected: 
00096     Button(); 
00097 
00098  
00100     virtual void   LButtonDown(const Pt& pt, Flags<ModKey> mod_keys);
00101     virtual void   LDrag(const Pt& pt, const Pt& move, Flags<ModKey> mod_keys);
00102     virtual void   LButtonUp(const Pt& pt, Flags<ModKey> mod_keys);
00103     virtual void   LClick(const Pt& pt, Flags<ModKey> mod_keys);
00104     virtual void   MouseHere(const Pt& pt, Flags<ModKey> mod_keys);
00105     virtual void   MouseLeave();
00106 
00107     virtual void   RenderUnpressed();   
00108     virtual void   RenderPressed();     
00109     virtual void   RenderRollover();    
00110 
00111 
00112 private:
00113     void           RenderDefault();     
00114 
00115     ButtonState    m_state;             
00116 
00117     SubTexture     m_unpressed_graphic; 
00118     SubTexture     m_pressed_graphic;   
00119     SubTexture     m_rollover_graphic;  
00120 
00121     friend class boost::serialization::access;
00122     template <class Archive>
00123     void serialize(Archive& ar, const unsigned int version);
00124 };
00125 
00126 // define EnumMap and stream operators for Button::ButtonState
00127 GG_ENUM_MAP_BEGIN(Button::ButtonState)
00128     GG_ENUM_MAP_INSERT(Button::BN_PRESSED)
00129     GG_ENUM_MAP_INSERT(Button::BN_UNPRESSED)
00130     GG_ENUM_MAP_INSERT(Button::BN_ROLLOVER)
00131 GG_ENUM_MAP_END
00132 
00133 GG_ENUM_STREAM_IN(Button::ButtonState)
00134 GG_ENUM_STREAM_OUT(Button::ButtonState)
00135 
00136 
00148 class GG_API StateButton : public TextControl
00149 {
00150 public: 
00152     typedef boost::signal<void (bool)> CheckedSignalType; 
00153 
00154  
00156     StateButton(X x, Y y, X w, Y h, const std::string& str, const boost::shared_ptr<Font>& font, Flags<TextFormat> format, 
00157                 Clr color, Clr text_color = CLR_BLACK, Clr interior = CLR_ZERO, StateButtonStyle style = SBSTYLE_3D_XBOX,
00158                 Flags<WndFlag> flags = INTERACTIVE); 
00159 
00160  
00162     virtual Pt       MinUsableSize() const;
00163 
00164     bool             Checked() const;       
00165     Clr              InteriorColor() const; 
00166 
00168     StateButtonStyle Style() const;
00169 
00170     mutable CheckedSignalType CheckedSignal; 
00171 
00172  
00174     virtual void     Render();
00175     virtual void     SizeMove(const Pt& ul, const Pt& lr);
00176 
00177     void             Reset();                 
00178     void             SetCheck(bool b = true); 
00179     void             SetButtonPosition(const Pt& ul, const Pt& lr); 
00180     void             SetDefaultButtonPosition(); 
00181     virtual void     SetColor(Clr c);         
00182     void             SetInteriorColor(Clr c); 
00183 
00185     void             SetStyle(StateButtonStyle bs);
00186 
00187     virtual void     DefineAttributes(WndEditor* editor);
00189 
00190 protected: 
00192     StateButton(); 
00193 
00194  
00196     Pt  ButtonUpperLeft() const;  
00197     Pt  ButtonLowerRight() const; 
00198     Pt  TextUpperLeft() const;    
00199 
00200  
00202     virtual void LClick(const Pt& pt, Flags<ModKey> mod_keys);
00203 
00204     void RepositionButton();      
00205 
00206 
00207 private:
00208     bool              m_checked;     
00209     Clr               m_int_color;   
00210     StateButtonStyle  m_style;       
00211 
00212     Pt                m_button_ul;
00213     Pt                m_button_lr;
00214     Pt                m_text_ul;
00215 
00216     friend class boost::serialization::access;
00217     template <class Archive>
00218     void serialize(Archive& ar, const unsigned int version);
00219 };
00220 
00221 
00232 class GG_API RadioButtonGroup : public Control
00233 {
00234 public: 
00236     typedef boost::signal<void (std::size_t)> ButtonChangedSignalType; 
00237 
00238  
00240     RadioButtonGroup(X x, Y y, X w, Y h, Orientation orientation); 
00241 
00242  
00244     virtual Pt       MinUsableSize() const;
00245 
00247     Orientation      GetOrientation() const;
00248 
00250     bool             Empty() const;
00251 
00253     std::size_t      NumButtons() const;
00254 
00257     std::size_t      CheckedButton() const;
00258 
00263     bool             ExpandButtons() const;
00264 
00269     bool             ExpandButtonsProportionally() const;
00270 
00273     bool             RenderOutline() const;
00274 
00275     mutable ButtonChangedSignalType ButtonChangedSignal; 
00276 
00277  
00279     virtual void Render();
00280 
00284     void SetCheck(std::size_t index);
00285 
00290     void DisableButton(std::size_t index, bool b = true); 
00291 
00293     void AddButton(StateButton* bn);
00294 
00297     void AddButton(const std::string& text, const boost::shared_ptr<Font>& font, Flags<TextFormat> format,
00298                    Clr color, Clr text_color = CLR_BLACK, Clr interior = CLR_ZERO,
00299                    StateButtonStyle style = SBSTYLE_3D_RADIO);
00300 
00303     void InsertButton(std::size_t index, StateButton* bn);
00304 
00308     void InsertButton(std::size_t index, const std::string& text, const boost::shared_ptr<Font>& font, Flags<TextFormat> format,
00309                       Clr color, Clr text_color = CLR_BLACK, Clr interior = CLR_ZERO,
00310                       StateButtonStyle style = SBSTYLE_3D_RADIO);
00311 
00318     void RemoveButton(StateButton* button);
00319 
00324     void ExpandButtons(bool expand);
00325 
00330     void ExpandButtonsProportionally(bool proportional);
00331 
00334     void RenderOutline(bool render_outline);
00335 
00338     void RaiseCheckedButton();
00339 
00340     virtual void DefineAttributes(WndEditor* editor);
00341 
00344     static const std::size_t NO_BUTTON;
00346 
00347 protected:
00350     struct GG_API ButtonSlot
00351     {
00352         ButtonSlot();
00353         ButtonSlot(StateButton* button_);
00354         StateButton*               button;
00355         boost::signals::connection connection;
00356 
00357         template <class Archive>
00358         void serialize(Archive& ar, const unsigned int version);
00359     };
00360  
00362     RadioButtonGroup(); 
00363 
00364  
00366     const std::vector<ButtonSlot>& ButtonSlots() const; 
00367 
00368 
00369 private:
00370     class ButtonClickedFunctor // for catching button-click signals from the contained buttons
00371     {
00372     public:
00373         ButtonClickedFunctor(RadioButtonGroup* group, StateButton* button, std::size_t index);
00374         void operator()(bool checked);
00375     private:
00376         RadioButtonGroup* m_group;
00377         StateButton*      m_button;
00378         std::size_t       m_index;
00379     };
00380 
00381     void ConnectSignals();
00382     void SetCheckImpl(std::size_t index, bool signal);
00383     void Reconnect();
00384 
00385     const Orientation       m_orientation;
00386     std::vector<ButtonSlot> m_button_slots;
00387     std::size_t             m_checked_button; 
00388     bool                    m_expand_buttons;
00389     bool                    m_expand_buttons_proportionally;
00390     bool                    m_render_outline;
00391 
00392     friend class ButtonClickedFunctor;
00393 
00394     friend class boost::serialization::access;
00395     template <class Archive>
00396     void serialize(Archive& ar, const unsigned int version);
00397 };
00398 
00399 } // namespace GG
00400 
00401 
00402 // template implementations
00403 template <class Archive>
00404 void GG::Button::serialize(Archive& ar, const unsigned int version)
00405 {
00406     ar  & BOOST_SERIALIZATION_BASE_OBJECT_NVP(TextControl)
00407         & BOOST_SERIALIZATION_NVP(m_state)
00408         & BOOST_SERIALIZATION_NVP(m_unpressed_graphic)
00409         & BOOST_SERIALIZATION_NVP(m_pressed_graphic)
00410         & BOOST_SERIALIZATION_NVP(m_rollover_graphic);
00411 }
00412 
00413 template <class Archive>
00414 void GG::StateButton::serialize(Archive& ar, const unsigned int version)
00415 {
00416     ar  & BOOST_SERIALIZATION_BASE_OBJECT_NVP(TextControl)
00417         & BOOST_SERIALIZATION_NVP(m_checked)
00418         & BOOST_SERIALIZATION_NVP(m_int_color)
00419         & BOOST_SERIALIZATION_NVP(m_style)
00420         & BOOST_SERIALIZATION_NVP(m_button_ul)
00421         & BOOST_SERIALIZATION_NVP(m_button_lr)
00422         & BOOST_SERIALIZATION_NVP(m_text_ul);
00423 }
00424 
00425 template <class Archive>
00426 void GG::RadioButtonGroup::ButtonSlot::serialize(Archive& ar, const unsigned int version)
00427 {
00428     ar  & BOOST_SERIALIZATION_NVP(button);
00429 }
00430 
00431 template <class Archive>
00432 void GG::RadioButtonGroup::serialize(Archive& ar, const unsigned int version)
00433 {
00434     ar  & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Control)
00435         & boost::serialization::make_nvp("m_orientation", const_cast<Orientation&>(m_orientation))
00436         & BOOST_SERIALIZATION_NVP(m_button_slots)
00437         & BOOST_SERIALIZATION_NVP(m_expand_buttons)
00438         & BOOST_SERIALIZATION_NVP(m_expand_buttons_proportionally)
00439         & BOOST_SERIALIZATION_NVP(m_checked_button)
00440         & BOOST_SERIALIZATION_NVP(m_render_outline);
00441 
00442     if (Archive::is_loading::value)
00443         ConnectSignals();
00444 }
00445 
00446 #endif // _GG_Button_h_