123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- // Copyright 2019 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef UI_BASE_METADATA_PROPERTY_METADATA_H_
- #define UI_BASE_METADATA_PROPERTY_METADATA_H_
- #include <string>
- #include <type_traits>
- #include <utility>
- #include "base/component_export.h"
- #include "ui/base/class_property.h"
- #include "ui/base/metadata/base_type_conversion.h"
- #include "ui/base/metadata/metadata_cache.h"
- #include "ui/base/metadata/metadata_types.h"
- namespace ui {
- namespace metadata {
- namespace internal {
- template <typename TSource, typename TTarget, typename = void>
- struct DeRefHelper {
- static TTarget Get(TSource value) { return value; }
- };
- template <typename TSource, typename TTarget>
- struct DeRefHelper<
- TSource,
- TTarget,
- typename std::enable_if<!std::is_same<TSource, TTarget>::value>::type> {
- static TTarget Get(TSource value) { return *value; }
- };
- template <typename TKey, typename TValue>
- struct ClassPropertyMetaDataTypeHelper;
- template <typename TKValue_, typename TValue_>
- struct ClassPropertyMetaDataTypeHelper<const ui::ClassProperty<TKValue_>* const,
- TValue_> {
- using TKValue = TKValue_;
- using TValue = TValue_;
- // Returns |value| when |TKValue| == |TValue|. Otherwise, TKValue must be the
- // pointer type to TValue, returns |*value| instead.
- // This is useful for owned propertyies like ui::ClassProperty<gfx::Insets*>
- // where we want to inspect the actual value, rather than the pointer.
- static TValue DeRef(TKValue value) {
- return DeRefHelper<TKValue, TValue>::Get(value);
- }
- };
- // Works around static casting issues related to the void*. See the comment on
- // the METADATA_ACCESSORS_INTERNAL_BASE macro for more information about why
- // this is necessary. NOTE: The reinterpret_cast<> here is merely to bring
- // ReinterpretToBaseClass() into scope and make it callable. The body of that
- // function does not access |this|, so this call is safe.
- template <typename TClass>
- TClass* AsClass(void* obj) {
- return static_cast<TClass*>(
- reinterpret_cast<TClass*>(obj)->ReinterpretToBaseClass(obj));
- }
- } // namespace internal
- // Represents meta data for a specific read-only property member of class
- // |TClass|, with underlying type |TValue|, as the type of the actual member.
- // Using a separate |TRet| type for the getter function's return type to allow
- // it to return a type with qualifier and by reference.
- template <typename TClass,
- typename TValue,
- typename TRet,
- TRet (TClass::*Get)() const,
- typename TConverter = ui::metadata::TypeConverter<TValue>>
- class ObjectPropertyReadOnlyMetaData : public ui::metadata::MemberMetaDataBase {
- public:
- using MemberMetaDataBase::MemberMetaDataBase;
- ObjectPropertyReadOnlyMetaData(const ObjectPropertyReadOnlyMetaData&) =
- delete;
- ObjectPropertyReadOnlyMetaData& operator=(
- const ObjectPropertyReadOnlyMetaData&) = delete;
- ~ObjectPropertyReadOnlyMetaData() override = default;
- std::u16string GetValueAsString(void* obj) const override {
- if (!kTypeIsSerializable && !kTypeIsReadOnly)
- return std::u16string();
- return TConverter::ToString((internal::AsClass<TClass>(obj)->*Get)());
- }
- ui::metadata::PropertyFlags GetPropertyFlags() const override {
- return kTypeIsSerializable ? (ui::metadata::PropertyFlags::kReadOnly |
- ui::metadata::PropertyFlags::kSerializable)
- : ui::metadata::PropertyFlags::kReadOnly;
- }
- const char* GetMemberNamePrefix() const override {
- return TConverter::PropertyNamePrefix();
- }
- private:
- static constexpr bool kTypeIsSerializable = TConverter::is_serializable;
- static constexpr bool kTypeIsReadOnly = TConverter::is_read_only;
- };
- // Represents meta data for a specific property member of class |TClass|, with
- // underlying type |TValue|, as the type of the actual member.
- // Allows for interaction with the property as if it were the underlying data
- // type (|TValue|), but still uses the Property's functionality under the hood
- // (so it will trigger things like property changed notifications).
- template <typename TClass,
- typename TValue,
- typename TSig,
- TSig Set,
- typename TRet,
- TRet (TClass::*Get)() const,
- typename TConverter = ui::metadata::TypeConverter<TValue>>
- class ObjectPropertyMetaData
- : public ObjectPropertyReadOnlyMetaData<TClass,
- TValue,
- TRet,
- Get,
- TConverter> {
- public:
- using ObjectPropertyReadOnlyMetaData<TClass, TValue, TRet, Get, TConverter>::
- ObjectPropertyReadOnlyMetaData;
- ObjectPropertyMetaData(const ObjectPropertyMetaData&) = delete;
- ObjectPropertyMetaData& operator=(const ObjectPropertyMetaData&) = delete;
- ~ObjectPropertyMetaData() override = default;
- void SetValueAsString(void* obj, const std::u16string& new_value) override {
- if (!kTypeIsSerializable || kTypeIsReadOnly)
- return;
- if (absl::optional<TValue> result = TConverter::FromString(new_value)) {
- (internal::AsClass<TClass>(obj)->*Set)(std::move(result.value()));
- }
- }
- ui::metadata::MemberMetaDataBase::ValueStrings GetValidValues()
- const override {
- if (!kTypeIsSerializable)
- return {};
- return TConverter::GetValidStrings();
- }
- ui::metadata::PropertyFlags GetPropertyFlags() const override {
- ui::metadata::PropertyFlags flags = ui::metadata::PropertyFlags::kEmpty;
- if (kTypeIsSerializable)
- flags = flags | ui::metadata::PropertyFlags::kSerializable;
- if (kTypeIsReadOnly)
- flags = flags | ui::metadata::PropertyFlags::kReadOnly;
- return flags;
- }
- private:
- static constexpr bool kTypeIsSerializable = TConverter::is_serializable;
- static constexpr bool kTypeIsReadOnly = TConverter::is_read_only;
- };
- // Represents metadata for a ui::ClassProperty attached on a class instance.
- // Converts property value to |TValue| when possible. This allows inspecting
- // the actual value when the property is a pointer of type |TValue*|.
- template <typename TClass,
- typename TKey,
- typename TValue,
- typename TConverter = ui::metadata::TypeConverter<TValue>>
- class ClassPropertyMetaData : public ui::metadata::MemberMetaDataBase {
- public:
- using TypeHelper = internal::ClassPropertyMetaDataTypeHelper<TKey, TValue>;
- ClassPropertyMetaData(TKey key, const std::string& property_type)
- : MemberMetaDataBase(key->name, property_type), key_(key) {}
- ClassPropertyMetaData(const ClassPropertyMetaData&) = delete;
- ClassPropertyMetaData& operator=(const ClassPropertyMetaData&) = delete;
- ~ClassPropertyMetaData() override = default;
- // Returns the property value as a string.
- // If the property value is an pointer of type |TKValue*| and
- // |TKValue| == |TValue|, dereferences the pointer.
- std::u16string GetValueAsString(void* obj) const override {
- typename TypeHelper::TKValue value =
- internal::AsClass<TClass>(obj)->GetProperty(key_);
- if (std::is_pointer<typename TypeHelper::TKValue>::value && !value) {
- return u"(not assigned)";
- } else {
- // GetProperty() returns a pointer when this is an owned property.
- // If |TValue| is not pointer, DeRef() returns |*value|, otherwise
- // it returns |value| as it is.
- return TConverter::ToString(TypeHelper::DeRef(value));
- }
- }
- void SetValueAsString(void* obj, const std::u16string& new_value) override {
- absl::optional<TValue> value = TConverter::FromString(new_value);
- if (value)
- internal::AsClass<TClass>(obj)->SetProperty(key_, *value);
- }
- ui::metadata::PropertyFlags GetPropertyFlags() const override {
- ui::metadata::PropertyFlags flags = ui::metadata::PropertyFlags::kEmpty;
- if (kTypeIsSerializable)
- flags = flags | ui::metadata::PropertyFlags::kSerializable;
- if (kTypeIsReadOnly)
- flags = flags | ui::metadata::PropertyFlags::kReadOnly;
- return flags;
- }
- private:
- TKey key_;
- static constexpr bool kTypeIsSerializable = TConverter::is_serializable;
- static constexpr bool kTypeIsReadOnly = TConverter::is_read_only;
- };
- } // namespace metadata
- } // namespace ui
- #endif // UI_BASE_METADATA_PROPERTY_METADATA_H_
|