OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "views/widget/gtk_views_fixed.h" | 5 #include "views/widget/gtk_views_fixed.h" |
6 | 6 |
| 7 #include "base/logging.h" |
| 8 |
7 // We store whether we use the widget's allocated size as a property. Ideally | 9 // We store whether we use the widget's allocated size as a property. Ideally |
8 // we would stash this in GtkFixedChild, but GtkFixed doesn't allow subclassing | 10 // we would stash this in GtkFixedChild, but GtkFixed doesn't allow subclassing |
9 // gtk_fixed_put. Alternatively we could subclass GtkContainer and use our own | 11 // gtk_fixed_put. Alternatively we could subclass GtkContainer and use our own |
10 // API (effectively duplicating GtkFixed), but that means folks could no longer | 12 // API (effectively duplicating GtkFixed), but that means folks could no longer |
11 // use the GtkFixed API else where in Chrome. For now I'm going with this route. | 13 // use the GtkFixed API else where in Chrome. For now I'm going with this route. |
12 static const char* kUseAllocatedSize = "__VIEWS_USE_ALLOCATED_SIZE__"; | 14 static const char* kUseAllocatedSize = "__VIEWS_USE_ALLOCATED_SIZE__"; |
| 15 static const char* kRequisitionWidth = "__VIEWS_REQUISITION_WIDTH__"; |
| 16 static const char* kRequisitionHeight = "__VIEWS_REQUISITION_HEIGHT__"; |
13 | 17 |
14 G_BEGIN_DECLS | 18 G_BEGIN_DECLS |
15 | 19 |
16 G_DEFINE_TYPE(GtkViewsFixed, gtk_views_fixed, GTK_TYPE_FIXED) | 20 G_DEFINE_TYPE(GtkViewsFixed, gtk_views_fixed, GTK_TYPE_FIXED) |
17 | 21 |
18 static void gtk_views_fixed_size_allocate(GtkWidget* widget, | 22 static void gtk_views_fixed_size_allocate(GtkWidget* widget, |
19 GtkAllocation* allocation) { | 23 GtkAllocation* allocation) { |
20 widget->allocation = *allocation; | 24 widget->allocation = *allocation; |
21 if (!GTK_WIDGET_NO_WINDOW(widget) && GTK_WIDGET_REALIZED(widget)) { | 25 if (!GTK_WIDGET_NO_WINDOW(widget) && GTK_WIDGET_REALIZED(widget)) { |
22 gdk_window_move_resize(widget->window, allocation->x, allocation->y, | 26 gdk_window_move_resize(widget->window, allocation->x, allocation->y, |
23 allocation->width, allocation->height); | 27 allocation->width, allocation->height); |
24 } | 28 } |
25 | 29 |
26 int border_width = GTK_CONTAINER(widget)->border_width; | 30 int border_width = GTK_CONTAINER(widget)->border_width; |
27 GList* children = GTK_FIXED(widget)->children; | 31 GList* children = GTK_FIXED(widget)->children; |
28 while (children) { | 32 while (children) { |
29 GtkFixedChild* child = reinterpret_cast<GtkFixedChild*>(children->data); | 33 GtkFixedChild* child = reinterpret_cast<GtkFixedChild*>(children->data); |
30 children = children->next; | 34 children = children->next; |
31 | 35 |
32 if (GTK_WIDGET_VISIBLE(child->widget)) { | 36 if (GTK_WIDGET_VISIBLE(child->widget)) { |
33 GtkAllocation child_allocation; | 37 GtkAllocation child_allocation; |
34 | 38 |
35 gpointer use_allocated_size = g_object_get_data(G_OBJECT(child->widget), | 39 int width, height; |
36 kUseAllocatedSize); | 40 bool use_allocated_size = |
| 41 gtk_views_fixed_get_widget_size(child->widget, &width, &height); |
37 if (use_allocated_size) { | 42 if (use_allocated_size) { |
38 // NOTE: even though the size isn't changing, we have to call | 43 // NOTE: even though the size isn't changing, we have to call |
39 // size_allocate, otherwise things like buttons won't repaint. | 44 // size_allocate, otherwise things like buttons won't repaint. |
40 child_allocation.width = child->widget->allocation.width; | 45 child_allocation.width = width; |
41 child_allocation.height = child->widget->allocation.height; | 46 child_allocation.height = height; |
42 } else { | 47 } else { |
43 GtkRequisition child_requisition; | 48 GtkRequisition child_requisition; |
44 gtk_widget_get_child_requisition(child->widget, &child_requisition); | 49 gtk_widget_get_child_requisition(child->widget, &child_requisition); |
45 child_allocation.width = child_requisition.width; | 50 child_allocation.width = child_requisition.width; |
46 child_allocation.height = child_requisition.height; | 51 child_allocation.height = child_requisition.height; |
47 } | 52 } |
48 child_allocation.x = child->x + border_width; | 53 child_allocation.x = child->x + border_width; |
49 child_allocation.y = child->y + border_width; | 54 child_allocation.y = child->y + border_width; |
50 | 55 |
51 if (GTK_WIDGET_NO_WINDOW(widget)) { | 56 if (GTK_WIDGET_NO_WINDOW(widget)) { |
(...skipping 12 matching lines...) Expand all Loading... |
64 widget_class->size_allocate = gtk_views_fixed_size_allocate; | 69 widget_class->size_allocate = gtk_views_fixed_size_allocate; |
65 } | 70 } |
66 | 71 |
67 static void gtk_views_fixed_init(GtkViewsFixed* fixed) { | 72 static void gtk_views_fixed_init(GtkViewsFixed* fixed) { |
68 } | 73 } |
69 | 74 |
70 GtkWidget* gtk_views_fixed_new(void) { | 75 GtkWidget* gtk_views_fixed_new(void) { |
71 return GTK_WIDGET(g_object_new(GTK_TYPE_VIEWS_FIXED, NULL)); | 76 return GTK_WIDGET(g_object_new(GTK_TYPE_VIEWS_FIXED, NULL)); |
72 } | 77 } |
73 | 78 |
74 void gtk_views_fixed_set_use_allocated_size(GtkWidget* widget, bool value) { | 79 void gtk_views_fixed_set_widget_size(GtkWidget* widget, |
| 80 int width, int height) { |
| 81 // Remember the allocation request, and set this widget up to use it. |
| 82 bool use_requested_size = (width != 0 && height != 0); |
75 g_object_set_data(G_OBJECT(widget), kUseAllocatedSize, | 83 g_object_set_data(G_OBJECT(widget), kUseAllocatedSize, |
76 reinterpret_cast<gpointer>(value ? 1 : 0)); | 84 reinterpret_cast<gpointer>(use_requested_size ? 1 : 0)); |
| 85 g_object_set_data(G_OBJECT(widget), kRequisitionWidth, |
| 86 reinterpret_cast<gpointer>(width)); |
| 87 g_object_set_data(G_OBJECT(widget), kRequisitionHeight, |
| 88 reinterpret_cast<gpointer>(height)); |
| 89 |
| 90 gtk_widget_queue_resize(widget); |
| 91 } |
| 92 |
| 93 bool gtk_views_fixed_get_widget_size(GtkWidget* widget, |
| 94 int* width, int* height) { |
| 95 DCHECK(width); |
| 96 DCHECK(height); |
| 97 *width = reinterpret_cast<glong>(g_object_get_data(G_OBJECT(widget), |
| 98 kRequisitionWidth)); |
| 99 *height = reinterpret_cast<glong>(g_object_get_data(G_OBJECT(widget), |
| 100 kRequisitionHeight)); |
| 101 return (g_object_get_data(G_OBJECT(widget), kUseAllocatedSize) != 0); |
77 } | 102 } |
78 | 103 |
79 G_END_DECLS | 104 G_END_DECLS |
OLD | NEW |