gtkvbbox.c 7.78 KB
Newer Older
Elliot Lee's avatar
Elliot Lee committed
1 2 3 4
/* GTK - The GIMP Toolkit
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
Elliot Lee's avatar
Elliot Lee committed
6 7 8 9 10 11
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Lesser General Public License for more details.
Elliot Lee's avatar
Elliot Lee committed
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
15 16 17
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
Elliot Lee's avatar
Elliot Lee committed
18
 */
19 20

/*
21
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22 23 24 25 26
 * file for a list of people on the GTK+ Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
 */

Elliot Lee's avatar
Elliot Lee committed
27 28 29 30 31 32 33 34 35 36 37
#include "gtkvbbox.h"


static void gtk_vbutton_box_class_init    (GtkVButtonBoxClass   *klass);
static void gtk_vbutton_box_init          (GtkVButtonBox        *box);
static void gtk_vbutton_box_size_request  (GtkWidget      *widget,
					   GtkRequisition *requisition);
static void gtk_vbutton_box_size_allocate (GtkWidget      *widget,
					   GtkAllocation  *allocation);

static gint default_spacing = 10;
38
static GtkButtonBoxStyle default_layout_style = GTK_BUTTONBOX_EDGE;
Elliot Lee's avatar
Elliot Lee committed
39

Manish Singh's avatar
Manish Singh committed
40
GType
41
gtk_vbutton_box_get_type (void)
Elliot Lee's avatar
Elliot Lee committed
42
{
Manish Singh's avatar
Manish Singh committed
43
  static GType vbutton_box_type = 0;
Elliot Lee's avatar
Elliot Lee committed
44 45 46

  if (!vbutton_box_type)
    {
Manish Singh's avatar
Manish Singh committed
47
      static const GTypeInfo vbutton_box_info =
Elliot Lee's avatar
Elliot Lee committed
48 49
      {
	sizeof (GtkVButtonBoxClass),
Manish Singh's avatar
Manish Singh committed
50 51 52 53 54 55 56 57
	NULL,		/* base_init */
	NULL,		/* base_finalize */
	(GClassInitFunc) gtk_vbutton_box_class_init,
	NULL,		/* class_finalize */
	NULL,		/* class_data */
	sizeof (GtkVButtonBox),
	0,		/* n_preallocs */
	(GInstanceInitFunc) gtk_vbutton_box_init,
Elliot Lee's avatar
Elliot Lee committed
58 59
      };

Manish Singh's avatar
Manish Singh committed
60 61 62
      vbutton_box_type =
	g_type_register_static (GTK_TYPE_BUTTON_BOX, "GtkVButtonBox",
				&vbutton_box_info, 0);
Elliot Lee's avatar
Elliot Lee committed
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
    }

  return vbutton_box_type;
}

static void
gtk_vbutton_box_class_init (GtkVButtonBoxClass *class)
{
  GtkWidgetClass *widget_class;

  widget_class = (GtkWidgetClass*) class;

  widget_class->size_request = gtk_vbutton_box_size_request;
  widget_class->size_allocate = gtk_vbutton_box_size_allocate;
}

static void
gtk_vbutton_box_init (GtkVButtonBox *vbutton_box)
{
  /* button_box_init has done everything allready */
}

GtkWidget*
86
gtk_vbutton_box_new (void)
Elliot Lee's avatar
Elliot Lee committed
87 88 89
{
  GtkVButtonBox *vbutton_box;

Manish Singh's avatar
Manish Singh committed
90 91
  vbutton_box = g_object_new (GTK_TYPE_VBUTTON_BOX, NULL);

Elliot Lee's avatar
Elliot Lee committed
92 93 94 95 96 97 98
  return GTK_WIDGET (vbutton_box);
}



/* set default value for spacing */

99 100
void
gtk_vbutton_box_set_spacing_default (gint spacing)
Elliot Lee's avatar
Elliot Lee committed
101 102 103 104 105 106 107
{
  default_spacing = spacing;
}


/* set default value for layout style */

108 109
void
gtk_vbutton_box_set_layout_default (GtkButtonBoxStyle layout)
Elliot Lee's avatar
Elliot Lee committed
110
{
111 112 113
  g_return_if_fail (layout >= GTK_BUTTONBOX_DEFAULT_STYLE &&
		    layout <= GTK_BUTTONBOX_END);

Elliot Lee's avatar
Elliot Lee committed
114 115 116 117 118
  default_layout_style = layout;
}

/* get default value for spacing */

119 120
gint
gtk_vbutton_box_get_spacing_default (void)
Elliot Lee's avatar
Elliot Lee committed
121 122 123 124 125 126 127 128
{
  return default_spacing;
}



/* get default value for layout style */

129 130
GtkButtonBoxStyle
gtk_vbutton_box_get_layout_default (void)
Elliot Lee's avatar
Elliot Lee committed
131 132 133 134 135 136
{
  return default_layout_style;
}



137

