// Copyright 2017 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef UI_BASE_CLASS_PROPERTY_H_ #define UI_BASE_CLASS_PROPERTY_H_ #include <stdint.h> #include <cstring> #include <map> #include <memory> #include <set> #include <type_traits> #include "base/component_export.h" #include "base/time/time.h" #include "ui/base/ui_base_types.h" // This header should be included by code that defines ClassProperties. // // To define a new ClassProperty: // // #include "foo/foo_export.h" // #include "ui/base/class_property.h" // // DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(FOO_EXPORT, MyType) // namespace foo { // // Use this to define an exported property that is primitive, // // or a pointer you don't want automatically deleted. // DEFINE_UI_CLASS_PROPERTY_KEY(MyType, kMyKey, MyDefault) // // // Use this to define an exported property whose value is a heap // // allocated object, and has to be owned and freed by the class. // DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(gfx::Rect, kRestoreBoundsKey, nullptr) // // } // foo namespace // // To define a new type used for ClassProperty. // // // outside all namespaces: // DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(FOO_EXPORT, MyType) // // If a property type is not exported, use // DEFINE_UI_CLASS_PROPERTY_TYPE(MyType) which is a shorthand for // DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(, MyType). // // If the properties are used outside the file where they are defined // their accessor methods should also be declared in a suitable header // using DECLARE_EXPORTED_UI_CLASS_PROPERTY_TYPE(FOO_EXPORT, MyType) // // Cascading properties: // // Use the DEFINE_CASCADING_XXX macros to create a class property type that // will automatically search up an instance hierarchy for the first defined // property. This only affects the GetProperty() call. SetProperty() will // still explicitly set the value on the given instance. This is useful for // hierarchies of instances which a single set property can effect a whole sub- // tree of instances. // // In order to use this feature, you must override GetParentHandler() on the // class that inherits PropertyHandler. namespace ui { // Type of a function to delete a property that this window owns. PropertyDeallocator; template<typename T> struct ClassProperty { … }; namespace subtle { class PropertyHelper; } class COMPONENT_EXPORT(UI_BASE) PropertyHandler { … }; // No single new-style cast works for every conversion to/from int64_t, so we // need this helper class. template<typename T> class ClassPropertyCaster { … }; ClassPropertyCaster<T *>; template <> class ClassPropertyCaster<base::TimeDelta> { … }; template <> class ClassPropertyCaster<float> { … }; namespace subtle { class COMPONENT_EXPORT(UI_BASE) PropertyHelper { … }; } // namespace subtle // Template implementation is necessary in the .h file unless we want to break // [DECLARE|DEFINE]_EXPORTED_UI_CLASS_PROPERTY_TYPE() below into different // macros for owned and unowned properties; implementing them as pure templates // makes them nearly impossible to implement or use incorrectly at the cost of a // small amount of code duplication across libraries. template <typename T> void PropertyHandler::SetProperty(const ClassProperty<T*>* property, const T& value) { … } template <typename T> void PropertyHandler::SetProperty(const ClassProperty<T*>* property, T&& value) { … } template <typename T> T* PropertyHandler::SetProperty(const ClassProperty<T*>* property, std::unique_ptr<T> value) { … } } // namespace ui // Macros to declare the property getter/setter template functions. #define DECLARE_EXPORTED_UI_CLASS_PROPERTY_TYPE(EXPORT, T) … // Macros to instantiate the property getter/setter template functions. #define DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(EXPORT, T) … #define DEFINE_UI_CLASS_PROPERTY_TYPE(T) … #define DEFINE_UI_CLASS_PROPERTY_KEY(TYPE, NAME, DEFAULT) … #define DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(TYPE, NAME, DEFAULT) … #define DEFINE_CASCADING_UI_CLASS_PROPERTY_KEY(TYPE, NAME, DEFAULT) … #define DEFINE_CASCADING_OWNED_UI_CLASS_PROPERTY_KEY(TYPE, NAME, DEFAULT) … #endif // UI_BASE_CLASS_PROPERTY_H_