GG
|
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