Elliot Lee's avatar
Elliot Lee committed
138 139 140 141 142 143 144 145 146 147
static void
gtk_vbutton_box_size_request (GtkWidget      *widget,
			      GtkRequisition *requisition)
{
  GtkBox *box;
  GtkButtonBox *bbox;
  gint nvis_children;
  gint child_width;
  gint child_height;
  gint spacing;
148
  GtkButtonBoxStyle layout;
Elliot Lee's avatar
Elliot Lee committed
149 150 151 152
  
  box = GTK_BOX (widget);
  bbox = GTK_BUTTON_BOX (widget);

153
  spacing = box->spacing;
154
  layout = bbox->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE
Elliot Lee's avatar
Elliot Lee committed
155 156
	  ? bbox->layout_style : default_layout_style;
  
157 158
  _gtk_button_box_child_requisition (widget,
                                     &nvis_children,
159
				     NULL,
160 161
                                     &child_width,
                                     &child_height);
Elliot Lee's avatar
Elliot Lee committed
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199

  if (nvis_children == 0)
    {
      requisition->width = 0; 
      requisition->height = 0;
    }
  else
    {
      switch (layout)
      {
      case GTK_BUTTONBOX_SPREAD:
        requisition->height =
		nvis_children*child_height + ((nvis_children+1)*spacing);
	break;
      case GTK_BUTTONBOX_EDGE:
      case GTK_BUTTONBOX_START:
      case GTK_BUTTONBOX_END:
        requisition->height =
		nvis_children*child_height + ((nvis_children-1)*spacing);
	break;
      default:
	    g_assert_not_reached();
	    break;
      }
	  
      requisition->width = child_width;
    }
	  
  requisition->width += GTK_CONTAINER (box)->border_width * 2;
  requisition->height += GTK_CONTAINER (box)->border_width * 2;
}



static void
gtk_vbutton_box_size_allocate (GtkWidget     *widget,
			       GtkAllocation *allocation)
{
200
  GtkBox *base_box;
Elliot Lee's avatar
Elliot Lee committed
201 202 203 204 205 206
  GtkButtonBox *box;
  GtkVButtonBox *hbox;
  GtkBoxChild *child;
  GList *children;
  GtkAllocation child_allocation;
  gint nvis_children;
207
  gint n_secondaries;
Elliot Lee's avatar
Elliot Lee committed
208 209 210 211
  gint child_width;
  gint child_height;
  gint x = 0;
  gint y = 0;
212
  gint secondary_y = 0;
Elliot Lee's avatar
Elliot Lee committed
213 214 215
  gint height;
  gint childspace;
  gint childspacing = 0;
216
  GtkButtonBoxStyle layout;
Elliot Lee's avatar
Elliot Lee committed
217 218
  gint spacing;
  
219
  base_box = GTK_BOX (widget);
Elliot Lee's avatar
Elliot Lee committed
220 221
  box = GTK_BUTTON_BOX (widget);
  hbox = GTK_VBUTTON_BOX (widget);
222
  spacing = base_box->spacing;
223
  layout = box->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE
Elliot Lee's avatar
Elliot Lee committed
224
	  ? box->layout_style : default_layout_style;
225 226
  _gtk_button_box_child_requisition (widget,
                                     &nvis_children,
227
				     &n_secondaries,
228 229
                                     &child_width,
                                     &child_height);
Elliot Lee's avatar
Elliot Lee committed
230 231 232 233 234
  widget->allocation = *allocation;
  height = allocation->height - GTK_CONTAINER (box)->border_width*2;
  switch (layout)
  {
  case GTK_BUTTONBOX_SPREAD:
235
    childspacing = (height - (nvis_children * child_height)) / (nvis_children + 1);
Elliot Lee's avatar
Elliot Lee committed
236
    y = allocation->y + GTK_CONTAINER (box)->border_width + childspacing;
237
    secondary_y = y + ((nvis_children - n_secondaries) * (child_height + childspacing));
Elliot Lee's avatar
Elliot Lee committed
238 239 240 241
    break;
  case GTK_BUTTONBOX_EDGE:
    if (nvis_children >= 2)
      {
242
        childspacing = (height - (nvis_children*child_height)) / (nvis_children-1);
Elliot Lee's avatar
Elliot Lee committed
243
	y = allocation->y + GTK_CONTAINER (box)->border_width;
244
	secondary_y = y + ((nvis_children - n_secondaries) * (child_height + childspacing));
Elliot Lee's avatar
Elliot Lee committed
245 246 247
      }
    else
      {
248 249 250
	/* one or zero children, just center */
	childspacing = height;
	y = secondary_y = allocation->y + (allocation->height - child_height) / 2;
Elliot Lee's avatar
Elliot Lee committed
251 252 253 254 255
      }
    break;
  case GTK_BUTTONBOX_START:
    childspacing = spacing;
    y = allocation->y + GTK_CONTAINER (box)->border_width;
256 257 258 259
    secondary_y = allocation->y + allocation->height
      - child_height * n_secondaries
      - spacing * (n_secondaries - 1)
      - GTK_CONTAINER (box)->border_width;
Elliot Lee's avatar
Elliot Lee committed
260 261 262
    break;
  case GTK_BUTTONBOX_END:
    childspacing = spacing;
263 264 265 266 267
    y = allocation->y + allocation->height 
      - child_height * (nvis_children - n_secondaries)
      - spacing * (nvis_children - n_secondaries - 1)
      - GTK_CONTAINER (box)->border_width;
    secondary_y = allocation->y + GTK_CONTAINER (box)->border_width;
Elliot Lee's avatar
Elliot Lee committed
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
    break;
  default:
    g_assert_not_reached();
    break;
  }
		  
  
  x = allocation->x + (allocation->width - child_width) / 2;
  childspace = child_height + childspacing;

  children = GTK_BOX (box)->children;
	  
  while (children)
    {
      child = children->data;
      children = children->next;

      if (GTK_WIDGET_VISIBLE (child->widget))
	{
	  child_allocation.width = child_width;
	  child_allocation.height = child_height;
	  child_allocation.x = x;
290 291 292 293 294 295 296 297 298 299 300 301
	  
	  if (child->is_secondary)
	    {
	      child_allocation.y = secondary_y;
	      secondary_y += childspace;
	    }
	  else
	    {
	      child_allocation.y = y;
	      y += childspace;
	    }
	  
Elliot Lee's avatar
Elliot Lee committed
302 303 304 305 306 307
	  gtk_widget_size_allocate (child->widget, &child_allocation);
	}
    }
}