cwidget  0.5.16
radiogroup.h
00001 // radiogroup.h                    -*-c++-*-
00002 //
00003 //  Ok, here's how radio-button-like behavior is implemented:
00004 //
00005 //  Radio-groups store some group of buttons.  They constrain the buttons
00006 // so that exactly one is on.  This is done by various devious means:
00007 // the first button added is always selected, and subsequently added selected
00008 // buttons override previously selected buttons.  You can manually select a
00009 // button through this class (by ID) or via the button's own set_checked
00010 // routine.
00011 //
00012 //  (note that radio-groups are NOT WIDGETS!!!)
00013 //  (note that this does NOT attempt to memory-manage its "children"!)
00014 //  (note that you should generally delete this at the same time as its
00015 //   children, or Bad Things[tm] may happen.. (more specifically, if you
00016 //   delete a selected child, some other random option will be selected))
00017 //
00018 //  Oh, one more note: although any togglebutton can be used in a radio
00019 // widget, passing in checkbuttons has a high probability of causing weird
00020 // things.  Use radiobuttons.  (if you want them to look like checkbuttons,
00021 // use the extended togglebutton constructor..)
00022 
00023 #ifndef RADIOGROUP_H
00024 #define RADIOGROUP_H
00025 
00026 #include <cwidget/generic/util/ref_ptr.h>
00027 
00028 #include <vector>
00029 
00030 #include <sigc++/connection.h>
00031 #include <sigc++/trackable.h>
00032 
00033 namespace cwidget
00034 {
00035   namespace widgets
00036   {
00037     class togglebutton;
00038 
00039     class radiogroup:public sigc::trackable
00040     {
00041       struct item
00042       {
00043         util::ref_ptr<togglebutton> b;
00044         int id;
00045 
00046         // Needed, unfortunately.
00047         sigc::connection destroyed_conn, pressed_conn;
00048 
00049         item(const util::ref_ptr<togglebutton> &_b, int _id,
00050              const sigc::connection &_dconn, const sigc::connection &_pconn)
00051           :b(_b), id(_id), destroyed_conn(_dconn), pressed_conn(_pconn) {}
00052       };
00053 
00054       typedef std::vector<item> itemlist;
00055 
00056       itemlist items;
00057 
00058       // The index of the currently selected button
00059       itemlist::size_type selected;
00060 
00061       // Called when a particular button is selected.
00062       // The argument is the *index* of the button.
00063       void button_pressed(itemlist::size_type index);
00064     public:
00065       radiogroup();
00066       ~radiogroup();
00067 
00068       void add_button(const util::ref_ptr<togglebutton> &b, int id);
00069       void rem_button(const util::ref_ptr<togglebutton> &b);
00070 
00071       void rem_button_bare(togglebutton &b);
00072 
00074       bool selection_valid();
00075 
00077       int get_selected();
00078 
00079       // Selects a button by id.
00080       void select(int id);
00081 
00083       void destroy();
00084 
00085       // Emitted when one of the sub-items is chosen.  (you could also collect
00086       // the individual button signals; this is just a higher-level view of it)
00087       sigc::signal1<void, int> item_selected;
00088     };
00089   }
00090 }
00091 
00092 #endif