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/view.h"
303
304 // Helpers for template boiler-plate.
305 #define CEF_VIEW_IMPL_T \
306 template <class ViewsViewClass, class CefViewClass, \
307 class CefViewDelegateClass>
308 #define CEF_VIEW_IMPL_A ViewsViewClass, CefViewClass, CefViewDelegateClass
309 #define CEF_VIEW_IMPL_D CefViewImpl<CEF_VIEW_IMPL_A>
310
311 // Base template for implementing CefView-derived classes. See above comments
312 // for a usage overview.
313 CEF_VIEW_IMPL_T class CefViewImpl : public CefViewAdapter, public CefViewClass {
314 public:
315 // Necessary for the CEF_REQUIRE_VALID_*() macros to compile.
316 typedef CEF_VIEW_IMPL_D ParentClass;
317
318 // Returns the content views::View object that should be the target of most
319 // customization actions. May be the root view or a child of the root view.
content_view()320 virtual views::View* content_view() const { return root_view(); }
321
322 // Returns the CEF delegate as the derived type which may be nullptr.
delegate()323 CefViewDelegateClass* delegate() const { return delegate_.get(); }
324
325 // Returns the root views::View object owned by this CefView.
root_view()326 ViewsViewClass* root_view() const { return root_view_ref_; }
327
328 // CefViewAdapter methods:
Get()329 views::View* Get() const override { return root_view(); }
PassOwnership()330 std::unique_ptr<views::View> PassOwnership() override {
331 DCHECK(root_view_);
332 return std::move(root_view_);
333 }
ResumeOwnership()334 void ResumeOwnership() override {
335 DCHECK(root_view_ref_);
336 DCHECK(!root_view_);
337 root_view_.reset(root_view_ref_);
338 }
Detach()339 void Detach() override {
340 if (root_view_)
341 root_view_.reset();
342 root_view_ref_ = nullptr;
343 }
GetDebugInfo(base::DictionaryValue * info,bool include_children)344 void GetDebugInfo(base::DictionaryValue* info,
345 bool include_children) override {
346 info->SetString("type", GetDebugType());
347 info->SetInteger("id", root_view()->GetID());
348
349 // Use GetBounds() because some subclasses (like CefWindowImpl) override it.
350 const CefRect& bounds = GetBounds();
351 std::unique_ptr<base::DictionaryValue> bounds_value(
352 new base::DictionaryValue());
353 bounds_value->SetInteger("x", bounds.x);
354 bounds_value->SetInteger("y", bounds.y);
355 bounds_value->SetInteger("width", bounds.width);
356 bounds_value->SetInteger("height", bounds.height);
357 info->Set("bounds", std::move(bounds_value));
358 }
359
360 // CefView methods. When adding new As*() methods make sure to update
361 // CefViewAdapter::GetFor() in view_adapter.cc.
AsBrowserView()362 CefRefPtr<CefBrowserView> AsBrowserView() override { return nullptr; }
AsButton()363 CefRefPtr<CefButton> AsButton() override { return nullptr; }
AsPanel()364 CefRefPtr<CefPanel> AsPanel() override { return nullptr; }
AsScrollView()365 CefRefPtr<CefScrollView> AsScrollView() override { return nullptr; }
AsTextfield()366 CefRefPtr<CefTextfield> AsTextfield() override { return nullptr; }
367 CefString GetTypeString() override;
368 CefString ToString(bool include_children) override;
369 bool IsValid() override;
370 bool IsAttached() override;
371 bool IsSame(CefRefPtr<CefView> that) override;
372 CefRefPtr<CefViewDelegate> GetDelegate() override;
373 CefRefPtr<CefWindow> GetWindow() override;
374 int GetID() override;
375 void SetID(int id) override;
376 int GetGroupID() override;
377 void SetGroupID(int group_id) override;
378 CefRefPtr<CefView> GetParentView() override;
379 CefRefPtr<CefView> GetViewForID(int id) override;
380 void SetBounds(const CefRect& bounds) override;
381 CefRect GetBounds() override;
382 CefRect GetBoundsInScreen() override;
383 void SetSize(const CefSize& size) override;
384 CefSize GetSize() override;
385 void SetPosition(const CefPoint& position) override;
386 CefPoint GetPosition() override;
387 CefSize GetPreferredSize() override;
388 void SizeToPreferredSize() override;
389 CefSize GetMinimumSize() override;
390 CefSize GetMaximumSize() override;
391 int GetHeightForWidth(int width) override;
392 void InvalidateLayout() override;
393 void SetVisible(bool visible) override;
394 bool IsVisible() override;
395 bool IsDrawn() override;
396 void SetEnabled(bool enabled) override;
397 bool IsEnabled() override;
398 void SetFocusable(bool focusable) override;
399 bool IsFocusable() override;
400 bool IsAccessibilityFocusable() override;
401 void RequestFocus() override;
402 void SetBackgroundColor(cef_color_t color) override;
403 cef_color_t GetBackgroundColor() override;
404 bool ConvertPointToScreen(CefPoint& point) override;
405 bool ConvertPointFromScreen(CefPoint& point) override;
406 bool ConvertPointToWindow(CefPoint& point) override;
407 bool ConvertPointFromWindow(CefPoint& point) override;
408 bool ConvertPointToView(CefRefPtr<CefView> view, CefPoint& point) override;
409 bool ConvertPointFromView(CefRefPtr<CefView> view, CefPoint& point) override;
410
411 protected:
412 // Create a new implementation object.
413 // Always call Initialize() after creation.
414 // |delegate| may be nullptr.
CefViewImpl(CefRefPtr<CefViewDelegateClass> delegate)415 explicit CefViewImpl(CefRefPtr<CefViewDelegateClass> delegate)
416 : delegate_(delegate), root_view_ref_(nullptr) {}
417
418 // Initialize this object.
Initialize()419 virtual void Initialize() {
420 root_view_.reset(CreateRootView());
421 DCHECK(root_view_.get());
422 root_view_ref_ = root_view_.get();
423 view_util::Register(this);
424 InitializeRootView();
425 }
426
427 // Create the root views::View object.
428 virtual ViewsViewClass* CreateRootView() = 0;
429
430 // Perform required initialization of the root_view() object created by
431 // CreateRootView(). Called after this object has been registered.
432 virtual void InitializeRootView() = 0;
433
434 private:
435 CefRefPtr<CefViewDelegateClass> delegate_;
436
437 // Owned reference to the views::View wrapped by this object. Will be nullptr
438 // before the View is created and after the View's ownership is transferred.
439 std::unique_ptr<ViewsViewClass> root_view_;
440
441 // Unowned reference to the views::View wrapped by this object. Will be
442 // nullptr before the View is created and after the View is destroyed.
443 ViewsViewClass* root_view_ref_;
444 };
445
GetTypeString()446 CEF_VIEW_IMPL_T CefString CEF_VIEW_IMPL_D::GetTypeString() {
447 CEF_REQUIRE_UIT_RETURN(CefString());
448 return GetDebugType();
449 }
450
ToString(bool include_children)451 CEF_VIEW_IMPL_T CefString CEF_VIEW_IMPL_D::ToString(bool include_children) {
452 CEF_REQUIRE_UIT_RETURN(CefString());
453 std::unique_ptr<base::DictionaryValue> info(new base::DictionaryValue());
454 if (IsValid())
455 GetDebugInfo(info.get(), include_children);
456 else
457 info->SetString("type", GetDebugType());
458
459 std::string json_string;
460 base::JSONWriter::WriteWithOptions(*info, 0, &json_string);
461 return json_string;
462 }
463
IsValid()464 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsValid() {
465 CEF_REQUIRE_UIT_RETURN(false);
466 return !!root_view_ref_;
467 }
468
IsAttached()469 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsAttached() {
470 CEF_REQUIRE_UIT_RETURN(false);
471 return !root_view_.get();
472 }
473
IsSame(CefRefPtr<CefView> that)474 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsSame(CefRefPtr<CefView> that) {
475 CEF_REQUIRE_UIT_RETURN(false);
476 CefViewImpl* that_impl = static_cast<CefViewImpl*>(that.get());
477 if (!that_impl)
478 return false;
479 return this == that_impl;
480 }
481
GetDelegate()482 CEF_VIEW_IMPL_T CefRefPtr<CefViewDelegate> CEF_VIEW_IMPL_D::GetDelegate() {
483 CEF_REQUIRE_UIT_RETURN(nullptr);
484 return delegate();
485 }
486
GetWindow()487 CEF_VIEW_IMPL_T CefRefPtr<CefWindow> CEF_VIEW_IMPL_D::GetWindow() {
488 CEF_REQUIRE_UIT_RETURN(nullptr);
489 if (root_view())
490 return view_util::GetWindowFor(root_view()->GetWidget());
491 return nullptr;
492 }
493
GetID()494 CEF_VIEW_IMPL_T int CEF_VIEW_IMPL_D::GetID() {
495 CEF_REQUIRE_VALID_RETURN(0);
496 return root_view()->GetID();
497 }
498
SetID(int id)499 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetID(int id) {
500 CEF_REQUIRE_VALID_RETURN_VOID();
501 root_view()->SetID(id);
502 }
503
GetGroupID()504 CEF_VIEW_IMPL_T int CEF_VIEW_IMPL_D::GetGroupID() {
505 CEF_REQUIRE_VALID_RETURN(0);
506 return root_view()->GetGroup();
507 }
508
SetGroupID(int group_id)509 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetGroupID(int group_id) {
510 CEF_REQUIRE_VALID_RETURN_VOID();
511 if (root_view()->GetGroup() != -1)
512 return;
513 root_view()->SetGroup(group_id);
514 }
515
GetParentView()516 CEF_VIEW_IMPL_T CefRefPtr<CefView> CEF_VIEW_IMPL_D::GetParentView() {
517 CEF_REQUIRE_VALID_RETURN(nullptr);
518 views::View* view = root_view()->parent();
519 if (!view)
520 return nullptr;
521 return view_util::GetFor(view, true);
522 }
523
GetViewForID(int id)524 CEF_VIEW_IMPL_T CefRefPtr<CefView> CEF_VIEW_IMPL_D::GetViewForID(int id) {
525 CEF_REQUIRE_VALID_RETURN(nullptr);
526 views::View* view = root_view()->GetViewByID(id);
527 if (!view)
528 return nullptr;
529 return view_util::GetFor(view, true);
530 }
531
SetBounds(const CefRect & bounds)532 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetBounds(const CefRect& bounds) {
533 CEF_REQUIRE_VALID_RETURN_VOID();
534 root_view()->SetBoundsRect(
535 gfx::Rect(bounds.x, bounds.y, bounds.width, bounds.height));
536 }
537
GetBounds()538 CEF_VIEW_IMPL_T CefRect CEF_VIEW_IMPL_D::GetBounds() {
539 CEF_REQUIRE_VALID_RETURN(CefRect());
540 const gfx::Rect& bounds = root_view()->bounds();
541 return CefRect(bounds.x(), bounds.y(), bounds.width(), bounds.height());
542 }
543
GetBoundsInScreen()544 CEF_VIEW_IMPL_T CefRect CEF_VIEW_IMPL_D::GetBoundsInScreen() {
545 CEF_REQUIRE_VALID_RETURN(CefRect());
546 const gfx::Rect& bounds = root_view()->GetBoundsInScreen();
547 return CefRect(bounds.x(), bounds.y(), bounds.width(), bounds.height());
548 }
549
SetSize(const CefSize & size)550 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetSize(const CefSize& size) {
551 CEF_REQUIRE_VALID_RETURN_VOID();
552 root_view()->SetSize(gfx::Size(size.width, size.height));
553 }
554
GetSize()555 CEF_VIEW_IMPL_T CefSize CEF_VIEW_IMPL_D::GetSize() {
556 CEF_REQUIRE_VALID_RETURN(CefSize());
557 // Call GetBounds() since child classes may override it.
558 const CefRect& bounds = GetBounds();
559 return CefSize(bounds.width, bounds.height);
560 }
561
SetPosition(const CefPoint & position)562 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetPosition(const CefPoint& position) {
563 CEF_REQUIRE_VALID_RETURN_VOID();
564 root_view()->SetPosition(gfx::Point(position.x, position.y));
565 }
566
GetPosition()567 CEF_VIEW_IMPL_T CefPoint CEF_VIEW_IMPL_D::GetPosition() {
568 CEF_REQUIRE_VALID_RETURN(CefPoint());
569 // Call GetBounds() since child classes may override it.
570 const CefRect& bounds = GetBounds();
571 return CefPoint(bounds.x, bounds.y);
572 }
573
GetPreferredSize()574 CEF_VIEW_IMPL_T CefSize CEF_VIEW_IMPL_D::GetPreferredSize() {
575 CEF_REQUIRE_VALID_RETURN(CefSize());
576 const gfx::Size& size = root_view()->GetPreferredSize();
577 return CefSize(size.width(), size.height());
578 }
579
SizeToPreferredSize()580 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SizeToPreferredSize() {
581 CEF_REQUIRE_VALID_RETURN_VOID();
582 root_view()->SizeToPreferredSize();
583 }
584
GetMinimumSize()585 CEF_VIEW_IMPL_T CefSize CEF_VIEW_IMPL_D::GetMinimumSize() {
586 CEF_REQUIRE_VALID_RETURN(CefSize());
587 const gfx::Size& size = root_view()->GetMinimumSize();
588 return CefSize(size.width(), size.height());
589 }
590
GetMaximumSize()591 CEF_VIEW_IMPL_T CefSize CEF_VIEW_IMPL_D::GetMaximumSize() {
592 CEF_REQUIRE_VALID_RETURN(CefSize());
593 const gfx::Size& size = root_view()->GetMaximumSize();
594 return CefSize(size.width(), size.height());
595 }
596
GetHeightForWidth(int width)597 CEF_VIEW_IMPL_T int CEF_VIEW_IMPL_D::GetHeightForWidth(int width) {
598 CEF_REQUIRE_VALID_RETURN(0);
599 return root_view()->GetHeightForWidth(width);
600 }
601
InvalidateLayout()602 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::InvalidateLayout() {
603 CEF_REQUIRE_VALID_RETURN_VOID();
604 root_view()->InvalidateLayout();
605 }
606
SetVisible(bool visible)607 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetVisible(bool visible) {
608 CEF_REQUIRE_VALID_RETURN_VOID();
609 root_view()->SetVisible(visible);
610 }
611
IsVisible()612 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsVisible() {
613 CEF_REQUIRE_VALID_RETURN(false);
614 return root_view()->GetVisible();
615 }
616
IsDrawn()617 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsDrawn() {
618 CEF_REQUIRE_VALID_RETURN(false);
619 return root_view()->IsDrawn();
620 }
621
SetEnabled(bool enabled)622 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetEnabled(bool enabled) {
623 CEF_REQUIRE_VALID_RETURN_VOID();
624 root_view()->SetEnabled(enabled);
625 }
626
IsEnabled()627 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsEnabled() {
628 CEF_REQUIRE_VALID_RETURN(false);
629 return root_view()->GetEnabled();
630 }
631
SetFocusable(bool focusable)632 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetFocusable(bool focusable) {
633 CEF_REQUIRE_VALID_RETURN_VOID();
634 root_view()->SetFocusBehavior(focusable ? views::View::FocusBehavior::ALWAYS
635 : views::View::FocusBehavior::NEVER);
636 }
637
IsFocusable()638 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsFocusable() {
639 CEF_REQUIRE_VALID_RETURN(false);
640 return root_view()->IsFocusable();
641 }
642
IsAccessibilityFocusable()643 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::IsAccessibilityFocusable() {
644 CEF_REQUIRE_VALID_RETURN(false);
645 return root_view()->IsAccessibilityFocusable();
646 }
647
RequestFocus()648 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::RequestFocus() {
649 CEF_REQUIRE_VALID_RETURN_VOID();
650 root_view()->RequestFocus();
651 }
652
SetBackgroundColor(cef_color_t color)653 CEF_VIEW_IMPL_T void CEF_VIEW_IMPL_D::SetBackgroundColor(cef_color_t color) {
654 CEF_REQUIRE_VALID_RETURN_VOID();
655 content_view()->SetBackground(views::CreateSolidBackground(color));
656 }
657
GetBackgroundColor()658 CEF_VIEW_IMPL_T cef_color_t CEF_VIEW_IMPL_D::GetBackgroundColor() {
659 CEF_REQUIRE_VALID_RETURN(0U);
660 return content_view()->background()->get_color();
661 }
662
ConvertPointToScreen(CefPoint & point)663 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::ConvertPointToScreen(CefPoint& point) {
664 CEF_REQUIRE_VALID_RETURN(false);
665 gfx::Point gfx_point = gfx::Point(point.x, point.y);
666 if (!view_util::ConvertPointToScreen(root_view(), &gfx_point, false))
667 return false;
668 point = CefPoint(gfx_point.x(), gfx_point.y());
669 return true;
670 }
671
ConvertPointFromScreen(CefPoint & point)672 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::ConvertPointFromScreen(CefPoint& point) {
673 CEF_REQUIRE_VALID_RETURN(false);
674 gfx::Point gfx_point = gfx::Point(point.x, point.y);
675 if (!view_util::ConvertPointFromScreen(root_view(), &gfx_point, false))
676 return false;
677 point = CefPoint(gfx_point.x(), gfx_point.y());
678 return true;
679 }
680
ConvertPointToWindow(CefPoint & point)681 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::ConvertPointToWindow(CefPoint& point) {
682 CEF_REQUIRE_VALID_RETURN(false);
683 gfx::Point gfx_point = gfx::Point(point.x, point.y);
684 if (!view_util::ConvertPointToWindow(root_view(), &gfx_point))
685 return false;
686 point = CefPoint(gfx_point.x(), gfx_point.y());
687 return true;
688 }
689
ConvertPointFromWindow(CefPoint & point)690 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::ConvertPointFromWindow(CefPoint& point) {
691 CEF_REQUIRE_VALID_RETURN(false);
692 gfx::Point gfx_point = gfx::Point(point.x, point.y);
693 if (!view_util::ConvertPointFromWindow(root_view(), &gfx_point))
694 return false;
695 point = CefPoint(gfx_point.x(), gfx_point.y());
696 return true;
697 }
698
ConvertPointToView(CefRefPtr<CefView> view,CefPoint & point)699 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::ConvertPointToView(
700 CefRefPtr<CefView> view,
701 CefPoint& point) {
702 CEF_REQUIRE_VALID_RETURN(false);
703 if (!root_view()->GetWidget())
704 return false;
705 views::View* target_view = view_util::GetFor(view);
706 if (!target_view || target_view->GetWidget() != root_view()->GetWidget())
707 return false;
708 gfx::Point gfx_point = gfx::Point(point.x, point.y);
709 views::View::ConvertPointToTarget(root_view(), target_view, &gfx_point);
710 point = CefPoint(gfx_point.x(), gfx_point.y());
711 return true;
712 }
713
ConvertPointFromView(CefRefPtr<CefView> view,CefPoint & point)714 CEF_VIEW_IMPL_T bool CEF_VIEW_IMPL_D::ConvertPointFromView(
715 CefRefPtr<CefView> view,
716 CefPoint& point) {
717 CEF_REQUIRE_VALID_RETURN(false);
718 if (!root_view()->GetWidget())
719 return false;
720 views::View* target_view = view_util::GetFor(view);
721 if (!target_view || target_view->GetWidget() != root_view()->GetWidget())
722 return false;
723 gfx::Point gfx_point = gfx::Point(point.x, point.y);
724 views::View::ConvertPointToTarget(target_view, root_view(), &gfx_point);
725 point = CefPoint(gfx_point.x(), gfx_point.y());
726 return true;
727 }
728
729 #endif // CEF_LIBCEF_BROWSER_VIEWS_VIEW_IMPL_H_
730