comparison plugins/ticker/gtkticker.c @ 5170:13ffa9ae4282

[gaim-migrate @ 5534] This makes the buddy ticker plugin work again, and may cause some slight breakage in some plugins, since it slightly changes the behavior of: event_buddy_signon event_buddy_signoff event_buddy_away event_buddy_back Then again, it's nothing compared to the massive breakage being thought up for the very near future ;-) committer: Tailor Script <tailor@pidgin.im>
author Nathan Walp <nwalp@pidgin.im>
date Fri, 18 Apr 2003 21:49:45 +0000
parents 42d53c416bb9
children aeb5ee62debc
comparison
equal deleted inserted replaced
5169:71927464a1db 5170:13ffa9ae4282
28 static void gtk_ticker_class_init (GtkTickerClass *klass); 28 static void gtk_ticker_class_init (GtkTickerClass *klass);
29 static void gtk_ticker_init (GtkTicker *ticker); 29 static void gtk_ticker_init (GtkTicker *ticker);
30 static void gtk_ticker_map (GtkWidget *widget); 30 static void gtk_ticker_map (GtkWidget *widget);
31 static void gtk_ticker_realize (GtkWidget *widget); 31 static void gtk_ticker_realize (GtkWidget *widget);
32 static void gtk_ticker_size_request (GtkWidget *widget, 32 static void gtk_ticker_size_request (GtkWidget *widget,
33 GtkRequisition *requisition); 33 GtkRequisition *requisition);
34 static void gtk_ticker_size_allocate (GtkWidget *widget, 34 static void gtk_ticker_size_allocate (GtkWidget *widget,
35 GtkAllocation *allocation); 35 GtkAllocation *allocation);
36 static gint gtk_ticker_expose (GtkWidget *widget,
37 GdkEventExpose *event);
38 static void gtk_ticker_add_real (GtkContainer *container, 36 static void gtk_ticker_add_real (GtkContainer *container,
39 GtkWidget *widget); 37 GtkWidget *widget);
40 static void gtk_ticker_remove_real (GtkContainer *container, 38 static void gtk_ticker_remove_real (GtkContainer *container,
41 GtkWidget *widget); 39 GtkWidget *widget);
42 static void gtk_ticker_forall (GtkContainer *container, 40 static void gtk_ticker_forall (GtkContainer *container,
43 gboolean include_internals, 41 gboolean include_internals,
44 GtkCallback callback, 42 GtkCallback callback,
45 gpointer callback_data); 43 gpointer callback_data);
46 static GtkType gtk_ticker_child_type (GtkContainer *container); 44 static GtkType gtk_ticker_child_type (GtkContainer *container);
47 45
48 46
49 static GtkContainerClass *parent_class = NULL; 47 static GtkContainerClass *parent_class = NULL;
50 48
51 49
52 GType 50 GType gtk_ticker_get_type (void)
53 gtk_ticker_get_type (void) 51 {
54 { 52 static GType ticker_type = 0;
55 static GType ticker_type = 0; 53
56 54 if (!ticker_type)
57 if (!ticker_type) 55 {
58 { 56 static const GTypeInfo ticker_info =
59 static const GTypeInfo ticker_info = 57 {
60 { 58 sizeof(GtkTickerClass),
61 sizeof(GtkTickerClass), 59 NULL,
62 NULL, 60 NULL,
63 NULL, 61 (GClassInitFunc) gtk_ticker_class_init,
64 (GClassInitFunc) gtk_ticker_class_init, 62 NULL,
65 NULL, 63 NULL,
66 NULL, 64 sizeof(GtkTicker),
67 sizeof(GtkTicker), 65 0,
68 0, 66 (GInstanceInitFunc) gtk_ticker_init
69 (GInstanceInitFunc) gtk_ticker_init 67 };
70 }; 68
71 69 ticker_type = g_type_register_static (GTK_TYPE_CONTAINER, "GtkTicker",
72 ticker_type = g_type_register_static (GTK_TYPE_CONTAINER, "GtkTicker", 70 &ticker_info, 0);
73 &ticker_info, 0); 71 }
74 } 72
75 73 return ticker_type;
76 return ticker_type; 74 }
77 } 75
78 76 static void gtk_ticker_finalize(GObject *object) {
79 static void 77 gtk_ticker_stop_scroll(GTK_TICKER(object));
80 gtk_ticker_class_init (GtkTickerClass *class) 78
81 { 79 G_OBJECT_CLASS(parent_class)->finalize(object);
82 GtkObjectClass *object_class; 80 }
83 GtkWidgetClass *widget_class; 81
84 GtkContainerClass *container_class; 82 static void gtk_ticker_class_init (GtkTickerClass *class)
85 83 {
86 object_class = (GtkObjectClass*) class; 84 GObjectClass *gobject_class;
87 widget_class = (GtkWidgetClass*) class; 85 GtkWidgetClass *widget_class;
88 container_class = (GtkContainerClass*) class; 86 GtkContainerClass *container_class;
89 87
90 parent_class = gtk_type_class (GTK_TYPE_CONTAINER); 88 gobject_class = (GObjectClass*) class;
91 89 widget_class = (GtkWidgetClass*) class;
92 widget_class->map = gtk_ticker_map; 90 container_class = (GtkContainerClass*) class;
93 widget_class->realize = gtk_ticker_realize; 91
94 widget_class->size_request = gtk_ticker_size_request; 92 parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
95 widget_class->size_allocate = gtk_ticker_size_allocate; 93
96 widget_class->expose_event = gtk_ticker_expose; 94 gobject_class->finalize = gtk_ticker_finalize;
97 95
98 container_class->add = gtk_ticker_add_real; 96 widget_class->map = gtk_ticker_map;
99 container_class->remove = gtk_ticker_remove_real; 97 widget_class->realize = gtk_ticker_realize;
100 container_class->forall = gtk_ticker_forall; 98 widget_class->size_request = gtk_ticker_size_request;
101 container_class->child_type = gtk_ticker_child_type; 99 widget_class->size_allocate = gtk_ticker_size_allocate;
102 } 100
103 101 container_class->add = gtk_ticker_add_real;
104 static GtkType 102 container_class->remove = gtk_ticker_remove_real;
105 gtk_ticker_child_type (GtkContainer *container) 103 container_class->forall = gtk_ticker_forall;
106 { 104 container_class->child_type = gtk_ticker_child_type;
107 return GTK_TYPE_WIDGET; 105 }
108 } 106
109 107 static GtkType gtk_ticker_child_type (GtkContainer *container)
110 static void 108 {
111 gtk_ticker_init (GtkTicker *ticker) 109 return GTK_TYPE_WIDGET;
112 { 110 }
113 GTK_WIDGET_UNSET_FLAGS (ticker, GTK_NO_WINDOW); 111
114 112 static void gtk_ticker_init (GtkTicker *ticker)
115 ticker->interval = (guint) 200; 113 {
116 ticker->scootch = (guint) 2; 114 GTK_WIDGET_UNSET_FLAGS (ticker, GTK_NO_WINDOW);
117 ticker->children = NULL; 115
118 ticker->timer = 0; 116 ticker->interval = (guint) 200;
119 ticker->dirty = TRUE; 117 ticker->scootch = (guint) 2;
120 } 118 ticker->children = NULL;
121 119 ticker->timer = 0;
122 GtkWidget* 120 ticker->dirty = TRUE;
123 gtk_ticker_new (void) 121 }
122
123 GtkWidget* gtk_ticker_new (void)
124 { 124 {
125 return GTK_WIDGET(g_object_new(GTK_TYPE_TICKER, NULL)); 125 return GTK_WIDGET(g_object_new(GTK_TYPE_TICKER, NULL));
126 } 126 }
127 127
128 static void 128 static void gtk_ticker_put (GtkTicker *ticker, GtkWidget *widget)
129 gtk_ticker_put (GtkTicker *ticker, 129 {
130 GtkWidget *widget) 130 GtkTickerChild *child_info;
131 { 131
132 GtkTickerChild *child_info; 132 g_return_if_fail (ticker != NULL);
133 133 g_return_if_fail (GTK_IS_TICKER (ticker));
134 g_return_if_fail (ticker != NULL); 134 g_return_if_fail (widget != NULL);
135 g_return_if_fail (GTK_IS_TICKER (ticker)); 135
136 g_return_if_fail (widget != NULL); 136 child_info = g_new(GtkTickerChild, 1);
137 137 child_info->widget = widget;
138 child_info = g_new(GtkTickerChild, 1); 138 child_info->x = 0;
139 child_info->widget = widget; 139
140 child_info->x = 0; 140 gtk_widget_set_parent(widget, GTK_WIDGET (ticker));
141 141
142 gtk_widget_set_parent(widget, GTK_WIDGET (ticker)); 142 ticker->children = g_list_append (ticker->children, child_info);
143 143
144 ticker->children = g_list_append (ticker->children, child_info); 144 if (GTK_WIDGET_REALIZED (ticker))
145 145 gtk_widget_realize (widget);
146 if (GTK_WIDGET_REALIZED (ticker)) 146
147 gtk_widget_realize (widget); 147 if (GTK_WIDGET_VISIBLE (ticker) && GTK_WIDGET_VISIBLE (widget))
148 148 {
149 if (GTK_WIDGET_VISIBLE (ticker) && GTK_WIDGET_VISIBLE (widget)) 149 if (GTK_WIDGET_MAPPED (ticker))
150 { 150 gtk_widget_map (widget);
151 if (GTK_WIDGET_MAPPED (ticker)) 151
152 gtk_widget_map (widget); 152 gtk_widget_queue_resize (GTK_WIDGET (ticker));
153 153 }
154 gtk_widget_queue_resize (GTK_WIDGET (ticker)); 154 }
155 } 155
156 } 156 void gtk_ticker_set_interval (GtkTicker *ticker, gint interval)
157 157 {
158 void 158 g_return_if_fail (ticker != NULL);
159 gtk_ticker_set_interval (GtkTicker *ticker, gint interval ) 159 g_return_if_fail (GTK_IS_TICKER (ticker));
160 { 160
161 g_return_if_fail (ticker != NULL); 161 if ( interval < 0 )
162 g_return_if_fail (GTK_IS_TICKER (ticker)); 162 interval = 200;
163 163 ticker->interval = interval;
164 if ( interval < 0 ) 164 }
165 interval = 200; 165
166 ticker->interval = interval; 166 guint gtk_ticker_get_interval (GtkTicker *ticker)
167 167 {
168 } 168 g_return_val_if_fail (ticker != NULL, -1);
169 169 g_return_val_if_fail (GTK_IS_TICKER (ticker), -1);
170 guint 170
171 gtk_ticker_get_interval (GtkTicker *ticker ) 171 return ticker->interval;
172 { 172 }
173 g_return_val_if_fail (ticker != NULL, -1); 173
174 g_return_val_if_fail (GTK_IS_TICKER (ticker), -1); 174 void gtk_ticker_set_scootch (GtkTicker *ticker, gint scootch)
175 175 {
176 return ticker->interval; 176 g_return_if_fail (ticker != NULL);
177 } 177 g_return_if_fail (GTK_IS_TICKER (ticker));
178 178
179 void 179 if (scootch <= 0)
180 gtk_ticker_set_scootch (GtkTicker *ticker, gint scootch ) 180 scootch = 2;
181 { 181 ticker->scootch = scootch;
182 g_return_if_fail (ticker != NULL); 182 ticker->dirty = TRUE;
183 g_return_if_fail (GTK_IS_TICKER (ticker)); 183 }
184 184
185 if ( scootch <= 0 ) 185 guint gtk_ticker_get_scootch (GtkTicker *ticker )
186 scootch = 2; 186 {
187 ticker->scootch = scootch; 187 g_return_val_if_fail (ticker != NULL, -1);
188 ticker->dirty = TRUE; 188 g_return_val_if_fail (GTK_IS_TICKER (ticker), -1);
189 } 189
190 190 return ticker->scootch;
191 guint 191 }
192 gtk_ticker_get_scootch (GtkTicker *ticker ) 192
193 { 193 void gtk_ticker_set_spacing (GtkTicker *ticker, gint spacing )
194 g_return_val_if_fail (ticker != NULL, -1); 194 {
195 g_return_val_if_fail (GTK_IS_TICKER (ticker), -1); 195 g_return_if_fail (ticker != NULL);
196 196 g_return_if_fail (GTK_IS_TICKER (ticker));
197 return ticker->scootch; 197
198 } 198 if ( spacing < 0 )
199 199 spacing = 0;
200 void 200 ticker->spacing = spacing;
201 gtk_ticker_set_spacing (GtkTicker *ticker, gint spacing ) 201 ticker->dirty = TRUE;
202 { 202 }
203 g_return_if_fail (ticker != NULL); 203
204 g_return_if_fail (GTK_IS_TICKER (ticker)); 204 static int ticker_timeout(gpointer data)
205
206 if ( spacing < 0 )
207 spacing = 0;
208 ticker->spacing = spacing;
209 ticker->dirty = TRUE;
210
211 }
212
213 static int
214 ticker_timeout( gpointer data )
215 { 205 {
216 GtkTicker *ticker = (GtkTicker *) data; 206 GtkTicker *ticker = (GtkTicker *) data;
217 207
218 if (GTK_WIDGET_VISIBLE (ticker)) 208 if (GTK_WIDGET_VISIBLE (ticker))
219 gtk_widget_queue_resize (GTK_WIDGET (ticker)); 209 gtk_widget_queue_resize (GTK_WIDGET (ticker));
220 210
221 return( TRUE ); 211 return( TRUE );
222 } 212 }
223 213
224 void 214 void gtk_ticker_start_scroll(GtkTicker *ticker)
225 gtk_ticker_start_scroll(GtkTicker *ticker) 215 {
226 { 216 g_return_if_fail (ticker != NULL);
227 g_return_if_fail (ticker != NULL); 217 g_return_if_fail (GTK_IS_TICKER (ticker));
228 g_return_if_fail (GTK_IS_TICKER (ticker));
229 if ( ticker->timer != 0 ) 218 if ( ticker->timer != 0 )
230 return; 219 return;
231 ticker->timer = g_timeout_add(ticker->interval, ticker_timeout, ticker); 220 ticker->timer = g_timeout_add(ticker->interval, ticker_timeout, ticker);
232 } 221 }
233 222
234 void 223 void gtk_ticker_stop_scroll(GtkTicker *ticker)
235 gtk_ticker_stop_scroll(GtkTicker *ticker) 224 {
236 { 225 g_return_if_fail (ticker != NULL);
237 g_return_if_fail (ticker != NULL); 226 g_return_if_fail (GTK_IS_TICKER (ticker));
238 g_return_if_fail (GTK_IS_TICKER (ticker));
239 if ( ticker->timer == 0 ) 227 if ( ticker->timer == 0 )
240 return; 228 return;
241 g_source_remove(ticker->timer); 229 g_source_remove(ticker->timer);
242 ticker->timer = 0; 230 ticker->timer = 0;
243 231 }
244 } 232
245 233 guint gtk_ticker_get_spacing (GtkTicker *ticker )
246 guint 234 {
247 gtk_ticker_get_spacing (GtkTicker *ticker ) 235 g_return_val_if_fail (ticker != NULL, -1);
248 { 236 g_return_val_if_fail (GTK_IS_TICKER (ticker), -1);
249 g_return_val_if_fail (ticker != NULL, -1); 237
250 g_return_val_if_fail (GTK_IS_TICKER (ticker), -1); 238 return ticker->spacing;
251 239 }
252 return ticker->spacing; 240
253 } 241 static void gtk_ticker_map (GtkWidget *widget)
254 242 {
255 static void 243 GtkTicker *ticker;
256 gtk_ticker_map (GtkWidget *widget) 244 GtkTickerChild *child;
257 { 245 GList *children;
258 GtkTicker *ticker; 246
259 GtkTickerChild *child; 247 g_return_if_fail (widget != NULL);
260 GList *children; 248 g_return_if_fail (GTK_IS_TICKER (widget));
261 249
262 g_return_if_fail (widget != NULL); 250 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
263 g_return_if_fail (GTK_IS_TICKER (widget)); 251 ticker = GTK_TICKER (widget);
264 252
265 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED); 253 children = ticker->children;
266 ticker = GTK_TICKER (widget); 254 while (children)
267 255 {
268 children = ticker->children; 256 child = children->data;
269 while (children) 257 children = children->next;
270 { 258
271 child = children->data; 259 if (GTK_WIDGET_VISIBLE (child->widget) &&
272 children = children->next; 260 !GTK_WIDGET_MAPPED (child->widget))
273 261 gtk_widget_map (child->widget);
274 if (GTK_WIDGET_VISIBLE (child->widget) && 262 }
275 !GTK_WIDGET_MAPPED (child->widget)) 263
276 gtk_widget_map (child->widget); 264 gdk_window_show (widget->window);
277 } 265 }
278 266
279 gdk_window_show (widget->window); 267 static void gtk_ticker_realize (GtkWidget *widget)
280 } 268 {
281 269 GdkWindowAttr attributes;
282 static void 270 gint attributes_mask;
283 gtk_ticker_realize (GtkWidget *widget) 271
284 { 272 g_return_if_fail (widget != NULL);
285 GdkWindowAttr attributes; 273 g_return_if_fail (GTK_IS_TICKER (widget));
286 gint attributes_mask; 274
287 275 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
288 g_return_if_fail (widget != NULL); 276
289 g_return_if_fail (GTK_IS_TICKER (widget)); 277 attributes.window_type = GDK_WINDOW_CHILD;
290 278 attributes.x = widget->allocation.x;
291 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); 279 attributes.y = widget->allocation.y;
292 280 attributes.width = widget->allocation.width;
293 attributes.window_type = GDK_WINDOW_CHILD; 281 attributes.height = widget->allocation.height;
294 attributes.x = widget->allocation.x; 282 attributes.wclass = GDK_INPUT_OUTPUT;
295 attributes.y = widget->allocation.y; 283 attributes.visual = gtk_widget_get_visual (widget);
296 attributes.width = widget->allocation.width; 284 attributes.colormap = gtk_widget_get_colormap (widget);
297 attributes.height = widget->allocation.height; 285 attributes.event_mask = gtk_widget_get_events (widget);
298 attributes.wclass = GDK_INPUT_OUTPUT; 286 attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
299 attributes.visual = gtk_widget_get_visual (widget); 287
300 attributes.colormap = gtk_widget_get_colormap (widget); 288 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
301 attributes.event_mask = gtk_widget_get_events (widget); 289
302 attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK; 290 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
303 291 &attributes, attributes_mask);
304 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; 292 gdk_window_set_user_data (widget->window, widget);
305 293
306 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), 294 widget->style = gtk_style_attach (widget->style, widget->window);
307 &attributes, attributes_mask); 295 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
308 gdk_window_set_user_data (widget->window, widget); 296 }
309 297
310 widget->style = gtk_style_attach (widget->style, widget->window); 298 static void gtk_ticker_size_request (GtkWidget *widget, GtkRequisition *requisition)
311 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); 299 {
312 } 300 GtkTicker *ticker;
313 301 GtkTickerChild *child;
314 static void 302 GList *children;
315 gtk_ticker_size_request (GtkWidget *widget, 303 GtkRequisition child_requisition;
316 GtkRequisition *requisition) 304
317 { 305 g_return_if_fail (widget != NULL);
318 GtkTicker *ticker; 306 g_return_if_fail (GTK_IS_TICKER (widget));
319 GtkTickerChild *child; 307 g_return_if_fail (requisition != NULL);
320 GList *children; 308
321 GtkRequisition child_requisition; 309 ticker = GTK_TICKER (widget);
322 310 requisition->width = 0;
323 g_return_if_fail (widget != NULL); 311 requisition->height = 0;
324 g_return_if_fail (GTK_IS_TICKER (widget)); 312
325 g_return_if_fail (requisition != NULL); 313 children = ticker->children;
326 314 while (children)
327 ticker = GTK_TICKER (widget); 315 {
328 requisition->width = 0; 316 child = children->data;
329 requisition->height = 0; 317 children = children->next;
330 318
331 children = ticker->children; 319 if (GTK_WIDGET_VISIBLE (child->widget))
332 while (children) 320 {
333 { 321 gtk_widget_size_request (child->widget, &child_requisition);
334 child = children->data; 322
335 children = children->next; 323 requisition->height = MAX (requisition->height,
336 324 child_requisition.height);
337 if (GTK_WIDGET_VISIBLE (child->widget)) 325 requisition->width += child_requisition.width + ticker->spacing;
338 { 326 }
339 gtk_widget_size_request (child->widget, &child_requisition); 327 }
340 328 if ( requisition->width > ticker->spacing )
341 requisition->height = MAX (requisition->height, 329 requisition->width -= ticker->spacing;
342 child_requisition.height); 330
343 requisition->width += child_requisition.width + ticker->spacing; 331 requisition->height += GTK_CONTAINER (ticker)->border_width * 2;
344 } 332 requisition->width += GTK_CONTAINER (ticker)->border_width * 2;
345 } 333 }
346 if ( requisition->width > ticker->spacing ) 334
347 requisition->width -= ticker->spacing; 335 static void gtk_ticker_compute_offsets (GtkTicker *ticker)
348 336 {
349 requisition->height += GTK_CONTAINER (ticker)->border_width * 2; 337 GtkTickerChild *child;
350 requisition->width += GTK_CONTAINER (ticker)->border_width * 2; 338 GtkRequisition child_requisition;
351 } 339 GList *children;
352 340 guint16 border_width;
353 static void 341
354 gtk_ticker_compute_offsets (GtkTicker *ticker) 342 g_return_if_fail (ticker != NULL);
355 { 343 g_return_if_fail (GTK_IS_TICKER(ticker));
356 GtkTickerChild *child; 344
357 GtkRequisition child_requisition; 345 border_width = GTK_CONTAINER (ticker)->border_width;
358 GList *children; 346
359 guint16 border_width; 347 ticker->width = GTK_WIDGET(ticker)->allocation.width;
360 348 ticker->total = 0;
361 g_return_if_fail (ticker != NULL); 349 children = ticker->children;
362 g_return_if_fail (GTK_IS_TICKER(ticker)); 350 while (children) {
363 351 child = children->data;
364 border_width = GTK_CONTAINER (ticker)->border_width; 352
365 353 child->x = 0;
366 ticker->width = GTK_WIDGET(ticker)->allocation.width; 354 if (GTK_WIDGET_VISIBLE (child->widget)) {
367 ticker->total = 0; 355 gtk_widget_get_child_requisition (child->widget, &child_requisition);
368 children = ticker->children; 356 child->offset = ticker->total;
369 while (children) { 357 ticker->total +=
370 child = children->data; 358 child_requisition.width + border_width + ticker->spacing;
371 359 }
372 child->x = 0; 360 children = children->next;
373 if (GTK_WIDGET_VISIBLE (child->widget)) { 361 }
374 gtk_widget_get_child_requisition (child->widget, &child_requisition); 362 ticker->dirty = FALSE;
375 child->offset = ticker->total; 363 }
376 ticker->total += 364
377 child_requisition.width + border_width + ticker->spacing; 365 static void gtk_ticker_size_allocate (GtkWidget *widget,
378 } 366 GtkAllocation *allocation)
379 children = children->next; 367 {
380 } 368 GtkTicker *ticker;
381 ticker->dirty = FALSE; 369 GtkTickerChild *child;
382 } 370 GtkAllocation child_allocation;
383 371 GtkRequisition child_requisition;
384 static void 372 GList *children;
385 gtk_ticker_size_allocate (GtkWidget *widget, 373 guint16 border_width;
386 GtkAllocation *allocation) 374
387 { 375 g_return_if_fail (widget != NULL);
388 GtkTicker *ticker; 376 g_return_if_fail (GTK_IS_TICKER(widget));
389 GtkTickerChild *child; 377 g_return_if_fail (allocation != NULL);
390 GtkAllocation child_allocation; 378
391 GtkRequisition child_requisition; 379 ticker = GTK_TICKER (widget);
392 GList *children; 380
393 guint16 border_width; 381 if ( GTK_WIDGET(ticker)->allocation.width != ticker->width )
394 382 ticker->dirty = TRUE;
395 g_return_if_fail (widget != NULL); 383
396 g_return_if_fail (GTK_IS_TICKER(widget)); 384 if ( ticker->dirty == TRUE ) {
397 g_return_if_fail (allocation != NULL); 385 gtk_ticker_compute_offsets( ticker );
398 386 }
399 ticker = GTK_TICKER (widget); 387
400 388 widget->allocation = *allocation;
401 if ( GTK_WIDGET(ticker)->allocation.width != ticker->width ) 389 if (GTK_WIDGET_REALIZED (widget))
390 gdk_window_move_resize (widget->window,
391 allocation->x,
392 allocation->y,
393 allocation->width,
394 allocation->height);
395
396 border_width = GTK_CONTAINER (ticker)->border_width;
397
398 children = ticker->children;
399 while (children)
400 {
401 child = children->data;
402 child->x -= ticker->scootch;
403
404 if (GTK_WIDGET_VISIBLE (child->widget)) {
405 gtk_widget_get_child_requisition (child->widget, &child_requisition);
406 child_allocation.width = child_requisition.width;
407 child_allocation.x = child->offset + border_width + child->x;
408 if ( ( child_allocation.x + child_allocation.width ) < GTK_WIDGET(ticker)->allocation.x ) {
409 if ( ticker->total >= GTK_WIDGET(ticker)->allocation.width ) {
410 child->x += GTK_WIDGET(ticker)->allocation.x + GTK_WIDGET(ticker)->allocation.width + ( ticker->total - ( GTK_WIDGET(ticker)->allocation.x + GTK_WIDGET(ticker)->allocation.width ) );
411 }
412 else {
413 child->x += GTK_WIDGET(ticker)->allocation.x + GTK_WIDGET(ticker)->allocation.width;
414 }
415 }
416 child_allocation.y = border_width;
417 child_allocation.height = child_requisition.height;
418 gtk_widget_size_allocate (child->widget, &child_allocation);
419 }
420 children = children->next;
421 }
422 }
423
424 void gtk_ticker_add(GtkTicker *ticker, GtkWidget *widget)
425 {
426 gtk_ticker_add_real( GTK_CONTAINER( ticker ), widget );
402 ticker->dirty = TRUE; 427 ticker->dirty = TRUE;
403 428 }
404 if ( ticker->dirty == TRUE ) { 429
405 gtk_ticker_compute_offsets( ticker ); 430 void gtk_ticker_remove(GtkTicker *ticker, GtkWidget *widget)
406 } 431 {
407 432 gtk_ticker_remove_real( GTK_CONTAINER( ticker ), widget );
408 widget->allocation = *allocation; 433 ticker->dirty = TRUE;
409 if (GTK_WIDGET_REALIZED (widget)) 434 }
410 gdk_window_move_resize (widget->window, 435
411 allocation->x, 436 static void gtk_ticker_add_real(GtkContainer *container, GtkWidget *widget)
412 allocation->y, 437 {
413 allocation->width, 438 g_return_if_fail (container != NULL);
414 allocation->height); 439 g_return_if_fail (GTK_IS_TICKER (container));
415 440 g_return_if_fail (widget != NULL);
416 border_width = GTK_CONTAINER (ticker)->border_width; 441
417 442 gtk_ticker_put(GTK_TICKER (container), widget);
418 children = ticker->children; 443 }
419 while (children) 444
420 { 445 static void gtk_ticker_remove_real(GtkContainer *container, GtkWidget *widget)
421 child = children->data; 446 {
422 child->x -= ticker->scootch; 447 GtkTicker *ticker;
423 448 GtkTickerChild *child;
424 if (GTK_WIDGET_VISIBLE (child->widget)) { 449 GList *children;
425 gtk_widget_get_child_requisition (child->widget, &child_requisition); 450
426 child_allocation.width = child_requisition.width; 451 g_return_if_fail (container != NULL);
427 child_allocation.x = child->offset + border_width + child->x; 452 g_return_if_fail (GTK_IS_TICKER (container));
428 if ( ( child_allocation.x + child_allocation.width ) < GTK_WIDGET(ticker)->allocation.x ) { 453 g_return_if_fail (widget != NULL);
429 if ( ticker->total >= GTK_WIDGET(ticker)->allocation.width ) { 454
430 child->x += GTK_WIDGET(ticker)->allocation.x + GTK_WIDGET(ticker)->allocation.width + ( ticker->total - ( GTK_WIDGET(ticker)->allocation.x + GTK_WIDGET(ticker)->allocation.width ) ); 455 ticker = GTK_TICKER (container);
456
457 children = ticker->children;
458 while (children)
459 {
460 child = children->data;
461
462 if (child->widget == widget)
463 {
464 gboolean was_visible = GTK_WIDGET_VISIBLE (widget);
465
466 gtk_widget_unparent (widget);
467
468 ticker->children = g_list_remove_link (ticker->children, children);
469 g_list_free (children);
470 g_free (child);
471
472 if (was_visible && GTK_WIDGET_VISIBLE (container))
473 gtk_widget_queue_resize (GTK_WIDGET (container));
474
475 break;
431 } 476 }
432 else { 477
433 child->x += GTK_WIDGET(ticker)->allocation.x + GTK_WIDGET(ticker)->allocation.width; 478 children = children->next;
434 } 479 }
435 } 480 }
436 child_allocation.y = border_width; 481
437 child_allocation.height = child_requisition.height; 482 static void gtk_ticker_forall (GtkContainer *container,
438 gtk_widget_size_allocate (child->widget, &child_allocation); 483 gboolean include_internals,
439 } 484 GtkCallback callback,
440 children = children->next; 485 gpointer callback_data)
441 } 486 {
442 } 487 GtkTicker *ticker;
443 488 GtkTickerChild *child;
444 static gint 489 GList *children;
445 gtk_ticker_expose (GtkWidget *widget, GdkEventExpose *event) 490
446 { 491 g_return_if_fail (container != NULL);
447 GtkTicker *ticker; 492 g_return_if_fail (GTK_IS_TICKER (container));
448 GtkTickerChild *child; 493 g_return_if_fail (callback != NULL);
449 GdkEventExpose child_event; 494
450 GList *children; 495 ticker = GTK_TICKER (container);
451 496
452 g_return_val_if_fail (widget != NULL, FALSE); 497 children = ticker->children;
453 g_return_val_if_fail (GTK_IS_TICKER (widget), FALSE); 498 while (children)
454 g_return_val_if_fail (event != NULL, FALSE); 499 {
455 500 child = children->data;
456 if (GTK_WIDGET_DRAWABLE (widget)) 501 children = children->next;
457 { 502
458 ticker = GTK_TICKER (widget); 503 (* callback) (child->widget, callback_data);
459 504 }
460 child_event = *event; 505 }
461 506
462 children = ticker->children;
463 while (children)
464 {
465 child = children->data;
466 children = children->next;
467
468 if (GTK_WIDGET_NO_WINDOW (child->widget) &&
469 gtk_widget_intersect (child->widget, &event->area,
470 &child_event.area))
471 gtk_widget_event (child->widget, (GdkEvent*) &child_event);
472 }
473 }
474
475 return FALSE;
476 }
477
478
479 void
480 gtk_ticker_add(GtkTicker *ticker, GtkWidget *widget)
481 {
482 gtk_ticker_add_real( GTK_CONTAINER( ticker ), widget );
483 ticker->dirty = TRUE;
484 }
485
486 void
487 gtk_ticker_remove(GtkTicker *ticker, GtkWidget *widget)
488 {
489 gtk_ticker_remove_real( GTK_CONTAINER( ticker ), widget );
490 ticker->dirty = TRUE;
491 }
492
493 static void
494 gtk_ticker_add_real(GtkContainer *container,
495 GtkWidget *widget)
496 {
497 g_return_if_fail (container != NULL);
498 g_return_if_fail (GTK_IS_TICKER (container));
499 g_return_if_fail (widget != NULL);
500
501 gtk_ticker_put(GTK_TICKER (container), widget);
502 }
503
504 static void
505 gtk_ticker_remove_real(GtkContainer *container,
506 GtkWidget *widget)
507 {
508 GtkTicker *ticker;
509 GtkTickerChild *child;
510 GList *children;
511
512 g_return_if_fail (container != NULL);
513 g_return_if_fail (GTK_IS_TICKER (container));
514 g_return_if_fail (widget != NULL);
515
516 ticker = GTK_TICKER (container);
517
518 children = ticker->children;
519 while (children)
520 {
521 child = children->data;
522
523 if (child->widget == widget)
524 {
525 gboolean was_visible = GTK_WIDGET_VISIBLE (widget);
526
527 gtk_widget_unparent (widget);
528
529 ticker->children = g_list_remove_link (ticker->children, children);
530 g_list_free (children);
531 g_free (child);
532
533 if (was_visible && GTK_WIDGET_VISIBLE (container))
534 gtk_widget_queue_resize (GTK_WIDGET (container));
535
536 break;
537 }
538
539 children = children->next;
540 }
541 }
542
543 static void
544 gtk_ticker_forall (GtkContainer *container,
545 gboolean include_internals,
546 GtkCallback callback,
547 gpointer callback_data)
548 {
549 GtkTicker *ticker;
550 GtkTickerChild *child;
551 GList *children;
552
553 g_return_if_fail (container != NULL);
554 g_return_if_fail (GTK_IS_TICKER (container));
555 g_return_if_fail (callback != NULL);
556
557 ticker = GTK_TICKER (container);
558
559 children = ticker->children;
560 while (children)
561 {
562 child = children->data;
563 children = children->next;
564
565 (* callback) (child->widget, callback_data);
566 }
567 }