mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Implement Views framework on Windows and Linux (issue #1749).
- Add Views header files in a new include/views directory. - Add initial top-level window (CefWindow), control (CefBrowserView, CefLabelButton, CefMenuButton, CefPanel, CefScrollView, CefTextfield) and layout (CefBoxLayout, CefFlowLayout) support. See libcef/browser/views/view_impl.h comments for implementation details. - Add Views example usage in cefclient and cefsimple and Views unit tests in cef_unittests. Pass the `--use-views` command-line flag to cefclient, cefsimple and cef_unittests to run using the Views framework instead of platform APIs. For cefclient and cefsimple this will create the browser window and all related functionality using the Views framework. For cef_unittests this will run all tests (except OSR tests) in a Views-based browser window. Views- specific unit tests (`--gtest_filter=Views*`) will be run even if the the `--use-views` flag is not specified. - Pass the `--hide-frame` command-line flag to cefclient to demo a frameless Views-based browser window. - Pass the `--hide-controls` command-line flag to cefclient to demo a browser window without top controls. This also works in non-Views mode. - Pass the `--enable-high-dpi-support` command-line flag to cef_unittests on Windows to test high-DPI support on a display that supports it. - Add CefImage for reading/writing image file formats. - Add CefBrowser::DownloadImage() for downloading image URLs as a CefImage representation. This is primarily for loading favicons. - Add CefMenuModel::CreateMenuModel() and CefMenuModelDelegate for creating custom menus. This is primarily for use with CefMenuButton. - Add CefBrowser::TryCloseBrowser() helper for closing a browser. Also improve related documentation in cef_life_span_handler.h. - Rename cef_page_range_t to cef_range_t. It is now also used by CefTextfield. - Remove CefLifeSpanHandler::RunModal() which is never called. - Add draggable regions example to cefclient.
This commit is contained in:
@@ -11,11 +11,14 @@
|
||||
#include "libcef/browser/browser_context_impl.h"
|
||||
#include "libcef/browser/browser_info.h"
|
||||
#include "libcef/browser/browser_info_manager.h"
|
||||
#include "libcef/browser/browser_platform_delegate.h"
|
||||
#include "libcef/browser/browser_util.h"
|
||||
#include "libcef/browser/content_browser_client.h"
|
||||
#include "libcef/browser/context.h"
|
||||
#include "libcef/browser/devtools_delegate.h"
|
||||
#include "libcef/browser/devtools_frontend.h"
|
||||
#include "libcef/browser/extensions/browser_extensions_util.h"
|
||||
#include "libcef/browser/image_impl.h"
|
||||
#include "libcef/browser/media_capture_devices_dispatcher.h"
|
||||
#include "libcef/browser/navigate_params.h"
|
||||
#include "libcef/browser/navigation_entry_impl.h"
|
||||
@@ -149,45 +152,25 @@ void ShowDevToolsWithHelper(ShowDevToolsHelper* helper) {
|
||||
delete helper;
|
||||
}
|
||||
|
||||
// Convert a NativeWebKeyboardEvent to a CefKeyEvent.
|
||||
bool GetCefKeyEvent(const content::NativeWebKeyboardEvent& event,
|
||||
CefKeyEvent& cef_event) {
|
||||
switch (event.type) {
|
||||
case blink::WebKeyboardEvent::RawKeyDown:
|
||||
cef_event.type = KEYEVENT_RAWKEYDOWN;
|
||||
break;
|
||||
case blink::WebKeyboardEvent::KeyDown:
|
||||
cef_event.type = KEYEVENT_KEYDOWN;
|
||||
break;
|
||||
case blink::WebKeyboardEvent::KeyUp:
|
||||
cef_event.type = KEYEVENT_KEYUP;
|
||||
break;
|
||||
case blink::WebKeyboardEvent::Char:
|
||||
cef_event.type = KEYEVENT_CHAR;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
// Callback from CefBrowserHostImpl::DownloadImage.
|
||||
void OnDownloadImage(uint32 max_image_size,
|
||||
CefRefPtr<CefDownloadImageCallback> callback,
|
||||
int id,
|
||||
int http_status_code,
|
||||
const GURL& image_url,
|
||||
const std::vector<SkBitmap>& bitmaps,
|
||||
const std::vector<gfx::Size>& sizes) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
CefRefPtr<CefImageImpl> image_impl;
|
||||
|
||||
if (!bitmaps.empty()) {
|
||||
image_impl = new CefImageImpl();
|
||||
image_impl->AddBitmaps(max_image_size, bitmaps);
|
||||
}
|
||||
|
||||
cef_event.modifiers = 0;
|
||||
if (event.modifiers & blink::WebKeyboardEvent::ShiftKey)
|
||||
cef_event.modifiers |= EVENTFLAG_SHIFT_DOWN;
|
||||
if (event.modifiers & blink::WebKeyboardEvent::ControlKey)
|
||||
cef_event.modifiers |= EVENTFLAG_CONTROL_DOWN;
|
||||
if (event.modifiers & blink::WebKeyboardEvent::AltKey)
|
||||
cef_event.modifiers |= EVENTFLAG_ALT_DOWN;
|
||||
if (event.modifiers & blink::WebKeyboardEvent::MetaKey)
|
||||
cef_event.modifiers |= EVENTFLAG_COMMAND_DOWN;
|
||||
if (event.modifiers & blink::WebKeyboardEvent::IsKeyPad)
|
||||
cef_event.modifiers |= EVENTFLAG_IS_KEY_PAD;
|
||||
|
||||
cef_event.windows_key_code = event.windowsKeyCode;
|
||||
cef_event.native_key_code = event.nativeKeyCode;
|
||||
cef_event.is_system_key = event.isSystemKey;
|
||||
cef_event.character = event.text[0];
|
||||
cef_event.unmodified_character = event.unmodifiedText[0];
|
||||
|
||||
return true;
|
||||
callback->OnDownloadImageFinished(image_url.spec(), http_status_code,
|
||||
image_impl.get());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -263,9 +246,15 @@ CefRefPtr<CefBrowser> CefBrowserHost::CreateBrowserSync(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CefBrowserHostImpl::CreateParams create_params;
|
||||
create_params.window_info.reset(new CefWindowInfo(windowInfo));
|
||||
create_params.client = client;
|
||||
create_params.url = url;
|
||||
create_params.settings = settings;
|
||||
create_params.request_context = request_context;
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> browser =
|
||||
CefBrowserHostImpl::Create(windowInfo, client, url, settings,
|
||||
NULL, false, request_context);
|
||||
CefBrowserHostImpl::Create(create_params);
|
||||
return browser.get();
|
||||
}
|
||||
|
||||
@@ -275,28 +264,60 @@ CefRefPtr<CefBrowser> CefBrowserHost::CreateBrowserSync(
|
||||
|
||||
// static
|
||||
CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::Create(
|
||||
const CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient> client,
|
||||
const CefString& url,
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefBrowserHostImpl> opener,
|
||||
bool is_popup,
|
||||
CefRefPtr<CefRequestContext> request_context) {
|
||||
CreateParams& create_params) {
|
||||
scoped_ptr<CefBrowserPlatformDelegate> platform_delegate =
|
||||
CefBrowserPlatformDelegate::Create(windowInfo, settings, client);
|
||||
CHECK(platform_delegate.get());
|
||||
CefBrowserPlatformDelegate::Create(create_params);
|
||||
CHECK(platform_delegate);
|
||||
|
||||
const bool is_devtools_popup = !!create_params.devtools_opener;
|
||||
|
||||
scoped_refptr<CefBrowserInfo> info =
|
||||
CefBrowserInfoManager::GetInstance()->CreateBrowserInfo(
|
||||
is_popup, platform_delegate->IsWindowless());
|
||||
is_devtools_popup,
|
||||
platform_delegate->IsWindowless());
|
||||
|
||||
// Get or create the request context and browser context.
|
||||
CefRefPtr<CefRequestContextImpl> request_context_impl =
|
||||
CefRequestContextImpl::GetForRequestContext(
|
||||
create_params.request_context);
|
||||
DCHECK(request_context_impl);
|
||||
scoped_refptr<CefBrowserContext> browser_context =
|
||||
request_context_impl->GetBrowserContext();
|
||||
DCHECK(browser_context);
|
||||
|
||||
if (!create_params.request_context) {
|
||||
// Using the global request context.
|
||||
create_params.request_context = request_context_impl.get();
|
||||
}
|
||||
|
||||
content::WebContents::CreateParams wc_create_params(
|
||||
browser_context.get());
|
||||
|
||||
if (platform_delegate->IsWindowless()) {
|
||||
// Create the OSR view for the WebContents.
|
||||
platform_delegate->CreateViewForWebContents(
|
||||
&wc_create_params.view,
|
||||
&wc_create_params.delegate_view);
|
||||
}
|
||||
|
||||
content::WebContents* web_contents =
|
||||
content::WebContents::Create(wc_create_params);
|
||||
DCHECK(web_contents);
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> browser =
|
||||
CefBrowserHostImpl::CreateInternal(settings, client, NULL, info, opener,
|
||||
request_context,
|
||||
std::move(platform_delegate));
|
||||
if (browser.get() && !url.empty()) {
|
||||
browser->LoadURL(CefFrameHostImpl::kMainFrameId, url, content::Referrer(),
|
||||
ui::PAGE_TRANSITION_TYPED, std::string());
|
||||
CefBrowserHostImpl::CreateInternal(
|
||||
create_params.settings,
|
||||
create_params.client,
|
||||
web_contents,
|
||||
info,
|
||||
create_params.devtools_opener,
|
||||
is_devtools_popup,
|
||||
create_params.request_context,
|
||||
std::move(platform_delegate));
|
||||
if (browser.get() && !create_params.url.empty()) {
|
||||
browser->LoadURL(CefFrameHostImpl::kMainFrameId, create_params.url,
|
||||
content::Referrer(), ui::PAGE_TRANSITION_TYPED,
|
||||
std::string());
|
||||
}
|
||||
return browser.get();
|
||||
}
|
||||
@@ -308,38 +329,28 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::CreateInternal(
|
||||
content::WebContents* web_contents,
|
||||
scoped_refptr<CefBrowserInfo> browser_info,
|
||||
CefRefPtr<CefBrowserHostImpl> opener,
|
||||
bool is_devtools_popup,
|
||||
CefRefPtr<CefRequestContext> request_context,
|
||||
scoped_ptr<CefBrowserPlatformDelegate> platform_delegate) {
|
||||
CEF_REQUIRE_UIT();
|
||||
DCHECK(browser_info.get());
|
||||
DCHECK(web_contents);
|
||||
DCHECK(browser_info);
|
||||
DCHECK(request_context);
|
||||
DCHECK(platform_delegate);
|
||||
|
||||
// If |opener| is non-NULL it must be a popup window.
|
||||
DCHECK(!opener.get() || browser_info->is_popup());
|
||||
|
||||
if (!web_contents) {
|
||||
// Get or create the request context and browser context.
|
||||
CefRefPtr<CefRequestContextImpl> request_context_impl =
|
||||
CefRequestContextImpl::GetForRequestContext(request_context);
|
||||
DCHECK(request_context_impl.get());
|
||||
scoped_refptr<CefBrowserContext> browser_context =
|
||||
request_context_impl->GetBrowserContext();
|
||||
DCHECK(browser_context.get());
|
||||
|
||||
if (!request_context.get())
|
||||
request_context = request_context_impl.get();
|
||||
|
||||
content::WebContents::CreateParams create_params(
|
||||
browser_context.get());
|
||||
|
||||
if (platform_delegate->IsWindowless()) {
|
||||
platform_delegate->CreateViewForWebContents(&create_params.view,
|
||||
&create_params.delegate_view);
|
||||
}
|
||||
|
||||
web_contents = content::WebContents::Create(create_params);
|
||||
platform_delegate->WebContentsCreated(web_contents);
|
||||
if (opener) {
|
||||
// Give the opener browser's platform delegate an opportunity to modify the
|
||||
// new browser's platform delegate.
|
||||
opener->platform_delegate_->PopupWebContentsCreated(
|
||||
settings, client, web_contents, platform_delegate.get(),
|
||||
is_devtools_popup);
|
||||
}
|
||||
|
||||
platform_delegate->WebContentsCreated(web_contents);
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> browser =
|
||||
new CefBrowserHostImpl(settings, client, web_contents, browser_info,
|
||||
opener, request_context,
|
||||
@@ -347,12 +358,28 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::CreateInternal(
|
||||
if (!browser->CreateHostWindow())
|
||||
return nullptr;
|
||||
|
||||
// Notify that the browser has been created. These must be delivered in the
|
||||
// expected order.
|
||||
|
||||
// 1. Notify the browser's LifeSpanHandler. This must always be the first
|
||||
// notification for the browser.
|
||||
if (client.get()) {
|
||||
CefRefPtr<CefLifeSpanHandler> handler = client->GetLifeSpanHandler();
|
||||
if (handler.get())
|
||||
handler->OnAfterCreated(browser.get());
|
||||
}
|
||||
|
||||
// 2. Notify the platform delegate. With Views this will result in a call to
|
||||
// CefBrowserViewDelegate::OnBrowserCreated().
|
||||
browser->platform_delegate_->NotifyBrowserCreated();
|
||||
|
||||
if (opener) {
|
||||
// 3. Notify the opener browser's platform delegate. With Views this will
|
||||
// result in a call to CefBrowserViewDelegate::OnPopupBrowserViewCreated().
|
||||
opener->platform_delegate_->PopupBrowserCreated(browser.get(),
|
||||
is_devtools_popup);
|
||||
}
|
||||
|
||||
return browser;
|
||||
}
|
||||
|
||||
@@ -539,6 +566,27 @@ void CefBrowserHostImpl::CloseBrowser(bool force_close) {
|
||||
}
|
||||
}
|
||||
|
||||
bool CefBrowserHostImpl::TryCloseBrowser() {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
NOTREACHED() << "called on invalid thread";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Protect against multiple requests to close while the close is pending.
|
||||
if (destruction_state_ <= DESTRUCTION_STATE_PENDING) {
|
||||
if (destruction_state_ == DESTRUCTION_STATE_NONE) {
|
||||
// Request that the browser close.
|
||||
CloseBrowser(false);
|
||||
}
|
||||
|
||||
// Cancel the close.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allow the close.
|
||||
return true;
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::SetFocus(bool focus) {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
@@ -569,13 +617,23 @@ void CefBrowserHostImpl::SetWindowVisibility(bool visible) {
|
||||
}
|
||||
|
||||
CefWindowHandle CefBrowserHostImpl::GetWindowHandle() {
|
||||
return platform_delegate_->GetHostWindowHandle();
|
||||
if (IsViewsHosted() && CEF_CURRENTLY_ON_UIT()) {
|
||||
// Always return the most up-to-date window handle for a views-hosted
|
||||
// browser since it may change if the view is re-parented.
|
||||
if (platform_delegate_)
|
||||
return platform_delegate_->GetHostWindowHandle();
|
||||
}
|
||||
return host_window_handle_;
|
||||
}
|
||||
|
||||
CefWindowHandle CefBrowserHostImpl::GetOpenerWindowHandle() {
|
||||
return opener_;
|
||||
}
|
||||
|
||||
bool CefBrowserHostImpl::HasView() {
|
||||
return IsViewsHosted();
|
||||
}
|
||||
|
||||
CefRefPtr<CefClient> CefBrowserHostImpl::GetClient() {
|
||||
return client_;
|
||||
}
|
||||
@@ -657,6 +715,34 @@ void CefBrowserHostImpl::StartDownload(const CefString& url) {
|
||||
manager->DownloadUrl(std::move(params));
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::DownloadImage(
|
||||
const CefString& image_url,
|
||||
bool is_favicon,
|
||||
uint32 max_image_size,
|
||||
bool bypass_cache,
|
||||
CefRefPtr<CefDownloadImageCallback> callback) {
|
||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefBrowserHostImpl::DownloadImage, this, image_url,
|
||||
is_favicon, max_image_size, bypass_cache, callback));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!callback)
|
||||
return;
|
||||
|
||||
GURL gurl = GURL(image_url.ToString());
|
||||
if (gurl.is_empty() || !gurl.is_valid())
|
||||
return;
|
||||
|
||||
if (!web_contents())
|
||||
return;
|
||||
|
||||
web_contents()->DownloadImage(
|
||||
gurl, is_favicon, max_image_size * gfx::ImageSkia::GetMaxSupportedScale(),
|
||||
bypass_cache, base::Bind(OnDownloadImage, max_image_size, callback));
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::Print() {
|
||||
if (CEF_CURRENTLY_ON_UIT()) {
|
||||
content::WebContents* actionable_contents = GetActionableWebContents();
|
||||
@@ -1262,6 +1348,10 @@ bool CefBrowserHostImpl::IsWindowless() const {
|
||||
return is_windowless_;
|
||||
}
|
||||
|
||||
bool CefBrowserHostImpl::IsViewsHosted() const {
|
||||
return is_views_hosted_;
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::WindowDestroyed() {
|
||||
CEF_REQUIRE_UIT();
|
||||
DCHECK(!window_destroyed_);
|
||||
@@ -1274,6 +1364,15 @@ void CefBrowserHostImpl::DestroyBrowser() {
|
||||
|
||||
destruction_state_ = DESTRUCTION_STATE_COMPLETED;
|
||||
|
||||
// Notify that this browser has been destroyed. These must be delivered in the
|
||||
// expected order.
|
||||
|
||||
// 1. Notify the platform delegate. With Views this will result in a call to
|
||||
// CefBrowserViewDelegate::OnBrowserDestroyed().
|
||||
platform_delegate_->NotifyBrowserDestroyed();
|
||||
|
||||
// 2. Notify the browser's LifeSpanHandler. This must always be the last
|
||||
// notification for this browser.
|
||||
if (client_.get()) {
|
||||
CefRefPtr<CefLifeSpanHandler> handler = client_->GetLifeSpanHandler();
|
||||
if (handler.get()) {
|
||||
@@ -1290,7 +1389,10 @@ void CefBrowserHostImpl::DestroyBrowser() {
|
||||
if (menu_manager_.get())
|
||||
menu_manager_->Destroy();
|
||||
|
||||
// Notify any observers that may have state associated with this browser.
|
||||
FOR_EACH_OBSERVER(Observer, observers_, OnBrowserDestroyed(this));
|
||||
|
||||
// Disassociate the platform delegate from this browser.
|
||||
platform_delegate_->BrowserDestroyed(this);
|
||||
|
||||
while (!queued_messages_.empty()) {
|
||||
@@ -1323,7 +1425,14 @@ views::Widget* CefBrowserHostImpl::GetWindowWidget() const {
|
||||
CEF_REQUIRE_UIT();
|
||||
return platform_delegate_->GetWindowWidget();
|
||||
}
|
||||
#endif
|
||||
|
||||
CefRefPtr<CefBrowserView> CefBrowserHostImpl::GetBrowserView() const {
|
||||
CEF_REQUIRE_UIT();
|
||||
if (IsViewsHosted())
|
||||
return platform_delegate_->GetBrowserView();
|
||||
return nullptr;
|
||||
}
|
||||
#endif // defined(USE_AURA)
|
||||
|
||||
void CefBrowserHostImpl::CancelContextMenu() {
|
||||
CEF_REQUIRE_UIT();
|
||||
@@ -2006,7 +2115,7 @@ bool CefBrowserHostImpl::PreHandleKeyboardEvent(
|
||||
CefRefPtr<CefKeyboardHandler> handler = client_->GetKeyboardHandler();
|
||||
if (handler.get()) {
|
||||
CefKeyEvent cef_event;
|
||||
if (!GetCefKeyEvent(event, cef_event))
|
||||
if (!browser_util::GetCefKeyEvent(event, cef_event))
|
||||
return false;
|
||||
|
||||
cef_event.focus_on_editable_field = focus_on_editable_field_;
|
||||
@@ -2031,7 +2140,7 @@ void CefBrowserHostImpl::HandleKeyboardEvent(
|
||||
CefRefPtr<CefKeyboardHandler> handler = client_->GetKeyboardHandler();
|
||||
if (handler.get()) {
|
||||
CefKeyEvent cef_event;
|
||||
if (GetCefKeyEvent(event, cef_event)) {
|
||||
if (browser_util::GetCefKeyEvent(event, cef_event)) {
|
||||
cef_event.focus_on_editable_field = focus_on_editable_field_;
|
||||
|
||||
CefEventHandle event_handle = platform_delegate_->GetEventHandle(event);
|
||||
@@ -2090,7 +2199,6 @@ void CefBrowserHostImpl::WebContentsCreated(
|
||||
const std::string& frame_name,
|
||||
const GURL& target_url,
|
||||
content::WebContents* new_contents) {
|
||||
CefWindowInfo window_info;
|
||||
CefBrowserSettings settings;
|
||||
CefRefPtr<CefClient> client;
|
||||
scoped_ptr<CefBrowserPlatformDelegate> platform_delegate;
|
||||
@@ -2105,8 +2213,6 @@ void CefBrowserHostImpl::WebContentsCreated(
|
||||
DCHECK(info.get());
|
||||
DCHECK(info->is_popup());
|
||||
|
||||
platform_delegate->WebContentsCreated(new_contents);
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> opener = GetBrowserForContents(source_contents);
|
||||
DCHECK(opener.get());
|
||||
|
||||
@@ -2118,7 +2224,7 @@ void CefBrowserHostImpl::WebContentsCreated(
|
||||
DCHECK(request_context.get());
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> browser = CefBrowserHostImpl::CreateInternal(
|
||||
settings, client, new_contents, info, opener, request_context,
|
||||
settings, client, new_contents, info, opener, false, request_context,
|
||||
std::move(platform_delegate));
|
||||
}
|
||||
|
||||
@@ -2446,9 +2552,12 @@ void CefBrowserHostImpl::DidUpdateFaviconURL(
|
||||
std::vector<CefString> icon_urls;
|
||||
std::vector<content::FaviconURL>::const_iterator it =
|
||||
candidates.begin();
|
||||
for (; it != candidates.end(); ++it)
|
||||
icon_urls.push_back(it->icon_url.spec());
|
||||
handler->OnFaviconURLChange(this, icon_urls);
|
||||
for (; it != candidates.end(); ++it) {
|
||||
if (it->icon_type == content::FaviconURL::FAVICON)
|
||||
icon_urls.push_back(it->icon_url.spec());
|
||||
}
|
||||
if (!icon_urls.empty())
|
||||
handler->OnFaviconURLChange(this, icon_urls);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2639,6 +2748,8 @@ CefBrowserHostImpl::CefBrowserHostImpl(
|
||||
request_context_(request_context),
|
||||
platform_delegate_(std::move(platform_delegate)),
|
||||
is_windowless_(platform_delegate_->IsWindowless()),
|
||||
is_views_hosted_(platform_delegate_->IsViewsHosted()),
|
||||
host_window_handle_(kNullWindowHandle),
|
||||
is_loading_(false),
|
||||
can_go_back_(false),
|
||||
can_go_forward_(false),
|
||||
@@ -2654,10 +2765,11 @@ CefBrowserHostImpl::CefBrowserHostImpl(
|
||||
focus_on_editable_field_(false),
|
||||
mouse_cursor_change_disabled_(false),
|
||||
devtools_frontend_(NULL) {
|
||||
if (opener.get())
|
||||
if (opener.get() && !platform_delegate_->IsViewsHosted()) {
|
||||
// GetOpenerWindowHandle() only returns a value for non-views-hosted
|
||||
// popup browsers.
|
||||
opener_ = opener->GetWindowHandle();
|
||||
|
||||
DCHECK(request_context_.get());
|
||||
}
|
||||
|
||||
DCHECK(!browser_info_->browser().get());
|
||||
browser_info_->set_browser(this);
|
||||
@@ -2692,13 +2804,19 @@ CefBrowserHostImpl::CefBrowserHostImpl(
|
||||
// Make sure RenderViewCreated is called at least one time.
|
||||
RenderViewCreated(web_contents->GetRenderViewHost());
|
||||
|
||||
// Associate the platform delegate with this browser.
|
||||
platform_delegate_->BrowserCreated(this);
|
||||
}
|
||||
|
||||
bool CefBrowserHostImpl::CreateHostWindow() {
|
||||
if (IsWindowless())
|
||||
return true;
|
||||
return platform_delegate_->CreateHostWindow();
|
||||
// |host_window_handle_| will not change after initial host creation for
|
||||
// non-views-hosted browsers.
|
||||
bool success = true;
|
||||
if (!IsWindowless())
|
||||
success = platform_delegate_->CreateHostWindow();
|
||||
if (success && !IsViewsHosted())
|
||||
host_window_handle_ = platform_delegate_->GetHostWindowHandle();
|
||||
return success;
|
||||
}
|
||||
|
||||
CefRefPtr<CefFrame> CefBrowserHostImpl::GetOrCreateFrame(
|
||||
|
@@ -15,8 +15,8 @@
|
||||
#include "include/cef_browser.h"
|
||||
#include "include/cef_client.h"
|
||||
#include "include/cef_frame.h"
|
||||
#include "include/views/cef_browser_view.h"
|
||||
#include "libcef/browser/browser_info.h"
|
||||
#include "libcef/browser/browser_platform_delegate.h"
|
||||
#include "libcef/browser/file_dialog_manager.h"
|
||||
#include "libcef/browser/frame_host_impl.h"
|
||||
#include "libcef/browser/javascript_dialog_manager.h"
|
||||
@@ -37,10 +37,17 @@ namespace net {
|
||||
class URLRequest;
|
||||
}
|
||||
|
||||
#if defined(USE_AURA)
|
||||
namespace views {
|
||||
class Widget;
|
||||
}
|
||||
#endif // defined(USE_AURA)
|
||||
|
||||
struct Cef_DraggableRegion_Params;
|
||||
struct Cef_Request_Params;
|
||||
struct Cef_Response_Params;
|
||||
class CefBrowserInfo;
|
||||
class CefBrowserPlatformDelegate;
|
||||
class CefDevToolsFrontend;
|
||||
struct CefNavigateParams;
|
||||
class SiteInstance;
|
||||
@@ -86,15 +93,37 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
|
||||
~CefBrowserHostImpl() override;
|
||||
|
||||
struct CreateParams {
|
||||
// Platform-specific window creation info. Will be nullptr when creating a
|
||||
// views-hosted browser.
|
||||
scoped_ptr<CefWindowInfo> window_info;
|
||||
|
||||
#if defined(USE_AURA)
|
||||
// The BrowserView that will own a views-hosted browser. Will be nullptr for
|
||||
// popup browsers (the BrowserView will be created later in that case).
|
||||
CefRefPtr<CefBrowserView> browser_view;
|
||||
#endif
|
||||
|
||||
// Client implementation. May be nullptr.
|
||||
CefRefPtr<CefClient> client;
|
||||
|
||||
// Initial URL to load. May be empty.
|
||||
CefString url;
|
||||
|
||||
// Browser settings.
|
||||
CefBrowserSettings settings;
|
||||
|
||||
// Other browser that opened this DevTools browser. Will be nullptr for non-
|
||||
// DevTools browsers.
|
||||
CefRefPtr<CefBrowserHostImpl> devtools_opener;
|
||||
|
||||
// Request context to use when creating the browser. If nullptr the global
|
||||
// request context will be used.
|
||||
CefRefPtr<CefRequestContext> request_context;
|
||||
};
|
||||
|
||||
// Create a new CefBrowserHostImpl instance.
|
||||
static CefRefPtr<CefBrowserHostImpl> Create(
|
||||
const CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient> client,
|
||||
const CefString& url,
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefBrowserHostImpl> opener,
|
||||
bool is_popup,
|
||||
CefRefPtr<CefRequestContext> request_context);
|
||||
static CefRefPtr<CefBrowserHostImpl> Create(CreateParams& create_params);
|
||||
|
||||
// Returns the browser associated with the specified RenderViewHost.
|
||||
static CefRefPtr<CefBrowserHostImpl> GetBrowserForHost(
|
||||
@@ -118,10 +147,12 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
// CefBrowserHost methods.
|
||||
CefRefPtr<CefBrowser> GetBrowser() override;
|
||||
void CloseBrowser(bool force_close) override;
|
||||
bool TryCloseBrowser() override;
|
||||
void SetFocus(bool focus) override;
|
||||
void SetWindowVisibility(bool visible) override;
|
||||
CefWindowHandle GetWindowHandle() override;
|
||||
CefWindowHandle GetOpenerWindowHandle() override;
|
||||
bool HasView() override;
|
||||
CefRefPtr<CefClient> GetClient() override;
|
||||
CefRefPtr<CefRequestContext> GetRequestContext() override;
|
||||
double GetZoomLevel() override;
|
||||
@@ -134,6 +165,11 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
int selected_accept_filter,
|
||||
CefRefPtr<CefRunFileDialogCallback> callback) override;
|
||||
void StartDownload(const CefString& url) override;
|
||||
void DownloadImage(const CefString& image_url,
|
||||
bool is_favicon,
|
||||
uint32 max_image_size,
|
||||
bool bypass_cache,
|
||||
CefRefPtr<CefDownloadImageCallback> callback) override;
|
||||
void Print() override;
|
||||
void PrintToPDF(const CefString& path,
|
||||
const CefPdfPrintSettings& settings,
|
||||
@@ -212,6 +248,9 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
// Returns true if windowless rendering is enabled.
|
||||
bool IsWindowless() const;
|
||||
|
||||
// Returns true if this browser is views-hosted.
|
||||
bool IsViewsHosted() const;
|
||||
|
||||
// Called when the OS window hosting the browser is destroyed.
|
||||
void WindowDestroyed();
|
||||
|
||||
@@ -226,6 +265,10 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
// Returns the Widget owner for the browser window. Only used with windowed
|
||||
// rendering.
|
||||
views::Widget* GetWindowWidget() const;
|
||||
|
||||
// Returns the BrowserView associated with this browser. Only used with views-
|
||||
// based browsers.
|
||||
CefRefPtr<CefBrowserView> GetBrowserView() const;
|
||||
#endif
|
||||
|
||||
// Returns the frame associated with the specified URLRequest.
|
||||
@@ -271,7 +314,8 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
// Set the frame that currently has focus.
|
||||
void SetFocusedFrame(int64 frame_id);
|
||||
|
||||
// Convert from view coordinates to screen coordinates.
|
||||
// Convert from view coordinates to screen coordinates. Potential display
|
||||
// scaling will be applied to the result.
|
||||
gfx::Point GetScreenPoint(const gfx::Point& view) const;
|
||||
|
||||
// Thread safe accessors.
|
||||
@@ -449,6 +493,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
content::WebContents* web_contents,
|
||||
scoped_refptr<CefBrowserInfo> browser_info,
|
||||
CefRefPtr<CefBrowserHostImpl> opener,
|
||||
bool is_devtools_popup,
|
||||
CefRefPtr<CefRequestContext> request_context,
|
||||
scoped_ptr<CefBrowserPlatformDelegate> platform_delegate);
|
||||
|
||||
@@ -521,6 +566,8 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
CefRefPtr<CefRequestContext> request_context_;
|
||||
scoped_ptr<CefBrowserPlatformDelegate> platform_delegate_;
|
||||
const bool is_windowless_;
|
||||
const bool is_views_hosted_;
|
||||
CefWindowHandle host_window_handle_;
|
||||
|
||||
// Volatile state information. All access must be protected by the state lock.
|
||||
base::Lock state_lock_;
|
||||
|
@@ -202,8 +202,10 @@ bool CefBrowserInfoManager::CanCreateWindow(
|
||||
CefRefPtr<CefClient> client = browser->GetClient();
|
||||
bool allow = true;
|
||||
|
||||
scoped_ptr<CefWindowInfo> window_info(new CefWindowInfo);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
pending_popup->window_info.SetAsPopup(NULL, CefString());
|
||||
window_info->SetAsPopup(NULL, CefString());
|
||||
#endif
|
||||
|
||||
// Start with the current browser's settings.
|
||||
@@ -222,13 +224,13 @@ bool CefBrowserInfoManager::CanCreateWindow(
|
||||
#if (defined(OS_WIN) || defined(OS_MACOSX))
|
||||
// Default to the size from the popup features.
|
||||
if (cef_features.xSet)
|
||||
pending_popup->window_info.x = cef_features.x;
|
||||
window_info->x = cef_features.x;
|
||||
if (cef_features.ySet)
|
||||
pending_popup->window_info.y = cef_features.y;
|
||||
window_info->y = cef_features.y;
|
||||
if (cef_features.widthSet)
|
||||
pending_popup->window_info.width = cef_features.width;
|
||||
window_info->width = cef_features.width;
|
||||
if (cef_features.heightSet)
|
||||
pending_popup->window_info.height = cef_features.height;
|
||||
window_info->height = cef_features.height;
|
||||
#endif
|
||||
|
||||
allow = !handler->OnBeforePopup(browser.get(),
|
||||
@@ -238,7 +240,7 @@ bool CefBrowserInfoManager::CanCreateWindow(
|
||||
static_cast<cef_window_open_disposition_t>(disposition),
|
||||
user_gesture,
|
||||
cef_features,
|
||||
pending_popup->window_info,
|
||||
*window_info,
|
||||
pending_popup->client,
|
||||
pending_popup->settings,
|
||||
no_javascript_access);
|
||||
@@ -246,10 +248,16 @@ bool CefBrowserInfoManager::CanCreateWindow(
|
||||
}
|
||||
|
||||
if (allow) {
|
||||
CefBrowserHostImpl::CreateParams create_params;
|
||||
|
||||
if (!browser->IsViewsHosted())
|
||||
create_params.window_info = std::move(window_info);
|
||||
|
||||
create_params.settings = pending_popup->settings;
|
||||
create_params.client = pending_popup->client;
|
||||
|
||||
pending_popup->platform_delegate =
|
||||
CefBrowserPlatformDelegate::Create(pending_popup->window_info,
|
||||
pending_popup->settings,
|
||||
pending_popup->client);
|
||||
CefBrowserPlatformDelegate::Create(create_params);
|
||||
CHECK(pending_popup->platform_delegate.get());
|
||||
|
||||
pending_popup->step =
|
||||
|
@@ -168,7 +168,6 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
|
||||
std::string target_frame_name;
|
||||
|
||||
// Values specified by OnBeforePopup.
|
||||
CefWindowInfo window_info;
|
||||
CefBrowserSettings settings;
|
||||
CefRefPtr<CefClient> client;
|
||||
|
||||
|
@@ -34,7 +34,7 @@ void CefBrowserPlatformDelegate::RenderViewCreated(
|
||||
content::RenderViewHost* render_view_host) {
|
||||
// Indicate that the view has an external parent (namely us). This changes the
|
||||
// default view behavior in some cases (e.g. focus handling on Linux).
|
||||
if (render_view_host->GetWidget()->GetView())
|
||||
if (!IsViewsHosted() && render_view_host->GetWidget()->GetView())
|
||||
render_view_host->GetWidget()->GetView()->SetHasExternalParent(true);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,12 @@ void CefBrowserPlatformDelegate::BrowserCreated(CefBrowserHostImpl* browser) {
|
||||
browser_ = browser;
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegate::NotifyBrowserCreated() {
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegate::NotifyBrowserDestroyed() {
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegate::BrowserDestroyed(CefBrowserHostImpl* browser) {
|
||||
DCHECK(browser_ && browser_ == browser);
|
||||
browser_ = nullptr;
|
||||
@@ -62,7 +68,25 @@ views::Widget* CefBrowserPlatformDelegate::GetWindowWidget() const {
|
||||
NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
CefRefPtr<CefBrowserView> CefBrowserPlatformDelegate::GetBrowserView() const {
|
||||
NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
#endif // defined(USE_AURA)
|
||||
|
||||
void CefBrowserPlatformDelegate::PopupWebContentsCreated(
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefClient> client,
|
||||
content::WebContents* new_web_contents,
|
||||
CefBrowserPlatformDelegate* new_platform_delegate,
|
||||
bool is_devtools) {
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegate::PopupBrowserCreated(
|
||||
CefBrowserHostImpl* new_browser,
|
||||
bool is_devtools) {
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegate::SendCaptureLostEvent() {
|
||||
content::RenderWidgetHostImpl* widget =
|
||||
|
@@ -11,7 +11,9 @@
|
||||
|
||||
#include "include/cef_client.h"
|
||||
#include "include/cef_drag_data.h"
|
||||
#include "include/views/cef_browser_view.h"
|
||||
#include "include/internal/cef_types.h"
|
||||
#include "libcef/browser/browser_host_impl.h"
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
@@ -35,7 +37,6 @@ class Widget;
|
||||
}
|
||||
#endif
|
||||
|
||||
class CefBrowserHostImpl;
|
||||
class CefBrowserInfo;
|
||||
class CefFileDialogRunner;
|
||||
class CefJavaScriptDialogRunner;
|
||||
@@ -49,9 +50,7 @@ class CefBrowserPlatformDelegate {
|
||||
// Create a new CefBrowserPlatformDelegate instance. May be called on multiple
|
||||
// threads.
|
||||
static scoped_ptr<CefBrowserPlatformDelegate> Create(
|
||||
const CefWindowInfo& window_info,
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefClient> client);
|
||||
CefBrowserHostImpl::CreateParams& create_params);
|
||||
|
||||
// Called to create the view objects for a new WebContents. Will only be
|
||||
// called a single time per instance. May be called on multiple threads. Only
|
||||
@@ -69,12 +68,22 @@ class CefBrowserPlatformDelegate {
|
||||
content::RenderViewHost* render_view_host);
|
||||
|
||||
// Called after the owning CefBrowserHostImpl is created. Will only be called
|
||||
// a single time per instance.
|
||||
// a single time per instance. Do not send any client notifications from this
|
||||
// method.
|
||||
virtual void BrowserCreated(CefBrowserHostImpl* browser);
|
||||
|
||||
// Send any notifications related to browser creation. Called after
|
||||
// BrowserCreated().
|
||||
virtual void NotifyBrowserCreated();
|
||||
|
||||
// Send any notifications related to browser destruction. Called before
|
||||
// BrowserDestroyed().
|
||||
virtual void NotifyBrowserDestroyed();
|
||||
|
||||
// Called before the owning CefBrowserHostImpl is destroyed. Will only be
|
||||
// called a single time per instance. All references to the CefBrowserHostImpl
|
||||
// and WebContents should be cleared when this method is called.
|
||||
// and WebContents should be cleared when this method is called. Do not send
|
||||
// any client notifications from this method.
|
||||
virtual void BrowserDestroyed(CefBrowserHostImpl* browser);
|
||||
|
||||
// Create the window that hosts the browser. Will only be called a single time
|
||||
@@ -96,7 +105,34 @@ class CefBrowserPlatformDelegate {
|
||||
// Returns the Widget owner for the browser window. Only used with windowed
|
||||
// rendering.
|
||||
virtual views::Widget* GetWindowWidget() const;
|
||||
#endif
|
||||
|
||||
// Returns the BrowserView associated with this browser. Only used with views-
|
||||
// based browsers.
|
||||
virtual CefRefPtr<CefBrowserView> GetBrowserView() const;
|
||||
#endif // defined(USE_AURA)
|
||||
|
||||
// Called after the WebContents have been created for a new popup browser
|
||||
// parented to this browser but before the CefBrowserHostImpl is created for
|
||||
// the popup. |is_devtools| will be true if the popup will host DevTools. This
|
||||
// method will be called before WebContentsCreated() is called on
|
||||
// |new_platform_delegate|. Do not make the new browser visible in this
|
||||
// callback.
|
||||
virtual void PopupWebContentsCreated(
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefClient> client,
|
||||
content::WebContents* new_web_contents,
|
||||
CefBrowserPlatformDelegate* new_platform_delegate,
|
||||
bool is_devtools);
|
||||
|
||||
// Called after the CefBrowserHostImpl is created for a new popup browser
|
||||
// parented to this browser. |is_devtools| will be true if the popup will host
|
||||
// DevTools. This method will be called immediately after
|
||||
// CefLifeSpanHandler::OnAfterCreated() for the popup browser. It is safe to
|
||||
// make the new browser visible in this callback (for example, add the browser
|
||||
// to a window and show it).
|
||||
virtual void PopupBrowserCreated(
|
||||
CefBrowserHostImpl* new_browser,
|
||||
bool is_devtools);
|
||||
|
||||
// Notify the window that it was resized.
|
||||
virtual void WasResized() = 0;
|
||||
@@ -128,7 +164,8 @@ class CefBrowserPlatformDelegate {
|
||||
virtual void SetWindowVisibility(bool visible);
|
||||
#endif
|
||||
|
||||
// Convert from view coordinates to screen coordinates.
|
||||
// Convert from view coordinates to screen coordinates. Potential display
|
||||
// scaling will be applied to the result.
|
||||
virtual gfx::Point GetScreenPoint(const gfx::Point& view) const = 0;
|
||||
|
||||
// Open the specified text in the default text editor.
|
||||
@@ -173,6 +210,10 @@ class CefBrowserPlatformDelegate {
|
||||
// called on multiple threads.
|
||||
virtual bool IsWindowless() const = 0;
|
||||
|
||||
// Returns true if this delegate implements views-hosted browser handling. May
|
||||
// be called on multiple threads.
|
||||
virtual bool IsViewsHosted() const = 0;
|
||||
|
||||
// Notify the browser that it was hidden. Only used with windowless rendering.
|
||||
virtual void WasHidden(bool hidden);
|
||||
|
||||
|
@@ -21,6 +21,10 @@
|
||||
#error A delegate implementation is not available for your platform.
|
||||
#endif
|
||||
|
||||
#if defined(USE_AURA)
|
||||
#include "libcef/browser/views/browser_platform_delegate_views.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
scoped_ptr<CefBrowserPlatformDelegateNative> CreateNativeDelegate(
|
||||
@@ -53,14 +57,28 @@ scoped_ptr<CefBrowserPlatformDelegateOsr> CreateOSRDelegate(
|
||||
|
||||
// static
|
||||
scoped_ptr<CefBrowserPlatformDelegate> CefBrowserPlatformDelegate::Create(
|
||||
const CefWindowInfo& window_info,
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefClient> client) {
|
||||
scoped_ptr<CefBrowserPlatformDelegateNative> native_delegate =
|
||||
CreateNativeDelegate(window_info);
|
||||
if (window_info.windowless_rendering_enabled &&
|
||||
client->GetRenderHandler().get()) {
|
||||
return CreateOSRDelegate(std::move(native_delegate));
|
||||
CefBrowserHostImpl::CreateParams& create_params) {
|
||||
if (create_params.window_info) {
|
||||
scoped_ptr<CefBrowserPlatformDelegateNative> native_delegate =
|
||||
CreateNativeDelegate(*create_params.window_info.get());
|
||||
if (create_params.window_info->windowless_rendering_enabled &&
|
||||
create_params.client &&
|
||||
create_params.client->GetRenderHandler().get()) {
|
||||
return CreateOSRDelegate(std::move(native_delegate));
|
||||
}
|
||||
return std::move(native_delegate);
|
||||
}
|
||||
return std::move(native_delegate);
|
||||
#if defined(USE_AURA)
|
||||
else {
|
||||
// CefWindowInfo is not used in this case.
|
||||
scoped_ptr<CefBrowserPlatformDelegateNative> native_delegate =
|
||||
CreateNativeDelegate(CefWindowInfo());
|
||||
return make_scoped_ptr(new CefBrowserPlatformDelegateViews(
|
||||
std::move(native_delegate),
|
||||
static_cast<CefBrowserViewImpl*>(create_params.browser_view.get())));
|
||||
}
|
||||
#endif // defined(USE_AURA)
|
||||
|
||||
NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
|
57
libcef/browser/browser_util.cc
Normal file
57
libcef/browser/browser_util.cc
Normal file
@@ -0,0 +1,57 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/browser_util.h"
|
||||
|
||||
#include "content/public/browser/native_web_keyboard_event.h"
|
||||
|
||||
namespace browser_util {
|
||||
|
||||
bool GetCefKeyEvent(const content::NativeWebKeyboardEvent& event,
|
||||
CefKeyEvent& cef_event) {
|
||||
switch (event.type) {
|
||||
case blink::WebKeyboardEvent::RawKeyDown:
|
||||
cef_event.type = KEYEVENT_RAWKEYDOWN;
|
||||
break;
|
||||
case blink::WebKeyboardEvent::KeyDown:
|
||||
cef_event.type = KEYEVENT_KEYDOWN;
|
||||
break;
|
||||
case blink::WebKeyboardEvent::KeyUp:
|
||||
cef_event.type = KEYEVENT_KEYUP;
|
||||
break;
|
||||
case blink::WebKeyboardEvent::Char:
|
||||
cef_event.type = KEYEVENT_CHAR;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
cef_event.modifiers = 0;
|
||||
if (event.modifiers & blink::WebKeyboardEvent::ShiftKey)
|
||||
cef_event.modifiers |= EVENTFLAG_SHIFT_DOWN;
|
||||
if (event.modifiers & blink::WebKeyboardEvent::ControlKey)
|
||||
cef_event.modifiers |= EVENTFLAG_CONTROL_DOWN;
|
||||
if (event.modifiers & blink::WebKeyboardEvent::AltKey)
|
||||
cef_event.modifiers |= EVENTFLAG_ALT_DOWN;
|
||||
if (event.modifiers & blink::WebKeyboardEvent::MetaKey)
|
||||
cef_event.modifiers |= EVENTFLAG_COMMAND_DOWN;
|
||||
if (event.modifiers & blink::WebKeyboardEvent::IsKeyPad)
|
||||
cef_event.modifiers |= EVENTFLAG_IS_KEY_PAD;
|
||||
|
||||
cef_event.windows_key_code = event.windowsKeyCode;
|
||||
cef_event.native_key_code = event.nativeKeyCode;
|
||||
cef_event.is_system_key = event.isSystemKey;
|
||||
cef_event.character = event.text[0];
|
||||
cef_event.unmodified_character = event.unmodifiedText[0];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetCefKeyEvent(const ui::KeyEvent& event,
|
||||
CefKeyEvent& cef_event) {
|
||||
content::NativeWebKeyboardEvent native_event(event);
|
||||
return GetCefKeyEvent(native_event, cef_event);
|
||||
}
|
||||
|
||||
} // namespace browser_util
|
31
libcef/browser/browser_util.h
Normal file
31
libcef/browser/browser_util.h
Normal file
@@ -0,0 +1,31 @@
|
||||
// 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_BROWSER_UTIL_H_
|
||||
#define CEF_LIBCEF_BROWSER_BROWSER_UTIL_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/internal/cef_types_wrappers.h"
|
||||
|
||||
namespace content {
|
||||
struct NativeWebKeyboardEvent;
|
||||
}
|
||||
|
||||
namespace ui {
|
||||
class KeyEvent;
|
||||
}
|
||||
|
||||
namespace browser_util {
|
||||
|
||||
// Convert a content::NativeWebKeyboardEvent to a CefKeyEvent.
|
||||
bool GetCefKeyEvent(const content::NativeWebKeyboardEvent& event,
|
||||
CefKeyEvent& cef_event);
|
||||
|
||||
// Convert a ui::KeyEvent to a CefKeyEvent.
|
||||
bool GetCefKeyEvent(const ui::KeyEvent& event,
|
||||
CefKeyEvent& cef_event);
|
||||
|
||||
} // namespace browser_util
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_BROWSER_UTIL_H_
|
@@ -109,11 +109,16 @@ CefDevToolsFrontend* CefDevToolsFrontend::Show(
|
||||
new_settings.background_color = SK_ColorWHITE;
|
||||
}
|
||||
|
||||
CefBrowserHostImpl::CreateParams create_params;
|
||||
if (!inspected_browser->IsViewsHosted())
|
||||
create_params.window_info.reset(new CefWindowInfo(windowInfo));
|
||||
create_params.client = client;
|
||||
create_params.settings = new_settings;
|
||||
create_params.devtools_opener = inspected_browser;
|
||||
create_params.request_context = inspected_browser->GetRequestContext();
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> frontend_browser =
|
||||
CefBrowserHostImpl::Create(windowInfo, client, CefString(),
|
||||
new_settings,
|
||||
inspected_browser, true,
|
||||
inspected_browser->GetRequestContext());
|
||||
CefBrowserHostImpl::Create(create_params);
|
||||
|
||||
content::WebContents* inspected_contents = inspected_browser->web_contents();
|
||||
if (!inspect_element_at.IsEmpty()) {
|
||||
|
426
libcef/browser/image_impl.cc
Normal file
426
libcef/browser/image_impl.cc
Normal file
@@ -0,0 +1,426 @@
|
||||
// Copyright (c) 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.
|
||||
|
||||
#include "libcef/browser/image_impl.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "ui/gfx/codec/jpeg_codec.h"
|
||||
#include "ui/gfx/codec/png_codec.h"
|
||||
#include "ui/gfx/image/image_png_rep.h"
|
||||
#include "ui/gfx/image/image_skia.h"
|
||||
|
||||
namespace {
|
||||
|
||||
SkColorType GetSkColorType(cef_color_type_t color_type) {
|
||||
switch (color_type) {
|
||||
case CEF_COLOR_TYPE_RGBA_8888:
|
||||
return kRGBA_8888_SkColorType;
|
||||
case CEF_COLOR_TYPE_BGRA_8888:
|
||||
return kBGRA_8888_SkColorType;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
NOTREACHED();
|
||||
return kUnknown_SkColorType;
|
||||
}
|
||||
|
||||
SkAlphaType GetSkAlphaType(cef_alpha_type_t alpha_type) {
|
||||
switch (alpha_type) {
|
||||
case CEF_ALPHA_TYPE_OPAQUE:
|
||||
return kOpaque_SkAlphaType;
|
||||
case CEF_ALPHA_TYPE_PREMULTIPLIED:
|
||||
return kPremul_SkAlphaType;
|
||||
case CEF_ALPHA_TYPE_POSTMULTIPLIED:
|
||||
return kUnpremul_SkAlphaType;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
NOTREACHED();
|
||||
return kUnknown_SkAlphaType;
|
||||
}
|
||||
|
||||
// Compress as PNG. Requires post-multiplied alpha.
|
||||
bool PNGMethod(bool with_transparency,
|
||||
const SkBitmap& bitmap,
|
||||
std::vector<unsigned char>* compressed) {
|
||||
return gfx::PNGCodec::Encode(
|
||||
reinterpret_cast<unsigned char*>(bitmap.getPixels()),
|
||||
bitmap.colorType() == kBGRA_8888_SkColorType ?
|
||||
gfx::PNGCodec::FORMAT_BGRA : gfx::PNGCodec::FORMAT_RGBA,
|
||||
gfx::Size(bitmap.width(), bitmap.height()),
|
||||
static_cast<int>(bitmap.rowBytes()),
|
||||
bitmap.alphaType() == kOpaque_SkAlphaType || !with_transparency,
|
||||
std::vector<gfx::PNGCodec::Comment>(),
|
||||
compressed);
|
||||
}
|
||||
|
||||
// Compress as JPEG. This internally uses JCS_EXT_RGBX or JCS_EXT_BGRX which
|
||||
// causes the alpha channel to be ignored. Requires post-multiplied alpha.
|
||||
bool JPEGMethod(int quality,
|
||||
const SkBitmap& bitmap,
|
||||
std::vector<unsigned char>* compressed) {
|
||||
return gfx::JPEGCodec::Encode(
|
||||
reinterpret_cast<unsigned char*>(bitmap.getPixels()),
|
||||
bitmap.colorType() == kBGRA_8888_SkColorType ?
|
||||
gfx::JPEGCodec::FORMAT_BGRA : gfx::JPEGCodec::FORMAT_RGBA,
|
||||
bitmap.width(),
|
||||
bitmap.height(),
|
||||
static_cast<int>(bitmap.rowBytes()),
|
||||
quality,
|
||||
compressed);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
CefRefPtr<CefImage> CefImage::CreateImage() {
|
||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||
return new CefImageImpl();
|
||||
}
|
||||
|
||||
CefImageImpl::CefImageImpl() {
|
||||
CEF_REQUIRE_UIT();
|
||||
}
|
||||
|
||||
CefImageImpl::CefImageImpl(const gfx::ImageSkia& image_skia)
|
||||
: image_(image_skia) {
|
||||
CEF_REQUIRE_UIT();
|
||||
}
|
||||
|
||||
CefImageImpl::~CefImageImpl() {
|
||||
CEF_REQUIRE_UIT();
|
||||
}
|
||||
|
||||
bool CefImageImpl::IsEmpty() {
|
||||
CEF_REQUIRE_UIT_RETURN(false);
|
||||
return image_.IsEmpty();
|
||||
}
|
||||
|
||||
bool CefImageImpl::IsSame(CefRefPtr<CefImage> that) {
|
||||
CEF_REQUIRE_UIT_RETURN(false);
|
||||
CefImageImpl* that_impl = static_cast<CefImageImpl*>(that.get());
|
||||
if (!that_impl)
|
||||
return false;
|
||||
|
||||
// Quick check for the same object.
|
||||
if (this == that_impl)
|
||||
return true;
|
||||
|
||||
return image_.AsImageSkia().BackedBySameObjectAs(
|
||||
that_impl->image_.AsImageSkia());
|
||||
}
|
||||
|
||||
bool CefImageImpl::AddBitmap(float scale_factor,
|
||||
int pixel_width,
|
||||
int pixel_height,
|
||||
cef_color_type_t color_type,
|
||||
cef_alpha_type_t alpha_type,
|
||||
const void* pixel_data,
|
||||
size_t pixel_data_size) {
|
||||
CEF_REQUIRE_UIT_RETURN(false);
|
||||
const SkColorType ct = GetSkColorType(color_type);
|
||||
const SkAlphaType at = GetSkAlphaType(alpha_type);
|
||||
|
||||
// Make sure the client passed in the expected values.
|
||||
if (ct != kBGRA_8888_SkColorType && ct != kRGBA_8888_SkColorType)
|
||||
return false;
|
||||
if (pixel_data_size != pixel_width * pixel_height * 4U)
|
||||
return false;
|
||||
|
||||
SkBitmap bitmap;
|
||||
if (!bitmap.tryAllocPixels(
|
||||
SkImageInfo::Make(pixel_width, pixel_height, ct, at))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DCHECK_EQ(pixel_data_size, bitmap.getSize());
|
||||
|
||||
{
|
||||
SkAutoLockPixels bitmap_lock(bitmap);
|
||||
memcpy(bitmap.getPixels(), pixel_data, pixel_data_size);
|
||||
}
|
||||
|
||||
return AddBitmap(scale_factor, bitmap);
|
||||
}
|
||||
|
||||
bool CefImageImpl::AddPNG(float scale_factor,
|
||||
const void* png_data,
|
||||
size_t png_data_size) {
|
||||
CEF_REQUIRE_UIT_RETURN(false);
|
||||
|
||||
SkBitmap bitmap;
|
||||
if (!gfx::PNGCodec::Decode(static_cast<const unsigned char*>(png_data),
|
||||
png_data_size, &bitmap)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return AddBitmap(scale_factor, bitmap);
|
||||
}
|
||||
|
||||
bool CefImageImpl::AddJPEG(float scale_factor,
|
||||
const void* jpeg_data,
|
||||
size_t jpeg_data_size) {
|
||||
CEF_REQUIRE_UIT_RETURN(false);
|
||||
|
||||
scoped_ptr<SkBitmap> bitmap(
|
||||
gfx::JPEGCodec::Decode(static_cast<const unsigned char*>(jpeg_data),
|
||||
jpeg_data_size));
|
||||
if (!bitmap.get())
|
||||
return false;
|
||||
|
||||
return AddBitmap(scale_factor, *bitmap);
|
||||
}
|
||||
|
||||
size_t CefImageImpl::GetWidth() {
|
||||
CEF_REQUIRE_UIT_RETURN(false);
|
||||
return image_.Width();
|
||||
}
|
||||
|
||||
size_t CefImageImpl::GetHeight() {
|
||||
CEF_REQUIRE_UIT_RETURN(false);
|
||||
return image_.Height();
|
||||
}
|
||||
|
||||
bool CefImageImpl::HasRepresentation(float scale_factor) {
|
||||
CEF_REQUIRE_UIT_RETURN(false);
|
||||
return image_.AsImageSkia().HasRepresentation(scale_factor);
|
||||
}
|
||||
|
||||
bool CefImageImpl::RemoveRepresentation(float scale_factor) {
|
||||
CEF_REQUIRE_UIT_RETURN(false);
|
||||
gfx::ImageSkia image_skia = image_.AsImageSkia();
|
||||
if (image_skia.HasRepresentation(scale_factor)) {
|
||||
image_skia.RemoveRepresentation(scale_factor);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CefImageImpl::GetRepresentationInfo(float scale_factor,
|
||||
float& actual_scale_factor,
|
||||
int& pixel_width,
|
||||
int& pixel_height) {
|
||||
CEF_REQUIRE_UIT_RETURN(false);
|
||||
gfx::ImageSkia image_skia = image_.AsImageSkia();
|
||||
if (image_skia.isNull())
|
||||
return false;
|
||||
|
||||
const gfx::ImageSkiaRep& rep = image_skia.GetRepresentation(scale_factor);
|
||||
if (rep.is_null())
|
||||
return false;
|
||||
|
||||
actual_scale_factor = rep.scale();
|
||||
pixel_width = rep.sk_bitmap().width();
|
||||
pixel_height = rep.sk_bitmap().height();
|
||||
return true;
|
||||
}
|
||||
|
||||
CefRefPtr<CefBinaryValue> CefImageImpl::GetAsBitmap(
|
||||
float scale_factor,
|
||||
cef_color_type_t color_type,
|
||||
cef_alpha_type_t alpha_type,
|
||||
int& pixel_width,
|
||||
int& pixel_height) {
|
||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||
|
||||
const SkColorType desired_ct = GetSkColorType(color_type);
|
||||
const SkAlphaType desired_at = GetSkAlphaType(alpha_type);
|
||||
|
||||
const SkBitmap* bitmap = GetBitmap(scale_factor);
|
||||
if (!bitmap)
|
||||
return nullptr;
|
||||
|
||||
SkAutoLockPixels bitmap_lock(*bitmap);
|
||||
DCHECK(bitmap->readyToDraw());
|
||||
|
||||
pixel_width = bitmap->width();
|
||||
pixel_height = bitmap->height();
|
||||
|
||||
if (bitmap->colorType() == desired_ct && bitmap->alphaType() == desired_at) {
|
||||
// No conversion necessary.
|
||||
return CefBinaryValue::Create(bitmap->getPixels(), bitmap->getSize());
|
||||
} else {
|
||||
SkBitmap desired_bitmap;
|
||||
if (!ConvertBitmap(*bitmap, &desired_bitmap, desired_ct, desired_at))
|
||||
return nullptr;
|
||||
SkAutoLockPixels bitmap_lock(desired_bitmap);
|
||||
DCHECK(desired_bitmap.readyToDraw());
|
||||
return CefBinaryValue::Create(desired_bitmap.getPixels(),
|
||||
desired_bitmap.getSize());
|
||||
}
|
||||
}
|
||||
|
||||
CefRefPtr<CefBinaryValue> CefImageImpl::GetAsPNG(float scale_factor,
|
||||
bool with_transparency,
|
||||
int& pixel_width,
|
||||
int& pixel_height) {
|
||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||
const SkBitmap* bitmap = GetBitmap(scale_factor);
|
||||
if (!bitmap)
|
||||
return nullptr;
|
||||
|
||||
std::vector<unsigned char> compressed;
|
||||
if (!WritePNG(*bitmap, &compressed, with_transparency))
|
||||
return nullptr;
|
||||
|
||||
pixel_width = bitmap->width();
|
||||
pixel_height = bitmap->height();
|
||||
|
||||
return CefBinaryValue::Create(&compressed.front(), compressed.size());
|
||||
}
|
||||
|
||||
CefRefPtr<CefBinaryValue> CefImageImpl::GetAsJPEG(float scale_factor,
|
||||
int quality,
|
||||
int& pixel_width,
|
||||
int& pixel_height) {
|
||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||
const SkBitmap* bitmap = GetBitmap(scale_factor);
|
||||
if (!bitmap)
|
||||
return nullptr;
|
||||
|
||||
std::vector<unsigned char> compressed;
|
||||
if (!WriteJPEG(*bitmap, &compressed, quality))
|
||||
return nullptr;
|
||||
|
||||
pixel_width = bitmap->width();
|
||||
pixel_height = bitmap->height();
|
||||
|
||||
return CefBinaryValue::Create(&compressed.front(), compressed.size());
|
||||
}
|
||||
|
||||
void CefImageImpl::AddBitmaps(int32_t scale_1x_size,
|
||||
const std::vector<SkBitmap>& bitmaps) {
|
||||
if (scale_1x_size == 0) {
|
||||
// Set the scale 1x size to the smallest bitmap pixel size.
|
||||
int32_t min_size = std::numeric_limits<int32_t>::max();
|
||||
for (const SkBitmap& bitmap : bitmaps) {
|
||||
const int32_t size = std::max(bitmap.width(), bitmap.height());
|
||||
if (size < min_size)
|
||||
min_size = size;
|
||||
}
|
||||
scale_1x_size = min_size;
|
||||
}
|
||||
|
||||
for (const SkBitmap& bitmap : bitmaps) {
|
||||
const int32_t size = std::max(bitmap.width(), bitmap.height());
|
||||
const float scale_factor = static_cast<float>(size) /
|
||||
static_cast<float>(scale_1x_size);
|
||||
AddBitmap(scale_factor, bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
gfx::ImageSkia CefImageImpl::GetForced1xScaleRepresentation(
|
||||
float scale_factor) const {
|
||||
if (scale_factor == 1.0f) {
|
||||
// We can use the existing image without modification.
|
||||
return image_.AsImageSkia();
|
||||
}
|
||||
|
||||
const SkBitmap* bitmap = GetBitmap(scale_factor);
|
||||
gfx::ImageSkia image_skia;
|
||||
if (bitmap)
|
||||
image_skia.AddRepresentation(gfx::ImageSkiaRep(*bitmap, 1.0f));
|
||||
return image_skia;
|
||||
}
|
||||
|
||||
bool CefImageImpl::AddBitmap(float scale_factor,
|
||||
const SkBitmap& bitmap) {
|
||||
DCHECK(bitmap.readyToDraw());
|
||||
DCHECK(bitmap.colorType() == kBGRA_8888_SkColorType ||
|
||||
bitmap.colorType() == kRGBA_8888_SkColorType);
|
||||
|
||||
gfx::ImageSkiaRep skia_rep(bitmap, scale_factor);
|
||||
if (image_.IsEmpty()) {
|
||||
gfx::Image image((gfx::ImageSkia(skia_rep)));
|
||||
image_.SwapRepresentations(&image);
|
||||
} else {
|
||||
image_.AsImageSkia().AddRepresentation(skia_rep);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const SkBitmap* CefImageImpl::GetBitmap(float scale_factor) const {
|
||||
gfx::ImageSkia image_skia = image_.AsImageSkia();
|
||||
if (image_skia.isNull())
|
||||
return nullptr;
|
||||
|
||||
const gfx::ImageSkiaRep& rep = image_skia.GetRepresentation(scale_factor);
|
||||
if (rep.is_null())
|
||||
return nullptr;
|
||||
|
||||
return &rep.sk_bitmap();
|
||||
}
|
||||
|
||||
// static
|
||||
bool CefImageImpl::ConvertBitmap(const SkBitmap& src_bitmap,
|
||||
SkBitmap* target_bitmap,
|
||||
SkColorType target_ct,
|
||||
SkAlphaType target_at) {
|
||||
DCHECK(src_bitmap.readyToDraw());
|
||||
DCHECK(src_bitmap.colorType() != target_ct ||
|
||||
src_bitmap.alphaType() != target_at);
|
||||
DCHECK(target_bitmap);
|
||||
|
||||
SkImageInfo target_info =
|
||||
SkImageInfo::Make(src_bitmap.width(), src_bitmap.height(), target_ct,
|
||||
target_at);
|
||||
if (!target_bitmap->tryAllocPixels(target_info))
|
||||
return false;
|
||||
|
||||
SkAutoLockPixels bitmap_lock(*target_bitmap);
|
||||
if (!src_bitmap.readPixels(target_info, target_bitmap->getPixels(),
|
||||
target_bitmap->rowBytes(), 0, 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DCHECK(target_bitmap->readyToDraw());
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool CefImageImpl::WriteCompressedFormat(const SkBitmap& bitmap,
|
||||
std::vector<unsigned char>* compressed,
|
||||
const CompressionMethod& method) {
|
||||
const SkBitmap* bitmap_ptr = nullptr;
|
||||
SkBitmap bitmap_postalpha;
|
||||
if (bitmap.alphaType() == kPremul_SkAlphaType) {
|
||||
// Compression methods require post-multiplied alpha values.
|
||||
SkAutoLockPixels bitmap_lock(bitmap);
|
||||
if (!ConvertBitmap(bitmap, &bitmap_postalpha, bitmap.colorType(),
|
||||
kUnpremul_SkAlphaType)) {
|
||||
return false;
|
||||
}
|
||||
bitmap_ptr = &bitmap_postalpha;
|
||||
} else {
|
||||
bitmap_ptr = &bitmap;
|
||||
}
|
||||
|
||||
SkAutoLockPixels bitmap_lock(*bitmap_ptr);
|
||||
DCHECK(bitmap_ptr->readyToDraw());
|
||||
DCHECK(bitmap_ptr->colorType() == kBGRA_8888_SkColorType ||
|
||||
bitmap_ptr->colorType() == kRGBA_8888_SkColorType);
|
||||
DCHECK(bitmap_ptr->alphaType() == kOpaque_SkAlphaType ||
|
||||
bitmap_ptr->alphaType() == kUnpremul_SkAlphaType);
|
||||
|
||||
return method.Run(*bitmap_ptr, compressed);
|
||||
}
|
||||
|
||||
// static
|
||||
bool CefImageImpl::WritePNG(const SkBitmap& bitmap,
|
||||
std::vector<unsigned char>* compressed,
|
||||
bool with_transparency) {
|
||||
return WriteCompressedFormat(bitmap, compressed,
|
||||
base::Bind(PNGMethod, with_transparency));
|
||||
}
|
||||
|
||||
// static
|
||||
bool CefImageImpl::WriteJPEG(const SkBitmap& bitmap,
|
||||
std::vector<unsigned char>* compressed,
|
||||
int quality) {
|
||||
return WriteCompressedFormat(bitmap, compressed,
|
||||
base::Bind(JPEGMethod, quality));
|
||||
}
|
125
libcef/browser/image_impl.h
Normal file
125
libcef/browser/image_impl.h
Normal file
@@ -0,0 +1,125 @@
|
||||
// Copyright (c) 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_IMAGE_IMPL_H_
|
||||
#define CEF_LIBCEF_BROWSER_IMAGE_IMPL_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/cef_image.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
class CefImageImpl : public CefImage {
|
||||
public:
|
||||
// Creates an empty image with no representations.
|
||||
CefImageImpl();
|
||||
|
||||
// Creates a new image by copying the ImageSkia for use as the default
|
||||
// representation.
|
||||
explicit CefImageImpl(const gfx::ImageSkia& image_skia);
|
||||
|
||||
// Deletes the image and, if the only owner of the storage, all of its cached
|
||||
// representations.
|
||||
~CefImageImpl() override;
|
||||
|
||||
// CefImage methods:
|
||||
bool IsEmpty() override;
|
||||
bool IsSame(CefRefPtr<CefImage> that) override;
|
||||
bool AddBitmap(float scale_factor,
|
||||
int pixel_width,
|
||||
int pixel_height,
|
||||
cef_color_type_t color_type,
|
||||
cef_alpha_type_t alpha_type,
|
||||
const void* pixel_data,
|
||||
size_t pixel_data_size) override;
|
||||
bool AddPNG(float scale_factor,
|
||||
const void* png_data,
|
||||
size_t png_data_size) override;
|
||||
bool AddJPEG(float scale_factor,
|
||||
const void* jpeg_data,
|
||||
size_t jpeg_data_size) override;
|
||||
size_t GetWidth() override;
|
||||
size_t GetHeight() override;
|
||||
bool HasRepresentation(float scale_factor) override;
|
||||
bool RemoveRepresentation(float scale_factor) override;
|
||||
bool GetRepresentationInfo(float scale_factor,
|
||||
float& actual_scale_factor,
|
||||
int& pixel_width,
|
||||
int& pixel_height) override;
|
||||
CefRefPtr<CefBinaryValue> GetAsBitmap(float scale_factor,
|
||||
cef_color_type_t color_type,
|
||||
cef_alpha_type_t alpha_type,
|
||||
int& pixel_width,
|
||||
int& pixel_height) override;
|
||||
CefRefPtr<CefBinaryValue> GetAsPNG(float scale_factor,
|
||||
bool with_transparency,
|
||||
int& pixel_width,
|
||||
int& pixel_height) override;
|
||||
CefRefPtr<CefBinaryValue> GetAsJPEG(float scale_factor,
|
||||
int quality,
|
||||
int& pixel_width,
|
||||
int& pixel_height) override;
|
||||
|
||||
// Add |bitmaps| which should be the same image at different scale factors.
|
||||
// |scale_1x_size| is the size in pixels of the 1x factor image. If
|
||||
// |scale_1x_size| is 0 the smallest image size in pixels will be used as the
|
||||
// 1x factor size.
|
||||
void AddBitmaps(int32_t scale_1x_size,
|
||||
const std::vector<SkBitmap>& bitmaps);
|
||||
|
||||
// Return a representation of this Image that contains only the bitmap nearest
|
||||
// |scale_factor| as the 1x scale representation. Conceptually this is an
|
||||
// incorrect representation but is necessary to work around bugs in the views
|
||||
// architecture.
|
||||
// TODO(cef): Remove once https://crbug.com/597732 is resolved.
|
||||
gfx::ImageSkia GetForced1xScaleRepresentation(float scale_factor) const;
|
||||
|
||||
const gfx::Image& image() const { return image_; }
|
||||
|
||||
private:
|
||||
// Add a bitmap.
|
||||
bool AddBitmap(float scale_factor,
|
||||
const SkBitmap& bitmap);
|
||||
|
||||
// Returns the bitmap that most closely matches |scale_factor| or nullptr if
|
||||
// one doesn't exist.
|
||||
const SkBitmap* GetBitmap(float scale_factor) const;
|
||||
|
||||
// Convert |src_bitmap| to |target_bitmap| with |target_ct| and |target_at|.
|
||||
static bool ConvertBitmap(const SkBitmap& src_bitmap,
|
||||
SkBitmap* target_bitmap,
|
||||
SkColorType target_ct,
|
||||
SkAlphaType target_at);
|
||||
|
||||
// The |bitmap| argument will be RGBA or BGRA and either opaque or transparent
|
||||
// with post-multiplied alpha. Writes the compressed output into |compressed|.
|
||||
typedef base::Callback<bool(const SkBitmap& /*bitmap*/,
|
||||
std::vector<unsigned char>* /*compressed*/)>
|
||||
CompressionMethod;
|
||||
|
||||
// Write |bitmap| into |compressed| using |method|.
|
||||
static bool WriteCompressedFormat(const SkBitmap& bitmap,
|
||||
std::vector<unsigned char>* compressed,
|
||||
const CompressionMethod& method);
|
||||
|
||||
// Write |bitmap| into |compressed| using PNG encoding.
|
||||
static bool WritePNG(const SkBitmap& bitmap,
|
||||
std::vector<unsigned char>* compressed,
|
||||
bool with_transparency);
|
||||
|
||||
// Write |bitmap| into |compressed| using JPEG encoding. The alpha channel
|
||||
// will be ignored.
|
||||
static bool WriteJPEG(const SkBitmap& bitmap,
|
||||
std::vector<unsigned char>* compressed,
|
||||
int quality);
|
||||
|
||||
gfx::Image image_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefImageImpl);
|
||||
DISALLOW_COPY_AND_ASSIGN(CefImageImpl);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_IMAGE_IMPL_H_
|
@@ -98,7 +98,7 @@ CefMenuManager::CefMenuManager(CefBrowserHostImpl* browser,
|
||||
weak_ptr_factory_(this) {
|
||||
DCHECK(web_contents());
|
||||
DCHECK(runner_.get());
|
||||
model_ = new CefMenuModelImpl(this);
|
||||
model_ = new CefMenuModelImpl(this, nullptr);
|
||||
}
|
||||
|
||||
CefMenuManager::~CefMenuManager() {
|
||||
@@ -197,7 +197,7 @@ bool CefMenuManager::CreateContextMenu(
|
||||
|
||||
if (custom_menu)
|
||||
return true;
|
||||
return runner_->RunContextMenu(browser_, model_->model(), params_);
|
||||
return runner_->RunContextMenu(browser_, model_.get(), params_);
|
||||
}
|
||||
|
||||
void CefMenuManager::CancelContextMenu() {
|
||||
|
@@ -7,6 +7,8 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "libcef/browser/thread_util.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
@@ -162,6 +164,18 @@ class CefSimpleMenuModel : public ui::MenuModel {
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
CefRefPtr<CefMenuModel> CefMenuModel::CreateMenuModel(
|
||||
CefRefPtr<CefMenuModelDelegate> delegate) {
|
||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||
DCHECK(delegate);
|
||||
if (!delegate)
|
||||
return nullptr;
|
||||
|
||||
CefRefPtr<CefMenuModelImpl> menu_model =
|
||||
new CefMenuModelImpl(nullptr, delegate);
|
||||
return menu_model;
|
||||
}
|
||||
|
||||
struct CefMenuModelImpl::Item {
|
||||
Item(cef_menu_item_type_t type,
|
||||
@@ -203,9 +217,13 @@ struct CefMenuModelImpl::Item {
|
||||
};
|
||||
|
||||
|
||||
CefMenuModelImpl::CefMenuModelImpl(Delegate* delegate)
|
||||
CefMenuModelImpl::CefMenuModelImpl(
|
||||
Delegate* delegate,
|
||||
CefRefPtr<CefMenuModelDelegate> menu_model_delegate)
|
||||
: supported_thread_id_(base::PlatformThread::CurrentId()),
|
||||
delegate_(delegate) {
|
||||
delegate_(delegate),
|
||||
menu_model_delegate_(menu_model_delegate) {
|
||||
DCHECK(delegate_ || menu_model_delegate_);
|
||||
model_.reset(new CefSimpleMenuModel(this));
|
||||
}
|
||||
|
||||
@@ -266,7 +284,7 @@ CefRefPtr<CefMenuModel> CefMenuModelImpl::AddSubMenu(int command_id,
|
||||
return NULL;
|
||||
|
||||
Item item(MENUITEMTYPE_SUBMENU, command_id, label, -1);
|
||||
item.submenu_ = new CefMenuModelImpl(delegate_);
|
||||
item.submenu_ = new CefMenuModelImpl(delegate_, menu_model_delegate_);
|
||||
AppendItem(item);
|
||||
return item.submenu_.get();
|
||||
}
|
||||
@@ -313,7 +331,7 @@ CefRefPtr<CefMenuModel> CefMenuModelImpl::InsertSubMenuAt(
|
||||
return NULL;
|
||||
|
||||
Item item(MENUITEMTYPE_SUBMENU, command_id, label, -1);
|
||||
item.submenu_ = new CefMenuModelImpl(delegate_);
|
||||
item.submenu_ = new CefMenuModelImpl(delegate_, menu_model_delegate_);
|
||||
InsertItemAt(item, index);
|
||||
return item.submenu_.get();
|
||||
}
|
||||
@@ -618,13 +636,25 @@ bool CefMenuModelImpl::GetAcceleratorAt(int index, int& key_code,
|
||||
}
|
||||
|
||||
void CefMenuModelImpl::ActivatedAt(int index, cef_event_flags_t event_flags) {
|
||||
if (VerifyContext() && delegate_)
|
||||
delegate_->ExecuteCommand(this, GetCommandIdAt(index), event_flags);
|
||||
if (!VerifyContext())
|
||||
return;
|
||||
|
||||
const int command_id = GetCommandIdAt(index);
|
||||
if (delegate_)
|
||||
delegate_->ExecuteCommand(this, command_id, event_flags);
|
||||
if (menu_model_delegate_)
|
||||
menu_model_delegate_->ExecuteCommand(this, command_id, event_flags);
|
||||
}
|
||||
|
||||
void CefMenuModelImpl::MenuWillShow() {
|
||||
if (VerifyContext() && delegate_)
|
||||
if (!VerifyContext())
|
||||
return;
|
||||
|
||||
if (delegate_)
|
||||
delegate_->MenuWillShow(this);
|
||||
if (menu_model_delegate_)
|
||||
menu_model_delegate_->MenuWillShow(this);
|
||||
FOR_EACH_OBSERVER(Observer, observers_, MenuWillShow(this));
|
||||
}
|
||||
|
||||
void CefMenuModelImpl::MenuClosed() {
|
||||
@@ -641,7 +671,13 @@ void CefMenuModelImpl::MenuClosed() {
|
||||
|
||||
base::string16 CefMenuModelImpl::GetFormattedLabelAt(int index) {
|
||||
base::string16 label = GetLabelAt(index).ToString16();
|
||||
delegate_->FormatLabel(label);
|
||||
if (delegate_)
|
||||
delegate_->FormatLabel(label);
|
||||
if (menu_model_delegate_) {
|
||||
CefString new_label = label;
|
||||
if (menu_model_delegate_->FormatLabel(this, new_label))
|
||||
label = new_label;
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
@@ -662,6 +698,18 @@ bool CefMenuModelImpl::VerifyRefCount() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void CefMenuModelImpl::AddObserver(Observer* observer) {
|
||||
observers_.AddObserver(observer);
|
||||
}
|
||||
|
||||
void CefMenuModelImpl::RemoveObserver(Observer* observer) {
|
||||
observers_.RemoveObserver(observer);
|
||||
}
|
||||
|
||||
bool CefMenuModelImpl::HasObserver(Observer* observer) const {
|
||||
return observers_.HasObserver(observer);
|
||||
}
|
||||
|
||||
void CefMenuModelImpl::AddMenuItem(const content::MenuItem& menu_item) {
|
||||
const int command_id = static_cast<int>(menu_item.action);
|
||||
|
||||
@@ -726,6 +774,9 @@ void CefMenuModelImpl::ValidateItem(const Item& item) {
|
||||
void CefMenuModelImpl::OnMenuClosed() {
|
||||
if (delegate_)
|
||||
delegate_->MenuClosed(this);
|
||||
if (menu_model_delegate_)
|
||||
menu_model_delegate_->MenuClosed(this);
|
||||
FOR_EACH_OBSERVER(Observer, observers_, MenuClosed(this));
|
||||
}
|
||||
|
||||
bool CefMenuModelImpl::VerifyContext() {
|
||||
|
@@ -10,8 +10,10 @@
|
||||
#include <vector>
|
||||
|
||||
#include "include/cef_menu_model.h"
|
||||
#include "include/cef_menu_model_delegate.h"
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/observer_list.h"
|
||||
#include "base/threading/platform_thread.h"
|
||||
#include "ui/base/models/menu_model.h"
|
||||
|
||||
@@ -42,8 +44,22 @@ class CefMenuModelImpl : public CefMenuModel {
|
||||
virtual ~Delegate() {}
|
||||
};
|
||||
|
||||
// The delegate must outlive this class.
|
||||
explicit CefMenuModelImpl(Delegate* delegate);
|
||||
class Observer {
|
||||
public:
|
||||
// Notifies the delegate that the menu is about to show.
|
||||
virtual void MenuWillShow(CefRefPtr<CefMenuModelImpl> source) {};
|
||||
|
||||
// Notifies the delegate that the menu has closed.
|
||||
virtual void MenuClosed(CefRefPtr<CefMenuModelImpl> source) {};
|
||||
|
||||
protected:
|
||||
virtual ~Observer() {}
|
||||
};
|
||||
|
||||
// Either |delegate| or |menu_model_delegate| must be non-nullptr.
|
||||
// If |delegate| is non-nullptr it must outlive this class.
|
||||
CefMenuModelImpl(Delegate* delegate,
|
||||
CefRefPtr<CefMenuModelDelegate> menu_model_delegate);
|
||||
~CefMenuModelImpl() override;
|
||||
|
||||
// CefMenuModel methods.
|
||||
@@ -116,12 +132,20 @@ class CefMenuModelImpl : public CefMenuModel {
|
||||
// Verify that only a single reference exists to all CefMenuModelImpl objects.
|
||||
bool VerifyRefCount();
|
||||
|
||||
// Manage observer objects. The observer must either outlive this object or
|
||||
// remove itself before destruction.
|
||||
void AddObserver(Observer* observer);
|
||||
void RemoveObserver(Observer* observer);
|
||||
bool HasObserver(Observer* observer) const;
|
||||
|
||||
// Helper for adding custom menu items originating from the renderer process.
|
||||
void AddMenuItem(const content::MenuItem& menu_item);
|
||||
|
||||
ui::MenuModel* model() { return model_.get(); }
|
||||
|
||||
// Used when created via CefMenuManager.
|
||||
Delegate* delegate() { return delegate_; }
|
||||
void set_delegate(Delegate* delegate) { delegate_ = NULL; }
|
||||
void set_delegate(Delegate* delegate) { delegate_ = delegate; }
|
||||
|
||||
private:
|
||||
struct Item;
|
||||
@@ -140,10 +164,19 @@ class CefMenuModelImpl : public CefMenuModel {
|
||||
bool VerifyContext();
|
||||
|
||||
base::PlatformThreadId supported_thread_id_;
|
||||
|
||||
// Used when created via CefMenuManager.
|
||||
Delegate* delegate_;
|
||||
|
||||
// Used when created via CefMenuModel::CreateMenuModel().
|
||||
CefRefPtr<CefMenuModelDelegate> menu_model_delegate_;
|
||||
|
||||
ItemVector items_;
|
||||
scoped_ptr<ui::MenuModel> model_;
|
||||
|
||||
// Observers that want to be notified of changes to this object.
|
||||
base::ObserverList<Observer> observers_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(CefMenuModelImpl);
|
||||
DISALLOW_COPY_AND_ASSIGN(CefMenuModelImpl);
|
||||
};
|
||||
|
@@ -12,17 +12,14 @@ namespace content {
|
||||
struct ContextMenuParams;
|
||||
}
|
||||
|
||||
namespace ui {
|
||||
class MenuModel;
|
||||
}
|
||||
|
||||
class CefBrowserHostImpl;
|
||||
class CefMenuModelImpl;
|
||||
|
||||
// Provides platform-specific menu implementations for CefMenuCreator.
|
||||
class CefMenuRunner {
|
||||
public:
|
||||
virtual bool RunContextMenu(CefBrowserHostImpl* browser,
|
||||
ui::MenuModel* model,
|
||||
CefMenuModelImpl* model,
|
||||
const content::ContextMenuParams& params) = 0;
|
||||
virtual void CancelContextMenu() {}
|
||||
virtual bool FormatLabel(base::string16& label) { return false; }
|
||||
|
@@ -45,3 +45,7 @@ void CefBrowserPlatformDelegateNative::SendMouseWheelEvent(
|
||||
bool CefBrowserPlatformDelegateNative::IsWindowless() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CefBrowserPlatformDelegateNative::IsViewsHosted() const {
|
||||
return false;
|
||||
}
|
||||
|
@@ -30,6 +30,7 @@ class CefBrowserPlatformDelegateNative : public CefBrowserPlatformDelegate {
|
||||
void SendMouseEvent(const blink::WebMouseEvent& event) override;
|
||||
void SendMouseWheelEvent(const blink::WebMouseWheelEvent& event) override;
|
||||
bool IsWindowless() const override;
|
||||
bool IsViewsHosted() const override;
|
||||
|
||||
const CefWindowInfo& window_info() const { return window_info_; }
|
||||
|
||||
|
@@ -133,15 +133,7 @@
|
||||
}
|
||||
|
||||
- (BOOL)windowShouldClose:(id)window {
|
||||
// Protect against multiple requests to close while the close is pending.
|
||||
if (browser_ && browser_->destruction_state() <=
|
||||
CefBrowserHostImpl::DESTRUCTION_STATE_PENDING) {
|
||||
if (browser_->destruction_state() ==
|
||||
CefBrowserHostImpl::DESTRUCTION_STATE_NONE) {
|
||||
// Request that the browser close.
|
||||
browser_->CloseBrowser(false);
|
||||
}
|
||||
|
||||
if (browser_ && !browser_->TryCloseBrowser()) {
|
||||
// Cancel the close.
|
||||
return NO;
|
||||
}
|
||||
|
@@ -576,16 +576,7 @@ LRESULT CALLBACK CefBrowserPlatformDelegateNativeWin::WndProc(
|
||||
|
||||
switch (message) {
|
||||
case WM_CLOSE:
|
||||
// Protect against multiple requests to close while the close is pending.
|
||||
if (browser &&
|
||||
browser->destruction_state() <=
|
||||
CefBrowserHostImpl::DESTRUCTION_STATE_PENDING) {
|
||||
if (browser->destruction_state() ==
|
||||
CefBrowserHostImpl::DESTRUCTION_STATE_NONE) {
|
||||
// Request that the browser close.
|
||||
browser->CloseBrowser(false);
|
||||
}
|
||||
|
||||
if (browser && !browser->TryCloseBrowser()) {
|
||||
// Cancel the close.
|
||||
return 0;
|
||||
}
|
||||
|
@@ -15,10 +15,10 @@ CefMenuRunnerLinux::CefMenuRunnerLinux() {
|
||||
|
||||
bool CefMenuRunnerLinux::RunContextMenu(
|
||||
CefBrowserHostImpl* browser,
|
||||
ui::MenuModel* model,
|
||||
CefMenuModelImpl* model,
|
||||
const content::ContextMenuParams& params) {
|
||||
menu_.reset(
|
||||
new views::MenuRunner(model, views::MenuRunner::CONTEXT_MENU));
|
||||
new views::MenuRunner(model->model(), views::MenuRunner::CONTEXT_MENU));
|
||||
|
||||
const gfx::Point& screen_point =
|
||||
browser->GetScreenPoint(gfx::Point(params.x, params.y));
|
||||
|
@@ -17,7 +17,7 @@ class CefMenuRunnerLinux: public CefMenuRunner {
|
||||
|
||||
// CefMenuRunner methods.
|
||||
bool RunContextMenu(CefBrowserHostImpl* browser,
|
||||
ui::MenuModel* model,
|
||||
CefMenuModelImpl* model,
|
||||
const content::ContextMenuParams& params) override;
|
||||
void CancelContextMenu() override;
|
||||
bool FormatLabel(base::string16& label) override;
|
||||
|
@@ -23,7 +23,7 @@ class CefMenuRunnerMac : public CefMenuRunner {
|
||||
|
||||
// CefMenuRunner methods.
|
||||
bool RunContextMenu(CefBrowserHostImpl* browser,
|
||||
ui::MenuModel* model,
|
||||
CefMenuModelImpl* model,
|
||||
const content::ContextMenuParams& params) override;
|
||||
void CancelContextMenu() override;
|
||||
|
||||
|
@@ -20,10 +20,10 @@ CefMenuRunnerMac::~CefMenuRunnerMac() {
|
||||
|
||||
bool CefMenuRunnerMac::RunContextMenu(
|
||||
CefBrowserHostImpl* browser,
|
||||
ui::MenuModel* model,
|
||||
CefMenuModelImpl* model,
|
||||
const content::ContextMenuParams& params) {
|
||||
// Create a menu controller based on the model.
|
||||
menu_controller_.reset([[MenuController alloc] initWithModel:model
|
||||
menu_controller_.reset([[MenuController alloc] initWithModel:model->model()
|
||||
useWithPopUpButtonCell:NO]);
|
||||
|
||||
// Keep the menu controller alive (by adding an additional retain) until after
|
||||
|
@@ -15,10 +15,10 @@ CefMenuRunnerWin::CefMenuRunnerWin() {
|
||||
|
||||
bool CefMenuRunnerWin::RunContextMenu(
|
||||
CefBrowserHostImpl* browser,
|
||||
ui::MenuModel* model,
|
||||
CefMenuModelImpl* model,
|
||||
const content::ContextMenuParams& params) {
|
||||
// Create a menu based on the model.
|
||||
menu_.reset(new views::NativeMenuWin(model, NULL));
|
||||
menu_.reset(new views::NativeMenuWin(model->model(), NULL));
|
||||
menu_->Rebuild(NULL);
|
||||
|
||||
// Make sure events can be pumped while the menu is up.
|
||||
|
@@ -18,7 +18,7 @@ class CefMenuRunnerWin : public CefMenuRunner {
|
||||
|
||||
// CefMenuRunner methods.
|
||||
bool RunContextMenu(CefBrowserHostImpl* browser,
|
||||
ui::MenuModel* model,
|
||||
CefMenuModelImpl* model,
|
||||
const content::ContextMenuParams& params) override;
|
||||
|
||||
private:
|
||||
|
@@ -339,16 +339,7 @@ uint32_t CefWindowX11::DispatchEvent(const ui::PlatformEvent& event) {
|
||||
Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]);
|
||||
if (protocol == atom_cache_.GetAtom(kWMDeleteWindow)) {
|
||||
// We have received a close message from the window manager.
|
||||
if (browser_.get() && browser_->destruction_state() <=
|
||||
CefBrowserHostImpl::DESTRUCTION_STATE_PENDING) {
|
||||
if (browser_->destruction_state() ==
|
||||
CefBrowserHostImpl::DESTRUCTION_STATE_NONE) {
|
||||
// Request that the browser close.
|
||||
browser_->CloseBrowser(false);
|
||||
}
|
||||
|
||||
// Cancel the close.
|
||||
} else {
|
||||
if (!browser_ || browser_->TryCloseBrowser()) {
|
||||
// Allow the close.
|
||||
XDestroyWindow(xdisplay_, xwindow_);
|
||||
}
|
||||
|
@@ -177,6 +177,10 @@ bool CefBrowserPlatformDelegateOsr::IsWindowless() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CefBrowserPlatformDelegateOsr::IsViewsHosted() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateOsr::WasHidden(bool hidden) {
|
||||
CefRenderWidgetHostViewOSR* view = GetOSRHostView();
|
||||
if (view) {
|
||||
|
@@ -51,6 +51,7 @@ class CefBrowserPlatformDelegateOsr :
|
||||
scoped_ptr<CefJavaScriptDialogRunner> CreateJavaScriptDialogRunner() override;
|
||||
scoped_ptr<CefMenuRunner> CreateMenuRunner() override;
|
||||
bool IsWindowless() const override;
|
||||
bool IsViewsHosted() const override;
|
||||
void WasHidden(bool hidden) override;
|
||||
void NotifyScreenInfoChanged() override;
|
||||
void Invalidate(cef_paint_element_type_t type) override;
|
||||
|
@@ -78,7 +78,7 @@ void CefPrintSettingsImpl::SetPageRanges(const PageRangeList& ranges) {
|
||||
printing::PageRanges page_ranges;
|
||||
PageRangeList::const_iterator it = ranges.begin();
|
||||
for(; it != ranges.end(); ++it) {
|
||||
const CefPageRange& cef_range = *it;
|
||||
const CefRange& cef_range = *it;
|
||||
printing::PageRange range;
|
||||
range.from = cef_range.from;
|
||||
range.to = cef_range.to;
|
||||
@@ -100,7 +100,7 @@ void CefPrintSettingsImpl::GetPageRanges(PageRangeList& ranges) {
|
||||
printing::PageRanges::const_iterator it = page_ranges.begin();
|
||||
for (; it != page_ranges.end(); ++it) {
|
||||
const printing::PageRange& range = *it;
|
||||
ranges.push_back(CefPageRange(range.from, range.to));
|
||||
ranges.push_back(CefRange(range.from, range.to));
|
||||
}
|
||||
}
|
||||
|
||||
|
39
libcef/browser/views/basic_label_button_impl.cc
Normal file
39
libcef/browser/views/basic_label_button_impl.cc
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/basic_label_button_impl.h"
|
||||
|
||||
#include "libcef/browser/views/basic_label_button_view.h"
|
||||
|
||||
// static
|
||||
CefRefPtr<CefLabelButton> CefLabelButton::CreateLabelButton(
|
||||
CefRefPtr<CefButtonDelegate> delegate,
|
||||
const CefString& text,
|
||||
bool with_frame) {
|
||||
return CefBasicLabelButtonImpl::Create(delegate, text, with_frame);
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<CefBasicLabelButtonImpl> CefBasicLabelButtonImpl::Create(
|
||||
CefRefPtr<CefButtonDelegate> delegate,
|
||||
const CefString& text,
|
||||
bool with_frame) {
|
||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||
CefRefPtr<CefBasicLabelButtonImpl> label_button =
|
||||
new CefBasicLabelButtonImpl(delegate);
|
||||
label_button->Initialize();
|
||||
if (!text.empty())
|
||||
label_button->SetText(text);
|
||||
if (with_frame)
|
||||
label_button->root_view()->SetStyle(views::CustomButton::STYLE_BUTTON);
|
||||
return label_button;
|
||||
}
|
||||
|
||||
CefBasicLabelButtonImpl::CefBasicLabelButtonImpl(CefRefPtr<CefButtonDelegate> delegate)
|
||||
: ParentClass(delegate) {
|
||||
}
|
||||
|
||||
views::LabelButton* CefBasicLabelButtonImpl::CreateRootView() {
|
||||
return new CefBasicLabelButtonView(delegate());
|
||||
}
|
45
libcef/browser/views/basic_label_button_impl.h
Normal file
45
libcef/browser/views/basic_label_button_impl.h
Normal file
@@ -0,0 +1,45 @@
|
||||
// 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_BASIC_LABEL_BUTTON_IMPL_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_BASIC_LABEL_BUTTON_IMPL_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_label_button.h"
|
||||
#include "include/views/cef_button_delegate.h"
|
||||
|
||||
#include "libcef/browser/views/label_button_impl.h"
|
||||
|
||||
#include "ui/views/controls/button/label_button.h"
|
||||
|
||||
class CefBasicLabelButtonImpl :
|
||||
public CefLabelButtonImpl<views::LabelButton, CefLabelButton,
|
||||
CefButtonDelegate> {
|
||||
public:
|
||||
typedef CefLabelButtonImpl<views::LabelButton, CefLabelButton,
|
||||
CefButtonDelegate> ParentClass;
|
||||
|
||||
// Create a new CefLabelButton instance. |delegate| may be nullptr.
|
||||
static CefRefPtr<CefBasicLabelButtonImpl> Create(
|
||||
CefRefPtr<CefButtonDelegate> delegate,
|
||||
const CefString& text,
|
||||
bool with_frame);
|
||||
|
||||
// CefViewAdapter methods:
|
||||
std::string GetDebugType() override { return "LabelButton"; }
|
||||
|
||||
private:
|
||||
// Create a new implementation object.
|
||||
// Always call Initialize() after creation.
|
||||
// |delegate| may be nullptr.
|
||||
explicit CefBasicLabelButtonImpl(CefRefPtr<CefButtonDelegate> delegate);
|
||||
|
||||
// CefViewImpl methods:
|
||||
views::LabelButton* CreateRootView() override;
|
||||
|
||||
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefBasicLabelButtonImpl);
|
||||
DISALLOW_COPY_AND_ASSIGN(CefBasicLabelButtonImpl);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_BASIC_LABEL_BUTTON_IMPL_H_
|
10
libcef/browser/views/basic_label_button_view.cc
Normal file
10
libcef/browser/views/basic_label_button_view.cc
Normal file
@@ -0,0 +1,10 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/basic_label_button_view.h"
|
||||
|
||||
CefBasicLabelButtonView::CefBasicLabelButtonView(
|
||||
CefButtonDelegate* cef_delegate)
|
||||
: ParentClass(cef_delegate) {
|
||||
}
|
37
libcef/browser/views/basic_label_button_view.h
Normal file
37
libcef/browser/views/basic_label_button_view.h
Normal file
@@ -0,0 +1,37 @@
|
||||
// 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_BASIC_LABEL_BUTTON_VIEW_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_BASIC_LABEL_BUTTON_VIEW_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_button_delegate.h"
|
||||
|
||||
#include "libcef/browser/views/label_button_view.h"
|
||||
|
||||
#include "ui/views/controls/button/label_button.h"
|
||||
|
||||
// Extend views::LabelButton with a no-argument constructor as required by the
|
||||
// CefViewView template and extend views::ButtonListener as required by the
|
||||
// CefButtonView template.
|
||||
class LabelButtonEx : public views::LabelButton,
|
||||
public views::ButtonListener {
|
||||
public:
|
||||
LabelButtonEx() : views::LabelButton(this, base::string16()) {
|
||||
}
|
||||
};
|
||||
|
||||
class CefBasicLabelButtonView :
|
||||
public CefLabelButtonView<LabelButtonEx, CefButtonDelegate> {
|
||||
public:
|
||||
typedef CefLabelButtonView<LabelButtonEx, CefButtonDelegate> ParentClass;
|
||||
|
||||
// |cef_delegate| may be nullptr.
|
||||
explicit CefBasicLabelButtonView(CefButtonDelegate* cef_delegate);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(CefBasicLabelButtonView);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_BASIC_LABEL_BUTTON_VIEW_H_
|
30
libcef/browser/views/basic_panel_impl.cc
Normal file
30
libcef/browser/views/basic_panel_impl.cc
Normal file
@@ -0,0 +1,30 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/basic_panel_impl.h"
|
||||
|
||||
#include "libcef/browser/views/basic_panel_view.h"
|
||||
|
||||
// static
|
||||
CefRefPtr<CefPanel> CefPanel::CreatePanel(
|
||||
CefRefPtr<CefPanelDelegate> delegate) {
|
||||
return CefBasicPanelImpl::Create(delegate);
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<CefBasicPanelImpl> CefBasicPanelImpl::Create(
|
||||
CefRefPtr<CefPanelDelegate> delegate) {
|
||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||
CefRefPtr<CefBasicPanelImpl> panel = new CefBasicPanelImpl(delegate);
|
||||
panel->Initialize();
|
||||
return panel;
|
||||
}
|
||||
|
||||
CefBasicPanelImpl::CefBasicPanelImpl(CefRefPtr<CefPanelDelegate> delegate)
|
||||
: ParentClass(delegate) {
|
||||
}
|
||||
|
||||
views::View* CefBasicPanelImpl::CreateRootView() {
|
||||
return new CefBasicPanelView(delegate());
|
||||
}
|
41
libcef/browser/views/basic_panel_impl.h
Normal file
41
libcef/browser/views/basic_panel_impl.h
Normal file
@@ -0,0 +1,41 @@
|
||||
// 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_BASIC_PANEL_IMPL_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_BASIC_PANEL_IMPL_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_panel.h"
|
||||
#include "include/views/cef_panel_delegate.h"
|
||||
|
||||
#include "libcef/browser/views/panel_impl.h"
|
||||
|
||||
#include "ui/views/view.h"
|
||||
|
||||
class CefBasicPanelImpl :
|
||||
public CefPanelImpl<views::View, CefPanel, CefPanelDelegate> {
|
||||
public:
|
||||
typedef CefPanelImpl<views::View, CefPanel, CefPanelDelegate> ParentClass;
|
||||
|
||||
// Create a new CefPanel instance. |delegate| may be nullptr.
|
||||
static CefRefPtr<CefBasicPanelImpl> Create(
|
||||
CefRefPtr<CefPanelDelegate> delegate);
|
||||
|
||||
// CefViewAdapter methods:
|
||||
std::string GetDebugType() override { return "Panel"; }
|
||||
|
||||
private:
|
||||
// Create a new implementation object.
|
||||
// Always call Initialize() after creation.
|
||||
// |delegate| may be nullptr.
|
||||
explicit CefBasicPanelImpl(CefRefPtr<CefPanelDelegate> delegate);
|
||||
|
||||
// CefViewImpl methods:
|
||||
views::View* CreateRootView() override;
|
||||
|
||||
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefBasicPanelImpl);
|
||||
DISALLOW_COPY_AND_ASSIGN(CefBasicPanelImpl);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_BASIC_PANEL_IMPL_H_
|
9
libcef/browser/views/basic_panel_view.cc
Normal file
9
libcef/browser/views/basic_panel_view.cc
Normal file
@@ -0,0 +1,9 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/basic_panel_view.h"
|
||||
|
||||
CefBasicPanelView::CefBasicPanelView(CefPanelDelegate* cef_delegate)
|
||||
: ParentClass(cef_delegate) {
|
||||
}
|
24
libcef/browser/views/basic_panel_view.h
Normal file
24
libcef/browser/views/basic_panel_view.h
Normal file
@@ -0,0 +1,24 @@
|
||||
// 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_BASIC_PANEL_VIEW_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_BASIC_PANEL_VIEW_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_panel_delegate.h"
|
||||
|
||||
#include "libcef/browser/views/panel_view.h"
|
||||
|
||||
class CefBasicPanelView : public CefPanelView<views::View, CefPanelDelegate> {
|
||||
public:
|
||||
typedef CefPanelView<views::View, CefPanelDelegate> ParentClass;
|
||||
|
||||
// |cef_delegate| may be nullptr.
|
||||
explicit CefBasicPanelView(CefPanelDelegate* cef_delegate);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(CefBasicPanelView);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_BASIC_PANEL_VIEW_H_
|
78
libcef/browser/views/box_layout_impl.cc
Normal file
78
libcef/browser/views/box_layout_impl.cc
Normal file
@@ -0,0 +1,78 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/box_layout_impl.h"
|
||||
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/browser/views/view_util.h"
|
||||
|
||||
// static
|
||||
CefRefPtr<CefBoxLayoutImpl> CefBoxLayoutImpl::Create(
|
||||
const CefBoxLayoutSettings& settings,
|
||||
views::View* owner_view) {
|
||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||
CefRefPtr<CefBoxLayoutImpl> impl = new CefBoxLayoutImpl(settings);
|
||||
impl->Initialize(owner_view);
|
||||
return impl;
|
||||
}
|
||||
|
||||
void CefBoxLayoutImpl::SetFlexForView(CefRefPtr<CefView> view, int flex) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
DCHECK_GE(flex, 0);
|
||||
if (flex < 0)
|
||||
return;
|
||||
|
||||
DCHECK(view && view->IsValid() && view->IsAttached());
|
||||
if (!view || !view->IsValid() || !view->IsAttached())
|
||||
return;
|
||||
|
||||
views::View* view_ptr = view_util::GetFor(view);
|
||||
DCHECK_EQ(view_ptr->parent(), owner_view());
|
||||
if (view_ptr->parent() != owner_view())
|
||||
return;
|
||||
|
||||
layout()->SetFlexForView(view_ptr, flex);
|
||||
}
|
||||
|
||||
void CefBoxLayoutImpl::ClearFlexForView(CefRefPtr<CefView> view) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
DCHECK(view && view->IsValid() && view->IsAttached());
|
||||
if (!view || !view->IsValid() || !view->IsAttached())
|
||||
return;
|
||||
|
||||
views::View* view_ptr = view_util::GetFor(view);
|
||||
DCHECK_EQ(view_ptr->parent(), owner_view());
|
||||
if (view_ptr->parent() != owner_view())
|
||||
return;
|
||||
|
||||
layout()->ClearFlexForView(view_ptr);
|
||||
}
|
||||
|
||||
CefBoxLayoutImpl::CefBoxLayoutImpl(const CefBoxLayoutSettings& settings)
|
||||
: settings_(settings) {
|
||||
}
|
||||
|
||||
views::BoxLayout* CefBoxLayoutImpl::CreateLayout() {
|
||||
views::BoxLayout* layout = new views::BoxLayout(
|
||||
settings_.horizontal ? views::BoxLayout::kHorizontal :
|
||||
views::BoxLayout::kVertical,
|
||||
settings_.inside_border_horizontal_spacing,
|
||||
settings_.inside_border_vertical_spacing,
|
||||
settings_.between_child_spacing);
|
||||
layout->set_main_axis_alignment(
|
||||
static_cast<views::BoxLayout::MainAxisAlignment>(
|
||||
settings_.main_axis_alignment));
|
||||
layout->set_cross_axis_alignment(
|
||||
static_cast<views::BoxLayout::CrossAxisAlignment>(
|
||||
settings_.cross_axis_alignment));
|
||||
layout->set_inside_border_insets(gfx::Insets(
|
||||
settings_.inside_border_insets.top,
|
||||
settings_.inside_border_insets.left,
|
||||
settings_.inside_border_insets.bottom,
|
||||
settings_.inside_border_insets.right));
|
||||
layout->set_minimum_cross_axis_size(settings_.minimum_cross_axis_size);
|
||||
if (settings_.default_flex > 0)
|
||||
layout->SetDefaultFlex(settings_.default_flex);
|
||||
return layout;
|
||||
}
|
43
libcef/browser/views/box_layout_impl.h
Normal file
43
libcef/browser/views/box_layout_impl.h
Normal file
@@ -0,0 +1,43 @@
|
||||
// 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_BOX_LAYOUT_IMPL_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_BOX_LAYOUT_IMPL_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_box_layout.h"
|
||||
|
||||
#include "libcef/browser/views/layout_impl.h"
|
||||
#include "ui/views/layout/box_layout.h"
|
||||
|
||||
class CefBoxLayoutImpl :
|
||||
public CefLayoutImpl<views::BoxLayout, CefBoxLayout> {
|
||||
public:
|
||||
// Necessary for the CEF_REQUIRE_VALID_*() macros to compile.
|
||||
typedef CefLayoutImpl<views::BoxLayout, CefBoxLayout> ParentClass;
|
||||
|
||||
// Create a new CefBoxLayout insance. |owner_view| must be non-nullptr.
|
||||
static CefRefPtr<CefBoxLayoutImpl> Create(
|
||||
const CefBoxLayoutSettings& settings,
|
||||
views::View* owner_view);
|
||||
|
||||
// CefBoxLayout methods:
|
||||
void SetFlexForView(CefRefPtr<CefView> view, int flex) override;
|
||||
void ClearFlexForView(CefRefPtr<CefView> view) override;
|
||||
|
||||
// CefLayout methods:
|
||||
CefRefPtr<CefBoxLayout> AsBoxLayout() override { return this; }
|
||||
|
||||
private:
|
||||
explicit CefBoxLayoutImpl(const CefBoxLayoutSettings& settings);
|
||||
|
||||
views::BoxLayout* CreateLayout() override;
|
||||
|
||||
CefBoxLayoutSettings settings_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefBoxLayoutImpl);
|
||||
DISALLOW_COPY_AND_ASSIGN(CefBoxLayoutImpl);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_BOX_LAYOUT_IMPL_H_
|
289
libcef/browser/views/browser_platform_delegate_views.cc
Normal file
289
libcef/browser/views/browser_platform_delegate_views.cc
Normal file
@@ -0,0 +1,289 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/browser_platform_delegate_views.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "include/views/cef_window.h"
|
||||
#include "libcef/browser/browser_host_impl.h"
|
||||
#include "libcef/browser/views/browser_view_impl.h"
|
||||
#include "libcef/browser/views/menu_runner_views.h"
|
||||
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/render_widget_host.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// Default popup window delegate implementation.
|
||||
class PopupWindowDelegate : public CefWindowDelegate {
|
||||
public:
|
||||
explicit PopupWindowDelegate(CefRefPtr<CefBrowserView> browser_view)
|
||||
: browser_view_(browser_view) {
|
||||
}
|
||||
|
||||
void OnWindowCreated(CefRefPtr<CefWindow> window) override {
|
||||
window->AddChildView(browser_view_);
|
||||
window->Show();
|
||||
browser_view_->RequestFocus();
|
||||
}
|
||||
|
||||
void OnWindowDestroyed(CefRefPtr<CefWindow> window) override {
|
||||
browser_view_ = nullptr;
|
||||
}
|
||||
|
||||
bool CanClose(CefRefPtr<CefWindow> window) override {
|
||||
CefRefPtr<CefBrowser> browser = browser_view_->GetBrowser();
|
||||
if (browser)
|
||||
return browser->GetHost()->TryCloseBrowser();
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
CefRefPtr<CefBrowserView> browser_view_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(PopupWindowDelegate);
|
||||
DISALLOW_COPY_AND_ASSIGN(PopupWindowDelegate);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
CefBrowserPlatformDelegateViews::CefBrowserPlatformDelegateViews(
|
||||
scoped_ptr<CefBrowserPlatformDelegateNative> native_delegate,
|
||||
CefRefPtr<CefBrowserViewImpl> browser_view)
|
||||
: native_delegate_(std::move(native_delegate)),
|
||||
browser_view_(browser_view) {
|
||||
native_delegate_->set_windowless_handler(this);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::set_browser_view(
|
||||
CefRefPtr<CefBrowserViewImpl> browser_view) {
|
||||
browser_view_ = browser_view;
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::WebContentsCreated(
|
||||
content::WebContents* web_contents) {
|
||||
browser_view_->WebContentsCreated(web_contents);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::BrowserCreated(
|
||||
CefBrowserHostImpl* browser) {
|
||||
CefBrowserPlatformDelegate::BrowserCreated(browser);
|
||||
|
||||
browser_view_->BrowserCreated(browser);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::NotifyBrowserCreated() {
|
||||
DCHECK(browser_view_);
|
||||
DCHECK(browser_);
|
||||
if (browser_view_->delegate())
|
||||
browser_view_->delegate()->OnBrowserCreated(browser_view_, browser_);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::NotifyBrowserDestroyed() {
|
||||
DCHECK(browser_view_);
|
||||
DCHECK(browser_);
|
||||
if (browser_view_->delegate())
|
||||
browser_view_->delegate()->OnBrowserDestroyed(browser_view_, browser_);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::BrowserDestroyed(
|
||||
CefBrowserHostImpl* browser) {
|
||||
CefBrowserPlatformDelegate::BrowserDestroyed(browser);
|
||||
|
||||
browser_view_->BrowserDestroyed(browser);
|
||||
browser_view_ = nullptr;
|
||||
}
|
||||
|
||||
bool CefBrowserPlatformDelegateViews::CreateHostWindow() {
|
||||
// Nothing to do here.
|
||||
return true;
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::CloseHostWindow() {
|
||||
views::Widget* widget = GetWindowWidget();
|
||||
if (widget && !widget->IsClosed())
|
||||
widget->Close();
|
||||
}
|
||||
|
||||
CefWindowHandle CefBrowserPlatformDelegateViews::GetHostWindowHandle() const {
|
||||
return view_util::GetWindowHandle(GetWindowWidget());
|
||||
}
|
||||
|
||||
views::Widget* CefBrowserPlatformDelegateViews::GetWindowWidget() const {
|
||||
if (browser_view_->root_view())
|
||||
return browser_view_->root_view()->GetWidget();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CefRefPtr<CefBrowserView>
|
||||
CefBrowserPlatformDelegateViews::GetBrowserView() const {
|
||||
return browser_view_.get();
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::PopupWebContentsCreated(
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefClient> client,
|
||||
content::WebContents* new_web_contents,
|
||||
CefBrowserPlatformDelegate* new_platform_delegate,
|
||||
bool is_devtools) {
|
||||
DCHECK(new_platform_delegate->IsViewsHosted());
|
||||
CefBrowserPlatformDelegateViews* new_platform_delegate_impl =
|
||||
static_cast<CefBrowserPlatformDelegateViews*>(new_platform_delegate);
|
||||
|
||||
CefRefPtr<CefBrowserViewDelegate> new_delegate;
|
||||
if (browser_view_->delegate()) {
|
||||
new_delegate = browser_view_->delegate()->GetDelegateForPopupBrowserView(
|
||||
browser_view_.get(), settings, client, is_devtools);
|
||||
}
|
||||
|
||||
// Create a new BrowserView for the popup.
|
||||
CefRefPtr<CefBrowserViewImpl> new_browser_view =
|
||||
CefBrowserViewImpl::CreateForPopup(settings, new_delegate);
|
||||
|
||||
// Associate the PlatformDelegate with the new BrowserView.
|
||||
new_platform_delegate_impl->set_browser_view(new_browser_view);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::PopupBrowserCreated(
|
||||
CefBrowserHostImpl* new_browser,
|
||||
bool is_devtools) {
|
||||
CefRefPtr<CefBrowserView> new_browser_view =
|
||||
CefBrowserView::GetForBrowser(new_browser);
|
||||
DCHECK(new_browser_view);
|
||||
|
||||
bool popup_handled = false;
|
||||
if (browser_view_->delegate()) {
|
||||
popup_handled = browser_view_->delegate()->OnPopupBrowserViewCreated(
|
||||
browser_view_.get(), new_browser_view.get(), is_devtools);
|
||||
}
|
||||
|
||||
if (!popup_handled) {
|
||||
CefWindow::CreateTopLevelWindow(
|
||||
new PopupWindowDelegate(new_browser_view.get()));
|
||||
}
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::WasResized() {
|
||||
content::RenderViewHost* host = browser_->web_contents()->GetRenderViewHost();
|
||||
if (host)
|
||||
host->GetWidget()->WasResized();
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::SendKeyEvent(
|
||||
const content::NativeWebKeyboardEvent& event) {
|
||||
content::RenderViewHost* host = browser_->web_contents()->GetRenderViewHost();
|
||||
if (host)
|
||||
host->GetWidget()->ForwardKeyboardEvent(event);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::SendMouseEvent(
|
||||
const blink::WebMouseEvent& event) {
|
||||
content::RenderViewHost* host = browser_->web_contents()->GetRenderViewHost();
|
||||
if (host)
|
||||
host->GetWidget()->ForwardMouseEvent(event);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::SendMouseWheelEvent(
|
||||
const blink::WebMouseWheelEvent& event) {
|
||||
content::RenderViewHost* host = browser_->web_contents()->GetRenderViewHost();
|
||||
if (host)
|
||||
host->GetWidget()->ForwardWheelEvent(event);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::SendFocusEvent(bool setFocus) {
|
||||
// Will result in a call to WebContents::Focus().
|
||||
if (setFocus && browser_view_->root_view())
|
||||
browser_view_->root_view()->RequestFocus();
|
||||
}
|
||||
|
||||
gfx::Point CefBrowserPlatformDelegateViews::GetScreenPoint(
|
||||
const gfx::Point& view_pt) const {
|
||||
if (!browser_view_->root_view())
|
||||
return view_pt;
|
||||
|
||||
gfx::Point screen_point = view_pt;
|
||||
view_util::ConvertPointToScreen(browser_view_->root_view(), &screen_point,
|
||||
true);
|
||||
return screen_point;
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::ViewText(const std::string& text) {
|
||||
native_delegate_->ViewText(text);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::HandleKeyboardEvent(
|
||||
const content::NativeWebKeyboardEvent& event) {
|
||||
native_delegate_->HandleKeyboardEvent(event);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::HandleExternalProtocol(const GURL& url) {
|
||||
native_delegate_->HandleExternalProtocol(url);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::TranslateKeyEvent(
|
||||
content::NativeWebKeyboardEvent& result,
|
||||
const CefKeyEvent& key_event) const {
|
||||
native_delegate_->TranslateKeyEvent(result, key_event);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::TranslateClickEvent(
|
||||
blink::WebMouseEvent& result,
|
||||
const CefMouseEvent& mouse_event,
|
||||
CefBrowserHost::MouseButtonType type,
|
||||
bool mouseUp, int clickCount) const {
|
||||
native_delegate_->TranslateClickEvent(result, mouse_event, type, mouseUp,
|
||||
clickCount);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::TranslateMoveEvent(
|
||||
blink::WebMouseEvent& result,
|
||||
const CefMouseEvent& mouse_event,
|
||||
bool mouseLeave) const {
|
||||
native_delegate_->TranslateMoveEvent(result, mouse_event, mouseLeave);
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateViews::TranslateWheelEvent(
|
||||
blink::WebMouseWheelEvent& result,
|
||||
const CefMouseEvent& mouse_event,
|
||||
int deltaX, int deltaY) const {
|
||||
native_delegate_->TranslateWheelEvent(result, mouse_event, deltaX, deltaY);
|
||||
}
|
||||
|
||||
CefEventHandle CefBrowserPlatformDelegateViews::GetEventHandle(
|
||||
const content::NativeWebKeyboardEvent& event) const {
|
||||
return native_delegate_->GetEventHandle(event);
|
||||
}
|
||||
|
||||
scoped_ptr<CefFileDialogRunner>
|
||||
CefBrowserPlatformDelegateViews::CreateFileDialogRunner() {
|
||||
return native_delegate_->CreateFileDialogRunner();
|
||||
}
|
||||
|
||||
scoped_ptr<CefJavaScriptDialogRunner>
|
||||
CefBrowserPlatformDelegateViews::CreateJavaScriptDialogRunner() {
|
||||
return native_delegate_->CreateJavaScriptDialogRunner();
|
||||
}
|
||||
|
||||
scoped_ptr<CefMenuRunner> CefBrowserPlatformDelegateViews::CreateMenuRunner() {
|
||||
return make_scoped_ptr(new CefMenuRunnerViews(browser_view_.get()));
|
||||
}
|
||||
|
||||
bool CefBrowserPlatformDelegateViews::IsWindowless() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CefBrowserPlatformDelegateViews::IsViewsHosted() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
CefWindowHandle CefBrowserPlatformDelegateViews::GetParentWindowHandle() const {
|
||||
return GetHostWindowHandle();
|
||||
}
|
||||
|
||||
gfx::Point CefBrowserPlatformDelegateViews::GetParentScreenPoint(
|
||||
const gfx::Point& view) const {
|
||||
return GetScreenPoint(view);
|
||||
}
|
84
libcef/browser/views/browser_platform_delegate_views.h
Normal file
84
libcef/browser/views/browser_platform_delegate_views.h
Normal file
@@ -0,0 +1,84 @@
|
||||
// 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_BROWSER_PLATFORM_DELEGATE_VIEWS_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_BROWSER_PLATFORM_DELEGATE_VIEWS_H_
|
||||
|
||||
#include "libcef/browser/browser_platform_delegate.h"
|
||||
#include "libcef/browser/native/browser_platform_delegate_native.h"
|
||||
#include "libcef/browser/views/browser_view_impl.h"
|
||||
|
||||
// Implementation of Views-based browser functionality.
|
||||
class CefBrowserPlatformDelegateViews :
|
||||
public CefBrowserPlatformDelegate,
|
||||
public CefBrowserPlatformDelegateNative::WindowlessHandler {
|
||||
public:
|
||||
// Platform-specific behaviors will be delegated to |native_delegate|.
|
||||
// |browser_view_getter| may be initially empty for popup browsers.
|
||||
CefBrowserPlatformDelegateViews(
|
||||
scoped_ptr<CefBrowserPlatformDelegateNative> native_delegate,
|
||||
CefRefPtr<CefBrowserViewImpl> browser_view);
|
||||
|
||||
void set_browser_view(CefRefPtr<CefBrowserViewImpl> browser_view);
|
||||
|
||||
// CefBrowserPlatformDelegate methods:
|
||||
void WebContentsCreated(content::WebContents* web_contents) override;
|
||||
void BrowserCreated(CefBrowserHostImpl* browser) override;
|
||||
void NotifyBrowserCreated() override;
|
||||
void NotifyBrowserDestroyed() override;
|
||||
void BrowserDestroyed(CefBrowserHostImpl* browser) override;
|
||||
bool CreateHostWindow() override;
|
||||
void CloseHostWindow() override;
|
||||
CefWindowHandle GetHostWindowHandle() const override;
|
||||
views::Widget* GetWindowWidget() const override;
|
||||
CefRefPtr<CefBrowserView> GetBrowserView() const override;
|
||||
void PopupWebContentsCreated(
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefClient> client,
|
||||
content::WebContents* new_web_contents,
|
||||
CefBrowserPlatformDelegate* new_platform_delegate,
|
||||
bool is_devtools) override;
|
||||
void PopupBrowserCreated(
|
||||
CefBrowserHostImpl* new_browser,
|
||||
bool is_devtools) override;
|
||||
void WasResized() override;
|
||||
void SendKeyEvent(const content::NativeWebKeyboardEvent& event) override;
|
||||
void SendMouseEvent(const blink::WebMouseEvent& event) override;
|
||||
void SendMouseWheelEvent(const blink::WebMouseWheelEvent& event) override;
|
||||
void SendFocusEvent(bool setFocus) override;
|
||||
gfx::Point GetScreenPoint(const gfx::Point& view) const override;
|
||||
void ViewText(const std::string& text) override;
|
||||
void HandleKeyboardEvent(
|
||||
const content::NativeWebKeyboardEvent& event) override;
|
||||
void HandleExternalProtocol(const GURL& url) override;
|
||||
void TranslateKeyEvent(content::NativeWebKeyboardEvent& result,
|
||||
const CefKeyEvent& key_event) const override;
|
||||
void TranslateClickEvent(blink::WebMouseEvent& result,
|
||||
const CefMouseEvent& mouse_event,
|
||||
CefBrowserHost::MouseButtonType type,
|
||||
bool mouseUp, int clickCount) const override;
|
||||
void TranslateMoveEvent(blink::WebMouseEvent& result,
|
||||
const CefMouseEvent& mouse_event,
|
||||
bool mouseLeave) const override;
|
||||
void TranslateWheelEvent(blink::WebMouseWheelEvent& result,
|
||||
const CefMouseEvent& mouse_event,
|
||||
int deltaX, int deltaY) const override;
|
||||
CefEventHandle GetEventHandle(
|
||||
const content::NativeWebKeyboardEvent& event) const override;
|
||||
scoped_ptr<CefFileDialogRunner> CreateFileDialogRunner() override;
|
||||
scoped_ptr<CefJavaScriptDialogRunner> CreateJavaScriptDialogRunner() override;
|
||||
scoped_ptr<CefMenuRunner> CreateMenuRunner() override;
|
||||
bool IsWindowless() const override;
|
||||
bool IsViewsHosted() const override;
|
||||
|
||||
// CefBrowserPlatformDelegateNative::WindowlessHandler methods:
|
||||
CefWindowHandle GetParentWindowHandle() const override;
|
||||
gfx::Point GetParentScreenPoint(const gfx::Point& view) const override;
|
||||
|
||||
private:
|
||||
scoped_ptr<CefBrowserPlatformDelegateNative> native_delegate_;
|
||||
CefRefPtr<CefBrowserViewImpl> browser_view_;
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_BROWSER_PLATFORM_DELEGATE_VIEWS_H_
|
165
libcef/browser/views/browser_view_impl.cc
Normal file
165
libcef/browser/views/browser_view_impl.cc
Normal file
@@ -0,0 +1,165 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/browser_view_impl.h"
|
||||
|
||||
#include "libcef/browser/browser_host_impl.h"
|
||||
#include "libcef/browser/context.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
|
||||
// static
|
||||
CefRefPtr<CefBrowserView> CefBrowserView::CreateBrowserView(
|
||||
CefRefPtr<CefClient> client,
|
||||
const CefString& url,
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefRequestContext> request_context,
|
||||
CefRefPtr<CefBrowserViewDelegate> delegate) {
|
||||
return CefBrowserViewImpl::Create(client, url, settings, request_context,
|
||||
delegate);
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<CefBrowserView> CefBrowserView::GetForBrowser(
|
||||
CefRefPtr<CefBrowser> browser) {
|
||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||
CefBrowserHostImpl* browser_impl =
|
||||
static_cast<CefBrowserHostImpl*>(browser.get());
|
||||
if (browser_impl && browser_impl->IsViewsHosted())
|
||||
return browser_impl->GetBrowserView();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<CefBrowserViewImpl> CefBrowserViewImpl::Create(
|
||||
CefRefPtr<CefClient> client,
|
||||
const CefString& url,
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefRequestContext> request_context,
|
||||
CefRefPtr<CefBrowserViewDelegate> delegate) {
|
||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||
CefRefPtr<CefBrowserViewImpl> browser_view = new CefBrowserViewImpl(delegate);
|
||||
browser_view->SetPendingBrowserCreateParams(client, url, settings,
|
||||
request_context);
|
||||
browser_view->Initialize();
|
||||
browser_view->SetDefaults(settings);
|
||||
return browser_view;
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<CefBrowserViewImpl> CefBrowserViewImpl::CreateForPopup(
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefBrowserViewDelegate> delegate) {
|
||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||
CefRefPtr<CefBrowserViewImpl> browser_view = new CefBrowserViewImpl(delegate);
|
||||
browser_view->Initialize();
|
||||
browser_view->SetDefaults(settings);
|
||||
return browser_view;
|
||||
}
|
||||
|
||||
void CefBrowserViewImpl::WebContentsCreated(
|
||||
content::WebContents* web_contents) {
|
||||
if (root_view())
|
||||
root_view()->SetWebContents(web_contents);
|
||||
}
|
||||
|
||||
void CefBrowserViewImpl::BrowserCreated(CefBrowserHostImpl* browser) {
|
||||
browser_ = browser;
|
||||
}
|
||||
|
||||
void CefBrowserViewImpl::BrowserDestroyed(CefBrowserHostImpl* browser) {
|
||||
DCHECK_EQ(browser, browser_);
|
||||
browser_ = nullptr;
|
||||
|
||||
if (root_view())
|
||||
root_view()->SetWebContents(nullptr);
|
||||
}
|
||||
|
||||
CefRefPtr<CefBrowser> CefBrowserViewImpl::GetBrowser() {
|
||||
CEF_REQUIRE_VALID_RETURN(nullptr);
|
||||
return browser_;
|
||||
}
|
||||
|
||||
void CefBrowserViewImpl::SetBackgroundColor(cef_color_t color) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
ParentClass::SetBackgroundColor(color);
|
||||
if (root_view())
|
||||
root_view()->SetResizeBackgroundColor(color);
|
||||
}
|
||||
|
||||
void CefBrowserViewImpl::Detach() {
|
||||
ParentClass::Detach();
|
||||
|
||||
// root_view() will be nullptr now.
|
||||
DCHECK(!root_view());
|
||||
|
||||
if (browser_) {
|
||||
// |browser_| will disappear when WindowDestroyed() indirectly calls
|
||||
// BrowserDestroyed() so keep a reference.
|
||||
CefRefPtr<CefBrowserHostImpl> browser = browser_;
|
||||
|
||||
// Force the browser to be destroyed.
|
||||
browser->WindowDestroyed();
|
||||
}
|
||||
}
|
||||
|
||||
void CefBrowserViewImpl::GetDebugInfo(base::DictionaryValue* info,
|
||||
bool include_children) {
|
||||
ParentClass::GetDebugInfo(info, include_children);
|
||||
if (browser_)
|
||||
info->SetString("url", browser_->GetMainFrame()->GetURL().ToString());
|
||||
}
|
||||
|
||||
void CefBrowserViewImpl::OnBrowserViewAdded() {
|
||||
if (!browser_ && pending_browser_create_params_) {
|
||||
// Top-level browsers will be created when this view is added to the views
|
||||
// hierarchy.
|
||||
pending_browser_create_params_->browser_view = this;
|
||||
|
||||
CefBrowserHostImpl::Create(*pending_browser_create_params_);
|
||||
DCHECK(browser_);
|
||||
|
||||
pending_browser_create_params_.reset(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
CefBrowserViewImpl::CefBrowserViewImpl(
|
||||
CefRefPtr<CefBrowserViewDelegate> delegate)
|
||||
: ParentClass(delegate) {
|
||||
}
|
||||
|
||||
void CefBrowserViewImpl::SetPendingBrowserCreateParams(
|
||||
CefRefPtr<CefClient> client,
|
||||
const CefString& url,
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefRequestContext> request_context) {
|
||||
DCHECK(!pending_browser_create_params_);
|
||||
pending_browser_create_params_.reset(new CefBrowserHostImpl::CreateParams());
|
||||
pending_browser_create_params_->client = client;
|
||||
pending_browser_create_params_->url = url;
|
||||
pending_browser_create_params_->settings = settings;
|
||||
pending_browser_create_params_->request_context = request_context;
|
||||
}
|
||||
|
||||
void CefBrowserViewImpl::SetDefaults(const CefBrowserSettings& settings) {
|
||||
SkColor background_color = SK_ColorWHITE;
|
||||
if (CefColorGetA(settings.background_color) > 0) {
|
||||
background_color = SkColorSetRGB(
|
||||
CefColorGetR(settings.background_color),
|
||||
CefColorGetG(settings.background_color),
|
||||
CefColorGetB(settings.background_color));
|
||||
} else {
|
||||
const CefSettings& global_settings = CefContext::Get()->settings();
|
||||
if (CefColorGetA(global_settings.background_color) > 0) {
|
||||
background_color = SkColorSetRGB(
|
||||
CefColorGetR(global_settings.background_color),
|
||||
CefColorGetG(global_settings.background_color),
|
||||
CefColorGetB(global_settings.background_color));
|
||||
}
|
||||
}
|
||||
SetBackgroundColor(background_color);
|
||||
}
|
||||
|
||||
CefBrowserViewView* CefBrowserViewImpl::CreateRootView() {
|
||||
return new CefBrowserViewView(delegate(), this);
|
||||
}
|
85
libcef/browser/views/browser_view_impl.h
Normal file
85
libcef/browser/views/browser_view_impl.h
Normal file
@@ -0,0 +1,85 @@
|
||||
// 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_BROWSER_VIEW_IMPL_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_BROWSER_VIEW_IMPL_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/cef_client.h"
|
||||
#include "include/views/cef_browser_view.h"
|
||||
#include "include/views/cef_browser_view_delegate.h"
|
||||
|
||||
#include "libcef/browser/browser_host_impl.h"
|
||||
#include "libcef/browser/views/view_impl.h"
|
||||
#include "libcef/browser/views/browser_view_view.h"
|
||||
|
||||
class CefBrowserViewImpl :
|
||||
public CefViewImpl<CefBrowserViewView, CefBrowserView,
|
||||
CefBrowserViewDelegate>,
|
||||
public CefBrowserViewView::Delegate {
|
||||
public:
|
||||
typedef CefViewImpl<CefBrowserViewView, CefBrowserView,
|
||||
CefBrowserViewDelegate> ParentClass;
|
||||
|
||||
// Create a new CefBrowserView instance. |delegate| may be nullptr.
|
||||
static CefRefPtr<CefBrowserViewImpl> Create(
|
||||
CefRefPtr<CefClient> client,
|
||||
const CefString& url,
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefRequestContext> request_context,
|
||||
CefRefPtr<CefBrowserViewDelegate> delegate);
|
||||
|
||||
// Create a new CefBrowserView instance for a popup. |delegate| may be
|
||||
// nullptr.
|
||||
static CefRefPtr<CefBrowserViewImpl> CreateForPopup(
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefBrowserViewDelegate> delegate);
|
||||
|
||||
// Called from CefBrowserPlatformDelegateViews.
|
||||
void WebContentsCreated(content::WebContents* web_contents);
|
||||
void BrowserCreated(CefBrowserHostImpl* browser);
|
||||
void BrowserDestroyed(CefBrowserHostImpl* browser);
|
||||
|
||||
// CefBrowserView methods:
|
||||
CefRefPtr<CefBrowser> GetBrowser() override;
|
||||
|
||||
// CefView methods:
|
||||
CefRefPtr<CefBrowserView> AsBrowserView() override { return this; }
|
||||
void SetBackgroundColor(cef_color_t color) override;
|
||||
|
||||
// CefViewAdapter methods:
|
||||
void Detach() override;
|
||||
std::string GetDebugType() override { return "BrowserView"; }
|
||||
void GetDebugInfo(base::DictionaryValue* info,
|
||||
bool include_children) override;
|
||||
|
||||
// CefBrowserViewView::Delegate methods:
|
||||
void OnBrowserViewAdded() override;
|
||||
|
||||
private:
|
||||
// Create a new implementation object.
|
||||
// Always call Initialize() after creation.
|
||||
// |delegate| may be nullptr.
|
||||
explicit CefBrowserViewImpl(CefRefPtr<CefBrowserViewDelegate> delegate);
|
||||
|
||||
void SetPendingBrowserCreateParams(
|
||||
CefRefPtr<CefClient> client,
|
||||
const CefString& url,
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefRequestContext> request_context);
|
||||
|
||||
void SetDefaults(const CefBrowserSettings& settings);
|
||||
|
||||
// CefViewImpl methods:
|
||||
CefBrowserViewView* CreateRootView() override;
|
||||
|
||||
scoped_ptr<CefBrowserHostImpl::CreateParams> pending_browser_create_params_;
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> browser_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefBrowserViewImpl);
|
||||
DISALLOW_COPY_AND_ASSIGN(CefBrowserViewImpl);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_BROWSER_VIEW_IMPL_H_
|
35
libcef/browser/views/browser_view_view.cc
Normal file
35
libcef/browser/views/browser_view_view.cc
Normal file
@@ -0,0 +1,35 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/browser_view_view.h"
|
||||
|
||||
#include "libcef/browser/views/browser_view_impl.h"
|
||||
|
||||
CefBrowserViewView::CefBrowserViewView(CefBrowserViewDelegate* cef_delegate,
|
||||
Delegate* browser_view_delegate)
|
||||
: ParentClass(cef_delegate),
|
||||
browser_view_delegate_(browser_view_delegate) {
|
||||
DCHECK(browser_view_delegate_);
|
||||
}
|
||||
|
||||
void CefBrowserViewView::ViewHierarchyChanged(
|
||||
const ViewHierarchyChangedDetails& details) {
|
||||
ParentClass::ViewHierarchyChanged(details);
|
||||
if (details.is_add && details.child == this) {
|
||||
gfx::Size size = GetPreferredSize();
|
||||
if (size.IsEmpty()) {
|
||||
// No size was provided for this View. Size it to the parent by default
|
||||
// or, depending on the Layout, the browser may be initially 0x0 size and
|
||||
// will not display until the parent is next resized (resulting in a call
|
||||
// to WebView::OnBoundsChanged). For example, this can happen when adding
|
||||
// this View to a CefWindow with FillLayout and then calling
|
||||
// CefWindow::Show() without first resizing the CefWindow.
|
||||
size = details.parent->GetPreferredSize();
|
||||
if (!size.IsEmpty())
|
||||
SetSize(size);
|
||||
}
|
||||
|
||||
browser_view_delegate_->OnBrowserViewAdded();
|
||||
}
|
||||
}
|
53
libcef/browser/views/browser_view_view.h
Normal file
53
libcef/browser/views/browser_view_view.h
Normal file
@@ -0,0 +1,53 @@
|
||||
// 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_BROWSER_VIEW_VIEW_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_BROWSER_VIEW_VIEW_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_browser_view_delegate.h"
|
||||
|
||||
#include "libcef/browser/views/view_view.h"
|
||||
|
||||
#include "ui/views/controls/webview/webview.h"
|
||||
|
||||
// Extend views::WebView with a no-argument constructor as required by the
|
||||
// CefViewView template.
|
||||
class WebViewEx : public views::WebView {
|
||||
public:
|
||||
WebViewEx() : views::WebView(nullptr) {
|
||||
}
|
||||
};
|
||||
|
||||
class CefBrowserViewView :
|
||||
public CefViewView<WebViewEx, CefBrowserViewDelegate> {
|
||||
public:
|
||||
typedef CefViewView<WebViewEx, CefBrowserViewDelegate> ParentClass;
|
||||
|
||||
class Delegate {
|
||||
public:
|
||||
// Called when the BrowserView has been added to a parent view.
|
||||
virtual void OnBrowserViewAdded() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~Delegate() {}
|
||||
};
|
||||
|
||||
// |cef_delegate| may be nullptr.
|
||||
// |browser_view_delegate| must be non-nullptr.
|
||||
CefBrowserViewView(CefBrowserViewDelegate* cef_delegate,
|
||||
Delegate* browser_view_delegate);
|
||||
|
||||
// View methods:
|
||||
void ViewHierarchyChanged(
|
||||
const ViewHierarchyChangedDetails& details) override;
|
||||
|
||||
private:
|
||||
// Not owned by this object.
|
||||
Delegate* browser_view_delegate_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefBrowserViewView);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_BROWSER_VIEW_VIEW_H_
|
72
libcef/browser/views/button_impl.h
Normal file
72
libcef/browser/views/button_impl.h
Normal file
@@ -0,0 +1,72 @@
|
||||
// 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_BUTTON_IMPL_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_BUTTON_IMPL_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_button.h"
|
||||
#include "include/views/cef_label_button.h"
|
||||
|
||||
#include "libcef/browser/views/view_impl.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "ui/views/controls/button/custom_button.h"
|
||||
|
||||
// Helpers for template boiler-plate.
|
||||
#define CEF_BUTTON_IMPL_T CEF_VIEW_IMPL_T
|
||||
#define CEF_BUTTON_IMPL_A CEF_VIEW_IMPL_A
|
||||
#define CEF_BUTTON_IMPL_D CefButtonImpl<CEF_BUTTON_IMPL_A>
|
||||
|
||||
// Template for implementing CefButton-derived classes. See comments in
|
||||
// view_impl.h for a usage overview.
|
||||
CEF_BUTTON_IMPL_T class CefButtonImpl : public CEF_VIEW_IMPL_D {
|
||||
public:
|
||||
typedef CEF_VIEW_IMPL_D ParentClass;
|
||||
|
||||
// CefButton methods. When adding new As*() methods make sure to update
|
||||
// CefViewAdapter::GetFor() in view_adapter.cc.
|
||||
CefRefPtr<CefLabelButton> AsLabelButton() override { return nullptr; }
|
||||
void SetState(cef_button_state_t state) override;
|
||||
cef_button_state_t GetState() override;
|
||||
void SetTooltipText(const CefString& tooltip_text) override;
|
||||
void SetAccessibleName(const CefString& name) override;
|
||||
|
||||
// CefView methods:
|
||||
CefRefPtr<CefButton> AsButton() override { return this; }
|
||||
|
||||
protected:
|
||||
// Create a new implementation object.
|
||||
// Always call Initialize() after creation.
|
||||
// |delegate| may be nullptr.
|
||||
explicit CefButtonImpl(CefRefPtr<CefViewDelegateClass> delegate)
|
||||
: ParentClass(delegate) {
|
||||
}
|
||||
};
|
||||
|
||||
CEF_BUTTON_IMPL_T void CEF_BUTTON_IMPL_D::SetState(cef_button_state_t state) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
ParentClass::root_view()->SetState(
|
||||
static_cast<views::Button::ButtonState>(state));
|
||||
}
|
||||
|
||||
CEF_BUTTON_IMPL_T cef_button_state_t CEF_BUTTON_IMPL_D::GetState() {
|
||||
CEF_REQUIRE_VALID_RETURN(CEF_BUTTON_STATE_NORMAL);
|
||||
return static_cast<cef_button_state_t>(ParentClass::root_view()->state());
|
||||
}
|
||||
|
||||
CEF_BUTTON_IMPL_T void CEF_BUTTON_IMPL_D::SetTooltipText(
|
||||
const CefString& tooltip_text) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
ParentClass::root_view()->SetTooltipText(tooltip_text);
|
||||
}
|
||||
|
||||
CEF_BUTTON_IMPL_T void CEF_BUTTON_IMPL_D::SetAccessibleName(
|
||||
const CefString& name) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
ParentClass::root_view()->SetAccessibleName(name);
|
||||
}
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_BUTTON_IMPL_H_
|
54
libcef/browser/views/button_view.h
Normal file
54
libcef/browser/views/button_view.h
Normal file
@@ -0,0 +1,54 @@
|
||||
// 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_BUTTON_VIEW_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_BUTTON_VIEW_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_button_delegate.h"
|
||||
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/browser/views/view_view.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "ui/views/controls/button/custom_button.h"
|
||||
|
||||
// Helpers for template boiler-plate.
|
||||
#define CEF_BUTTON_VIEW_T CEF_VIEW_VIEW_T
|
||||
#define CEF_BUTTON_VIEW_A CEF_VIEW_VIEW_A
|
||||
#define CEF_BUTTON_VIEW_D CefButtonView<CEF_BUTTON_VIEW_A>
|
||||
|
||||
// Template for implementing views::CustomButton-derived classes. The
|
||||
// views::CustomButton-derived type passed to this template must extend
|
||||
// views::ButtonListener (for example, see LabelButtonEx from
|
||||
// basic_label_button_view.h). See comments in view_impl.h for a usage overview.
|
||||
CEF_BUTTON_VIEW_T class CefButtonView : public CEF_VIEW_VIEW_D {
|
||||
public:
|
||||
typedef CEF_VIEW_VIEW_D ParentClass;
|
||||
|
||||
// |cef_delegate| may be nullptr.
|
||||
explicit CefButtonView(CefViewDelegateClass* cef_delegate)
|
||||
: ParentClass(cef_delegate) {
|
||||
}
|
||||
|
||||
// Returns the CefButton associated with this view. See comments on
|
||||
// CefViewView::GetCefView.
|
||||
CefRefPtr<CefButton> GetCefButton() const {
|
||||
CefRefPtr<CefButton> button = ParentClass::GetCefView()->AsButton();
|
||||
DCHECK(button);
|
||||
return button;
|
||||
}
|
||||
|
||||
// views::ButtonListener methods:
|
||||
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
|
||||
};
|
||||
|
||||
CEF_BUTTON_VIEW_T void CEF_BUTTON_VIEW_D::ButtonPressed(
|
||||
views::Button* sender, const ui::Event& event) {
|
||||
if (ParentClass::cef_delegate())
|
||||
ParentClass::cef_delegate()->OnButtonPressed(GetCefButton());
|
||||
}
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_BUTTON_VIEW_H_
|
104
libcef/browser/views/display_impl.cc
Normal file
104
libcef/browser/views/display_impl.cc
Normal file
@@ -0,0 +1,104 @@
|
||||
// Copyright (c) 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.
|
||||
|
||||
#include "libcef/browser/views/display_impl.h"
|
||||
|
||||
#include "libcef/browser/views/view_util.h"
|
||||
|
||||
#include "ui/gfx/screen.h"
|
||||
|
||||
// static
|
||||
CefRefPtr<CefDisplay> CefDisplay::GetPrimaryDisplay() {
|
||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||
return new CefDisplayImpl(gfx::Screen::GetScreen()->GetPrimaryDisplay());
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<CefDisplay> CefDisplay::GetDisplayNearestPoint(
|
||||
const CefPoint& point,
|
||||
bool input_pixel_coords) {
|
||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||
return new CefDisplayImpl(view_util::GetDisplayNearestPoint(
|
||||
gfx::Point(point.x, point.y), input_pixel_coords));
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<CefDisplay> CefDisplay::GetDisplayMatchingBounds(
|
||||
const CefRect& bounds,
|
||||
bool input_pixel_coords) {
|
||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||
return new CefDisplayImpl(view_util::GetDisplayMatchingBounds(
|
||||
gfx::Rect(bounds.x, bounds.y, bounds.width, bounds.height),
|
||||
input_pixel_coords));
|
||||
}
|
||||
|
||||
// static
|
||||
size_t CefDisplay::GetDisplayCount() {
|
||||
CEF_REQUIRE_UIT_RETURN(0U);
|
||||
return static_cast<size_t>(gfx::Screen::GetScreen()->GetNumDisplays());
|
||||
}
|
||||
|
||||
// static
|
||||
void CefDisplay::GetAllDisplays(std::vector<CefRefPtr<CefDisplay> >& displays) {
|
||||
CEF_REQUIRE_UIT_RETURN_VOID();
|
||||
|
||||
displays.clear();
|
||||
|
||||
typedef std::vector<gfx::Display> DisplayVector;
|
||||
DisplayVector vec = gfx::Screen::GetScreen()->GetAllDisplays();
|
||||
for (size_t i = 0; i < vec.size(); ++i)
|
||||
displays.push_back(new CefDisplayImpl(vec[i]));
|
||||
}
|
||||
|
||||
CefDisplayImpl::CefDisplayImpl(const gfx::Display& display)
|
||||
: display_(display) {
|
||||
CEF_REQUIRE_UIT();
|
||||
}
|
||||
|
||||
CefDisplayImpl::~CefDisplayImpl() {
|
||||
CEF_REQUIRE_UIT();
|
||||
}
|
||||
|
||||
int64 CefDisplayImpl::GetID() {
|
||||
CEF_REQUIRE_UIT_RETURN(-1);
|
||||
return display_.id();
|
||||
}
|
||||
|
||||
float CefDisplayImpl::GetDeviceScaleFactor() {
|
||||
CEF_REQUIRE_UIT_RETURN(0.0f);
|
||||
return display_.device_scale_factor();
|
||||
}
|
||||
|
||||
void CefDisplayImpl::ConvertPointToPixels(CefPoint& point) {
|
||||
CEF_REQUIRE_UIT_RETURN_VOID();
|
||||
gfx::Point gfx_point(point.x, point.y);
|
||||
view_util::ConvertPointToPixels(&gfx_point, display_.device_scale_factor());
|
||||
point = CefPoint(gfx_point.x(), gfx_point.y());
|
||||
}
|
||||
|
||||
void CefDisplayImpl::ConvertPointFromPixels(CefPoint& point) {
|
||||
CEF_REQUIRE_UIT_RETURN_VOID();
|
||||
gfx::Point gfx_point(point.x, point.y);
|
||||
view_util::ConvertPointFromPixels(&gfx_point, display_.device_scale_factor());
|
||||
point = CefPoint(gfx_point.x(), gfx_point.y());
|
||||
}
|
||||
|
||||
CefRect CefDisplayImpl::GetBounds() {
|
||||
CEF_REQUIRE_UIT_RETURN(CefRect());
|
||||
const gfx::Rect& gfx_rect = display_.bounds();
|
||||
return CefRect(gfx_rect.x(), gfx_rect.y(),
|
||||
gfx_rect.width(), gfx_rect.height());
|
||||
}
|
||||
|
||||
CefRect CefDisplayImpl::GetWorkArea() {
|
||||
CEF_REQUIRE_UIT_RETURN(CefRect());
|
||||
const gfx::Rect& gfx_rect = display_.work_area();
|
||||
return CefRect(gfx_rect.x(), gfx_rect.y(),
|
||||
gfx_rect.width(), gfx_rect.height());
|
||||
}
|
||||
|
||||
int CefDisplayImpl::GetRotation() {
|
||||
CEF_REQUIRE_UIT_RETURN(0);
|
||||
return display_.RotationAsDegree();
|
||||
}
|
37
libcef/browser/views/display_impl.h
Normal file
37
libcef/browser/views/display_impl.h
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright (c) 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_DISPLAY_IMPL_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_DISPLAY_IMPL_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_display.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
|
||||
#include "ui/gfx/display.h"
|
||||
|
||||
class CefDisplayImpl : public CefDisplay {
|
||||
public:
|
||||
explicit CefDisplayImpl(const gfx::Display& display);
|
||||
~CefDisplayImpl() override;
|
||||
|
||||
// CefDisplay methods:
|
||||
int64 GetID() override;
|
||||
float GetDeviceScaleFactor() override;
|
||||
void ConvertPointToPixels(CefPoint& point) override;
|
||||
void ConvertPointFromPixels(CefPoint& point) override;
|
||||
CefRect GetBounds() override;
|
||||
CefRect GetWorkArea() override;
|
||||
int GetRotation() override;
|
||||
|
||||
const gfx::Display& display() const { return display_; }
|
||||
|
||||
private:
|
||||
gfx::Display display_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefDisplayImpl);
|
||||
DISALLOW_COPY_AND_ASSIGN(CefDisplayImpl);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_DISPLAY_IMPL_H_
|
22
libcef/browser/views/fill_layout_impl.cc
Normal file
22
libcef/browser/views/fill_layout_impl.cc
Normal file
@@ -0,0 +1,22 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/fill_layout_impl.h"
|
||||
|
||||
#include "libcef/browser/thread_util.h"
|
||||
|
||||
// static
|
||||
CefRefPtr<CefFillLayout> CefFillLayoutImpl::Create(views::View* owner_view) {
|
||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||
CefRefPtr<CefFillLayoutImpl> impl = new CefFillLayoutImpl();
|
||||
impl->Initialize(owner_view);
|
||||
return impl;
|
||||
}
|
||||
|
||||
CefFillLayoutImpl::CefFillLayoutImpl() {
|
||||
}
|
||||
|
||||
views::FillLayout* CefFillLayoutImpl::CreateLayout() {
|
||||
return new views::FillLayout();
|
||||
}
|
32
libcef/browser/views/fill_layout_impl.h
Normal file
32
libcef/browser/views/fill_layout_impl.h
Normal file
@@ -0,0 +1,32 @@
|
||||
// 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_FILL_LAYOUT_IMPL_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_FILL_LAYOUT_IMPL_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_fill_layout.h"
|
||||
|
||||
#include "libcef/browser/views/layout_impl.h"
|
||||
#include "ui/views/layout/fill_layout.h"
|
||||
|
||||
class CefFillLayoutImpl :
|
||||
public CefLayoutImpl<views::FillLayout, CefFillLayout> {
|
||||
public:
|
||||
// Create a new CefFillLayout insance. |owner_view| must be non-nullptr.
|
||||
static CefRefPtr<CefFillLayout> Create(views::View* owner_view);
|
||||
|
||||
// CefLayout methods:
|
||||
CefRefPtr<CefFillLayout> AsFillLayout() override { return this; }
|
||||
|
||||
private:
|
||||
CefFillLayoutImpl();
|
||||
|
||||
views::FillLayout* CreateLayout() override;
|
||||
|
||||
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefFillLayoutImpl);
|
||||
DISALLOW_COPY_AND_ASSIGN(CefFillLayoutImpl);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_FILL_LAYOUT_IMPL_H_
|
137
libcef/browser/views/label_button_impl.h
Normal file
137
libcef/browser/views/label_button_impl.h
Normal file
@@ -0,0 +1,137 @@
|
||||
// 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_LABEL_BUTTON_IMPL_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_LABEL_BUTTON_IMPL_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_button.h"
|
||||
#include "include/views/cef_label_button.h"
|
||||
#include "include/views/cef_menu_button.h"
|
||||
|
||||
#include "libcef/browser/image_impl.h"
|
||||
#include "libcef/browser/views/button_impl.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "ui/views/controls/button/label_button.h"
|
||||
|
||||
// Helpers for template boiler-plate.
|
||||
#define CEF_LABEL_BUTTON_IMPL_T CEF_BUTTON_IMPL_T
|
||||
#define CEF_LABEL_BUTTON_IMPL_A CEF_BUTTON_IMPL_A
|
||||
#define CEF_LABEL_BUTTON_IMPL_D CefLabelButtonImpl<CEF_LABEL_BUTTON_IMPL_A>
|
||||
|
||||
// Template for implementing CefLabelButton-derived classes. See comments in
|
||||
// view_impl.h for a usage overview.
|
||||
CEF_LABEL_BUTTON_IMPL_T class CefLabelButtonImpl : public CEF_BUTTON_IMPL_D {
|
||||
public:
|
||||
typedef CEF_BUTTON_IMPL_D ParentClass;
|
||||
|
||||
// CefLabelButton methods. When adding new As*() methods make sure to update
|
||||
// CefViewAdapter::GetFor() in view_adapter.cc.
|
||||
void SetText(const CefString& text) override;
|
||||
CefString GetText() override;
|
||||
void SetImage(cef_button_state_t button_state,
|
||||
CefRefPtr<CefImage> image) override;
|
||||
CefRefPtr<CefImage> GetImage(cef_button_state_t button_state) override;
|
||||
void SetTextColor(cef_button_state_t for_state, cef_color_t color) override;
|
||||
void SetEnabledTextColors(cef_color_t color) override;
|
||||
void SetFontList(const CefString& font_list) override;
|
||||
void SetHorizontalAlignment(cef_horizontal_alignment_t alignment) override;
|
||||
void SetMinimumSize(const CefSize& size) override;
|
||||
void SetMaximumSize(const CefSize& size) override;
|
||||
|
||||
// CefLabelButton methods:
|
||||
CefRefPtr<CefMenuButton> AsMenuButton() override { return nullptr; }
|
||||
|
||||
// CefButton methods:
|
||||
CefRefPtr<CefLabelButton> AsLabelButton() override { return this; }
|
||||
|
||||
// CefViewAdapter methods:
|
||||
void GetDebugInfo(base::DictionaryValue* info,
|
||||
bool include_children) override {
|
||||
ParentClass::GetDebugInfo(info, include_children);
|
||||
info->SetString("text", ParentClass::root_view()->GetText());
|
||||
}
|
||||
|
||||
protected:
|
||||
// Create a new implementation object.
|
||||
// Always call Initialize() after creation.
|
||||
// |delegate| may be nullptr.
|
||||
explicit CefLabelButtonImpl(CefRefPtr<CefViewDelegateClass> delegate)
|
||||
: ParentClass(delegate) {
|
||||
}
|
||||
};
|
||||
|
||||
CEF_LABEL_BUTTON_IMPL_T void CEF_LABEL_BUTTON_IMPL_D::SetText(
|
||||
const CefString& text) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
ParentClass::root_view()->SetText(text);
|
||||
}
|
||||
|
||||
CEF_LABEL_BUTTON_IMPL_T CefString CEF_LABEL_BUTTON_IMPL_D::GetText() {
|
||||
CEF_REQUIRE_VALID_RETURN(CefString());
|
||||
return ParentClass::root_view()->GetText();
|
||||
}
|
||||
|
||||
CEF_LABEL_BUTTON_IMPL_T void CEF_LABEL_BUTTON_IMPL_D::SetImage(
|
||||
cef_button_state_t button_state,
|
||||
CefRefPtr<CefImage> image) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
gfx::ImageSkia image_skia;
|
||||
if (image)
|
||||
image_skia = static_cast<CefImageImpl*>(image.get())->image().AsImageSkia();
|
||||
ParentClass::root_view()->SetImage(
|
||||
static_cast<views::Button::ButtonState>(button_state), image_skia);
|
||||
}
|
||||
|
||||
CEF_LABEL_BUTTON_IMPL_T CefRefPtr<CefImage> CEF_LABEL_BUTTON_IMPL_D::GetImage(
|
||||
cef_button_state_t button_state) {
|
||||
CEF_REQUIRE_VALID_RETURN(nullptr);
|
||||
const gfx::ImageSkia& image_skia = ParentClass::root_view()->GetImage(
|
||||
static_cast<views::Button::ButtonState>(button_state));
|
||||
if (image_skia.isNull())
|
||||
return nullptr;
|
||||
return new CefImageImpl(image_skia);
|
||||
}
|
||||
|
||||
CEF_LABEL_BUTTON_IMPL_T void CEF_LABEL_BUTTON_IMPL_D::SetTextColor(
|
||||
cef_button_state_t for_state, cef_color_t color) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
ParentClass::root_view()->SetTextColor(
|
||||
static_cast<views::Button::ButtonState>(for_state), color);
|
||||
}
|
||||
|
||||
CEF_LABEL_BUTTON_IMPL_T void CEF_LABEL_BUTTON_IMPL_D::SetEnabledTextColors(
|
||||
cef_color_t color) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
ParentClass::root_view()->SetEnabledTextColors(color);
|
||||
}
|
||||
|
||||
CEF_LABEL_BUTTON_IMPL_T void CEF_LABEL_BUTTON_IMPL_D::SetFontList(
|
||||
const CefString& font_list) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
ParentClass::root_view()->SetFontList(gfx::FontList(font_list));
|
||||
}
|
||||
|
||||
CEF_LABEL_BUTTON_IMPL_T void CEF_LABEL_BUTTON_IMPL_D::SetHorizontalAlignment(
|
||||
cef_horizontal_alignment_t alignment) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
ParentClass::root_view()->SetHorizontalAlignment(
|
||||
static_cast<gfx::HorizontalAlignment>(alignment));
|
||||
}
|
||||
|
||||
CEF_LABEL_BUTTON_IMPL_T void CEF_LABEL_BUTTON_IMPL_D::SetMinimumSize(
|
||||
const CefSize& size) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
ParentClass::root_view()->SetMinSize(gfx::Size(size.width, size.height));
|
||||
}
|
||||
|
||||
CEF_LABEL_BUTTON_IMPL_T void CEF_LABEL_BUTTON_IMPL_D::SetMaximumSize(
|
||||
const CefSize& size) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
ParentClass::root_view()->SetMaxSize(gfx::Size(size.width, size.height));
|
||||
}
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_LABEL_BUTTON_IMPL_H_
|
48
libcef/browser/views/label_button_view.h
Normal file
48
libcef/browser/views/label_button_view.h
Normal file
@@ -0,0 +1,48 @@
|
||||
// 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_LABEL_BUTTON_VIEW_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_LABEL_BUTTON_VIEW_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_label_button.h"
|
||||
#include "libcef/browser/views/button_view.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "ui/gfx/font_list.h"
|
||||
|
||||
// Helpers for template boiler-plate.
|
||||
#define CEF_LABEL_BUTTON_VIEW_T CEF_BUTTON_VIEW_T
|
||||
#define CEF_LABEL_BUTTON_VIEW_A CEF_BUTTON_VIEW_A
|
||||
#define CEF_LABEL_BUTTON_VIEW_D CefLabelButtonView<CEF_LABEL_BUTTON_VIEW_A>
|
||||
|
||||
// Template for implementing views::View-derived classes that support adding and
|
||||
// removing children (called a Panel in CEF terminology). See comments in
|
||||
// view_impl.h for a usage overview.
|
||||
CEF_LABEL_BUTTON_VIEW_T class CefLabelButtonView : public CEF_BUTTON_VIEW_D {
|
||||
public:
|
||||
typedef CEF_BUTTON_VIEW_D ParentClass;
|
||||
|
||||
// |cef_delegate| may be nullptr.
|
||||
explicit CefLabelButtonView(CefViewDelegateClass* cef_delegate)
|
||||
: ParentClass(cef_delegate) {
|
||||
// Use our defaults instead of the Views framework defaults.
|
||||
ParentClass::SetFontList(gfx::FontList(view_util::kDefaultFontList));
|
||||
}
|
||||
|
||||
// Returns the CefLabelButton associated with this view. See comments on
|
||||
// CefViewView::GetCefView.
|
||||
CefRefPtr<CefLabelButton> GetCefLabelButton() const {
|
||||
CefRefPtr<CefLabelButton> label_button =
|
||||
ParentClass::GetCefButton()->AsLabelButton();
|
||||
DCHECK(label_button);
|
||||
return label_button;
|
||||
}
|
||||
|
||||
// CefViewView methods:
|
||||
bool HasMinimumSize() const { return true; }
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_LABEL_BUTTON_VIEW_H_
|
21
libcef/browser/views/layout_adapter.cc
Normal file
21
libcef/browser/views/layout_adapter.cc
Normal file
@@ -0,0 +1,21 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/layout_adapter.h"
|
||||
|
||||
#include "libcef/browser/views/box_layout_impl.h"
|
||||
#include "libcef/browser/views/fill_layout_impl.h"
|
||||
|
||||
// static
|
||||
CefLayoutAdapter* CefLayoutAdapter::GetFor(CefRefPtr<CefLayout> layout) {
|
||||
CefLayoutAdapter* adapter = nullptr;
|
||||
if (layout->AsBoxLayout()) {
|
||||
adapter = static_cast<CefBoxLayoutImpl*>(layout->AsBoxLayout().get());
|
||||
} else if (layout->AsFillLayout()) {
|
||||
adapter = static_cast<CefFillLayoutImpl*>(layout->AsFillLayout().get());
|
||||
}
|
||||
|
||||
DCHECK(adapter);
|
||||
return adapter;
|
||||
}
|
40
libcef/browser/views/layout_adapter.h
Normal file
40
libcef/browser/views/layout_adapter.h
Normal file
@@ -0,0 +1,40 @@
|
||||
// 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_LAYOUT_ADAPTER_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_LAYOUT_ADAPTER_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_layout.h"
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
|
||||
namespace views {
|
||||
class LayoutManager;
|
||||
};
|
||||
|
||||
// Exposes a common interface from all CefLayout implementation objects to
|
||||
// simplify the layout_util implementation. See comments in view_impl.h for a
|
||||
// usage overview.
|
||||
class CefLayoutAdapter {
|
||||
public:
|
||||
CefLayoutAdapter() {}
|
||||
|
||||
// Returns the CefLayoutAdapter for the specified |layout|.
|
||||
static CefLayoutAdapter* GetFor(CefRefPtr<CefLayout> layout);
|
||||
|
||||
// Returns the underlying views::LayoutManager object. Does not transfer
|
||||
// ownership.
|
||||
virtual views::LayoutManager* Get() const = 0;
|
||||
|
||||
// Release all references to the views::LayoutManager object. This is called
|
||||
// when the views::LayoutManager is deleted after being assigned to a
|
||||
// views::View.
|
||||
virtual void Detach() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~CefLayoutAdapter() {}
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_LAYOUT_ADAPTER_H_
|
84
libcef/browser/views/layout_impl.h
Normal file
84
libcef/browser/views/layout_impl.h
Normal file
@@ -0,0 +1,84 @@
|
||||
// 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_LAYOUT_IMPL_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_LAYOUT_IMPL_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_box_layout.h"
|
||||
#include "include/views/cef_fill_layout.h"
|
||||
#include "include/views/cef_layout.h"
|
||||
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/browser/views/layout_adapter.h"
|
||||
#include "libcef/browser/views/layout_util.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "ui/views/layout/layout_manager.h"
|
||||
#include "ui/views/view.h"
|
||||
|
||||
// Base template for implementing CefLayout-derived classes. See comments in
|
||||
// view_impl.h for a usage overview.
|
||||
template <class ViewsLayoutClass, class CefLayoutClass>
|
||||
class CefLayoutImpl : public CefLayoutAdapter,
|
||||
public CefLayoutClass {
|
||||
public:
|
||||
// Returns the underlying views::LayoutManager object as the derived type.
|
||||
// Does not transfer ownership.
|
||||
ViewsLayoutClass* layout() const { return layout_ref_; }
|
||||
|
||||
// Returns the views::View that owns this object.
|
||||
views::View* owner_view() const { return owner_view_; }
|
||||
|
||||
// CefLayoutAdapter methods:
|
||||
views::LayoutManager* Get() const override {
|
||||
return layout();
|
||||
}
|
||||
void Detach() override {
|
||||
owner_view_ = nullptr;
|
||||
layout_ref_ = nullptr;
|
||||
}
|
||||
|
||||
// CefLayout methods. When adding new As*() methods make sure to update
|
||||
// CefLayoutAdapter::GetFor() in layout_adapter.cc.
|
||||
CefRefPtr<CefBoxLayout> AsBoxLayout() override { return nullptr; }
|
||||
CefRefPtr<CefFillLayout> AsFillLayout() override { return nullptr; }
|
||||
bool IsValid() override {
|
||||
CEF_REQUIRE_UIT_RETURN(false);
|
||||
return !!layout_ref_;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Create a new implementation object.
|
||||
// Always call Initialize() after creation.
|
||||
CefLayoutImpl()
|
||||
: layout_ref_(nullptr),
|
||||
owner_view_(nullptr) {
|
||||
}
|
||||
|
||||
// Initialize this object and assign ownership to |owner_view|.
|
||||
void Initialize(views::View* owner_view) {
|
||||
DCHECK(owner_view);
|
||||
owner_view_ = owner_view;
|
||||
layout_ref_ = CreateLayout();
|
||||
DCHECK(layout_ref_);
|
||||
owner_view->SetLayoutManager(layout_ref_);
|
||||
layout_util::Assign(this, owner_view);
|
||||
}
|
||||
|
||||
// Create the views::LayoutManager object.
|
||||
virtual ViewsLayoutClass* CreateLayout() = 0;
|
||||
|
||||
private:
|
||||
// Unowned reference to the views::LayoutManager wrapped by this object. Will
|
||||
// be nullptr after the views::LayoutManager is destroyed.
|
||||
ViewsLayoutClass* layout_ref_;
|
||||
|
||||
// Unowned reference to the views::View that owns this object. Will be nullptr
|
||||
// after the views::LayoutManager is destroyed.
|
||||
views::View* owner_view_;
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_LAYOUT_IMPL_H_
|
75
libcef/browser/views/layout_util.cc
Normal file
75
libcef/browser/views/layout_util.cc
Normal file
@@ -0,0 +1,75 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/layout_util.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "libcef/browser/views/layout_adapter.h"
|
||||
|
||||
#include "ui/views/view.h"
|
||||
|
||||
namespace layout_util {
|
||||
|
||||
namespace {
|
||||
|
||||
// Manages the association between views::View and CefLayout instances.
|
||||
class UserData : public base::SupportsUserData::Data {
|
||||
public:
|
||||
static CefRefPtr<CefLayout> GetFor(const views::View* view) {
|
||||
UserData* data = static_cast<UserData*>(view->GetUserData(UserDataKey()));
|
||||
if (data)
|
||||
return data->layout_;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Assign ownership of the underlying views::LayoutManager to |owner_view|.
|
||||
// The views::View that owns the views::LayoutManager will gain a ref-counted
|
||||
// reference to the CefLayout and the CefLayout will keep an unowned reference
|
||||
// to the views::LayoutManager. Destruction of the views::View will release
|
||||
// the reference to the CefLayout.
|
||||
static void Assign(CefRefPtr<CefLayout> cef_layout,
|
||||
views::View* owner_view) {
|
||||
DCHECK(owner_view);
|
||||
DCHECK(cef_layout->IsValid());
|
||||
|
||||
views::LayoutManager* layout = CefLayoutAdapter::GetFor(cef_layout)->Get();
|
||||
DCHECK(layout);
|
||||
|
||||
// The CefLayout previously associated with |owner_view|, if any, will be
|
||||
// destroyed by this call.
|
||||
owner_view->SetUserData(UserDataKey(), new UserData(cef_layout));
|
||||
}
|
||||
|
||||
private:
|
||||
explicit UserData(CefRefPtr<CefLayout> cef_layout)
|
||||
: layout_(cef_layout) {
|
||||
DCHECK(layout_);
|
||||
}
|
||||
|
||||
~UserData() override {
|
||||
CefLayoutAdapter::GetFor(layout_)->Detach();
|
||||
}
|
||||
|
||||
static void* UserDataKey() {
|
||||
// We just need a unique constant. Use the address of a static that
|
||||
// COMDAT folding won't touch in an optimizing linker.
|
||||
static int data_key = 0;
|
||||
return reinterpret_cast<void*>(&data_key);
|
||||
}
|
||||
|
||||
CefRefPtr<CefLayout> layout_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
CefRefPtr<CefLayout> GetFor(const views::View* view) {
|
||||
return UserData::GetFor(view);
|
||||
}
|
||||
|
||||
void Assign(CefRefPtr<CefLayout> layout, views::View* owner_view) {
|
||||
return UserData::Assign(layout, owner_view);
|
||||
}
|
||||
|
||||
} // namespace layout_util
|
33
libcef/browser/views/layout_util.h
Normal file
33
libcef/browser/views/layout_util.h
Normal file
@@ -0,0 +1,33 @@
|
||||
// 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_LAYOUT_UTIL_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_LAYOUT_UTIL_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_layout.h"
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "ui/views/layout/layout_manager.h"
|
||||
|
||||
namespace views {
|
||||
class View;
|
||||
}
|
||||
|
||||
// The below functions manage the relationship between CefLayout and
|
||||
// views::LayoutManager instances. See comments in view_impl.h for a usage
|
||||
// overview.
|
||||
|
||||
namespace layout_util {
|
||||
|
||||
// Returns the CefLayout object associated with |owner_view|.
|
||||
CefRefPtr<CefLayout> GetFor(const views::View* owner_view);
|
||||
|
||||
// Assign ownership of |layout| to |owner_view|. If a CefLayout is already
|
||||
// associated with |owner_view| it will be invalidated.
|
||||
void Assign(CefRefPtr<CefLayout> layout, views::View* owner_view);
|
||||
|
||||
} // namespace layout_util
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_LAYOUT_UTIL_H_
|
60
libcef/browser/views/menu_button_impl.cc
Normal file
60
libcef/browser/views/menu_button_impl.cc
Normal file
@@ -0,0 +1,60 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/menu_button_impl.h"
|
||||
|
||||
#include "libcef/browser/views/menu_button_view.h"
|
||||
#include "libcef/browser/views/window_impl.h"
|
||||
|
||||
// static
|
||||
CefRefPtr<CefMenuButton> CefMenuButton::CreateMenuButton(
|
||||
CefRefPtr<CefMenuButtonDelegate> delegate,
|
||||
const CefString& text,
|
||||
bool with_frame,
|
||||
bool with_menu_marker) {
|
||||
return CefMenuButtonImpl::Create(delegate, text, with_frame,
|
||||
with_menu_marker);
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<CefMenuButtonImpl> CefMenuButtonImpl::Create(
|
||||
CefRefPtr<CefMenuButtonDelegate> delegate,
|
||||
const CefString& text,
|
||||
bool with_frame,
|
||||
bool with_menu_marker) {
|
||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||
DCHECK(delegate);
|
||||
if (!delegate)
|
||||
return nullptr;
|
||||
CefRefPtr<CefMenuButtonImpl> menu_button = new CefMenuButtonImpl(delegate);
|
||||
menu_button->Initialize();
|
||||
if (!text.empty())
|
||||
menu_button->SetText(text);
|
||||
if (with_frame)
|
||||
menu_button->root_view()->SetStyle(views::CustomButton::STYLE_BUTTON);
|
||||
menu_button->root_view()->set_show_menu_marker(with_menu_marker);
|
||||
return menu_button;
|
||||
}
|
||||
|
||||
void CefMenuButtonImpl::ShowMenu(CefRefPtr<CefMenuModel> menu_model,
|
||||
const CefPoint& screen_point,
|
||||
cef_menu_anchor_position_t anchor_position) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
CefRefPtr<CefWindow> window =
|
||||
view_util::GetWindowFor(root_view()->GetWidget());
|
||||
CefWindowImpl* window_impl = static_cast<CefWindowImpl*>(window.get());
|
||||
if (window_impl) {
|
||||
window_impl->ShowMenu(root_view(), menu_model, screen_point,
|
||||
anchor_position);
|
||||
}
|
||||
}
|
||||
|
||||
CefMenuButtonImpl::CefMenuButtonImpl(CefRefPtr<CefMenuButtonDelegate> delegate)
|
||||
: ParentClass(delegate) {
|
||||
DCHECK(delegate);
|
||||
}
|
||||
|
||||
views::MenuButton* CefMenuButtonImpl::CreateRootView() {
|
||||
return new CefMenuButtonView(delegate());
|
||||
}
|
55
libcef/browser/views/menu_button_impl.h
Normal file
55
libcef/browser/views/menu_button_impl.h
Normal file
@@ -0,0 +1,55 @@
|
||||
// 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_MENU_BUTTON_IMPL_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_MENU_BUTTON_IMPL_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_menu_button.h"
|
||||
#include "include/views/cef_menu_button_delegate.h"
|
||||
|
||||
#include "libcef/browser/menu_model_impl.h"
|
||||
#include "libcef/browser/views/label_button_impl.h"
|
||||
|
||||
#include "ui/views/controls/button/menu_button.h"
|
||||
|
||||
class CefMenuButtonImpl :
|
||||
public CefLabelButtonImpl<views::MenuButton, CefMenuButton,
|
||||
CefMenuButtonDelegate> {
|
||||
public:
|
||||
typedef CefLabelButtonImpl<views::MenuButton, CefMenuButton,
|
||||
CefMenuButtonDelegate> ParentClass;
|
||||
|
||||
// Create a new CefMenuButton instance. |delegate| must not be nullptr.
|
||||
static CefRefPtr<CefMenuButtonImpl> Create(
|
||||
CefRefPtr<CefMenuButtonDelegate> delegate,
|
||||
const CefString& text,
|
||||
bool with_frame,
|
||||
bool with_menu_marker);
|
||||
|
||||
// CefMenuButton methods:
|
||||
void ShowMenu(CefRefPtr<CefMenuModel> menu_model,
|
||||
const CefPoint& screen_point,
|
||||
cef_menu_anchor_position_t anchor_position) override;
|
||||
|
||||
// CefLabelButton methods:
|
||||
CefRefPtr<CefMenuButton> AsMenuButton() override { return this; }
|
||||
|
||||
// CefViewAdapter methods:
|
||||
std::string GetDebugType() override { return "MenuButton"; }
|
||||
|
||||
private:
|
||||
// Create a new implementation object.
|
||||
// Always call Initialize() after creation.
|
||||
// |delegate| must not be nullptr.
|
||||
explicit CefMenuButtonImpl(CefRefPtr<CefMenuButtonDelegate> delegate);
|
||||
|
||||
// CefViewImpl methods:
|
||||
views::MenuButton* CreateRootView() override;
|
||||
|
||||
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefMenuButtonImpl);
|
||||
DISALLOW_COPY_AND_ASSIGN(CefMenuButtonImpl);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_MENU_BUTTON_IMPL_H_
|
24
libcef/browser/views/menu_button_view.cc
Normal file
24
libcef/browser/views/menu_button_view.cc
Normal file
@@ -0,0 +1,24 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/menu_button_view.h"
|
||||
|
||||
CefMenuButtonView::CefMenuButtonView(
|
||||
CefMenuButtonDelegate* cef_delegate)
|
||||
: ParentClass(cef_delegate) {
|
||||
DCHECK(cef_delegate);
|
||||
}
|
||||
|
||||
CefRefPtr<CefMenuButton> CefMenuButtonView::GetCefMenuButton() const {
|
||||
CefRefPtr<CefMenuButton> menu_button = GetCefLabelButton()->AsMenuButton();
|
||||
DCHECK(menu_button);
|
||||
return menu_button;
|
||||
}
|
||||
|
||||
void CefMenuButtonView::OnMenuButtonClicked(views::MenuButton* source,
|
||||
const gfx::Point& point,
|
||||
const ui::Event* event) {
|
||||
cef_delegate()->OnMenuButtonPressed(GetCefMenuButton(),
|
||||
CefPoint(point.x(), point.y()));
|
||||
}
|
52
libcef/browser/views/menu_button_view.h
Normal file
52
libcef/browser/views/menu_button_view.h
Normal file
@@ -0,0 +1,52 @@
|
||||
// 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_MENU_BUTTON_VIEW_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_MENU_BUTTON_VIEW_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_menu_button.h"
|
||||
#include "include/views/cef_menu_button_delegate.h"
|
||||
|
||||
#include "libcef/browser/views/label_button_view.h"
|
||||
|
||||
#include "ui/views/controls/button/menu_button.h"
|
||||
#include "ui/views/controls/button/menu_button_listener.h"
|
||||
|
||||
// Extend views::LabelButton with a no-argument constructor as required by the
|
||||
// CefViewView template and extend views::ButtonListener as required by the
|
||||
// CefButtonView template.
|
||||
class MenuButtonEx : public views::MenuButton,
|
||||
public views::ButtonListener,
|
||||
public views::MenuButtonListener {
|
||||
public:
|
||||
MenuButtonEx() : views::MenuButton(base::string16(), this, true) {
|
||||
// TODO(cef): MenuButton should not use ButtonListener. See
|
||||
// http://crbug.com/585252 for details.
|
||||
Button::listener_ = this;
|
||||
}
|
||||
};
|
||||
|
||||
class CefMenuButtonView :
|
||||
public CefLabelButtonView<MenuButtonEx, CefMenuButtonDelegate> {
|
||||
public:
|
||||
typedef CefLabelButtonView<MenuButtonEx, CefMenuButtonDelegate> ParentClass;
|
||||
|
||||
// |cef_delegate| must not be nullptr.
|
||||
explicit CefMenuButtonView(CefMenuButtonDelegate* cef_delegate);
|
||||
|
||||
// Returns the CefMenuButton associated with this view. See comments on
|
||||
// CefViewView::GetCefView.
|
||||
CefRefPtr<CefMenuButton> GetCefMenuButton() const;
|
||||
|
||||
// views::MenuButtonListener methods:
|
||||
void OnMenuButtonClicked(views::MenuButton* source,
|
||||
const gfx::Point& point,
|
||||
const ui::Event* event) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(CefMenuButtonView);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_MENU_BUTTON_VIEW_H_
|
39
libcef/browser/views/menu_runner_views.cc
Normal file
39
libcef/browser/views/menu_runner_views.cc
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/menu_runner_views.h"
|
||||
|
||||
#include "libcef/browser/browser_host_impl.h"
|
||||
#include "libcef/browser/views/browser_view_impl.h"
|
||||
|
||||
CefMenuRunnerViews::CefMenuRunnerViews(CefBrowserViewImpl* browser_view)
|
||||
: browser_view_(browser_view) {
|
||||
}
|
||||
|
||||
bool CefMenuRunnerViews::RunContextMenu(
|
||||
CefBrowserHostImpl* browser,
|
||||
CefMenuModelImpl* model,
|
||||
const content::ContextMenuParams& params) {
|
||||
CefRefPtr<CefWindow> window = browser_view_->GetWindow();
|
||||
if (!window)
|
||||
return false;
|
||||
|
||||
CefPoint screen_point(params.x, params.y);
|
||||
browser_view_->ConvertPointToScreen(screen_point);
|
||||
|
||||
window->ShowMenu(model, screen_point, CEF_MENU_ANCHOR_TOPRIGHT);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CefMenuRunnerViews::CancelContextMenu() {
|
||||
CefRefPtr<CefWindow> window = browser_view_->GetWindow();
|
||||
if (window)
|
||||
window->CancelMenu();
|
||||
}
|
||||
|
||||
bool CefMenuRunnerViews::FormatLabel(base::string16& label) {
|
||||
// Remove the accelerator indicator (&) from label strings.
|
||||
const char16 replace[] = {L'&', 0};
|
||||
return base::ReplaceChars(label, replace, base::string16(), &label);
|
||||
}
|
29
libcef/browser/views/menu_runner_views.h
Normal file
29
libcef/browser/views/menu_runner_views.h
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright (c) 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_MENU_RUNNER_VIEWS_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_MENU_RUNNER_VIEWS_H_
|
||||
#pragma once
|
||||
|
||||
#include "libcef/browser/menu_runner.h"
|
||||
|
||||
class CefBrowserViewImpl;
|
||||
|
||||
class CefMenuRunnerViews: public CefMenuRunner {
|
||||
public:
|
||||
// |browser_view| is guaranteed to outlive this object.
|
||||
explicit CefMenuRunnerViews(CefBrowserViewImpl* browser_view);
|
||||
|
||||
// CefMenuRunner methods.
|
||||
bool RunContextMenu(CefBrowserHostImpl* browser,
|
||||
CefMenuModelImpl* model,
|
||||
const content::ContextMenuParams& params) override;
|
||||
void CancelContextMenu() override;
|
||||
bool FormatLabel(base::string16& label) override;
|
||||
|
||||
private:
|
||||
CefBrowserViewImpl* browser_view_;
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_MENU_RUNNER_VIEWS_H_
|
213
libcef/browser/views/panel_impl.h
Normal file
213
libcef/browser/views/panel_impl.h
Normal file
@@ -0,0 +1,213 @@
|
||||
// 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"
|
||||
#include "base/memory/scoped_ptr.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()->child_count();
|
||||
if (count > 0U) {
|
||||
scoped_ptr<base::ListValue> children(new base::ListValue());
|
||||
|
||||
for (size_t i = 0U; i < count; ++i) {
|
||||
views::View* view = ParentClass::content_view()->child_at(i);
|
||||
CefViewAdapter* adapter = CefViewAdapter::GetFor(view);
|
||||
if (adapter) {
|
||||
scoped_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;
|
||||
|
||||
scoped_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(index, ParentClass::content_view()->child_count());
|
||||
if (!view.get() || !view->IsValid() || view->IsAttached() ||
|
||||
index < 0 || index > ParentClass::content_view()->child_count()) {
|
||||
return;
|
||||
}
|
||||
|
||||
scoped_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()->has_children()) {
|
||||
CefRefPtr<CefView> view =
|
||||
view_util::GetFor(ParentClass::content_view()->child_at(0), false);
|
||||
RemoveChildView(view);
|
||||
}
|
||||
}
|
||||
|
||||
CEF_PANEL_IMPL_T size_t CEF_PANEL_IMPL_D::GetChildViewCount() {
|
||||
CEF_REQUIRE_VALID_RETURN(0U);
|
||||
return ParentClass::content_view()->child_count();
|
||||
}
|
||||
|
||||
CEF_PANEL_IMPL_T CefRefPtr<CefView> CEF_PANEL_IMPL_D::GetChildViewAt(
|
||||
int index) {
|
||||
CEF_REQUIRE_VALID_RETURN(nullptr);
|
||||
DCHECK_GE(index, 0);
|
||||
DCHECK_LT(index, ParentClass::content_view()->child_count());
|
||||
if (index < 0 || index >= ParentClass::content_view()->child_count())
|
||||
return nullptr;
|
||||
|
||||
CefRefPtr<CefView> view =
|
||||
view_util::GetFor(ParentClass::content_view()->child_at(index), false);
|
||||
DCHECK(view);
|
||||
return view;
|
||||
}
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_PANEL_IMPL_H_
|
43
libcef/browser/views/panel_view.h
Normal file
43
libcef/browser/views/panel_view.h
Normal file
@@ -0,0 +1,43 @@
|
||||
// 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_VIEW_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_PANEL_VIEW_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_panel_delegate.h"
|
||||
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/browser/views/view_view.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
|
||||
// Helpers for template boiler-plate.
|
||||
#define CEF_PANEL_VIEW_T CEF_VIEW_VIEW_T
|
||||
#define CEF_PANEL_VIEW_A CEF_VIEW_VIEW_A
|
||||
#define CEF_PANEL_VIEW_D CefPanelView<CEF_PANEL_VIEW_A>
|
||||
|
||||
// Template for implementing views::View-derived classes that support adding and
|
||||
// removing children (called a Panel in CEF terminology). See comments in
|
||||
// view_impl.h for a usage overview.
|
||||
CEF_PANEL_VIEW_T class CefPanelView : public CEF_VIEW_VIEW_D {
|
||||
public:
|
||||
typedef CEF_VIEW_VIEW_D ParentClass;
|
||||
|
||||
// |cef_delegate| may be nullptr.
|
||||
explicit CefPanelView(CefViewDelegateClass* cef_delegate)
|
||||
: ParentClass(cef_delegate) {
|
||||
}
|
||||
|
||||
// Returns the CefPanel associated with this view. See comments on
|
||||
// CefViewView::GetCefView.
|
||||
CefRefPtr<CefPanel> GetCefPanel() const {
|
||||
CefRefPtr<CefPanel> panel = ParentClass::GetCefView()->AsPanel();
|
||||
DCHECK(panel);
|
||||
return panel;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_PANEL_VIEW_H_
|
88
libcef/browser/views/scroll_view_impl.cc
Normal file
88
libcef/browser/views/scroll_view_impl.cc
Normal file
@@ -0,0 +1,88 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/scroll_view_impl.h"
|
||||
|
||||
// static
|
||||
CefRefPtr<CefScrollView> CefScrollView::CreateScrollView(
|
||||
CefRefPtr<CefViewDelegate> delegate) {
|
||||
return CefScrollViewImpl::Create(delegate);
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<CefScrollViewImpl> CefScrollViewImpl::Create(
|
||||
CefRefPtr<CefViewDelegate> delegate) {
|
||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||
CefRefPtr<CefScrollViewImpl> view = new CefScrollViewImpl(delegate);
|
||||
view->Initialize();
|
||||
return view;
|
||||
}
|
||||
|
||||
void CefScrollViewImpl::SetContentView(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;
|
||||
|
||||
scoped_ptr<views::View> view_ptr = view_util::PassOwnership(view);
|
||||
root_view()->SetContents(view_ptr.release());
|
||||
}
|
||||
|
||||
CefRefPtr<CefView> CefScrollViewImpl::GetContentView() {
|
||||
CEF_REQUIRE_VALID_RETURN(nullptr);
|
||||
return view_util::GetFor(root_view()->contents(), false);
|
||||
}
|
||||
|
||||
CefRect CefScrollViewImpl::GetVisibleContentRect() {
|
||||
CEF_REQUIRE_VALID_RETURN(CefRect());
|
||||
const gfx::Rect& rect = root_view()->GetVisibleRect();
|
||||
return CefRect(rect.x(), rect.y(), rect.width(), rect.height());
|
||||
}
|
||||
|
||||
bool CefScrollViewImpl::HasHorizontalScrollbar() {
|
||||
CEF_REQUIRE_VALID_RETURN(false);
|
||||
const views::ScrollBar* scrollbar = root_view()->horizontal_scroll_bar();
|
||||
return scrollbar && scrollbar->visible();
|
||||
}
|
||||
|
||||
int CefScrollViewImpl::GetHorizontalScrollbarHeight() {
|
||||
CEF_REQUIRE_VALID_RETURN(0);
|
||||
return root_view()->GetScrollBarHeight();
|
||||
}
|
||||
|
||||
bool CefScrollViewImpl::HasVerticalScrollbar() {
|
||||
CEF_REQUIRE_VALID_RETURN(false);
|
||||
const views::ScrollBar* scrollbar = root_view()->vertical_scroll_bar();
|
||||
return scrollbar && scrollbar->visible();
|
||||
}
|
||||
|
||||
int CefScrollViewImpl::GetVerticalScrollbarWidth() {
|
||||
CEF_REQUIRE_VALID_RETURN(0);
|
||||
return root_view()->GetScrollBarWidth();
|
||||
}
|
||||
|
||||
void CefScrollViewImpl::GetDebugInfo(base::DictionaryValue* info,
|
||||
bool include_children) {
|
||||
ParentClass::GetDebugInfo(info, include_children);
|
||||
if (include_children) {
|
||||
views::View* view = root_view()->contents();
|
||||
CefViewAdapter* adapter = CefViewAdapter::GetFor(view);
|
||||
if (adapter) {
|
||||
scoped_ptr<base::DictionaryValue> child_info(
|
||||
new base::DictionaryValue());
|
||||
adapter->GetDebugInfo(child_info.get(), include_children);
|
||||
info->Set("content_view", std::move(child_info));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CefScrollViewImpl::CefScrollViewImpl(CefRefPtr<CefViewDelegate> delegate)
|
||||
: ParentClass(delegate) {
|
||||
}
|
||||
|
||||
CefScrollViewView* CefScrollViewImpl::CreateRootView() {
|
||||
return new CefScrollViewView(delegate());
|
||||
}
|
53
libcef/browser/views/scroll_view_impl.h
Normal file
53
libcef/browser/views/scroll_view_impl.h
Normal file
@@ -0,0 +1,53 @@
|
||||
// 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_SCROLL_VIEW_IMPL_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_SCROLL_VIEW_IMPL_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_scroll_view.h"
|
||||
#include "include/views/cef_view_delegate.h"
|
||||
|
||||
#include "libcef/browser/views/scroll_view_view.h"
|
||||
#include "libcef/browser/views/view_impl.h"
|
||||
|
||||
class CefScrollViewImpl :
|
||||
public CefViewImpl<CefScrollViewView, CefScrollView, CefViewDelegate> {
|
||||
public:
|
||||
typedef CefViewImpl<CefScrollViewView, CefScrollView, CefViewDelegate>
|
||||
ParentClass;
|
||||
|
||||
// Create a new CefScrollView instance. |delegate| may be nullptr.
|
||||
static CefRefPtr<CefScrollViewImpl> Create(
|
||||
CefRefPtr<CefViewDelegate> delegate);
|
||||
|
||||
// CefScrollView methods:
|
||||
CefRefPtr<CefScrollView> AsScrollView() override { return this; }
|
||||
void SetContentView(CefRefPtr<CefView> view) override;
|
||||
CefRefPtr<CefView> GetContentView() override;
|
||||
CefRect GetVisibleContentRect() override;
|
||||
bool HasHorizontalScrollbar() override;
|
||||
int GetHorizontalScrollbarHeight() override;
|
||||
bool HasVerticalScrollbar() override;
|
||||
int GetVerticalScrollbarWidth() override;
|
||||
|
||||
// CefViewAdapter methods:
|
||||
std::string GetDebugType() override { return "ScrollView"; }
|
||||
void GetDebugInfo(base::DictionaryValue* info,
|
||||
bool include_children) override;
|
||||
|
||||
private:
|
||||
// Create a new implementation object.
|
||||
// Always call Initialize() after creation.
|
||||
// |delegate| may be nullptr.
|
||||
CefScrollViewImpl(CefRefPtr<CefViewDelegate> delegate);
|
||||
|
||||
// CefViewImpl methods:
|
||||
CefScrollViewView* CreateRootView() override;
|
||||
|
||||
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefScrollViewImpl);
|
||||
DISALLOW_COPY_AND_ASSIGN(CefScrollViewImpl);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_SCROLL_VIEW_IMPL_H_
|
9
libcef/browser/views/scroll_view_view.cc
Normal file
9
libcef/browser/views/scroll_view_view.cc
Normal file
@@ -0,0 +1,9 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/scroll_view_view.h"
|
||||
|
||||
CefScrollViewView::CefScrollViewView(CefViewDelegate* cef_delegate)
|
||||
: ParentClass(cef_delegate) {
|
||||
}
|
27
libcef/browser/views/scroll_view_view.h
Normal file
27
libcef/browser/views/scroll_view_view.h
Normal file
@@ -0,0 +1,27 @@
|
||||
// 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_SCROLL_VIEW_VIEW_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_SCROLL_VIEW_VIEW_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_panel_delegate.h"
|
||||
|
||||
#include "libcef/browser/views/view_view.h"
|
||||
|
||||
#include "ui/views/controls/scroll_view.h"
|
||||
|
||||
class CefScrollViewView :
|
||||
public CefViewView<views::ScrollView, CefViewDelegate> {
|
||||
public:
|
||||
typedef CefViewView<views::ScrollView, CefViewDelegate> ParentClass;
|
||||
|
||||
// |cef_delegate| may be nullptr.
|
||||
explicit CefScrollViewView(CefViewDelegate* cef_delegate);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(CefScrollViewView);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_SCROLL_VIEW_VIEW_H_
|
214
libcef/browser/views/textfield_impl.cc
Normal file
214
libcef/browser/views/textfield_impl.cc
Normal file
@@ -0,0 +1,214 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/textfield_impl.h"
|
||||
|
||||
#include "libcef/browser/thread_util.h"
|
||||
|
||||
// static
|
||||
CefRefPtr<CefTextfield> CefTextfield::CreateTextfield(
|
||||
CefRefPtr<CefTextfieldDelegate> delegate) {
|
||||
return CefTextfieldImpl::Create(delegate);
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<CefTextfieldImpl> CefTextfieldImpl::Create(
|
||||
CefRefPtr<CefTextfieldDelegate> delegate) {
|
||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||
CefRefPtr<CefTextfieldImpl> textfield = new CefTextfieldImpl(delegate);
|
||||
textfield->Initialize();
|
||||
return textfield;
|
||||
}
|
||||
|
||||
void CefTextfieldImpl::SetPasswordInput(bool password_input) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
root_view()->SetTextInputType(password_input ? ui::TEXT_INPUT_TYPE_PASSWORD :
|
||||
ui::TEXT_INPUT_TYPE_TEXT);
|
||||
}
|
||||
|
||||
bool CefTextfieldImpl::IsPasswordInput() {
|
||||
CEF_REQUIRE_VALID_RETURN(false);
|
||||
return (root_view()->GetTextInputType() == ui::TEXT_INPUT_TYPE_PASSWORD);
|
||||
}
|
||||
|
||||
void CefTextfieldImpl::SetReadOnly(bool read_only) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
root_view()->SetReadOnly(read_only);
|
||||
}
|
||||
|
||||
bool CefTextfieldImpl::IsReadOnly() {
|
||||
CEF_REQUIRE_VALID_RETURN(false);
|
||||
return root_view()->read_only();
|
||||
}
|
||||
|
||||
CefString CefTextfieldImpl::GetText() {
|
||||
CEF_REQUIRE_VALID_RETURN(CefString());
|
||||
return root_view()->text();
|
||||
}
|
||||
|
||||
void CefTextfieldImpl::SetText(const CefString& text) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
root_view()->SetText(text);
|
||||
}
|
||||
|
||||
void CefTextfieldImpl::AppendText(const CefString& text) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
root_view()->AppendText(text);
|
||||
}
|
||||
|
||||
void CefTextfieldImpl::InsertOrReplaceText(const CefString& text) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
root_view()->InsertOrReplaceText(text);
|
||||
}
|
||||
|
||||
bool CefTextfieldImpl::HasSelection() {
|
||||
CEF_REQUIRE_VALID_RETURN(false);
|
||||
return root_view()->HasSelection();
|
||||
}
|
||||
|
||||
CefString CefTextfieldImpl::GetSelectedText() {
|
||||
CEF_REQUIRE_VALID_RETURN(CefString());
|
||||
return root_view()->GetSelectedText();
|
||||
}
|
||||
|
||||
void CefTextfieldImpl::SelectAll(bool reversed) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
root_view()->SelectAll(reversed);
|
||||
}
|
||||
|
||||
void CefTextfieldImpl::ClearSelection() {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
root_view()->ClearSelection();
|
||||
}
|
||||
|
||||
CefRange CefTextfieldImpl::GetSelectedRange() {
|
||||
CEF_REQUIRE_VALID_RETURN(CefRange());
|
||||
const gfx::Range& range = root_view()->GetSelectedRange();
|
||||
return CefRange(range.start(), range.end());
|
||||
}
|
||||
|
||||
void CefTextfieldImpl::SelectRange(const CefRange& range) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
root_view()->SelectRange(gfx::Range(range.from, range.to));
|
||||
}
|
||||
|
||||
size_t CefTextfieldImpl::GetCursorPosition() {
|
||||
CEF_REQUIRE_VALID_RETURN(0U);
|
||||
return root_view()->GetCursorPosition();
|
||||
}
|
||||
|
||||
void CefTextfieldImpl::SetTextColor(cef_color_t color) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
root_view()->SetTextColor(color);
|
||||
}
|
||||
|
||||
cef_color_t CefTextfieldImpl::GetTextColor() {
|
||||
CEF_REQUIRE_VALID_RETURN(0U);
|
||||
return root_view()->GetTextColor();
|
||||
}
|
||||
|
||||
void CefTextfieldImpl::SetSelectionTextColor(cef_color_t color) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
root_view()->SetSelectionTextColor(color);
|
||||
}
|
||||
|
||||
cef_color_t CefTextfieldImpl::GetSelectionTextColor() {
|
||||
CEF_REQUIRE_VALID_RETURN(0U);
|
||||
return root_view()->GetSelectionTextColor();
|
||||
}
|
||||
|
||||
void CefTextfieldImpl::SetSelectionBackgroundColor(cef_color_t color) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
root_view()->SetSelectionBackgroundColor(color);
|
||||
}
|
||||
|
||||
cef_color_t CefTextfieldImpl::GetSelectionBackgroundColor() {
|
||||
CEF_REQUIRE_VALID_RETURN(0U);
|
||||
return root_view()->GetSelectionBackgroundColor();
|
||||
}
|
||||
|
||||
void CefTextfieldImpl::SetFontList(const CefString& font_list) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
root_view()->SetFontList(gfx::FontList(font_list));
|
||||
}
|
||||
|
||||
void CefTextfieldImpl::ApplyTextColor(cef_color_t color,
|
||||
const CefRange& range) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (range.from == range.to)
|
||||
root_view()->SetColor(color);
|
||||
else
|
||||
root_view()->ApplyColor(color, gfx::Range(range.from, range.to));
|
||||
}
|
||||
|
||||
void CefTextfieldImpl::ApplyTextStyle(cef_text_style_t style,
|
||||
bool add,
|
||||
const CefRange& range) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (range.from == range.to) {
|
||||
root_view()->SetStyle(static_cast<gfx::TextStyle>(style), add);
|
||||
} else {
|
||||
root_view()->ApplyStyle(static_cast<gfx::TextStyle>(style), add,
|
||||
gfx::Range(range.from, range.to));
|
||||
}
|
||||
}
|
||||
|
||||
bool CefTextfieldImpl::IsCommandEnabled(int command_id) {
|
||||
CEF_REQUIRE_VALID_RETURN(false);
|
||||
return root_view()->IsCommandIdEnabled(command_id);
|
||||
}
|
||||
|
||||
void CefTextfieldImpl::ExecuteCommand(int command_id) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (root_view()->IsCommandIdEnabled(command_id))
|
||||
root_view()->ExecuteCommand(command_id);
|
||||
}
|
||||
|
||||
void CefTextfieldImpl::ClearEditHistory() {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
root_view()->ClearEditHistory();
|
||||
}
|
||||
|
||||
void CefTextfieldImpl::SetPlaceholderText(const CefString& text) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
root_view()->set_placeholder_text(text);
|
||||
}
|
||||
|
||||
CefString CefTextfieldImpl::GetPlaceholderText() {
|
||||
CEF_REQUIRE_VALID_RETURN(CefString());
|
||||
return root_view()->GetPlaceholderText();
|
||||
}
|
||||
|
||||
void CefTextfieldImpl::SetPlaceholderTextColor(cef_color_t color) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
root_view()->set_placeholder_text_color(color);
|
||||
}
|
||||
|
||||
cef_color_t CefTextfieldImpl::GetPlaceholderTextColor() {
|
||||
CEF_REQUIRE_VALID_RETURN(0U);
|
||||
return root_view()->placeholder_text_color();
|
||||
}
|
||||
|
||||
void CefTextfieldImpl::SetBackgroundColor(cef_color_t color) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
root_view()->SetBackgroundColor(color);
|
||||
}
|
||||
|
||||
cef_color_t CefTextfieldImpl::GetBackgroundColor() {
|
||||
CEF_REQUIRE_VALID_RETURN(0U);
|
||||
return root_view()->GetBackgroundColor();
|
||||
}
|
||||
|
||||
void CefTextfieldImpl::SetAccessibleName(const CefString& name) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
root_view()->SetAccessibleName(name);
|
||||
}
|
||||
|
||||
CefTextfieldImpl::CefTextfieldImpl(CefRefPtr<CefTextfieldDelegate> delegate)
|
||||
: ParentClass(delegate) {
|
||||
}
|
||||
|
||||
CefTextfieldView* CefTextfieldImpl::CreateRootView() {
|
||||
return new CefTextfieldView(delegate());
|
||||
}
|
83
libcef/browser/views/textfield_impl.h
Normal file
83
libcef/browser/views/textfield_impl.h
Normal file
@@ -0,0 +1,83 @@
|
||||
// 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_TEXTFIELD_IMPL_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_TEXTFIELD_IMPL_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_textfield.h"
|
||||
#include "include/views/cef_textfield_delegate.h"
|
||||
|
||||
#include "libcef/browser/views/view_impl.h"
|
||||
#include "libcef/browser/views/textfield_view.h"
|
||||
|
||||
class CefTextfieldImpl :
|
||||
public CefViewImpl<CefTextfieldView, CefTextfield, CefTextfieldDelegate> {
|
||||
public:
|
||||
typedef CefViewImpl<CefTextfieldView, CefTextfield, CefTextfieldDelegate>
|
||||
ParentClass;
|
||||
|
||||
// Create a new CefTextfield instance. |delegate| may be nullptr.
|
||||
static CefRefPtr<CefTextfieldImpl> Create(
|
||||
CefRefPtr<CefTextfieldDelegate> delegate);
|
||||
|
||||
// CefTextfield methods:
|
||||
void SetPasswordInput(bool password_input) override;
|
||||
bool IsPasswordInput() override;
|
||||
void SetReadOnly(bool read_only) override;
|
||||
bool IsReadOnly() override;
|
||||
CefString GetText() override;
|
||||
void SetText(const CefString& text) override;
|
||||
void AppendText(const CefString& text) override;
|
||||
void InsertOrReplaceText(const CefString& text) override;
|
||||
bool HasSelection() override;
|
||||
CefString GetSelectedText() override;
|
||||
void SelectAll(bool reversed) override;
|
||||
void ClearSelection() override;
|
||||
CefRange GetSelectedRange() override;
|
||||
void SelectRange(const CefRange& range) override;
|
||||
size_t GetCursorPosition() override;
|
||||
void SetTextColor(cef_color_t color) override;
|
||||
cef_color_t GetTextColor() override;
|
||||
void SetSelectionTextColor(cef_color_t color) override;
|
||||
cef_color_t GetSelectionTextColor() override;
|
||||
void SetSelectionBackgroundColor(cef_color_t color) override;
|
||||
cef_color_t GetSelectionBackgroundColor() override;
|
||||
void SetFontList(const CefString& font_list) override;
|
||||
void ApplyTextColor(cef_color_t color,
|
||||
const CefRange& range) override;
|
||||
void ApplyTextStyle(cef_text_style_t style,
|
||||
bool add,
|
||||
const CefRange& range) override;
|
||||
bool IsCommandEnabled(int command_id) override;
|
||||
void ExecuteCommand(int command_id) override;
|
||||
void ClearEditHistory() override;
|
||||
void SetPlaceholderText(const CefString& text) override;
|
||||
CefString GetPlaceholderText() override;
|
||||
void SetPlaceholderTextColor(cef_color_t color) override;
|
||||
cef_color_t GetPlaceholderTextColor() override;
|
||||
void SetAccessibleName(const CefString& name) override;
|
||||
|
||||
// CefView methods:
|
||||
CefRefPtr<CefTextfield> AsTextfield() override { return this; }
|
||||
void SetBackgroundColor(cef_color_t color) override;
|
||||
cef_color_t GetBackgroundColor() override;
|
||||
|
||||
// CefViewAdapter methods:
|
||||
std::string GetDebugType() override { return "Textfield"; }
|
||||
|
||||
private:
|
||||
// Create a new implementation object.
|
||||
// Always call Initialize() after creation.
|
||||
// |delegate| may be nullptr.
|
||||
explicit CefTextfieldImpl(CefRefPtr<CefTextfieldDelegate> delegate);
|
||||
|
||||
// CefViewImpl methods:
|
||||
CefTextfieldView* CreateRootView() override;
|
||||
|
||||
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefTextfieldImpl);
|
||||
DISALLOW_COPY_AND_ASSIGN(CefTextfieldImpl);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_TEXTFIELD_IMPL_H_
|
35
libcef/browser/views/textfield_view.cc
Normal file
35
libcef/browser/views/textfield_view.cc
Normal file
@@ -0,0 +1,35 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/textfield_view.h"
|
||||
|
||||
#include "libcef/browser/browser_util.h"
|
||||
|
||||
CefTextfieldView::CefTextfieldView(CefTextfieldDelegate* cef_delegate)
|
||||
: ParentClass(cef_delegate) {
|
||||
set_controller(this);
|
||||
|
||||
// Use our defaults instead of the Views framework defaults.
|
||||
SetFontList(gfx::FontList(view_util::kDefaultFontList));
|
||||
}
|
||||
|
||||
bool CefTextfieldView::HandleKeyEvent(views::Textfield* sender,
|
||||
const ui::KeyEvent& key_event) {
|
||||
DCHECK_EQ(sender, this);
|
||||
|
||||
if (!cef_delegate())
|
||||
return false;
|
||||
|
||||
CefKeyEvent cef_key_event;
|
||||
if (!browser_util::GetCefKeyEvent(key_event, cef_key_event))
|
||||
return false;
|
||||
|
||||
return cef_delegate()->OnKeyEvent(GetCefTextfield(), cef_key_event);
|
||||
}
|
||||
|
||||
void CefTextfieldView::OnAfterUserAction(views::Textfield* sender) {
|
||||
DCHECK_EQ(sender, this);
|
||||
if (cef_delegate())
|
||||
cef_delegate()->OnAfterUserAction(GetCefTextfield());
|
||||
}
|
43
libcef/browser/views/textfield_view.h
Normal file
43
libcef/browser/views/textfield_view.h
Normal file
@@ -0,0 +1,43 @@
|
||||
// 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_TEXTFIELD_VIEW_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_TEXTFIELD_VIEW_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_textfield_delegate.h"
|
||||
|
||||
#include "include/views/cef_textfield.h"
|
||||
#include "libcef/browser/views/view_view.h"
|
||||
|
||||
#include "ui/views/controls/textfield/textfield.h"
|
||||
#include "ui/views/controls/textfield/textfield_controller.h"
|
||||
|
||||
class CefTextfieldView :
|
||||
public CefViewView<views::Textfield, CefTextfieldDelegate>,
|
||||
public views::TextfieldController {
|
||||
public:
|
||||
typedef CefViewView<views::Textfield, CefTextfieldDelegate> ParentClass;
|
||||
|
||||
// |cef_delegate| may be nullptr.
|
||||
explicit CefTextfieldView(CefTextfieldDelegate* cef_delegate);
|
||||
|
||||
// Returns the CefTextfield associated with this view. See comments on
|
||||
// CefViewView::GetCefView.
|
||||
CefRefPtr<CefTextfield> GetCefTextfield() const {
|
||||
CefRefPtr<CefTextfield> textfield = GetCefView()->AsTextfield();
|
||||
DCHECK(textfield);
|
||||
return textfield;
|
||||
}
|
||||
|
||||
// TextfieldController methods:
|
||||
bool HandleKeyEvent(views::Textfield* sender,
|
||||
const ui::KeyEvent& key_event) override;
|
||||
void OnAfterUserAction(views::Textfield* sender) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(CefTextfieldView);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_TEXTFIELD_VIEW_H_
|
55
libcef/browser/views/view_adapter.cc
Normal file
55
libcef/browser/views/view_adapter.cc
Normal file
@@ -0,0 +1,55 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/view_adapter.h"
|
||||
|
||||
#include "libcef/browser/views/basic_label_button_impl.h"
|
||||
#include "libcef/browser/views/basic_panel_impl.h"
|
||||
#include "libcef/browser/views/browser_view_impl.h"
|
||||
#include "libcef/browser/views/menu_button_impl.h"
|
||||
#include "libcef/browser/views/scroll_view_impl.h"
|
||||
#include "libcef/browser/views/textfield_impl.h"
|
||||
#include "libcef/browser/views/view_util.h"
|
||||
#include "libcef/browser/views/window_impl.h"
|
||||
|
||||
// static
|
||||
CefViewAdapter* CefViewAdapter::GetFor(CefRefPtr<CefView> view) {
|
||||
CefViewAdapter* adapter = nullptr;
|
||||
if (view->AsBrowserView()) {
|
||||
adapter = static_cast<CefBrowserViewImpl*>(view->AsBrowserView().get());
|
||||
} else if (view->AsButton()) {
|
||||
CefRefPtr<CefButton> button = view->AsButton();
|
||||
if (button->AsLabelButton()) {
|
||||
CefRefPtr<CefLabelButton> label_button = button->AsLabelButton();
|
||||
if (label_button->AsMenuButton()) {
|
||||
adapter = static_cast<CefMenuButtonImpl*>(
|
||||
label_button->AsMenuButton().get());
|
||||
} else {
|
||||
adapter = static_cast<CefBasicLabelButtonImpl*>(label_button.get());
|
||||
}
|
||||
}
|
||||
} else if (view->AsPanel()) {
|
||||
CefRefPtr<CefPanel> panel = view->AsPanel();
|
||||
if (panel->AsWindow()) {
|
||||
adapter = static_cast<CefWindowImpl*>(panel->AsWindow().get());
|
||||
} else {
|
||||
adapter = static_cast<CefBasicPanelImpl*>(panel.get());
|
||||
}
|
||||
} else if (view->AsScrollView()) {
|
||||
adapter = static_cast<CefScrollViewImpl*>(view->AsScrollView().get());
|
||||
} else if (view->AsTextfield()) {
|
||||
adapter = static_cast<CefTextfieldImpl*>(view->AsTextfield().get());
|
||||
}
|
||||
|
||||
DCHECK(adapter);
|
||||
return adapter;
|
||||
}
|
||||
|
||||
// static
|
||||
CefViewAdapter* CefViewAdapter::GetFor(views::View* view) {
|
||||
CefRefPtr<CefView> cef_view = view_util::GetFor(view, false);
|
||||
if (cef_view)
|
||||
return GetFor(cef_view);
|
||||
return nullptr;
|
||||
}
|
60
libcef/browser/views/view_adapter.h
Normal file
60
libcef/browser/views/view_adapter.h
Normal file
@@ -0,0 +1,60 @@
|
||||
// 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_ADAPTER_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_VIEW_ADAPTER_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_view.h"
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
}
|
||||
|
||||
namespace views {
|
||||
class View;
|
||||
}
|
||||
|
||||
// Exposes a common interface from all CefView implementation objects to
|
||||
// simplify the view_util implementation. See comments in view_impl.h for a
|
||||
// usage overview.
|
||||
class CefViewAdapter {
|
||||
public:
|
||||
CefViewAdapter() {}
|
||||
|
||||
// Returns the CefViewAdapter for the specified |view|.
|
||||
static CefViewAdapter* GetFor(CefRefPtr<CefView> view);
|
||||
static CefViewAdapter* GetFor(views::View* view);
|
||||
|
||||
// Returns the underlying views::View object. Does not transfer ownership.
|
||||
virtual views::View* Get() const = 0;
|
||||
|
||||
// Pass ownership of the underlying views::View object to the caller. This
|
||||
// object keeps an unowned reference to the views::View object. This is called
|
||||
// when the views::View is parented to another views::View.
|
||||
virtual scoped_ptr<views::View> PassOwnership() = 0;
|
||||
|
||||
// Resume ownership of the underlying views::View object. This is called when
|
||||
// the views::View is no longer parented to another views::View.
|
||||
virtual void ResumeOwnership() = 0;
|
||||
|
||||
// Release all references to the views::View object. This is called when the
|
||||
// views::View is deleted after being parented to another views::View.
|
||||
virtual void Detach() = 0;
|
||||
|
||||
// Override this method to provide a string representation of the View type.
|
||||
// Only implement this method in concrete classes.
|
||||
virtual std::string GetDebugType() = 0;
|
||||
|
||||
// Override this method to provide debug info specific to the View type.
|
||||
virtual void GetDebugInfo(base::DictionaryValue* info,
|
||||
bool include_children) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~CefViewAdapter() {}
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_VIEW_ADAPTER_H_
|
719
libcef/browser/views/view_impl.h
Normal file
719
libcef/browser/views/view_impl.h
Normal file
@@ -0,0 +1,719 @@
|
||||
// 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::CustomButton =>
|
||||
// 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/memory/scoped_ptr.h"
|
||||
#include "base/values.h"
|
||||
#include "ui/views/background.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.
|
||||
typedef CEF_VIEW_IMPL_D ParentClass;
|
||||
|
||||
// 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();
|
||||
}
|
||||
scoped_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::DictionaryValue* info,
|
||||
bool include_children) override {
|
||||
info->SetString("type", GetDebugType());
|
||||
info->SetInteger("id", root_view()->id());
|
||||
|
||||
// Use GetBounds() because some subclasses (like CefWindowImpl) override it.
|
||||
const CefRect& bounds = GetBounds();
|
||||
scoped_ptr<base::DictionaryValue> bounds_value(new base::DictionaryValue());
|
||||
bounds_value->SetInteger("x", bounds.x);
|
||||
bounds_value->SetInteger("y", bounds.y);
|
||||
bounds_value->SetInteger("width", bounds.width);
|
||||
bounds_value->SetInteger("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;
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
// Create the root views::View object.
|
||||
virtual ViewsViewClass* CreateRootView() = 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.
|
||||
scoped_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());
|
||||
scoped_ptr<base::DictionaryValue> info(new base::DictionaryValue());
|
||||
if (IsValid())
|
||||
GetDebugInfo(info.get(), include_children);
|
||||
else
|
||||
info->SetString("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()->id();
|
||||
}
|
||||
|
||||
CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetID(int id) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
root_view()->set_id(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 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()->visible();
|
||||
}
|
||||
|
||||
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()->enabled();
|
||||
}
|
||||
|
||||
CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetFocusable(bool focusable) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
root_view()->SetFocusable(focusable);
|
||||
}
|
||||
|
||||
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()->set_background(
|
||||
views::Background::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_
|
315
libcef/browser/views/view_util.cc
Normal file
315
libcef/browser/views/view_util.cc
Normal file
@@ -0,0 +1,315 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/view_util.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "libcef/browser/views/view_adapter.h"
|
||||
|
||||
#include "ui/aura/window.h"
|
||||
#include "ui/aura/window_tree_host.h"
|
||||
#include "ui/gfx/geometry/point.h"
|
||||
#include "ui/gfx/geometry/point_conversions.h"
|
||||
#include "ui/gfx/screen.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "ui/views/widget/widget_delegate.h"
|
||||
#include "ui/views/window/non_client_view.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "ui/gfx/win/dpi.h"
|
||||
#endif
|
||||
|
||||
namespace view_util {
|
||||
|
||||
namespace {
|
||||
|
||||
// Manages the association between views::View and CefView instances.
|
||||
class UserData : public base::SupportsUserData::Data {
|
||||
public:
|
||||
// Create the initial association between the views::View and the CefView. The
|
||||
// CefView owns the views::View at this stage.
|
||||
static void Register(CefRefPtr<CefView> cef_view) {
|
||||
DCHECK(cef_view->IsValid());
|
||||
DCHECK(!cef_view->IsAttached());
|
||||
|
||||
views::View* view = CefViewAdapter::GetFor(cef_view)->Get();
|
||||
DCHECK(view);
|
||||
|
||||
// The CefView should not already be registered.
|
||||
DCHECK(!view->GetUserData(UserDataKey()));
|
||||
|
||||
view->SetUserData(UserDataKey(), new UserData(cef_view));
|
||||
}
|
||||
|
||||
static CefRefPtr<CefView> GetFor(const views::View* view) {
|
||||
DCHECK(view);
|
||||
UserData* data = static_cast<UserData*>(view->GetUserData(UserDataKey()));
|
||||
if (data)
|
||||
return data->view_ref_;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Transfer ownership of the views::View to the caller. The views::View will
|
||||
// gain a ref-counted reference to the CefView and the CefView will keep an
|
||||
// unowned reference to the views::View. Destruction of the views::View will
|
||||
// release the ref-counted reference to the CefView.
|
||||
static scoped_ptr<views::View> PassOwnership(
|
||||
CefRefPtr<CefView> cef_view) WARN_UNUSED_RESULT {
|
||||
DCHECK(cef_view->IsValid());
|
||||
DCHECK(!cef_view->IsAttached());
|
||||
|
||||
scoped_ptr<views::View> view =
|
||||
CefViewAdapter::GetFor(cef_view)->PassOwnership();
|
||||
DCHECK(view);
|
||||
|
||||
UserData* data = static_cast<UserData*>(view->GetUserData(UserDataKey()));
|
||||
DCHECK(data);
|
||||
data->TakeReference();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
// The CefView resumes ownership of the views::View. The views::View no longer
|
||||
// keeps a ref-counted reference to the CefView.
|
||||
static void ResumeOwnership(CefRefPtr<CefView> cef_view) {
|
||||
DCHECK(cef_view->IsValid());
|
||||
DCHECK(cef_view->IsAttached());
|
||||
|
||||
CefViewAdapter* adapter = CefViewAdapter::GetFor(cef_view);
|
||||
adapter->ResumeOwnership();
|
||||
|
||||
views::View* view = adapter->Get();
|
||||
DCHECK(view);
|
||||
|
||||
UserData* data = static_cast<UserData*>(view->GetUserData(UserDataKey()));
|
||||
DCHECK(data);
|
||||
data->ReleaseReference();
|
||||
}
|
||||
|
||||
private:
|
||||
explicit UserData(CefRefPtr<CefView> cef_view)
|
||||
: view_ref_(cef_view.get()) {
|
||||
DCHECK(view_ref_);
|
||||
}
|
||||
|
||||
~UserData() override {
|
||||
if (view_) {
|
||||
// The CefView does not own the views::View. Remove the CefView's
|
||||
// reference to the views::View.
|
||||
CefViewAdapter::GetFor(view_)->Detach();
|
||||
}
|
||||
}
|
||||
|
||||
void TakeReference() {
|
||||
view_ = view_ref_;
|
||||
}
|
||||
|
||||
void ReleaseReference() {
|
||||
view_ = nullptr;
|
||||
}
|
||||
|
||||
static void* UserDataKey() {
|
||||
// We just need a unique constant. Use the address of a static that
|
||||
// COMDAT folding won't touch in an optimizing linker.
|
||||
static int data_key = 0;
|
||||
return reinterpret_cast<void*>(&data_key);
|
||||
}
|
||||
|
||||
CefRefPtr<CefView> view_;
|
||||
CefView* view_ref_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
const SkColor kDefaultBackgroundColor = SkColorSetARGB(255, 255, 255, 255);
|
||||
const char kDefaultFontList[] = "Arial, Helvetica, 14px";
|
||||
|
||||
void Register(CefRefPtr<CefView> view) {
|
||||
UserData::Register(view);
|
||||
}
|
||||
|
||||
CefRefPtr<CefView> GetFor(const views::View* view, bool find_known_parent) {
|
||||
if (!view)
|
||||
return nullptr;
|
||||
|
||||
if (!find_known_parent)
|
||||
return UserData::GetFor(view);
|
||||
|
||||
CefRefPtr<CefView> cef_view;
|
||||
const views::View* current_view = view;
|
||||
do {
|
||||
cef_view = UserData::GetFor(current_view);
|
||||
if (cef_view)
|
||||
break;
|
||||
current_view = current_view->parent();
|
||||
} while (current_view);
|
||||
|
||||
return cef_view;
|
||||
}
|
||||
|
||||
views::View* GetFor(CefRefPtr<CefView> view) {
|
||||
return CefViewAdapter::GetFor(view)->Get();
|
||||
}
|
||||
|
||||
scoped_ptr<views::View> PassOwnership(CefRefPtr<CefView> view) {
|
||||
return UserData::PassOwnership(view);
|
||||
}
|
||||
|
||||
void ResumeOwnership(CefRefPtr<CefView> view) {
|
||||
UserData::ResumeOwnership(view);
|
||||
}
|
||||
|
||||
CefRefPtr<CefWindow> GetWindowFor(views::Widget* widget) {
|
||||
CefRefPtr<CefWindow> window;
|
||||
|
||||
if (widget) {
|
||||
// The views::WidgetDelegate should be a CefWindowView and |content_view|
|
||||
// should be the same CefWindowView. However, just in case the views::Widget
|
||||
// was created by something else let's go about this the safer way.
|
||||
views::View* content_view = widget->widget_delegate()->GetContentsView();
|
||||
CefRefPtr<CefView> cef_view = GetFor(content_view, false);
|
||||
if (cef_view && cef_view->AsPanel())
|
||||
window = cef_view->AsPanel()->AsWindow();
|
||||
|
||||
// The Window should always exist if we created the views::Widget.
|
||||
DCHECK(window);
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
gfx::Display GetDisplayNearestPoint(const gfx::Point& point,
|
||||
bool input_pixel_coords) {
|
||||
gfx::Point find_point = point;
|
||||
#if defined(OS_WIN)
|
||||
if (input_pixel_coords)
|
||||
find_point = gfx::win::ScreenToDIPPoint(point);
|
||||
#endif
|
||||
return gfx::Screen::GetScreen()->GetDisplayNearestPoint(find_point);
|
||||
}
|
||||
|
||||
gfx::Display GetDisplayMatchingBounds(const gfx::Rect& bounds,
|
||||
bool input_pixel_coords) {
|
||||
gfx::Rect find_bounds = bounds;
|
||||
#if defined(OS_WIN)
|
||||
if (input_pixel_coords)
|
||||
find_bounds = gfx::win::ScreenToDIPRect(find_bounds);
|
||||
#endif
|
||||
return gfx::Screen::GetScreen()->GetDisplayMatching(bounds);
|
||||
}
|
||||
|
||||
void ConvertPointFromPixels(gfx::Point* point,
|
||||
int device_scale_factor) {
|
||||
*point = gfx::ToFlooredPoint(
|
||||
gfx::ScalePoint(gfx::PointF(*point), 1.0f / device_scale_factor));
|
||||
}
|
||||
|
||||
void ConvertPointToPixels(gfx::Point* point,
|
||||
int device_scale_factor) {
|
||||
*point = gfx::ToFlooredPoint(
|
||||
gfx::ScalePoint(gfx::PointF(*point), device_scale_factor));
|
||||
}
|
||||
|
||||
bool ConvertPointToScreen(views::View* view,
|
||||
gfx::Point* point,
|
||||
bool output_pixel_coords) {
|
||||
if (!view->GetWidget())
|
||||
return false;
|
||||
|
||||
views::View::ConvertPointToScreen(view, point);
|
||||
|
||||
if (output_pixel_coords) {
|
||||
const gfx::Display& display = GetDisplayNearestPoint(*point, false);
|
||||
ConvertPointToPixels(point, display.device_scale_factor());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConvertPointFromScreen(views::View* view,
|
||||
gfx::Point* point,
|
||||
bool input_pixel_coords) {
|
||||
if (!view->GetWidget())
|
||||
return false;
|
||||
|
||||
if (input_pixel_coords) {
|
||||
const gfx::Display& display = GetDisplayNearestPoint(*point, true);
|
||||
ConvertPointFromPixels(point, display.device_scale_factor());
|
||||
}
|
||||
|
||||
views::View::ConvertPointFromScreen(view, point);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConvertPointToWindow(views::View* view,
|
||||
gfx::Point* point) {
|
||||
views::Widget* widget = view->GetWidget();
|
||||
if (!widget)
|
||||
return false;
|
||||
|
||||
views::View::ConvertPointToWidget(view, point);
|
||||
|
||||
if (widget->non_client_view()) {
|
||||
views::NonClientFrameView* non_client_frame_view =
|
||||
widget->non_client_view()->frame_view();
|
||||
if (non_client_frame_view) {
|
||||
// When using a custom drawn NonClientFrameView the native Window will not
|
||||
// know the actual client bounds. Adjust the native Window bounds for the
|
||||
// reported client bounds.
|
||||
const gfx::Rect& client_bounds =
|
||||
non_client_frame_view->GetBoundsForClientView();
|
||||
*point -= client_bounds.OffsetFromOrigin();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConvertPointFromWindow(views::View* view,
|
||||
gfx::Point* point) {
|
||||
|
||||
views::Widget* widget = view->GetWidget();
|
||||
if (!widget)
|
||||
return false;
|
||||
|
||||
if (widget->non_client_view()) {
|
||||
views::NonClientFrameView* non_client_frame_view =
|
||||
widget->non_client_view()->frame_view();
|
||||
if (non_client_frame_view) {
|
||||
// When using a custom drawn NonClientFrameView the native Window will not
|
||||
// know the actual client bounds. Adjust the native Window bounds for the
|
||||
// reported client bounds.
|
||||
const gfx::Rect& client_bounds =
|
||||
non_client_frame_view->GetBoundsForClientView();
|
||||
*point += client_bounds.OffsetFromOrigin();
|
||||
}
|
||||
}
|
||||
|
||||
views::View::ConvertPointFromWidget(view, point);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
gfx::NativeWindow GetNativeWindow(views::Widget* widget) {
|
||||
if (widget) {
|
||||
aura::Window* window = widget->GetNativeWindow();
|
||||
if (window)
|
||||
return window->GetRootWindow();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CefWindowHandle GetWindowHandle(views::Widget* widget) {
|
||||
// Same implementation as views::HWNDForView() but cross-platform.
|
||||
if (widget) {
|
||||
aura::Window* window = widget->GetNativeWindow();
|
||||
if (window && window->GetRootWindow())
|
||||
return window->GetHost()->GetAcceleratedWidget();
|
||||
}
|
||||
return kNullWindowHandle;
|
||||
}
|
||||
|
||||
} // namespace view_util
|
127
libcef/browser/views/view_util.h
Normal file
127
libcef/browser/views/view_util.h
Normal file
@@ -0,0 +1,127 @@
|
||||
// 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_UTIL_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_VIEW_UTIL_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_view.h"
|
||||
#include "include/views/cef_window.h"
|
||||
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "ui/views/view.h"
|
||||
|
||||
namespace gfx {
|
||||
class Display;
|
||||
class Point;
|
||||
}
|
||||
|
||||
namespace views {
|
||||
class Widget;
|
||||
}
|
||||
|
||||
#define CEF_REQUIRE_VALID_RETURN(ret) \
|
||||
if (!ParentClass::IsValid()) \
|
||||
return ret;
|
||||
|
||||
#define CEF_REQUIRE_VALID_RETURN_VOID() \
|
||||
if (!ParentClass::IsValid()) \
|
||||
return;
|
||||
|
||||
// The below functions manage the relationship between CefView and views::View
|
||||
// instances. See comments in view_impl.h for a usage overview.
|
||||
|
||||
namespace view_util {
|
||||
|
||||
// Default values.
|
||||
extern const SkColor kDefaultBackgroundColor;
|
||||
extern const char kDefaultFontList[];
|
||||
|
||||
// Called when a CefView is initialized to create the initial association
|
||||
// between the underlying views::View and |view|. The CefView owns the
|
||||
// views::View at this stage.
|
||||
void Register(CefRefPtr<CefView> view);
|
||||
|
||||
// Returns the CefView object associated with the specified |view|. If no
|
||||
// CefView is associated with |view| and |find_known_parent| is true then this
|
||||
// function will return the closest parent views::View with an associated
|
||||
// CefView.
|
||||
CefRefPtr<CefView> GetFor(const views::View* view, bool find_known_parent);
|
||||
|
||||
// Returns the views::View object associated with the specified |view|.
|
||||
// Ownership of the views::View object does not change.
|
||||
views::View* GetFor(CefRefPtr<CefView> view);
|
||||
|
||||
// Returns the views::View object associated with the specified |view| and
|
||||
// passes ownership to the caller. The views::View object should then be passed
|
||||
// to another views::View via views::View or views::LayoutManager methods. The
|
||||
// views::View will keep a ref-counted reference to |view|, and |view| will keep
|
||||
// an un-owned reference to the views::View. These references will reset when
|
||||
// the views::View object is deleted or when ResumeOwnership() is called.
|
||||
scoped_ptr<views::View> PassOwnership(CefRefPtr<CefView> view)
|
||||
WARN_UNUSED_RESULT;
|
||||
|
||||
// Causes |view| to resume ownership of the views::View object. Should be called
|
||||
// after removing the views::View object from its previous parent.
|
||||
void ResumeOwnership(CefRefPtr<CefView> view);
|
||||
|
||||
// Returns the Window associated with |widget|.
|
||||
CefRefPtr<CefWindow> GetWindowFor(views::Widget* widget);
|
||||
|
||||
// Returns the Display nearest |point|. Set |input_pixel_coords| to true if
|
||||
// |point| is in pixel coordinates instead of density independent pixels (DIP).
|
||||
gfx::Display GetDisplayNearestPoint(const gfx::Point& point,
|
||||
bool input_pixel_coords);
|
||||
|
||||
// Returns the Display that most closely intersects |bounds|. Set
|
||||
// |input_pixel_coords| to true if |bounds| is in pixel coordinates instead of
|
||||
// density independent pixels (DIP).
|
||||
gfx::Display GetDisplayMatchingBounds(const gfx::Rect& bounds,
|
||||
bool input_pixel_coords);
|
||||
|
||||
// Convert |point| from pixel coordinates to density independent pixels (DIP)
|
||||
// using |device_scale_factor|.
|
||||
void ConvertPointFromPixels(gfx::Point* point,
|
||||
int device_scale_factor);
|
||||
|
||||
// Convert |point| to pixel coordinates from density independent pixels (DIP)
|
||||
// using |device_scale_factor|.
|
||||
void ConvertPointToPixels(gfx::Point* point,
|
||||
int device_scale_factor);
|
||||
|
||||
// Convert |point| from |view| to screen coordinates. If |output_pixel_coords|
|
||||
// is true then |point| will be output in pixel coordinates instead of density
|
||||
// independent pixels (DIP). Returns false if |view| does not currently belong
|
||||
// to a Widget.
|
||||
bool ConvertPointToScreen(views::View* view,
|
||||
gfx::Point* point,
|
||||
bool output_pixel_coords);
|
||||
|
||||
// Convert |point| from screen to |view| coordinates. Set |input_pixel_coords|
|
||||
// to true when |point| is being input in pixel coordinates instead of density
|
||||
// independent pixels (DIP). Returns false if |view| does not currently belong
|
||||
// to a Widget.
|
||||
bool ConvertPointFromScreen(views::View* view,
|
||||
gfx::Point* point,
|
||||
bool input_pixel_coords);
|
||||
|
||||
// Convert |point| from |view| to window (Widget) coordinates. Returns false if
|
||||
// |view| does not currently belong to a Widget.
|
||||
bool ConvertPointToWindow(views::View* view,
|
||||
gfx::Point* point);
|
||||
|
||||
// Convert |point| from window (Widget) to |view| coordinates. Returns false if
|
||||
// |view| does not currently belong to a Widget.
|
||||
bool ConvertPointFromWindow(views::View* view,
|
||||
gfx::Point* point);
|
||||
|
||||
// Returns the native window handle for |widget|. May return nullptr.
|
||||
gfx::NativeWindow GetNativeWindow(views::Widget* widget);
|
||||
|
||||
// Returns the platform window handle for |widget|. May return nullptr.
|
||||
CefWindowHandle GetWindowHandle(views::Widget* widget);
|
||||
|
||||
} // namespace view_util
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_VIEW_UTIL_H_
|
190
libcef/browser/views/view_view.h
Normal file
190
libcef/browser/views/view_view.h
Normal file
@@ -0,0 +1,190 @@
|
||||
// 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_VIEW_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_VIEW_VIEW_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_view.h"
|
||||
#include "include/views/cef_view_delegate.h"
|
||||
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/browser/views/view_util.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "ui/views/background.h"
|
||||
#include "ui/views/view.h"
|
||||
|
||||
// Helpers for template boiler-plate.
|
||||
#define CEF_VIEW_VIEW_T \
|
||||
template <class ViewsViewClass, class CefViewDelegateClass>
|
||||
#define CEF_VIEW_VIEW_A \
|
||||
ViewsViewClass, CefViewDelegateClass
|
||||
#define CEF_VIEW_VIEW_D CefViewView<CEF_VIEW_VIEW_A>
|
||||
|
||||
// Base template for implementing views::View-derived classes. The views::View-
|
||||
// derived type passed to this template must provide a no-argument constructor
|
||||
// (for example, see LabelButtonEx from basic_label_button_view.h). See comments
|
||||
// in view_impl.h for a usage overview.
|
||||
CEF_VIEW_VIEW_T class CefViewView : public ViewsViewClass {
|
||||
public:
|
||||
typedef ViewsViewClass ParentClass;
|
||||
|
||||
// |cef_delegate| may be nullptr.
|
||||
explicit CefViewView(CefViewDelegateClass* cef_delegate)
|
||||
: cef_delegate_(cef_delegate) {
|
||||
// Use our defaults instead of the Views framework defaults.
|
||||
ParentClass::set_background(views::Background::CreateSolidBackground(
|
||||
view_util::kDefaultBackgroundColor));
|
||||
}
|
||||
|
||||
// Returns the CefViewDelegate-derived delegate associated with this view.
|
||||
// May return nullptr.
|
||||
CefViewDelegateClass* cef_delegate() const { return cef_delegate_; }
|
||||
|
||||
// Returns the CefView associated with this view. May return nullptr during
|
||||
// CefViewImpl initialization. If callbacks to the CefViewImpl-derived class
|
||||
// are required define an interface that the CefViewImpl-derived class can
|
||||
// implement and pass as an unowned instance to this object's constructor (see
|
||||
// for example CefWindowView).
|
||||
CefRefPtr<CefView> GetCefView() const {
|
||||
CefRefPtr<CefView> view = view_util::GetFor(this, false);
|
||||
DCHECK(view);
|
||||
return view;
|
||||
}
|
||||
|
||||
// views::View methods:
|
||||
gfx::Size GetPreferredSize() const override;
|
||||
gfx::Size GetMinimumSize() const override;
|
||||
gfx::Size GetMaximumSize() const override;
|
||||
int GetHeightForWidth(int w) const override;
|
||||
void Layout() override;
|
||||
void ViewHierarchyChanged(
|
||||
const views::View::ViewHierarchyChangedDetails& details) override;
|
||||
|
||||
// Return true if this View is expected to have a minimum size (for example,
|
||||
// a button where the minimum size is based on the label).
|
||||
virtual bool HasMinimumSize() const { return false; }
|
||||
|
||||
private:
|
||||
void NotifyChildViewChanged(
|
||||
const views::View::ViewHierarchyChangedDetails& details);
|
||||
void NotifyParentViewChanged(
|
||||
const views::View::ViewHierarchyChangedDetails& details);
|
||||
|
||||
// Not owned by this object.
|
||||
CefViewDelegateClass* cef_delegate_;
|
||||
};
|
||||
|
||||
CEF_VIEW_VIEW_T gfx::Size CEF_VIEW_VIEW_D::GetPreferredSize() const {
|
||||
gfx::Size result;
|
||||
if (cef_delegate()) {
|
||||
CefSize cef_size = cef_delegate()->GetPreferredSize(GetCefView());
|
||||
if (!cef_size.IsEmpty())
|
||||
result = gfx::Size(cef_size.width, cef_size.height);
|
||||
}
|
||||
if (result.IsEmpty())
|
||||
result = ParentClass::GetPreferredSize();
|
||||
if (result.IsEmpty()) {
|
||||
// Some layouts like BoxLayout expect the preferred size to be non-empty.
|
||||
// The user may have set the size explicitly. Therefore return the current
|
||||
// size as the preferred size.
|
||||
result = ParentClass::size();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
CEF_VIEW_VIEW_T gfx::Size CEF_VIEW_VIEW_D::GetMinimumSize() const {
|
||||
gfx::Size result;
|
||||
if (cef_delegate()) {
|
||||
CefSize cef_size = cef_delegate()->GetMinimumSize(GetCefView());
|
||||
if (!cef_size.IsEmpty())
|
||||
result = gfx::Size(cef_size.width, cef_size.height);
|
||||
}
|
||||
// We don't want to call ParentClass::GetMinimumSize() in all cases because
|
||||
// the default views::View implementation will call GetPreferredSize(). That
|
||||
// may result in size() being returned which keeps the View from shrinking.
|
||||
if (result.IsEmpty() && HasMinimumSize())
|
||||
result = ParentClass::GetMinimumSize();
|
||||
return result;
|
||||
}
|
||||
|
||||
CEF_VIEW_VIEW_T gfx::Size CEF_VIEW_VIEW_D::GetMaximumSize() const {
|
||||
gfx::Size result;
|
||||
if (cef_delegate()) {
|
||||
CefSize cef_size = cef_delegate()->GetMaximumSize(GetCefView());
|
||||
if (!cef_size.IsEmpty())
|
||||
result = gfx::Size(cef_size.width, cef_size.height);
|
||||
}
|
||||
if (result.IsEmpty())
|
||||
result = ParentClass::GetMaximumSize();
|
||||
return result;
|
||||
}
|
||||
|
||||
CEF_VIEW_VIEW_T int CEF_VIEW_VIEW_D::GetHeightForWidth(int w) const {
|
||||
int result = 0;
|
||||
if (cef_delegate())
|
||||
result = cef_delegate()->GetHeightForWidth(GetCefView(), w);
|
||||
if (result == 0)
|
||||
result = ParentClass::GetHeightForWidth(w);
|
||||
if (result == 0) {
|
||||
// Some layouts like FillLayout will ignore the preferred size if this view
|
||||
// has no children. We want to use the preferred size if not otherwise
|
||||
// specified.
|
||||
result = GetPreferredSize().height();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
CEF_VIEW_VIEW_T void CEF_VIEW_VIEW_D::Layout() {
|
||||
ParentClass::Layout();
|
||||
|
||||
// If Layout() did not provide a size then use the preferred size.
|
||||
if (ParentClass::size().IsEmpty())
|
||||
ParentClass::SizeToPreferredSize();
|
||||
}
|
||||
|
||||
CEF_VIEW_VIEW_T void CEF_VIEW_VIEW_D::ViewHierarchyChanged(
|
||||
const views::View::ViewHierarchyChangedDetails& details) {
|
||||
NotifyChildViewChanged(details);
|
||||
NotifyParentViewChanged(details);
|
||||
ParentClass::ViewHierarchyChanged(details);
|
||||
}
|
||||
|
||||
CEF_VIEW_VIEW_T void CEF_VIEW_VIEW_D::NotifyChildViewChanged(
|
||||
const views::View::ViewHierarchyChangedDetails& details) {
|
||||
if (!cef_delegate())
|
||||
return;
|
||||
|
||||
// Only interested with the parent is |this| object and the notification is
|
||||
// about an immediate child (notifications are also sent for grandchildren).
|
||||
if (details.parent != this || details.child->parent() != this)
|
||||
return;
|
||||
|
||||
// Only notify for children that have a known CEF root view. For example,
|
||||
// don't notify when ScrollView adds child scroll bars.
|
||||
CefRefPtr<CefView> child = view_util::GetFor(details.child, false);
|
||||
if (child)
|
||||
cef_delegate()->OnChildViewChanged(GetCefView(), details.is_add, child);
|
||||
}
|
||||
|
||||
CEF_VIEW_VIEW_T void CEF_VIEW_VIEW_D::NotifyParentViewChanged(
|
||||
const views::View::ViewHierarchyChangedDetails& details) {
|
||||
if (!cef_delegate())
|
||||
return;
|
||||
|
||||
// Only interested when the child is |this| object and notification is about
|
||||
// the immediate parent (notifications are sent for all parents).
|
||||
if (details.child != this || details.parent != ParentClass::parent())
|
||||
return;
|
||||
|
||||
// The immediate parent might be an intermediate view so find the closest
|
||||
// known CEF root view.
|
||||
CefRefPtr<CefView> parent = view_util::GetFor(details.parent, true);
|
||||
DCHECK(parent);
|
||||
cef_delegate()->OnParentViewChanged(GetCefView(), details.is_add, parent);
|
||||
}
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_VIEW_VIEW_H_
|
499
libcef/browser/views/window_impl.cc
Normal file
499
libcef/browser/views/window_impl.cc
Normal file
@@ -0,0 +1,499 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/window_impl.h"
|
||||
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/browser/views/display_impl.h"
|
||||
#include "libcef/browser/views/fill_layout_impl.h"
|
||||
#include "libcef/browser/views/layout_util.h"
|
||||
#include "libcef/browser/views/view_util.h"
|
||||
#include "libcef/browser/views/window_view.h"
|
||||
|
||||
#include "ui/base/test/ui_controls.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "ui/views/controls/menu/menu_runner.h"
|
||||
|
||||
#if defined(USE_AURA)
|
||||
#include "ui/aura/test/ui_controls_factory_aura.h"
|
||||
#include "ui/base/test/ui_controls_aura.h"
|
||||
#if defined(OS_LINUX)
|
||||
#include "ui/views/test/ui_controls_factory_desktop_aurax11.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "ui/gfx/win/dpi.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
// Based on chrome/test/base/interactive_ui_tests_main.cc.
|
||||
void InitializeUITesting() {
|
||||
static bool initialized = false;
|
||||
if (!initialized) {
|
||||
ui_controls::EnableUIControls();
|
||||
|
||||
#if defined(USE_AURA)
|
||||
#if defined(OS_LINUX)
|
||||
ui_controls::InstallUIControlsAura(
|
||||
views::test::CreateUIControlsDesktopAura());
|
||||
#else
|
||||
ui_controls::InstallUIControlsAura(aura::test::CreateUIControlsAura(NULL));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
CefRefPtr<CefWindow> CefWindow::CreateTopLevelWindow(
|
||||
CefRefPtr<CefWindowDelegate> delegate) {
|
||||
return CefWindowImpl::Create(delegate);
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<CefWindowImpl> CefWindowImpl::Create(
|
||||
CefRefPtr<CefWindowDelegate> delegate) {
|
||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||
CefRefPtr<CefWindowImpl> window = new CefWindowImpl(delegate);
|
||||
window->Initialize();
|
||||
window->CreateWidget();
|
||||
if (delegate)
|
||||
delegate->OnWindowCreated(window.get());
|
||||
return window;
|
||||
}
|
||||
|
||||
void CefWindowImpl::Show() {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (widget_)
|
||||
widget_->Show();
|
||||
}
|
||||
|
||||
void CefWindowImpl::Hide() {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (widget_)
|
||||
widget_->Hide();
|
||||
}
|
||||
|
||||
void CefWindowImpl::CenterWindow(const CefSize& size) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (widget_)
|
||||
widget_->CenterWindow(gfx::Size(size.width, size.height));
|
||||
}
|
||||
|
||||
void CefWindowImpl::Close() {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (widget_ && !widget_->IsClosed())
|
||||
widget_->Close();
|
||||
}
|
||||
|
||||
bool CefWindowImpl::IsClosed() {
|
||||
CEF_REQUIRE_UIT_RETURN(false);
|
||||
return destroyed_ || (widget_ && widget_->IsClosed());
|
||||
}
|
||||
|
||||
void CefWindowImpl::Activate() {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (widget_ && widget_->CanActivate() && !widget_->IsActive())
|
||||
widget_->Activate();
|
||||
}
|
||||
|
||||
void CefWindowImpl::Deactivate() {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (widget_&& widget_->CanActivate() && widget_->IsActive())
|
||||
widget_->Deactivate();
|
||||
}
|
||||
|
||||
bool CefWindowImpl::IsActive() {
|
||||
CEF_REQUIRE_VALID_RETURN(false);
|
||||
if (widget_)
|
||||
return widget_->IsActive();
|
||||
return false;
|
||||
}
|
||||
|
||||
void CefWindowImpl::BringToTop() {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (widget_)
|
||||
widget_->StackAtTop();
|
||||
}
|
||||
|
||||
void CefWindowImpl::SetAlwaysOnTop(bool on_top) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (widget_ && on_top != widget_->IsAlwaysOnTop())
|
||||
widget_->SetAlwaysOnTop(on_top);
|
||||
}
|
||||
|
||||
bool CefWindowImpl::IsAlwaysOnTop() {
|
||||
CEF_REQUIRE_VALID_RETURN(false);
|
||||
if (widget_)
|
||||
return widget_->IsAlwaysOnTop();
|
||||
return false;
|
||||
}
|
||||
|
||||
void CefWindowImpl::Maximize() {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (widget_ && !widget_->IsMaximized())
|
||||
widget_->Maximize();
|
||||
}
|
||||
|
||||
void CefWindowImpl::Minimize() {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (widget_ && !widget_->IsMinimized())
|
||||
widget_->Minimize();
|
||||
}
|
||||
|
||||
void CefWindowImpl::Restore() {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (widget_ && (widget_->IsMaximized() || widget_->IsMinimized()))
|
||||
widget_->Restore();
|
||||
}
|
||||
|
||||
void CefWindowImpl::SetFullscreen(bool fullscreen) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (widget_ && fullscreen != widget_->IsFullscreen())
|
||||
widget_->SetFullscreen(fullscreen);
|
||||
}
|
||||
|
||||
bool CefWindowImpl::IsMaximized() {
|
||||
CEF_REQUIRE_VALID_RETURN(false);
|
||||
if (widget_)
|
||||
return widget_->IsMaximized();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CefWindowImpl::IsMinimized() {
|
||||
CEF_REQUIRE_VALID_RETURN(false);
|
||||
if (widget_)
|
||||
return widget_->IsMinimized();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CefWindowImpl::IsFullscreen() {
|
||||
CEF_REQUIRE_VALID_RETURN(false);
|
||||
if (widget_)
|
||||
return widget_->IsFullscreen();
|
||||
return false;
|
||||
}
|
||||
|
||||
void CefWindowImpl::SetTitle(const CefString& title) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (root_view())
|
||||
root_view()->SetTitle(title);
|
||||
}
|
||||
|
||||
CefString CefWindowImpl::GetTitle() {
|
||||
CEF_REQUIRE_VALID_RETURN(CefString());
|
||||
if (root_view())
|
||||
return root_view()->title();
|
||||
return CefString();
|
||||
}
|
||||
|
||||
void CefWindowImpl::SetWindowIcon(CefRefPtr<CefImage> image) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (root_view())
|
||||
root_view()->SetWindowIcon(image);
|
||||
}
|
||||
|
||||
CefRefPtr<CefImage> CefWindowImpl::GetWindowIcon() {
|
||||
CEF_REQUIRE_VALID_RETURN(nullptr);
|
||||
if (root_view())
|
||||
return root_view()->window_icon();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CefWindowImpl::SetWindowAppIcon(CefRefPtr<CefImage> image) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (root_view())
|
||||
root_view()->SetWindowAppIcon(image);
|
||||
}
|
||||
|
||||
CefRefPtr<CefImage> CefWindowImpl::GetWindowAppIcon() {
|
||||
CEF_REQUIRE_VALID_RETURN(nullptr);
|
||||
if (root_view())
|
||||
return root_view()->window_app_icon();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CefWindowImpl::GetDebugInfo(base::DictionaryValue* info,
|
||||
bool include_children) {
|
||||
ParentClass::GetDebugInfo(info, include_children);
|
||||
if (root_view())
|
||||
info->SetString("title", root_view()->title());
|
||||
}
|
||||
|
||||
void CefWindowImpl::ShowMenu(CefRefPtr<CefMenuModel> menu_model,
|
||||
const CefPoint& screen_point,
|
||||
cef_menu_anchor_position_t anchor_position) {
|
||||
ShowMenu(nullptr, menu_model, screen_point, anchor_position);
|
||||
}
|
||||
|
||||
void CefWindowImpl::Detach() {
|
||||
// OnDeleteDelegate should always be called before Detach().
|
||||
DCHECK(!widget_);
|
||||
|
||||
ParentClass::Detach();
|
||||
}
|
||||
|
||||
void CefWindowImpl::SetBounds(const CefRect& bounds) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (widget_) {
|
||||
widget_->SetBounds(
|
||||
gfx::Rect(bounds.x, bounds.y, bounds.width, bounds.height));
|
||||
}
|
||||
}
|
||||
|
||||
CefRect CefWindowImpl::GetBounds() {
|
||||
CEF_REQUIRE_VALID_RETURN(CefRect());
|
||||
gfx::Rect bounds;
|
||||
if (widget_)
|
||||
bounds = widget_->GetWindowBoundsInScreen();
|
||||
return CefRect(bounds.x(), bounds.y(), bounds.width(), bounds.height());
|
||||
}
|
||||
|
||||
CefRect CefWindowImpl::GetBoundsInScreen() {
|
||||
return GetBounds();
|
||||
}
|
||||
|
||||
void CefWindowImpl::SetSize(const CefSize& size) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (widget_)
|
||||
widget_->SetSize(gfx::Size(size.width, size.height));
|
||||
}
|
||||
|
||||
void CefWindowImpl::SetPosition(const CefPoint& position) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (widget_) {
|
||||
gfx::Rect bounds = widget_->GetWindowBoundsInScreen();
|
||||
bounds.set_origin(gfx::Point(position.x, position.y));
|
||||
widget_->SetBounds(bounds);
|
||||
}
|
||||
}
|
||||
|
||||
void CefWindowImpl::SizeToPreferredSize() {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (widget_) {
|
||||
if (widget_->non_client_view())
|
||||
widget_->SetSize(widget_->non_client_view()->GetPreferredSize());
|
||||
else
|
||||
widget_->SetSize(root_view()->GetPreferredSize());
|
||||
}
|
||||
}
|
||||
|
||||
void CefWindowImpl::SetVisible(bool visible) {
|
||||
if (visible)
|
||||
Show();
|
||||
else
|
||||
Hide();
|
||||
}
|
||||
|
||||
bool CefWindowImpl::IsVisible() {
|
||||
CEF_REQUIRE_VALID_RETURN(false);
|
||||
if (widget_)
|
||||
return widget_->IsVisible();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CefWindowImpl::IsDrawn() {
|
||||
return IsVisible();
|
||||
}
|
||||
|
||||
void CefWindowImpl::SetBackgroundColor(cef_color_t color) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
ParentClass::SetBackgroundColor(color);
|
||||
if (widget_ && widget_->GetCompositor())
|
||||
widget_->GetCompositor()->SetBackgroundColor(color);
|
||||
}
|
||||
|
||||
bool CefWindowImpl::CanWidgetClose() {
|
||||
if (delegate())
|
||||
return delegate()->CanClose(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CefWindowImpl::OnWindowViewDeleted() {
|
||||
CancelMenu();
|
||||
|
||||
destroyed_ = true;
|
||||
widget_ = nullptr;
|
||||
|
||||
if (delegate())
|
||||
delegate()->OnWindowDestroyed(this);
|
||||
|
||||
// Call Detach() here instead of waiting for the root View to be deleted so
|
||||
// that any following attempts to call CefWindow methods from the delegate
|
||||
// will fail.
|
||||
Detach();
|
||||
}
|
||||
|
||||
void CefWindowImpl::MenuClosed(CefRefPtr<CefMenuModelImpl> source) {
|
||||
DCHECK_EQ(menu_model_, source);
|
||||
menu_model_->RemoveObserver(this);
|
||||
menu_model_ = nullptr;
|
||||
menu_runner_.reset(nullptr);
|
||||
}
|
||||
|
||||
void CefWindowImpl::ShowMenu(views::MenuButton* menu_button,
|
||||
CefRefPtr<CefMenuModel> menu_model,
|
||||
const CefPoint& screen_point,
|
||||
cef_menu_anchor_position_t anchor_position) {
|
||||
CancelMenu();
|
||||
|
||||
if (!widget_)
|
||||
return;
|
||||
|
||||
CefMenuModelImpl* menu_model_impl =
|
||||
static_cast<CefMenuModelImpl*>(menu_model.get());
|
||||
if (!menu_model_impl || !menu_model_impl->model())
|
||||
return;
|
||||
|
||||
menu_model_ = menu_model_impl;
|
||||
menu_model_->AddObserver(this);
|
||||
|
||||
menu_runner_.reset(
|
||||
new views::MenuRunner(menu_model_impl->model(),
|
||||
menu_button ? views::MenuRunner::HAS_MNEMONICS :
|
||||
views::MenuRunner::CONTEXT_MENU));
|
||||
|
||||
views::MenuRunner::RunResult result = menu_runner_->RunMenuAt(
|
||||
widget_,
|
||||
menu_button,
|
||||
gfx::Rect(gfx::Point(screen_point.x, screen_point.y), gfx::Size()),
|
||||
static_cast<views::MenuAnchorPosition>(anchor_position),
|
||||
ui::MENU_SOURCE_NONE);
|
||||
ALLOW_UNUSED_LOCAL(result);
|
||||
}
|
||||
|
||||
void CefWindowImpl::CancelMenu() {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (menu_runner_)
|
||||
menu_runner_->Cancel();
|
||||
DCHECK(!menu_model_);
|
||||
DCHECK(!menu_runner_);
|
||||
}
|
||||
|
||||
CefRefPtr<CefDisplay> CefWindowImpl::GetDisplay() {
|
||||
CEF_REQUIRE_VALID_RETURN(nullptr);
|
||||
if (widget_ && root_view()) {
|
||||
const gfx::Display& display = root_view()->GetDisplay();
|
||||
if (display.is_valid())
|
||||
return new CefDisplayImpl(display);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CefRect CefWindowImpl::GetClientAreaBoundsInScreen() {
|
||||
CEF_REQUIRE_VALID_RETURN(CefRect());
|
||||
if (widget_) {
|
||||
gfx::Rect bounds = widget_->GetClientAreaBoundsInScreen();
|
||||
|
||||
views::NonClientFrameView* non_client_frame_view =
|
||||
root_view()->GetNonClientFrameView();
|
||||
if (non_client_frame_view) {
|
||||
// When using a custom drawn NonClientFrameView the native Window will not
|
||||
// know the actual client bounds. Adjust the native Window bounds for the
|
||||
// reported client bounds.
|
||||
const gfx::Rect& client_bounds =
|
||||
non_client_frame_view->GetBoundsForClientView();
|
||||
bounds.set_origin(bounds.origin() + client_bounds.OffsetFromOrigin());
|
||||
bounds.set_size(client_bounds.size());
|
||||
}
|
||||
|
||||
return CefRect(bounds.x(), bounds.y(), bounds.width(), bounds.height());
|
||||
}
|
||||
return CefRect();
|
||||
}
|
||||
|
||||
void CefWindowImpl::SetDraggableRegions(
|
||||
const std::vector<CefDraggableRegion>& regions) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (root_view())
|
||||
root_view()->SetDraggableRegions(regions);
|
||||
}
|
||||
|
||||
CefWindowHandle CefWindowImpl::GetWindowHandle() {
|
||||
CEF_REQUIRE_VALID_RETURN(kNullWindowHandle);
|
||||
return view_util::GetWindowHandle(widget_);
|
||||
}
|
||||
|
||||
void CefWindowImpl::SendKeyPress(int key_code,
|
||||
uint32 event_flags) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
InitializeUITesting();
|
||||
|
||||
gfx::NativeWindow native_window = view_util::GetNativeWindow(widget_);
|
||||
if (!native_window)
|
||||
return;
|
||||
|
||||
ui_controls::SendKeyPress(native_window,
|
||||
static_cast<ui::KeyboardCode>(key_code),
|
||||
!!(event_flags & EVENTFLAG_CONTROL_DOWN),
|
||||
!!(event_flags & EVENTFLAG_SHIFT_DOWN),
|
||||
!!(event_flags & EVENTFLAG_ALT_DOWN),
|
||||
false); // Command key is not supported by Aura.
|
||||
}
|
||||
|
||||
void CefWindowImpl::SendMouseMove(int screen_x, int screen_y) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
InitializeUITesting();
|
||||
|
||||
gfx::Point point(screen_x, screen_y);
|
||||
#if defined(OS_WIN)
|
||||
// Windows expects pixel coordinates.
|
||||
point = gfx::win::DIPToScreenPoint(point);
|
||||
#endif
|
||||
|
||||
ui_controls::SendMouseMove(point.x(), point.y());
|
||||
}
|
||||
|
||||
void CefWindowImpl::SendMouseEvents(cef_mouse_button_type_t button,
|
||||
bool mouse_down,
|
||||
bool mouse_up) {
|
||||
CEF_REQUIRE_VALID_RETURN_VOID();
|
||||
if (!mouse_down && !mouse_up)
|
||||
return;
|
||||
|
||||
InitializeUITesting();
|
||||
|
||||
ui_controls::MouseButton type = ui_controls::LEFT;
|
||||
if (button == MBT_MIDDLE)
|
||||
type = ui_controls::MIDDLE;
|
||||
else if (button == MBT_RIGHT)
|
||||
type = ui_controls::RIGHT;
|
||||
|
||||
int state = 0;
|
||||
if (mouse_down)
|
||||
state |= ui_controls::DOWN;
|
||||
if (mouse_up)
|
||||
state |= ui_controls::UP;
|
||||
|
||||
ui_controls::SendMouseEvents(type, state);
|
||||
}
|
||||
|
||||
CefWindowImpl::CefWindowImpl(CefRefPtr<CefWindowDelegate> delegate)
|
||||
: ParentClass(delegate),
|
||||
widget_(nullptr),
|
||||
destroyed_(false) {
|
||||
}
|
||||
|
||||
CefWindowView* CefWindowImpl::CreateRootView() {
|
||||
return new CefWindowView(delegate(), this);
|
||||
}
|
||||
|
||||
void CefWindowImpl::CreateWidget() {
|
||||
DCHECK(!widget_);
|
||||
|
||||
root_view()->CreateWidget();
|
||||
widget_ = root_view()->GetWidget();
|
||||
DCHECK(widget_);
|
||||
|
||||
// The Widget and root View are owned by the native window. Therefore don't
|
||||
// keep an owned reference.
|
||||
scoped_ptr<views::View> view_ptr = view_util::PassOwnership(this);
|
||||
views::View* view = view_ptr.release();
|
||||
ALLOW_UNUSED_LOCAL(view);
|
||||
}
|
134
libcef/browser/views/window_impl.h
Normal file
134
libcef/browser/views/window_impl.h
Normal file
@@ -0,0 +1,134 @@
|
||||
// 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_WINDOW_IMPL_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_WINDOW_IMPL_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_window.h"
|
||||
#include "include/views/cef_window_delegate.h"
|
||||
|
||||
#include "libcef/browser/menu_model_impl.h"
|
||||
#include "libcef/browser/views/panel_impl.h"
|
||||
#include "libcef/browser/views/window_view.h"
|
||||
|
||||
#include "ui/views/controls/menu/menu_runner.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
|
||||
namespace views {
|
||||
class MenuButton;
|
||||
}
|
||||
|
||||
class CefWindowImpl :
|
||||
public CefPanelImpl<CefWindowView, CefWindow, CefWindowDelegate>,
|
||||
public CefWindowView::Delegate,
|
||||
public CefMenuModelImpl::Observer {
|
||||
public:
|
||||
typedef CefPanelImpl<CefWindowView, CefWindow, CefWindowDelegate> ParentClass;
|
||||
|
||||
// Create a new CefWindow instance. |delegate| may be nullptr.
|
||||
static CefRefPtr<CefWindowImpl> Create(CefRefPtr<CefWindowDelegate> delegate);
|
||||
|
||||
// CefWindow methods:
|
||||
void Show() override;
|
||||
void Hide() override;
|
||||
void CenterWindow(const CefSize& size) override;
|
||||
void Close() override;
|
||||
bool IsClosed() override;
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
bool IsActive() override;
|
||||
void BringToTop() override;
|
||||
void SetAlwaysOnTop(bool on_top) override;
|
||||
bool IsAlwaysOnTop() override;
|
||||
void Maximize() override;
|
||||
void Minimize() override;
|
||||
void Restore() override;
|
||||
void SetFullscreen(bool fullscreen) override;
|
||||
bool IsMaximized() override;
|
||||
bool IsMinimized() override;
|
||||
bool IsFullscreen() override;
|
||||
void SetTitle(const CefString& title) override;
|
||||
CefString GetTitle() override;
|
||||
void SetWindowIcon(CefRefPtr<CefImage> image) override;
|
||||
CefRefPtr<CefImage> GetWindowIcon() override;
|
||||
void SetWindowAppIcon(CefRefPtr<CefImage> image) override;
|
||||
CefRefPtr<CefImage> GetWindowAppIcon() override;
|
||||
void ShowMenu(CefRefPtr<CefMenuModel> menu_model,
|
||||
const CefPoint& screen_point,
|
||||
cef_menu_anchor_position_t anchor_position) override;
|
||||
void CancelMenu() override;
|
||||
CefRefPtr<CefDisplay> GetDisplay() override;
|
||||
CefRect GetClientAreaBoundsInScreen() override;
|
||||
void SetDraggableRegions(
|
||||
const std::vector<CefDraggableRegion>& regions) override;
|
||||
CefWindowHandle GetWindowHandle() override;
|
||||
void SendKeyPress(int key_code,
|
||||
uint32 event_flags) override;
|
||||
void SendMouseMove(int screen_x, int screen_y) override;
|
||||
void SendMouseEvents(cef_mouse_button_type_t button,
|
||||
bool mouse_down,
|
||||
bool mouse_up) override;
|
||||
|
||||
// CefViewAdapter methods:
|
||||
void Detach() override;
|
||||
|
||||
// CefPanel methods:
|
||||
CefRefPtr<CefWindow> AsWindow() override { return this; }
|
||||
|
||||
// CefView methods:
|
||||
void SetBounds(const CefRect& bounds) override;
|
||||
CefRect GetBounds() override;
|
||||
CefRect GetBoundsInScreen() override;
|
||||
void SetSize(const CefSize& bounds) override;
|
||||
void SetPosition(const CefPoint& position) override;
|
||||
void SizeToPreferredSize() override;
|
||||
void SetVisible(bool visible) override;
|
||||
bool IsVisible() override;
|
||||
bool IsDrawn() override;
|
||||
void SetBackgroundColor(cef_color_t color) override;
|
||||
|
||||
// CefWindowView::Delegate methods:
|
||||
bool CanWidgetClose() override;
|
||||
void OnWindowViewDeleted() override;
|
||||
|
||||
// CefMenuModelImpl::Observer methods:
|
||||
void MenuClosed(CefRefPtr<CefMenuModelImpl> source) override;
|
||||
|
||||
// CefViewAdapter methods:
|
||||
std::string GetDebugType() override { return "Window"; }
|
||||
void GetDebugInfo(base::DictionaryValue* info,
|
||||
bool include_children) override;
|
||||
|
||||
void ShowMenu(views::MenuButton* menu_button,
|
||||
CefRefPtr<CefMenuModel> menu_model,
|
||||
const CefPoint& screen_point,
|
||||
cef_menu_anchor_position_t anchor_position);
|
||||
|
||||
private:
|
||||
// Create a new implementation object.
|
||||
// Always call Initialize() after creation.
|
||||
// |delegate| may be nullptr.
|
||||
explicit CefWindowImpl(CefRefPtr<CefWindowDelegate> delegate);
|
||||
|
||||
// CefViewImpl methods:
|
||||
CefWindowView* CreateRootView() override;
|
||||
|
||||
// Initialize the Widget.
|
||||
void CreateWidget();
|
||||
|
||||
views::Widget* widget_;
|
||||
|
||||
// True if the window has been destroyed.
|
||||
bool destroyed_;
|
||||
|
||||
// The currently active menu model and runner.
|
||||
CefRefPtr<CefMenuModelImpl> menu_model_;
|
||||
scoped_ptr<views::MenuRunner> menu_runner_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefWindowImpl);
|
||||
DISALLOW_COPY_AND_ASSIGN(CefWindowImpl);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_WINDOW_IMPL_H_
|
491
libcef/browser/views/window_view.cc
Normal file
491
libcef/browser/views/window_view.cc
Normal file
@@ -0,0 +1,491 @@
|
||||
// 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.
|
||||
|
||||
#include "libcef/browser/views/window_view.h"
|
||||
|
||||
#include "libcef/browser/image_impl.h"
|
||||
|
||||
#include "third_party/skia/include/core/SkRegion.h"
|
||||
#include "ui/aura/window.h"
|
||||
#include "ui/base/hit_test.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "ui/views/window/native_frame_view.h"
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
#include <X11/Xlib.h>
|
||||
#include "ui/gfx/x/x11_types.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "ui/gfx/win/dpi.h"
|
||||
#include "ui/views/win/hwnd_util.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
// Specialize ClientView to handle Widget-related events.
|
||||
class ClientViewEx : public views::ClientView {
|
||||
public:
|
||||
ClientViewEx(views::Widget* widget,
|
||||
views::View* contents_view,
|
||||
CefWindowView::Delegate* window_delegate)
|
||||
: views::ClientView(widget, contents_view),
|
||||
window_delegate_(window_delegate) {
|
||||
DCHECK(window_delegate_);
|
||||
}
|
||||
|
||||
bool CanClose() override {
|
||||
return window_delegate_->CanWidgetClose();
|
||||
}
|
||||
|
||||
private:
|
||||
CefWindowView::Delegate* window_delegate_; // Not owned by this object.
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ClientViewEx);
|
||||
};
|
||||
|
||||
// Extend NativeFrameView with draggable region handling.
|
||||
class NativeFrameViewEx : public views::NativeFrameView {
|
||||
public:
|
||||
NativeFrameViewEx(views::Widget* widget,
|
||||
CefWindowView* view)
|
||||
: views::NativeFrameView(widget),
|
||||
widget_(widget),
|
||||
view_(view) {
|
||||
}
|
||||
|
||||
gfx::Rect GetWindowBoundsForClientBounds(
|
||||
const gfx::Rect& client_bounds) const override {
|
||||
#if defined(OS_WIN)
|
||||
// views::GetWindowBoundsForClientBounds() expects the input Rect to be in
|
||||
// pixel coordinates. NativeFrameView does not implement this correctly so
|
||||
// we need to provide our own implementation. See http://crbug.com/602692.
|
||||
gfx::Rect pixel_bounds = gfx::win::DIPToScreenRect(client_bounds);
|
||||
pixel_bounds = views::GetWindowBoundsForClientBounds(
|
||||
static_cast<View*>(const_cast<NativeFrameViewEx*>(this)),
|
||||
pixel_bounds);
|
||||
return gfx::win::ScreenToDIPRect(pixel_bounds);
|
||||
#else
|
||||
// Use the default implementation.
|
||||
return views::NativeFrameView::GetWindowBoundsForClientBounds(
|
||||
client_bounds);
|
||||
#endif
|
||||
}
|
||||
|
||||
int NonClientHitTest(const gfx::Point& point) override {
|
||||
if (widget_->IsFullscreen())
|
||||
return HTCLIENT;
|
||||
|
||||
// Test for mouse clicks that fall within the draggable region.
|
||||
SkRegion* draggable_region = view_->draggable_region();
|
||||
if (draggable_region && draggable_region->contains(point.x(), point.y()))
|
||||
return HTCAPTION;
|
||||
|
||||
return views::NativeFrameView::NonClientHitTest(point);
|
||||
}
|
||||
|
||||
private:
|
||||
// Not owned by this object.
|
||||
views::Widget* widget_;
|
||||
CefWindowView* view_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NativeFrameViewEx);
|
||||
};
|
||||
|
||||
// The visible edge around the content area inside the frame border. Necessary
|
||||
// to resize when there are controls that handle mouse events at the edge of the
|
||||
// client area. Only used in restored mode.
|
||||
const int kNonClientBorderThickness = 1;
|
||||
|
||||
// The area inside the frame border that can be clicked and dragged for resizing
|
||||
// the window. Only used in restored mode.
|
||||
const int kResizeBorderThickness = 4;
|
||||
|
||||
// The distance from each window corner that triggers diaginal resizing. Only
|
||||
// used in restored mode.
|
||||
const int kResizeAreaCornerSize = 16;
|
||||
|
||||
// Implement NonClientFrameView without the system default caption and icon but
|
||||
// with a resizable border. Based on AppWindowFrameView and CustomFrameView.
|
||||
class CaptionlessFrameView : public views::NonClientFrameView {
|
||||
public:
|
||||
CaptionlessFrameView(views::Widget* widget,
|
||||
CefWindowView* view)
|
||||
: widget_(widget),
|
||||
view_(view) {
|
||||
}
|
||||
|
||||
gfx::Rect GetBoundsForClientView() const override {
|
||||
return client_view_bounds_;
|
||||
}
|
||||
|
||||
gfx::Rect GetWindowBoundsForClientBounds(
|
||||
const gfx::Rect& client_bounds) const override {
|
||||
int border_thickness = NonClientBorderThickness();
|
||||
return gfx::Rect(client_bounds.x() - border_thickness,
|
||||
client_bounds.y() - border_thickness,
|
||||
client_bounds.width() + (2 * border_thickness),
|
||||
client_bounds.height() + (2 * border_thickness));
|
||||
}
|
||||
|
||||
int NonClientHitTest(const gfx::Point& point) override {
|
||||
if (widget_->IsFullscreen())
|
||||
return HTCLIENT;
|
||||
|
||||
// Sanity check.
|
||||
if (!bounds().Contains(point))
|
||||
return HTNOWHERE;
|
||||
|
||||
// Check the frame first, as we allow a small area overlapping the contents
|
||||
// to be used for resize handles.
|
||||
bool can_ever_resize = widget_->widget_delegate()
|
||||
? widget_->widget_delegate()->CanResize()
|
||||
: false;
|
||||
// Don't allow overlapping resize handles when the window is maximized or
|
||||
// fullscreen, as it can't be resized in those states.
|
||||
int resize_border_thickness = ResizeBorderThickness();
|
||||
int frame_component = GetHTComponentForFrame(point,
|
||||
resize_border_thickness,
|
||||
resize_border_thickness,
|
||||
kResizeAreaCornerSize,
|
||||
kResizeAreaCornerSize,
|
||||
can_ever_resize);
|
||||
if (frame_component != HTNOWHERE)
|
||||
return frame_component;
|
||||
|
||||
// Test for mouse clicks that fall within the draggable region.
|
||||
SkRegion* draggable_region = view_->draggable_region();
|
||||
if (draggable_region && draggable_region->contains(point.x(), point.y()))
|
||||
return HTCAPTION;
|
||||
|
||||
int client_component = widget_->client_view()->NonClientHitTest(point);
|
||||
if (client_component != HTNOWHERE)
|
||||
return client_component;
|
||||
|
||||
// Caption is a safe default.
|
||||
return HTCAPTION;
|
||||
}
|
||||
|
||||
void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) override {
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
void ResetWindowControls() override {
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
void UpdateWindowIcon() override {
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
void UpdateWindowTitle() override {
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
void SizeConstraintsChanged() override {
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
void OnPaint(gfx::Canvas* canvas) override {
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
void Layout() override {
|
||||
int border_thickness = NonClientBorderThickness();
|
||||
client_view_bounds_.SetRect(border_thickness, border_thickness,
|
||||
std::max(0, width() - (2 * border_thickness)),
|
||||
std::max(0, height() - (2 * border_thickness)));
|
||||
}
|
||||
|
||||
gfx::Size GetPreferredSize() const override {
|
||||
return widget_->non_client_view()->GetWindowBoundsForClientBounds(
|
||||
gfx::Rect(widget_->client_view()->GetPreferredSize())).size();
|
||||
}
|
||||
|
||||
gfx::Size GetMinimumSize() const override {
|
||||
return widget_->non_client_view()->GetWindowBoundsForClientBounds(
|
||||
gfx::Rect(widget_->client_view()->GetMinimumSize())).size();
|
||||
}
|
||||
|
||||
gfx::Size GetMaximumSize() const override {
|
||||
gfx::Size max_size = widget_->client_view()->GetMaximumSize();
|
||||
gfx::Size converted_size =
|
||||
widget_->non_client_view()->GetWindowBoundsForClientBounds(
|
||||
gfx::Rect(max_size)).size();
|
||||
return gfx::Size(max_size.width() == 0 ? 0 : converted_size.width(),
|
||||
max_size.height() == 0 ? 0 : converted_size.height());
|
||||
}
|
||||
|
||||
private:
|
||||
int NonClientBorderThickness() const {
|
||||
return (widget_->IsMaximized() || widget_->IsFullscreen() ?
|
||||
0 : kNonClientBorderThickness);
|
||||
}
|
||||
|
||||
int ResizeBorderThickness() const {
|
||||
return (widget_->IsMaximized() || widget_->IsFullscreen() ?
|
||||
0 : kResizeBorderThickness);
|
||||
}
|
||||
|
||||
// Not owned by this object.
|
||||
views::Widget* widget_;
|
||||
CefWindowView* view_;
|
||||
|
||||
// The bounds of the client view, in this view's coordinates.
|
||||
gfx::Rect client_view_bounds_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CaptionlessFrameView);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
CefWindowView::CefWindowView(CefWindowDelegate* cef_delegate,
|
||||
Delegate* window_delegate)
|
||||
: ParentClass(cef_delegate),
|
||||
window_delegate_(window_delegate),
|
||||
is_frameless_(false) {
|
||||
DCHECK(window_delegate_);
|
||||
}
|
||||
|
||||
void CefWindowView::CreateWidget() {
|
||||
DCHECK(!GetWidget());
|
||||
|
||||
// |widget| is owned by the NativeWidget and will be destroyed in response to
|
||||
// a native destruction message.
|
||||
views::Widget* widget = new views::Widget;
|
||||
|
||||
views::Widget::InitParams params;
|
||||
params.delegate = this;
|
||||
params.type = views::Widget::InitParams::TYPE_WINDOW;
|
||||
|
||||
if (cef_delegate())
|
||||
is_frameless_ = cef_delegate()->IsFrameless(GetCefWindow());
|
||||
if (is_frameless_) {
|
||||
// Don't show the native window caption but keep a resizable border.
|
||||
params.remove_caption = true;
|
||||
// Remove the black opaque background that's displayed by default.
|
||||
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
|
||||
}
|
||||
|
||||
widget->Init(params);
|
||||
|
||||
// |widget| should now be associated with |this|.
|
||||
DCHECK_EQ(widget, GetWidget());
|
||||
// |widget| must be top-level for focus handling to work correctly.
|
||||
DCHECK(widget->is_top_level());
|
||||
// |widget| must be activatable for focus handling to work correctly.
|
||||
DCHECK(widget->widget_delegate()->CanActivate());
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
if (is_frameless_) {
|
||||
::Window window = view_util::GetWindowHandle(widget);
|
||||
DCHECK(window);
|
||||
::Display* display = gfx::GetXDisplay();
|
||||
DCHECK(display);
|
||||
|
||||
// Make the window borderless. From
|
||||
// http://stackoverflow.com/questions/1904445/borderless-windows-on-linux
|
||||
struct MwmHints {
|
||||
unsigned long flags;
|
||||
unsigned long functions;
|
||||
unsigned long decorations;
|
||||
long input_mode;
|
||||
unsigned long status;
|
||||
};
|
||||
enum {
|
||||
MWM_HINTS_FUNCTIONS = (1L << 0),
|
||||
MWM_HINTS_DECORATIONS = (1L << 1),
|
||||
|
||||
MWM_FUNC_ALL = (1L << 0),
|
||||
MWM_FUNC_RESIZE = (1L << 1),
|
||||
MWM_FUNC_MOVE = (1L << 2),
|
||||
MWM_FUNC_MINIMIZE = (1L << 3),
|
||||
MWM_FUNC_MAXIMIZE = (1L << 4),
|
||||
MWM_FUNC_CLOSE = (1L << 5)
|
||||
};
|
||||
|
||||
Atom mwmHintsProperty = XInternAtom(display, "_MOTIF_WM_HINTS", 0);
|
||||
struct MwmHints hints;
|
||||
hints.flags = MWM_HINTS_DECORATIONS;
|
||||
hints.decorations = 0;
|
||||
XChangeProperty(display, window, mwmHintsProperty, mwmHintsProperty, 32,
|
||||
PropModeReplace, (unsigned char *)&hints, 5);
|
||||
}
|
||||
#endif // defined(OS_LINUX)
|
||||
}
|
||||
|
||||
CefRefPtr<CefWindow> CefWindowView::GetCefWindow() const {
|
||||
CefRefPtr<CefWindow> window = GetCefPanel()->AsWindow();
|
||||
DCHECK(window);
|
||||
return window;
|
||||
}
|
||||
|
||||
void CefWindowView::DeleteDelegate() {
|
||||
// Remove all child Views before deleting the Window so that notifications
|
||||
// resolve correctly.
|
||||
RemoveAllChildViews(true);
|
||||
|
||||
window_delegate_->OnWindowViewDeleted();
|
||||
|
||||
// Deletes |this|.
|
||||
views::WidgetDelegateView::DeleteDelegate();
|
||||
}
|
||||
|
||||
bool CefWindowView::CanResize() const {
|
||||
if (!cef_delegate())
|
||||
return true;
|
||||
return cef_delegate()->CanResize(GetCefWindow());
|
||||
}
|
||||
|
||||
bool CefWindowView::CanMinimize() const {
|
||||
if (!cef_delegate())
|
||||
return true;
|
||||
return cef_delegate()->CanMinimize(GetCefWindow());
|
||||
}
|
||||
|
||||
bool CefWindowView::CanMaximize() const {
|
||||
if (!cef_delegate())
|
||||
return true;
|
||||
return cef_delegate()->CanMaximize(GetCefWindow());
|
||||
}
|
||||
|
||||
base::string16 CefWindowView::GetWindowTitle() const {
|
||||
return title_;
|
||||
}
|
||||
|
||||
gfx::ImageSkia CefWindowView::GetWindowIcon() {
|
||||
if (!window_icon_)
|
||||
return ParentClass::GetWindowIcon();
|
||||
return static_cast<CefImageImpl*>(window_icon_.get())->
|
||||
GetForced1xScaleRepresentation(GetDisplay().device_scale_factor());
|
||||
}
|
||||
|
||||
gfx::ImageSkia CefWindowView::GetWindowAppIcon() {
|
||||
if (!window_app_icon_)
|
||||
return ParentClass::GetWindowAppIcon();
|
||||
return static_cast<CefImageImpl*>(window_app_icon_.get())->
|
||||
GetForced1xScaleRepresentation(GetDisplay().device_scale_factor());
|
||||
}
|
||||
|
||||
views::View* CefWindowView::GetContentsView() {
|
||||
// |this| will be the "Contents View" hosted by the Widget via ClientView and
|
||||
// RootView.
|
||||
return this;
|
||||
}
|
||||
|
||||
views::ClientView* CefWindowView::CreateClientView(views::Widget* widget) {
|
||||
return new ClientViewEx(widget, GetContentsView(), window_delegate_);
|
||||
}
|
||||
|
||||
views::NonClientFrameView* CefWindowView::CreateNonClientFrameView(
|
||||
views::Widget* widget) {
|
||||
if (is_frameless_) {
|
||||
// Custom frame type that doesn't render a caption.
|
||||
return new CaptionlessFrameView(widget, this);
|
||||
} else if (widget->ShouldUseNativeFrame()) {
|
||||
// DesktopNativeWidgetAura::CreateNonClientFrameView() returns
|
||||
// NativeFrameView by default. Extend that type.
|
||||
return new NativeFrameViewEx(widget, this);
|
||||
} else {
|
||||
// Widget::CreateNonClientFrameView() returns CustomFrameView by default.
|
||||
// Need to extend CustomFrameView on this platform.
|
||||
NOTREACHED() << "Platform does not use NativeFrameView";
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool CefWindowView::ShouldDescendIntoChildForEventHandling(
|
||||
gfx::NativeView child,
|
||||
const gfx::Point& location) {
|
||||
if (is_frameless_) {
|
||||
// If the window is resizable it should claim mouse events that fall on the
|
||||
// window border.
|
||||
views::NonClientFrameView* ncfv = GetNonClientFrameView();
|
||||
if (ncfv) {
|
||||
int result = ncfv->NonClientHitTest(location);
|
||||
if (result >= HTLEFT && result <= HTBORDER)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// The window should claim mouse events that fall within the draggable region.
|
||||
return !draggable_region_.get() ||
|
||||
!draggable_region_->contains(location.x(), location.y());
|
||||
}
|
||||
|
||||
void CefWindowView::ViewHierarchyChanged(
|
||||
const views::View::ViewHierarchyChangedDetails& details) {
|
||||
if (details.child == this) {
|
||||
// This View's parent types (RootView, ClientView) are not exposed via the
|
||||
// CEF API. Therefore don't send notifications about this View's parent
|
||||
// changes.
|
||||
return;
|
||||
}
|
||||
|
||||
ParentClass::ViewHierarchyChanged(details);
|
||||
}
|
||||
|
||||
gfx::Display CefWindowView::GetDisplay() const {
|
||||
const views::Widget* widget = GetWidget();
|
||||
if (widget) {
|
||||
return view_util::GetDisplayMatchingBounds(
|
||||
widget->GetWindowBoundsInScreen(), false);
|
||||
}
|
||||
return gfx::Display();
|
||||
}
|
||||
|
||||
void CefWindowView::SetTitle(const base::string16& title) {
|
||||
title_ = title;
|
||||
views::Widget* widget = GetWidget();
|
||||
if (widget)
|
||||
widget->UpdateWindowTitle();
|
||||
}
|
||||
|
||||
void CefWindowView::SetWindowIcon(CefRefPtr<CefImage> window_icon) {
|
||||
if (std::max(window_icon->GetWidth(), window_icon->GetHeight()) != 16U) {
|
||||
DLOG(ERROR) << "Window icons must be 16 DIP in size.";
|
||||
return;
|
||||
}
|
||||
|
||||
window_icon_ = window_icon;
|
||||
views::Widget* widget = GetWidget();
|
||||
if (widget)
|
||||
widget->UpdateWindowIcon();
|
||||
}
|
||||
|
||||
void CefWindowView::SetWindowAppIcon(CefRefPtr<CefImage> window_app_icon) {
|
||||
window_app_icon_ = window_app_icon;
|
||||
views::Widget* widget = GetWidget();
|
||||
if (widget)
|
||||
widget->UpdateWindowIcon();
|
||||
}
|
||||
|
||||
void CefWindowView::SetDraggableRegions(
|
||||
const std::vector<CefDraggableRegion>& regions) {
|
||||
if (regions.empty()) {
|
||||
if (draggable_region_)
|
||||
draggable_region_.reset(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
draggable_region_.reset(new SkRegion);
|
||||
for (const CefDraggableRegion& region : regions) {
|
||||
draggable_region_->op(
|
||||
region.bounds.x,
|
||||
region.bounds.y,
|
||||
region.bounds.x + region.bounds.width,
|
||||
region.bounds.y + region.bounds.height,
|
||||
region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op);
|
||||
}
|
||||
}
|
||||
|
||||
views::NonClientFrameView* CefWindowView::GetNonClientFrameView() const {
|
||||
const views::Widget* widget = GetWidget();
|
||||
if (!widget)
|
||||
return nullptr;
|
||||
if (!widget->non_client_view())
|
||||
return nullptr;
|
||||
return widget->non_client_view()->frame_view();
|
||||
}
|
116
libcef/browser/views/window_view.h
Normal file
116
libcef/browser/views/window_view.h
Normal file
@@ -0,0 +1,116 @@
|
||||
// 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_WINDOW_VIEW_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_WINDOW_VIEW_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/views/cef_window.h"
|
||||
#include "include/views/cef_window_delegate.h"
|
||||
|
||||
#include "libcef/browser/views/panel_view.h"
|
||||
|
||||
#include "ui/gfx/display.h"
|
||||
#include "ui/views/widget/widget_delegate.h"
|
||||
|
||||
class SkRegion;
|
||||
|
||||
// Manages the views-based root window. This object will be deleted
|
||||
// automatically when the associated root window is destroyed.
|
||||
class CefWindowView :
|
||||
public CefPanelView<views::WidgetDelegateView, CefWindowDelegate> {
|
||||
public:
|
||||
typedef CefPanelView<views::WidgetDelegateView, CefWindowDelegate>
|
||||
ParentClass;
|
||||
|
||||
class Delegate {
|
||||
public:
|
||||
// Returns true to signal that the Widget can be closed.
|
||||
virtual bool CanWidgetClose() = 0;
|
||||
|
||||
// Called when the WindowView is about to be deleted.
|
||||
virtual void OnWindowViewDeleted() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~Delegate() {}
|
||||
};
|
||||
|
||||
// |cef_delegate| may be nullptr.
|
||||
// |window_delegate| must be non-nullptr.
|
||||
CefWindowView(CefWindowDelegate* cef_delegate,
|
||||
Delegate* window_delegate);
|
||||
|
||||
// Create the Widget.
|
||||
void CreateWidget();
|
||||
|
||||
// Returns the CefWindow associated with this view. See comments on
|
||||
// CefViewView::GetCefView.
|
||||
CefRefPtr<CefWindow> GetCefWindow() const;
|
||||
|
||||
// views::WidgetDelegateView methods:
|
||||
void DeleteDelegate() override;
|
||||
|
||||
// views::WidgetDelegate methods:
|
||||
bool CanResize() const override;
|
||||
bool CanMinimize() const override;
|
||||
bool CanMaximize() const override;
|
||||
base::string16 GetWindowTitle() const override;
|
||||
gfx::ImageSkia GetWindowIcon() override;
|
||||
gfx::ImageSkia GetWindowAppIcon() override;
|
||||
views::View* GetContentsView() override;
|
||||
views::ClientView* CreateClientView(views::Widget* widget) override;
|
||||
views::NonClientFrameView* CreateNonClientFrameView(
|
||||
views::Widget* widget) override;
|
||||
bool ShouldDescendIntoChildForEventHandling(
|
||||
gfx::NativeView child,
|
||||
const gfx::Point& location) override;
|
||||
|
||||
// views::View methods:
|
||||
void ViewHierarchyChanged(
|
||||
const views::View::ViewHierarchyChangedDetails& details) override;
|
||||
|
||||
// Returns the Display containing this Window.
|
||||
gfx::Display GetDisplay() const;
|
||||
|
||||
// Set/get the window title.
|
||||
void SetTitle(const base::string16& title);
|
||||
base::string16 title() const { return title_; }
|
||||
|
||||
// Set/get the window icon. This should be a 16x16 icon suitable for use in
|
||||
// the Windows's title bar.
|
||||
void SetWindowIcon(CefRefPtr<CefImage> window_icon);
|
||||
CefRefPtr<CefImage> window_icon() const { return window_icon_; }
|
||||
|
||||
// Set/get the window app icon. This should be a larger icon for use in the
|
||||
// host environment app switching UI. On Windows, this is the ICON_BIG used in
|
||||
// Alt-Tab list and Windows taskbar. The Window icon will be used by default
|
||||
// if no Window App icon is specified.
|
||||
void SetWindowAppIcon(CefRefPtr<CefImage> window_app_icon);
|
||||
CefRefPtr<CefImage> window_app_icon() const { return window_app_icon_; }
|
||||
|
||||
// Set/get the draggable regions.
|
||||
void SetDraggableRegions(
|
||||
const std::vector<CefDraggableRegion>& regions);
|
||||
SkRegion* draggable_region() const { return draggable_region_.get(); }
|
||||
|
||||
// Returns the NonClientFrameView for this Window. May be nullptr.
|
||||
views::NonClientFrameView* GetNonClientFrameView() const;
|
||||
|
||||
private:
|
||||
// Not owned by this object.
|
||||
Delegate* window_delegate_;
|
||||
|
||||
// True if the window is frameless. It might still be resizable and draggable.
|
||||
bool is_frameless_;
|
||||
|
||||
base::string16 title_;
|
||||
CefRefPtr<CefImage> window_icon_;
|
||||
CefRefPtr<CefImage> window_app_icon_;
|
||||
|
||||
scoped_ptr<SkRegion> draggable_region_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefWindowView);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_WINDOW_VIEW_H_
|
Reference in New Issue
Block a user