// Copyright 2020 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_VIEWS_METADATA_VIEW_FACTORY_H_ #define UI_VIEWS_METADATA_VIEW_FACTORY_H_ #include <functional> #include <map> #include <memory> #include <optional> #include <string_view> #include <utility> #include <vector> #include "base/functional/bind.h" #include "base/macros/concat.h" #include "base/memory/raw_ptr.h" #include "ui/base/class_property.h" #include "ui/base/metadata/base_type_conversion.h" #include "ui/views/metadata/view_factory_internal.h" #include "ui/views/views_export.h" namespace views { template <typename Builder> class BaseViewBuilderT : public internal::ViewBuilderCore { … }; } // namespace views // Example of builder class generated by the following macros. // // template <typename Builder, typename ViewClass> // class ViewBuilderT : public BaseViewBuilderT<Builder, ViewClass> { // public: // ViewBuilderT() = default; // ViewBuilderT(const ViewBuilderT&&) = default; // ViewBuilderT& operator=(const ViewBuilderT&&) = default; // ~ViewBuilderT() override = default; // // Builder& SetEnabled(bool value) { // auto setter = std::make_unique< // PropertySetter<ViewClass, bool, decltype(&ViewClass::SetEnabled), // &ViewClass::SetEnabled>>(value); // ViewBuilderCore::AddPropertySetter(std::move(setter)); // return *static_cast<Builder*>(this); // } // // Builder& SetVisible(bool value) { // auto setter = std::make_unique< // PropertySetter<ViewClass, bool, &ViewClass::SetVisible>>(value); // ViewBuilderCore::AddPropertySetter(std::move(setter)); // return *static_cast<Builder*>(this); // } // }; // // class VIEWS_EXPORT ViewBuilderTest // : public ViewBuilderT<ViewBuilderTest, View> {}; // // template <typename Builder, typename ViewClass> // class LabelButtonBuilderT : public ViewBuilderT<Builder, ViewClass> { // public: // LabelButtonBuilderT() = default; // LabelButtonBuilderT(LabelButtonBuilderT&&) = default; // LabelButtonBuilderT& operator=(LabelButtonBuilderT&&) = default; // ~LabelButtonBuilderT() override = default; // // Builder& SetIsDefault(bool value) { // auto setter = std::make_unique< // PropertySetter<ViewClass, bool, decltype(&ViewClass::SetIsDefault), // &ViewClass::SetIsDefault>>(value); // ViewBuilderCore::AddPropertySetter(std::move(setter)); // return *static_cast<Builder*>(this); // } // }; // // class VIEWS_EXPORT LabelButtonBuilder // : public LabelButtonBuilderT<LabelButtonBuilder, LabelButton> {}; // The maximum number of overloaded params is 10. This should be overkill since // a function with 10 params is well into the "suspect" territory anyway. // TODO(kylixrd@): Evaluate whether a max of 5 may be more reasonable. #define NUM_ARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) … #define NUM_ARGS(...) … // This will expand the list of types into a parameter declaration list. // eg: DECL_PARAMS(int, char, float, double) will expand to: // int param4, char param3, float param2, double param1 #define DECL_PARAM1(type) … #define DECL_PARAM2(type, ...) … #define DECL_PARAM3(type, ...) … #define DECL_PARAM4(type, ...) … #define DECL_PARAM5(type, ...) … #define DECL_PARAM6(type, ...) … #define DECL_PARAM7(type, ...) … #define DECL_PARAM8(type, ...) … #define DECL_PARAM9(type, ...) … #define DECL_PARAM10(type, ...) … #define DECL_PARAMS(...) … // This will expand into list of parameters suitable for calling a function // using the same param names from the above expansion. // eg: PASS_PARAMS(int, char, float, double) // param4, param3, param2, param1 #define PASS_PARAM1(type) … #define PASS_PARAM2(type, ...) … #define PASS_PARAM3(type, ...) … #define PASS_PARAM4(type, ...) … #define PASS_PARAM5(type, ...) … #define PASS_PARAM6(type, ...) … #define PASS_PARAM7(type, ...) … #define PASS_PARAM8(type, ...) … #define PASS_PARAM9(type, ...) … #define PASS_PARAM10(type, ...) … #define PASS_PARAMS(...) … // BEGIN_VIEW_BUILDER, END_VIEW_BUILDER and VIEW_BUILDER_XXXX macros should // be placed into the same namespace as the 'view_class' parameter. #define BEGIN_VIEW_BUILDER(export, view_class, ancestor) … #define VIEW_BUILDER_PROPERTY2(property_type, property_name) … #define VIEW_BUILDER_PROPERTY3(property_type, property_name, field_type) … #define GET_VB_MACRO(_1, _2, _3, macro_name, ...) … #define VIEW_BUILDER_PROPERTY(...) … // Sometimes the method being called is on the ancestor to ViewClass_. This // macro will ensure the overload casts function correctly by specifying the // ancestor class on which the method is declared. In most cases the following // macro will be used. // NOTE: See the Builder declaration for DialogDelegateView in dialog_delegate.h // for an example. #define VIEW_BUILDER_OVERLOAD_METHOD_CLASS(class_name, method_name, ...) … // Unless the above scenario is in play, please favor the use of this macro for // declaring overloaded builder methods. #define VIEW_BUILDER_OVERLOAD_METHOD(method_name, ...) … #define VIEW_BUILDER_METHOD(method_name, ...) … // Enables exposing a template or ambiguously-named method by providing an alias // that will be used on the Builder. // // Examples: // // VIEW_BUILDER_METHOD_ALIAS( // AddTab, AddTab<View>, std::string_view, unique_ptr<View>) // // VIEW_BUILDER_METHOD_ALIAS(UnambiguousName, AmbiguousName, int) // #define VIEW_BUILDER_METHOD_ALIAS(builder_method, view_method, ...) … #define VIEW_BUILDER_VIEW_TYPE_PROPERTY(property_type, property_name) … #define VIEW_BUILDER_VIEW_PROPERTY(property_type, property_name) … #define VIEW_BUILDER_PROPERTY_DEFAULT(property_type, property_name, default) … // Turn off clang-format due to it messing up the following macro. Places the // semi-colon on a separate line. // clang-format off #define END_VIEW_BUILDER … // Unlike the above macros, DEFINE_VIEW_BUILDER must be placed in the global // namespace. Unless 'view_class' is already in the 'views' namespace, it should // be fully qualified with the namespace in which it lives. #define DEFINE_VIEW_BUILDER(export, view_class) … // clang-format on #endif // UI_VIEWS_METADATA_VIEW_FACTORY_H_