mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			761 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			761 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// 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_
 |