summaryrefslogtreecommitdiff
path: root/libcef/browser/views/view_impl.h
diff options
context:
space:
mode:
Diffstat (limited to 'libcef/browser/views/view_impl.h')
-rw-r--r--libcef/browser/views/view_impl.h760
1 files changed, 760 insertions, 0 deletions
diff --git a/libcef/browser/views/view_impl.h b/libcef/browser/views/view_impl.h
new file mode 100644
index 00000000..d9e105d8
--- /dev/null
+++ b/libcef/browser/views/view_impl.h
@@ -0,0 +1,760 @@
+// Copyright 2016 The Chromium Embedded Framework 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 CEF_LIBCEF_BROWSER_VIEWS_VIEW_IMPL_H_
+#define CEF_LIBCEF_BROWSER_VIEWS_VIEW_IMPL_H_
+#pragma once
+
+// CEF exposes views framework functionality via a hierarchy of CefView and
+// related objects. While the goal is to accurately represent views framework
+// capabilities there is not always a direct 1:1 mapping between the CEF
+// implementation and the underlying views implementation. Certain liberties
+// have been taken with the CEF API design to clarify the user experience.
+//
+// CEF implementation overview:
+//
+// CefView-derived classes (CefPanel, CefLabelButton, etc.) are implemented
+// using a specialization of the CefViewImpl template. On Initialize() the
+// CefViewImpl object creates an underlying views::View object via the
+// CreateRootView() method. The views::View objects are implemented using a
+// specialization of the CefViewView template. CefViewView extends the
+// views::View-derived class and executes CefViewDelegate-derived callbacks by
+// overriding views::View methods.
+//
+// Example 1: The CefBasicPanelImpl object created via CefPanel::CreatePanel()
+// has the following object hierarchy:
+//
+// CefView => CefPanel =>
+// CefViewImpl<views::View, CefPanel, CefPanelDelegate> =>
+// CefPanelImpl<views::View, CefPanel, CefPanelDelegate> =>
+// CefBasicPanelImpl.
+//
+// And the CefBasicPanelView object created via
+// CefBasicPanelImpl::CreateRootView() has the following object hierarchy:
+//
+// views::View =>
+// CefViewView<views::View, CefPanelDelegate> =>
+// CefPanelView<views::View, CefPanelDelegate> =>
+// CefBasicPanelView.
+//
+// Example 2: In some cases an intermediary type is required to meet CEF
+// template requirements (e.g. CefViewView requires a no-argument constructor).
+// The CefBasicLabelButtonImpl object created via
+// CefLabelButton::CreateLabelButton() has the following object hierarchy:
+//
+// CefView => CefButton => CefLabelButton =>
+// CefViewImpl<views::LabelButton, CefLabelButton, CefButtonDelegate> =>
+// CefButtonImpl<views::LabelButton, CefLabelButton, CefButtonDelegate> =>
+// CefLabelButtonImpl<views::LabelButton, CefLabelButton,
+// CefButtonDelegate> =>
+// CefBasicLabelButtonImpl
+//
+// And the CefBasicLabelButtonView object created via
+// CefBasicLabelButtonImpl::CreateRootView() has the following object hierarchy:
+//
+// views::View => views::Button => views::LabelButton =>
+// LabelButtonEx (used to implement the required no-argument constructor) =>
+// CefViewView<LabelButtonEx, CefButtonDelegate> =>
+// CefButtonView<LabelButtonEx, CefButtonDelegate> =>
+// CefLabelButtonView<LabelButtonEx, CefButtonDelegate> =>
+// CefBasicLabelButtonView.
+//
+//
+// General design considerations:
+//
+// CefView classes are ref-counted whereas views::View classes are not. There
+// is generally a 1:1 relationship between CefView and views::View objects.
+// However, there may be intermediary views::View objects that are not exposed
+// by the CEF layer. For example:
+// - views::Widget creates views::RootView and views::ContentView child objects;
+// - views::ScrollView creates views::ScrollView::Viewport child objects.
+//
+// The views::View class exposes methods that are not applicable for a subset of
+// views implementations. For example:
+// - Calling AddChildView() on a views::LabelButton is unexpected;
+// - Adding a child to a views::ScrollView requires calling the SetContents()
+// method instead of AddChildView().
+// To avoid user confusion CEF introduces a CefPanel type that extends CefView
+// and exposes common child management functionality. Types that allow
+// arbitrary children extend CefPanel instead of CefView.
+//
+//
+// Object ownership considerations:
+//
+// On initial creation the CefViewImpl object owns an underlying views::View
+// object (created by overriding the CreateRootView() method) and the
+// views::View object holds a non-ref-counted reference to the CefViewImpl
+// object. If a CefViewImpl is destroyed (all refs released) then the underlying
+// views::View object is deleted.
+//
+// When a views::View object is parented to another views::View (via
+// CefPanel::AddChildView or similar) the ownership semantics change. The
+// CefViewImpl swaps its owned reference for an unowned reference and the
+// views::View gains a ref-counted reference to the CefViewImpl
+// (CefView::IsAttached() now returns true).
+//
+// When a parent views::View is deleted all child views::Views in the view
+// hierarchy are also deleted (see [1] for exceptions). When this happens the
+// ref-counted CefViewImpl reference held by the views::View is released. The
+// CefViewImpl is deleted if the client kept no references, otherwise the
+// CefViewImpl is marked as invalid (CefView::IsValid() now returns false).
+//
+// When a views::View is removed from the view hierarchy (via
+// CefPanel::RemoveChildView or similar) the initial ownership state is
+// restored. The CefViewImpl regains ownership of the views::View and the
+// ref-counted CefViewImpl reference held by the views::View is released.
+//
+// The relationship between CefViewImpl and views::View objects is managed using
+// the view_util:: functions. Type conversion is facilitated using the As*()
+// methods exposed by CefView-derived classes and the CefViewAdapter interface
+// implemented by CefViewImpl. See view_util.[cc|h] for implementation details.
+//
+// Some other object types are also tied to views::View lifetime. For example,
+// CefLayout and the underling views::LayoutManager objects are owned by the
+// views::View that they're assigned to. This relationship is managed using the
+// layout_util:: functions in layout_util.[cc|h].
+//
+// [1] By default views::View objects are deleted when the parent views::View
+// object is deleted. However, this behavior can be changed either
+// explicitly by calling set_owned_by_client() or implicitly by using
+// interfaces like WidgetDelegateView (where WidgetDelegate is-a View, and
+// the View is deleted when the native Widget is destroyed). CEF
+// implementations that utilize this behavior must take special care with
+// object ownership management.
+//
+//
+// To implement a new CefView-derived class:
+//
+// 1. Choose a views class to expose.
+// * We'll create a new CefFooBar class which exposes a hypothetical
+// views::FooBar class. The views::FooBar class might look like this:
+//
+// File ui/views/foo_bar.h:
+//
+// namespace views {
+//
+// // FooBar view does a task on child views.
+// class FooBar : public View {
+// public:
+// FooBar();
+//
+// // Do a task.
+// void DoTask();
+// // Called when the task is done.
+// virtual void OnTaskDone();
+//
+// // View methods:
+// void Layout() override; // Implements custom layout of child views.
+// };
+//
+// } // namespace views
+//
+// 2. Determine the existing CefView-derived class that the new view class
+// should extend.
+// * Since in this example CefFooBar can have arbitrary child views we'll
+// have it extend CefPanel.
+//
+// 3. Determine whether the new view class can use an existing delegate class
+// (like CefPanelDelegate) or whether it needs its own delegate class.
+// * Since CefFooBar has an OnTaskDone() callback we'll add a new
+// CefFooBarDelegate class to expose it.
+//
+// 4. Create new header files in the cef/include/views/ directory.
+// * Using existing files as a model, the resulting header contents might
+// look like this:
+//
+// File cef/include/views/cef_foo_bar.h:
+//
+// ///
+// // A FooBar view does a task on child views.
+// ///
+// /*--cef(source=library)--*/
+// class CefFooBar : public CefPanel {
+// public:
+// ///
+// // Create a new FooBar.
+// ///
+// /*--cef(optional_param=delegate)--*/
+// static CefRefPtr<CefFooBar> CreateFooBar(
+// CefRefPtr<CefFooBarDelegate> delegate);
+//
+// ///
+// // Do a task.
+// ///
+// /*--cef()--*/
+// virtual void DoTask() =0;
+// };
+//
+// File cef/include/views/cef_foo_bar_delegate.h:
+//
+// ///
+// // Implement this interface to handle FooBar events.
+// ///
+// /*--cef(source=client)--*/
+// class CefFooBarDelegate : public CefPanelDelegate {
+// public:
+// ///
+// // Called when the task is done.
+// ///
+// /*--cef()--*/
+// virtual void OnTaskDone(CefRefPtr<CefFooBar> foobar) {}
+// };
+//
+// 5. Add an As*() method to the CefView-derived class.
+// * Using existing file contents as a model, make the following changes in
+// cef/include/views/cef_panel.h:
+// * Forward declare the CefFooBar class.
+// * Add a new CefPanel::AsFooBar() method:
+//
+// ///
+// // Returns this Panel as a FooBar or NULL if this is not a FooBar.
+// ///
+// /*--cef()--*/
+// virtual CefRefPtr<CefFooBar> AsFooBar() =0;
+//
+// 6. Add a default implementation for the As*() method to the CefViewImpl-
+// derived class.
+// * Using existing file contents as a model, make the following changes in
+// cef/libcef/browser/views/panel_impl.h:
+// * Include "include/views/cef_foo_bar.h".
+// * Add a default CefPanelImpl::AsFooBar() implementation:
+//
+// CefRefPtr<CefFooBar> AsFooBar() override { return nullptr; }
+//
+// 7. Update the CefViewAdapter::GetFor() method implementation to call the
+// As*() method.
+// * Using existing file contents as a model, make the following changes in
+// cef/libcef/browser/views/view_adapter.cc:
+// * Include "include/views/cef_foo_bar.h".
+// * Call the AsFooBar() method to identify the adapter object:
+//
+// ... if (view->AsPanel()) {
+// CefRefPtr<CefPanel> panel = view->AsPanel();
+// if (panel->AsFooBar()) {
+// adapter = static_cast<CefFooBarImpl*>(panel->AsFooBar().get());
+// } else ...
+// } else ...
+//
+// 8. Implement the CefViewView-derived class.
+// * Using existing files as a model (for example, CefBasicPanelView), create
+// a CefFooBarView class at cef/libcef/browser/views/foo_bar_view.[cc|h].
+// This class:
+// * Extends CefPanelView<views::FooBar, CefFooBarDelegate>.
+// * Overrides the views::FooBar::OnTaskDone method to execute the
+// CefFooBarDelegate::OnTaskDone callback:
+//
+// void CefFooBarView::OnTaskDone() {
+// if (cef_delegate())
+// cef_delegate()->OnTaskDone(GetCefFooBar());
+// }
+//
+// 9. Implement the CefViewImpl-derived class.
+// * Use existing files as a model (for example, CefBasicPanelImpl), create a
+// CefFooBarImpl class at cef/libcef/browser/views/foo_bar_impl.[cc|h].
+// This class:
+// * Extends CefPanelImpl<views::FooBar, CefFooBar, CefFooBarDelegate>.
+// * Implements AsFooBar() to return |this|.
+// * Implements CreateRootView() to return a new CefFooBarView instance.
+// * Implements the CefFooBar::DoTask() method to call
+// views::FooBar::DoTask():
+//
+// void CefFooBarImpl::DoTask() {
+// CEF_REQUIRE_VALID_RETURN_VOID();
+// root_view()->DoTask();
+// }
+//
+// 10. Implement the static method that creates the CefViewImpl-derived object
+// instance.
+// * Use existing files as a model (for example, CefBasicPanelImpl),
+// implement the CefFooBar::CreateFooBar static method in
+// cef/libcef/browser/views/foo_bar_impl.cc. This method:
+// * Creates a new CefFooBarImpl object.
+// * Calls Initialize() on the CefFooBarImpl object.
+// * Returns the CefFooBarImpl object.
+//
+// 11. Add the new source files from #7 and #8 to the 'libcef_static' target in
+// cef.gyp.
+//
+// 12. Update the CEF project files and build.
+// * Run cef/tools/translator.[bat|sh] to update the translation layer for
+// the new/modified classes. This tool needs to be run whenever header
+// files in the cef/include/ directory are changed.
+// * Run cef/cef_create_projects.[bat|sh] to update the Ninja build files.
+// * Build CEF using Ninja.
+//
+
+#include "include/views/cef_browser_view.h"
+#include "include/views/cef_button.h"
+#include "include/views/cef_panel.h"
+#include "include/views/cef_scroll_view.h"
+#include "include/views/cef_textfield.h"
+#include "include/views/cef_view.h"
+
+#include "libcef/browser/thread_util.h"
+#include "libcef/browser/views/view_adapter.h"
+#include "libcef/browser/views/view_util.h"
+
+#include "base/json/json_writer.h"
+#include "base/logging.h"
+#include "base/values.h"
+#include "ui/views/background.h"
+#include "ui/views/border.h"
+#include "ui/views/view.h"
+
+// Helpers for template boiler-plate.
+#define CEF_VIEW_IMPL_T \
+ template <class ViewsViewClass, class CefViewClass, \
+ class CefViewDelegateClass>
+#define CEF_VIEW_IMPL_A ViewsViewClass, CefViewClass, CefViewDelegateClass
+#define CEF_VIEW_IMPL_D CefViewImpl<CEF_VIEW_IMPL_A>
+
+// Base template for implementing CefView-derived classes. See above comments
+// for a usage overview.
+CEF_VIEW_IMPL_T class CefViewImpl : public CefViewAdapter, public CefViewClass {
+ public:
+ // Necessary for the CEF_REQUIRE_VALID_*() macros to compile.
+ using ParentClass = CEF_VIEW_IMPL_D;
+
+ // Returns the content views::View object that should be the target of most
+ // customization actions. May be the root view or a child of the root view.
+ virtual views::View* content_view() const { return root_view(); }
+
+ // Returns the CEF delegate as the derived type which may be nullptr.
+ CefViewDelegateClass* delegate() const { return delegate_.get(); }
+
+ // Returns the root views::View object owned by this CefView.
+ ViewsViewClass* root_view() const { return root_view_ref_; }
+
+ // CefViewAdapter methods:
+ views::View* Get() const override { return root_view(); }
+ std::unique_ptr<views::View> PassOwnership() override {
+ DCHECK(root_view_);
+ return std::move(root_view_);
+ }
+ void ResumeOwnership() override {
+ DCHECK(root_view_ref_);
+ DCHECK(!root_view_);
+ root_view_.reset(root_view_ref_);
+ }
+ void Detach() override {
+ if (root_view_) {
+ root_view_.reset();
+ }
+ root_view_ref_ = nullptr;
+ }
+ void GetDebugInfo(base::Value::Dict* info, bool include_children) override {
+ info->Set("type", GetDebugType());
+ info->Set("id", root_view()->GetID());
+
+ // Use GetBounds() because some subclasses (like CefWindowImpl) override it.
+ const CefRect& bounds = GetBounds();
+ base::Value::Dict bounds_value;
+ bounds_value.Set("x", bounds.x);
+ bounds_value.Set("y", bounds.y);
+ bounds_value.Set("width", bounds.width);
+ bounds_value.Set("height", bounds.height);
+ info->Set("bounds", std::move(bounds_value));
+ }
+
+ // CefView methods. When adding new As*() methods make sure to update
+ // CefViewAdapter::GetFor() in view_adapter.cc.
+ CefRefPtr<CefBrowserView> AsBrowserView() override { return nullptr; }
+ CefRefPtr<CefButton> AsButton() override { return nullptr; }
+ CefRefPtr<CefPanel> AsPanel() override { return nullptr; }
+ CefRefPtr<CefScrollView> AsScrollView() override { return nullptr; }
+ CefRefPtr<CefTextfield> AsTextfield() override { return nullptr; }
+ CefString GetTypeString() override;
+ CefString ToString(bool include_children) override;
+ bool IsValid() override;
+ bool IsAttached() override;
+ bool IsSame(CefRefPtr<CefView> that) override;
+ CefRefPtr<CefViewDelegate> GetDelegate() override;
+ CefRefPtr<CefWindow> GetWindow() override;
+ int GetID() override;
+ void SetID(int id) override;
+ int GetGroupID() override;
+ void SetGroupID(int group_id) override;
+ CefRefPtr<CefView> GetParentView() override;
+ CefRefPtr<CefView> GetViewForID(int id) override;
+ void SetBounds(const CefRect& bounds) override;
+ CefRect GetBounds() override;
+ CefRect GetBoundsInScreen() override;
+ void SetSize(const CefSize& size) override;
+ CefSize GetSize() override;
+ void SetPosition(const CefPoint& position) override;
+ CefPoint GetPosition() override;
+ void SetInsets(const CefInsets& insets) override;
+ CefInsets GetInsets() override;
+ CefSize GetPreferredSize() override;
+ void SizeToPreferredSize() override;
+ CefSize GetMinimumSize() override;
+ CefSize GetMaximumSize() override;
+ int GetHeightForWidth(int width) override;
+ void InvalidateLayout() override;
+ void SetVisible(bool visible) override;
+ bool IsVisible() override;
+ bool IsDrawn() override;
+ void SetEnabled(bool enabled) override;
+ bool IsEnabled() override;
+ void SetFocusable(bool focusable) override;
+ bool IsFocusable() override;
+ bool IsAccessibilityFocusable() override;
+ void RequestFocus() override;
+ void SetBackgroundColor(cef_color_t color) override;
+ cef_color_t GetBackgroundColor() override;
+ bool ConvertPointToScreen(CefPoint& point) override;
+ bool ConvertPointFromScreen(CefPoint& point) override;
+ bool ConvertPointToWindow(CefPoint& point) override;
+ bool ConvertPointFromWindow(CefPoint& point) override;
+ bool ConvertPointToView(CefRefPtr<CefView> view, CefPoint& point) override;
+ bool ConvertPointFromView(CefRefPtr<CefView> view, CefPoint& point) override;
+
+ protected:
+ // Create a new implementation object.
+ // Always call Initialize() after creation.
+ // |delegate| may be nullptr.
+ explicit CefViewImpl(CefRefPtr<CefViewDelegateClass> delegate)
+ : delegate_(delegate), root_view_ref_(nullptr) {}
+
+ // Initialize this object.
+ virtual void Initialize() {
+ root_view_.reset(CreateRootView());
+ DCHECK(root_view_.get());
+ root_view_ref_ = root_view_.get();
+ view_util::Register(this);
+ InitializeRootView();
+ }
+
+ // Create the root views::View object.
+ virtual ViewsViewClass* CreateRootView() = 0;
+
+ // Perform required initialization of the root_view() object created by
+ // CreateRootView(). Called after this object has been registered.
+ virtual void InitializeRootView() = 0;
+
+ private:
+ CefRefPtr<CefViewDelegateClass> delegate_;
+
+ // Owned reference to the views::View wrapped by this object. Will be nullptr
+ // before the View is created and after the View's ownership is transferred.
+ std::unique_ptr<ViewsViewClass> root_view_;
+
+ // Unowned reference to the views::View wrapped by this object. Will be
+ // nullptr before the View is created and after the View is destroyed.
+ ViewsViewClass* root_view_ref_;
+};
+
+CEF_VIEW_IMPL_T CefString CEF_VIEW_IMPL_D::GetTypeString() {
+ CEF_REQUIRE_UIT_RETURN(CefString());
+ return GetDebugType();
+}
+
+CEF_VIEW_IMPL_T CefString CEF_VIEW_IMPL_D::ToString(bool include_children) {
+ CEF_REQUIRE_UIT_RETURN(CefString());
+ base::Value::Dict info;
+ if (IsValid()) {
+ GetDebugInfo(&info, include_children);
+ } else {
+ info.Set("type", GetDebugType());
+ }
+
+ std::string json_string;
+ base::JSONWriter::WriteWithOptions(info, 0, &json_string);
+ return json_string;
+}
+
+CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsValid() {
+ CEF_REQUIRE_UIT_RETURN(false);
+ return !!root_view_ref_;
+}
+
+CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsAttached() {
+ CEF_REQUIRE_UIT_RETURN(false);
+ return !root_view_.get();
+}
+
+CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsSame(CefRefPtr<CefView> that) {
+ CEF_REQUIRE_UIT_RETURN(false);
+ CefViewImpl* that_impl = static_cast<CefViewImpl*>(that.get());
+ if (!that_impl) {
+ return false;
+ }
+ return this == that_impl;
+}
+
+CEF_VIEW_IMPL_T CefRefPtr<CefViewDelegate> CEF_VIEW_IMPL_D::GetDelegate() {
+ CEF_REQUIRE_UIT_RETURN(nullptr);
+ return delegate();
+}
+
+CEF_VIEW_IMPL_T CefRefPtr<CefWindow> CEF_VIEW_IMPL_D::GetWindow() {
+ CEF_REQUIRE_UIT_RETURN(nullptr);
+ if (root_view()) {
+ return view_util::GetWindowFor(root_view()->GetWidget());
+ }
+ return nullptr;
+}
+
+CEF_VIEW_IMPL_T int CEF_VIEW_IMPL_D::GetID() {
+ CEF_REQUIRE_VALID_RETURN(0);
+ return root_view()->GetID();
+}
+
+CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetID(int id) {
+ CEF_REQUIRE_VALID_RETURN_VOID();
+ root_view()->SetID(id);
+}
+
+CEF_VIEW_IMPL_T int CEF_VIEW_IMPL_D::GetGroupID() {
+ CEF_REQUIRE_VALID_RETURN(0);
+ return root_view()->GetGroup();
+}
+
+CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetGroupID(int group_id) {
+ CEF_REQUIRE_VALID_RETURN_VOID();
+ if (root_view()->GetGroup() != -1) {
+ return;
+ }
+ root_view()->SetGroup(group_id);
+}
+
+CEF_VIEW_IMPL_T CefRefPtr<CefView> CEF_VIEW_IMPL_D::GetParentView() {
+ CEF_REQUIRE_VALID_RETURN(nullptr);
+ views::View* view = root_view()->parent();
+ if (!view) {
+ return nullptr;
+ }
+ return view_util::GetFor(view, true);
+}
+
+CEF_VIEW_IMPL_T CefRefPtr<CefView> CEF_VIEW_IMPL_D::GetViewForID(int id) {
+ CEF_REQUIRE_VALID_RETURN(nullptr);
+ views::View* view = root_view()->GetViewByID(id);
+ if (!view) {
+ return nullptr;
+ }
+ return view_util::GetFor(view, true);
+}
+
+CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetBounds(const CefRect& bounds) {
+ CEF_REQUIRE_VALID_RETURN_VOID();
+ root_view()->SetBoundsRect(
+ gfx::Rect(bounds.x, bounds.y, bounds.width, bounds.height));
+}
+
+CEF_VIEW_IMPL_T CefRect CEF_VIEW_IMPL_D::GetBounds() {
+ CEF_REQUIRE_VALID_RETURN(CefRect());
+ const gfx::Rect& bounds = root_view()->bounds();
+ return CefRect(bounds.x(), bounds.y(), bounds.width(), bounds.height());
+}
+
+CEF_VIEW_IMPL_T CefRect CEF_VIEW_IMPL_D::GetBoundsInScreen() {
+ CEF_REQUIRE_VALID_RETURN(CefRect());
+ const gfx::Rect& bounds = root_view()->GetBoundsInScreen();
+ return CefRect(bounds.x(), bounds.y(), bounds.width(), bounds.height());
+}
+
+CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetSize(const CefSize& size) {
+ CEF_REQUIRE_VALID_RETURN_VOID();
+ root_view()->SetSize(gfx::Size(size.width, size.height));
+}
+
+CEF_VIEW_IMPL_T CefSize CEF_VIEW_IMPL_D::GetSize() {
+ CEF_REQUIRE_VALID_RETURN(CefSize());
+ // Call GetBounds() since child classes may override it.
+ const CefRect& bounds = GetBounds();
+ return CefSize(bounds.width, bounds.height);
+}
+
+CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetPosition(const CefPoint& position) {
+ CEF_REQUIRE_VALID_RETURN_VOID();
+ root_view()->SetPosition(gfx::Point(position.x, position.y));
+}
+
+CEF_VIEW_IMPL_T CefPoint CEF_VIEW_IMPL_D::GetPosition() {
+ CEF_REQUIRE_VALID_RETURN(CefPoint());
+ // Call GetBounds() since child classes may override it.
+ const CefRect& bounds = GetBounds();
+ return CefPoint(bounds.x, bounds.y);
+}
+
+CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetInsets(const CefInsets& insets) {
+ CEF_REQUIRE_VALID_RETURN_VOID();
+ const gfx::Insets& gfx_insets =
+ gfx::Insets::TLBR(insets.top, insets.left, insets.bottom, insets.right);
+ root_view()->SetBorder(
+ gfx_insets.IsEmpty() ? nullptr : views::CreateEmptyBorder(gfx_insets));
+}
+
+CEF_VIEW_IMPL_T CefInsets CEF_VIEW_IMPL_D::GetInsets() {
+ CEF_REQUIRE_VALID_RETURN(CefInsets());
+ const auto insets = root_view()->GetInsets();
+ return CefInsets(insets.top(), insets.left(), insets.bottom(),
+ insets.right());
+}
+
+CEF_VIEW_IMPL_T CefSize CEF_VIEW_IMPL_D::GetPreferredSize() {
+ CEF_REQUIRE_VALID_RETURN(CefSize());
+ const gfx::Size& size = root_view()->GetPreferredSize();
+ return CefSize(size.width(), size.height());
+}
+
+CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SizeToPreferredSize() {
+ CEF_REQUIRE_VALID_RETURN_VOID();
+ root_view()->SizeToPreferredSize();
+}
+
+CEF_VIEW_IMPL_T CefSize CEF_VIEW_IMPL_D::GetMinimumSize() {
+ CEF_REQUIRE_VALID_RETURN(CefSize());
+ const gfx::Size& size = root_view()->GetMinimumSize();
+ return CefSize(size.width(), size.height());
+}
+
+CEF_VIEW_IMPL_T CefSize CEF_VIEW_IMPL_D::GetMaximumSize() {
+ CEF_REQUIRE_VALID_RETURN(CefSize());
+ const gfx::Size& size = root_view()->GetMaximumSize();
+ return CefSize(size.width(), size.height());
+}
+
+CEF_VIEW_IMPL_T int CEF_VIEW_IMPL_D::GetHeightForWidth(int width) {
+ CEF_REQUIRE_VALID_RETURN(0);
+ return root_view()->GetHeightForWidth(width);
+}
+
+CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::InvalidateLayout() {
+ CEF_REQUIRE_VALID_RETURN_VOID();
+ root_view()->InvalidateLayout();
+}
+
+CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetVisible(bool visible) {
+ CEF_REQUIRE_VALID_RETURN_VOID();
+ root_view()->SetVisible(visible);
+}
+
+CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsVisible() {
+ CEF_REQUIRE_VALID_RETURN(false);
+ return root_view()->GetVisible();
+}
+
+CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsDrawn() {
+ CEF_REQUIRE_VALID_RETURN(false);
+ return root_view()->IsDrawn();
+}
+
+CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetEnabled(bool enabled) {
+ CEF_REQUIRE_VALID_RETURN_VOID();
+ root_view()->SetEnabled(enabled);
+}
+
+CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsEnabled() {
+ CEF_REQUIRE_VALID_RETURN(false);
+ return root_view()->GetEnabled();
+}
+
+CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetFocusable(bool focusable) {
+ CEF_REQUIRE_VALID_RETURN_VOID();
+ root_view()->SetFocusBehavior(focusable ? views::View::FocusBehavior::ALWAYS
+ : views::View::FocusBehavior::NEVER);
+}
+
+CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsFocusable() {
+ CEF_REQUIRE_VALID_RETURN(false);
+ return root_view()->IsFocusable();
+}
+
+CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsAccessibilityFocusable() {
+ CEF_REQUIRE_VALID_RETURN(false);
+ return root_view()->IsAccessibilityFocusable();
+}
+
+CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::RequestFocus() {
+ CEF_REQUIRE_VALID_RETURN_VOID();
+ root_view()->RequestFocus();
+}
+
+CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetBackgroundColor(cef_color_t color) {
+ CEF_REQUIRE_VALID_RETURN_VOID();
+ content_view()->SetBackground(views::CreateSolidBackground(color));
+}
+
+CEF_VIEW_IMPL_T cef_color_t CEF_VIEW_IMPL_D::GetBackgroundColor() {
+ CEF_REQUIRE_VALID_RETURN(0U);
+ return content_view()->background()->get_color();
+}
+
+CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::ConvertPointToScreen(CefPoint& point) {
+ CEF_REQUIRE_VALID_RETURN(false);
+ gfx::Point gfx_point = gfx::Point(point.x, point.y);
+ if (!view_util::ConvertPointToScreen(root_view(), &gfx_point, false)) {
+ return false;
+ }
+ point = CefPoint(gfx_point.x(), gfx_point.y());
+ return true;
+}
+
+CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::ConvertPointFromScreen(CefPoint& point) {
+ CEF_REQUIRE_VALID_RETURN(false);
+ gfx::Point gfx_point = gfx::Point(point.x, point.y);
+ if (!view_util::ConvertPointFromScreen(root_view(), &gfx_point, false)) {
+ return false;
+ }
+ point = CefPoint(gfx_point.x(), gfx_point.y());
+ return true;
+}
+
+CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::ConvertPointToWindow(CefPoint& point) {
+ CEF_REQUIRE_VALID_RETURN(false);
+ gfx::Point gfx_point = gfx::Point(point.x, point.y);
+ if (!view_util::ConvertPointToWindow(root_view(), &gfx_point)) {
+ return false;
+ }
+ point = CefPoint(gfx_point.x(), gfx_point.y());
+ return true;
+}
+
+CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::ConvertPointFromWindow(CefPoint& point) {
+ CEF_REQUIRE_VALID_RETURN(false);
+ gfx::Point gfx_point = gfx::Point(point.x, point.y);
+ if (!view_util::ConvertPointFromWindow(root_view(), &gfx_point)) {
+ return false;
+ }
+ point = CefPoint(gfx_point.x(), gfx_point.y());
+ return true;
+}
+
+CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::ConvertPointToView(
+ CefRefPtr<CefView> view,
+ CefPoint& point) {
+ CEF_REQUIRE_VALID_RETURN(false);
+ if (!root_view()->GetWidget()) {
+ return false;
+ }
+ views::View* target_view = view_util::GetFor(view);
+ if (!target_view || target_view->GetWidget() != root_view()->GetWidget()) {
+ return false;
+ }
+ gfx::Point gfx_point = gfx::Point(point.x, point.y);
+ views::View::ConvertPointToTarget(root_view(), target_view, &gfx_point);
+ point = CefPoint(gfx_point.x(), gfx_point.y());
+ return true;
+}
+
+CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::ConvertPointFromView(
+ CefRefPtr<CefView> view,
+ CefPoint& point) {
+ CEF_REQUIRE_VALID_RETURN(false);
+ if (!root_view()->GetWidget()) {
+ return false;
+ }
+ views::View* target_view = view_util::GetFor(view);
+ if (!target_view || target_view->GetWidget() != root_view()->GetWidget()) {
+ return false;
+ }
+ gfx::Point gfx_point = gfx::Point(point.x, point.y);
+ views::View::ConvertPointToTarget(target_view, root_view(), &gfx_point);
+ point = CefPoint(gfx_point.x(), gfx_point.y());
+ return true;
+}
+
+#endif // CEF_LIBCEF_BROWSER_VIEWS_VIEW_IMPL_H_