diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-11 21:59:06 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-11 21:59:06 +0000 |
commit | 1558020441c8b594993252707f610dc2de481bad (patch) | |
tree | 2f5e0ea5af1965f9820c2979e7b79237ba17ef53 /views/controls | |
parent | b6ca264f3c8d6b010e92774f1ef508dc3c39604e (diff) | |
download | chromium_src-1558020441c8b594993252707f610dc2de481bad.zip chromium_src-1558020441c8b594993252707f610dc2de481bad.tar.gz chromium_src-1558020441c8b594993252707f610dc2de481bad.tar.bz2 |
Adds back some code removed during Ben's landing of views renaming.
Adds support for GTK buttons.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/113212
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15793 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/controls')
-rw-r--r-- | views/controls/button/native_button_gtk.cc | 95 | ||||
-rw-r--r-- | views/controls/button/native_button_gtk.h | 46 | ||||
-rw-r--r-- | views/controls/native_control_gtk.cc | 70 | ||||
-rw-r--r-- | views/controls/native_control_gtk.h | 42 | ||||
-rw-r--r-- | views/controls/native_view_host_gtk.cc | 121 | ||||
-rw-r--r-- | views/controls/native_view_host_gtk.h | 49 |
6 files changed, 423 insertions, 0 deletions
diff --git a/views/controls/button/native_button_gtk.cc b/views/controls/button/native_button_gtk.cc new file mode 100644 index 0000000..e140b21 --- /dev/null +++ b/views/controls/button/native_button_gtk.cc @@ -0,0 +1,95 @@ +// 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 <gtk/gtk.h> + +#include "views/controls/button/native_button_gtk.h" + +#include "base/logging.h" +#include "base/string_util.h" +#include "views/controls/button/checkbox.h" +#include "views/controls/button/native_button.h" +#include "views/controls/button/radio_button.h" +#include "views/widget/widget.h" + +namespace views { + +NativeButtonGtk::NativeButtonGtk(NativeButton* native_button) + : NativeControlGtk(), + native_button_(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); +} + +NativeButtonGtk::~NativeButtonGtk() { +} + +void NativeButtonGtk::UpdateLabel() { + if (!native_view()) + return; + + gtk_button_set_label(GTK_BUTTON(native_view()), + WideToUTF8(native_button_->label()).c_str()); +} + +void NativeButtonGtk::UpdateFont() { + if (!native_view()) + return; + + NOTIMPLEMENTED(); + // SendMessage(GetHWND(), WM_SETFONT, + // reinterpret_cast<WPARAM>(native_button_->font().hfont()), + // FALSE); +} + +void NativeButtonGtk::UpdateEnabled() { + if (!native_view()) + return; + SetEnabled(native_button_->IsEnabled()); +} + +void NativeButtonGtk::UpdateDefault() { + if (!native_view()) + return; + if (!IsCheckbox()) + NOTIMPLEMENTED(); +} + +View* NativeButtonGtk::GetView() { + return this; +} + +void NativeButtonGtk::SetFocus() { + // Focus the associated widget. + Focus(); +} + +gfx::Size NativeButtonGtk::GetPreferredSize() { + GtkRequisition size_request = { 0, 0 }; + gtk_widget_size_request(native_view(), &size_request); + return gfx::Size(size_request.width, size_request.height); +} + +void NativeButtonGtk::CreateNativeControl() { + GtkWidget* widget = gtk_button_new(); + NativeControlCreated(widget); +} + +void NativeButtonGtk::NativeControlCreated(GtkWidget* widget) { + NativeControlGtk::NativeControlCreated(widget); + + UpdateFont(); + UpdateLabel(); + UpdateDefault(); +} + +// static +NativeButtonWrapper* NativeButtonWrapper::CreateNativeButtonWrapper( + NativeButton* native_button) { + return new NativeButtonGtk(native_button); +} + +} // namespace views diff --git a/views/controls/button/native_button_gtk.h b/views/controls/button/native_button_gtk.h new file mode 100644 index 0000000..e76a703 --- /dev/null +++ b/views/controls/button/native_button_gtk.h @@ -0,0 +1,46 @@ +// 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_BUTTON_NATIVE_BUTTON_GTK_H_ +#define VIEWS_CONTROLS_BUTTON_NATIVE_BUTTON_GTK_H_ + +#include "views/controls/button/native_button_wrapper.h" +#include "views/controls/native_control_gtk.h" + +namespace views { + +// A View that hosts a native GTK button. +class NativeButtonGtk : public NativeControlGtk, public NativeButtonWrapper { + public: + explicit NativeButtonGtk(NativeButton* native_button); + virtual ~NativeButtonGtk(); + + // Overridden from NativeButtonWrapper: + virtual void UpdateLabel(); + virtual void UpdateFont(); + virtual void UpdateEnabled(); + virtual void UpdateDefault(); + virtual View* GetView(); + virtual void SetFocus(); + + // Overridden from View: + virtual gfx::Size GetPreferredSize(); + + protected: + virtual void CreateNativeControl(); + virtual void NativeControlCreated(GtkWidget* widget); + + // Returns true if this button is actually a checkbox or radio button. + virtual bool IsCheckbox() const { return false; } + + private: + // The NativeButton we are bound to. + NativeButton* native_button_; + + DISALLOW_COPY_AND_ASSIGN(NativeButtonGtk); +}; + +} // namespace views + +#endif // #ifndef VIEWS_CONTROLS_BUTTON_NATIVE_BUTTON_GTK_H_ diff --git a/views/controls/native_control_gtk.cc b/views/controls/native_control_gtk.cc new file mode 100644 index 0000000..3cf6438 --- /dev/null +++ b/views/controls/native_control_gtk.cc @@ -0,0 +1,70 @@ +// #ifndef CHROME_VIEWS_NATIVE_CONTROL_WIN_H_// 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_control_gtk.h" + +#include <gtk/gtk.h> + +#include "base/logging.h" + +namespace views { + +static const char* kNativeControlGtkKey = "__NATIVE_CONTROL_GTK__"; + +NativeControlGtk::NativeControlGtk() { +} + +NativeControlGtk::~NativeControlGtk() { + DCHECK(!native_view()); +} + +//////////////////////////////////////////////////////////////////////////////// +// NativeControlGtk, View overrides: + +void NativeControlGtk::SetEnabled(bool enabled) { + NOTIMPLEMENTED(); + if (IsEnabled() != enabled) { + View::SetEnabled(enabled); + if (native_view()) + gtk_widget_set_sensitive(native_view(), IsEnabled()); + } +} + +void NativeControlGtk::ViewHierarchyChanged(bool is_add, View* parent, + View* child) { + // Create the widget when we're added to a valid Widget. Many controls need a + // parent widget to function properly. + if (is_add && GetWidget() && !native_view()) + CreateNativeControl(); + + // Call the base class to hide the view if we're being removed. + NativeViewHostGtk::ViewHierarchyChanged(is_add, parent, child); +} + +void NativeControlGtk::VisibilityChanged(View* starting_from, bool is_visible) { + if (!is_visible) { + // We destroy the child widget when we become invisible because of the + // performance cost of maintaining widgets that aren't currently needed. + Detach(); + } else if (!native_view()) { + CreateNativeControl(); + } +} + +void NativeControlGtk::Focus() { + DCHECK(native_view()); + NOTIMPLEMENTED(); +} + +void NativeControlGtk::NativeControlCreated(GtkWidget* native_control) { + // Adds a mapping between the GtkWidget and us. + g_object_set_data(G_OBJECT(native_control), kNativeControlGtkKey, this); + + Attach(native_control); + + // Update the newly created GtkWdigetwith any resident enabled state. + gtk_widget_set_sensitive(native_view(), IsEnabled()); +} + +} // namespace views diff --git a/views/controls/native_control_gtk.h b/views/controls/native_control_gtk.h new file mode 100644 index 0000000..fb766c7 --- /dev/null +++ b/views/controls/native_control_gtk.h @@ -0,0 +1,42 @@ +// 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_CONTROL_GTK_H_ +#define VIEWS_CONTROLS_NATIVE_CONTROL_GTK_H_ + +#include "views/controls/native_view_host_gtk.h" + +namespace views { + +// A View that hosts a native control. +class NativeControlGtk : public NativeViewHostGtk { + public: + NativeControlGtk(); + virtual ~NativeControlGtk(); + + // Overridden from View: + virtual void SetEnabled(bool enabled); + + protected: + virtual void ViewHierarchyChanged(bool is_add, View *parent, View *child); + virtual void VisibilityChanged(View* starting_from, bool is_visible); + virtual void Focus(); + + // Called when the NativeControlGtk is attached to a View hierarchy with a + // valid Widget. The NativeControlGtk should use this opportunity to create + // its associated GtkWidget. + virtual void CreateNativeControl() = 0; + + // MUST be called by the subclass implementation of |CreateNativeControl| + // immediately after creating the control GtkWidget, otherwise it won't be + // attached to the GtkView and will be effectively orphaned. + virtual void NativeControlCreated(GtkWidget* widget); + + private: + DISALLOW_COPY_AND_ASSIGN(NativeControlGtk); +}; + +} // namespace views + +#endif // #ifndef VIEWS_CONTROLS_NATIVE_CONTROL_GTK_H_ diff --git a/views/controls/native_view_host_gtk.cc b/views/controls/native_view_host_gtk.cc new file mode 100644 index 0000000..5f6b8a3 --- /dev/null +++ b/views/controls/native_view_host_gtk.cc @@ -0,0 +1,121 @@ +// 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() { +} + +NativeViewHostGtk::~NativeViewHostGtk() { +} + +void NativeViewHostGtk::Attach(GtkWidget* widget) { + DCHECK(native_view() == NULL); + DCHECK(widget); + + 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()); + // 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()); +} + +} // namespace views diff --git a/views/controls/native_view_host_gtk.h b/views/controls/native_view_host_gtk.h new file mode 100644 index 0000000..d8a134d --- /dev/null +++ b/views/controls/native_view_host_gtk.h @@ -0,0 +1,49 @@ +// 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_HOST_VIEW_GTK_H_ +#define VIEWS_CONTROLS_NATIVE_HOST_VIEW_GTK_H_ + +#include <string> + +#include "views/controls/native_view_host.h" + +namespace views { + +class NativeViewHostGtk : public NativeViewHost { + public: + NativeViewHostGtk(); + virtual ~NativeViewHostGtk(); + + // 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. + 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(NativeViewHostGtk); +}; + +} // namespace views + +#endif // VIEWS_CONTROLS_NATIVE_HOST_VIEW_GTK_H_ |