summaryrefslogtreecommitdiffstats
path: root/views
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-29 06:02:19 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-29 06:02:19 +0000
commit17dee5e7005a82e08d11be50d56477939124a6b7 (patch)
tree7133a5d7a086ce238057cb82e0e81d332dafba8f /views
parentbf0136d62bfe02f57821ce026c04b6e8204eb482 (diff)
downloadchromium_src-17dee5e7005a82e08d11be50d56477939124a6b7.zip
chromium_src-17dee5e7005a82e08d11be50d56477939124a6b7.tar.gz
chromium_src-17dee5e7005a82e08d11be50d56477939124a6b7.tar.bz2
Refactors HWNDView, NativeViewHostGtk and NativeViewHost so that they match the NativeControl pattern established for NativeButtons. NativeViewHost is a platform-neutral class that clients instantiate. Behind the scenes the platform instantiates the appropriate NativeViewHostWrapper implementation, either NativeViewHostGtk (as before) or NativeViewHostWin (replaces HWNDView).
BUG=none TEST=none Review URL: http://codereview.chromium.org/114059 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17169 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r--views/controls/button/native_button_gtk.cc5
-rw-r--r--views/controls/button/native_button_win.cc14
-rw-r--r--views/controls/hwnd_view.cc138
-rw-r--r--views/controls/hwnd_view.h66
-rw-r--r--views/controls/native/native_view_host.cc137
-rw-r--r--views/controls/native/native_view_host.h (renamed from views/controls/native_view_host.h)93
-rw-r--r--views/controls/native/native_view_host_gtk.cc173
-rw-r--r--views/controls/native/native_view_host_gtk.h (renamed from views/controls/native_view_host_gtk.h)46
-rw-r--r--views/controls/native/native_view_host_win.cc135
-rw-r--r--views/controls/native/native_view_host_win.h46
-rw-r--r--views/controls/native/native_view_host_wrapper.h62
-rw-r--r--views/controls/native_control.cc6
-rw-r--r--views/controls/native_control.h4
-rw-r--r--views/controls/native_control_gtk.cc4
-rw-r--r--views/controls/native_control_gtk.h4
-rw-r--r--views/controls/native_control_win.cc32
-rw-r--r--views/controls/native_control_win.h6
-rw-r--r--views/controls/native_view_host.cc79
-rw-r--r--views/controls/native_view_host_gtk.cc157
-rw-r--r--views/controls/scrollbar/native_scroll_bar.cc4
-rw-r--r--views/controls/scrollbar/native_scroll_bar.h4
-rw-r--r--views/controls/separator.cc2
-rw-r--r--views/controls/table/table_view.cc2
-rw-r--r--views/controls/textfield/native_textfield_win.cc6
-rw-r--r--views/controls/textfield/native_textfield_win.h4
-rw-r--r--views/controls/textfield/textfield.cc2
-rw-r--r--views/focus/focus_manager.h2
-rw-r--r--views/view_unittest.cc4
-rw-r--r--views/views.gyp13
29 files changed, 684 insertions, 566 deletions
diff --git a/views/controls/button/native_button_gtk.cc b/views/controls/button/native_button_gtk.cc
index 3f10897..63da111 100644
--- a/views/controls/button/native_button_gtk.cc
+++ b/views/controls/button/native_button_gtk.cc
@@ -11,6 +11,7 @@
#include "views/controls/button/checkbox.h"
#include "views/controls/button/native_button.h"
#include "views/controls/button/radio_button.h"
+#include "views/controls/native/native_view_host_gtk.h"
#include "views/widget/widget.h"
namespace views {
@@ -21,7 +22,7 @@ NativeButtonGtk::NativeButtonGtk(NativeButton* native_button)
// Associates the actual GtkWidget with the native_button so the native_button
// is the one considered as having the focus (not the wrapper) when the
// GtkWidget is focused directly (with a click for example).
- SetAssociatedFocusView(native_button);
+ set_focus_view(native_button);
}
NativeButtonGtk::~NativeButtonGtk() {
@@ -90,7 +91,7 @@ void NativeButtonGtk::NativeControlCreated(GtkWidget* widget) {
// static
void NativeButtonGtk::CallClicked(GtkButton* widget) {
- View* view = GetViewForNative(GTK_WIDGET(widget));
+ View* view = NativeViewHostGtk::GetViewForNative(GTK_WIDGET(widget));
if (view)
static_cast<NativeButtonGtk*>(view)->OnClicked();
}
diff --git a/views/controls/button/native_button_win.cc b/views/controls/button/native_button_win.cc
index 5dd70d3..8d51907 100644
--- a/views/controls/button/native_button_win.cc
+++ b/views/controls/button/native_button_win.cc
@@ -23,7 +23,7 @@ NativeButtonWin::NativeButtonWin(NativeButton* native_button)
// Associates the actual HWND with the native_button so the native_button is
// the one considered as having the focus (not the wrapper) when the HWND is
// focused directly (with a click for example).
- SetAssociatedFocusView(native_button);
+ set_focus_view(native_button);
}
NativeButtonWin::~NativeButtonWin() {
@@ -33,11 +33,11 @@ NativeButtonWin::~NativeButtonWin() {
// NativeButtonWin, NativeButtonWrapper implementation:
void NativeButtonWin::UpdateLabel() {
- SetWindowText(GetHWND(), native_button_->label().c_str());
+ SetWindowText(native_view(), native_button_->label().c_str());
}
void NativeButtonWin::UpdateFont() {
- SendMessage(GetHWND(), WM_SETFONT,
+ SendMessage(native_view(), WM_SETFONT,
reinterpret_cast<WPARAM>(native_button_->font().hfont()),
FALSE);
}
@@ -48,7 +48,7 @@ void NativeButtonWin::UpdateEnabled() {
void NativeButtonWin::UpdateDefault() {
if (!IsCheckbox()) {
- SendMessage(GetHWND(), BM_SETSTYLE,
+ SendMessage(native_view(), BM_SETSTYLE,
native_button_->is_default() ? BS_DEFPUSHBUTTON : BS_PUSHBUTTON,
true);
}
@@ -68,7 +68,7 @@ void NativeButtonWin::SetFocus() {
gfx::Size NativeButtonWin::GetPreferredSize() {
SIZE sz = {0};
- SendMessage(GetHWND(), BCM_GETIDEALSIZE, 0, reinterpret_cast<LPARAM>(&sz));
+ SendMessage(native_view(), BCM_GETIDEALSIZE, 0, reinterpret_cast<LPARAM>(&sz));
return gfx::Size(sz.cx, sz.cy);
}
@@ -142,12 +142,12 @@ gfx::Size NativeCheckboxWin::GetPreferredSize() {
// NativeCheckboxWin, NativeButtonWrapper implementation:
void NativeCheckboxWin::UpdateChecked() {
- SendMessage(GetHWND(), BM_SETCHECK,
+ SendMessage(native_view(), BM_SETCHECK,
checkbox_->checked() ? BST_CHECKED : BST_UNCHECKED, 0);
}
void NativeCheckboxWin::SetPushed(bool pushed) {
- SendMessage(GetHWND(), BM_SETSTATE, pushed, 0);
+ SendMessage(native_view(), BM_SETSTATE, pushed, 0);
}
bool NativeCheckboxWin::OnKeyDown(int vkey) {
diff --git a/views/controls/hwnd_view.cc b/views/controls/hwnd_view.cc
deleted file mode 100644
index 77269f2..0000000
--- a/views/controls/hwnd_view.cc
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "views/controls/hwnd_view.h"
-
-#include "app/gfx/canvas.h"
-#include "base/logging.h"
-#include "views/focus/focus_manager.h"
-#include "views/widget/widget.h"
-
-namespace views {
-
-static const char kViewClassName[] = "views/HWNDView";
-
-HWNDView::HWNDView() : NativeViewHost() {
-}
-
-HWNDView::~HWNDView() {
-}
-
-void HWNDView::Attach(HWND hwnd) {
- DCHECK(native_view() == NULL);
- DCHECK(hwnd) << "Impossible detatched tab case; See crbug.com/6316";
-
- set_native_view(hwnd);
-
- // First hide the new window. We don't want anything to draw (like sub-hwnd
- // borders), when we change the parent below.
- ShowWindow(hwnd, SW_HIDE);
-
- // Need to set the HWND's parent before changing its size to avoid flashing.
- ::SetParent(hwnd, GetWidget()->GetNativeView());
- Layout();
-
- // Register with the focus manager so the associated view is focused when the
- // native control gets the focus.
- FocusManager::InstallFocusSubclass(
- hwnd, associated_focus_view() ? associated_focus_view() : this);
-}
-
-void HWNDView::Detach() {
- DCHECK(native_view());
- FocusManager::UninstallFocusSubclass(native_view());
- set_native_view(NULL);
- set_installed_clip(false);
-}
-
-void HWNDView::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 HWND, and the HWND
- // 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 (installed_clip())
- canvas->FillRectInt(SkColorSetRGB(255, 255, 255), 0, 0, width(), height());
-}
-
-std::string HWNDView::GetClassName() const {
- return kViewClassName;
-}
-
-void HWNDView::ViewHierarchyChanged(bool is_add, View *parent, View *child) {
- if (!native_view())
- return;
-
- Widget* widget = GetWidget();
- if (is_add && widget) {
- HWND parent_hwnd = ::GetParent(native_view());
- HWND widget_hwnd = widget->GetNativeView();
- if (parent_hwnd != widget_hwnd)
- ::SetParent(native_view(), widget_hwnd);
- if (IsVisibleInRootView())
- ::ShowWindow(native_view(), SW_SHOW);
- else
- ::ShowWindow(native_view(), SW_HIDE);
- Layout();
- } else if (!is_add) {
- ::ShowWindow(native_view(), SW_HIDE);
- ::SetParent(native_view(), NULL);
- }
-}
-
-void HWNDView::Focus() {
- ::SetFocus(native_view());
-}
-
-void HWNDView::InstallClip(int x, int y, int w, int h) {
- HRGN clip_region = CreateRectRgn(x, y, x + w, y + h);
- // NOTE: SetWindowRgn owns the region (as well as the deleting the
- // current region), as such we don't delete the old region.
- SetWindowRgn(native_view(), clip_region, FALSE);
-}
-
-void HWNDView::UninstallClip() {
- SetWindowRgn(native_view(), 0, FALSE);
-}
-
-void HWNDView::ShowWidget(int x, int y, int w, int h) {
- UINT swp_flags = SWP_DEFERERASE |
- SWP_NOACTIVATE |
- SWP_NOCOPYBITS |
- SWP_NOOWNERZORDER |
- SWP_NOZORDER;
- // Only send the SHOWWINDOW flag if we're invisible, to avoid flashing.
- if (!::IsWindowVisible(native_view()))
- swp_flags = (swp_flags | SWP_SHOWWINDOW) & ~SWP_NOREDRAW;
-
- if (fast_resize()) {
- // In a fast resize, we move the window and clip it with SetWindowRgn.
- RECT win_rect;
- GetWindowRect(native_view(), &win_rect);
- gfx::Rect rect(win_rect);
- ::SetWindowPos(native_view(), 0, x, y, rect.width(), rect.height(),
- swp_flags);
-
- HRGN clip_region = CreateRectRgn(0, 0, w, h);
- SetWindowRgn(native_view(), clip_region, FALSE);
- set_installed_clip(true);
- } else {
- ::SetWindowPos(native_view(), 0, x, y, w, h, swp_flags);
- }
-}
-
-void HWNDView::HideWidget() {
- if (!::IsWindowVisible(native_view()))
- return; // Currently not visible, nothing to do.
-
- // The window is currently visible, but its clipped by another view. Hide
- // it.
- ::SetWindowPos(native_view(), 0, 0, 0, 0, 0,
- SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
- SWP_NOREDRAW | SWP_NOOWNERZORDER);
-}
-
-} // namespace views
diff --git a/views/controls/hwnd_view.h b/views/controls/hwnd_view.h
deleted file mode 100644
index 1ad1ef6..0000000
--- a/views/controls/hwnd_view.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef VIEWS_CONTROLS_HWND_VIEW_H_
-#define VIEWS_CONTROLS_HWND_VIEW_H_
-
-#include <string>
-
-#include "views/controls/native_view_host.h"
-
-namespace views {
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// HWNDView class
-//
-// The HWNDView class hosts a native window handle (HWND) sizing it
-// according to the bounds of the view. This is useful whenever you need to
-// show a UI control that has a HWND (e.g. a native windows Edit control)
-// within thew View hierarchy and benefit from the sizing/layout.
-//
-/////////////////////////////////////////////////////////////////////////////
-// TODO: Rename this to NativeViewHostWin.
-class HWNDView : public NativeViewHost {
- public:
- HWNDView();
- virtual ~HWNDView();
-
- // Attach a window handle to this View, making the window it represents
- // subject to sizing according to this View's parent container's Layout
- // Manager's sizing heuristics.
- //
- // This object should be added to the view hierarchy before calling this
- // function, which will expect the parent to be valid.
- void Attach(HWND hwnd);
-
- // Detach the attached window handle. It will no longer be updated
- void Detach();
-
- // TODO(sky): convert this to native_view().
- HWND GetHWND() const { return native_view(); }
-
- virtual void Paint(gfx::Canvas* canvas);
-
- // Overridden from View.
- virtual std::string GetClassName() const;
-
- protected:
- virtual void ViewHierarchyChanged(bool is_add, View *parent, View *child);
-
- virtual void Focus();
-
- // NativeHostView overrides.
- virtual void InstallClip(int x, int y, int w, int h);
- virtual void UninstallClip();
- virtual void ShowWidget(int x, int y, int w, int h);
- virtual void HideWidget();
-
- private:
- DISALLOW_COPY_AND_ASSIGN(HWNDView);
-};
-
-} // namespace views
-
-#endif // VIEWS_CONTROLS_HWND_VIEW_H_
diff --git a/views/controls/native/native_view_host.cc b/views/controls/native/native_view_host.cc
new file mode 100644
index 0000000..18ba870
--- /dev/null
+++ b/views/controls/native/native_view_host.cc
@@ -0,0 +1,137 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#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"
+
+namespace views {
+
+// static
+const char NativeViewHost::kViewClassName[] = "views/NativeViewHost";
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeViewHost, public:
+
+NativeViewHost::NativeViewHost()
+ : native_view_(NULL),
+ native_wrapper_(NULL),
+ fast_resize_(false),
+ focus_view_(NULL) {
+ // The native widget is placed relative to the root. As such, we need to
+ // know when the position of any ancestor changes, or our visibility relative
+ // to other views changed as it'll effect our position relative to the root.
+ SetNotifyWhenVisibleBoundsInRootChanges(true);
+}
+
+NativeViewHost::~NativeViewHost() {
+}
+
+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_ || !native_wrapper_)
+ return;
+
+ // Since widgets know nothing about the View hierarchy (they are direct
+ // children of the Widget that hosts our View hierarchy) they need to be
+ // positioned in the coordinate system of the Widget, not the current
+ // view.
+ gfx::Point top_left;
+ ConvertPointToWidget(this, &top_left);
+
+ gfx::Rect vis_bounds = GetVisibleBounds();
+ bool visible = !vis_bounds.IsEmpty();
+
+ 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();
+ 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.
+ native_wrapper_->UninstallClip();
+ }
+ }
+
+ 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();
+}
+
+void NativeViewHost::VisibleBoundsInRootChanged() {
+ 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
diff --git a/views/controls/native_view_host.h b/views/controls/native/native_view_host.h
index 15cf98e..c9dce23 100644
--- a/views/controls/native_view_host.h
+++ b/views/controls/native/native_view_host.h
@@ -13,21 +13,34 @@
namespace views {
-// Base class for embedding native widgets in a view.
+class NativeViewHostWrapper;
+
+// A View type that hosts a gfx::NativeView. The bounds of the native view are
+// kept in sync with the bounds of this view as it is moved and sized.
+// Under the hood, a platform-specific NativeViewHostWrapper implementation does
+// the platform-specific work of manipulating the underlying OS widget type.
class NativeViewHost : public View {
public:
+ // The NativeViewHost's class name.
+ static const char kViewClassName[];
+
NativeViewHost();
virtual ~NativeViewHost();
- void SetPreferredSize(const gfx::Size& size);
- virtual gfx::Size GetPreferredSize();
+ // Attach a gfx::NativeView to this View. Its bounds will be kept in sync
+ // with the bounds of this View until Detach is called.
+ //
+ // Because native views are positioned in the coordinates of their parent
+ // native view, this function should only be called after this View has been
+ // added to a View hierarchy hosted within a valid Widget.
+ void Attach(gfx::NativeView native_view);
- // Overriden to invoke Layout.
- virtual void VisibilityChanged(View* starting_from, bool is_visible);
+ // Detach the attached window handle. Its bounds and visibility will no longer
+ // be manipulated by this View.
+ void Detach();
- // Invokes any of InstallClip, UninstallClip, ShowWidget or HideWidget
- // depending upon what portion of the widget is view in the parent.
- virtual void Layout();
+ // Sets a preferred size for the native view attached to this View.
+ void SetPreferredSize(const gfx::Size& size);
// A NativeViewHost has an associated focus View so that the focus of the
// native control and of the View are kept in sync. In simple cases where the
@@ -36,58 +49,48 @@ class NativeViewHost : public View {
// view (such as TextField), the actual View is not the NativeViewHost and
// this method must be called to set that.
// This method must be called before Attach().
- void SetAssociatedFocusView(View* view) { focus_view_ = view; }
- View* associated_focus_view() { return focus_view_; }
+ void set_focus_view(View* view) { focus_view_ = view; }
+ View* focus_view() { return focus_view_; }
+ // Fast resizing will move the native view and clip its visible region, this
+ // will result in white areas and will not resize the content (so scrollbars
+ // will be all wrong and content will flow offscreen). Only use this
+ // when you're doing extremely quick, high-framerate vertical resizes
+ // and don't care about accuracy. Make sure you do a real resize at the
+ // end. USE WITH CAUTION.
void set_fast_resize(bool fast_resize) { fast_resize_ = fast_resize; }
bool fast_resize() const { return fast_resize_; }
- // The embedded native view.
+ // Accessor for |native_view_|.
gfx::NativeView native_view() const { return native_view_; }
- protected:
- // Notification that our visible bounds relative to the root has changed.
- // Invokes Layout to make sure the widget is positioned correctly.
- virtual void VisibleBoundsInRootChanged();
-
- // Sets the native view. Subclasses will typically invoke Layout after setting
- // the widget.
- void set_native_view(gfx::NativeView widget) { native_view_ = widget; }
+ void NativeViewDestroyed();
- // Installs a clip on the native widget.
- virtual void InstallClip(int x, int y, int w, int h) = 0;
-
- // Removes the clip installed on the native widget by way of InstallClip.
- virtual void UninstallClip() = 0;
-
- // Shows the widget at the specified position (relative to the parent widget).
- virtual void ShowWidget(int x, int y, int w, int h) = 0;
-
- // Hides the widget. NOTE: this may be invoked when the widget is already
- // hidden.
- virtual void HideWidget() = 0;
+ // Overridden from View:
+ virtual gfx::Size GetPreferredSize();
+ virtual void Layout();
+ virtual void Paint(gfx::Canvas* canvas);
+ virtual void VisibilityChanged(View* starting_from, bool is_visible);
- void set_installed_clip(bool installed_clip) {
- installed_clip_ = installed_clip;
- }
- bool installed_clip() const { return installed_clip_; }
+ protected:
+ virtual void VisibleBoundsInRootChanged();
+ virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child);
+ virtual std::string GetClassName() const;
+ virtual void Focus();
private:
+ // The attached native view.
gfx::NativeView native_view_;
+ // A platform-specific wrapper that does the OS-level manipulation of the
+ // attached gfx::NativeView.
+ NativeViewHostWrapper* native_wrapper_;
+
// The preferred size of this View
gfx::Size preferred_size_;
- // Have we installed a region on the HWND used to clip to only the visible
- // portion of the HWND?
- bool installed_clip_;
-
- // Fast resizing will move the hwnd and clip its window region, this will
- // result in white areas and will not resize the content (so scrollbars
- // will be all wrong and content will flow offscreen). Only use this
- // when you're doing extremely quick, high-framerate vertical resizes
- // and don't care about accuracy. Make sure you do a real resize at the
- // end. USE WITH CAUTION.
+ // True if the native view is being resized using the fast method described
+ // in the setter/accessor above.
bool fast_resize_;
// The view that should be given focus when this NativeViewHost is focused.
diff --git a/views/controls/native/native_view_host_gtk.cc b/views/controls/native/native_view_host_gtk.cc
new file mode 100644
index 0000000..643fa30
--- /dev/null
+++ b/views/controls/native/native_view_host_gtk.cc
@@ -0,0 +1,173 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "views/controls/native/native_view_host_gtk.h"
+
+#include <gtk/gtk.h>
+
+#include "base/logging.h"
+#include "views/controls/native/native_view_host.h"
+#include "views/widget/widget_gtk.h"
+
+namespace views {
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeViewHostGtk, public:
+
+NativeViewHostWin::NativeViewHostWin(NativeViewHost* host)
+ : host_(host),
+ installed_clip_(false),
+ destroy_signal_id_(0) {
+}
+
+NativeViewHostGtk::~NativeViewHostGtk() {
+}
+
+// static
+View* NativeViewHostGtk::GetViewForNative(GtkWidget* widget) {
+ gpointer user_data = g_object_get_data(G_OBJECT(widget), "chrome-view");
+ return static_cast<View*>(user_data);
+}
+
+// static
+void NativeViewHostGtk::SetViewForNative(GtkWidget* widget, View* view) {
+ g_object_set_data(G_OBJECT(widget), "chrome-view", view);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeViewHostGtk, NativeViewHostWrapper implementation:
+
+void NativeViewHostGtk::NativeViewAttached() {
+ DCHECK(host_->native_view());
+
+ // Adds a mapping between the GtkWidget and us.
+ SetViewForNative(host_->native_view(), host_);
+
+ destroy_signal_id_ = g_signal_connect(G_OBJECT(host_->native_view()),
+ "destroy", G_CALLBACK(CallDestroy),
+ NULL);
+
+ // First hide the new window. We don't want anything to draw (like sub-hwnd
+ // borders), when we change the parent below.
+ gtk_widget_hide(host_->native_view());
+
+ // Set the parent.
+ static_cast<WidgetGtk*>(host_->GetWidget())->AddChild(host_->native_view());
+ host_->Layout();
+
+ // TODO(port): figure out focus.
+ // FocusManager::InstallFocusSubclass(
+ // hwnd, associated_focus_view()_ ? associated_focus_view() : this);
+}
+
+void NativeViewHostGtk::NativeViewDetaching() {
+ DCHECK(host_->native_view());
+
+ g_signal_handler_disconnect(G_OBJECT(host_->native_view()),
+ destroy_signal_id_);
+ destroy_signal_id_ = 0;
+
+ // TODO(port): focus.
+ // FocusManager::UninstallFocusSubclass(native_view());
+ installed_clip_ = false;
+}
+
+void NativeViewHostGtk::AddedToWidget() {
+ WidgetGtk* parent_widget = static_cast<WidgetGtk*>(host_->GetWidget());
+ GtkWidget* widget_parent = gtk_widget_get_parent(host_->native_view());
+ GtkWidget* parent_widget_widget = parent_widget->child_widget_parent();
+ if (widget_parent != parent_widget_widget) {
+ g_object_ref(host_->native_view());
+ if (widget_parent)
+ gtk_container_remove(GTK_CONTAINER(widget_parent), host_->native_view());
+ gtk_container_add(GTK_CONTAINER(parent_widget_widget),
+ host_->native_view());
+ g_object_unref(host_->native_view());
+ }
+ if (host_->IsVisibleInRootView())
+ gtk_widget_show(host_->native_view());
+ else
+ gtk_widget_hide(host_->native_view());
+ host_->Layout();
+}
+
+void NativeViewHostGtk::RemovedFromWidget() {
+ WidgetGtk* parent_widget = static_cast<WidgetGtk*>(host_->GetWidget());
+ gtk_widget_hide(host_->native_view());
+ if (parent_widget) {
+ gtk_container_remove(GTK_CONTAINER(parent_widget->child_widget_parent()),
+ host_->native_view());
+ }
+}
+
+void NativeViewHostGtk::InstallClip(int x, int y, int w, int h) {
+ DCHECK(w > 0 && h > 0);
+
+ bool has_window =
+ (GTK_WIDGET_FLAGS(host_->native_view()) & GTK_NO_WINDOW) == 0;
+ if (!has_window) {
+ // Clip is only supported on GtkWidgets that have windows. If this becomes
+ // an issue (as it may be in the options dialog) we'll need to wrap the
+ // widget in a GtkFixed with a window. We have to do this as not all widgets
+ // support turning on GTK_NO_WINDOW (for example, buttons don't appear to
+ // draw anything when they have a window).
+ NOTREACHED();
+ return;
+ }
+ DCHECK(has_window);
+ // Unset the current region.
+ gdk_window_shape_combine_region(host_->native_view()->window, NULL, 0, 0);
+
+ // Set a new region.
+ // TODO: using shapes is a bit expensive. Should investigated if there is
+ // another more efficient way to accomplish this.
+ GdkRectangle clip_rect = { x, y, w, h };
+ GdkRegion* clip_region = gdk_region_rectangle(&clip_rect);
+ gdk_window_shape_combine_region(host_->native_view()->window, clip_region, x,
+ y);
+ gdk_region_destroy(clip_region);
+ installed_clip_ = true;
+}
+
+void NativeViewHostGtk::UninstallClip() {
+ gtk_widget_shape_combine_mask(host_->native_view(), NULL, 0, 0);
+ installed_clip_ = false;
+}
+
+void NativeViewHostGtk::ShowWidget(int x, int y, int w, int h) {
+ WidgetGtk* parent = static_cast<WidgetGtk*>(host_->GetWidget());
+ parent->PositionChild(host_->native_view(), x, y, w, h);
+ gtk_widget_show(host_->native_view());
+}
+
+void NativeViewHostGtk::HideWidget() {
+ gtk_widget_hide(host_->native_view());
+}
+
+void NativeViewHostGtk::SetFocus() {
+ NOTIMPLEMENTED();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeViewHostGtk, private:
+
+// static
+void NativeViewHostGtk::CallDestroy(GtkObject* object) {
+ View* view = GetViewForNative(GTK_WIDGET(object));
+ if (!view)
+ return;
+
+ return static_cast<NativeViewHost*>(view)->NativeViewDestroyed();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeViewHostWrapper, public:
+
+// static
+NativeViewHostWrapper* NativeViewHostWrapper::CreateWrapper(
+ NativeViewHost* host) {
+ return new NativeViewHostGtk(host);
+}
+
+} // namespace views
diff --git a/views/controls/native_view_host_gtk.h b/views/controls/native/native_view_host_gtk.h
index 1b383af..40a6a65 100644
--- a/views/controls/native_view_host_gtk.h
+++ b/views/controls/native/native_view_host_gtk.h
@@ -8,50 +8,47 @@
#include <gtk/gtk.h>
#include <string>
-#include "views/controls/native_view_host.h"
+#include "base/logging.h"
+#include "views/controls/native/native_view_host_wrapper.h"
namespace views {
-class NativeViewHostGtk : public NativeViewHost {
+class View;
+
+class NativeViewHostGtk : public NativeViewHostWrapper {
public:
- NativeViewHostGtk();
+ explicit NativeViewHostGtk(NativeViewHost* host);
virtual ~NativeViewHostGtk();
// Sets and retrieves the View associated with a particular widget.
+ // TODO(beng): move to NativeViewHost, and have take gfx::NativeViews.
static View* GetViewForNative(GtkWidget* widget);
static void SetViewForNative(GtkWidget* widget, View* view);
- // Attach a widget to this View, making the window it represents
- // subject to sizing according to this View's parent container's Layout
- // Manager's sizing heuristics.
- //
- // This object should be added to the view hierarchy before calling this
- // function, which will expect the parent to be valid.
-
- // TODO: figure out ownership!
- void Attach(gfx::NativeView w);
-
- // Detach the attached widget handle. It will no longer be updated
- void Detach();
-
- protected:
- virtual void ViewHierarchyChanged(bool is_add, View *parent, View *child);
-
- virtual void Focus();
-
- // NativeHostView overrides.
+ // Overridden from NativeViewHostWrapper:
+ virtual void NativeViewAttached();
+ virtual void NativeViewDetaching();
+ virtual void AddedToWidget();
+ virtual void RemovedFromWidget();
virtual void InstallClip(int x, int y, int w, int h);
+ virtual bool HasInstalledClip();
virtual void UninstallClip();
virtual void ShowWidget(int x, int y, int w, int h);
virtual void HideWidget();
+ virtual void SetFocus();
private:
+ // Our associated NativeViewHost.
+ NativeViewHost* host_;
+
+ // Have we installed a region on the gfx::NativeView used to clip to only the
+ // visible portion of the gfx::NativeView ?
+ bool installed_clip_;
+
// Signal handle id for 'destroy' signal.
gulong destroy_signal_id_;
// Invoked from the 'destroy' signal.
- void OnDestroy();
-
static void CallDestroy(GtkObject* object);
DISALLOW_COPY_AND_ASSIGN(NativeViewHostGtk);
@@ -60,3 +57,4 @@ class NativeViewHostGtk : public NativeViewHost {
} // namespace views
#endif // VIEWS_CONTROLS_NATIVE_HOST_VIEW_GTK_H_
+
diff --git a/views/controls/native/native_view_host_win.cc b/views/controls/native/native_view_host_win.cc
new file mode 100644
index 0000000..0cbaaa7
--- /dev/null
+++ b/views/controls/native/native_view_host_win.cc
@@ -0,0 +1,135 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "views/controls/native/native_view_host_win.h"
+
+#include "app/gfx/canvas.h"
+#include "base/logging.h"
+#include "views/controls/native/native_view_host.h"
+#include "views/focus/focus_manager.h"
+#include "views/widget/widget.h"
+
+namespace views {
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeViewHostWin, public:
+
+NativeViewHostWin::NativeViewHostWin(NativeViewHost* host)
+ : host_(host),
+ installed_clip_(false) {
+}
+
+NativeViewHostWin::~NativeViewHostWin() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeViewHostWin, NativeViewHostWrapper implementation:
+
+void NativeViewHostWin::NativeViewAttached() {
+ DCHECK(host_->native_view())
+ << "Impossible detatched tab case; See crbug.com/6316";
+
+ // First hide the new window. We don't want anything to draw (like sub-hwnd
+ // borders), when we change the parent below.
+ ShowWindow(host_->native_view(), SW_HIDE);
+
+ // Need to set the HWND's parent before changing its size to avoid flashing.
+ SetParent(host_->native_view(), host_->GetWidget()->GetNativeView());
+ host_->Layout();
+
+ // Register with the focus manager so the associated view is focused when the
+ // native control gets the focus.
+ View* focus_view = host_->focus_view() ? host_->focus_view() : host_;
+ FocusManager::InstallFocusSubclass(host_->native_view(), focus_view);
+}
+
+void NativeViewHostWin::NativeViewDetaching() {
+ DCHECK(host_->native_view());
+ FocusManager::UninstallFocusSubclass(host_->native_view());
+ installed_clip_ = false;
+}
+
+void NativeViewHostWin::AddedToWidget() {
+ HWND parent_hwnd = GetParent(host_->native_view());
+ HWND widget_hwnd = host_->GetWidget()->GetNativeView();
+ if (parent_hwnd != widget_hwnd)
+ SetParent(host_->native_view(), widget_hwnd);
+ if (host_->IsVisibleInRootView())
+ ShowWindow(host_->native_view(), SW_SHOW);
+ else
+ ShowWindow(host_->native_view(), SW_HIDE);
+ host_->Layout();
+}
+
+void NativeViewHostWin::RemovedFromWidget() {
+ ShowWindow(host_->native_view(), SW_HIDE);
+ SetParent(host_->native_view(), NULL);
+}
+
+void NativeViewHostWin::InstallClip(int x, int y, int w, int h) {
+ HRGN clip_region = CreateRectRgn(x, y, x + w, y + h);
+ // NOTE: SetWindowRgn owns the region (as well as the deleting the
+ // current region), as such we don't delete the old region.
+ SetWindowRgn(host_->native_view(), clip_region, FALSE);
+ installed_clip_ = true;
+}
+
+bool NativeViewHostWin::HasInstalledClip() {
+ return installed_clip_;
+}
+
+void NativeViewHostWin::UninstallClip() {
+ SetWindowRgn(host_->native_view(), 0, FALSE);
+ installed_clip_ = false;
+}
+
+void NativeViewHostWin::ShowWidget(int x, int y, int w, int h) {
+ UINT swp_flags = SWP_DEFERERASE |
+ SWP_NOACTIVATE |
+ SWP_NOCOPYBITS |
+ SWP_NOOWNERZORDER |
+ SWP_NOZORDER;
+ // Only send the SHOWWINDOW flag if we're invisible, to avoid flashing.
+ if (!IsWindowVisible(host_->native_view()))
+ swp_flags = (swp_flags | SWP_SHOWWINDOW) & ~SWP_NOREDRAW;
+
+ if (host_->fast_resize()) {
+ // In a fast resize, we move the window and clip it with SetWindowRgn.
+ RECT win_rect;
+ GetWindowRect(host_->native_view(), &win_rect);
+ gfx::Rect rect(win_rect);
+ SetWindowPos(host_->native_view(), 0, x, y, rect.width(), rect.height(),
+ swp_flags);
+
+ InstallClip(0, 0, w, h);
+ } else {
+ SetWindowPos(host_->native_view(), 0, x, y, w, h, swp_flags);
+ }
+}
+
+void NativeViewHostWin::HideWidget() {
+ if (!IsWindowVisible(host_->native_view()))
+ return; // Currently not visible, nothing to do.
+
+ // The window is currently visible, but its clipped by another view. Hide
+ // it.
+ SetWindowPos(host_->native_view(), 0, 0, 0, 0, 0,
+ SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
+ SWP_NOREDRAW | SWP_NOOWNERZORDER);
+}
+
+void NativeViewHostWin::SetFocus() {
+ ::SetFocus(host_->native_view());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// NativeViewHostWrapper, public:
+
+// static
+NativeViewHostWrapper* NativeViewHostWrapper::CreateWrapper(
+ NativeViewHost* host) {
+ return new NativeViewHostWin(host);
+}
+
+} // namespace views
diff --git a/views/controls/native/native_view_host_win.h b/views/controls/native/native_view_host_win.h
new file mode 100644
index 0000000..51bc616
--- /dev/null
+++ b/views/controls/native/native_view_host_win.h
@@ -0,0 +1,46 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef VIEWS_CONTROLS_HWND_VIEW_H_
+#define VIEWS_CONTROLS_HWND_VIEW_H_
+
+#include "base/logging.h"
+#include "views/controls/native/native_view_host_wrapper.h"
+
+namespace views {
+
+class NativeViewHost;
+
+// A Windows implementation of NativeViewHostWrapper
+class NativeViewHostWin : public NativeViewHostWrapper {
+ public:
+ explicit NativeViewHostWin(NativeViewHost* host);
+ virtual ~NativeViewHostWin();
+
+ // Overridden from NativeViewHostWrapper:
+ virtual void NativeViewAttached();
+ virtual void NativeViewDetaching();
+ virtual void AddedToWidget();
+ virtual void RemovedFromWidget();
+ virtual void InstallClip(int x, int y, int w, int h);
+ virtual bool HasInstalledClip();
+ virtual void UninstallClip();
+ virtual void ShowWidget(int x, int y, int w, int h);
+ virtual void HideWidget();
+ virtual void SetFocus();
+
+ private:
+ // Our associated NativeViewHost.
+ NativeViewHost* host_;
+
+ // Have we installed a region on the gfx::NativeView used to clip to only the
+ // visible portion of the gfx::NativeView ?
+ bool installed_clip_;
+
+ DISALLOW_COPY_AND_ASSIGN(NativeViewHostWin);
+};
+
+} // namespace views
+
+#endif // VIEWS_CONTROLS_HWND_VIEW_H_
diff --git a/views/controls/native/native_view_host_wrapper.h b/views/controls/native/native_view_host_wrapper.h
new file mode 100644
index 0000000..4b14403
--- /dev/null
+++ b/views/controls/native/native_view_host_wrapper.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
+// source code is governed by a BSD-style license that can be found in the
+// LICENSE file.
+
+#ifndef VIEWS_CONTROLS_NATIVE_NATIVE_VIEW_HOST_WRAPPER_H_
+#define VIEWS_CONTROLS_NATIVE_NATIVE_VIEW_HOST_WRAPPER_H_
+
+namespace views {
+
+class NativeViewHost;
+
+// An interface that implemented by an object that wraps a gfx::NativeView on
+// a specific platform, used to perform platform specific operations on that
+// native view when attached, detached, moved and sized.
+class NativeViewHostWrapper {
+ public:
+ // Called when a gfx::NativeView has been attached to the associated
+ // NativeViewHost, allowing the wrapper to perform platform-specific
+ // initialization.
+ virtual void NativeViewAttached() = 0;
+
+ // Called before the attached gfx::NativeView is detached from the
+ // NativeViewHost, allowing the wrapper to perform platform-specific
+ // cleanup.
+ virtual void NativeViewDetaching() = 0;
+
+ // Called when our associated NativeViewHost is added to a View hierarchy
+ // rooted at a valid Widget.
+ virtual void AddedToWidget() = 0;
+
+ // Called when our associated NativeViewHost is removed from a View hierarchy
+ // rooted at a valid Widget.
+ virtual void RemovedFromWidget() = 0;
+
+ // Installs a clip on the gfx::NativeView.
+ virtual void InstallClip(int x, int y, int w, int h) = 0;
+
+ // Whether or not a clip has been installed on the wrapped gfx::NativeView.
+ virtual bool HasInstalledClip() = 0;
+
+ // Removes the clip installed on the gfx::NativeView by way of InstallClip.
+ virtual void UninstallClip() = 0;
+
+ // Shows the gfx::NativeView at the specified position (relative to the parent
+ // native view).
+ virtual void ShowWidget(int x, int y, int w, int h) = 0;
+
+ // Hides the gfx::NativeView. NOTE: this may be invoked when the native view
+ // is already hidden.
+ virtual void HideWidget() = 0;
+
+ // Sets focus to the gfx::NativeView.
+ virtual void SetFocus() = 0;
+
+ // Creates a platform-specific instance of an object implementing this
+ // interface.
+ static NativeViewHostWrapper* CreateWrapper(NativeViewHost* host);
+};
+
+} // namespace views
+
+#endif // VIEWS_CONTROLS_NATIVE_NATIVE_VIEW_HOST_WRAPPER_H_
diff --git a/views/controls/native_control.cc b/views/controls/native_control.cc
index d5293b2..cbb375a 100644
--- a/views/controls/native_control.cc
+++ b/views/controls/native_control.cc
@@ -15,7 +15,7 @@
#include "base/win_util.h"
#include "views/background.h"
#include "views/border.h"
-#include "views/controls/hwnd_view.h"
+#include "views/controls/native/native_view_host.h"
#include "views/focus/focus_manager.h"
#include "views/widget/widget.h"
#include "base/gfx/native_theme.h"
@@ -182,7 +182,7 @@ NativeControl::~NativeControl() {
void NativeControl::ValidateNativeControl() {
if (hwnd_view_ == NULL) {
- hwnd_view_ = new HWNDView();
+ hwnd_view_ = new NativeViewHost;
AddChildView(hwnd_view_);
}
@@ -202,7 +202,7 @@ void NativeControl::ValidateNativeControl() {
void NativeControl::ViewHierarchyChanged(bool is_add, View *parent,
View *child) {
- if (is_add && GetWidget()) {
+ if (is_add && child == this && GetWidget()) {
ValidateNativeControl();
Layout();
}
diff --git a/views/controls/native_control.h b/views/controls/native_control.h
index 22c0fa4..f6f9752 100644
--- a/views/controls/native_control.h
+++ b/views/controls/native_control.h
@@ -15,7 +15,7 @@ class CPoint;
namespace views {
-class HWNDView;
+class NativeViewHost;
class NativeControlContainer;
////////////////////////////////////////////////////////////////////////////////
@@ -111,7 +111,7 @@ class NativeControl : public View {
// This variable is protected to provide subclassers direct access. However
// subclassers should always check for NULL since this variable is only
// initialized in ValidateNativeControl().
- HWNDView* hwnd_view_;
+ NativeViewHost* hwnd_view_;
// Fixed size information. -1 for a size means no fixed size.
int fixed_width_;
diff --git a/views/controls/native_control_gtk.cc b/views/controls/native_control_gtk.cc
index 11781f6..cae4476 100644
--- a/views/controls/native_control_gtk.cc
+++ b/views/controls/native_control_gtk.cc
@@ -10,7 +10,7 @@
namespace views {
-NativeControlGtk::NativeControlGtk() : NativeViewHostGtk() {
+NativeControlGtk::NativeControlGtk() {
}
NativeControlGtk::~NativeControlGtk() {
@@ -38,7 +38,7 @@ void NativeControlGtk::ViewHierarchyChanged(bool is_add, View* parent,
CreateNativeControl();
// Call the base class to hide the view if we're being removed.
- NativeViewHostGtk::ViewHierarchyChanged(is_add, parent, child);
+ NativeViewHost::ViewHierarchyChanged(is_add, parent, child);
}
void NativeControlGtk::VisibilityChanged(View* starting_from, bool is_visible) {
diff --git a/views/controls/native_control_gtk.h b/views/controls/native_control_gtk.h
index fb766c7..2f0ffab 100644
--- a/views/controls/native_control_gtk.h
+++ b/views/controls/native_control_gtk.h
@@ -5,12 +5,12 @@
#ifndef VIEWS_CONTROLS_NATIVE_CONTROL_GTK_H_
#define VIEWS_CONTROLS_NATIVE_CONTROL_GTK_H_
-#include "views/controls/native_view_host_gtk.h"
+#include "views/controls/native/native_view_host.h"
namespace views {
// A View that hosts a native control.
-class NativeControlGtk : public NativeViewHostGtk {
+class NativeControlGtk : public NativeViewHost {
public:
NativeControlGtk();
virtual ~NativeControlGtk();
diff --git a/views/controls/native_control_win.cc b/views/controls/native_control_win.cc
index c1ddadf..eb188af 100644
--- a/views/controls/native_control_win.cc
+++ b/views/controls/native_control_win.cc
@@ -23,11 +23,11 @@ WNDPROC NativeControlWin::original_wndproc_ = NULL;
////////////////////////////////////////////////////////////////////////////////
// NativeControlWin, public:
-NativeControlWin::NativeControlWin() : HWNDView() {
+NativeControlWin::NativeControlWin() {
}
NativeControlWin::~NativeControlWin() {
- HWND hwnd = GetHWND();
+ HWND hwnd = native_view();
if (hwnd) {
// Destroy the hwnd if it still exists. Otherwise we won't have shut things
// down correctly, leading to leaking and crashing if another message
@@ -47,7 +47,7 @@ bool NativeControlWin::ProcessMessage(UINT message, WPARAM w_param,
case WM_CTLCOLORBTN:
case WM_CTLCOLORSTATIC:
*result = GetControlColor(message, reinterpret_cast<HDC>(w_param),
- GetHWND());
+ native_view());
return true;
}
return false;
@@ -59,37 +59,37 @@ bool NativeControlWin::ProcessMessage(UINT message, WPARAM w_param,
void NativeControlWin::SetEnabled(bool enabled) {
if (IsEnabled() != enabled) {
View::SetEnabled(enabled);
- if (GetHWND())
- EnableWindow(GetHWND(), IsEnabled());
+ if (native_view())
+ EnableWindow(native_view(), IsEnabled());
}
}
void NativeControlWin::ViewHierarchyChanged(bool is_add, View* parent,
View* child) {
+ // Call the base class to hide the view if we're being removed.
+ NativeViewHost::ViewHierarchyChanged(is_add, parent, child);
+
// Create the HWND when we're added to a valid Widget. Many controls need a
// parent HWND to function properly.
- if (is_add && GetWidget() && !GetHWND())
+ if (is_add && GetWidget() && !native_view())
CreateNativeControl();
-
- // Call the base class to hide the view if we're being removed.
- HWNDView::ViewHierarchyChanged(is_add, parent, child);
}
void NativeControlWin::VisibilityChanged(View* starting_from, bool is_visible) {
if (!is_visible) {
// We destroy the child control HWND when we become invisible because of the
// performance cost of maintaining many HWNDs.
- HWND hwnd = GetHWND();
+ HWND hwnd = native_view();
Detach();
DestroyWindow(hwnd);
- } else if (!GetHWND()) {
+ } else if (!native_view()) {
CreateNativeControl();
}
}
void NativeControlWin::Focus() {
- DCHECK(GetHWND());
- SetFocus(GetHWND());
+ DCHECK(native_view());
+ SetFocus(native_view());
}
////////////////////////////////////////////////////////////////////////////////
@@ -123,13 +123,13 @@ void NativeControlWin::NativeControlCreated(HWND native_control) {
SetProp(native_control, kNativeControlOriginalWndProcKey, original_wndproc_);
Attach(native_control);
- // GetHWND() is now valid.
+ // native_view() is now valid.
// Update the newly created HWND with any resident enabled state.
- EnableWindow(GetHWND(), IsEnabled());
+ EnableWindow(native_view(), IsEnabled());
// This message ensures that the focus border is shown.
- SendMessage(GetHWND(), WM_CHANGEUISTATE,
+ SendMessage(native_view(), WM_CHANGEUISTATE,
MAKEWPARAM(UIS_CLEAR, UISF_HIDEFOCUS), 0);
}
diff --git a/views/controls/native_control_win.h b/views/controls/native_control_win.h
index 6f9923f..eee4ded8 100644
--- a/views/controls/native_control_win.h
+++ b/views/controls/native_control_win.h
@@ -5,12 +5,12 @@
#ifndef VIEWS_CONTROLS_NATIVE_CONTROL_WIN_H_
#define VIEWS_CONTROLS_NATIVE_CONTROL_WIN_H_
-#include "views/controls/hwnd_view.h"
+#include "views/controls/native/native_view_host.h"
namespace views {
// A View that hosts a native Windows control.
-class NativeControlWin : public HWNDView {
+class NativeControlWin : public NativeViewHost {
public:
static const wchar_t* kNativeControlWinKey;
@@ -60,7 +60,7 @@ class NativeControlWin : public HWNDView {
// MUST be called by the subclass implementation of |CreateNativeControl|
// immediately after creating the control HWND, otherwise it won't be attached
- // to the HWNDView and will be effectively orphaned.
+ // to the NativeViewHost and will be effectively orphaned.
virtual void NativeControlCreated(HWND native_control);
// Returns additional extended style flags. When subclasses call
diff --git a/views/controls/native_view_host.cc b/views/controls/native_view_host.cc
deleted file mode 100644
index 0e00aee..0000000
--- a/views/controls/native_view_host.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// 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/widget/widget.h"
-#include "base/logging.h"
-
-namespace views {
-
-NativeViewHost::NativeViewHost()
- : native_view_(NULL),
- installed_clip_(false),
- fast_resize_(false),
- focus_view_(NULL) {
- // The native widget is placed relative to the root. As such, we need to
- // know when the position of any ancestor changes, or our visibility relative
- // to other views changed as it'll effect our position relative to the root.
- SetNotifyWhenVisibleBoundsInRootChanges(true);
-}
-
-NativeViewHost::~NativeViewHost() {
-}
-
-gfx::Size NativeViewHost::GetPreferredSize() {
- return preferred_size_;
-}
-
-void NativeViewHost::SetPreferredSize(const gfx::Size& size) {
- preferred_size_ = size;
- PreferredSizeChanged();
-}
-
-void NativeViewHost::Layout() {
- if (!native_view_)
- return;
-
- // Since widgets know nothing about the View hierarchy (they are direct
- // children of the Widget that hosts our View hierarchy) they need to be
- // positioned in the coordinate system of the Widget, not the current
- // view.
- gfx::Point top_left;
- ConvertPointToWidget(this, &top_left);
-
- gfx::Rect vis_bounds = GetVisibleBounds();
- bool visible = !vis_bounds.IsEmpty();
-
- if (visible && !fast_resize_) {
- 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_) {
- // The whole widget is visible but we installed a clip on the widget,
- // uninstall it.
- UninstallClip();
- installed_clip_ = false;
- }
- }
-
- if (visible) {
- ShowWidget(top_left.x(), top_left.y(), width(), height());
- } else {
- HideWidget();
- }
-}
-
-void NativeViewHost::VisibilityChanged(View* starting_from, bool is_visible) {
- Layout();
-}
-
-void NativeViewHost::VisibleBoundsInRootChanged() {
- Layout();
-}
-
-} // namespace views
diff --git a/views/controls/native_view_host_gtk.cc b/views/controls/native_view_host_gtk.cc
deleted file mode 100644
index 3f3952d..0000000
--- a/views/controls/native_view_host_gtk.cc
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// 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_gtk.h"
-
-#include <gtk/gtk.h>
-
-#include "base/logging.h"
-#include "views/widget/widget_gtk.h"
-
-namespace views {
-
-NativeViewHostGtk::NativeViewHostGtk()
- : NativeViewHost(),
- destroy_signal_id_(0) {
-}
-
-NativeViewHostGtk::~NativeViewHostGtk() {
-}
-
-// static
-View* NativeViewHostGtk::GetViewForNative(GtkWidget* widget) {
- gpointer user_data = g_object_get_data(G_OBJECT(widget), "chrome-view");
- return static_cast<View*>(user_data);
-}
-
-// static
-void NativeViewHostGtk::SetViewForNative(GtkWidget* widget, View* view) {
- g_object_set_data(G_OBJECT(widget), "chrome-view", view);
-}
-
-void NativeViewHostGtk::Attach(GtkWidget* widget) {
- DCHECK(native_view() == NULL);
- DCHECK(widget);
-
- // Adds a mapping between the GtkWidget and us.
- SetViewForNative(widget, this);
-
- destroy_signal_id_ = g_signal_connect(G_OBJECT(widget), "destroy",
- G_CALLBACK(CallDestroy), NULL);
-
- set_native_view(widget);
-
- // First hide the new window. We don't want anything to draw (like sub-hwnd
- // borders), when we change the parent below.
- gtk_widget_hide(widget);
-
- // Set the parent.
- static_cast<WidgetGtk*>(GetWidget())->AddChild(widget);
- Layout();
-
- // TODO: figure out focus.
- // FocusManager::InstallFocusSubclass(
- // hwnd, associated_focus_view()_ ? associated_focus_view() : this);
-}
-
-void NativeViewHostGtk::Detach() {
- DCHECK(native_view());
-
- g_signal_handler_disconnect(G_OBJECT(native_view()), destroy_signal_id_);
- destroy_signal_id_ = 0;
-
- // TODO: focus.
- // FocusManager::UninstallFocusSubclass(native_view());
- set_native_view(NULL);
- set_installed_clip(false);
-}
-
-void NativeViewHostGtk::ViewHierarchyChanged(bool is_add, View* parent,
- View* child) {
- if (!native_view())
- return;
-
- WidgetGtk* parent_widget = static_cast<WidgetGtk*>(GetWidget());
- if (is_add && parent_widget) {
- GtkWidget* widget_parent = gtk_widget_get_parent(native_view());
- GtkWidget* parent_widget_widget = parent_widget->child_widget_parent();
- if (widget_parent != parent_widget_widget) {
- g_object_ref(native_view());
- if (widget_parent)
- gtk_container_remove(GTK_CONTAINER(widget_parent), native_view());
- gtk_container_add(GTK_CONTAINER(parent_widget_widget), native_view());
- g_object_unref(native_view());
- }
- if (IsVisibleInRootView())
- gtk_widget_show(native_view());
- else
- gtk_widget_hide(native_view());
- Layout();
- } else if (!is_add) {
- gtk_widget_hide(native_view());
- if (parent_widget) {
- gtk_container_remove(GTK_CONTAINER(parent_widget->child_widget_parent()),
- native_view());
- }
- }
-}
-
-void NativeViewHostGtk::Focus() {
- NOTIMPLEMENTED();
-}
-
-void NativeViewHostGtk::InstallClip(int x, int y, int w, int h) {
- DCHECK(w > 0 && h > 0);
-
- bool has_window = (GTK_WIDGET_FLAGS(native_view()) & GTK_NO_WINDOW) == 0;
- if (!has_window) {
- // Clip is only supported on GtkWidgets that have windows. If this becomes
- // an issue (as it may be in the options dialog) we'll need to wrap the
- // widget in a GtkFixed with a window. We have to do this as not all widgets
- // support turning on GTK_NO_WINDOW (for example, buttons don't appear to
- // draw anything when they have a window).
- NOTREACHED();
- return;
- }
- DCHECK(has_window);
- // Unset the current region.
- gdk_window_shape_combine_region(native_view()->window, NULL, 0, 0);
-
- // Set a new region.
- // TODO: using shapes is a bit expensive. Should investigated if there is
- // another more efficient way to accomplish this.
- GdkRectangle clip_rect = { x, y, w, h };
- GdkRegion* clip_region = gdk_region_rectangle(&clip_rect);
- gdk_window_shape_combine_region(native_view()->window, clip_region, x, y);
- gdk_region_destroy(clip_region);
-}
-
-void NativeViewHostGtk::UninstallClip() {
- gtk_widget_shape_combine_mask(native_view(), NULL, 0, 0);
-}
-
-void NativeViewHostGtk::ShowWidget(int x, int y, int w, int h) {
- WidgetGtk* parent = static_cast<WidgetGtk*>(GetWidget());
- parent->PositionChild(native_view(), x, y, w, h);
- gtk_widget_show(native_view());
-}
-
-void NativeViewHostGtk::HideWidget() {
- gtk_widget_hide(native_view());
-}
-
-void NativeViewHostGtk::OnDestroy() {
- set_native_view(NULL);
-}
-
-// static
-void NativeViewHostGtk::CallDestroy(GtkObject* object) {
- View* view = GetViewForNative(GTK_WIDGET(object));
- if (!view)
- return;
-
- return static_cast<NativeViewHostGtk*>(view)->OnDestroy();
-}
-
-} // namespace views
diff --git a/views/controls/scrollbar/native_scroll_bar.cc b/views/controls/scrollbar/native_scroll_bar.cc
index 52ddd91..15cfa8f 100644
--- a/views/controls/scrollbar/native_scroll_bar.cc
+++ b/views/controls/scrollbar/native_scroll_bar.cc
@@ -13,7 +13,7 @@
#include <string>
#include "base/message_loop.h"
-#include "views/controls/hwnd_view.h"
+#include "views/controls/native/native_view_host.h"
#include "views/widget/widget.h"
namespace views {
@@ -231,7 +231,7 @@ void NativeScrollBar::ViewHierarchyChanged(bool is_add, View *parent,
View *child) {
Widget* widget;
if (is_add && (widget = GetWidget()) && !sb_view_) {
- sb_view_ = new HWNDView();
+ sb_view_ = new NativeViewHost;
AddChildView(sb_view_);
sb_container_ = new ScrollBarContainer(this);
sb_view_->Attach(*sb_container_);
diff --git a/views/controls/scrollbar/native_scroll_bar.h b/views/controls/scrollbar/native_scroll_bar.h
index 2747bce..85a0453 100644
--- a/views/controls/scrollbar/native_scroll_bar.h
+++ b/views/controls/scrollbar/native_scroll_bar.h
@@ -11,7 +11,7 @@
namespace views {
-class HWNDView;
+class NativeViewHost;
class ScrollBarContainer;
/////////////////////////////////////////////////////////////////////////////
@@ -53,7 +53,7 @@ class NativeScrollBar : public ScrollBar {
#if defined(OS_WIN)
// The sb_view_ takes care of keeping sb_container in sync with the
// view hierarchy
- HWNDView* sb_view_;
+ NativeViewHost* sb_view_;
#endif // defined(OS_WIN)
// sb_container_ is a custom hwnd that we use to wrap the real
diff --git a/views/controls/separator.cc b/views/controls/separator.cc
index f331ce8..af0962f 100644
--- a/views/controls/separator.cc
+++ b/views/controls/separator.cc
@@ -4,7 +4,7 @@
#include "views/controls/separator.h"
-#include "views/controls/hwnd_view.h"
+#include "views/controls/native/native_view_host.h"
namespace views {
diff --git a/views/controls/table/table_view.cc b/views/controls/table/table_view.cc
index 5650f9f..d114b2d6 100644
--- a/views/controls/table/table_view.cc
+++ b/views/controls/table/table_view.cc
@@ -21,7 +21,7 @@
#include "skia/ext/skia_utils_win.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColorFilter.h"
-#include "views/controls/hwnd_view.h"
+#include "views/controls/native/native_view_host.h"
namespace views {
diff --git a/views/controls/textfield/native_textfield_win.cc b/views/controls/textfield/native_textfield_win.cc
index 33fc104..401116c 100644
--- a/views/controls/textfield/native_textfield_win.cc
+++ b/views/controls/textfield/native_textfield_win.cc
@@ -12,8 +12,8 @@
#include "base/win_util.h"
#include "grit/app_strings.h"
#include "skia/ext/skia_utils_win.h"
-#include "views/controls/hwnd_view.h"
#include "views/controls/menu/menu_win.h"
+#include "views/controls/native/native_view_host.h"
#include "views/controls/textfield/native_textfield_win.h"
#include "views/controls/textfield/textfield.h"
#include "views/focus/focus_util_win.h"
@@ -111,9 +111,9 @@ NativeTextfieldWin::NativeTextfieldWin(Textfield* textfield)
IDS_APP_SELECT_ALL,
l10n_util::GetString(IDS_APP_SELECT_ALL));
- container_view_ = new HWNDView;
+ container_view_ = new NativeViewHost;
textfield_->AddChildView(container_view_);
- container_view_->SetAssociatedFocusView(textfield_);
+ container_view_->set_focus_view(textfield_);
container_view_->Attach(m_hWnd);
}
diff --git a/views/controls/textfield/native_textfield_win.h b/views/controls/textfield/native_textfield_win.h
index 6e8a12f..194614a 100644
--- a/views/controls/textfield/native_textfield_win.h
+++ b/views/controls/textfield/native_textfield_win.h
@@ -17,7 +17,7 @@
namespace views {
-class HWNDView;
+class NativeViewHost;
class Textfield;
static const int kDefaultEditStyle = WS_CHILD | WS_VISIBLE;
@@ -192,7 +192,7 @@ class NativeTextfieldWin
int ime_composition_length_;
// TODO(beng): remove this when we are a subclass of NativeControlWin.
- HWNDView* container_view_;
+ NativeViewHost* container_view_;
COLORREF bg_color_;
diff --git a/views/controls/textfield/textfield.cc b/views/controls/textfield/textfield.cc
index b7d64e6..38f2a80 100644
--- a/views/controls/textfield/textfield.cc
+++ b/views/controls/textfield/textfield.cc
@@ -162,6 +162,7 @@ bool Textfield::IsKeystrokeEnter(const Keystroke& key) {
#if defined(OS_WIN)
return key.key == VK_RETURN;
#else
+ // TODO(port): figure out VK_constants
NOTIMPLEMENTED();
return false;
#endif
@@ -172,6 +173,7 @@ bool Textfield::IsKeystrokeEscape(const Keystroke& key) {
#if defined(OS_WIN)
return key.key == VK_ESCAPE;
#else
+ // TODO(port): figure out VK_constants
NOTIMPLEMENTED();
return false;
#endif
diff --git a/views/focus/focus_manager.h b/views/focus/focus_manager.h
index 92c5480..133c027 100644
--- a/views/focus/focus_manager.h
+++ b/views/focus/focus_manager.h
@@ -29,7 +29,7 @@
// focus. This is used in NativeControl for example, where a View wraps an
// actual native window.
// This is already done for you if you subclass the NativeControl class or if
-// you use the HWNDView class.
+// you use the NativeViewHost class.
//
// When creating a top window, if it derives from WidgetWin, the
// |has_own_focus_manager| of the Init method lets you specify whether that
diff --git a/views/view_unittest.cc b/views/view_unittest.cc
index 2ccf8b5..cd0184e 100644
--- a/views/view_unittest.cc
+++ b/views/view_unittest.cc
@@ -713,7 +713,7 @@ class ButtonTest : public NativeButton {
}
HWND GetHWND() {
- return static_cast<NativeButtonWin*>(native_wrapper_)->GetHWND();
+ return static_cast<NativeButtonWin*>(native_wrapper_)->native_view();
}
};
@@ -723,7 +723,7 @@ class CheckboxTest : public Checkbox {
}
HWND GetHWND() {
- return static_cast<NativeCheckboxWin*>(native_wrapper_)->GetHWND();
+ return static_cast<NativeCheckboxWin*>(native_wrapper_)->native_view();
}
};
diff --git a/views/views.gyp b/views/views.gyp
index 5633572..69ed7a1 100644
--- a/views/views.gyp
+++ b/views/views.gyp
@@ -87,8 +87,6 @@
'controls/button/text_button.h',
'controls/combo_box.cc',
'controls/combo_box.h',
- 'controls/hwnd_view.cc',
- 'controls/hwnd_view.h',
'controls/image_view.cc',
'controls/image_view.h',
'controls/label.cc',
@@ -113,10 +111,13 @@
'controls/native_control_gtk.h',
'controls/native_control_win.cc',
'controls/native_control_win.h',
- 'controls/native_view_host.cc',
- 'controls/native_view_host.h',
- 'controls/native_view_host_gtk.cc',
- 'controls/native_view_host_gtk.h',
+ 'controls/native/native_view_host.cc',
+ 'controls/native/native_view_host.h',
+ 'controls/native/native_view_host_gtk.cc',
+ 'controls/native/native_view_host_gtk.h',
+ 'controls/native/native_view_host_win.cc',
+ 'controls/native/native_view_host_win.h',
+ 'controls/native/native_view_host_wrapper.h',
'controls/scroll_view.cc',
'controls/scroll_view.h',
'controls/scrollbar/bitmap_scroll_bar.cc',