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