| // 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_PANEL_IMPL_H_ |
| #define CEF_LIBCEF_BROWSER_VIEWS_PANEL_IMPL_H_ |
| #pragma once |
| |
| #include "include/views/cef_fill_layout.h" |
| #include "include/views/cef_layout.h" |
| #include "include/views/cef_panel.h" |
| #include "include/views/cef_window.h" |
| |
| #include "libcef/browser/views/box_layout_impl.h" |
| #include "libcef/browser/views/fill_layout_impl.h" |
| #include "libcef/browser/views/layout_util.h" |
| #include "libcef/browser/views/view_impl.h" |
| |
| #include "base/logging.h" |
| |
| // Helpers for template boiler-plate. |
| #define CEF_PANEL_IMPL_T CEF_VIEW_IMPL_T |
| #define CEF_PANEL_IMPL_A CEF_VIEW_IMPL_A |
| #define CEF_PANEL_IMPL_D CefPanelImpl<CEF_PANEL_IMPL_A> |
| |
| // Template for implementing CefPanel-derived classes. See comments in |
| // view_impl.h for a usage overview. |
| CEF_PANEL_IMPL_T class CefPanelImpl : public CEF_VIEW_IMPL_D { |
| public: |
| using ParentClass = CEF_VIEW_IMPL_D; |
| |
| // CefPanel methods. When adding new As*() methods make sure to update |
| // CefViewAdapter::GetFor() in view_adapter.cc. |
| CefRefPtr<CefWindow> AsWindow() override { return nullptr; } |
| CefRefPtr<CefFillLayout> SetToFillLayout() override; |
| CefRefPtr<CefBoxLayout> SetToBoxLayout( |
| const CefBoxLayoutSettings& settings) override; |
| CefRefPtr<CefLayout> GetLayout() override; |
| void Layout() override; |
| void AddChildView(CefRefPtr<CefView> view) override; |
| void AddChildViewAt(CefRefPtr<CefView> view, int index) override; |
| void ReorderChildView(CefRefPtr<CefView> view, int index) override; |
| void RemoveChildView(CefRefPtr<CefView> view) override; |
| void RemoveAllChildViews() override; |
| size_t GetChildViewCount() override; |
| CefRefPtr<CefView> GetChildViewAt(int index) override; |
| |
| // CefView methods: |
| CefRefPtr<CefPanel> AsPanel() override { return this; } |
| |
| // CefViewAdapter methods: |
| void GetDebugInfo(base::Value::Dict* info, bool include_children) override { |
| ParentClass::GetDebugInfo(info, include_children); |
| if (include_children) { |
| const size_t count = ParentClass::content_view()->children().size(); |
| if (count > 0U) { |
| base::Value::List children; |
| |
| for (size_t i = 0U; i < count; ++i) { |
| views::View* view = ParentClass::content_view()->children()[i]; |
| CefViewAdapter* adapter = CefViewAdapter::GetFor(view); |
| if (adapter) { |
| base::Value::Dict child_info; |
| adapter->GetDebugInfo(&child_info, include_children); |
| children.Append(std::move(child_info)); |
| } |
| } |
| |
| info->Set("children", std::move(children)); |
| } |
| } |
| } |
| |
| protected: |
| // Create a new implementation object. |
| // Always call Initialize() after creation. |
| // |delegate| may be nullptr. |
| explicit CefPanelImpl(CefRefPtr<CefViewDelegateClass> delegate) |
| : ParentClass(delegate) {} |
| |
| void Initialize() override { |
| ParentClass::Initialize(); |
| |
| // Create the default layout object. |
| SetToFillLayout(); |
| } |
| }; |
| |
| CEF_PANEL_IMPL_T CefRefPtr<CefFillLayout> CEF_PANEL_IMPL_D::SetToFillLayout() { |
| CEF_REQUIRE_VALID_RETURN(nullptr); |
| return CefFillLayoutImpl::Create(ParentClass::content_view()); |
| } |
| |
| CEF_PANEL_IMPL_T CefRefPtr<CefBoxLayout> CEF_PANEL_IMPL_D::SetToBoxLayout( |
| const CefBoxLayoutSettings& settings) { |
| CEF_REQUIRE_VALID_RETURN(nullptr); |
| return CefBoxLayoutImpl::Create(settings, ParentClass::content_view()); |
| } |
| |
| CEF_PANEL_IMPL_T CefRefPtr<CefLayout> CEF_PANEL_IMPL_D::GetLayout() { |
| CEF_REQUIRE_VALID_RETURN(nullptr); |
| return layout_util::GetFor(ParentClass::content_view()); |
| } |
| |
| CEF_PANEL_IMPL_T void CEF_PANEL_IMPL_D::Layout() { |
| CEF_REQUIRE_VALID_RETURN_VOID(); |
| return ParentClass::root_view()->Layout(); |
| } |
| |
| CEF_PANEL_IMPL_T void CEF_PANEL_IMPL_D::AddChildView(CefRefPtr<CefView> view) { |
| CEF_REQUIRE_VALID_RETURN_VOID(); |
| DCHECK(view.get()); |
| DCHECK(view->IsValid()); |
| if (!view.get() || !view->IsValid()) { |
| return; |
| } |
| |
| auto* view_ptr = view->IsAttached() |
| ? view_util::GetFor(view) |
| : view_util::PassOwnership(view).release(); |
| DCHECK(view_ptr); |
| ParentClass::content_view()->AddChildView(view_ptr); |
| } |
| |
| CEF_PANEL_IMPL_T void CEF_PANEL_IMPL_D::AddChildViewAt(CefRefPtr<CefView> view, |
| int index) { |
| CEF_REQUIRE_VALID_RETURN_VOID(); |
| DCHECK(view.get()); |
| DCHECK(view->IsValid()); |
| DCHECK_GE(index, 0); |
| DCHECK_LE(static_cast<unsigned int>(index), |
| ParentClass::content_view()->children().size()); |
| if (!view.get() || !view->IsValid() || index < 0 || |
| (static_cast<unsigned int>(index) > |
| ParentClass::content_view()->children().size())) { |
| return; |
| } |
| |
| auto* view_ptr = view->IsAttached() |
| ? view_util::GetFor(view) |
| : view_util::PassOwnership(view).release(); |
| DCHECK(view_ptr); |
| ParentClass::content_view()->AddChildViewAt(view_ptr, index); |
| } |
| |
| CEF_PANEL_IMPL_T void CEF_PANEL_IMPL_D::ReorderChildView( |
| CefRefPtr<CefView> view, |
| int index) { |
| CEF_REQUIRE_VALID_RETURN_VOID(); |
| DCHECK(view.get()); |
| DCHECK(view->IsValid()); |
| DCHECK(view->IsAttached()); |
| if (!view.get() || !view->IsValid() || !view->IsAttached()) { |
| return; |
| } |
| |
| views::View* view_ptr = view_util::GetFor(view); |
| DCHECK(view_ptr); |
| DCHECK_EQ(view_ptr->parent(), ParentClass::content_view()); |
| if (!view_ptr || view_ptr->parent() != ParentClass::content_view()) { |
| return; |
| } |
| |
| ParentClass::content_view()->ReorderChildView(view_ptr, index); |
| } |
| |
| CEF_PANEL_IMPL_T void CEF_PANEL_IMPL_D::RemoveChildView( |
| CefRefPtr<CefView> view) { |
| CEF_REQUIRE_VALID_RETURN_VOID(); |
| DCHECK(view.get()); |
| DCHECK(view->IsValid()); |
| DCHECK(view->IsAttached()); |
| if (!view.get() || !view->IsValid() || !view->IsAttached()) { |
| return; |
| } |
| |
| views::View* view_ptr = view_util::GetFor(view); |
| DCHECK(view_ptr); |
| DCHECK_EQ(view_ptr->parent(), ParentClass::content_view()); |
| if (!view_ptr || view_ptr->parent() != ParentClass::content_view()) { |
| return; |
| } |
| |
| ParentClass::content_view()->RemoveChildView(view_ptr); |
| view_util::ResumeOwnership(view); |
| } |
| |
| CEF_PANEL_IMPL_T void CEF_PANEL_IMPL_D::RemoveAllChildViews() { |
| CEF_REQUIRE_VALID_RETURN_VOID(); |
| while (!ParentClass::content_view()->children().empty()) { |
| CefRefPtr<CefView> view = view_util::GetFor( |
| ParentClass::content_view()->children().front(), false); |
| RemoveChildView(view); |
| } |
| } |
| |
| CEF_PANEL_IMPL_T size_t CEF_PANEL_IMPL_D::GetChildViewCount() { |
| CEF_REQUIRE_VALID_RETURN(0U); |
| return ParentClass::content_view()->children().size(); |
| } |
| |
| CEF_PANEL_IMPL_T CefRefPtr<CefView> CEF_PANEL_IMPL_D::GetChildViewAt( |
| int index) { |
| CEF_REQUIRE_VALID_RETURN(nullptr); |
| DCHECK_GE(index, 0); |
| DCHECK_LT(static_cast<unsigned int>(index), |
| ParentClass::content_view()->children().size()); |
| if (index < 0 || (static_cast<unsigned int>(index) >= |
| ParentClass::content_view()->children().size())) { |
| return nullptr; |
| } |
| |
| CefRefPtr<CefView> view = |
| view_util::GetFor(ParentClass::content_view()->children()[index], false); |
| DCHECK(view); |
| return view; |
| } |
| |
| #endif // CEF_LIBCEF_BROWSER_VIEWS_PANEL_IMPL_H_ |