diff options
-rw-r--r-- | views/controls/button/native_button.cc | 8 | ||||
-rw-r--r-- | views/views.gyp | 2 | ||||
-rw-r--r-- | views/widget/gtk_views_fixed.cc | 79 | ||||
-rw-r--r-- | views/widget/gtk_views_fixed.h | 49 | ||||
-rw-r--r-- | views/widget/widget_gtk.cc | 12 |
5 files changed, 143 insertions, 7 deletions
diff --git a/views/controls/button/native_button.cc b/views/controls/button/native_button.cc index a8f22dd..141cf328 100644 --- a/views/controls/button/native_button.cc +++ b/views/controls/button/native_button.cc @@ -16,13 +16,17 @@ namespace views { -static const int kButtonBorderHWidth = 8; - #if defined(OS_WIN) // The min size in DLUs comes from // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwue/html/ch14e.asp static const int kMinWidthDLUs = 50; static const int kMinHeightDLUs = 14; + +// Horizontal padding (on each side). +static const int kButtonBorderHWidth = 8; +#else +// Horizontal padding (on each side). +static const int kButtonBorderHWidth = 0; #endif // static diff --git a/views/views.gyp b/views/views.gyp index 11058f1..dc0de4d 100644 --- a/views/views.gyp +++ b/views/views.gyp @@ -254,6 +254,8 @@ 'widget/drop_target_gtk.h', 'widget/drop_target_win.cc', 'widget/drop_target_win.h', + 'widget/gtk_views_fixed.cc', + 'widget/gtk_views_fixed.h', 'widget/root_view.cc', 'widget/root_view.h', 'widget/root_view_gtk.cc', diff --git a/views/widget/gtk_views_fixed.cc b/views/widget/gtk_views_fixed.cc new file mode 100644 index 0000000..0b322bb --- /dev/null +++ b/views/widget/gtk_views_fixed.cc @@ -0,0 +1,79 @@ +// 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/widget/gtk_views_fixed.h" + +// We store whether we use the widget's allocated size as a property. Ideally +// we would stash this in GtkFixedChild, but GtkFixed doesn't allow subclassing +// gtk_fixed_put. Alternatively we could subclass GtkContainer and use our own +// API (effectively duplicating GtkFixed), but that means folks could no longer +// use the GtkFixed API else where in Chrome. For now I'm going with this route. +static const char* kUseAllocatedSize = "__VIEWS_USE_ALLOCATED_SIZE__"; + +G_BEGIN_DECLS + +G_DEFINE_TYPE(GtkViewsFixed, gtk_views_fixed, GTK_TYPE_FIXED) + +static void gtk_views_fixed_size_allocate(GtkWidget* widget, + GtkAllocation* allocation) { + widget->allocation = *allocation; + if (!GTK_WIDGET_NO_WINDOW(widget) && GTK_WIDGET_REALIZED(widget)) { + gdk_window_move_resize(widget->window, allocation->x, allocation->y, + allocation->width, allocation->height); + } + + int border_width = GTK_CONTAINER(widget)->border_width; + GList* children = GTK_FIXED(widget)->children; + while (children) { + GtkFixedChild* child = reinterpret_cast<GtkFixedChild*>(children->data); + children = children->next; + + if (GTK_WIDGET_VISIBLE(child->widget)) { + GtkAllocation child_allocation; + + gpointer use_allocated_size = g_object_get_data(G_OBJECT(child->widget), + kUseAllocatedSize); + if (use_allocated_size) { + // NOTE: even though the size isn't changing, we have to call + // size_allocate, otherwise things like buttons won't repaint. + child_allocation.width = child->widget->allocation.width; + child_allocation.height = child->widget->allocation.height; + } else { + GtkRequisition child_requisition; + gtk_widget_get_child_requisition(child->widget, &child_requisition); + child_allocation.width = child_requisition.width; + child_allocation.height = child_requisition.height; + } + child_allocation.x = child->x + border_width; + child_allocation.y = child->y + border_width; + + if (GTK_WIDGET_NO_WINDOW(widget)) { + child_allocation.x += widget->allocation.x; + child_allocation.y += widget->allocation.y; + } + + gtk_widget_size_allocate(child->widget, &child_allocation); + } + } +} + +static void gtk_views_fixed_class_init(GtkViewsFixedClass* views_fixed_class) { + GtkWidgetClass* widget_class = + reinterpret_cast<GtkWidgetClass*>(views_fixed_class); + widget_class->size_allocate = gtk_views_fixed_size_allocate; +} + +static void gtk_views_fixed_init(GtkViewsFixed* fixed) { +} + +GtkWidget* gtk_views_fixed_new(void) { + return GTK_WIDGET(g_object_new(GTK_TYPE_VIEWS_FIXED, NULL)); +} + +void gtk_views_fixed_set_use_allocated_size(GtkWidget* widget, bool value) { + g_object_set_data(G_OBJECT(widget), kUseAllocatedSize, + reinterpret_cast<gpointer>(value ? 1 : 0)); +} + +G_END_DECLS diff --git a/views/widget/gtk_views_fixed.h b/views/widget/gtk_views_fixed.h new file mode 100644 index 0000000..8fa3b80 --- /dev/null +++ b/views/widget/gtk_views_fixed.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_WIDGET_GTK_VIEWS_FIXED_H_ +#define VIEWS_WIDGET_GTK_VIEWS_FIXED_H_ + +#include <gdk/gdk.h> +#include <gtk/gtkfixed.h> + +// GtkViewsFixed is a subclass of GtkFixed that can give child widgets their +// current size rather than their requested size. This behavior is controlled +// by gtk_views_fixed_set_use_allocated_size; the default is to use the +// Widget's requested size. + +G_BEGIN_DECLS + +#define GTK_TYPE_VIEWS_FIXED (gtk_views_fixed_get_type ()) +#define GTK_VIEWS_FIXED(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_VIEWS_FIXED, GtkViewsFixed)) +#define GTK_VIEWS_FIXED_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_VIEWS_FIXED, GtkViewsFixedClass)) +#define GTK_IS_VIEWS_FIXED(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_VIEWS_FIXED)) +#define GTK_IS_VIEWS_FIXED_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_VIEWS_FIXED)) +#define GTK_VIEWS_FIXED_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_VIEWS_FIXED, GtkViewsFixed)) + +typedef struct _GtkViewsFixed GtkViewsFixed; +typedef struct _GtkViewsFixedClass GtkViewsFixedClass; + +struct _GtkViewsFixed { + GtkFixed fixed; +}; + +struct _GtkViewsFixedClass { + GtkFixedClass parent_class; +}; + +GtkWidget* gtk_views_fixed_new(); + +GType gtk_views_fixed_get_type(); + +void gtk_views_fixed_set_use_allocated_size(GtkWidget* widget, bool value); + +G_END_DECLS + +#endif // VIEWS_WIDGET_GTK_VIEWS_FIXED_H diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc index 4cb54a5..8274e2d 100644 --- a/views/widget/widget_gtk.cc +++ b/views/widget/widget_gtk.cc @@ -14,6 +14,7 @@ #include "base/string_util.h" #include "views/widget/default_theme_provider.h" #include "views/widget/drop_target_gtk.h" +#include "views/widget/gtk_views_fixed.h" #include "views/widget/root_view.h" #include "views/widget/tooltip_manager_gtk.h" #include "views/window/window_gtk.h" @@ -149,8 +150,10 @@ void WidgetGtk::RemoveChild(GtkWidget* child) { // We can be called after the contents widget has been destroyed, e.g. any // NativeViewHost not removed from the view hierarchy before the window is // closed. - if (GTK_IS_CONTAINER(window_contents_)) + if (GTK_IS_CONTAINER(window_contents_)) { gtk_container_remove(GTK_CONTAINER(window_contents_), child); + gtk_views_fixed_set_use_allocated_size(child, false); + } } void WidgetGtk::ReparentChild(GtkWidget* child) { @@ -159,9 +162,8 @@ void WidgetGtk::ReparentChild(GtkWidget* child) { void WidgetGtk::PositionChild(GtkWidget* child, int x, int y, int w, int h) { GtkAllocation alloc = { x, y, w, h }; - // For some reason we need to do both of these to size a widget. gtk_widget_size_allocate(child, &alloc); - gtk_widget_set_size_request(child, w, h); + gtk_views_fixed_set_use_allocated_size(child, true); gtk_fixed_move(GTK_FIXED(window_contents_), child, x, y); } @@ -1165,7 +1167,7 @@ void WidgetGtk::CreateGtkWidget(GtkWidget* parent, const gfx::Rect& bounds) { // that if we use GTK's double buffering and we tried to expand the dirty // region, it wouldn't get painted. if (type_ == TYPE_CHILD) { - window_contents_ = widget_ = gtk_fixed_new(); + window_contents_ = widget_ = gtk_views_fixed_new(); gtk_widget_set_name(widget_, "views-gtkwidget-child-fixed"); GTK_WIDGET_UNSET_FLAGS(widget_, GTK_DOUBLE_BUFFERED); gtk_fixed_set_has_window(GTK_FIXED(widget_), true); @@ -1200,7 +1202,7 @@ void WidgetGtk::CreateGtkWidget(GtkWidget* parent, const gfx::Rect& bounds) { } SetWindowForNative(widget_, static_cast<WindowGtk*>(this)); - window_contents_ = gtk_fixed_new(); + window_contents_ = gtk_views_fixed_new(); gtk_widget_set_name(window_contents_, "views-gtkwidget-window-fixed"); GTK_WIDGET_UNSET_FLAGS(window_contents_, GTK_DOUBLE_BUFFERED); gtk_fixed_set_has_window(GTK_FIXED(window_contents_), true); |