Crazy Eddie's GUI System
0.8.4
|
00001 /*********************************************************************** 00002 created: Sat Oct 8 2005 00003 author: Paul D Turner <paul@cegui.org.uk> 00004 *************************************************************************/ 00005 /*************************************************************************** 00006 * Copyright (C) 2004 - 2010 Paul D Turner & The CEGUI Development Team 00007 * 00008 * Permission is hereby granted, free of charge, to any person obtaining 00009 * a copy of this software and associated documentation files (the 00010 * "Software"), to deal in the Software without restriction, including 00011 * without limitation the rights to use, copy, modify, merge, publish, 00012 * distribute, sublicense, and/or sell copies of the Software, and to 00013 * permit persons to whom the Software is furnished to do so, subject to 00014 * the following conditions: 00015 * 00016 * The above copyright notice and this permission notice shall be 00017 * included in all copies or substantial portions of the Software. 00018 * 00019 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00020 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00021 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00022 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 00023 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00024 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00025 * OTHER DEALINGS IN THE SOFTWARE. 00026 ***************************************************************************/ 00027 #ifndef _CEGUIFalPropertyLinkDefinition_h_ 00028 #define _CEGUIFalPropertyLinkDefinition_h_ 00029 00030 #include "CEGUI/falagard/FalagardPropertyBase.h" 00031 #include "CEGUI/falagard/XMLHandler.h" 00032 #include "CEGUI/IteratorBase.h" 00033 #include <vector> 00034 00035 #if defined (_MSC_VER) 00036 # pragma warning(push) 00037 # pragma warning(disable : 4251) 00038 #endif 00039 00040 namespace CEGUI 00041 { 00042 00048 template <typename T> 00049 class PropertyLinkDefinition : public FalagardPropertyBase<T> 00050 { 00051 public: 00052 //------------------------------------------------------------------------// 00053 typedef typename TypedProperty<T>::Helper Helper; 00054 00055 //------------------------------------------------------------------------// 00056 PropertyLinkDefinition(const String& propertyName, const String& widgetName, 00057 const String& targetProperty, const String& initialValue, 00058 const String& origin, 00059 bool redrawOnWrite, bool layoutOnWrite, 00060 const String& fireEvent, const String& eventNamespace) : 00061 FalagardPropertyBase<T>(propertyName, 00062 Falagard_xmlHandler::PropertyLinkDefinitionHelpDefaultValue, 00063 initialValue, origin, 00064 redrawOnWrite, layoutOnWrite, 00065 fireEvent, eventNamespace) 00066 { 00067 // add initial target if it was specified via constructor 00068 // (typically meaning it came via XML attributes) 00069 if (!widgetName.empty() || !targetProperty.empty()) 00070 addLinkTarget(widgetName, targetProperty); 00071 } 00072 00073 ~PropertyLinkDefinition() {} 00074 00075 //------------------------------------------------------------------------// 00077 void addLinkTarget(const String& widget, const String& property) 00078 { 00079 d_targets.push_back(std::make_pair(widget,property)); 00080 } 00081 00082 //------------------------------------------------------------------------// 00084 void clearLinkTargets() 00085 { 00086 d_targets.clear(); 00087 } 00088 00089 //------------------------------------------------------------------------// 00090 // return whether a the given widget / property pair is a target of this 00091 // property link. 00092 bool isTargetProperty(const String& widget, const String& property) const 00093 { 00094 LinkTargetCollection::const_iterator i = d_targets.begin(); 00095 for (; i != d_targets.end(); ++i) 00096 { 00097 if (property == i->second && widget == i->first) 00098 return true; 00099 } 00100 00101 return false; 00102 } 00103 00104 //------------------------------------------------------------------------// 00105 void initialisePropertyReceiver(PropertyReceiver* receiver) const 00106 { 00107 updateLinkTargets(receiver, Helper::fromString(this->d_default)); 00108 } 00109 00110 //------------------------------------------------------------------------// 00111 Property* clone() const 00112 { 00113 return CEGUI_NEW_AO PropertyLinkDefinition<T>(*this); 00114 } 00115 00116 protected: 00117 // override members from FalagardPropertyBase 00118 //------------------------------------------------------------------------// 00119 typename Helper::safe_method_return_type 00120 getNative_impl(const PropertyReceiver* receiver) const 00121 { 00122 const LinkTargetCollection::const_iterator i(d_targets.begin()); 00123 00124 const Window* const target_wnd = 00125 getTargetWindow(receiver, i->first); 00126 00127 // if no target, or target (currently) invalid, return the default value 00128 if (d_targets.empty() || !target_wnd) 00129 return Helper::fromString(TypedProperty<T>::d_default); 00130 00131 // otherwise return the value of the property for first target, since 00132 // this is considered the 'master' target for get operations. 00133 return Helper::fromString(target_wnd->getProperty(i->second.empty() ? 00134 TypedProperty<T>::d_name : i->second)); 00135 } 00136 00137 //------------------------------------------------------------------------// 00138 void setNative_impl(PropertyReceiver* receiver, 00139 typename Helper::pass_type value) 00140 { 00141 updateLinkTargets(receiver, value); 00142 00143 // base handles things like ensuring redraws and such happen 00144 FalagardPropertyBase<T>::setNative_impl(receiver, value); 00145 } 00146 00147 //------------------------------------------------------------------------// 00148 void updateLinkTargets(PropertyReceiver* receiver, 00149 typename Helper::pass_type value) const 00150 { 00151 LinkTargetCollection::const_iterator i = d_targets.begin(); 00152 for ( ; i != d_targets.end(); ++i) 00153 { 00154 Window* target_wnd = getTargetWindow(receiver, i->first); 00155 00156 // only try to set property if target is currently valid. 00157 if (target_wnd) 00158 target_wnd->setProperty(i->second.empty() ? 00159 TypedProperty<T>::d_name : i->second, Helper::toString(value)); 00160 } 00161 } 00162 00163 //------------------------------------------------------------------------// 00164 void writeDefinitionXMLElementType(XMLSerializer& xml_stream) const 00165 { 00166 xml_stream.openTag(Falagard_xmlHandler::PropertyLinkDefinitionElement); 00167 writeFalagardXMLAttributes(xml_stream); 00168 writeDefinitionXMLAdditionalAttributes(xml_stream); 00169 } 00170 00171 //------------------------------------------------------------------------// 00172 void writeDefinitionXMLAdditionalAttributes(XMLSerializer& xml_stream) const 00173 { 00174 if(FalagardPropertyBase<T>::d_dataType.compare(Falagard_xmlHandler::GenericDataType) != 0) 00175 xml_stream.attribute(Falagard_xmlHandler::TypeAttribute, FalagardPropertyBase<T>::d_dataType); 00176 00177 if (!PropertyDefinitionBase::d_helpString.empty() && PropertyDefinitionBase::d_helpString.compare(CEGUI::Falagard_xmlHandler::PropertyLinkDefinitionHelpDefaultValue) != 0) 00178 xml_stream.attribute(Falagard_xmlHandler::HelpStringAttribute, PropertyDefinitionBase::d_helpString); 00179 } 00180 00181 //------------------------------------------------------------------------// 00182 void writeFalagardXMLAttributes(XMLSerializer& xml_stream) const 00183 { 00184 // HACK: Here we abuse some intimate knowledge in that we know it's 00185 // safe to write our sub-elements out although the function is named 00186 // for writing attributes. The alternative was to repeat code from the 00187 // base class, also demonstrating intimate knowledge ;) 00188 00189 LinkTargetCollection::const_iterator i(d_targets.begin()); 00190 00191 // if there is one target only, write it out as attributes 00192 if (d_targets.size() == 1) 00193 { 00194 if (!i->first.empty()) 00195 xml_stream.attribute(Falagard_xmlHandler::WidgetAttribute, i->first); 00196 00197 if (!i->second.empty()) 00198 xml_stream.attribute(Falagard_xmlHandler::TargetPropertyAttribute, i->second); 00199 } 00200 // we have multiple targets, so write them as PropertyLinkTarget tags 00201 else 00202 { 00203 for ( ; i != d_targets.end(); ++i) 00204 { 00205 xml_stream.openTag(Falagard_xmlHandler::PropertyLinkTargetElement); 00206 00207 if (!i->first.empty()) 00208 xml_stream.attribute(Falagard_xmlHandler::WidgetAttribute, i->first); 00209 00210 if (!i->second.empty()) 00211 xml_stream.attribute(Falagard_xmlHandler::PropertyAttribute, i->second); 00212 00213 xml_stream.closeTag(); 00214 } 00215 } 00216 } 00217 00218 //------------------------------------------------------------------------// 00220 const Window* getTargetWindow(const PropertyReceiver* receiver, 00221 const String& name) const 00222 { 00223 if (name.empty()) 00224 return static_cast<const Window*>(receiver); 00225 00226 // handle link back to parent. Return receiver if no parent. 00227 if (name == Falagard_xmlHandler::ParentIdentifier) 00228 return static_cast<const Window*>(receiver)->getParent(); 00229 00230 return static_cast<const Window*>(receiver)->getChild(name); 00231 } 00232 00233 //------------------------------------------------------------------------// 00235 Window* getTargetWindow(PropertyReceiver* receiver, 00236 const String& name) const 00237 { 00238 return const_cast<Window*>( 00239 getTargetWindow(static_cast<const PropertyReceiver*>(receiver), name)); 00240 } 00241 00242 //------------------------------------------------------------------------// 00243 typedef std::pair<String,String> StringPair; 00245 typedef std::vector<StringPair CEGUI_VECTOR_ALLOC(StringPair)> LinkTargetCollection; 00246 00248 LinkTargetCollection d_targets; 00249 00250 public: 00251 typedef ConstVectorIterator<LinkTargetCollection> LinkTargetIterator; 00252 00253 LinkTargetIterator getLinkTargetIterator() const 00254 { 00255 return LinkTargetIterator(d_targets.begin(),d_targets.end()); 00256 } 00257 }; 00258 00259 } 00260 00261 #if defined (_MSC_VER) 00262 # pragma warning(pop) 00263 #endif 00264 00265 #endif 00266