// 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 // 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: typedef CEF_VIEW_IMPL_D ParentClass; // CefPanel methods. When adding new As*() methods make sure to update // CefViewAdapter::GetFor() in view_adapter.cc. CefRefPtr AsWindow() override { return nullptr; } CefRefPtr SetToFillLayout() override; CefRefPtr SetToBoxLayout( const CefBoxLayoutSettings& settings) override; CefRefPtr GetLayout() override; void Layout() override; void AddChildView(CefRefPtr view) override; void AddChildViewAt(CefRefPtr view, int index) override; void ReorderChildView(CefRefPtr view, int index) override; void RemoveChildView(CefRefPtr view) override; void RemoveAllChildViews() override; size_t GetChildViewCount() override; CefRefPtr GetChildViewAt(int index) override; // CefView methods: CefRefPtr AsPanel() override { return this; } // CefViewAdapter methods: void GetDebugInfo(base::DictionaryValue* 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) { std::unique_ptr children(new base::ListValue()); for (size_t i = 0U; i < count; ++i) { views::View* view = ParentClass::content_view()->children()[i]; CefViewAdapter* adapter = CefViewAdapter::GetFor(view); if (adapter) { std::unique_ptr child_info( new base::DictionaryValue()); adapter->GetDebugInfo(child_info.get(), 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 delegate) : ParentClass(delegate) {} void Initialize() override { ParentClass::Initialize(); // Create the default layout object. SetToFillLayout(); } }; CEF_PANEL_IMPL_T CefRefPtr CEF_PANEL_IMPL_D::SetToFillLayout() { CEF_REQUIRE_VALID_RETURN(nullptr); return CefFillLayoutImpl::Create(ParentClass::content_view()); } CEF_PANEL_IMPL_T CefRefPtr 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 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 view) { CEF_REQUIRE_VALID_RETURN_VOID(); DCHECK(view.get()); DCHECK(view->IsValid()); DCHECK(!view->IsAttached()); if (!view.get() || !view->IsValid() || view->IsAttached()) return; std::unique_ptr view_ptr = view_util::PassOwnership(view); ParentClass::content_view()->AddChildView(view_ptr.release()); } CEF_PANEL_IMPL_T void CEF_PANEL_IMPL_D::AddChildViewAt(CefRefPtr view, int index) { CEF_REQUIRE_VALID_RETURN_VOID(); DCHECK(view.get()); DCHECK(view->IsValid()); DCHECK(!view->IsAttached()); DCHECK_GE(index, 0); DCHECK_LE(static_cast(index), ParentClass::content_view()->children().size()); if (!view.get() || !view->IsValid() || view->IsAttached() || index < 0 || (static_cast(index) > ParentClass::content_view()->children().size())) { return; } std::unique_ptr view_ptr = view_util::PassOwnership(view); ParentClass::content_view()->AddChildViewAt(view_ptr.release(), index); } CEF_PANEL_IMPL_T void CEF_PANEL_IMPL_D::ReorderChildView( CefRefPtr 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 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 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 CEF_PANEL_IMPL_D::GetChildViewAt( int index) { CEF_REQUIRE_VALID_RETURN(nullptr); DCHECK_GE(index, 0); DCHECK_LT(static_cast(index), ParentClass::content_view()->children().size()); if (index < 0 || (static_cast(index) >= ParentClass::content_view()->children().size())) return nullptr; CefRefPtr view = view_util::GetFor(ParentClass::content_view()->children()[index], false); DCHECK(view); return view; } #endif // CEF_LIBCEF_BROWSER_VIEWS_PANEL_IMPL_H_