WndEditor.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /* GG is a GUI for SDL and OpenGL.
00003    Copyright (C) 2003 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@hotmail.com */
00025 
00030 #ifndef _GG_WndEditor_h_
00031 #define _GG_WndEditor_h_
00032 
00033 #include <GG/DropDownList.h>
00034 #include <GG/Edit.h>
00035 #include <GG/GUI.h>
00036 #include <GG/ListBox.h>
00037 #include <GG/dialogs/ColorDlg.h>
00038 
00039 #include <boost/type_traits.hpp>
00040 
00041 
00042 namespace GG {
00043 
00044 namespace detail {
00045     GG_API extern const int ATTRIBUTE_ROW_HEIGHT;
00046     GG_API extern const int ATTRIBUTE_ROW_CONTROL_WIDTH;
00047 }
00048 
00049 struct AttributeRowBase;
00050 
00054 template <class T>
00055 struct AttributeChangedAction
00056 {
00057     virtual ~AttributeChangedAction() {}
00058     virtual void operator()(const T& value) {}
00059 };
00060 
00065 class GG_API WndEditor : public Wnd
00066 {
00067 public:
00069     template <class FlagType>
00070     struct FlagsAndAction
00071     {
00072         Flags<FlagType>* m_flags;
00073         boost::shared_ptr<AttributeChangedAction<Flags<FlagType> > > m_action;
00074     };
00075 
00077     WndEditor(int h, const boost::shared_ptr<Font>& font);
00078 
00080     const boost::shared_ptr<Font>& GetFont() const;
00081 
00083     const Wnd* GetWnd() const;
00084 
00085     virtual void Render ();
00086 
00089     void SetWnd(Wnd* wnd, const std::string& name = "");
00090 
00092     void Label(const std::string& name);
00093 
00095     void Attribute(AttributeRowBase* row);
00096 
00098     template <class T>
00099     void Attribute(const std::string& name, T& value,
00100                    const boost::shared_ptr<AttributeChangedAction<T> >& attribute_changed_action);
00101 
00103     template <class T>
00104     void Attribute(const std::string& name, T& value);
00105 
00108     template <class T>
00109     void Attribute(const std::string& name, T& value, const T& min, const T& max,
00110                    const boost::shared_ptr<AttributeChangedAction<T> >& attribute_changed_action);
00111 
00114     template <class T>
00115     void Attribute(const std::string& name, T& value, const T& min, const T& max);
00116 
00118     template <class T>
00119     void ConstAttribute(const std::string& name, const T& value);
00120 
00122     template <class T>
00123     void CustomText(const std::string& name, const T& functor);
00124 
00127     template <class FlagType>
00128     void BeginFlags(Flags<FlagType>& flags,
00129                     const boost::shared_ptr<AttributeChangedAction<Flags<FlagType> > >& attribute_changed_action);
00130 
00133     template <class FlagType>
00134     void BeginFlags(Flags<FlagType>& flags);
00135 
00137     template <class FlagType>
00138     void Flag(const std::string& name, FlagType flag);
00139 
00142     template <class FlagType>
00143     void FlagGroup(const std::string& name, const std::vector<FlagType>& group_values);
00144 
00146     void EndFlags();
00147 
00148     mutable boost::signal<void (Wnd*, const std::string&)> WndNameChangedSignal; 
00149     mutable boost::signal<void (Wnd*)> WndChangedSignal; 
00150 
00151 private:
00152     void Init();
00153     void AttributeChangedSlot();
00154     void NameChangedSlot(const std::string& name);
00155 
00156     Wnd* m_wnd;
00157     ListBox* m_list_box;
00158     boost::shared_ptr<Font> m_font;
00159     boost::shared_ptr<Font> m_label_font;
00160     boost::any m_current_flags_and_action;
00161 };
00162 
00165 struct GG_API AttributeRowBase : ListBox::Row
00166 {
00167     virtual void Refresh(); 
00168     virtual void Update();  
00169     mutable boost::signal<void ()> ChangedSignal; 
00170 };
00171 
00173 template <class T>
00174 struct AttributeRow : AttributeRowBase
00175 {
00176     AttributeRow(const std::string& name, T& value, const boost::shared_ptr<Font>& font);
00177     virtual void Update();
00178     mutable boost::signal<void (const T&)> ValueChangedSignal; 
00179 private:
00180     void TextChanged(const std::string& value_text);
00181     T& m_value;
00182     Edit* m_edit;
00183     boost::signals::connection m_edit_connection;
00184 };
00185 
00187 template <>
00188 struct GG_API AttributeRow<Pt> : AttributeRowBase
00189 {
00190     AttributeRow(const std::string& name, Pt& value, const boost::shared_ptr<Font>& font);
00191     virtual void Update();
00192     mutable boost::signal<void (const Pt&)> ValueChangedSignal; 
00193 private:
00194     Pt& m_value;
00195     Edit* m_x_edit;
00196     Edit* m_y_edit;
00197     boost::signals::connection m_x_connection;
00198     boost::signals::connection m_y_connection;
00199 };
00200 
00202 template <>
00203 struct GG_API AttributeRow<Clr> : AttributeRowBase
00204 {
00205     AttributeRow(const std::string& name, Clr& value, const boost::shared_ptr<Font>& font);
00206     virtual void Update();
00207     mutable boost::signal<void (const Clr&)> ValueChangedSignal; 
00208 private:
00209     void ColorButtonClicked();
00210     Clr& m_value;
00211     ColorDlg::ColorButton* m_color_button;
00212     boost::shared_ptr<Font> m_font;
00213 };
00214 
00216 template <>
00217 struct GG_API AttributeRow<bool> : AttributeRowBase
00218 {
00219     AttributeRow(const std::string& name, bool& value, const boost::shared_ptr<Font>& font);
00220     virtual void Update();
00221     mutable boost::signal<void (const bool&)> ValueChangedSignal; 
00222 private:
00223     void SelectionChanged(int selection);
00224     bool& m_value;
00225     RadioButtonGroup* m_radio_button_group;
00226     boost::signals::connection m_button_group_connection;
00227 };
00228 
00230 template <>
00231 struct GG_API AttributeRow<boost::shared_ptr<Font> > : AttributeRowBase
00232 {
00233     AttributeRow(const std::string& name, boost::shared_ptr<Font>& value, const boost::shared_ptr<Font>& font);
00234     virtual void Update();
00235     mutable boost::signal<void (const boost::shared_ptr<Font>&)> ValueChangedSignal; 
00236 private:
00237     void FilenameChanged(const std::string& filename_text);
00238     void PointsChanged(const std::string& points_text);
00239     boost::shared_ptr<Font>& m_value;
00240     Edit* m_filename_edit;
00241     Edit* m_points_edit;
00242     boost::signals::connection m_filename_connection;
00243     boost::signals::connection m_points_connection;
00244 };
00245 
00249 template <class T, bool is_enum = boost::is_enum<T>::value>
00250 struct RangedAttributeRow : AttributeRowBase
00251 {
00252     RangedAttributeRow(const std::string& name, T& value, const T& min, const T& max, const boost::shared_ptr<Font>& font);
00253     virtual void Update();
00254     mutable boost::signal<void (const T&)> ValueChangedSignal; 
00255 private:
00256     void TextChanged(const std::string& value_text);
00257     T& m_value;
00258     T m_min;
00259     T m_max;
00260     Edit* m_edit;
00261     boost::signals::connection m_edit_connection;
00262 };
00263 
00265 template <class T>
00266 struct RangedAttributeRow<T, true> : AttributeRowBase
00267 {
00268     RangedAttributeRow(const std::string& name, T& value, const T& min, const T& max, const boost::shared_ptr<Font>& font);
00269     virtual void Update();
00270     mutable boost::signal<void (const T&)> ValueChangedSignal; 
00271 private:
00272     void SelectionChanged(int selection);
00273     T& m_value;
00274     T m_min;
00275     DropDownList* m_enum_drop_list;
00276     boost::signals::connection m_drop_list_connection;
00277 };
00278 
00280 template <class T>
00281 struct ConstAttributeRow : AttributeRowBase
00282 {
00283     ConstAttributeRow(const std::string& name, const T& value, const boost::shared_ptr<Font>& font);
00284     virtual void Refresh();
00285 private:
00286     const T& m_value;
00287     TextControl* m_value_text;
00288 };
00289 
00291 template <>
00292 struct GG_API ConstAttributeRow<Pt> : AttributeRowBase
00293 {
00294     ConstAttributeRow(const std::string& name, const Pt& value, const boost::shared_ptr<Font>& font);
00295     virtual void Refresh();
00296 private:
00297     const Pt& m_value;
00298     TextControl* m_value_text;
00299 };
00300 
00302 template <>
00303 struct GG_API ConstAttributeRow<Clr> : AttributeRowBase
00304 {
00305     ConstAttributeRow(const std::string& name, const Clr& value, const boost::shared_ptr<Font>& font);
00306     virtual void Refresh();
00307 private:
00308     const Clr& m_value;
00309     TextControl* m_value_text;
00310 };
00311 
00313 template <class FlagType>
00314 struct FlagAttributeRow : AttributeRowBase
00315 {
00318     FlagAttributeRow(const std::string& name, Flags<FlagType>& flags, FlagType value, const boost::shared_ptr<Font>& font);
00319     virtual void Update();
00320     mutable boost::signal<void (const Flags<FlagType>&)> ValueChangedSignal; 
00321 private:
00322     void CheckChanged(bool checked);
00323     Flags<FlagType>& m_flags;
00324     FlagType m_value;
00325     StateButton* m_check_box;
00326     boost::signals::connection m_check_box_connection;
00327 };
00328 
00331 template <class FlagType>
00332 struct FlagGroupAttributeRow : AttributeRowBase
00333 {
00336     FlagGroupAttributeRow(const std::string& name, Flags<FlagType>& flags, FlagType value, const std::vector<FlagType>& group_values, const boost::shared_ptr<Font>& font);
00337     virtual void Update();
00338     mutable boost::signal<void (const Flags<FlagType>&)> ValueChangedSignal; 
00339 private:
00340     void SelectionChanged(int selection);
00341     Flags<FlagType>& m_flags;
00342     FlagType m_value;
00343     std::vector<FlagType> m_group_values;
00344     DropDownList* m_flag_drop_list;
00345     boost::signals::connection m_drop_list_connection;
00346 };
00347 
00353 template <class T>
00354 struct CustomTextRow : AttributeRowBase
00355 {
00356     CustomTextRow(const std::string& name, const T& functor, const Wnd*& wnd, const boost::shared_ptr<Font>& font);
00357     virtual void Refresh();
00358 private:
00359     T m_functor;
00360     const Wnd*& m_wnd;
00361     TextControl* m_display_text;
00362 };
00363 
00364 
00365 // template implementations
00366 template <class T>
00367 void WndEditor::Attribute(const std::string& name, T& value,
00368                           const boost::shared_ptr<AttributeChangedAction<T> >& attribute_changed_action)
00369 {
00370     AttributeRow<T>* attribute = new AttributeRow<T>(name, value, m_font);
00371     m_list_box->Insert(attribute);
00372     if (attribute_changed_action)
00373         Connect(attribute->ValueChangedSignal, &AttributeChangedAction<T>::operator(), attribute_changed_action);
00374     Connect(attribute->ChangedSignal, &WndEditor::AttributeChangedSlot, this);
00375 }
00376 
00377 template <class T>
00378 void WndEditor::Attribute(const std::string& name, T& value)
00379 {
00380     AttributeRow<T>* attribute = new AttributeRow<T>(name, value, m_font);
00381     m_list_box->Insert(attribute);
00382     Connect(attribute->ChangedSignal, &WndEditor::AttributeChangedSlot, this);
00383 }
00384 
00385 template <class T>
00386 void WndEditor::Attribute(const std::string& name, T& value, const T& min, const T& max,
00387                           const boost::shared_ptr<AttributeChangedAction<T> >& attribute_changed_action)
00388 {
00389     RangedAttributeRow<T>* attribute = new RangedAttributeRow<T>(name, value, min, max, m_font);
00390     m_list_box->Insert(attribute);
00391     if (attribute_changed_action)
00392         Connect(attribute->ValueChangedSignal, &AttributeChangedAction<T>::operator(), attribute_changed_action);
00393     Connect(attribute->ChangedSignal, &WndEditor::AttributeChangedSlot, this);
00394 }
00395 
00396 template <class T>
00397 void WndEditor::Attribute(const std::string& name, T& value, const T& min, const T& max)
00398 {
00399     RangedAttributeRow<T>* attribute = new RangedAttributeRow<T>(name, value, min, max, m_font);
00400     m_list_box->Insert(attribute);
00401     Connect(attribute->ChangedSignal, &WndEditor::AttributeChangedSlot, this);
00402 }
00403 
00404 template <class T>
00405 void WndEditor::ConstAttribute(const std::string& name, const T& value)
00406 {
00407     ConstAttributeRow<T>* attribute = new ConstAttributeRow<T>(name, value, m_font);
00408     m_list_box->Insert(attribute);
00409 }
00410 
00411 template <class T>
00412 void WndEditor::CustomText(const std::string& name, const T& functor)
00413 {
00414     CustomTextRow<T>* display_row = new CustomTextRow<T>(name, functor, const_cast<const Wnd*&>(m_wnd), m_font);
00415     m_list_box->Insert(display_row);
00416 }
00417 
00418 template <class FlagType>
00419 void WndEditor::BeginFlags(Flags<FlagType>& flags,
00420                            const boost::shared_ptr<AttributeChangedAction<Flags<FlagType> > >& attribute_changed_action)
00421 {
00422     FlagsAndAction<FlagType> flags_and_action;
00423     flags_and_action.m_flags = &flags;
00424     flags_and_action.m_action = attribute_changed_action;
00425     m_current_flags_and_action = flags_and_action;
00426 }
00427 
00428 
00429 template <class FlagType>
00430 void WndEditor::BeginFlags(Flags<FlagType>& flags)
00431 {
00432     FlagsAndAction<FlagType> flags_and_action;
00433     flags_and_action.m_flags = &flags;
00434     m_current_flags_and_action = flags_and_action;
00435 }
00436 
00437 template <class FlagType>
00438 void WndEditor::Flag(const std::string& name, FlagType flag)
00439 {
00440     if (m_current_flags_and_action.empty()) {
00441         throw std::runtime_error("WndEditor::Flag() : Attempted to create a flag outside of a BeginFlags()/EndFlags() "
00442                                  "block.");
00443     }
00444     FlagsAndAction<FlagType> flags_and_action;
00445     try {
00446         flags_and_action = boost::any_cast<FlagsAndAction<FlagType> >(m_current_flags_and_action);
00447     } catch (const boost::bad_any_cast&) {
00448         throw std::runtime_error("WndEditor::Flag() : Attempted to initialize a flag group from a set of flags "
00449                                  "of a type that does not match the most recent call to BeginFlags().");
00450     }
00451     FlagAttributeRow<FlagType>* flag_attribute = new FlagAttributeRow<FlagType>(name, *flags_and_action.m_flags, flag, m_font);
00452     m_list_box->Insert(flag_attribute);
00453     if (flags_and_action.m_action)
00454         Connect(flag_attribute->ValueChangedSignal, &AttributeChangedAction<Flags<FlagType> >::operator(), flags_and_action.m_action);
00455     Connect(flag_attribute->ChangedSignal, &WndEditor::AttributeChangedSlot, this);
00456 }
00457 
00458 template <class FlagType>
00459 void WndEditor::FlagGroup(const std::string& name, const std::vector<FlagType>& group_values)
00460 {
00461     if (m_current_flags_and_action.empty()) {
00462         throw std::runtime_error("WndEditor::FlagGroup() : Attempted to create a flag group outside of a BeginFlags()/"
00463                                  "EndFlags() block.");
00464     }
00465     FlagsAndAction<FlagType> flags_and_action;
00466     try {
00467         flags_and_action = boost::any_cast<FlagsAndAction<FlagType> >(m_current_flags_and_action);
00468     } catch (const boost::bad_any_cast&) {
00469         throw std::runtime_error("WndEditor::FlagGroup() : Attempted to initialize a flag group from a set of flags "
00470                                  "of a type that does not match the type of the flags given to the most recent call "
00471                                  "to BeginFlags().");
00472     }
00473     if (group_values.empty()) {
00474         throw std::runtime_error("WndEditor::FlagGroup() : Attempted to initialize a flag group from a n empty set of flags.");
00475     }
00476     bool value_found = false;
00477     FlagType value;
00478     for (unsigned int i = 0; i < group_values.size(); ++i) {
00479         if (*flags_and_action.m_flags & group_values[i]) {
00480             value = group_values[i];
00481             value_found = true;
00482             break;
00483         }
00484     }
00485     FlagGroupAttributeRow<FlagType>* flag_group = new FlagGroupAttributeRow<FlagType>(name, *flags_and_action.m_flags, value, group_values, m_font);
00486     m_list_box->Insert(flag_group);
00487     if (flags_and_action.m_action)
00488         Connect(flag_group->ValueChangedSignal, &AttributeChangedAction<Flags<FlagType> >::operator(), flags_and_action.m_action);
00489     Connect(flag_group->ChangedSignal, &WndEditor::AttributeChangedSlot, this);
00490 }
00491 
00492 template <class T>
00493 AttributeRow<T>::AttributeRow(const std::string& name, T& value, const boost::shared_ptr<Font>& font) :
00494     m_value(value),
00495     m_edit(0)
00496 {
00497     push_back(CreateControl(name, font, CLR_BLACK));
00498     m_edit = new Edit(0, 0, 1, "", font, CLR_GRAY, CLR_BLACK, CLR_WHITE);
00499     m_edit->Resize(Pt(detail::ATTRIBUTE_ROW_CONTROL_WIDTH, m_edit->Height()));
00500     Resize(m_edit->Size());
00501     push_back(m_edit);
00502     *m_edit << value;
00503     m_edit_connection = Connect(m_edit->FocusUpdateSignal, &AttributeRow::TextChanged, this);
00504 }
00505 
00506 template <class T>
00507 void AttributeRow<T>::TextChanged(const std::string& value_text)
00508 {
00509     try {
00510         T value = boost::lexical_cast<T>(value_text);
00511         m_value = value;
00512         m_edit->SetTextColor(CLR_BLACK);
00513         ValueChangedSignal(m_value);
00514         ChangedSignal();
00515     } catch (const boost::bad_lexical_cast& e) {
00516         m_edit->SetTextColor(CLR_RED);
00517     }
00518 }
00519 
00520 template <class T>
00521 void AttributeRow<T>::Update()
00522 {
00523     m_edit_connection.block();
00524     *m_edit << m_value;
00525     m_edit_connection.unblock();
00526 }
00527 
00528 template <class T, bool is_enum>
00529 RangedAttributeRow<T, is_enum>::RangedAttributeRow(const std::string& name, T& value, const T& min, const T& max, const boost::shared_ptr<Font>& font) :
00530     m_value(value),
00531     m_min(min),
00532     m_max(max),
00533     m_edit(0)
00534 {
00535     push_back(CreateControl(name, font, CLR_BLACK));
00536     m_edit = new Edit(0, 0, 1, "", font, CLR_GRAY, CLR_BLACK, CLR_WHITE);
00537     m_edit->Resize(Pt(detail::ATTRIBUTE_ROW_CONTROL_WIDTH, m_edit->Height()));
00538     Resize(m_edit->Size());
00539     push_back(m_edit);
00540     *m_edit << value;
00541     m_edit_connection = Connect(m_edit->FocusUpdateSignal, &RangedAttributeRow::TextChanged, this);
00542 }
00543 
00544 template <class T, bool is_enum>
00545 void RangedAttributeRow<T, is_enum>::TextChanged(const std::string& value_text)
00546 {
00547     try {
00548         T value = boost::lexical_cast<T>(value_text);
00549         if (value < m_min || m_max < value)
00550             throw boost::bad_lexical_cast();
00551         m_value = value;
00552         m_edit->SetTextColor(CLR_BLACK);
00553         ValueChangedSignal(m_value);
00554         ChangedSignal();
00555     } catch (const boost::bad_lexical_cast& e) {
00556         m_edit->SetTextColor(CLR_RED);
00557     }
00558 }
00559 
00560 template <class T, bool is_enum>
00561 void RangedAttributeRow<T, is_enum>::Update()
00562 {
00563     m_edit_connection.block();
00564     *m_edit << m_value;
00565     m_edit_connection.unblock();
00566 }
00567 
00568 template <class T>
00569 RangedAttributeRow<T, true>::RangedAttributeRow(const std::string& name, T& value, const T& min, const T& max, const boost::shared_ptr<Font>& font) :
00570     m_value(value),
00571     m_min(min),
00572     m_enum_drop_list(0)
00573 {
00574     push_back(CreateControl(name, font, CLR_BLACK));
00575     m_enum_drop_list = new DropDownList(0, 0, detail::ATTRIBUTE_ROW_CONTROL_WIDTH, detail::ATTRIBUTE_ROW_HEIGHT, detail::ATTRIBUTE_ROW_HEIGHT * (max - min + 1) + 4, CLR_GRAY);
00576     m_enum_drop_list->SetInteriorColor(CLR_WHITE);
00577     m_enum_drop_list->SetStyle(LIST_NOSORT);
00578     for (T i = min; i <= max; i = T(i + 1)) {
00579         Row* row = new ListBox::Row();
00580         std::string enum_label = boost::lexical_cast<std::string>(i);
00581         std::string::size_type pos = enum_label.find_last_of(':');
00582         if (pos != std::string::npos) {
00583             ++pos;
00584             enum_label = enum_label.substr(pos);
00585         }
00586         row->push_back(CreateControl(enum_label, font, CLR_BLACK));
00587         m_enum_drop_list->Insert(row);
00588     }
00589     push_back(m_enum_drop_list);
00590     m_enum_drop_list->Select(m_value - m_min);
00591     m_drop_list_connection = Connect(m_enum_drop_list->SelChangedSignal, &RangedAttributeRow::SelectionChanged, this);
00592 }
00593 
00594 template <class T>
00595 void RangedAttributeRow<T, true>::SelectionChanged(int selection)
00596 {
00597     m_value = T(m_min + selection);
00598     ValueChangedSignal(m_value);
00599     ChangedSignal();
00600 }
00601 
00602 template <class T>
00603 void RangedAttributeRow<T, true>::Update()
00604 {
00605     m_drop_list_connection.block();
00606     m_enum_drop_list->Select(m_value - m_min);
00607     m_drop_list_connection.unblock();
00608 }
00609 
00610 template <class T>
00611 ConstAttributeRow<T>::ConstAttributeRow(const std::string& name, const T& value, const boost::shared_ptr<Font>& font) :
00612     m_value(value),
00613     m_value_text(0)
00614 {
00615     push_back(CreateControl(name, font, CLR_BLACK));
00616     m_value_text = new TextControl(0, 0, detail::ATTRIBUTE_ROW_CONTROL_WIDTH, detail::ATTRIBUTE_ROW_HEIGHT, boost::lexical_cast<std::string>(m_value), font, CLR_BLACK, FORMAT_LEFT);
00617     push_back(m_value_text);
00618 }
00619 
00620 template <class T>
00621 void ConstAttributeRow<T>::Refresh()
00622 {
00623     m_value_text->SetText(boost::lexical_cast<std::string>(m_value));
00624 }
00625 
00626 template <class FlagType>
00627 FlagAttributeRow<FlagType>::FlagAttributeRow(const std::string& name, Flags<FlagType>& flags, FlagType value, const boost::shared_ptr<Font>& font) :
00628     m_flags(flags),
00629     m_value(value),
00630     m_check_box(0)
00631 {
00632     boost::shared_ptr<Font> font_to_use = GUI::GetGUI()->GetFont(font->FontName(), font->PointSize() + 2);
00633     push_back(CreateControl(name, font, CLR_BLACK));
00634     m_check_box = new StateButton(0, 0, detail::ATTRIBUTE_ROW_CONTROL_WIDTH, detail::ATTRIBUTE_ROW_HEIGHT, "", font_to_use, FORMAT_LEFT, CLR_GRAY);
00635     m_check_box->SetCheck(m_flags & m_value);
00636     push_back(m_check_box);
00637     m_check_box_connection = Connect(m_check_box->CheckedSignal, &FlagAttributeRow::CheckChanged, this);
00638 }
00639 
00640 template <class FlagType>
00641 void FlagAttributeRow<FlagType>::CheckChanged(bool checked)
00642 {
00643     if (checked)
00644         m_flags |= m_value;
00645     else
00646         m_flags &= ~m_value;
00647     ValueChangedSignal(m_flags);
00648     ChangedSignal();
00649 }
00650 
00651 template <class FlagType>
00652 void FlagAttributeRow<FlagType>::Update()
00653 {
00654     m_check_box_connection.block();
00655     m_check_box->SetCheck(m_flags & m_value);
00656     m_check_box_connection.unblock();
00657 }
00658 
00659 template <class FlagType>
00660 FlagGroupAttributeRow<FlagType>::FlagGroupAttributeRow(const std::string& name, Flags<FlagType>& flags, FlagType value, const std::vector<FlagType>& group_values, const boost::shared_ptr<Font>& font) :
00661     m_flags(flags),
00662     m_value(value),
00663     m_group_values(group_values),
00664     m_flag_drop_list(0)
00665 {
00666     push_back(CreateControl(name, font, CLR_BLACK));
00667     m_flag_drop_list = new DropDownList(0, 0, detail::ATTRIBUTE_ROW_CONTROL_WIDTH, font->Height() + 8, detail::ATTRIBUTE_ROW_HEIGHT * static_cast<int>(m_group_values.size()) + 4, CLR_GRAY);
00668     Resize(m_flag_drop_list->Size());
00669     m_flag_drop_list->SetInteriorColor(CLR_WHITE);
00670     m_flag_drop_list->SetStyle(LIST_NOSORT);
00671     for (unsigned int i = 0; i < m_group_values.size(); ++i) {
00672         Row* row = new ListBox::Row();
00673         row->push_back(CreateControl(boost::lexical_cast<std::string>(m_group_values[i]), font, CLR_BLACK));
00674         m_flag_drop_list->Insert(row);
00675     }
00676     push_back(m_flag_drop_list);
00677     unsigned int index = 0;
00678     for (; index < m_group_values.size(); ++index) {
00679         if (m_group_values[index] == value)
00680             break;
00681     }
00682     if (index == m_group_values.size()) {
00683         throw std::runtime_error("FlagGroupAttributeRow::FlagGroupAttributeRow() : Attempted to initialize a "
00684                                  "flag group's drop-down list with a value that is not in the given set of group values.");
00685     }
00686     m_flag_drop_list->Select(index);
00687     m_drop_list_connection = Connect(m_flag_drop_list->SelChangedSignal, &FlagGroupAttributeRow::SelectionChanged, this);
00688 }
00689 
00690 template <class FlagType>
00691 void FlagGroupAttributeRow<FlagType>::SelectionChanged(int selection)
00692 {
00693     m_flags &= ~m_value;
00694     m_value = m_group_values[selection];
00695     m_flags |= m_value;
00696     ValueChangedSignal(m_flags);
00697     ChangedSignal();
00698 }
00699 
00700 template <class FlagType>
00701 void FlagGroupAttributeRow<FlagType>::Update()
00702 {
00703     m_drop_list_connection.block();
00704     unsigned int index = 0;
00705     for (; index < m_group_values.size(); ++index) {
00706         if (m_group_values[index] == m_value)
00707             break;
00708     }
00709     m_flag_drop_list->Select(index);
00710     m_drop_list_connection.unblock();
00711 }
00712 
00713 template <class T>
00714 CustomTextRow<T>::CustomTextRow(const std::string& name, const T& functor, const Wnd*& wnd, const boost::shared_ptr<Font>& font) :
00715     m_functor(functor),
00716     m_wnd(wnd),
00717     m_display_text(0)
00718 {
00719     push_back(CreateControl(name, font, CLR_BLACK));
00720     m_display_text = new TextControl(0, 0, detail::ATTRIBUTE_ROW_CONTROL_WIDTH, detail::ATTRIBUTE_ROW_HEIGHT, m_functor(m_wnd), font, CLR_BLACK, FORMAT_LEFT);
00721     Resize(m_display_text->Size());
00722     push_back(m_display_text);
00723 }
00724 
00725 template <class T>
00726 void CustomTextRow<T>::Refresh()
00727 {
00728     m_display_text->SetText(m_functor(m_wnd));
00729 }
00730 
00731 } // namespace GG
00732 
00733 #endif // _GG_WndEditor_h_

Generated on Wed Mar 26 14:35:42 2008 for GG by  doxygen 1.5.2