• 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/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