GG
AdamGlue.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /* GG is a GUI for SDL and OpenGL.
3  Copyright (C) 2003-2008 T. Zachary Laine
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public License
7  as published by the Free Software Foundation; either version 2.1
8  of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free
17  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18  02111-1307 USA
19 
20  If you do not wish to comply with the terms of the LGPL please
21  contact the author as other terms are available for a fee.
22 
23  Zach Laine
24  whatwasthataddress@gmail.com */
25 
30 #ifndef _AdamGlue_h_
31 #define _AdamGlue_h_
32 
33 #include <GG/DropDownList.h>
34 #include <GG/Spin.h>
35 #include <GG/adobe/adam.hpp>
36 
37 #include <boost/signals.hpp>
38 
39 
40 namespace GG {
41 
42 class TextControl;
43 class Button;
44 class StateButton;
45 class RadioButtonGroup;
46 class Edit;
47 template <class T>
48 class Slider;
49 
50 namespace detail {
51  template <class AdobeValueType, class GGValueType>
52  GGValueType AnyCast(const adobe::any_regular_t& any);
53 
54  template <class AdobeValueType, class GGValueType>
55  adobe::any_regular_t MakeAny(GGValueType x);
56 }
57 
58 struct AdamCellGlueBase {};
59 
60 template <
61  class ControlType,
62  class AdamValueType,
63  class GGValueType
64 >
65 struct AdamCellGlue;
66 
67 template <>
68 struct AdamCellGlue<TextControl, adobe::string_t, std::string> :
69  public AdamCellGlueBase
70 {
71  AdamCellGlue(TextControl& text, adobe::sheet_t& sheet, adobe::name_t cell);
72 
73 private:
74  typedef AdamCellGlue<TextControl, adobe::string_t, std::string> ThisType;
75 
76  void SheetChanged(const adobe::any_regular_t &any);
77 
78  TextControl* m_text;
79 };
80 
81 template <>
82 struct AdamCellGlue<Button, adobe::string_t, std::string> :
83  public AdamCellGlueBase
84 {
85  AdamCellGlue(Button& button, adobe::sheet_t& sheet, adobe::name_t cell);
86 
87 private:
88  typedef AdamCellGlue<Button, adobe::string_t, std::string> ThisType;
89 
90  void SheetChanged(const adobe::any_regular_t &any);
91  void Enable(bool b);
92 
93  Button* m_button;
94  adobe::sheet_t* m_sheet;
95  adobe::name_t m_cell;
96 };
97 
98 template <>
99 struct AdamCellGlue<StateButton, bool, bool> :
100  public AdamCellGlueBase
101 {
102  AdamCellGlue(StateButton& state_button, adobe::sheet_t& sheet, adobe::name_t cell);
103 
104 private:
105  typedef AdamCellGlue<StateButton, bool, bool> ThisType;
106 
107  void SheetChanged(const adobe::any_regular_t &any);
108  void Enable(bool b);
109  void ControlChanged(bool checked);
110 
111  StateButton* m_state_button;
112  adobe::sheet_t* m_sheet;
113  adobe::name_t m_cell;
114 };
115 
116 template <>
117 struct AdamCellGlue<RadioButtonGroup, double, std::size_t> :
118  public AdamCellGlueBase
119 {
120  AdamCellGlue(RadioButtonGroup& radio_button_group, adobe::sheet_t& sheet, adobe::name_t cell);
121 
122 private:
123  typedef AdamCellGlue<RadioButtonGroup, double, std::size_t> ThisType;
124 
125  void SheetChanged(const adobe::any_regular_t &any);
126  void Enable(bool b);
127  void ControlChanged(std::size_t button);
128 
129  RadioButtonGroup* m_radio_button_group;
130  adobe::sheet_t* m_sheet;
131  adobe::name_t m_cell;
132 };
133 
134 template <class AdamValueType, class T>
135 struct AdamCellGlue<Edit, AdamValueType, T> :
136  public AdamCellGlueBase
137 {
138  AdamCellGlue(Edit& edit, adobe::sheet_t& sheet, adobe::name_t cell);
139 
140 private:
141  typedef AdamCellGlue<Edit, AdamValueType, T> ThisType;
142 
143  void SheetChanged(const adobe::any_regular_t &any);
144  void Enable(bool b);
145  void ControlChanged(const std::string& str);
146 
147  Edit* m_edit;
148  adobe::sheet_t* m_sheet;
149  adobe::name_t m_cell;
150 };
151 
152 template <>
153 struct AdamCellGlue<MultiEdit, adobe::string_t, std::string> :
154  public AdamCellGlueBase
155 {
156  AdamCellGlue(MultiEdit& multi_edit, adobe::sheet_t& sheet, adobe::name_t cell);
157 
158 private:
159  typedef AdamCellGlue<MultiEdit, adobe::string_t, std::string> ThisType;
160 
161  void SheetChanged(const adobe::any_regular_t &any);
162  void Enable(bool b);
163  void ControlChanged(const std::string& str);
164 
165  MultiEdit* m_multi_edit;
166  adobe::sheet_t* m_sheet;
167  adobe::name_t m_cell;
168 };
169 
170 template <class T>
171 struct AdamCellGlue<Spin<T>, double, T> :
172  public AdamCellGlueBase
173 {
174  AdamCellGlue(Spin<T>& spin, adobe::sheet_t& sheet, adobe::name_t cell);
175 
176 private:
177  typedef AdamCellGlue<Spin<T>, double, T> ThisType;
178 
179  void SheetChanged(const adobe::any_regular_t &any);
180  void Enable(bool b);
181  void ControlChanged(T t);
182 
183  Spin<T>* m_spin;
184  adobe::sheet_t* m_sheet;
185  adobe::name_t m_cell;
186 };
187 
188 template <>
189 struct AdamCellGlue<DropDownList, double, std::size_t> :
190  public AdamCellGlueBase
191 {
192  AdamCellGlue(DropDownList& drop_list, adobe::sheet_t& sheet, adobe::name_t cell);
193 
194 private:
195  typedef AdamCellGlue<DropDownList, double, std::size_t> ThisType;
196 
197  void SheetChanged(const adobe::any_regular_t &any);
198  void Enable(bool b);
199  void ControlChanged(DropDownList::iterator it);
200 
201  DropDownList* m_drop_list;
202  adobe::sheet_t* m_sheet;
203  adobe::name_t m_cell;
204 };
205 
206 template <>
207 struct AdamCellGlue<Slider<int>, double, int> :
208  public AdamCellGlueBase
209 {
210  AdamCellGlue(Slider<int>& slider, adobe::sheet_t& sheet, adobe::name_t cell);
211 
212 private:
213  typedef AdamCellGlue<Slider<int>, double, int> ThisType;
214 
215  void SheetChanged(const adobe::any_regular_t &any);
216  void Enable(bool b);
217  void ControlChanged(int tab_posn, int min, int max);
218 
219  Slider<int>* m_slider;
220  adobe::sheet_t* m_sheet;
221  adobe::name_t m_cell;
222 };
223 
224 struct AdamSheetGlue
225 {
226  AdamSheetGlue(const std::string& str);
227  AdamSheetGlue(std::istream& stream);
228 
229  void SetCell(adobe::name_t cell, const adobe::any_regular_t& value);
230  void SetCells(const adobe::dictionary_t& dictionary);
231 
232  template <
233  class AdamValueType,
234  class GGValueType,
235  class ControlType
236  >
237  void BindCell(ControlType& control, adobe::name_t cell);
238 
239  adobe::any_regular_t Result();
240 
241 private:
242  void Init(std::istream& stream);
243 
244  adobe::sheet_t m_sheet;
245  std::vector<boost::shared_ptr<AdamCellGlueBase> > m_cells;
246 };
247 
248 
249 // implementations
250 
251 namespace detail {
252  template <class AdobeValueType, class GGValueType>
253  GGValueType AnyCast(const adobe::any_regular_t& any)
254  { return static_cast<GGValueType>(any.cast<AdobeValueType>()); }
255 
256  template <class AdobeValueType, class GGValueType>
257  adobe::any_regular_t MakeAny(GGValueType x)
258  { return adobe::any_regular_t(static_cast<AdobeValueType>(x)); }
259 }
260 
261 
262 // AdamCellGlue<Edit>
263 
264 template <class AdamValueType, class T>
265 AdamCellGlue<Edit, AdamValueType, T>::AdamCellGlue(
266  Edit& edit,
267  adobe::sheet_t& sheet,
268  adobe::name_t cell) :
269  m_edit(&edit),
270  m_sheet(&sheet),
271  m_cell(cell)
272 {
273  m_sheet->monitor_value(m_cell, boost::bind(&ThisType::SheetChanged, this, _1));
274  m_sheet->monitor_enabled(m_cell, 0, 0, boost::bind(&ThisType::Enable, this, _1));
275  m_edit->EditedSignal.connect(boost::bind(&ThisType::ControlChanged, this, _1));
276 }
277 
278 template <class AdamValueType, class T>
279 void AdamCellGlue<Edit, AdamValueType, T>::SheetChanged(const adobe::any_regular_t &any)
280 { *m_edit << detail::AnyCast<AdamValueType, T>(any); }
281 
282 template <class AdamValueType, class T>
283 void AdamCellGlue<Edit, AdamValueType, T>::Enable(bool b)
284 { m_edit->Disable(!b); }
285 
286 template <class AdamValueType, class T>
287 void AdamCellGlue<Edit, AdamValueType, T>::ControlChanged(const std::string& str)
288 {
289  try {
290  T x = boost::lexical_cast<T>(str);
291  m_sheet->set(m_cell, detail::MakeAny<AdamValueType, T>(x));
292  m_sheet->update();
293  } catch (const boost::bad_lexical_cast&) {}
294 }
295 
296 
297 // AdamCellGlue<Spin<T> >
298 
299 template <class T>
300 AdamCellGlue<Spin<T>, double, T>::AdamCellGlue(
301  Spin<T>& spin,
302  adobe::sheet_t& sheet,
303  adobe::name_t cell) :
304  m_spin(&spin),
305  m_sheet(&sheet),
306  m_cell(cell)
307 {
308  m_sheet->monitor_value(m_cell, boost::bind(&ThisType::SheetChanged, this, _1));
309  m_sheet->monitor_enabled(m_cell, 0, 0, boost::bind(&ThisType::Enable, this, _1));
310  m_spin->ValueChangedSignal.connect(boost::bind(&ThisType::ControlChanged, this, _1));
311 }
312 
313 template <class T>
314 void AdamCellGlue<Spin<T>, double, T>::SheetChanged(const adobe::any_regular_t &any)
315 { m_spin->SetValue(detail::AnyCast<double, T>(any)); }
316 
317 template <class T>
318 void AdamCellGlue<Spin<T>, double, T>::Enable(bool b)
319 { m_spin->Disable(!b); }
320 
321 template <class T>
322 void AdamCellGlue<Spin<T>, double, T>::ControlChanged(T t)
323 {
324  m_sheet->set(m_cell, detail::MakeAny<double, T>(t));
325  m_sheet->update();
326 }
327 
328 }
329 
330 #endif