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

Revision 14482, 24.6 KB checked in by ghudson, 24 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.
Line 
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 "gtksignal.h"
28#include "gtkviewport.h"
29
30enum {
31  ARG_0,
32  ARG_HADJUSTMENT,
33  ARG_VADJUSTMENT,
34  ARG_SHADOW_TYPE
35};
36
37
38static void gtk_viewport_class_init               (GtkViewportClass *klass);
39static void gtk_viewport_init                     (GtkViewport      *viewport);
40static void gtk_viewport_destroy                  (GtkObject        *object);
41static void gtk_viewport_finalize                 (GtkObject        *object);
42static void gtk_viewport_set_arg                  (GtkObject        *object,
43                                                   GtkArg           *arg,
44                                                   guint             arg_id);
45static void gtk_viewport_get_arg                  (GtkObject        *object,
46                                                   GtkArg           *arg,
47                                                   guint             arg_id);
48static void gtk_viewport_set_scroll_adjustments   (GtkViewport      *viewport,
49                                                   GtkAdjustment    *hadjustment,
50                                                   GtkAdjustment    *vadjustment);
51static void gtk_viewport_map                      (GtkWidget        *widget);
52static void gtk_viewport_unmap                    (GtkWidget        *widget);
53static void gtk_viewport_realize                  (GtkWidget        *widget);
54static void gtk_viewport_unrealize                (GtkWidget        *widget);
55static void gtk_viewport_paint                    (GtkWidget        *widget,
56                                                   GdkRectangle     *area);
57static void gtk_viewport_draw                     (GtkWidget        *widget,
58                                                   GdkRectangle     *area);
59static gint gtk_viewport_expose                   (GtkWidget        *widget,
60                                                   GdkEventExpose   *event);
61static void gtk_viewport_add                      (GtkContainer     *container,
62                                                   GtkWidget        *widget);
63static void gtk_viewport_size_request             (GtkWidget        *widget,
64                                                   GtkRequisition   *requisition);
65static void gtk_viewport_size_allocate            (GtkWidget        *widget,
66                                                   GtkAllocation    *allocation);
67static void gtk_viewport_adjustment_changed       (GtkAdjustment    *adjustment,
68                                                   gpointer          data);
69static void gtk_viewport_adjustment_value_changed (GtkAdjustment    *adjustment,
70                                                   gpointer          data);
71static void gtk_viewport_style_set                (GtkWidget *widget,
72                                                   GtkStyle  *previous_style);
73
74static GtkBinClass *parent_class;
75
76GtkType
77gtk_viewport_get_type (void)
78{
79  static GtkType viewport_type = 0;
80
81  if (!viewport_type)
82    {
83      static const GtkTypeInfo viewport_info =
84      {
85        "GtkViewport",
86        sizeof (GtkViewport),
87        sizeof (GtkViewportClass),
88        (GtkClassInitFunc) gtk_viewport_class_init,
89        (GtkObjectInitFunc) gtk_viewport_init,
90        /* reserved_1 */ NULL,
91        /* reserved_2 */ NULL,
92        (GtkClassInitFunc) NULL,
93      };
94
95      viewport_type = gtk_type_unique (GTK_TYPE_BIN, &viewport_info);
96    }
97
98  return viewport_type;
99}
100
101static void
102gtk_viewport_class_init (GtkViewportClass *class)
103{
104  GtkObjectClass *object_class;
105  GtkWidgetClass *widget_class;
106  GtkContainerClass *container_class;
107
108  object_class = (GtkObjectClass*) class;
109  widget_class = (GtkWidgetClass*) class;
110  container_class = (GtkContainerClass*) class;
111  parent_class = (GtkBinClass*) gtk_type_class (GTK_TYPE_BIN);
112
113  gtk_object_add_arg_type ("GtkViewport::hadjustment",
114                           GTK_TYPE_ADJUSTMENT,
115                           GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT,
116                           ARG_HADJUSTMENT);
117  gtk_object_add_arg_type ("GtkViewport::vadjustment",
118                           GTK_TYPE_ADJUSTMENT,
119                           GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT,
120                           ARG_VADJUSTMENT);
121  gtk_object_add_arg_type ("GtkViewport::shadow_type",
122                           GTK_TYPE_SHADOW_TYPE,
123                           GTK_ARG_READWRITE,
124                           ARG_SHADOW_TYPE);
125
126  object_class->set_arg = gtk_viewport_set_arg;
127  object_class->get_arg = gtk_viewport_get_arg;
128  object_class->destroy = gtk_viewport_destroy;
129  object_class->finalize = gtk_viewport_finalize;
130 
131  widget_class->map = gtk_viewport_map;
132  widget_class->unmap = gtk_viewport_unmap;
133  widget_class->realize = gtk_viewport_realize;
134  widget_class->unrealize = gtk_viewport_unrealize;
135  widget_class->draw = gtk_viewport_draw;
136  widget_class->expose_event = gtk_viewport_expose;
137  widget_class->size_request = gtk_viewport_size_request;
138  widget_class->size_allocate = gtk_viewport_size_allocate;
139  widget_class->style_set = gtk_viewport_style_set;
140
141  widget_class->set_scroll_adjustments_signal =
142    gtk_signal_new ("set_scroll_adjustments",
143                    GTK_RUN_LAST,
144                    object_class->type,
145                    GTK_SIGNAL_OFFSET (GtkViewportClass, set_scroll_adjustments),
146                    gtk_marshal_NONE__POINTER_POINTER,
147                    GTK_TYPE_NONE, 2, GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT);
148 
149  container_class->add = gtk_viewport_add;
150
151  class->set_scroll_adjustments = gtk_viewport_set_scroll_adjustments;
152}
153
154static void
155gtk_viewport_set_arg (GtkObject        *object,
156                      GtkArg           *arg,
157                      guint             arg_id)
158{
159  GtkViewport *viewport;
160
161  viewport = GTK_VIEWPORT (object);
162
163  switch (arg_id)
164    {
165    case ARG_HADJUSTMENT:
166      gtk_viewport_set_hadjustment (viewport, GTK_VALUE_POINTER (*arg));
167      break;
168    case ARG_VADJUSTMENT:
169      gtk_viewport_set_vadjustment (viewport, GTK_VALUE_POINTER (*arg));
170      break;
171    case ARG_SHADOW_TYPE:
172      gtk_viewport_set_shadow_type (viewport, GTK_VALUE_ENUM (*arg));
173      break;
174    default:
175      break;
176    }
177}
178
179static void
180gtk_viewport_get_arg (GtkObject        *object,
181                      GtkArg           *arg,
182                      guint             arg_id)
183{
184  GtkViewport *viewport;
185
186  viewport = GTK_VIEWPORT (object);
187
188  switch (arg_id)
189    {
190    case ARG_HADJUSTMENT:
191      GTK_VALUE_POINTER (*arg) = viewport->hadjustment;
192      break;
193    case ARG_VADJUSTMENT:
194      GTK_VALUE_POINTER (*arg) = viewport->vadjustment;
195      break;
196    case ARG_SHADOW_TYPE:
197      GTK_VALUE_ENUM (*arg) = viewport->shadow_type;
198      break;
199    default:
200      arg->type = GTK_TYPE_INVALID;
201      break;
202    }
203}
204
205static void
206gtk_viewport_init (GtkViewport *viewport)
207{
208  GTK_WIDGET_UNSET_FLAGS (viewport, GTK_NO_WINDOW);
209
210  gtk_container_set_resize_mode (GTK_CONTAINER (viewport), GTK_RESIZE_QUEUE);
211 
212  viewport->shadow_type = GTK_SHADOW_IN;
213  viewport->view_window = NULL;
214  viewport->bin_window = NULL;
215  viewport->hadjustment = NULL;
216  viewport->vadjustment = NULL;
217}
218
219GtkWidget*
220gtk_viewport_new (GtkAdjustment *hadjustment,
221                  GtkAdjustment *vadjustment)
222{
223  GtkWidget *viewport;
224
225  viewport = gtk_widget_new (GTK_TYPE_VIEWPORT,
226                             "hadjustment", hadjustment,
227                             "vadjustment", vadjustment,
228                             NULL);
229
230  return viewport;
231}
232
233static void
234gtk_viewport_destroy (GtkObject *object)
235{
236  GtkViewport *viewport = GTK_VIEWPORT (object);
237
238  if (viewport->hadjustment)
239    gtk_signal_disconnect_by_data (GTK_OBJECT (viewport->hadjustment),
240                                   viewport);
241  if (viewport->vadjustment)
242    gtk_signal_disconnect_by_data (GTK_OBJECT (viewport->vadjustment),
243                                   viewport);
244
245  GTK_OBJECT_CLASS(parent_class)->destroy (object);
246}
247
248static void
249gtk_viewport_finalize (GtkObject *object)
250{
251  GtkViewport *viewport = GTK_VIEWPORT (object);
252
253  gtk_object_unref (GTK_OBJECT (viewport->hadjustment));
254  gtk_object_unref (GTK_OBJECT (viewport->vadjustment));
255
256  GTK_OBJECT_CLASS(parent_class)->finalize (object);
257}
258
259GtkAdjustment*
260gtk_viewport_get_hadjustment (GtkViewport *viewport)
261{
262  g_return_val_if_fail (viewport != NULL, NULL);
263  g_return_val_if_fail (GTK_IS_VIEWPORT (viewport), NULL);
264
265  return viewport->hadjustment;
266}
267
268GtkAdjustment*
269gtk_viewport_get_vadjustment (GtkViewport *viewport)
270{
271  g_return_val_if_fail (viewport != NULL, NULL);
272  g_return_val_if_fail (GTK_IS_VIEWPORT (viewport), NULL);
273
274  return viewport->vadjustment;
275}
276
277void
278gtk_viewport_set_hadjustment (GtkViewport   *viewport,
279                              GtkAdjustment *adjustment)
280{
281  g_return_if_fail (viewport != NULL);
282  g_return_if_fail (GTK_IS_VIEWPORT (viewport));
283  if (adjustment)
284    g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
285
286  if (viewport->hadjustment && viewport->hadjustment != adjustment)
287    {
288      gtk_signal_disconnect_by_data (GTK_OBJECT (viewport->hadjustment),
289                                     (gpointer) viewport);
290      gtk_object_unref (GTK_OBJECT (viewport->hadjustment));
291    }
292
293  if (!adjustment)
294    adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0,
295                                                     0.0, 0.0, 0.0));
296
297  if (viewport->hadjustment != adjustment)
298    {
299      viewport->hadjustment = adjustment;
300      gtk_object_ref (GTK_OBJECT (viewport->hadjustment));
301      gtk_object_sink (GTK_OBJECT (viewport->hadjustment));
302     
303      gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
304                          (GtkSignalFunc) gtk_viewport_adjustment_changed,
305                          (gpointer) viewport);
306      gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
307                          (GtkSignalFunc) gtk_viewport_adjustment_value_changed,
308                          (gpointer) viewport);
309
310      gtk_viewport_adjustment_changed (adjustment, viewport);
311    }
312}
313
314void
315gtk_viewport_set_vadjustment (GtkViewport   *viewport,
316                              GtkAdjustment *adjustment)
317{
318  g_return_if_fail (viewport != NULL);
319  g_return_if_fail (GTK_IS_VIEWPORT (viewport));
320  if (adjustment)
321    g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
322
323  if (viewport->vadjustment && viewport->vadjustment != adjustment)
324    {
325      gtk_signal_disconnect_by_data (GTK_OBJECT (viewport->vadjustment),
326                                     (gpointer) viewport);
327      gtk_object_unref (GTK_OBJECT (viewport->vadjustment));
328    }
329
330  if (!adjustment)
331    adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0,
332                                                     0.0, 0.0, 0.0));
333
334  if (viewport->vadjustment != adjustment)
335    {
336      viewport->vadjustment = adjustment;
337      gtk_object_ref (GTK_OBJECT (viewport->vadjustment));
338      gtk_object_sink (GTK_OBJECT (viewport->vadjustment));
339     
340      gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
341                          (GtkSignalFunc) gtk_viewport_adjustment_changed,
342                          (gpointer) viewport);
343      gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
344                          (GtkSignalFunc) gtk_viewport_adjustment_value_changed,
345                          (gpointer) viewport);
346
347      gtk_viewport_adjustment_changed (adjustment, viewport);
348    }
349}
350
351static void
352gtk_viewport_set_scroll_adjustments (GtkViewport      *viewport,
353                                     GtkAdjustment    *hadjustment,
354                                     GtkAdjustment    *vadjustment)
355{
356  if (viewport->hadjustment != hadjustment)
357    gtk_viewport_set_hadjustment (viewport, hadjustment);
358  if (viewport->vadjustment != vadjustment)
359    gtk_viewport_set_vadjustment (viewport, vadjustment);
360}
361
362void
363gtk_viewport_set_shadow_type (GtkViewport   *viewport,
364                              GtkShadowType  type)
365{
366  g_return_if_fail (viewport != NULL);
367  g_return_if_fail (GTK_IS_VIEWPORT (viewport));
368
369  if ((GtkShadowType) viewport->shadow_type != type)
370    {
371      viewport->shadow_type = type;
372
373      if (GTK_WIDGET_VISIBLE (viewport))
374        {
375          gtk_widget_size_allocate (GTK_WIDGET (viewport), &(GTK_WIDGET (viewport)->allocation));
376          gtk_widget_queue_draw (GTK_WIDGET (viewport));
377        }
378    }
379}
380
381
382static void
383gtk_viewport_map (GtkWidget *widget)
384{
385  GtkBin *bin;
386
387  g_return_if_fail (widget != NULL);
388  g_return_if_fail (GTK_IS_VIEWPORT (widget));
389
390  GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
391  bin = GTK_BIN (widget);
392
393  if (bin->child &&
394      GTK_WIDGET_VISIBLE (bin->child) &&
395      !GTK_WIDGET_MAPPED (bin->child))
396    gtk_widget_map (bin->child);
397
398  gdk_window_show (widget->window);
399}
400
401static void
402gtk_viewport_unmap (GtkWidget *widget)
403{
404  g_return_if_fail (widget != NULL);
405  g_return_if_fail (GTK_IS_VIEWPORT (widget));
406
407  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
408 
409  gdk_window_hide (widget->window);
410}
411
412static void
413gtk_viewport_realize (GtkWidget *widget)
414{
415  GtkBin *bin;
416  GtkViewport *viewport;
417  GdkWindowAttr attributes;
418  gint attributes_mask;
419  gint event_mask;
420  gint border_width;
421
422  g_return_if_fail (widget != NULL);
423  g_return_if_fail (GTK_IS_VIEWPORT (widget));
424
425  border_width = GTK_CONTAINER (widget)->border_width;
426
427  bin = GTK_BIN (widget);
428  viewport = GTK_VIEWPORT (widget);
429  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
430
431  attributes.x = widget->allocation.x + border_width;
432  attributes.y = widget->allocation.y + border_width;
433  attributes.width = widget->allocation.width - border_width * 2;
434  attributes.height = widget->allocation.height - border_width * 2;
435  attributes.window_type = GDK_WINDOW_CHILD;
436  attributes.wclass = GDK_INPUT_OUTPUT;
437  attributes.visual = gtk_widget_get_visual (widget);
438  attributes.colormap = gtk_widget_get_colormap (widget);
439
440  event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
441  /* We select on button_press_mask so that button 4-5 scrolls are trapped.
442   */
443  attributes.event_mask = event_mask | GDK_BUTTON_PRESS_MASK;
444
445  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
446
447  widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
448                                   &attributes, attributes_mask);
449  gdk_window_set_user_data (widget->window, viewport);
450
451  if (viewport->shadow_type != GTK_SHADOW_NONE)
452    {
453      attributes.x = widget->style->klass->xthickness;
454      attributes.y = widget->style->klass->ythickness;
455    }
456  else
457    {
458      attributes.x = 0;
459      attributes.y = 0;
460    }
461
462  attributes.width = MAX (1, (gint)widget->allocation.width - attributes.x * 2 - border_width * 2);
463  attributes.height = MAX (1, (gint)widget->allocation.height - attributes.y * 2 - border_width * 2);
464  attributes.event_mask = 0;
465
466  viewport->view_window = gdk_window_new (widget->window, &attributes, attributes_mask);
467  gdk_window_set_user_data (viewport->view_window, viewport);
468
469  attributes.x = 0;
470  attributes.y = 0;
471
472  if (bin->child)
473    {
474      attributes.width = viewport->hadjustment->upper;
475      attributes.height = viewport->vadjustment->upper;
476    }
477 
478  attributes.event_mask = event_mask;
479
480  viewport->bin_window = gdk_window_new (viewport->view_window, &attributes, attributes_mask);
481  gdk_window_set_user_data (viewport->bin_window, viewport);
482
483  if (bin->child)
484    gtk_widget_set_parent_window (bin->child, viewport->bin_window);
485
486  widget->style = gtk_style_attach (widget->style, widget->window);
487  gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
488  gtk_style_set_background (widget->style, viewport->bin_window, GTK_STATE_NORMAL);
489
490   gtk_paint_flat_box(widget->style, viewport->bin_window, GTK_STATE_NORMAL,
491                      GTK_SHADOW_NONE,
492                      NULL, widget, "viewportbin",
493                      0, 0, -1, -1);
494   
495  gdk_window_show (viewport->bin_window);
496  gdk_window_show (viewport->view_window);
497}
498
499static void
500gtk_viewport_unrealize (GtkWidget *widget)
501{
502  GtkViewport *viewport;
503
504  g_return_if_fail (widget != NULL);
505  g_return_if_fail (GTK_IS_VIEWPORT (widget));
506
507  viewport = GTK_VIEWPORT (widget);
508
509  gdk_window_set_user_data (viewport->view_window, NULL);
510  gdk_window_destroy (viewport->view_window);
511  viewport->view_window = NULL;
512
513  gdk_window_set_user_data (viewport->bin_window, NULL);
514  gdk_window_destroy (viewport->bin_window);
515  viewport->bin_window = NULL;
516
517  if (GTK_WIDGET_CLASS (parent_class)->unrealize)
518    (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
519}
520
521static void
522gtk_viewport_paint (GtkWidget    *widget,
523                    GdkRectangle *area)
524{
525  GtkViewport *viewport;
526
527  g_return_if_fail (widget != NULL);
528  g_return_if_fail (GTK_IS_VIEWPORT (widget));
529  g_return_if_fail (area != NULL);
530
531  if (GTK_WIDGET_DRAWABLE (widget))
532    {
533      viewport = GTK_VIEWPORT (widget);
534
535      gtk_draw_shadow (widget->style, widget->window,
536                       GTK_STATE_NORMAL, viewport->shadow_type,
537                       0, 0, -1, -1);
538    }
539}
540
541static void
542gtk_viewport_draw (GtkWidget    *widget,
543                   GdkRectangle *area)
544{
545  GtkViewport *viewport;
546  GtkBin *bin;
547  GdkRectangle tmp_area;
548  GdkRectangle child_area;
549  gint border_width;
550
551  g_return_if_fail (widget != NULL);
552  g_return_if_fail (GTK_IS_VIEWPORT (widget));
553  g_return_if_fail (area != NULL);
554
555  if (GTK_WIDGET_DRAWABLE (widget))
556    {
557      viewport = GTK_VIEWPORT (widget);
558      bin = GTK_BIN (widget);
559
560      border_width = GTK_CONTAINER (widget)->border_width;
561     
562      tmp_area = *area;
563      tmp_area.x -= border_width;
564      tmp_area.y -= border_width;
565     
566      gtk_viewport_paint (widget, &tmp_area);
567
568      tmp_area.x += viewport->hadjustment->value - widget->style->klass->xthickness;
569      tmp_area.y += viewport->vadjustment->value - widget->style->klass->ythickness;
570     
571      gtk_paint_flat_box(widget->style, viewport->bin_window,
572                         GTK_STATE_NORMAL, GTK_SHADOW_NONE,
573                         &tmp_area, widget, "viewportbin",
574                         0, 0, -1, -1);
575
576      if (bin->child)
577        {
578          if (gtk_widget_intersect (bin->child, &tmp_area, &child_area))
579            gtk_widget_draw (bin->child, &child_area);
580        }
581    }
582}
583
584static gint
585gtk_viewport_expose (GtkWidget      *widget,
586                     GdkEventExpose *event)
587{
588  GtkViewport *viewport;
589  GtkBin *bin;
590  GdkEventExpose child_event;
591
592  g_return_val_if_fail (widget != NULL, FALSE);
593  g_return_val_if_fail (GTK_IS_VIEWPORT (widget), FALSE);
594  g_return_val_if_fail (event != NULL, FALSE);
595
596  if (GTK_WIDGET_DRAWABLE (widget))
597    {
598      viewport = GTK_VIEWPORT (widget);
599      bin = GTK_BIN (widget);
600
601      if (event->window == widget->window)
602        gtk_viewport_paint (widget, &event->area);
603      else if (event->window == viewport->bin_window)
604        {
605          child_event = *event;
606
607          gtk_paint_flat_box(widget->style, viewport->bin_window,
608                             GTK_STATE_NORMAL, GTK_SHADOW_NONE,
609                             &event->area, widget, "viewportbin",
610                             0, 0, -1, -1);
611         
612          if ((bin->child != NULL) &&
613              GTK_WIDGET_NO_WINDOW (bin->child) &&
614              gtk_widget_intersect (bin->child, &event->area, &child_event.area))
615            gtk_widget_event (bin->child, (GdkEvent*) &child_event);
616        }
617       
618
619    }
620
621  return FALSE;
622}
623
624static void
625gtk_viewport_add (GtkContainer *container,
626                  GtkWidget    *child)
627{
628  GtkBin *bin;
629
630  g_return_if_fail (container != NULL);
631  g_return_if_fail (GTK_IS_VIEWPORT (container));
632  g_return_if_fail (child != NULL);
633
634  bin = GTK_BIN (container);
635  g_return_if_fail (bin->child == NULL);
636
637  gtk_widget_set_parent_window (child, GTK_VIEWPORT (bin)->bin_window);
638
639  GTK_CONTAINER_CLASS (parent_class)->add (container, child);
640}
641
642static void
643gtk_viewport_size_request (GtkWidget      *widget,
644                           GtkRequisition *requisition)
645{
646  GtkViewport *viewport;
647  GtkBin *bin;
648  GtkRequisition child_requisition;
649
650  g_return_if_fail (widget != NULL);
651  g_return_if_fail (GTK_IS_VIEWPORT (widget));
652  g_return_if_fail (requisition != NULL);
653
654  viewport = GTK_VIEWPORT (widget);
655  bin = GTK_BIN (widget);
656
657  requisition->width = (GTK_CONTAINER (widget)->border_width +
658                        GTK_WIDGET (widget)->style->klass->xthickness) * 2 + 5;
659
660  requisition->height = (GTK_CONTAINER (widget)->border_width * 2 +
661                         GTK_WIDGET (widget)->style->klass->ythickness) * 2 + 5;
662
663  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
664    {
665      gtk_widget_size_request (bin->child, &child_requisition);
666      requisition->width += child_requisition.width;
667      requisition->height += child_requisition.height;
668    }
669}
670
671static void
672gtk_viewport_size_allocate (GtkWidget     *widget,
673                            GtkAllocation *allocation)
674{
675  GtkViewport *viewport;
676  GtkBin *bin;
677  GtkAllocation child_allocation;
678  gint hval, vval;
679  gint border_width;
680
681  g_return_if_fail (widget != NULL);
682  g_return_if_fail (GTK_IS_VIEWPORT (widget));
683  g_return_if_fail (allocation != NULL);
684
685  widget->allocation = *allocation;
686  viewport = GTK_VIEWPORT (widget);
687  bin = GTK_BIN (widget);
688
689  border_width = GTK_CONTAINER (widget)->border_width;
690
691  child_allocation.x = 0;
692  child_allocation.y = 0;
693
694  if (viewport->shadow_type != GTK_SHADOW_NONE)
695    {
696      child_allocation.x = GTK_WIDGET (viewport)->style->klass->xthickness;
697      child_allocation.y = GTK_WIDGET (viewport)->style->klass->ythickness;
698    }
699
700  child_allocation.width = MAX (1, allocation->width - child_allocation.x * 2 - border_width * 2);
701  child_allocation.height = MAX (1, allocation->height - child_allocation.y * 2 - border_width * 2);
702
703  if (GTK_WIDGET_REALIZED (widget))
704    {
705      gdk_window_move_resize (widget->window,
706                              allocation->x + border_width,
707                              allocation->y + border_width,
708                              allocation->width - border_width * 2,
709                              allocation->height - border_width * 2);
710
711      gdk_window_move_resize (viewport->view_window,
712                              child_allocation.x,
713                              child_allocation.y,
714                              child_allocation.width,
715                              child_allocation.height);
716    }
717
718  viewport->hadjustment->page_size = child_allocation.width;
719  viewport->hadjustment->page_increment = viewport->hadjustment->page_size / 2;
720  viewport->hadjustment->step_increment = 10;
721
722  viewport->vadjustment->page_size = child_allocation.height;
723  viewport->vadjustment->page_increment = viewport->vadjustment->page_size / 2;
724  viewport->vadjustment->step_increment = 10;
725
726  hval = viewport->hadjustment->value;
727  vval = viewport->vadjustment->value;
728
729  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
730    {
731      GtkRequisition child_requisition;
732      gtk_widget_get_child_requisition (bin->child, &child_requisition);
733     
734      viewport->hadjustment->lower = 0;
735      viewport->hadjustment->upper = MAX (child_requisition.width,
736                                          child_allocation.width);
737
738      hval = CLAMP (hval, 0,
739                    viewport->hadjustment->upper -
740                    viewport->hadjustment->page_size);
741
742      viewport->vadjustment->lower = 0;
743      viewport->vadjustment->upper = MAX (child_requisition.height,
744                                          child_allocation.height);
745
746      vval = CLAMP (vval, 0,
747                    viewport->vadjustment->upper -
748                    viewport->vadjustment->page_size);
749    }
750
751  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
752    {
753      child_allocation.x = 0;
754      child_allocation.y = 0;
755
756      child_allocation.width = viewport->hadjustment->upper;
757      child_allocation.height = viewport->vadjustment->upper;
758
759      if (GTK_WIDGET_REALIZED (widget))
760        gdk_window_resize (viewport->bin_window,
761                           child_allocation.width,
762                           child_allocation.height);
763
764      child_allocation.x = 0;
765      child_allocation.y = 0;
766      gtk_widget_size_allocate (bin->child, &child_allocation);
767    }
768
769  gtk_signal_emit_by_name (GTK_OBJECT (viewport->hadjustment), "changed");
770  gtk_signal_emit_by_name (GTK_OBJECT (viewport->vadjustment), "changed");
771  if (viewport->hadjustment->value != hval)
772    {
773      viewport->hadjustment->value = hval;
774      gtk_signal_emit_by_name (GTK_OBJECT (viewport->hadjustment), "value_changed");
775    }
776  if (viewport->vadjustment->value != vval)
777    {
778      viewport->vadjustment->value = vval;
779      gtk_signal_emit_by_name (GTK_OBJECT (viewport->vadjustment), "value_changed");
780    }
781}
782
783static void
784gtk_viewport_adjustment_changed (GtkAdjustment *adjustment,
785                                 gpointer       data)
786{
787  GtkViewport *viewport;
788
789  g_return_if_fail (adjustment != NULL);
790  g_return_if_fail (data != NULL);
791  g_return_if_fail (GTK_IS_VIEWPORT (data));
792
793  viewport = GTK_VIEWPORT (data);
794}
795
796static void
797gtk_viewport_adjustment_value_changed (GtkAdjustment *adjustment,
798                                       gpointer       data)
799{
800  GtkViewport *viewport;
801  GtkBin *bin;
802  GtkAllocation child_allocation;
803
804  g_return_if_fail (adjustment != NULL);
805  g_return_if_fail (data != NULL);
806  g_return_if_fail (GTK_IS_VIEWPORT (data));
807
808  viewport = GTK_VIEWPORT (data);
809  bin = GTK_BIN (data);
810
811  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
812    {
813      child_allocation.x = 0;
814      child_allocation.y = 0;
815
816      if (viewport->hadjustment->lower != (viewport->hadjustment->upper -
817                                           viewport->hadjustment->page_size))
818        child_allocation.x =  viewport->hadjustment->lower - viewport->hadjustment->value;
819
820      if (viewport->vadjustment->lower != (viewport->vadjustment->upper -
821                                           viewport->vadjustment->page_size))
822        child_allocation.y = viewport->vadjustment->lower - viewport->vadjustment->value;
823
824      if (GTK_WIDGET_REALIZED (viewport))
825        gdk_window_move (viewport->bin_window,
826                         child_allocation.x,
827                         child_allocation.y);
828    }
829}
830
831static void
832gtk_viewport_style_set (GtkWidget *widget,
833                        GtkStyle  *previous_style)
834{
835   GtkViewport *viewport;
836   
837   if (GTK_WIDGET_REALIZED (widget) &&
838       !GTK_WIDGET_NO_WINDOW (widget))
839     {
840        viewport = GTK_VIEWPORT (widget);
841       
842        gtk_style_set_background (widget->style, viewport->bin_window, GTK_STATE_NORMAL);
843        gtk_style_set_background (widget->style, widget->window, widget->state);
844     }
845}
Note: See TracBrowser for help on using the repository browser.