Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: ui/base/gtk/gtk_floating_container.cc

Issue 231733005: Delete the GTK+ port of Chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remerge to ToT Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/base/gtk/gtk_floating_container.h"
6
7 #include <gtk/gtk.h>
8
9 #include <algorithm>
10
11 #include "ui/gfx/gtk_compat.h"
12
13 namespace {
14
15 enum {
16 SET_FLOATING_POSITION,
17 LAST_SIGNAL
18 };
19
20 enum {
21 CHILD_PROP_0,
22 CHILD_PROP_X,
23 CHILD_PROP_Y
24 };
25
26 // Returns the GtkFloatingContainerChild associated with |widget| (or NULL if
27 // |widget| not found).
28 GtkFloatingContainerChild* GetChild(GtkFloatingContainer* container,
29 GtkWidget* widget) {
30 for (GList* floating_children = container->floating_children;
31 floating_children; floating_children = g_list_next(floating_children)) {
32 GtkFloatingContainerChild* child =
33 reinterpret_cast<GtkFloatingContainerChild*>(floating_children->data);
34
35 if (child->widget == widget)
36 return child;
37 }
38
39 return NULL;
40 }
41
42 const GParamFlags kStaticReadWriteProp = static_cast<GParamFlags>(
43 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
44
45 } // namespace
46
47 G_BEGIN_DECLS
48
49 static void gtk_floating_container_remove(GtkContainer* container,
50 GtkWidget* widget);
51 static void gtk_floating_container_forall(GtkContainer* container,
52 gboolean include_internals,
53 GtkCallback callback,
54 gpointer callback_data);
55 static void gtk_floating_container_size_request(GtkWidget* widget,
56 GtkRequisition* requisition);
57 static void gtk_floating_container_size_allocate(GtkWidget* widget,
58 GtkAllocation* allocation);
59 static void gtk_floating_container_set_child_property(GtkContainer* container,
60 GtkWidget* child,
61 guint property_id,
62 const GValue* value,
63 GParamSpec* pspec);
64 static void gtk_floating_container_get_child_property(GtkContainer* container,
65 GtkWidget* child,
66 guint property_id,
67 GValue* value,
68 GParamSpec* pspec);
69
70 static guint floating_container_signals[LAST_SIGNAL] = { 0 };
71
72 G_DEFINE_TYPE(GtkFloatingContainer, gtk_floating_container, GTK_TYPE_BIN)
73
74 static void gtk_floating_container_class_init(
75 GtkFloatingContainerClass *klass) {
76 GtkObjectClass* object_class =
77 reinterpret_cast<GtkObjectClass*>(klass);
78
79 GtkWidgetClass* widget_class =
80 reinterpret_cast<GtkWidgetClass*>(klass);
81 widget_class->size_request = gtk_floating_container_size_request;
82 widget_class->size_allocate = gtk_floating_container_size_allocate;
83
84 GtkContainerClass* container_class =
85 reinterpret_cast<GtkContainerClass*>(klass);
86 container_class->remove = gtk_floating_container_remove;
87 container_class->forall = gtk_floating_container_forall;
88
89 container_class->set_child_property =
90 gtk_floating_container_set_child_property;
91 container_class->get_child_property =
92 gtk_floating_container_get_child_property;
93
94 gtk_container_class_install_child_property(
95 container_class,
96 CHILD_PROP_X,
97 g_param_spec_int("x",
98 "X position",
99 "X position of child widget",
100 G_MININT,
101 G_MAXINT,
102 0,
103 kStaticReadWriteProp));
104
105 gtk_container_class_install_child_property(
106 container_class,
107 CHILD_PROP_Y,
108 g_param_spec_int("y",
109 "Y position",
110 "Y position of child widget",
111 G_MININT,
112 G_MAXINT,
113 0,
114 kStaticReadWriteProp));
115
116 floating_container_signals[SET_FLOATING_POSITION] =
117 g_signal_new("set-floating-position",
118 G_OBJECT_CLASS_TYPE(object_class),
119 static_cast<GSignalFlags>(G_SIGNAL_RUN_FIRST |
120 G_SIGNAL_ACTION),
121 0,
122 NULL, NULL,
123 g_cclosure_marshal_VOID__BOXED,
124 G_TYPE_NONE, 1,
125 GDK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
126 }
127
128 static void gtk_floating_container_init(GtkFloatingContainer* container) {
129 gtk_widget_set_has_window(GTK_WIDGET(container), FALSE);
130 container->floating_children = NULL;
131 }
132
133 static void gtk_floating_container_remove(GtkContainer* container,
134 GtkWidget* widget) {
135 g_return_if_fail(GTK_IS_WIDGET(widget));
136
137 GtkBin* bin = GTK_BIN(container);
138 if (gtk_bin_get_child(bin) == widget) {
139 ((GTK_CONTAINER_CLASS(gtk_floating_container_parent_class))->remove)
140 (container, widget);
141 } else {
142 // Handle the other case where it's in our |floating_children| list.
143 GtkFloatingContainer* floating = GTK_FLOATING_CONTAINER(container);
144 GList* children = floating->floating_children;
145 gboolean removed_child = false;
146 while (children) {
147 GtkFloatingContainerChild* child =
148 reinterpret_cast<GtkFloatingContainerChild*>(children->data);
149
150 if (child->widget == widget) {
151 removed_child = true;
152 gboolean was_visible = gtk_widget_get_visible(GTK_WIDGET(widget));
153
154 gtk_widget_unparent(widget);
155
156 floating->floating_children =
157 g_list_remove_link(floating->floating_children, children);
158 g_list_free(children);
159 g_free(child);
160
161 if (was_visible && gtk_widget_get_visible(GTK_WIDGET(container)))
162 gtk_widget_queue_resize(GTK_WIDGET(container));
163
164 break;
165 }
166 children = children->next;
167 }
168
169 g_return_if_fail(removed_child);
170 }
171 }
172
173 static void gtk_floating_container_forall(GtkContainer* container,
174 gboolean include_internals,
175 GtkCallback callback,
176 gpointer callback_data) {
177 g_return_if_fail(container != NULL);
178 g_return_if_fail(callback != NULL);
179
180 GtkFloatingContainer* floating = GTK_FLOATING_CONTAINER(container);
181 GList* children = floating->floating_children;
182 while (children) {
183 GtkFloatingContainerChild* child =
184 reinterpret_cast<GtkFloatingContainerChild*>(children->data);
185 children = children->next;
186
187 (*callback)(child->widget, callback_data);
188 }
189
190 // Let GtkBin do its part of the forall.
191 ((GTK_CONTAINER_CLASS(gtk_floating_container_parent_class))->forall)
192 (container, include_internals, callback, callback_data);
193 }
194
195 static void gtk_floating_container_size_request(GtkWidget* widget,
196 GtkRequisition* requisition) {
197 GtkBin* bin = GTK_BIN(widget);
198 if (bin && gtk_bin_get_child(bin)) {
199 gtk_widget_size_request(gtk_bin_get_child(bin), requisition);
200 } else {
201 requisition->width = 0;
202 requisition->height = 0;
203 }
204 }
205
206 static void gtk_floating_container_size_allocate(GtkWidget* widget,
207 GtkAllocation* allocation) {
208 gtk_widget_set_allocation(widget, allocation);
209
210 if (gtk_widget_get_has_window(widget) && gtk_widget_get_realized(widget)) {
211 gdk_window_move_resize(gtk_widget_get_window(widget),
212 allocation->x,
213 allocation->y,
214 allocation->width,
215 allocation->height);
216 }
217
218 // Give the same allocation to our GtkBin component.
219 GtkBin* bin = GTK_BIN(widget);
220 if (gtk_bin_get_child(bin)) {
221 gtk_widget_size_allocate(gtk_bin_get_child(bin), allocation);
222 }
223
224 // We need to give whoever is pulling our strings a chance to set the "x" and
225 // "y" properties on all of our children.
226 g_signal_emit(widget, floating_container_signals[SET_FLOATING_POSITION], 0,
227 allocation);
228
229 // Our allocation has been set. We've asked our controller to place the other
230 // widgets. Pass out allocations to all our children based on where they want
231 // to be.
232 GtkFloatingContainer* container = GTK_FLOATING_CONTAINER(widget);
233 GList* children = container->floating_children;
234 GtkAllocation child_allocation;
235 GtkRequisition child_requisition;
236 while (children) {
237 GtkFloatingContainerChild* child =
238 reinterpret_cast<GtkFloatingContainerChild*>(children->data);
239 children = children->next;
240
241 if (gtk_widget_get_visible(GTK_WIDGET(child->widget))) {
242 gtk_widget_size_request(child->widget, &child_requisition);
243 child_allocation.x = allocation->x + child->x;
244 child_allocation.y = allocation->y + child->y;
245 child_allocation.width = std::max(1, std::min(child_requisition.width,
246 allocation->width));
247 child_allocation.height = std::max(1, std::min(child_requisition.height,
248 allocation->height));
249 gtk_widget_size_allocate(child->widget, &child_allocation);
250 }
251 }
252 }
253
254 static void gtk_floating_container_set_child_property(GtkContainer* container,
255 GtkWidget* child,
256 guint property_id,
257 const GValue* value,
258 GParamSpec* pspec) {
259 GtkFloatingContainerChild* floating_child =
260 GetChild(GTK_FLOATING_CONTAINER(container), child);
261 g_return_if_fail(floating_child);
262
263 switch (property_id) {
264 case CHILD_PROP_X:
265 floating_child->x = g_value_get_int(value);
266 gtk_widget_child_notify(child, "x");
267 break;
268 case CHILD_PROP_Y:
269 floating_child->y = g_value_get_int(value);
270 gtk_widget_child_notify(child, "y");
271 break;
272 default:
273 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID(
274 container, property_id, pspec);
275 break;
276 };
277 }
278
279 static void gtk_floating_container_get_child_property(GtkContainer* container,
280 GtkWidget* child,
281 guint property_id,
282 GValue* value,
283 GParamSpec* pspec) {
284 GtkFloatingContainerChild* floating_child =
285 GetChild(GTK_FLOATING_CONTAINER(container), child);
286 g_return_if_fail(floating_child);
287
288 switch (property_id) {
289 case CHILD_PROP_X:
290 g_value_set_int(value, floating_child->x);
291 break;
292 case CHILD_PROP_Y:
293 g_value_set_int(value, floating_child->y);
294 break;
295 default:
296 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID(
297 container, property_id, pspec);
298 break;
299 };
300 }
301
302 GtkWidget* gtk_floating_container_new() {
303 return GTK_WIDGET(g_object_new(GTK_TYPE_FLOATING_CONTAINER, NULL));
304 }
305
306 void gtk_floating_container_add_floating(GtkFloatingContainer* container,
307 GtkWidget* widget) {
308 g_return_if_fail(GTK_IS_FLOATING_CONTAINER(container));
309 g_return_if_fail(GTK_IS_WIDGET(widget));
310
311 GtkFloatingContainerChild* child_info = g_new(GtkFloatingContainerChild, 1);
312 child_info->widget = widget;
313 child_info->x = 0;
314 child_info->y = 0;
315
316 gtk_widget_set_parent(widget, GTK_WIDGET(container));
317
318 container->floating_children =
319 g_list_append(container->floating_children, child_info);
320 }
321
322 G_END_DECLS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698