source: trunk/third/gtk/gtk/gtkfixed.c @ 14482

Revision 14482, 12.6 KB checked in by ghudson, 25 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r14481, which included commits to RCS files with non-trunk default branches.
RevLine 
[14481]1/* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20/*
21 * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
22 * file for a list of people on the GTK+ Team.  See the ChangeLog
23 * files for a list of changes.  These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
25 */
26
27#include "gtkfixed.h"
28
29
30static void gtk_fixed_class_init    (GtkFixedClass    *klass);
31static void gtk_fixed_init          (GtkFixed         *fixed);
32static void gtk_fixed_map           (GtkWidget        *widget);
33static void gtk_fixed_realize       (GtkWidget        *widget);
34static void gtk_fixed_size_request  (GtkWidget        *widget,
35                                     GtkRequisition   *requisition);
36static void gtk_fixed_size_allocate (GtkWidget        *widget,
37                                     GtkAllocation    *allocation);
38static void gtk_fixed_paint         (GtkWidget        *widget,
39                                     GdkRectangle     *area);
40static void gtk_fixed_draw          (GtkWidget        *widget,
41                                     GdkRectangle     *area);
42static gint gtk_fixed_expose        (GtkWidget        *widget,
43                                     GdkEventExpose   *event);
44static void gtk_fixed_add           (GtkContainer     *container,
45                                     GtkWidget        *widget);
46static void gtk_fixed_remove        (GtkContainer     *container,
47                                     GtkWidget        *widget);
48static void gtk_fixed_forall        (GtkContainer     *container,
49                                     gboolean          include_internals,
50                                     GtkCallback       callback,
51                                     gpointer          callback_data);
52static GtkType gtk_fixed_child_type (GtkContainer     *container);
53
54
55static GtkContainerClass *parent_class = NULL;
56
57
58GtkType
59gtk_fixed_get_type (void)
60{
61  static GtkType fixed_type = 0;
62
63  if (!fixed_type)
64    {
65      static const GtkTypeInfo fixed_info =
66      {
67        "GtkFixed",
68        sizeof (GtkFixed),
69        sizeof (GtkFixedClass),
70        (GtkClassInitFunc) gtk_fixed_class_init,
71        (GtkObjectInitFunc) gtk_fixed_init,
72        /* reserved_1 */ NULL,
73        /* reserved_2 */ NULL,
74        (GtkClassInitFunc) NULL,
75      };
76
77      fixed_type = gtk_type_unique (GTK_TYPE_CONTAINER, &fixed_info);
78    }
79
80  return fixed_type;
81}
82
83static void
84gtk_fixed_class_init (GtkFixedClass *class)
85{
86  GtkObjectClass *object_class;
87  GtkWidgetClass *widget_class;
88  GtkContainerClass *container_class;
89
90  object_class = (GtkObjectClass*) class;
91  widget_class = (GtkWidgetClass*) class;
92  container_class = (GtkContainerClass*) class;
93
94  parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
95
96  widget_class->map = gtk_fixed_map;
97  widget_class->realize = gtk_fixed_realize;
98  widget_class->size_request = gtk_fixed_size_request;
99  widget_class->size_allocate = gtk_fixed_size_allocate;
100  widget_class->draw = gtk_fixed_draw;
101  widget_class->expose_event = gtk_fixed_expose;
102
103  container_class->add = gtk_fixed_add;
104  container_class->remove = gtk_fixed_remove;
105  container_class->forall = gtk_fixed_forall;
106  container_class->child_type = gtk_fixed_child_type;
107}
108
109static GtkType
110gtk_fixed_child_type (GtkContainer     *container)
111{
112  return GTK_TYPE_WIDGET;
113}
114
115static void
116gtk_fixed_init (GtkFixed *fixed)
117{
118  GTK_WIDGET_UNSET_FLAGS (fixed, GTK_NO_WINDOW);
119 
120  fixed->children = NULL;
121}
122
123GtkWidget*
124gtk_fixed_new (void)
125{
126  GtkFixed *fixed;
127
128  fixed = gtk_type_new (GTK_TYPE_FIXED);
129  return GTK_WIDGET (fixed);
130}
131
132void
133gtk_fixed_put (GtkFixed       *fixed,
134               GtkWidget      *widget,
135               gint16         x,
136               gint16         y)
137{
138  GtkFixedChild *child_info;
139
140  g_return_if_fail (fixed != NULL);
141  g_return_if_fail (GTK_IS_FIXED (fixed));
142  g_return_if_fail (widget != NULL);
143
144  child_info = g_new (GtkFixedChild, 1);
145  child_info->widget = widget;
146  child_info->x = x;
147  child_info->y = y;
148
149  gtk_widget_set_parent (widget, GTK_WIDGET (fixed));
150
151  fixed->children = g_list_append (fixed->children, child_info);
152
153  if (GTK_WIDGET_REALIZED (fixed))
154    gtk_widget_realize (widget);
155
156  if (GTK_WIDGET_VISIBLE (fixed) && GTK_WIDGET_VISIBLE (widget))
157    {
158      if (GTK_WIDGET_MAPPED (fixed))
159        gtk_widget_map (widget);
160     
161      gtk_widget_queue_resize (GTK_WIDGET (fixed));
162    }
163}
164
165void
166gtk_fixed_move (GtkFixed       *fixed,
167                GtkWidget      *widget,
168                gint16         x,
169                gint16         y)
170{
171  GtkFixedChild *child;
172  GList *children;
173
174  g_return_if_fail (fixed != NULL);
175  g_return_if_fail (GTK_IS_FIXED (fixed));
176  g_return_if_fail (widget != NULL);
177
178  children = fixed->children;
179  while (children)
180    {
181      child = children->data;
182      children = children->next;
183
184      if (child->widget == widget)
185        {
186          child->x = x;
187          child->y = y;
188
189          if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (fixed))
190            gtk_widget_queue_resize (GTK_WIDGET (fixed));
191
192          break;
193        }
194    }
195}
196
197static void
198gtk_fixed_map (GtkWidget *widget)
199{
200  GtkFixed *fixed;
201  GtkFixedChild *child;
202  GList *children;
203
204  g_return_if_fail (widget != NULL);
205  g_return_if_fail (GTK_IS_FIXED (widget));
206
207  GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
208  fixed = GTK_FIXED (widget);
209
210  children = fixed->children;
211  while (children)
212    {
213      child = children->data;
214      children = children->next;
215
216      if (GTK_WIDGET_VISIBLE (child->widget) &&
217          !GTK_WIDGET_MAPPED (child->widget))
218        gtk_widget_map (child->widget);
219    }
220
221  gdk_window_show (widget->window);
222}
223
224static void
225gtk_fixed_realize (GtkWidget *widget)
226{
227  GdkWindowAttr attributes;
228  gint attributes_mask;
229
230  g_return_if_fail (widget != NULL);
231  g_return_if_fail (GTK_IS_FIXED (widget));
232
233  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
234
235  attributes.window_type = GDK_WINDOW_CHILD;
236  attributes.x = widget->allocation.x;
237  attributes.y = widget->allocation.y;
238  attributes.width = widget->allocation.width;
239  attributes.height = widget->allocation.height;
240  attributes.wclass = GDK_INPUT_OUTPUT;
241  attributes.visual = gtk_widget_get_visual (widget);
242  attributes.colormap = gtk_widget_get_colormap (widget);
243  attributes.event_mask = gtk_widget_get_events (widget);
244  attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
245
246  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
247
248  widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes,
249                                   attributes_mask);
250  gdk_window_set_user_data (widget->window, widget);
251
252  widget->style = gtk_style_attach (widget->style, widget->window);
253  gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
254}
255
256static void
257gtk_fixed_size_request (GtkWidget      *widget,
258                        GtkRequisition *requisition)
259{
260  GtkFixed *fixed; 
261  GtkFixedChild *child;
262  GList *children;
263  GtkRequisition child_requisition;
264
265  g_return_if_fail (widget != NULL);
266  g_return_if_fail (GTK_IS_FIXED (widget));
267  g_return_if_fail (requisition != NULL);
268
269  fixed = GTK_FIXED (widget);
270  requisition->width = 0;
271  requisition->height = 0;
272
273  children = fixed->children;
274  while (children)
275    {
276      child = children->data;
277      children = children->next;
278
279      if (GTK_WIDGET_VISIBLE (child->widget))
280        {
281          gtk_widget_size_request (child->widget, &child_requisition);
282
283          requisition->height = MAX (requisition->height,
284                                     child->y +
285                                     child_requisition.height);
286          requisition->width = MAX (requisition->width,
287                                    child->x +
288                                    child_requisition.width);
289        }
290    }
291
292  requisition->height += GTK_CONTAINER (fixed)->border_width * 2;
293  requisition->width += GTK_CONTAINER (fixed)->border_width * 2;
294}
295
296static void
297gtk_fixed_size_allocate (GtkWidget     *widget,
298                         GtkAllocation *allocation)
299{
300  GtkFixed *fixed;
301  GtkFixedChild *child;
302  GtkAllocation child_allocation;
303  GtkRequisition child_requisition;
304  GList *children;
305  guint16 border_width;
306
307  g_return_if_fail (widget != NULL);
308  g_return_if_fail (GTK_IS_FIXED(widget));
309  g_return_if_fail (allocation != NULL);
310
311  fixed = GTK_FIXED (widget);
312
313  widget->allocation = *allocation;
314  if (GTK_WIDGET_REALIZED (widget))
315    gdk_window_move_resize (widget->window,
316                            allocation->x,
317                            allocation->y,
318                            allocation->width,
319                            allocation->height);
320
321  border_width = GTK_CONTAINER (fixed)->border_width;
322 
323  children = fixed->children;
324  while (children)
325    {
326      child = children->data;
327      children = children->next;
328     
329      if (GTK_WIDGET_VISIBLE (child->widget))
330        {
331          gtk_widget_get_child_requisition (child->widget, &child_requisition);
332          child_allocation.x = child->x + border_width;
333          child_allocation.y = child->y + border_width;
334          child_allocation.width = child_requisition.width;
335          child_allocation.height = child_requisition.height;
336          gtk_widget_size_allocate (child->widget, &child_allocation);
337        }
338    }
339}
340
341static void
342gtk_fixed_paint (GtkWidget    *widget,
343                 GdkRectangle *area)
344{
345  g_return_if_fail (widget != NULL);
346  g_return_if_fail (GTK_IS_FIXED (widget));
347  g_return_if_fail (area != NULL);
348
349  if (GTK_WIDGET_DRAWABLE (widget))
350    gdk_window_clear_area (widget->window,
351                           area->x, area->y,
352                           area->width, area->height);
353}
354
355static void
356gtk_fixed_draw (GtkWidget    *widget,
357                GdkRectangle *area)
358{
359  GtkFixed *fixed;
360  GtkFixedChild *child;
361  GdkRectangle child_area;
362  GList *children;
363
364  g_return_if_fail (widget != NULL);
365  g_return_if_fail (GTK_IS_FIXED (widget));
366
367  if (GTK_WIDGET_DRAWABLE (widget))
368    {
369      fixed = GTK_FIXED (widget);
370      gtk_fixed_paint (widget, area);
371
372      children = fixed->children;
373      while (children)
374        {
375          child = children->data;
376          children = children->next;
377
378          if (gtk_widget_intersect (child->widget, area, &child_area))
379            gtk_widget_draw (child->widget, &child_area);
380        }
381    }
382}
383
384static gint
385gtk_fixed_expose (GtkWidget      *widget,
386                  GdkEventExpose *event)
387{
388  GtkFixed *fixed;
389  GtkFixedChild *child;
390  GdkEventExpose child_event;
391  GList *children;
392
393  g_return_val_if_fail (widget != NULL, FALSE);
394  g_return_val_if_fail (GTK_IS_FIXED (widget), FALSE);
395  g_return_val_if_fail (event != NULL, FALSE);
396
397  if (GTK_WIDGET_DRAWABLE (widget))
398    {
399      fixed = GTK_FIXED (widget);
400
401      child_event = *event;
402
403      children = fixed->children;
404      while (children)
405        {
406          child = children->data;
407          children = children->next;
408
409          if (GTK_WIDGET_NO_WINDOW (child->widget) &&
410              gtk_widget_intersect (child->widget, &event->area,
411                                    &child_event.area))
412            gtk_widget_event (child->widget, (GdkEvent*) &child_event);
413        }
414    }
415
416  return FALSE;
417}
418
419static void
420gtk_fixed_add (GtkContainer *container,
421               GtkWidget    *widget)
422{
423  g_return_if_fail (container != NULL);
424  g_return_if_fail (GTK_IS_FIXED (container));
425  g_return_if_fail (widget != NULL);
426
427  gtk_fixed_put (GTK_FIXED (container), widget, 0, 0);
428}
429
430static void
431gtk_fixed_remove (GtkContainer *container,
432                  GtkWidget    *widget)
433{
434  GtkFixed *fixed;
435  GtkFixedChild *child;
436  GList *children;
437
438  g_return_if_fail (container != NULL);
439  g_return_if_fail (GTK_IS_FIXED (container));
440  g_return_if_fail (widget != NULL);
441
442  fixed = GTK_FIXED (container);
443
444  children = fixed->children;
445  while (children)
446    {
447      child = children->data;
448
449      if (child->widget == widget)
450        {
451          gboolean was_visible = GTK_WIDGET_VISIBLE (widget);
452         
453          gtk_widget_unparent (widget);
454
455          fixed->children = g_list_remove_link (fixed->children, children);
456          g_list_free (children);
457          g_free (child);
458
459          if (was_visible && GTK_WIDGET_VISIBLE (container))
460            gtk_widget_queue_resize (GTK_WIDGET (container));
461
462          break;
463        }
464
465      children = children->next;
466    }
467}
468
469static void
470gtk_fixed_forall (GtkContainer *container,
471                  gboolean      include_internals,
472                  GtkCallback   callback,
473                  gpointer      callback_data)
474{
475  GtkFixed *fixed;
476  GtkFixedChild *child;
477  GList *children;
478
479  g_return_if_fail (container != NULL);
480  g_return_if_fail (GTK_IS_FIXED (container));
481  g_return_if_fail (callback != NULL);
482
483  fixed = GTK_FIXED (container);
484
485  children = fixed->children;
486  while (children)
487    {
488      child = children->data;
489      children = children->next;
490
491      (* callback) (child->widget, callback_data);
492    }
493}
Note: See TracBrowser for help on using the repository browser.