GG

AdamGlue.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    
00030 #ifndef _AdamGlue_h_
00031 #define _AdamGlue_h_
00032 
00033 #include <GG/Spin.h>
00034 #include <GG/adobe/adam.hpp>
00035 
00036 #include <boost/signals.hpp>
00037 
00038 
00039 namespace GG {
00040 
00041 class TextControl;
00042 class Button;
00043 class StateButton;
00044 class RadioButtonGroup;
00045 class Edit;
00046 class DropDownList;
00047 class Slider;
00048 
00049 namespace detail {
00050     template <class AdobeValueType, class GGValueType>
00051     GGValueType AnyCast(const adobe::any_regular_t& any);
00052 
00053     template <class AdobeValueType, class GGValueType>
00054     adobe::any_regular_t MakeAny(GGValueType x);
00055 }
00056 
00057 struct AdamCellGlueBase {};
00058 
00059 template <
00060     class ControlType,
00061     class AdamValueType,
00062     class GGValueType
00063 >
00064 struct AdamCellGlue;
00065 
00066 template <>
00067 struct AdamCellGlue<TextControl, adobe::string_t, std::string> :
00068     public AdamCellGlueBase
00069 {
00070     AdamCellGlue(TextControl& text, adobe::sheet_t& sheet, adobe::name_t cell);
00071 
00072 private:
00073     typedef AdamCellGlue<TextControl, adobe::string_t, std::string> ThisType;
00074 
00075     void SheetChanged(const adobe::any_regular_t &any);
00076 
00077     TextControl* m_text;
00078 };
00079 
00080 template <>
00081 struct AdamCellGlue<Button, adobe::string_t, std::string> :
00082     public AdamCellGlueBase
00083 {
00084     AdamCellGlue(Button& button, adobe::sheet_t& sheet, adobe::name_t cell);
00085 
00086 private:
00087     typedef AdamCellGlue<Button, adobe::string_t, std::string> ThisType;
00088 
00089     void SheetChanged(const adobe::any_regular_t &any);
00090     void Enable(bool b);
00091 
00092     Button* m_button;
00093     adobe::sheet_t* m_sheet;
00094     adobe::name_t m_cell;
00095 };
00096 
00097 template <>
00098 struct AdamCellGlue<StateButton, bool, bool> :
00099     public AdamCellGlueBase
00100 {
00101     AdamCellGlue(StateButton& state_button, adobe::sheet_t& sheet, adobe::name_t cell);
00102 
00103 private:
00104     typedef AdamCellGlue<StateButton, bool, bool> ThisType;
00105 
00106     void SheetChanged(const adobe::any_regular_t &any);
00107     void Enable(bool b);
00108     void ControlChanged(bool checked);
00109 
00110     StateButton* m_state_button;
00111     adobe::sheet_t* m_sheet;
00112     adobe::name_t m_cell;
00113 };
00114 
00115 template <>
00116 struct AdamCellGlue<RadioButtonGroup, double, std::size_t> :
00117     public AdamCellGlueBase
00118 {
00119     AdamCellGlue(RadioButtonGroup& radio_button_group, adobe::sheet_t& sheet, adobe::name_t cell);
00120 
00121 private:
00122     typedef AdamCellGlue<RadioButtonGroup, double, std::size_t> ThisType;
00123 
00124     void SheetChanged(const adobe::any_regular_t &any);
00125     void Enable(bool b);
00126     void ControlChanged(std::size_t button);
00127 
00128     RadioButtonGroup* m_radio_button_group;
00129     adobe::sheet_t* m_sheet;
00130     adobe::name_t m_cell;
00131 };
00132 
00133 template <class AdamValueType, class T>
00134 struct AdamCellGlue<Edit, AdamValueType, T> :
00135     public AdamCellGlueBase
00136 {
00137     AdamCellGlue(Edit& edit, adobe::sheet_t& sheet, adobe::name_t cell);
00138 
00139 private:
00140     typedef AdamCellGlue<Edit, AdamValueType, T> ThisType;
00141 
00142     void SheetChanged(const adobe::any_regular_t &any);
00143     void Enable(bool b);
00144     void ControlChanged(const std::string& str);
00145 
00146     Edit* m_edit;
00147     adobe::sheet_t* m_sheet;
00148     adobe::name_t m_cell;
00149 };
00150 
00151 template <>
00152 struct AdamCellGlue<MultiEdit, adobe::string_t, std::string> :
00153     public AdamCellGlueBase
00154 {
00155     AdamCellGlue(MultiEdit& multi_edit, adobe::sheet_t& sheet, adobe::name_t cell);
00156 
00157 private:
00158     typedef AdamCellGlue<MultiEdit, adobe::string_t, std::string> ThisType;
00159 
00160     void SheetChanged(const adobe::any_regular_t &any);
00161     void Enable(bool b);
00162     void ControlChanged(const std::string& str);
00163 
00164     MultiEdit* m_multi_edit;
00165     adobe::sheet_t* m_sheet;
00166     adobe::name_t m_cell;
00167 };
00168 
00169 template <class T>
00170 struct AdamCellGlue<Spin<T>, double, T> :
00171     public AdamCellGlueBase
00172 {
00173     AdamCellGlue(Spin<T>& spin, adobe::sheet_t& sheet, adobe::name_t cell);
00174 
00175 private:
00176     typedef AdamCellGlue<Spin<T>, double, T> ThisType;
00177 
00178     void SheetChanged(const adobe::any_regular_t &any);
00179     void Enable(bool b);
00180     void ControlChanged(T t);
00181 
00182     Spin<T>* m_spin;
00183     adobe::sheet_t* m_sheet;
00184     adobe::name_t m_cell;
00185 };
00186 
00187 template <>
00188 struct AdamCellGlue<DropDownList, double, std::size_t> :
00189     public AdamCellGlueBase
00190 {
00191     AdamCellGlue(DropDownList& drop_list, adobe::sheet_t& sheet, adobe::name_t cell);
00192 
00193 private:
00194     typedef AdamCellGlue<DropDownList, double, std::size_t> ThisType;
00195 
00196     void SheetChanged(const adobe::any_regular_t &any);
00197     void Enable(bool b);
00198     void ControlChanged(DropDownList::iterator it);
00199 
00200     DropDownList* m_drop_list;
00201     adobe::sheet_t* m_sheet;
00202     adobe::name_t m_cell;
00203 };
00204 
00205 template <>
00206 struct AdamCellGlue<Slider, double, int> :
00207     public AdamCellGlueBase
00208 {
00209     AdamCellGlue(Slider& slider, adobe::sheet_t& sheet, adobe::name_t cell);
00210 
00211 private:
00212     typedef AdamCellGlue<Slider, double, int> ThisType;
00213 
00214     void SheetChanged(const adobe::any_regular_t &any);
00215     void Enable(bool b);
00216     void ControlChanged(int tab_posn, int min, int max);
00217 
00218     Slider* m_slider;
00219     adobe::sheet_t* m_sheet;
00220     adobe::name_t m_cell;
00221 };
00222 
00223 struct AdamSheetGlue
00224 {
00225     AdamSheetGlue(const std::string& str);
00226     AdamSheetGlue(std::istream& stream);
00227 
00228     void SetCell(adobe::name_t cell, const adobe::any_regular_t& value);
00229     void SetCells(const adobe::dictionary_t& dictionary);
00230 
00231     template <
00232         class AdamValueType,
00233         class GGValueType,
00234         class ControlType
00235     >
00236     void BindCell(ControlType& control, adobe::name_t cell);
00237 
00238     adobe::any_regular_t Result();
00239 
00240 private:
00241     void Init(std::istream& stream);
00242 
00243     adobe::sheet_t m_sheet;
00244     std::vector<boost::shared_ptr<AdamCellGlueBase> > m_cells;
00245 };
00246 
00247 
00248 // implementations
00249 
00250 namespace detail {
00251     template <class AdobeValueType, class GGValueType>
00252     GGValueType AnyCast(const adobe::any_regular_t& any)
00253     { return static_cast<GGValueType>(any.cast<AdobeValueType>()); }
00254 
00255     template <class AdobeValueType, class GGValueType>
00256     adobe::any_regular_t MakeAny(GGValueType x)
00257     { return adobe::any_regular_t(static_cast<AdobeValueType>(x)); }
00258 }
00259 
00260 
00261 // AdamCellGlue<Edit>
00262 
00263 template <class AdamValueType, class T>
00264 AdamCellGlue<Edit, AdamValueType, T>::AdamCellGlue(
00265     Edit& edit,
00266     adobe::sheet_t& sheet,
00267     adobe::name_t cell) :
00268     m_edit(&edit),
00269     m_sheet(&sheet),
00270     m_cell(cell)
00271 {
00272     m_sheet->monitor_value(m_cell, boost::bind(&ThisType::SheetChanged, this, _1));
00273     m_sheet->monitor_enabled(m_cell, 0, 0, boost::bind(&ThisType::Enable, this, _1));
00274     m_edit->EditedSignal.connect(boost::bind(&ThisType::ControlChanged, this, _1));
00275 }
00276 
00277 template <class AdamValueType, class T>
00278 void AdamCellGlue<Edit, AdamValueType, T>::SheetChanged(const adobe::any_regular_t &any)
00279 { *m_edit << detail::AnyCast<AdamValueType, T>(any); }
00280 
00281 template <class AdamValueType, class T>
00282 void AdamCellGlue<Edit, AdamValueType, T>::Enable(bool b)
00283 { m_edit->Disable(!b); }
00284 
00285 template <class AdamValueType, class T>
00286 void AdamCellGlue<Edit, AdamValueType, T>::ControlChanged(const std::string& str)
00287 {
00288     try {
00289         T x = boost::lexical_cast<T>(str);
00290         m_sheet->set(m_cell, detail::MakeAny<AdamValueType, T>(x));
00291         m_sheet->update();
00292     } catch (const boost::bad_lexical_cast&) {}
00293 }
00294 
00295 
00296 // AdamCellGlue<Spin<T> >
00297 
00298 template <class T>
00299 AdamCellGlue<Spin<T>, double, T>::AdamCellGlue(
00300     Spin<T>& spin,
00301     adobe::sheet_t& sheet,
00302     adobe::name_t cell) :
00303     m_spin(&spin),
00304     m_sheet(&sheet),
00305     m_cell(cell)
00306 {
00307     m_sheet->monitor_value(m_cell, boost::bind(&ThisType::SheetChanged, this, _1));
00308     m_sheet->monitor_enabled(m_cell, 0, 0, boost::bind(&ThisType::Enable, this, _1));
00309     m_spin->ValueChangedSignal.connect(boost::bind(&ThisType::ControlChanged, this, _1));
00310 }
00311 
00312 template <class T>
00313 void AdamCellGlue<Spin<T>, double, T>::SheetChanged(const adobe::any_regular_t &any)
00314 { m_spin->SetValue(detail::AnyCast<double, T>(any)); }
00315 
00316 template <class T>
00317 void AdamCellGlue<Spin<T>, double, T>::Enable(bool b)
00318 { m_spin->Disable(!b); }
00319 
00320 template <class T>
00321 void AdamCellGlue<Spin<T>, double, T>::ControlChanged(T t)
00322 {
00323     m_sheet->set(m_cell, detail::MakeAny<double, T>(t));
00324     m_sheet->update();
00325 }
00326 
00327 }
00328 
00329 #endif