blob: 990f93100c29c595a5872ca6203855c9a7c1e35a [file] [log] [blame]
// 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:
typedef CEF_VIEW_IMPL_D ParentClass;
// 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::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<base::ListValue> 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<base::DictionaryValue> 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<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());
DCHECK(!view->IsAttached());
if (!view.get() || !view->IsValid() || view->IsAttached())
return;
std::unique_ptr<views::View> view_ptr = view_util::PassOwnership(view);
ParentClass::content_view()->AddChildView(view_ptr.release());
}
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(!view->IsAttached());
DCHECK_GE(index, 0);
DCHECK_LE(static_cast<unsigned int>(index),
ParentClass::content_view()->children().size());
if (!view.get() || !view->IsValid() || view->IsAttached() || index < 0 ||
(static_cast<unsigned int>(index) >
ParentClass::content_view()->children().size())) {
return;
}
std::unique_ptr<views::View> 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<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_