• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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