781 lines
28 KiB
C++
781 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
|
|
|
|
#include "base/memory/raw_ptr.h"
|
|
// 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 "base/json/json_writer.h"
|
|
#include "base/logging.h"
|
|
#include "base/values.h"
|
|
#include "cef/include/views/cef_browser_view.h"
|
|
#include "cef/include/views/cef_button.h"
|
|
#include "cef/include/views/cef_panel.h"
|
|
#include "cef/include/views/cef_scroll_view.h"
|
|
#include "cef/include/views/cef_textfield.h"
|
|
#include "cef/include/views/cef_view.h"
|
|
#include "cef/libcef/browser/thread_util.h"
|
|
#include "cef/libcef/browser/views/view_adapter.h"
|
|
#include "cef/libcef/browser/views/view_util.h"
|
|
#include "ui/gfx/color_palette.h"
|
|
#include "ui/views/accessibility/view_accessibility.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;
|
|
bool HasFocus() override;
|
|
void RequestFocus() override;
|
|
void SetBackgroundColor(cef_color_t color) override;
|
|
cef_color_t GetBackgroundColor() override;
|
|
cef_color_t GetThemeColor(int color_id) 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.
|
|
raw_ptr<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();
|
|
content_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 content_view()->IsFocusable();
|
|
}
|
|
|
|
CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsAccessibilityFocusable() {
|
|
CEF_REQUIRE_VALID_RETURN(false);
|
|
return content_view()->GetViewAccessibility().IsAccessibilityFocusable();
|
|
}
|
|
|
|
CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::HasFocus() {
|
|
CEF_REQUIRE_VALID_RETURN(false);
|
|
return content_view()->HasFocus();
|
|
}
|
|
|
|
CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::RequestFocus() {
|
|
CEF_REQUIRE_VALID_RETURN_VOID();
|
|
content_view()->RequestFocus();
|
|
}
|
|
|
|
CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetBackgroundColor(cef_color_t color) {
|
|
CEF_REQUIRE_VALID_RETURN_VOID();
|
|
root_view()->SetBackground(views::CreateSolidBackground(color));
|
|
}
|
|
|
|
CEF_VIEW_IMPL_T cef_color_t CEF_VIEW_IMPL_D::GetBackgroundColor() {
|
|
CEF_REQUIRE_VALID_RETURN(gfx::kPlaceholderColor);
|
|
// May return an empty value.
|
|
const auto& color =
|
|
view_util::GetBackgroundColor(root_view(), /*allow_transparency=*/true);
|
|
if (color) {
|
|
return *color;
|
|
}
|
|
return SK_ColorTRANSPARENT;
|
|
}
|
|
|
|
CEF_VIEW_IMPL_T cef_color_t CEF_VIEW_IMPL_D::GetThemeColor(int color_id) {
|
|
CEF_REQUIRE_VALID_RETURN(gfx::kPlaceholderColor);
|
|
return view_util::GetColor(root_view(), color_id);
|
|
}
|
|
|
|
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_
|