chromium/ui/views/view.h

// Copyright 2012 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_VIEW_H_
#define UI_VIEWS_VIEW_H_

#include <stddef.h>

#include <concepts>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include "base/callback_list.h"
#include "base/check.h"
#include "base/containers/contains.h"
#include "base/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/safety_checks.h"
#include "base/observer_list.h"
#include "base/types/pass_key.h"
#include "build/build_config.h"
#include "third_party/skia/include/core/SkPath.h"
#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/class_property.h"
#include "ui/base/clipboard/clipboard_format_type.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/dragdrop/drop_target_event.h"
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom-forward.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/base/metadata/metadata_types.h"
#include "ui/base/metadata/metadata_utils.h"
#include "ui/base/ui_base_types.h"
#include "ui/compositor/layer_delegate.h"
#include "ui/compositor/layer_observer.h"
#include "ui/compositor/layer_owner.h"
#include "ui/compositor/layer_type.h"
#include "ui/compositor/paint_cache.h"
#include "ui/events/event.h"
#include "ui/events/event_target.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/transform.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/geometry/vector2d_conversions.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/views/actions/action_view_interface.h"
#include "ui/views/layout/layout_manager.h"
#include "ui/views/layout/layout_types.h"
#include "ui/views/metadata/view_factory.h"
#include "ui/views/paint_info.h"
#include "ui/views/view_targeter.h"
#include "ui/views/views_export.h"

OSExchangeData;

namespace gfx {
class Canvas;
class Insets;
}  // namespace gfx

namespace ui {
struct AXActionData;
class ColorProvider;
class Compositor;
class InputMethod;
class Layer;
class LayerTreeOwner;
class NativeTheme;
class PaintContext;
class ThemeProvider;
class TransformRecorder;
}  // namespace ui

namespace views {

class Background;
class Border;
class ContextMenuController;
class DragController;
class FillLayout;
class FocusManager;
class FocusTraversable;
class LayoutProvider;
class ScrollView;
class SizeBounds;
class ViewAccessibility;
class ViewMaskLayer;
class ViewObserver;
class Widget;
class WordLookupClient;

namespace internal {
class PreEventDispatchHandler;
class PostEventDispatchHandler;
class RootView;
class ScopedChildrenLock;
}  // namespace internal

// Struct used to describe how a View hierarchy has changed. See
// View::ViewHierarchyChanged.
// TODO(pbos): Move to a separate view_hierarchy_changed_details.h header.
struct VIEWS_EXPORT ViewHierarchyChangedDetails {};

PropertyChangedCallback;

// The elements in PropertyEffects represent bits which define what effect(s) a
// changed Property has on the containing class. Additional elements should
// use the next most significant bit.
enum PropertyEffects {};

// When adding layers to the view, this indicates the region into which the
// layer is placed, in the region above or beneath the view.
enum class LayerRegion {};

// When calling |GetLayersInOrder|, this will indicate whether the View's
// own layer should be included in the returned vector or not.
enum class ViewLayer {};

/////////////////////////////////////////////////////////////////////////////
//
// View class
//
//   A View is a rectangle within the views View hierarchy. It is the base
//   class for all Views.
//
//   A View is a container of other Views (there is no such thing as a Leaf
//   View - makes code simpler, reduces type conversion headaches, design
//   mistakes etc)
//
//   The View contains basic properties for sizing (bounds), layout (flex,
//   orientation, etc), painting of children and event dispatch.
//
//   The View also uses a simple Box Layout Manager similar to XUL's
//   SprocketLayout system. Alternative Layout Managers implementing the
//   LayoutManager interface can be used to lay out children if required.
//
//   It is up to the subclass to implement Painting and storage of subclass -
//   specific properties and functionality.
//
//   Unless otherwise documented, views is not thread safe and should only be
//   accessed from the main thread.
//
//   Properties ------------------
//
//   Properties which are intended to be dynamically visible through metadata to
//   other subsystems, such as dev-tools must adhere to a naming convention,
//   usage and implementation patterns.
//
//   Properties start with their base name, such as "Frobble" (note the
//   capitalization). The method to set the property must be called SetXXXX and
//   the method to retrieve the value is called GetXXXX. For the aforementioned
//   Frobble property, this would be SetFrobble and GetFrobble.
//
//   void SetFrobble(bool is_frobble);
//   bool GetFrobble() const;
//
//   In the SetXXXX method, after the value storage location has been updated,
//   OnPropertyChanged() must be called using the address of the storage
//   location as a key. Additionally, any combination of PropertyEffects are
//   also passed in. This will ensure that any desired side effects are properly
//   invoked.
//
//   void View::SetFrobble(bool is_frobble) {
//     if (is_frobble == frobble_)
//       return;
//     frobble_ = is_frobble;
//     OnPropertyChanged(&frobble_, kPropertyEffectsPaint);
//   }
//
//   Each property should also have a way to "listen" to changes by registering
//   a callback.
//
//   base::CallbackListSubscription AddFrobbleChangedCallback(
//       PropertyChangedCallback callback);
//
//   Each callback uses the the existing base::Bind mechanisms which allow for
//   various kinds of callbacks; object methods, normal functions and lambdas.
//
//   Example:
//
//   class FrobbleView : public View {
//    ...
//    private:
//     void OnFrobbleChanged();
//     base::CallbackListSubscription frobble_changed_subscription_;
//   }
//
//   ...
//     frobble_changed_subscription_ = AddFrobbleChangedCallback(
//         base::BindRepeating(&FrobbleView::OnFrobbleChanged,
//         base::Unretained(this)));
//
//   Example:
//
//   void MyView::ValidateFrobbleChanged() {
//     bool frobble_changed = false;
//     base::CallbackListSubscription subscription =
//       frobble_view_->AddFrobbleChangedCallback(
//           base::BindRepeating([](bool* frobble_changed_ptr) {
//             *frobble_changed_ptr = true;
//           }, &frobble_changed));
//     frobble_view_->SetFrobble(!frobble_view_->GetFrobble());
//     LOG() << frobble_changed ? "Frobble changed" : "Frobble NOT changed!";
//   }
//
//   Property metadata -----------
//
//   For Views that expose properties which are intended to be dynamically
//   discoverable by other subsystems, each View and its descendants must
//   include metadata. These other subsystems, such as dev tools or a
//   declarative layout system, can then enumerate the properties on any given
//   instance or class. Using the enumerated information, the actual values of
//   the properties can be read or written. This will be done by getting and
//   setting the values using string representations. The metadata can also be
//   used to instantiate and initialize a View (or descendant) class from a
//   declarative "script".
//
//   For each View class in their respective header declaration, place the macro
//   METADATA_HEADER(<classname>, <view ancestor class>) in the initial private
//   section.
//
//   In the implementing .cc file, add the following macros to the same
//   namespace in which the class resides.
//
//   BEGIN_METADATA(View)
//   ADD_PROPERTY_METADATA(bool, Frobble)
//   END_METADATA
//
//   For each property, add a definition using ADD_PROPERTY_METADATA() between
//   the begin and end macros.
//
//   BEGIN_METADATA(MyView)
//   ADD_PROPERTY_METADATA(int, Bobble)
//   END_METADATA
/////////////////////////////////////////////////////////////////////////////
class VIEWS_EXPORT View : public ui::LayerDelegate,
                          public ui::LayerObserver,
                          public ui::LayerOwner,
                          public ui::AcceleratorTarget,
                          public ui::EventTarget,
                          public ui::EventHandler,
                          public ui::PropertyHandler,
                          public ui::metadata::MetaDataProvider {};

namespace internal {

#if DCHECK_IS_ON()
class ScopedChildrenLock {};
#else
class ScopedChildrenLock {
 public:
  explicit ScopedChildrenLock(const View* view);
  ~ScopedChildrenLock();
};
#endif

}  // namespace internal

class VIEWS_EXPORT BaseActionViewInterface : public ActionViewInterface {};

BEGIN_VIEW_BUILDER(VIEWS_EXPORT, View, BaseView)
template <typename LayoutManager>
BuilderT& SetLayoutManager(std::unique_ptr<LayoutManager> layout_manager) & {}}
template <typename LayoutManager>
BuilderT&& SetLayoutManager(std::unique_ptr<LayoutManager> layout_manager) && {}}

