Index: views/controls/native/native_view_host.cc |
=================================================================== |
--- views/controls/native/native_view_host.cc (revision 0) |
+++ views/controls/native/native_view_host.cc (working copy) |
@@ -2,16 +2,24 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "views/controls/native_view_host.h" |
+#include "views/controls/native/native_view_host.h" |
+#include "base/logging.h" |
+#include "app/gfx/canvas.h" |
+#include "views/controls/native/native_view_host_wrapper.h" |
#include "views/widget/widget.h" |
-#include "base/logging.h" |
namespace views { |
+// static |
+const char NativeViewHost::kViewClassName[] = "views/NativeViewHost"; |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+// NativeViewHost, public: |
+ |
NativeViewHost::NativeViewHost() |
: native_view_(NULL), |
- installed_clip_(false), |
+ native_wrapper_(NULL), |
fast_resize_(false), |
focus_view_(NULL) { |
// The native widget is placed relative to the root. As such, we need to |
@@ -23,17 +31,38 @@ |
NativeViewHost::~NativeViewHost() { |
} |
-gfx::Size NativeViewHost::GetPreferredSize() { |
- return preferred_size_; |
+void NativeViewHost::Attach(gfx::NativeView native_view) { |
+ DCHECK(!native_view_); |
+ native_view_ = native_view; |
+ native_wrapper_->NativeViewAttached(); |
} |
+void NativeViewHost::Detach() { |
+ DCHECK(native_view_); |
+ native_wrapper_->NativeViewDetaching(); |
+ native_view_ = NULL; |
+} |
+ |
void NativeViewHost::SetPreferredSize(const gfx::Size& size) { |
preferred_size_ = size; |
PreferredSizeChanged(); |
} |
+void NativeViewHost::NativeViewDestroyed() { |
+ // TODO(beng): figure out if this should/could call Detach instead since as it |
+ // stands right now this object is left in an inconsistent state. |
+ native_view_ = NULL; |
+} |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+// NativeViewHost, View overrides: |
+ |
+gfx::Size NativeViewHost::GetPreferredSize() { |
+ return preferred_size_; |
+} |
+ |
void NativeViewHost::Layout() { |
- if (!native_view_) |
+ if (!native_view_ || !native_wrapper_) |
return; |
// Since widgets know nothing about the View hierarchy (they are direct |
@@ -46,28 +75,38 @@ |
gfx::Rect vis_bounds = GetVisibleBounds(); |
bool visible = !vis_bounds.IsEmpty(); |
- if (visible && !fast_resize_) { |
+ if (visible && !fast_resize_ && native_wrapper_) { |
if (vis_bounds.size() != size()) { |
// Only a portion of the Widget is really visible. |
int x = vis_bounds.x(); |
int y = vis_bounds.y(); |
- InstallClip(x, y, vis_bounds.width(), vis_bounds.height()); |
- installed_clip_ = true; |
- } else if (installed_clip_) { |
+ native_wrapper_->InstallClip(x, y, vis_bounds.width(), |
+ vis_bounds.height()); |
+ } else if (native_wrapper_->HasInstalledClip()) { |
// The whole widget is visible but we installed a clip on the widget, |
// uninstall it. |
- UninstallClip(); |
- installed_clip_ = false; |
+ native_wrapper_->UninstallClip(); |
} |
} |
- if (visible) { |
- ShowWidget(top_left.x(), top_left.y(), width(), height()); |
- } else { |
- HideWidget(); |
- } |
+ if (visible) |
+ native_wrapper_->ShowWidget(top_left.x(), top_left.y(), width(), height()); |
+ else |
+ native_wrapper_->HideWidget(); |
} |
+void NativeViewHost::Paint(gfx::Canvas* canvas) { |
+ // The area behind our window is black, so during a fast resize (where our |
+ // content doesn't draw over the full size of our native view, and the native |
+ // view background color doesn't show up), we need to cover that blackness |
+ // with something so that fast resizes don't result in black flash. |
+ // |
+ // It would be nice if this used some approximation of the page's |
+ // current background color. |
+ if (native_wrapper_->HasInstalledClip()) |
+ canvas->FillRectInt(SK_ColorWHITE, 0, 0, width(), height()); |
+} |
+ |
void NativeViewHost::VisibilityChanged(View* starting_from, bool is_visible) { |
Layout(); |
} |
@@ -76,4 +115,23 @@ |
Layout(); |
} |
+void NativeViewHost::ViewHierarchyChanged(bool is_add, View* parent, |
+ View* child) { |
+ if (is_add && GetWidget()) { |
+ if (!native_wrapper_) |
+ native_wrapper_ = NativeViewHostWrapper::CreateWrapper(this); |
+ native_wrapper_->AddedToWidget(); |
+ } else if (!is_add) { |
+ native_wrapper_->RemovedFromWidget(); |
+ } |
+} |
+ |
+std::string NativeViewHost::GetClassName() const { |
+ return kViewClassName; |
+} |
+ |
+void NativeViewHost::Focus() { |
+ native_wrapper_->SetFocus(); |
+} |
+ |
} // namespace views |