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 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 // template implementations 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&) { 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 } // namespace GG 00746 00747 #endif // _GG_WndEditor_h_