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
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
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 }
00732
00733 #endif // _GG_WndEditor_h_