VIEW_BUILDER_OVERLOAD_METHOD(SetAccessibleName, const std::u16string&)
VIEW_BUILDER_OVERLOAD_METHOD(SetAccessibleName, View*)
VIEW_BUILDER_OVERLOAD_METHOD(SetAccessibleName,
                             std::u16string,
                             ax::mojom::NameFrom)
VIEW_BUILDER_OVERLOAD_METHOD(SetAccessibleDescription, const std::u16string&)
VIEW_BUILDER_OVERLOAD_METHOD(SetAccessibleDescription, View*)
VIEW_BUILDER_OVERLOAD_METHOD(SetAccessibleDescription,
                             const std::u16string&,
                             ax::mojom::DescriptionFrom)
VIEW_BUILDER_OVERLOAD_METHOD(SetAccessibleRole, ax::mojom::Role)
VIEW_BUILDER_OVERLOAD_METHOD(SetAccessibleRole,
                             ax::mojom::Role,
                             const std::u16string&)
VIEW_BUILDER_PROPERTY(std::unique_ptr<Background>, Background)
VIEW_BUILDER_PROPERTY(std::unique_ptr<Border>, Border)
VIEW_BUILDER_PROPERTY(gfx::Rect, BoundsRect)
VIEW_BUILDER_PROPERTY(gfx::Size, Size)
VIEW_BUILDER_PROPERTY(gfx::Point, Position)
VIEW_BUILDER_PROPERTY(int, X)
VIEW_BUILDER_PROPERTY(int, Y)
VIEW_BUILDER_PROPERTY(gfx::Size, PreferredSize)
VIEW_BUILDER_PROPERTY(SkPath, ClipPath)
VIEW_BUILDER_PROPERTY_DEFAULT(ui::LayerType, PaintToLayer, ui::LAYER_TEXTURED)
VIEW_BUILDER_PROPERTY(bool, Enabled)
VIEW_BUILDER_PROPERTY(bool, FlipCanvasOnPaintForRTLUI)
VIEW_BUILDER_PROPERTY(views::View::FocusBehavior, FocusBehavior)
VIEW_BUILDER_PROPERTY(int, Group)
VIEW_BUILDER_PROPERTY(int, ID)
VIEW_BUILDER_PROPERTY(bool, Mirrored)
VIEW_BUILDER_PROPERTY(bool, NotifyEnterExitOnChild)
VIEW_BUILDER_PROPERTY(gfx::Transform, Transform)
VIEW_BUILDER_PROPERTY(bool, Visible)
VIEW_BUILDER_PROPERTY(bool, CanProcessEventsWithinSubtree)
VIEW_BUILDER_PROPERTY(bool, UseDefaultFillLayout)
END_VIEW_BUILDER

}  // namespace views

DEFINE_VIEW_BUILDER()

#endif  // UI_VIEWS_VIEW_H_