1 // Copyright 2016 The Chromium Embedded Framework Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be found
3 // in the LICENSE file.
4
5 #ifndef CEF_LIBCEF_BROWSER_VIEWS_VIEW_IMPL_H_
6 #define CEF_LIBCEF_BROWSER_VIEWS_VIEW_IMPL_H_
7 #pragma once
8
9 // CEF exposes views framework functionality via a hierarchy of CefView and
10 // related objects. While the goal is to accurately represent views framework
11 // capabilities there is not always a direct 1:1 mapping between the CEF
12 // implementation and the underlying views implementation. Certain liberties
13 // have been taken with the CEF API design to clarify the user experience.
14 //
15 // CEF implementation overview:
16 //
17 // CefView-derived classes (CefPanel, CefLabelButton, etc.) are implemented
18 // using a specialization of the CefViewImpl template. On Initialize() the
19 // CefViewImpl object creates an underlying views::View object via the
20 // CreateRootView() method. The views::View objects are implemented using a
21 // specialization of the CefViewView template. CefViewView extends the
22 // views::View-derived class and executes CefViewDelegate-derived callbacks by
23 // overriding views::View methods.
24 //
25 // Example 1: The CefBasicPanelImpl object created via CefPanel::CreatePanel()
26 // has the following object hierarchy:
27 //
28 // CefView => CefPanel =>
29 // CefViewImpl<views::View, CefPanel, CefPanelDelegate> =>
30 // CefPanelImpl<views::View, CefPanel, CefPanelDelegate> =>
31 // CefBasicPanelImpl.
32 //
33 // And the CefBasicPanelView object created via
34 // CefBasicPanelImpl::CreateRootView() has the following object hierarchy:
35 //
36 // views::View =>
37 // CefViewView<views::View, CefPanelDelegate> =>
38 // CefPanelView<views::View, CefPanelDelegate> =>
39 // CefBasicPanelView.
40 //
41 // Example 2: In some cases an intermediary type is required to meet CEF
42 // template requirements (e.g. CefViewView requires a no-argument constructor).
43 // The CefBasicLabelButtonImpl object created via
44 // CefLabelButton::CreateLabelButton() has the following object hierarchy:
45 //
46 // CefView => CefButton => CefLabelButton =>
47 // CefViewImpl<views::LabelButton, CefLabelButton, CefButtonDelegate> =>
48 // CefButtonImpl<views::LabelButton, CefLabelButton, CefButtonDelegate> =>
49 // CefLabelButtonImpl<views::LabelButton, CefLabelButton,
50 // CefButtonDelegate> =>
51 // CefBasicLabelButtonImpl
52 //
53 // And the CefBasicLabelButtonView object created via
54 // CefBasicLabelButtonImpl::CreateRootView() has the following object hierarchy:
55 //
56 // views::View => views::Button => views::LabelButton =>
57 // LabelButtonEx (used to implement the required no-argument constructor) =>
58 // CefViewView<LabelButtonEx, CefButtonDelegate> =>
59 // CefButtonView<LabelButtonEx, CefButtonDelegate> =>
60 // CefLabelButtonView<LabelButtonEx, CefButtonDelegate> =>
61 // CefBasicLabelButtonView.
62 //
63 //
64 // General design considerations:
65 //
66 // CefView classes are ref-counted whereas views::View classes are not. There
67 // is generally a 1:1 relationship between CefView and views::View objects.
68 // However, there may be intermediary views::View objects that are not exposed
69 // by the CEF layer. For example:
70 // - views::Widget creates views::RootView and views::ContentView child objects;
71 // - views::ScrollView creates views::ScrollView::Viewport child objects.
72 //
73 // The views::View class exposes methods that are not applicable for a subset of
74 // views implementations. For example:
75 // - Calling AddChildView() on a views::LabelButton is unexpected;
76 // - Adding a child to a views::ScrollView requires calling the SetContents()
77 // method instead of AddChildView().
78 // To avoid user confusion CEF introduces a CefPanel type that extends CefView
79 // and exposes common child management functionality. Types that allow
80 // arbitrary children extend CefPanel instead of CefView.
81 //
82 //
83 // Object ownership considerations:
84 //
85 // On initial creation the CefViewImpl object owns an underlying views::View
86 // object (created by overriding the CreateRootView() method) and the
87 // views::View object holds a non-ref-counted reference to the CefViewImpl
88 // object. If a CefViewImpl is destroyed (all refs released) then the underlying
89 // views::View object is deleted.
90 //
91 // When a views::View object is parented to another views::View (via
92 // CefPanel::AddChildView or similar) the ownership semantics change. The
93 // CefViewImpl swaps its owned reference for an unowned reference and the
94 // views::View gains a ref-counted reference to the CefViewImpl
95 // (CefView::IsAttached() now returns true).
96 //
97 // When a parent views::View is deleted all child views::Views in the view
98 // hierarchy are also deleted (see [1] for exceptions). When this happens the
99 // ref-counted CefViewImpl reference held by the views::View is released. The
100 // CefViewImpl is deleted if the client kept no references, otherwise the
101 // CefViewImpl is marked as invalid (CefView::IsValid() now returns false).
102 //
103 // When a views::View is removed from the view hierarchy (via
104 // CefPanel::RemoveChildView or similar) the initial ownership state is
105 // restored. The CefViewImpl regains ownership of the views::View and the
106 // ref-counted CefViewImpl reference held by the views::View is released.
107 //
108 // The relationship between CefViewImpl and views::View objects is managed using
109 // the view_util:: functions. Type conversion is facilitated using the As*()
110 // methods exposed by CefView-derived classes and the CefViewAdapter interface
111 // implemented by CefViewImpl. See view_util.[cc|h] for implementation details.
112 //
113 // Some other object types are also tied to views::View lifetime. For example,
114 // CefLayout and the underling views::LayoutManager objects are owned by the
115 // views::View that they're assigned to. This relationship is managed using the
116 // layout_util:: functions in layout_util.[cc|h].
117 //
118 // [1] By default views::View objects are deleted when the parent views::View
119 // object is deleted. However, this behavior can be changed either
120 // explicitly by calling set_owned_by_client() or implicitly by using
121 // interfaces like WidgetDelegateView (where WidgetDelegate is-a View, and
122 // the View is deleted when the native Widget is destroyed). CEF
123 // implementations that utilize this behavior must take special care with
124 // object ownership management.
125 //
126 //
127 // To implement a new CefView-derived class:
128 //
129 // 1. Choose a views class to expose.
130 // * We'll create a new CefFooBar class which exposes a hypothetical
131 // views::FooBar class. The views::FooBar class might look like this:
132 //
133 // File ui/views/foo_bar.h:
134 //
135 // namespace views {
136 //
137 // // FooBar view does a task on child views.
138 // class FooBar : public View {
139 // public:
140 // FooBar();
141 //
142 // // Do a task.
143 // void DoTask();
144 // // Called when the task is done.
145 // virtual void OnTaskDone();
146 //
147 // // View methods:
148 // void Layout() override; // Implements custom layout of child views.
149 // };
150 //
151 // } // namespace views
152 //
153 // 2. Determine the existing CefView-derived class that the new view class
154 // should extend.
155 // * Since in this example CefFooBar can have arbitrary child views we'll
156 // have it extend CefPanel.
157 //
158 // 3. Determine whether the new view class can use an existing delegate class
159 // (like CefPanelDelegate) or whether it needs its own delegate class.
160 // * Since CefFooBar has an OnTaskDone() callback we'll add a new
161 // CefFooBarDelegate class to expose it.
162 //
163 // 4. Create new header files in the cef/include/views/ directory.
164 // * Using existing files as a model, the resulting header contents might
165 // look like this:
166 //
167 // File cef/include/views/cef_foo_bar.h:
168 //
169 // ///
170 // // A FooBar view does a task on child views.
171 // ///
172 // /*--cef(source=library)--*/
173 // class CefFooBar : public CefPanel {
174 // public:
175 // ///
176 // // Create a new FooBar.
177 // ///
178 // /*--cef(optional_param=delegate)--*/
179 // static CefRefPtr<CefFooBar> CreateFooBar(
180 // CefRefPtr<CefFooBarDelegate> delegate);
181 //
182 // ///
183 // // Do a task.
184 // ///
185 // /*--cef()--*/
186 // virtual void DoTask() =0;
187 // };
188 //
189 // File cef/include/views/cef_foo_bar_delegate.h:
190 //
191 // ///
192 // // Implement this interface to handle FooBar events.
193 // ///
194 // /*--cef(source=client)--*/
195 // class CefFooBarDelegate : public CefPanelDelegate {
196 // public:
197 // ///
198 // // Called when the task is done.
199 // ///
200 // /*--cef()--*/
201 // virtual void OnTaskDone(CefRefPtr<CefFooBar> foobar) {}
202 // };
203 //
204 // 5. Add an As*() method to the CefView-derived class.
205 // * Using existing file contents as a model, make the following changes in
206 // cef/include/views/cef_panel.h:
207 // * Forward declare the CefFooBar class.
208 // * Add a new CefPanel::AsFooBar() method:
209 //
210 // ///
211 // // Returns this Panel as a FooBar or NULL if this is not a FooBar.
212 // ///
213 // /*--cef()--*/
214 // virtual CefRefPtr<CefFooBar> AsFooBar() =0;
215 //
216 // 6. Add a default implementation for the As*() method to the CefViewImpl-
217 // derived class.
218 // * Using existing file contents as a model, make the following changes in
219 // cef/libcef/browser/views/panel_impl.h:
220 // * Include "include/views/cef_foo_bar.h".
221 // * Add a default CefPanelImpl::AsFooBar() implementation:
222 //
223 // CefRefPtr<CefFooBar> AsFooBar() override { return nullptr; }
224 //
225 // 7. Update the CefViewAdapter::GetFor() method implementation to call the
226 // As*() method.
227 // * Using existing file contents as a model, make the following changes in
228 // cef/libcef/browser/views/view_adapter.cc:
229 // * Include "include/views/cef_foo_bar.h".
230 // * Call the AsFooBar() method to identify the adapter object:
231 //
232 // ... if (view->AsPanel()) {
233 // CefRefPtr<CefPanel> panel = view->AsPanel();
234 // if (panel->AsFooBar()) {
235 // adapter = static_cast<CefFooBarImpl*>(panel->AsFooBar().get());
236 // } else ...
237 // } else ...
238 //
239 // 8. Implement the CefViewView-derived class.
240 // * Using existing files as a model (for example, CefBasicPanelView), create
241 // a CefFooBarView class at cef/libcef/browser/views/foo_bar_view.[cc|h].
242 // This class:
243 // * Extends CefPanelView<views::FooBar, CefFooBarDelegate>.
244 // * Overrides the views::FooBar::OnTaskDone method to execute the
245 // CefFooBarDelegate::OnTaskDone callback:
246 //
247 // void CefFooBarView::OnTaskDone() {
248 // if (cef_delegate())
249 // cef_delegate()->OnTaskDone(GetCefFooBar());
250 // }
251 //
252 // 9. Implement the CefViewImpl-derived class.
253 // * Use existing files as a model (for example, CefBasicPanelImpl), create a
254 // CefFooBarImpl class at cef/libcef/browser/views/foo_bar_impl.[cc|h].
255 // This class:
256 // * Extends CefPanelImpl<views::FooBar, CefFooBar, CefFooBarDelegate>.
257 // * Implements AsFooBar() to return |this|.
258 // * Implements CreateRootView() to return a new CefFooBarView instance.
259 // * Implements the CefFooBar::DoTask() method to call
260 // views::FooBar::DoTask():
261 //
262 // void CefFooBarImpl::DoTask() {
263 // CEF_REQUIRE_VALID_RETURN_VOID();
264 // root_view()->DoTask();
265 // }
266 //
267 // 10. Implement the static method that creates the CefViewImpl-derived object
268 // instance.
269 // * Use existing files as a model (for example, CefBasicPanelImpl),
270 // implement the CefFooBar::CreateFooBar static method in
271 // cef/libcef/browser/views/foo_bar_impl.cc. This method:
272 // * Creates a new CefFooBarImpl object.
273 // * Calls Initialize() on the CefFooBarImpl object.
274 // * Returns the CefFooBarImpl object.
275 //
276 // 11. Add the new source files from #7 and #8 to the 'libcef_static' target in
277 // cef.gyp.
278 //
279 // 12. Update the CEF project files and build.
280 // * Run cef/tools/translator.[bat|sh] to update the translation layer for
281 // the new/modified classes. This tool needs to be run whenever header
282 // files in the cef/include/ directory are changed.
283 // * Run cef/cef_create_projects.[bat|sh] to update the Ninja build files.
284 // * Build CEF using Ninja.
285 //
286
287 #include "include/views/cef_browser_view.h"
288 #include "include/views/cef_button.h"
289 #include "include/views/cef_panel.h"
290 #include "include/views/cef_scroll_view.h"
291 #include "include/views/cef_textfield.h"
292 #include "include/views/cef_view.h"
293
294 #include "libcef/browser/thread_util.h"
295 #include "libcef/browser/views/view_adapter.h"
296 #include "libcef/browser/views/view_util.h"
297
298 #include "base/json/json_writer.h"
299 #include "base/logging.h"
300 #include "base/values.h"
301 #include "ui/views/background.h"
302 #include "ui/views/border.h"
303 #include "ui/views/view.h"
304
305 // Helpers for template boiler-plate.
306 #define CEF_VIEW_IMPL_T \
307 template <class ViewsViewClass, class CefViewClass, \
308 class CefViewDelegateClass>
309 #define CEF_VIEW_IMPL_A ViewsViewClass, CefViewClass, CefViewDelegateClass
310 #define CEF_VIEW_IMPL_D CefViewImpl<CEF_VIEW_IMPL_A>
311
312 // Base template for implementing CefView-derived classes. See above comments
313 // for a usage overview.
314 CEF_VIEW_IMPL_T class CefViewImpl : public CefViewAdapter, public CefViewClass {
315 public:
316 // Necessary for the CEF_REQUIRE_VALID_*() macros to compile.
317 using ParentClass = CEF_VIEW_IMPL_D;
318
319 // Returns the content views::View object that should be the target of most
320 // customization actions. May be the root view or a child of the root view.
content_view()321 virtual views::View* content_view() const { return root_view(); }
322
323 // Returns the CEF delegate as the derived type which may be nullptr.
delegate()324 CefViewDelegateClass* delegate() const { return delegate_.get(); }
325
326 // Returns the root views::View object owned by this CefView.
root_view()327 ViewsViewClass* root_view() const { return root_view_ref_; }
328
329 // CefViewAdapter methods:
Get()330 views::View* Get() const override { return root_view(); }
PassOwnership()331 std::unique_ptr<views::View> PassOwnership() override {
332 DCHECK(root_view_);
333 return std::move(root_view_);
334 }
ResumeOwnership()335 void ResumeOwnership() override {
336 DCHECK(root_view_ref_);
337 DCHECK(!root_view_);
338 root_view_.reset(root_view_ref_);
339 }
Detach()340 void Detach() override {
341 if (root_view_)
342 root_view_.reset();
343 root_view_ref_ = nullptr;
344 }
GetDebugInfo(base::DictionaryValue * info,bool include_children)345 void GetDebugInfo(base::DictionaryValue* info,
346 bool include_children) override {
347 info->SetString("type", GetDebugType());
348 info->SetInteger("id", root_view()->GetID());
349
350 // Use GetBounds() because some subclasses (like CefWindowImpl) override it.
351 const CefRect& bounds = GetBounds();
352 std::unique_ptr<base::DictionaryValue> bounds_value(
353 new base::DictionaryValue());
354 bounds_value->SetInteger("x", bounds.x);
355 bounds_value->SetInteger("y", bounds.y);
356 bounds_value->SetInteger("width", bounds.width);
357 bounds_value->SetInteger("height", bounds.height);
358 info->Set("bounds", std::move(bounds_value));
359 }
360
361 // CefView methods. When adding new As*() methods make sure to update
362 // CefViewAdapter::GetFor() in view_adapter.cc.
AsBrowserView()363 CefRefPtr<CefBrowserView> AsBrowserView() override { return nullptr; }
AsButton()364 CefRefPtr<CefButton> AsButton() override { return nullptr; }
AsPanel()365 CefRefPtr<CefPanel> AsPanel() override { return nullptr; }
AsScrollView()366 CefRefPtr<CefScrollView> AsScrollView() override { return nullptr; }
AsTextfield()367 CefRefPtr<CefTextfield> AsTextfield() override { return nullptr; }
368 CefString GetTypeString() override;
369 CefString ToString(bool include_children) override;
370 bool IsValid() override;
371 bool IsAttached() override;
372 bool IsSame(CefRefPtr<CefView> that) override;
373 CefRefPtr<CefViewDelegate> GetDelegate() override;
374 CefRefPtr<CefWindow> GetWindow() override;
375 int GetID() override;
376 void SetID(int id) override;
377 int GetGroupID() override;
378 void SetGroupID(int group_id) override;
379 CefRefPtr<CefView> GetParentView() override;
380 CefRefPtr<CefView> GetViewForID(int id) override;
381 void SetBounds(const CefRect& bounds) override;
382 CefRect GetBounds() override;
383 CefRect GetBoundsInScreen() override;
384 void SetSize(const CefSize& size) override;
385 CefSize GetSize() override;
386 void SetPosition(const CefPoint& position) override;
387 CefPoint GetPosition() override;
388 void SetInsets(const CefInsets& insets) override;
389 CefInsets GetInsets() override;
390 CefSize GetPreferredSize() override;
391 void SizeToPreferredSize() override;
392 CefSize GetMinimumSize() override;
393 CefSize GetMaximumSize() override;
394 int GetHeightForWidth(int width) override;
395 void InvalidateLayout() override;
396 void SetVisible(bool visible) override;
397 bool IsVisible() override;
398 bool IsDrawn() override;
399 void SetEnabled(bool enabled) override;
400 bool IsEnabled() override;
401 void SetFocusable(bool focusable) override;
402 bool IsFocusable() override;
403 bool IsAccessibilityFocusable() override;
404 void RequestFocus() override;
405 void SetBackgroundColor(cef_color_t color) override;
406 cef_color_t GetBackgroundColor() override;
407 bool ConvertPointToScreen(CefPoint& point) override;
408 bool ConvertPointFromScreen(CefPoint& point) override;
409 bool ConvertPointToWindow(CefPoint& point) override;
410 bool ConvertPointFromWindow(CefPoint& point) override;
411 bool ConvertPointToView(CefRefPtr<CefView> view, CefPoint& point) override;
412 bool ConvertPointFromView(CefRefPtr<CefView> view, CefPoint& point) override;
413
414 protected:
415 // Create a new implementation object.
416 // Always call Initialize() after creation.
417 // |delegate| may be nullptr.
CefViewImpl(CefRefPtr<CefViewDelegateClass> delegate)418 explicit CefViewImpl(CefRefPtr<CefViewDelegateClass> delegate)
419 : delegate_(delegate), root_view_ref_(nullptr) {}
420
421 // Initialize this object.
Initialize()422 virtual void Initialize() {
423 root_view_.reset(CreateRootView());
424 DCHECK(root_view_.get());
425 root_view_ref_ = root_view_.get();
426 view_util::Register(this);
427 InitializeRootView();
428 }
429
430 // Create the root views::View object.
431 virtual ViewsViewClass* CreateRootView() = 0;
432
433 // Perform required initialization of the root_view() object created by
434 // CreateRootView(). Called after this object has been registered.
435 virtual void InitializeRootView() = 0;
436
437 private:
438 CefRefPtr<CefViewDelegateClass> delegate_;
439
440 // Owned reference to the views::View wrapped by this object. Will be nullptr
441 // before the View is created and after the View's ownership is transferred.
442 std::unique_ptr<ViewsViewClass> root_view_;
443
444 // Unowned reference to the views::View wrapped by this object. Will be
445 // nullptr before the View is created and after the View is destroyed.
446 ViewsViewClass* root_view_ref_;
447 };
448
GetTypeString()449 CEF_VIEW_IMPL_T CefString CEF_VIEW_IMPL_D::GetTypeString() {
450 CEF_REQUIRE_UIT_RETURN(CefString());
451 return GetDebugType();
452 }
453
ToString(bool include_children)454 CEF_VIEW_IMPL_T CefString CEF_VIEW_IMPL_D::ToString(bool include_children) {
455 CEF_REQUIRE_UIT_RETURN(CefString());
456 std::unique_ptr<base::DictionaryValue> info(new base::DictionaryValue());
457 if (IsValid())
458 GetDebugInfo(info.get(), include_children);
459 else
460 info->SetString("type", GetDebugType());
461
462 std::string json_string;
463 base::JSONWriter::WriteWithOptions(*info, 0, &json_string);
464 return json_string;
465 }
466
IsValid()467 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsValid() {
468 CEF_REQUIRE_UIT_RETURN(false);
469 return !!root_view_ref_;
470 }
471
IsAttached()472 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsAttached() {
473 CEF_REQUIRE_UIT_RETURN(false);
474 return !root_view_.get();
475 }
476
IsSame(CefRefPtr<CefView> that)477 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsSame(CefRefPtr<CefView> that) {
478 CEF_REQUIRE_UIT_RETURN(false);
479 CefViewImpl* that_impl = static_cast<CefViewImpl*>(that.get());
480 if (!that_impl)
481 return false;
482 return this == that_impl;
483 }
484
GetDelegate()485 CEF_VIEW_IMPL_T CefRefPtr<CefViewDelegate> CEF_VIEW_IMPL_D::GetDelegate() {
486 CEF_REQUIRE_UIT_RETURN(nullptr);
487 return delegate();
488 }
489
GetWindow()490 CEF_VIEW_IMPL_T CefRefPtr<CefWindow> CEF_VIEW_IMPL_D::GetWindow() {
491 CEF_REQUIRE_UIT_RETURN(nullptr);
492 if (root_view())
493 return view_util::GetWindowFor(root_view()->GetWidget());
494 return nullptr;
495 }
496
GetID()497 CEF_VIEW_IMPL_T int CEF_VIEW_IMPL_D::GetID() {
498 CEF_REQUIRE_VALID_RETURN(0);
499 return root_view()->GetID();
500 }
501
SetID(int id)502 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetID(int id) {
503 CEF_REQUIRE_VALID_RETURN_VOID();
504 root_view()->SetID(id);
505 }
506
GetGroupID()507 CEF_VIEW_IMPL_T int CEF_VIEW_IMPL_D::GetGroupID() {
508 CEF_REQUIRE_VALID_RETURN(0);
509 return root_view()->GetGroup();
510 }
511
SetGroupID(int group_id)512 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetGroupID(int group_id) {
513 CEF_REQUIRE_VALID_RETURN_VOID();
514 if (root_view()->GetGroup() != -1)
515 return;
516 root_view()->SetGroup(group_id);
517 }
518
GetParentView()519 CEF_VIEW_IMPL_T CefRefPtr<CefView> CEF_VIEW_IMPL_D::GetParentView() {
520 CEF_REQUIRE_VALID_RETURN(nullptr);
521 views::View* view = root_view()->parent();
522 if (!view)
523 return nullptr;
524 return view_util::GetFor(view, true);
525 }
526
GetViewForID(int id)527 CEF_VIEW_IMPL_T CefRefPtr<CefView> CEF_VIEW_IMPL_D::GetViewForID(int id) {
528 CEF_REQUIRE_VALID_RETURN(nullptr);
529 views::View* view = root_view()->GetViewByID(id);
530 if (!view)
531 return nullptr;
532 return view_util::GetFor(view, true);
533 }
534
SetBounds(const CefRect & bounds)535 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetBounds(const CefRect& bounds) {
536 CEF_REQUIRE_VALID_RETURN_VOID();
537 root_view()->SetBoundsRect(
538 gfx::Rect(bounds.x, bounds.y, bounds.width, bounds.height));
539 }
540
GetBounds()541 CEF_VIEW_IMPL_T CefRect CEF_VIEW_IMPL_D::GetBounds() {
542 CEF_REQUIRE_VALID_RETURN(CefRect());
543 const gfx::Rect& bounds = root_view()->bounds();
544 return CefRect(bounds.x(), bounds.y(), bounds.width(), bounds.height());
545 }
546
GetBoundsInScreen()547 CEF_VIEW_IMPL_T CefRect CEF_VIEW_IMPL_D::GetBoundsInScreen() {
548 CEF_REQUIRE_VALID_RETURN(CefRect());
549 const gfx::Rect& bounds = root_view()->GetBoundsInScreen();
550 return CefRect(bounds.x(), bounds.y(), bounds.width(), bounds.height());
551 }
552
SetSize(const CefSize & size)553 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetSize(const CefSize& size) {
554 CEF_REQUIRE_VALID_RETURN_VOID();
555 root_view()->SetSize(gfx::Size(size.width, size.height));
556 }
557
GetSize()558 CEF_VIEW_IMPL_T CefSize CEF_VIEW_IMPL_D::GetSize() {
559 CEF_REQUIRE_VALID_RETURN(CefSize());
560 // Call GetBounds() since child classes may override it.
561 const CefRect& bounds = GetBounds();
562 return CefSize(bounds.width, bounds.height);
563 }
564
SetPosition(const CefPoint & position)565 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetPosition(const CefPoint& position) {
566 CEF_REQUIRE_VALID_RETURN_VOID();
567 root_view()->SetPosition(gfx::Point(position.x, position.y));
568 }
569
GetPosition()570 CEF_VIEW_IMPL_T CefPoint CEF_VIEW_IMPL_D::GetPosition() {
571 CEF_REQUIRE_VALID_RETURN(CefPoint());
572 // Call GetBounds() since child classes may override it.
573 const CefRect& bounds = GetBounds();
574 return CefPoint(bounds.x, bounds.y);
575 }
576
SetInsets(const CefInsets & insets)577 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetInsets(const CefInsets& insets) {
578 CEF_REQUIRE_VALID_RETURN_VOID();
579 gfx::Insets gfx_insets(insets.top, insets.left, insets.bottom, insets.right);
580 root_view()->SetBorder(
581 gfx_insets.IsEmpty() ? nullptr : views::CreateEmptyBorder(gfx_insets));
582 }
583
GetInsets()584 CEF_VIEW_IMPL_T CefInsets CEF_VIEW_IMPL_D::GetInsets() {
585 CEF_REQUIRE_VALID_RETURN(CefInsets());
586 const auto insets = root_view()->GetInsets();
587 return CefInsets(insets.top(), insets.left(), insets.bottom(),
588 insets.right());
589 }
590
GetPreferredSize()591 CEF_VIEW_IMPL_T CefSize CEF_VIEW_IMPL_D::GetPreferredSize() {
592 CEF_REQUIRE_VALID_RETURN(CefSize());
593 const gfx::Size& size = root_view()->GetPreferredSize();
594 return CefSize(size.width(), size.height());
595 }
596
SizeToPreferredSize()597 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SizeToPreferredSize() {
598 CEF_REQUIRE_VALID_RETURN_VOID();
599 root_view()->SizeToPreferredSize();
600 }
601
GetMinimumSize()602 CEF_VIEW_IMPL_T CefSize CEF_VIEW_IMPL_D::GetMinimumSize() {
603 CEF_REQUIRE_VALID_RETURN(CefSize());
604 const gfx::Size& size = root_view()->GetMinimumSize();
605 return CefSize(size.width(), size.height());
606 }
607
GetMaximumSize()608 CEF_VIEW_IMPL_T CefSize CEF_VIEW_IMPL_D::GetMaximumSize() {
609 CEF_REQUIRE_VALID_RETURN(CefSize());
610 const gfx::Size& size = root_view()->GetMaximumSize();
611 return CefSize(size.width(), size.height());
612 }
613
GetHeightForWidth(int width)614 CEF_VIEW_IMPL_T int CEF_VIEW_IMPL_D::GetHeightForWidth(int width) {
615 CEF_REQUIRE_VALID_RETURN(0);
616 return root_view()->GetHeightForWidth(width);
617 }
618
InvalidateLayout()619 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::InvalidateLayout() {
620 CEF_REQUIRE_VALID_RETURN_VOID();
621 root_view()->InvalidateLayout();
622 }
623
SetVisible(bool visible)624 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetVisible(bool visible) {
625 CEF_REQUIRE_VALID_RETURN_VOID();
626 root_view()->SetVisible(visible);
627 }
628
IsVisible()629 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsVisible() {
630 CEF_REQUIRE_VALID_RETURN(false);
631 return root_view()->GetVisible();
632 }
633
IsDrawn()634 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsDrawn() {
635 CEF_REQUIRE_VALID_RETURN(false);
636 return root_view()->IsDrawn();
637 }
638
SetEnabled(bool enabled)639 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetEnabled(bool enabled) {
640 CEF_REQUIRE_VALID_RETURN_VOID();
641 root_view()->SetEnabled(enabled);
642 }
643
IsEnabled()644 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsEnabled() {
645 CEF_REQUIRE_VALID_RETURN(false);
646 return root_view()->GetEnabled();
647 }
648
SetFocusable(bool focusable)649 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetFocusable(bool focusable) {
650 CEF_REQUIRE_VALID_RETURN_VOID();
651 root_view()->SetFocusBehavior(focusable ? views::View::FocusBehavior::ALWAYS
652 : views::View::FocusBehavior::NEVER);
653 }
654
IsFocusable()655 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsFocusable() {
656 CEF_REQUIRE_VALID_RETURN(false);
657 return root_view()->IsFocusable();
658 }
659
IsAccessibilityFocusable()660 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsAccessibilityFocusable() {
661 CEF_REQUIRE_VALID_RETURN(false);
662 return root_view()->IsAccessibilityFocusable();
663 }
664
RequestFocus()665 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::RequestFocus() {
666 CEF_REQUIRE_VALID_RETURN_VOID();
667 root_view()->RequestFocus();
668 }
669
SetBackgroundColor(cef_color_t color)670 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetBackgroundColor(cef_color_t color) {
671 CEF_REQUIRE_VALID_RETURN_VOID();
672 content_view()->SetBackground(views::CreateSolidBackground(color));
673 }
674
GetBackgroundColor()675 CEF_VIEW_IMPL_T cef_color_t CEF_VIEW_IMPL_D::GetBackgroundColor() {
676 CEF_REQUIRE_VALID_RETURN(0U);
677 return content_view()->background()->get_color();
678 }
679
ConvertPointToScreen(CefPoint & point)680 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::ConvertPointToScreen(CefPoint& point) {
681 CEF_REQUIRE_VALID_RETURN(false);
682 gfx::Point gfx_point = gfx::Point(point.x, point.y);
683 if (!view_util::ConvertPointToScreen(root_view(), &gfx_point, false))
684 return false;
685 point = CefPoint(gfx_point.x(), gfx_point.y());
686 return true;
687 }
688
ConvertPointFromScreen(CefPoint & point)689 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::ConvertPointFromScreen(CefPoint& point) {
690 CEF_REQUIRE_VALID_RETURN(false);
691 gfx::Point gfx_point = gfx::Point(point.x, point.y);
692 if (!view_util::ConvertPointFromScreen(root_view(), &gfx_point, false))
693 return false;
694 point = CefPoint(gfx_point.x(), gfx_point.y());
695 return true;
696 }
697
ConvertPointToWindow(CefPoint & point)698 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::ConvertPointToWindow(CefPoint& point) {
699 CEF_REQUIRE_VALID_RETURN(false);
700 gfx::Point gfx_point = gfx::Point(point.x, point.y);
701 if (!view_util::ConvertPointToWindow(root_view(), &gfx_point))
702 return false;
703 point = CefPoint(gfx_point.x(), gfx_point.y());
704 return true;
705 }
706
ConvertPointFromWindow(CefPoint & point)707 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::ConvertPointFromWindow(CefPoint& point) {
708 CEF_REQUIRE_VALID_RETURN(false);
709 gfx::Point gfx_point = gfx::Point(point.x, point.y);
710 if (!view_util::ConvertPointFromWindow(root_view(), &gfx_point))
711 return false;
712 point = CefPoint(gfx_point.x(), gfx_point.y());
713 return true;
714 }
715
ConvertPointToView(CefRefPtr<CefView> view,CefPoint & point)716 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::ConvertPointToView(
717 CefRefPtr<CefView> view,
718 CefPoint& point) {
719 CEF_REQUIRE_VALID_RETURN(false);
720 if (!root_view()->GetWidget())
721 return false;
722 views::View* target_view = view_util::GetFor(view);
723 if (!target_view || target_view->GetWidget() != root_view()->GetWidget())
724 return false;
725 gfx::Point gfx_point = gfx::Point(point.x, point.y);
726 views::View::ConvertPointToTarget(root_view(), target_view, &gfx_point);
727 point = CefPoint(gfx_point.x(), gfx_point.y());
728 return true;
729 }
730
ConvertPointFromView(CefRefPtr<CefView> view,CefPoint & point)731 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::ConvertPointFromView(
732 CefRefPtr<CefView> view,
733 CefPoint& point) {
734 CEF_REQUIRE_VALID_RETURN(false);
735 if (!root_view()->GetWidget())
736 return false;
737 views::View* target_view = view_util::GetFor(view);
738 if (!target_view || target_view->GetWidget() != root_view()->GetWidget())
739 return false;
740 gfx::Point gfx_point = gfx::Point(point.x, point.y);
741 views::View::ConvertPointToTarget(target_view, root_view(), &gfx_point);
742 point = CefPoint(gfx_point.x(), gfx_point.y());
743 return true;
744 }
745
746 #endif // CEF_LIBCEF_BROWSER_VIEWS_VIEW_IMPL_H_
747