| 1 /* GTK - The GIMP Toolkit |
|
| 2 * |
|
| 3 * Copyright (C) 2003 Sun Microsystems, Inc. |
|
| 4 * |
|
| 5 * This library is free software; you can redistribute it and/or |
|
| 6 * modify it under the terms of the GNU Library General Public |
|
| 7 * License as published by the Free Software Foundation; either |
|
| 8 * version 2 of the License, or (at your option) any later version. |
|
| 9 * |
|
| 10 * This library is distributed in the hope that it will be useful, |
|
| 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
| 13 * Library General Public License for more details. |
|
| 14 * |
|
| 15 * You should have received a copy of the GNU Library General Public |
|
| 16 * License along with this library; if not, write to the |
|
| 17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
|
| 18 * Boston, MA 02111-1307, USA. |
|
| 19 * |
|
| 20 * Authors: |
|
| 21 * Mark McLoughlin <mark@skynet.ie> |
|
| 22 */ |
|
| 23 |
|
| 24 /* |
|
| 25 #include <config.h> |
|
| 26 */ |
|
| 27 |
|
| 28 #include <gtk/gtkversion.h> |
|
| 29 #if !GTK_CHECK_VERSION(2,4,0) |
|
| 30 #include "gtkexpander.h" |
|
| 31 |
|
| 32 #include <gtk/gtklabel.h> |
|
| 33 #include <gtk/gtkcontainer.h> |
|
| 34 #include <gtk/gtkmarshal.h> |
|
| 35 #include <gtk/gtkmain.h> |
|
| 36 #include <gtk/gtkprivate.h> |
|
| 37 #include <gdk/gdkkeysyms.h> |
|
| 38 |
|
| 39 #define P_(x) (x) |
|
| 40 |
|
| 41 #define DEFAULT_EXPANDER_SIZE 10 |
|
| 42 #define DEFAULT_EXPANDER_SPACING 2 |
|
| 43 |
|
| 44 enum |
|
| 45 { |
|
| 46 PROP_0, |
|
| 47 PROP_EXPANDED, |
|
| 48 PROP_LABEL, |
|
| 49 PROP_USE_UNDERLINE, |
|
| 50 PROP_USE_MARKUP, |
|
| 51 PROP_SPACING, |
|
| 52 PROP_LABEL_WIDGET |
|
| 53 }; |
|
| 54 |
|
| 55 struct _GtkExpanderPrivate |
|
| 56 { |
|
| 57 GtkWidget *label_widget; |
|
| 58 GdkWindow *event_window; |
|
| 59 gint spacing; |
|
| 60 |
|
| 61 GtkExpanderStyle expander_style; |
|
| 62 guint animation_timeout; |
|
| 63 |
|
| 64 guint expanded : 1; |
|
| 65 guint use_underline : 1; |
|
| 66 guint use_markup : 1; |
|
| 67 guint button_down : 1; |
|
| 68 guint prelight : 1; |
|
| 69 }; |
|
| 70 |
|
| 71 static void gtk_expander_class_init (GtkExpanderClass *klass); |
|
| 72 static void gtk_expander_init (GtkExpander *expander); |
|
| 73 |
|
| 74 static void gtk_expander_set_property (GObject *object, |
|
| 75 guint prop_id, |
|
| 76 const GValue *value, |
|
| 77 GParamSpec *pspec); |
|
| 78 static void gtk_expander_get_property (GObject *object, |
|
| 79 guint prop_id, |
|
| 80 GValue *value, |
|
| 81 GParamSpec *pspec); |
|
| 82 |
|
| 83 static void gtk_expander_finalize (GObject *object); |
|
| 84 |
|
| 85 static void gtk_expander_destroy (GtkObject *object); |
|
| 86 |
|
| 87 static void gtk_expander_realize (GtkWidget *widget); |
|
| 88 static void gtk_expander_unrealize (GtkWidget *widget); |
|
| 89 static void gtk_expander_size_request (GtkWidget *widget, |
|
| 90 GtkRequisition *requisition); |
|
| 91 static void gtk_expander_size_allocate (GtkWidget *widget, |
|
| 92 GtkAllocation *allocation); |
|
| 93 static void gtk_expander_map (GtkWidget *widget); |
|
| 94 static void gtk_expander_unmap (GtkWidget *widget); |
|
| 95 static gboolean gtk_expander_expose (GtkWidget *widget, |
|
| 96 GdkEventExpose *event); |
|
| 97 static gboolean gtk_expander_button_press (GtkWidget *widget, |
|
| 98 GdkEventButton *event); |
|
| 99 static gboolean gtk_expander_button_release (GtkWidget *widget, |
|
| 100 GdkEventButton *event); |
|
| 101 static gboolean gtk_expander_enter_notify (GtkWidget *widget, |
|
| 102 GdkEventCrossing *event); |
|
| 103 static gboolean gtk_expander_leave_notify (GtkWidget *widget, |
|
| 104 GdkEventCrossing *event); |
|
| 105 static gboolean gtk_expander_focus (GtkWidget *widget, |
|
| 106 GtkDirectionType direction); |
|
| 107 static void gtk_expander_grab_notify (GtkWidget *widget, |
|
| 108 gboolean was_grabbed); |
|
| 109 static void gtk_expander_state_changed (GtkWidget *widget, |
|
| 110 GtkStateType previous_state); |
|
| 111 |
|
| 112 static void gtk_expander_add (GtkContainer *container, |
|
| 113 GtkWidget *widget); |
|
| 114 static void gtk_expander_remove (GtkContainer *container, |
|
| 115 GtkWidget *widget); |
|
| 116 static void gtk_expander_forall (GtkContainer *container, |
|
| 117 gboolean include_internals, |
|
| 118 GtkCallback callback, |
|
| 119 gpointer callback_data); |
|
| 120 |
|
| 121 static void gtk_expander_activate (GtkExpander *expander); |
|
| 122 |
|
| 123 static void get_expander_bounds (GtkExpander *expander, |
|
| 124 GdkRectangle *rect); |
|
| 125 |
|
| 126 static GtkBinClass *parent_class = NULL; |
|
| 127 |
|
| 128 GType |
|
| 129 gtk_expander_get_type (void) |
|
| 130 { |
|
| 131 static GType expander_type = 0; |
|
| 132 |
|
| 133 if (!expander_type) |
|
| 134 { |
|
| 135 static const GTypeInfo expander_info = |
|
| 136 { |
|
| 137 sizeof (GtkExpanderClass), |
|
| 138 NULL, /* base_init */ |
|
| 139 NULL, /* base_finalize */ |
|
| 140 (GClassInitFunc) gtk_expander_class_init, |
|
| 141 NULL, /* class_finalize */ |
|
| 142 NULL, /* class_data */ |
|
| 143 sizeof (GtkExpander), |
|
| 144 0, /* n_preallocs */ |
|
| 145 (GInstanceInitFunc) gtk_expander_init, |
|
| 146 }; |
|
| 147 |
|
| 148 expander_type = g_type_register_static (GTK_TYPE_BIN, |
|
| 149 "GtkExpander", |
|
| 150 &expander_info, 0); |
|
| 151 } |
|
| 152 |
|
| 153 return expander_type; |
|
| 154 } |
|
| 155 |
|
| 156 static void |
|
| 157 gtk_expander_class_init (GtkExpanderClass *klass) |
|
| 158 { |
|
| 159 GObjectClass *gobject_class; |
|
| 160 GtkObjectClass *object_class; |
|
| 161 GtkWidgetClass *widget_class; |
|
| 162 GtkContainerClass *container_class; |
|
| 163 |
|
| 164 parent_class = g_type_class_peek_parent (klass); |
|
| 165 |
|
| 166 gobject_class = (GObjectClass *) klass; |
|
| 167 object_class = (GtkObjectClass *) klass; |
|
| 168 widget_class = (GtkWidgetClass *) klass; |
|
| 169 container_class = (GtkContainerClass *) klass; |
|
| 170 |
|
| 171 gobject_class->set_property = gtk_expander_set_property; |
|
| 172 gobject_class->get_property = gtk_expander_get_property; |
|
| 173 gobject_class->finalize = gtk_expander_finalize; |
|
| 174 |
|
| 175 object_class->destroy = gtk_expander_destroy; |
|
| 176 |
|
| 177 widget_class->realize = gtk_expander_realize; |
|
| 178 widget_class->unrealize = gtk_expander_unrealize; |
|
| 179 widget_class->size_request = gtk_expander_size_request; |
|
| 180 widget_class->size_allocate = gtk_expander_size_allocate; |
|
| 181 widget_class->map = gtk_expander_map; |
|
| 182 widget_class->unmap = gtk_expander_unmap; |
|
| 183 widget_class->expose_event = gtk_expander_expose; |
|
| 184 widget_class->button_press_event = gtk_expander_button_press; |
|
| 185 widget_class->button_release_event = gtk_expander_button_release; |
|
| 186 widget_class->enter_notify_event = gtk_expander_enter_notify; |
|
| 187 widget_class->leave_notify_event = gtk_expander_leave_notify; |
|
| 188 widget_class->focus = gtk_expander_focus; |
|
| 189 widget_class->grab_notify = gtk_expander_grab_notify; |
|
| 190 widget_class->state_changed = gtk_expander_state_changed; |
|
| 191 |
|
| 192 container_class->add = gtk_expander_add; |
|
| 193 container_class->remove = gtk_expander_remove; |
|
| 194 container_class->forall = gtk_expander_forall; |
|
| 195 |
|
| 196 klass->activate = gtk_expander_activate; |
|
| 197 |
|
| 198 g_object_class_install_property (gobject_class, |
|
| 199 PROP_EXPANDED, |
|
| 200 g_param_spec_boolean ("expanded", |
|
| 201 P_("Expanded"), |
|
| 202 P_("Whether the expander has been opened to reveal the child widget"), |
|
| 203 FALSE, |
|
| 204 G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); |
|
| 205 |
|
| 206 g_object_class_install_property (gobject_class, |
|
| 207 PROP_LABEL, |
|
| 208 g_param_spec_string ("label", |
|
| 209 P_("Label"), |
|
| 210 P_("Text of the expander's label"), |
|
| 211 NULL, |
|
| 212 G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); |
|
| 213 |
|
| 214 g_object_class_install_property (gobject_class, |
|
| 215 PROP_USE_UNDERLINE, |
|
| 216 g_param_spec_boolean ("use_underline", |
|
| 217 P_("Use underline"), |
|
| 218 P_("If set, an underline in the text indicates the next character should be used for the mnemonic accelerator key"), |
|
| 219 FALSE, |
|
| 220 G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); |
|
| 221 |
|
| 222 g_object_class_install_property (gobject_class, |
|
| 223 PROP_USE_MARKUP, |
|
| 224 g_param_spec_boolean ("use_markup", |
|
| 225 P_("Use markup"), |
|
| 226 P_("The text of the label includes XML markup. See pango_parse_markup()"), |
|
| 227 FALSE, |
|
| 228 G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); |
|
| 229 |
|
| 230 g_object_class_install_property (gobject_class, |
|
| 231 PROP_SPACING, |
|
| 232 g_param_spec_int ("spacing", |
|
| 233 P_("Spacing"), |
|
| 234 P_("Space to put between the label and the child"), |
|
| 235 0, |
|
| 236 G_MAXINT, |
|
| 237 0, |
|
| 238 G_PARAM_READWRITE)); |
|
| 239 |
|
| 240 g_object_class_install_property (gobject_class, |
|
| 241 PROP_LABEL_WIDGET, |
|
| 242 g_param_spec_object ("label_widget", |
|
| 243 P_("Label widget"), |
|
| 244 P_("A widget to display in place of the usual expander label"), |
|
| 245 GTK_TYPE_WIDGET, |
|
| 246 G_PARAM_READWRITE)); |
|
| 247 |
|
| 248 gtk_widget_class_install_style_property (widget_class, |
|
| 249 g_param_spec_int ("expander-size", |
|
| 250 P_("Expander Size"), |
|
| 251 P_("Size of the expander arrow"), |
|
| 252 0, |
|
| 253 G_MAXINT, |
|
| 254 DEFAULT_EXPANDER_SIZE, |
|
| 255 G_PARAM_READABLE)); |
|
| 256 |
|
| 257 gtk_widget_class_install_style_property (widget_class, |
|
| 258 g_param_spec_int ("expander-spacing", |
|
| 259 P_("Indicator Spacing"), |
|
| 260 P_("Spacing around expander arrow"), |
|
| 261 0, |
|
| 262 G_MAXINT, |
|
| 263 DEFAULT_EXPANDER_SPACING, |
|
| 264 G_PARAM_READABLE)); |
|
| 265 |
|
| 266 widget_class->activate_signal = |
|
| 267 g_signal_new ("activate", |
|
| 268 G_TYPE_FROM_CLASS (gobject_class), |
|
| 269 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, |
|
| 270 G_STRUCT_OFFSET (GtkExpanderClass, activate), |
|
| 271 NULL, NULL, |
|
| 272 gtk_marshal_VOID__VOID, |
|
| 273 G_TYPE_NONE, 0); |
|
| 274 } |
|
| 275 |
|
| 276 static void |
|
| 277 gtk_expander_finalize (GObject *obj) |
|
| 278 { |
|
| 279 GtkExpander *self = (GtkExpander *)obj; |
|
| 280 |
|
| 281 g_free(self->priv); |
|
| 282 |
|
| 283 G_OBJECT_CLASS(parent_class)->finalize (obj); |
|
| 284 } |
|
| 285 |
|
| 286 static void |
|
| 287 gtk_expander_init (GtkExpander *expander) |
|
| 288 { |
|
| 289 GtkExpanderPrivate *priv; |
|
| 290 |
|
| 291 expander->priv = priv = g_new0(GtkExpanderPrivate, 1); |
|
| 292 |
|
| 293 GTK_WIDGET_SET_FLAGS (expander, GTK_CAN_FOCUS); |
|
| 294 GTK_WIDGET_SET_FLAGS (expander, GTK_NO_WINDOW); |
|
| 295 |
|
| 296 priv->label_widget = NULL; |
|
| 297 priv->event_window = NULL; |
|
| 298 priv->spacing = 0; |
|
| 299 |
|
| 300 priv->expander_style = GTK_EXPANDER_COLLAPSED; |
|
| 301 priv->animation_timeout = 0; |
|
| 302 |
|
| 303 priv->expanded = FALSE; |
|
| 304 priv->use_underline = FALSE; |
|
| 305 priv->use_markup = FALSE; |
|
| 306 priv->button_down = FALSE; |
|
| 307 priv->prelight = FALSE; |
|
| 308 } |
|
| 309 |
|
| 310 static void |
|
| 311 gtk_expander_set_property (GObject *object, |
|
| 312 guint prop_id, |
|
| 313 const GValue *value, |
|
| 314 GParamSpec *pspec) |
|
| 315 { |
|
| 316 GtkExpander *expander = GTK_EXPANDER (object); |
|
| 317 |
|
| 318 switch (prop_id) |
|
| 319 { |
|
| 320 case PROP_EXPANDED: |
|
| 321 gtk_expander_set_expanded (expander, g_value_get_boolean (value)); |
|
| 322 break; |
|
| 323 case PROP_LABEL: |
|
| 324 gtk_expander_set_label (expander, g_value_get_string (value)); |
|
| 325 break; |
|
| 326 case PROP_USE_UNDERLINE: |
|
| 327 gtk_expander_set_use_underline (expander, g_value_get_boolean (value)); |
|
| 328 break; |
|
| 329 case PROP_USE_MARKUP: |
|
| 330 gtk_expander_set_use_markup (expander, g_value_get_boolean (value)); |
|
| 331 break; |
|
| 332 case PROP_SPACING: |
|
| 333 gtk_expander_set_spacing (expander, g_value_get_int (value)); |
|
| 334 break; |
|
| 335 case PROP_LABEL_WIDGET: |
|
| 336 gtk_expander_set_label_widget (expander, g_value_get_object (value)); |
|
| 337 break; |
|
| 338 default: |
|
| 339 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
|
| 340 break; |
|
| 341 } |
|
| 342 } |
|
| 343 |
|
| 344 static void |
|
| 345 gtk_expander_get_property (GObject *object, |
|
| 346 guint prop_id, |
|
| 347 GValue *value, |
|
| 348 GParamSpec *pspec) |
|
| 349 { |
|
| 350 GtkExpander *expander = GTK_EXPANDER (object); |
|
| 351 GtkExpanderPrivate *priv = expander->priv; |
|
| 352 |
|
| 353 switch (prop_id) |
|
| 354 { |
|
| 355 case PROP_EXPANDED: |
|
| 356 g_value_set_boolean (value, priv->expanded); |
|
| 357 break; |
|
| 358 case PROP_LABEL: |
|
| 359 g_value_set_string (value, gtk_expander_get_label (expander)); |
|
| 360 break; |
|
| 361 case PROP_USE_UNDERLINE: |
|
| 362 g_value_set_boolean (value, priv->use_underline); |
|
| 363 break; |
|
| 364 case PROP_USE_MARKUP: |
|
| 365 g_value_set_boolean (value, priv->use_markup); |
|
| 366 break; |
|
| 367 case PROP_SPACING: |
|
| 368 g_value_set_int (value, priv->spacing); |
|
| 369 break; |
|
| 370 case PROP_LABEL_WIDGET: |
|
| 371 g_value_set_object (value, |
|
| 372 priv->label_widget ? |
|
| 373 G_OBJECT (priv->label_widget) : NULL); |
|
| 374 break; |
|
| 375 default: |
|
| 376 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
|
| 377 break; |
|
| 378 } |
|
| 379 } |
|
| 380 |
|
| 381 static void |
|
| 382 gtk_expander_destroy (GtkObject *object) |
|
| 383 { |
|
| 384 GtkExpanderPrivate *priv = GTK_EXPANDER (object)->priv; |
|
| 385 |
|
| 386 if (priv->animation_timeout) |
|
| 387 { |
|
| 388 g_source_remove (priv->animation_timeout); |
|
| 389 priv->animation_timeout = 0; |
|
| 390 } |
|
| 391 |
|
| 392 GTK_OBJECT_CLASS (parent_class)->destroy (object); |
|
| 393 } |
|
| 394 |
|
| 395 static void |
|
| 396 gtk_expander_realize (GtkWidget *widget) |
|
| 397 { |
|
| 398 GtkExpanderPrivate *priv; |
|
| 399 GdkWindowAttr attributes; |
|
| 400 gint attributes_mask; |
|
| 401 gint border_width; |
|
| 402 GdkRectangle expander_rect; |
|
| 403 |
|
| 404 priv = GTK_EXPANDER (widget)->priv; |
|
| 405 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); |
|
| 406 |
|
| 407 border_width = GTK_CONTAINER (widget)->border_width; |
|
| 408 |
|
| 409 get_expander_bounds (GTK_EXPANDER (widget), &expander_rect); |
|
| 410 |
|
| 411 attributes.window_type = GDK_WINDOW_CHILD; |
|
| 412 attributes.x = widget->allocation.x + border_width; |
|
| 413 attributes.y = expander_rect.y; |
|
| 414 attributes.width = MAX (widget->allocation.width - 2 * border_width, 1); |
|
| 415 attributes.height = expander_rect.width; |
|
| 416 attributes.wclass = GDK_INPUT_ONLY; |
|
| 417 attributes.event_mask = gtk_widget_get_events (widget) | |
|
| 418 GDK_BUTTON_PRESS_MASK | |
|
| 419 GDK_BUTTON_RELEASE_MASK | |
|
| 420 GDK_ENTER_NOTIFY_MASK | |
|
| 421 GDK_LEAVE_NOTIFY_MASK; |
|
| 422 |
|
| 423 attributes_mask = GDK_WA_X | GDK_WA_Y; |
|
| 424 |
|
| 425 widget->window = gtk_widget_get_parent_window (widget); |
|
| 426 g_object_ref (widget->window); |
|
| 427 |
|
| 428 priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget), |
|
| 429 &attributes, attributes_mask); |
|
| 430 gdk_window_set_user_data (priv->event_window, widget); |
|
| 431 |
|
| 432 widget->style = gtk_style_attach (widget->style, widget->window); |
|
| 433 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); |
|
| 434 } |
|
| 435 |
|
| 436 static void |
|
| 437 gtk_expander_unrealize (GtkWidget *widget) |
|
| 438 { |
|
| 439 GtkExpanderPrivate *priv = GTK_EXPANDER (widget)->priv; |
|
| 440 |
|
| 441 if (priv->event_window) |
|
| 442 { |
|
| 443 gdk_window_set_user_data (priv->event_window, NULL); |
|
| 444 gdk_window_destroy (priv->event_window); |
|
| 445 priv->event_window = NULL; |
|
| 446 } |
|
| 447 |
|
| 448 GTK_WIDGET_CLASS (parent_class)->unrealize (widget); |
|
| 449 } |
|
| 450 |
|
| 451 static void |
|
| 452 gtk_expander_size_request (GtkWidget *widget, |
|
| 453 GtkRequisition *requisition) |
|
| 454 { |
|
| 455 GtkExpander *expander; |
|
| 456 GtkBin *bin; |
|
| 457 GtkExpanderPrivate *priv; |
|
| 458 gint border_width; |
|
| 459 gint expander_size; |
|
| 460 gint expander_spacing; |
|
| 461 gboolean interior_focus; |
|
| 462 gint focus_width; |
|
| 463 gint focus_pad; |
|
| 464 |
|
| 465 bin = GTK_BIN (widget); |
|
| 466 expander = GTK_EXPANDER (widget); |
|
| 467 priv = expander->priv; |
|
| 468 |
|
| 469 border_width = GTK_CONTAINER (widget)->border_width; |
|
| 470 |
|
| 471 gtk_widget_style_get (widget, |
|
| 472 "interior-focus", &interior_focus, |
|
| 473 "focus-line-width", &focus_width, |
|
| 474 "focus-padding", &focus_pad, |
|
| 475 "expander-size", &expander_size, |
|
| 476 "expander-spacing", &expander_spacing, |
|
| 477 NULL); |
|
| 478 |
|
| 479 requisition->width = expander_size + 2 * expander_spacing + |
|
| 480 2 * focus_width + 2 * focus_pad; |
|
| 481 requisition->height = interior_focus ? (2 * focus_width + 2 * focus_pad) : 0; |
|
| 482 |
|
| 483 if (priv->label_widget && GTK_WIDGET_VISIBLE (priv->label_widget)) |
|
| 484 { |
|
| 485 GtkRequisition label_requisition; |
|
| 486 |
|
| 487 gtk_widget_size_request (priv->label_widget, &label_requisition); |
|
| 488 |
|
| 489 requisition->width += label_requisition.width; |
|
| 490 requisition->height += label_requisition.height; |
|
| 491 } |
|
| 492 |
|
| 493 requisition->height = MAX (expander_size + 2 * expander_spacing, requisition->height); |
|
| 494 |
|
| 495 if (!interior_focus) |
|
| 496 requisition->height += 2 * focus_width + 2 * focus_pad; |
|
| 497 |
|
| 498 if (bin->child && GTK_WIDGET_CHILD_VISIBLE (bin->child)) |
|
| 499 { |
|
| 500 GtkRequisition child_requisition; |
|
| 501 |
|
| 502 gtk_widget_size_request (bin->child, &child_requisition); |
|
| 503 |
|
| 504 requisition->width = MAX (requisition->width, child_requisition.width); |
|
| 505 requisition->height += child_requisition.height + priv->spacing; |
|
| 506 } |
|
| 507 |
|
| 508 requisition->width += 2 * border_width; |
|
| 509 requisition->height += 2 * border_width; |
|
| 510 } |
|
| 511 |
|
| 512 static void |
|
| 513 get_expander_bounds (GtkExpander *expander, |
|
| 514 GdkRectangle *rect) |
|
| 515 { |
|
| 516 GtkWidget *widget; |
|
| 517 GtkBin *bin; |
|
| 518 GtkExpanderPrivate *priv; |
|
| 519 gint border_width; |
|
| 520 gint expander_size; |
|
| 521 gint expander_spacing; |
|
| 522 gboolean interior_focus; |
|
| 523 gint focus_width; |
|
| 524 gint focus_pad; |
|
| 525 gboolean ltr; |
|
| 526 |
|
| 527 widget = GTK_WIDGET (expander); |
|
| 528 bin = GTK_BIN (expander); |
|
| 529 priv = expander->priv; |
|
| 530 |
|
| 531 border_width = GTK_CONTAINER (expander)->border_width; |
|
| 532 |
|
| 533 gtk_widget_style_get (widget, |
|
| 534 "interior-focus", &interior_focus, |
|
| 535 "focus-line-width", &focus_width, |
|
| 536 "focus-padding", &focus_pad, |
|
| 537 "expander-size", &expander_size, |
|
| 538 "expander-spacing", &expander_spacing, |
|
| 539 NULL); |
|
| 540 |
|
| 541 ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL; |
|
| 542 |
|
| 543 rect->x = widget->allocation.x + border_width; |
|
| 544 rect->y = widget->allocation.y + border_width; |
|
| 545 |
|
| 546 if (ltr) |
|
| 547 rect->x += expander_spacing; |
|
| 548 else |
|
| 549 rect->x += widget->allocation.width - 2 * border_width - |
|
| 550 expander_spacing - expander_size; |
|
| 551 |
|
| 552 if (priv->label_widget && GTK_WIDGET_VISIBLE (priv->label_widget)) |
|
| 553 { |
|
| 554 GtkAllocation label_allocation; |
|
| 555 |
|
| 556 label_allocation = priv->label_widget->allocation; |
|
| 557 |
|
| 558 if (expander_size < label_allocation.height) |
|
| 559 rect->y += focus_width + focus_pad + (label_allocation.height - expander_size) / 2; |
|
| 560 else |
|
| 561 rect->y += expander_spacing; |
|
| 562 } |
|
| 563 else |
|
| 564 { |
|
| 565 rect->y += expander_spacing; |
|
| 566 } |
|
| 567 |
|
| 568 if (!interior_focus) |
|
| 569 { |
|
| 570 if (ltr) |
|
| 571 rect->x += focus_width + focus_pad; |
|
| 572 else |
|
| 573 rect->x -= focus_width + focus_pad; |
|
| 574 rect->y += focus_width + focus_pad; |
|
| 575 } |
|
| 576 |
|
| 577 rect->width = rect->height = expander_size; |
|
| 578 } |
|
| 579 |
|
| 580 static void |
|
| 581 gtk_expander_size_allocate (GtkWidget *widget, |
|
| 582 GtkAllocation *allocation) |
|
| 583 { |
|
| 584 GtkExpander *expander; |
|
| 585 GtkBin *bin; |
|
| 586 GtkExpanderPrivate *priv; |
|
| 587 GtkRequisition child_requisition; |
|
| 588 gboolean child_visible = FALSE; |
|
| 589 gint border_width; |
|
| 590 gint expander_size; |
|
| 591 gint expander_spacing; |
|
| 592 gboolean interior_focus; |
|
| 593 gint focus_width; |
|
| 594 gint focus_pad; |
|
| 595 gint label_height; |
|
| 596 |
|
| 597 expander = GTK_EXPANDER (widget); |
|
| 598 bin = GTK_BIN (widget); |
|
| 599 priv = expander->priv; |
|
| 600 |
|
| 601 border_width = GTK_CONTAINER (widget)->border_width; |
|
| 602 |
|
| 603 gtk_widget_style_get (widget, |
|
| 604 "interior-focus", &interior_focus, |
|
| 605 "focus-line-width", &focus_width, |
|
| 606 "focus-padding", &focus_pad, |
|
| 607 "expander-size", &expander_size, |
|
| 608 "expander-spacing", &expander_spacing, |
|
| 609 NULL); |
|
| 610 |
|
| 611 child_requisition.width = 0; |
|
| 612 child_requisition.height = 0; |
|
| 613 if (bin->child && GTK_WIDGET_CHILD_VISIBLE (bin->child)) |
|
| 614 { |
|
| 615 child_visible = TRUE; |
|
| 616 gtk_widget_get_child_requisition (bin->child, &child_requisition); |
|
| 617 } |
|
| 618 |
|
| 619 widget->allocation = *allocation; |
|
| 620 |
|
| 621 if (priv->label_widget && GTK_WIDGET_VISIBLE (priv->label_widget)) |
|
| 622 { |
|
| 623 GtkAllocation label_allocation; |
|
| 624 GtkRequisition label_requisition; |
|
| 625 gboolean ltr; |
|
| 626 |
|
| 627 gtk_widget_get_child_requisition (priv->label_widget, &label_requisition); |
|
| 628 |
|
| 629 ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL; |
|
| 630 |
|
| 631 if (ltr) |
|
| 632 label_allocation.x = (widget->allocation.x + |
|
| 633 border_width + focus_width + focus_pad + |
|
| 634 expander_size + 2 * expander_spacing); |
|
| 635 else |
|
| 636 label_allocation.x = (widget->allocation.x + widget->allocation.width - |
|
| 637 (label_requisition.width + |
|
| 638 border_width + focus_width + focus_pad + |
|
| 639 expander_size + 2 * expander_spacing)); |
|
| 640 |
|
| 641 label_allocation.y = widget->allocation.y + border_width + focus_width + focus_pad; |
|
| 642 |
|
| 643 label_allocation.width = MIN (label_requisition.width, |
|
| 644 allocation->width - 2 * border_width - |
|
| 645 expander_size - 2 * expander_spacing - |
|
| 646 2 * focus_width - 2 * focus_pad); |
|
| 647 label_allocation.width = MAX (label_allocation.width, 1); |
|
| 648 |
|
| 649 label_allocation.height = MIN (label_requisition.height, |
|
| 650 allocation->height - 2 * border_width - |
|
| 651 2 * focus_width - 2 * focus_pad - |
|
| 652 (child_visible ? priv->spacing : 0)); |
|
| 653 label_allocation.height = MAX (label_allocation.height, 1); |
|
| 654 |
|
| 655 gtk_widget_size_allocate (priv->label_widget, &label_allocation); |
|
| 656 |
|
| 657 label_height = label_allocation.height; |
|
| 658 } |
|
| 659 else |
|
| 660 { |
|
| 661 label_height = 0; |
|
| 662 } |
|
| 663 |
|
| 664 if (GTK_WIDGET_REALIZED (widget)) |
|
| 665 { |
|
| 666 GdkRectangle rect; |
|
| 667 |
|
| 668 get_expander_bounds (expander, &rect); |
|
| 669 |
|
| 670 gdk_window_move_resize (priv->event_window, |
|
| 671 allocation->x + border_width, rect.y, |
|
| 672 MAX (allocation->width - 2 * border_width, 1), rect.width); |
|
| 673 } |
|
| 674 |
|
| 675 if (child_visible) |
|
| 676 { |
|
| 677 GtkAllocation child_allocation; |
|
| 678 gint top_height; |
|
| 679 |
|
| 680 top_height = MAX (2 * expander_spacing + expander_size, |
|
| 681 label_height + |
|
| 682 (interior_focus ? 2 * focus_width + 2 * focus_pad : 0)); |
|
| 683 |
|
| 684 child_allocation.x = widget->allocation.x + border_width; |
|
| 685 child_allocation.y = widget->allocation.y + border_width + top_height + priv->spacing; |
|
| 686 |
|
| 687 if (!interior_focus) |
|
| 688 child_allocation.y += 2 * focus_width + 2 * focus_pad; |
|
| 689 |
|
| 690 child_allocation.width = MAX (allocation->width - 2 * border_width, 1); |
|
| 691 |
|
| 692 child_allocation.height = allocation->height - top_height - |
|
| 693 2 * border_width - priv->spacing - |
|
| 694 (!interior_focus ? 2 * focus_width + 2 * focus_pad : 0); |
|
| 695 child_allocation.height = MAX (child_allocation.height, 1); |
|
| 696 |
|
| 697 gtk_widget_size_allocate (bin->child, &child_allocation); |
|
| 698 } |
|
| 699 } |
|
| 700 |
|
| 701 static void |
|
| 702 gtk_expander_map (GtkWidget *widget) |
|
| 703 { |
|
| 704 GtkExpanderPrivate *priv = GTK_EXPANDER (widget)->priv; |
|
| 705 |
|
| 706 if (priv->label_widget) |
|
| 707 gtk_widget_map (priv->label_widget); |
|
| 708 |
|
| 709 GTK_WIDGET_CLASS (parent_class)->map (widget); |
|
| 710 |
|
| 711 if (priv->event_window) |
|
| 712 gdk_window_show (priv->event_window); |
|
| 713 } |
|
| 714 |
|
| 715 static void |
|
| 716 gtk_expander_unmap (GtkWidget *widget) |
|
| 717 { |
|
| 718 GtkExpanderPrivate *priv = GTK_EXPANDER (widget)->priv; |
|
| 719 |
|
| 720 if (priv->event_window) |
|
| 721 gdk_window_hide (priv->event_window); |
|
| 722 |
|
| 723 GTK_WIDGET_CLASS (parent_class)->unmap (widget); |
|
| 724 |
|
| 725 if (priv->label_widget) |
|
| 726 gtk_widget_unmap (priv->label_widget); |
|
| 727 } |
|
| 728 |
|
| 729 static void |
|
| 730 gtk_expander_paint_prelight (GtkExpander *expander) |
|
| 731 { |
|
| 732 GtkWidget *widget; |
|
| 733 GtkContainer *container; |
|
| 734 GtkExpanderPrivate *priv; |
|
| 735 GdkRectangle area; |
|
| 736 gboolean interior_focus; |
|
| 737 int focus_width; |
|
| 738 int focus_pad; |
|
| 739 int expander_size; |
|
| 740 int expander_spacing; |
|
| 741 |
|
| 742 priv = expander->priv; |
|
| 743 widget = GTK_WIDGET (expander); |
|
| 744 container = GTK_CONTAINER (expander); |
|
| 745 |
|
| 746 gtk_widget_style_get (widget, |
|
| 747 "interior-focus", &interior_focus, |
|
| 748 "focus-line-width", &focus_width, |
|
| 749 "focus-padding", &focus_pad, |
|
| 750 "expander-size", &expander_size, |
|
| 751 "expander-spacing", &expander_spacing, |
|
| 752 NULL); |
|
| 753 |
|
| 754 area.x = widget->allocation.x + container->border_width; |
|
| 755 area.y = widget->allocation.y + container->border_width; |
|
| 756 area.width = widget->allocation.width - (2 * container->border_width); |
|
| 757 |
|
| 758 if (priv->label_widget && GTK_WIDGET_VISIBLE (priv->label_widget)) |
|
| 759 area.height = priv->label_widget->allocation.height; |
|
| 760 else |
|
| 761 area.height = 0; |
|
| 762 |
|
| 763 area.height += interior_focus ? (focus_width + focus_pad) * 2 : 0; |
|
| 764 area.height = MAX (area.height, expander_size + 2 * expander_spacing); |
|
| 765 area.height += !interior_focus ? (focus_width + focus_pad) * 2 : 0; |
|
| 766 |
|
| 767 gtk_paint_flat_box (widget->style, widget->window, |
|
| 768 GTK_STATE_PRELIGHT, |
|
| 769 GTK_SHADOW_ETCHED_OUT, |
|
| 770 &area, widget, "expander", |
|
| 771 area.x, area.y, |
|
| 772 area.width, area.height); |
|
| 773 } |
|
| 774 |
|
| 775 static void |
|
| 776 gtk_expander_paint (GtkExpander *expander) |
|
| 777 { |
|
| 778 GtkWidget *widget; |
|
| 779 GdkRectangle clip; |
|
| 780 GtkStateType state; |
|
| 781 |
|
| 782 widget = GTK_WIDGET (expander); |
|
| 783 |
|
| 784 get_expander_bounds (expander, &clip); |
|
| 785 |
|
| 786 state = widget->state; |
|
| 787 if (expander->priv->prelight) |
|
| 788 { |
|
| 789 state = GTK_STATE_PRELIGHT; |
|
| 790 |
|
| 791 gtk_expander_paint_prelight (expander); |
|
| 792 } |
|
| 793 |
|
| 794 gtk_paint_expander (widget->style, |
|
| 795 widget->window, |
|
| 796 state, |
|
| 797 &clip, |
|
| 798 widget, |
|
| 799 "expander", |
|
| 800 clip.x + clip.width / 2, |
|
| 801 clip.y + clip.height / 2, |
|
| 802 expander->priv->expander_style); |
|
| 803 } |
|
| 804 |
|
| 805 static void |
|
| 806 gtk_expander_paint_focus (GtkExpander *expander, |
|
| 807 GdkRectangle *area) |
|
| 808 { |
|
| 809 GtkWidget *widget; |
|
| 810 GtkExpanderPrivate *priv; |
|
| 811 gint x, y, width, height; |
|
| 812 gboolean interior_focus; |
|
| 813 gint border_width; |
|
| 814 gint focus_width; |
|
| 815 gint focus_pad; |
|
| 816 gint expander_size; |
|
| 817 gint expander_spacing; |
|
| 818 gboolean ltr; |
|
| 819 |
|
| 820 widget = GTK_WIDGET (expander); |
|
| 821 priv = expander->priv; |
|
| 822 |
|
| 823 border_width = GTK_CONTAINER (widget)->border_width; |
|
| 824 |
|
| 825 gtk_widget_style_get (widget, |
|
| 826 "interior-focus", &interior_focus, |
|
| 827 "focus-line-width", &focus_width, |
|
| 828 "focus-padding", &focus_pad, |
|
| 829 "expander-size", &expander_size, |
|
| 830 "expander-spacing", &expander_spacing, |
|
| 831 NULL); |
|
| 832 |
|
| 833 ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL; |
|
| 834 |
|
| 835 x = widget->allocation.x + border_width; |
|
| 836 y = widget->allocation.y + border_width; |
|
| 837 |
|
| 838 if (ltr && interior_focus) |
|
| 839 x += expander_spacing * 2 + expander_size; |
|
| 840 |
|
| 841 width = height = 0; |
|
| 842 |
|
| 843 if (priv->label_widget && GTK_WIDGET_VISIBLE (priv->label_widget)) |
|
| 844 { |
|
| 845 GtkAllocation label_allocation = priv->label_widget->allocation; |
|
| 846 |
|
| 847 width = label_allocation.width; |
|
| 848 height = label_allocation.height; |
|
| 849 } |
|
| 850 |
|
| 851 if (!interior_focus) |
|
| 852 { |
|
| 853 width += expander_size + 2 * expander_spacing; |
|
| 854 height = MAX (height, expander_size + 2 * expander_spacing); |
|
| 855 } |
|
| 856 |
|
| 857 width += 2 * focus_pad + 2 * focus_width; |
|
| 858 height += 2 * focus_pad + 2 * focus_width; |
|
| 859 |
|
| 860 gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget), |
|
| 861 area, widget, "expander", |
|
| 862 x, y, width, height); |
|
| 863 } |
|
| 864 |
|
| 865 static gboolean |
|
| 866 gtk_expander_expose (GtkWidget *widget, |
|
| 867 GdkEventExpose *event) |
|
| 868 { |
|
| 869 if (GTK_WIDGET_DRAWABLE (widget)) |
|
| 870 { |
|
| 871 GtkExpander *expander = GTK_EXPANDER (widget); |
|
| 872 |
|
| 873 gtk_expander_paint (expander); |
|
| 874 |
|
| 875 if (GTK_WIDGET_HAS_FOCUS (expander)) |
|
| 876 gtk_expander_paint_focus (expander, &event->area); |
|
| 877 |
|
| 878 GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event); |
|
| 879 } |
|
| 880 |
|
| 881 return FALSE; |
|
| 882 } |
|
| 883 |
|
| 884 static gboolean |
|
| 885 gtk_expander_button_press (GtkWidget *widget, |
|
| 886 GdkEventButton *event) |
|
| 887 { |
|
| 888 GtkExpander *expander = GTK_EXPANDER (widget); |
|
| 889 |
|
| 890 if (event->button == 1 && event->window == expander->priv->event_window) |
|
| 891 { |
|
| 892 expander->priv->button_down = TRUE; |
|
| 893 return TRUE; |
|
| 894 } |
|
| 895 |
|
| 896 return FALSE; |
|
| 897 } |
|
| 898 |
|
| 899 static gboolean |
|
| 900 gtk_expander_button_release (GtkWidget *widget, |
|
| 901 GdkEventButton *event) |
|
| 902 { |
|
| 903 GtkExpander *expander = GTK_EXPANDER (widget); |
|
| 904 |
|
| 905 if (event->button == 1 && expander->priv->button_down) |
|
| 906 { |
|
| 907 gtk_widget_activate (widget); |
|
| 908 expander->priv->button_down = FALSE; |
|
| 909 return TRUE; |
|
| 910 } |
|
| 911 |
|
| 912 return FALSE; |
|
| 913 } |
|
| 914 |
|
| 915 static void |
|
| 916 gtk_expander_grab_notify (GtkWidget *widget, |
|
| 917 gboolean was_grabbed) |
|
| 918 { |
|
| 919 if (!was_grabbed) |
|
| 920 GTK_EXPANDER (widget)->priv->button_down = FALSE; |
|
| 921 } |
|
| 922 |
|
| 923 static void |
|
| 924 gtk_expander_state_changed (GtkWidget *widget, |
|
| 925 GtkStateType previous_state) |
|
| 926 { |
|
| 927 if (!GTK_WIDGET_IS_SENSITIVE (widget)) |
|
| 928 GTK_EXPANDER (widget)->priv->button_down = FALSE; |
|
| 929 } |
|
| 930 |
|
| 931 static void |
|
| 932 gtk_expander_redraw_expander (GtkExpander *expander) |
|
| 933 { |
|
| 934 GtkWidget *widget; |
|
| 935 |
|
| 936 widget = GTK_WIDGET (expander); |
|
| 937 |
|
| 938 if (GTK_WIDGET_REALIZED (widget)) |
|
| 939 gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE); |
|
| 940 } |
|
| 941 |
|
| 942 static gboolean |
|
| 943 gtk_expander_enter_notify (GtkWidget *widget, |
|
| 944 GdkEventCrossing *event) |
|
| 945 { |
|
| 946 GtkExpander *expander = GTK_EXPANDER (widget); |
|
| 947 GtkWidget *event_widget; |
|
| 948 |
|
| 949 event_widget = gtk_get_event_widget ((GdkEvent *) event); |
|
| 950 |
|
| 951 if (event_widget == widget && |
|
| 952 event->detail != GDK_NOTIFY_INFERIOR) |
|
| 953 { |
|
| 954 expander->priv->prelight = TRUE; |
|
| 955 |
|
| 956 if (expander->priv->label_widget) |
|
| 957 gtk_widget_set_state (expander->priv->label_widget, GTK_STATE_PRELIGHT); |
|
| 958 |
|
| 959 gtk_expander_redraw_expander (expander); |
|
| 960 } |
|
| 961 |
|
| 962 return FALSE; |
|
| 963 } |
|
| 964 |
|
| 965 static gboolean |
|
| 966 gtk_expander_leave_notify (GtkWidget *widget, |
|
| 967 GdkEventCrossing *event) |
|
| 968 { |
|
| 969 GtkExpander *expander = GTK_EXPANDER (widget); |
|
| 970 GtkWidget *event_widget; |
|
| 971 |
|
| 972 event_widget = gtk_get_event_widget ((GdkEvent *) event); |
|
| 973 |
|
| 974 if (event_widget == widget && |
|
| 975 event->detail != GDK_NOTIFY_INFERIOR) |
|
| 976 { |
|
| 977 expander->priv->prelight = FALSE; |
|
| 978 |
|
| 979 if (expander->priv->label_widget) |
|
| 980 gtk_widget_set_state (expander->priv->label_widget, GTK_STATE_NORMAL); |
|
| 981 |
|
| 982 gtk_expander_redraw_expander (expander); |
|
| 983 } |
|
| 984 |
|
| 985 return FALSE; |
|
| 986 } |
|
| 987 |
|
| 988 typedef enum |
|
| 989 { |
|
| 990 FOCUS_NONE, |
|
| 991 FOCUS_WIDGET, |
|
| 992 FOCUS_LABEL, |
|
| 993 FOCUS_CHILD |
|
| 994 } FocusSite; |
|
| 995 |
|
| 996 static gboolean |
|
| 997 focus_current_site (GtkExpander *expander, |
|
| 998 GtkDirectionType direction) |
|
| 999 { |
|
| 1000 GtkWidget *current_focus; |
|
| 1001 |
|
| 1002 current_focus = GTK_CONTAINER (expander)->focus_child; |
|
| 1003 |
|
| 1004 if (!current_focus) |
|
| 1005 return FALSE; |
|
| 1006 |
|
| 1007 return gtk_widget_child_focus (current_focus, direction); |
|
| 1008 } |
|
| 1009 |
|
| 1010 static gboolean |
|
| 1011 focus_in_site (GtkExpander *expander, |
|
| 1012 FocusSite site, |
|
| 1013 GtkDirectionType direction) |
|
| 1014 { |
|
| 1015 switch (site) |
|
| 1016 { |
|
| 1017 case FOCUS_WIDGET: |
|
| 1018 gtk_widget_grab_focus (GTK_WIDGET (expander)); |
|
| 1019 return TRUE; |
|
| 1020 case FOCUS_LABEL: |
|
| 1021 if (expander->priv->label_widget) |
|
| 1022 return gtk_widget_child_focus (expander->priv->label_widget, direction); |
|
| 1023 else |
|
| 1024 return FALSE; |
|
| 1025 case FOCUS_CHILD: |
|
| 1026 { |
|
| 1027 GtkWidget *child = gtk_bin_get_child (GTK_BIN (expander)); |
|
| 1028 |
|
| 1029 if (child && GTK_WIDGET_CHILD_VISIBLE (child)) |
|
| 1030 return gtk_widget_child_focus (child, direction); |
|
| 1031 else |
|
| 1032 return FALSE; |
|
| 1033 } |
|
| 1034 case FOCUS_NONE: |
|
| 1035 break; |
|
| 1036 } |
|
| 1037 |
|
| 1038 g_assert_not_reached (); |
|
| 1039 return FALSE; |
|
| 1040 } |
|
| 1041 |
|
| 1042 static FocusSite |
|
| 1043 get_next_site (GtkExpander *expander, |
|
| 1044 FocusSite site, |
|
| 1045 GtkDirectionType direction) |
|
| 1046 { |
|
| 1047 gboolean ltr; |
|
| 1048 |
|
| 1049 ltr = gtk_widget_get_direction (GTK_WIDGET (expander)) != GTK_TEXT_DIR_RTL; |
|
| 1050 |
|
| 1051 switch (site) |
|
| 1052 { |
|
| 1053 case FOCUS_NONE: |
|
| 1054 switch (direction) |
|
| 1055 { |
|
| 1056 case GTK_DIR_TAB_BACKWARD: |
|
| 1057 case GTK_DIR_LEFT: |
|
| 1058 case GTK_DIR_UP: |
|
| 1059 return FOCUS_CHILD; |
|
| 1060 case GTK_DIR_TAB_FORWARD: |
|
| 1061 case GTK_DIR_DOWN: |
|
| 1062 case GTK_DIR_RIGHT: |
|
| 1063 return FOCUS_WIDGET; |
|
| 1064 } |
|
| 1065 case FOCUS_WIDGET: |
|
| 1066 switch (direction) |
|
| 1067 { |
|
| 1068 case GTK_DIR_TAB_BACKWARD: |
|
| 1069 case GTK_DIR_UP: |
|
| 1070 return FOCUS_NONE; |
|
| 1071 case GTK_DIR_LEFT: |
|
| 1072 return ltr ? FOCUS_NONE : FOCUS_LABEL; |
|
| 1073 case GTK_DIR_TAB_FORWARD: |
|
| 1074 case GTK_DIR_DOWN: |
|
| 1075 return FOCUS_LABEL; |
|
| 1076 case GTK_DIR_RIGHT: |
|
| 1077 return ltr ? FOCUS_LABEL : FOCUS_NONE; |
|
| 1078 break; |
|
| 1079 } |
|
| 1080 case FOCUS_LABEL: |
|
| 1081 switch (direction) |
|
| 1082 { |
|
| 1083 case GTK_DIR_TAB_BACKWARD: |
|
| 1084 case GTK_DIR_UP: |
|
| 1085 return FOCUS_WIDGET; |
|
| 1086 case GTK_DIR_LEFT: |
|
| 1087 return ltr ? FOCUS_WIDGET : FOCUS_CHILD; |
|
| 1088 case GTK_DIR_TAB_FORWARD: |
|
| 1089 case GTK_DIR_DOWN: |
|
| 1090 return FOCUS_CHILD; |
|
| 1091 case GTK_DIR_RIGHT: |
|
| 1092 return ltr ? FOCUS_CHILD : FOCUS_WIDGET; |
|
| 1093 break; |
|
| 1094 } |
|
| 1095 case FOCUS_CHILD: |
|
| 1096 switch (direction) |
|
| 1097 { |
|
| 1098 case GTK_DIR_TAB_BACKWARD: |
|
| 1099 case GTK_DIR_LEFT: |
|
| 1100 case GTK_DIR_UP: |
|
| 1101 return FOCUS_LABEL; |
|
| 1102 case GTK_DIR_TAB_FORWARD: |
|
| 1103 case GTK_DIR_DOWN: |
|
| 1104 case GTK_DIR_RIGHT: |
|
| 1105 return FOCUS_NONE; |
|
| 1106 } |
|
| 1107 } |
|
| 1108 |
|
| 1109 g_assert_not_reached (); |
|
| 1110 return FOCUS_NONE; |
|
| 1111 } |
|
| 1112 |
|
| 1113 static gboolean |
|
| 1114 gtk_expander_focus (GtkWidget *widget, |
|
| 1115 GtkDirectionType direction) |
|
| 1116 { |
|
| 1117 GtkExpander *expander = GTK_EXPANDER (widget); |
|
| 1118 |
|
| 1119 if (!focus_current_site (expander, direction)) |
|
| 1120 { |
|
| 1121 GtkWidget *old_focus_child; |
|
| 1122 gboolean widget_is_focus; |
|
| 1123 FocusSite site = FOCUS_NONE; |
|
| 1124 |
|
| 1125 widget_is_focus = gtk_widget_is_focus (widget); |
|
| 1126 old_focus_child = GTK_CONTAINER (widget)->focus_child; |
|
| 1127 |
|
| 1128 if (old_focus_child && old_focus_child == expander->priv->label_widget) |
|
| 1129 site = FOCUS_LABEL; |
|
| 1130 else if (old_focus_child) |
|
| 1131 site = FOCUS_CHILD; |
|
| 1132 else if (widget_is_focus) |
|
| 1133 site = FOCUS_WIDGET; |
|
| 1134 |
|
| 1135 while ((site = get_next_site (expander, site, direction)) != FOCUS_NONE) |
|
| 1136 { |
|
| 1137 if (focus_in_site (expander, site, direction)) |
|
| 1138 return TRUE; |
|
| 1139 } |
|
| 1140 |
|
| 1141 return FALSE; |
|
| 1142 } |
|
| 1143 |
|
| 1144 return TRUE; |
|
| 1145 } |
|
| 1146 |
|
| 1147 static void |
|
| 1148 gtk_expander_add (GtkContainer *container, |
|
| 1149 GtkWidget *widget) |
|
| 1150 { |
|
| 1151 GTK_CONTAINER_CLASS (parent_class)->add (container, widget); |
|
| 1152 |
|
| 1153 gtk_widget_set_child_visible (widget, GTK_EXPANDER (container)->priv->expanded); |
|
| 1154 gtk_widget_queue_resize (GTK_WIDGET (container)); |
|
| 1155 } |
|
| 1156 |
|
| 1157 static void |
|
| 1158 gtk_expander_remove (GtkContainer *container, |
|
| 1159 GtkWidget *widget) |
|
| 1160 { |
|
| 1161 GtkExpander *expander = GTK_EXPANDER (container); |
|
| 1162 |
|
| 1163 if (GTK_EXPANDER (expander)->priv->label_widget == widget) |
|
| 1164 gtk_expander_set_label_widget (expander, NULL); |
|
| 1165 else |
|
| 1166 GTK_CONTAINER_CLASS (parent_class)->remove (container, widget); |
|
| 1167 } |
|
| 1168 |
|
| 1169 static void |
|
| 1170 gtk_expander_forall (GtkContainer *container, |
|
| 1171 gboolean include_internals, |
|
| 1172 GtkCallback callback, |
|
| 1173 gpointer callback_data) |
|
| 1174 { |
|
| 1175 GtkBin *bin = GTK_BIN (container); |
|
| 1176 GtkExpanderPrivate *priv = GTK_EXPANDER (container)->priv; |
|
| 1177 |
|
| 1178 if (bin->child) |
|
| 1179 (* callback) (bin->child, callback_data); |
|
| 1180 |
|
| 1181 if (priv->label_widget) |
|
| 1182 (* callback) (priv->label_widget, callback_data); |
|
| 1183 } |
|
| 1184 |
|
| 1185 static void |
|
| 1186 gtk_expander_activate (GtkExpander *expander) |
|
| 1187 { |
|
| 1188 gtk_expander_set_expanded (expander, !expander->priv->expanded); |
|
| 1189 } |
|
| 1190 |
|
| 1191 |
|
| 1192 /** |
|
| 1193 * gtk_expander_new: |
|
| 1194 * @label: the text of the label |
|
| 1195 * |
|
| 1196 * Creates a new expander using @label as the text of the label. |
|
| 1197 * |
|
| 1198 * Return value: a new #GtkExpander widget. |
|
| 1199 * |
|
| 1200 * Since: 2.4 |
|
| 1201 **/ |
|
| 1202 GtkWidget * |
|
| 1203 gtk_expander_new (const gchar *label) |
|
| 1204 { |
|
| 1205 return g_object_new (GTK_TYPE_EXPANDER, "label", label, NULL); |
|
| 1206 } |
|
| 1207 |
|
| 1208 /** |
|
| 1209 * gtk_expander_new_with_mnemonic: |
|
| 1210 * @label: the text of the label with an underscore in front of the |
|
| 1211 * mnemonic character |
|
| 1212 * |
|
| 1213 * Creates a new expander using @label as the text of the label. |
|
| 1214 * If characters in @label are preceded by an underscore, they are underlined. |
|
| 1215 * If you need a literal underscore character in a label, use '__' (two |
|
| 1216 * underscores). The first underlined character represents a keyboard |
|
| 1217 * accelerator called a mnemonic. |
|
| 1218 * Pressing Alt and that key activates the button. |
|
| 1219 * |
|
| 1220 * Return value: a new #GtkExpander widget. |
|
| 1221 * |
|
| 1222 * Since: 2.4 |
|
| 1223 **/ |
|
| 1224 GtkWidget * |
|
| 1225 gtk_expander_new_with_mnemonic (const gchar *label) |
|
| 1226 { |
|
| 1227 return g_object_new (GTK_TYPE_EXPANDER, |
|
| 1228 "label", label, |
|
| 1229 "use_underline", TRUE, |
|
| 1230 NULL); |
|
| 1231 } |
|
| 1232 |
|
| 1233 static gboolean |
|
| 1234 gtk_expander_animation_timeout (GtkExpander *expander) |
|
| 1235 { |
|
| 1236 GtkExpanderPrivate *priv = expander->priv; |
|
| 1237 GdkRectangle area; |
|
| 1238 gboolean finish = FALSE; |
|
| 1239 |
|
| 1240 GDK_THREADS_ENTER(); |
|
| 1241 |
|
| 1242 if (GTK_WIDGET_REALIZED (expander)) |
|
| 1243 { |
|
| 1244 get_expander_bounds (expander, &area); |
|
| 1245 gdk_window_invalidate_rect (GTK_WIDGET (expander)->window, &area, TRUE); |
|
| 1246 } |
|
| 1247 |
|
| 1248 if (priv->expanded) |
|
| 1249 { |
|
| 1250 if (priv->expander_style == GTK_EXPANDER_COLLAPSED) |
|
| 1251 { |
|
| 1252 priv->expander_style = GTK_EXPANDER_SEMI_EXPANDED; |
|
| 1253 } |
|
| 1254 else |
|
| 1255 { |
|
| 1256 priv->expander_style = GTK_EXPANDER_EXPANDED; |
|
| 1257 finish = TRUE; |
|
| 1258 } |
|
| 1259 } |
|
| 1260 else |
|
| 1261 { |
|
| 1262 if (priv->expander_style == GTK_EXPANDER_EXPANDED) |
|
| 1263 { |
|
| 1264 priv->expander_style = GTK_EXPANDER_SEMI_COLLAPSED; |
|
| 1265 } |
|
| 1266 else |
|
| 1267 { |
|
| 1268 priv->expander_style = GTK_EXPANDER_COLLAPSED; |
|
| 1269 finish = TRUE; |
|
| 1270 } |
|
| 1271 } |
|
| 1272 |
|
| 1273 if (finish) |
|
| 1274 { |
|
| 1275 priv->animation_timeout = 0; |
|
| 1276 if (GTK_BIN (expander)->child) |
|
| 1277 gtk_widget_set_child_visible (GTK_BIN (expander)->child, priv->expanded); |
|
| 1278 gtk_widget_queue_resize (GTK_WIDGET (expander)); |
|
| 1279 } |
|
| 1280 |
|
| 1281 GDK_THREADS_LEAVE(); |
|
| 1282 |
|
| 1283 return !finish; |
|
| 1284 } |
|
| 1285 |
|
| 1286 static void |
|
| 1287 gtk_expander_start_animation (GtkExpander *expander) |
|
| 1288 { |
|
| 1289 GtkExpanderPrivate *priv = expander->priv; |
|
| 1290 |
|
| 1291 if (priv->animation_timeout) |
|
| 1292 g_source_remove (priv->animation_timeout); |
|
| 1293 |
|
| 1294 priv->animation_timeout = |
|
| 1295 g_timeout_add (50, |
|
| 1296 (GSourceFunc) gtk_expander_animation_timeout, |
|
| 1297 expander); |
|
| 1298 } |
|
| 1299 |
|
| 1300 /** |
|
| 1301 * gtk_expander_set_expanded: |
|
| 1302 * @expander: a #GtkExpander |
|
| 1303 * @expanded: whether the child widget is revealed |
|
| 1304 * |
|
| 1305 * Sets the state of the expander. Set to %TRUE, if you want |
|
| 1306 * the child widget to be revealed, and %FALSE if you want the |
|
| 1307 * child widget to be hidden. |
|
| 1308 * |
|
| 1309 * Since: 2.4 |
|
| 1310 **/ |
|
| 1311 void |
|
| 1312 gtk_expander_set_expanded (GtkExpander *expander, |
|
| 1313 gboolean expanded) |
|
| 1314 { |
|
| 1315 GtkExpanderPrivate *priv; |
|
| 1316 |
|
| 1317 g_return_if_fail (GTK_IS_EXPANDER (expander)); |
|
| 1318 |
|
| 1319 priv = expander->priv; |
|
| 1320 |
|
| 1321 expanded = expanded != FALSE; |
|
| 1322 |
|
| 1323 if (priv->expanded != expanded) |
|
| 1324 { |
|
| 1325 priv->expanded = expanded; |
|
| 1326 |
|
| 1327 if (GTK_WIDGET_REALIZED (expander)) |
|
| 1328 { |
|
| 1329 gtk_expander_start_animation (expander); |
|
| 1330 } |
|
| 1331 else |
|
| 1332 { |
|
| 1333 priv->expander_style = expanded ? GTK_EXPANDER_EXPANDED : |
|
| 1334 GTK_EXPANDER_COLLAPSED; |
|
| 1335 |
|
| 1336 if (GTK_BIN (expander)->child) |
|
| 1337 { |
|
| 1338 gtk_widget_set_child_visible (GTK_BIN (expander)->child, priv->expanded); |
|
| 1339 gtk_widget_queue_resize (GTK_WIDGET (expander)); |
|
| 1340 } |
|
| 1341 } |
|
| 1342 |
|
| 1343 g_object_notify (G_OBJECT (expander), "expanded"); |
|
| 1344 } |
|
| 1345 } |
|
| 1346 |
|
| 1347 /** |
|
| 1348 * gtk_expander_get_expanded: |
|
| 1349 * @expander:a #GtkExpander |
|
| 1350 * |
|
| 1351 * Queries a #GtkExpander and returns its current state. Returns %TRUE |
|
| 1352 * if the child widget is revealed. |
|
| 1353 * |
|
| 1354 * See gtk_expander_set_expanded(). |
|
| 1355 * |
|
| 1356 * Return value: the current state of the expander. |
|
| 1357 * |
|
| 1358 * Since: 2.4 |
|
| 1359 **/ |
|
| 1360 gboolean |
|
| 1361 gtk_expander_get_expanded (GtkExpander *expander) |
|
| 1362 { |
|
| 1363 g_return_val_if_fail (GTK_IS_EXPANDER (expander), FALSE); |
|
| 1364 |
|
| 1365 return expander->priv->expanded; |
|
| 1366 } |
|
| 1367 |
|
| 1368 /** |
|
| 1369 * gtk_expander_set_spacing: |
|
| 1370 * @expander: a #GtkExpander |
|
| 1371 * @spacing: distance between the expander and child in pixels. |
|
| 1372 * |
|
| 1373 * Sets the spacing field of @expander, which is the number of pixels to |
|
| 1374 * place between expander and the child. |
|
| 1375 * |
|
| 1376 * Since: 2.4 |
|
| 1377 **/ |
|
| 1378 void |
|
| 1379 gtk_expander_set_spacing (GtkExpander *expander, |
|
| 1380 gint spacing) |
|
| 1381 { |
|
| 1382 g_return_if_fail (GTK_IS_EXPANDER (expander)); |
|
| 1383 g_return_if_fail (spacing >= 0); |
|
| 1384 |
|
| 1385 if (expander->priv->spacing != spacing) |
|
| 1386 { |
|
| 1387 expander->priv->spacing = spacing; |
|
| 1388 |
|
| 1389 gtk_widget_queue_resize (GTK_WIDGET (expander)); |
|
| 1390 |
|
| 1391 g_object_notify (G_OBJECT (expander), "spacing"); |
|
| 1392 } |
|
| 1393 } |
|
| 1394 |
|
| 1395 /** |
|
| 1396 * gtk_expander_get_spacing: |
|
| 1397 * @expander: a #GtkExpander |
|
| 1398 * |
|
| 1399 * Gets the value set by gtk_expander_set_spacing(). |
|
| 1400 * |
|
| 1401 * Return value: spacing between the expander and child. |
|
| 1402 * |
|
| 1403 * Since: 2.4 |
|
| 1404 **/ |
|
| 1405 gint |
|
| 1406 gtk_expander_get_spacing (GtkExpander *expander) |
|
| 1407 { |
|
| 1408 g_return_val_if_fail (GTK_IS_EXPANDER (expander), 0); |
|
| 1409 |
|
| 1410 return expander->priv->spacing; |
|
| 1411 } |
|
| 1412 |
|
| 1413 /** |
|
| 1414 * gtk_expander_set_label: |
|
| 1415 * @expander: a #GtkExpander |
|
| 1416 * @label: a string |
|
| 1417 * |
|
| 1418 * Sets the text of the label of the expander to @label. |
|
| 1419 * |
|
| 1420 * This will also clear any previously set labels. |
|
| 1421 * |
|
| 1422 * Since: 2.4 |
|
| 1423 **/ |
|
| 1424 void |
|
| 1425 gtk_expander_set_label (GtkExpander *expander, |
|
| 1426 const gchar *label) |
|
| 1427 { |
|
| 1428 g_return_if_fail (GTK_IS_EXPANDER (expander)); |
|
| 1429 |
|
| 1430 if (!label) |
|
| 1431 { |
|
| 1432 gtk_expander_set_label_widget (expander, NULL); |
|
| 1433 } |
|
| 1434 else |
|
| 1435 { |
|
| 1436 GtkWidget *child; |
|
| 1437 |
|
| 1438 child = gtk_label_new (label); |
|
| 1439 gtk_label_set_use_underline (GTK_LABEL (child), expander->priv->use_underline); |
|
| 1440 gtk_label_set_use_markup (GTK_LABEL (child), expander->priv->use_markup); |
|
| 1441 gtk_widget_show (child); |
|
| 1442 |
|
| 1443 gtk_expander_set_label_widget (expander, child); |
|
| 1444 } |
|
| 1445 |
|
| 1446 g_object_notify (G_OBJECT (expander), "label"); |
|
| 1447 } |
|
| 1448 |
|
| 1449 /** |
|
| 1450 * gtk_expander_get_label: |
|
| 1451 * @expander: a #GtkExpander |
|
| 1452 * |
|
| 1453 * Fetches the text from the label of the expander, as set by |
|
| 1454 * gtk_expander_set_label(). If the label text has not |
|
| 1455 * been set the return value will be %NULL. This will be the |
|
| 1456 * case if you create an empty button with gtk_button_new() to |
|
| 1457 * use as a container. |
|
| 1458 * |
|
| 1459 * Return value: The text of the label widget. This string is owned |
|
| 1460 * by the widget and must not be modified or freed. |
|
| 1461 * |
|
| 1462 * Since: 2.4 |
|
| 1463 **/ |
|
| 1464 G_CONST_RETURN char * |
|
| 1465 gtk_expander_get_label (GtkExpander *expander) |
|
| 1466 { |
|
| 1467 GtkExpanderPrivate *priv; |
|
| 1468 |
|
| 1469 g_return_val_if_fail (GTK_IS_EXPANDER (expander), NULL); |
|
| 1470 |
|
| 1471 priv = expander->priv; |
|
| 1472 |
|
| 1473 if (priv->label_widget && GTK_IS_LABEL (priv->label_widget)) |
|
| 1474 return gtk_label_get_text (GTK_LABEL (priv->label_widget)); |
|
| 1475 else |
|
| 1476 return NULL; |
|
| 1477 } |
|
| 1478 |
|
| 1479 /** |
|
| 1480 * gtk_expander_set_use_underline: |
|
| 1481 * @expander: a #GtkExpander |
|
| 1482 * @use_underline: %TRUE if underlines in the text indicate mnemonics |
|
| 1483 * |
|
| 1484 * If true, an underline in the text of the expander label indicates |
|
| 1485 * the next character should be used for the mnemonic accelerator key. |
|
| 1486 * |
|
| 1487 * Since: 2.4 |
|
| 1488 **/ |
|
| 1489 void |
|
| 1490 gtk_expander_set_use_underline (GtkExpander *expander, |
|
| 1491 gboolean use_underline) |
|
| 1492 { |
|
| 1493 GtkExpanderPrivate *priv; |
|
| 1494 |
|
| 1495 g_return_if_fail (GTK_IS_EXPANDER (expander)); |
|
| 1496 |
|
| 1497 priv = expander->priv; |
|
| 1498 |
|
| 1499 use_underline = use_underline != FALSE; |
|
| 1500 |
|
| 1501 if (priv->use_underline != use_underline) |
|
| 1502 { |
|
| 1503 priv->use_underline = use_underline; |
|
| 1504 |
|
| 1505 if (priv->label_widget && GTK_IS_LABEL (priv->label_widget)) |
|
| 1506 gtk_label_set_use_underline (GTK_LABEL (priv->label_widget), use_underline); |
|
| 1507 |
|
| 1508 g_object_notify (G_OBJECT (expander), "use-underline"); |
|
| 1509 } |
|
| 1510 } |
|
| 1511 |
|
| 1512 /** |
|
| 1513 * gtk_expander_get_use_underline: |
|
| 1514 * @expander: a #GtkExpander |
|
| 1515 * |
|
| 1516 * Returns whether an embedded underline in the expander label indicates a |
|
| 1517 * mnemonic. See gtk_expander_set_use_underline(). |
|
| 1518 * |
|
| 1519 * Return value: %TRUE if an embedded underline in the expander label |
|
| 1520 * indicates the mnemonic accelerator keys. |
|
| 1521 * |
|
| 1522 * Since: 2.4 |
|
| 1523 **/ |
|
| 1524 gboolean |
|
| 1525 gtk_expander_get_use_underline (GtkExpander *expander) |
|
| 1526 { |
|
| 1527 g_return_val_if_fail (GTK_IS_EXPANDER (expander), FALSE); |
|
| 1528 |
|
| 1529 return expander->priv->use_underline; |
|
| 1530 } |
|
| 1531 |
|
| 1532 /** |
|
| 1533 * gtk_expander_set_use_markup: |
|
| 1534 * @expander: a #GtkExpander |
|
| 1535 * @use_markup: %TRUE if the label's text should be parsed for markup |
|
| 1536 * |
|
| 1537 * Sets whether the text of the label contains markup in <link |
|
| 1538 * linkend="PangoMarkupFormat">Pango's text markup |
|
| 1539 * language</link>. See gtk_label_set_markup(). |
|
| 1540 * |
|
| 1541 * Since: 2.4 |
|
| 1542 **/ |
|
| 1543 void |
|
| 1544 gtk_expander_set_use_markup (GtkExpander *expander, |
|
| 1545 gboolean use_markup) |
|
| 1546 { |
|
| 1547 GtkExpanderPrivate *priv; |
|
| 1548 |
|
| 1549 g_return_if_fail (GTK_IS_EXPANDER (expander)); |
|
| 1550 |
|
| 1551 priv = expander->priv; |
|
| 1552 |
|
| 1553 use_markup = use_markup != FALSE; |
|
| 1554 |
|
| 1555 if (priv->use_markup != use_markup) |
|
| 1556 { |
|
| 1557 priv->use_markup = use_markup; |
|
| 1558 |
|
| 1559 if (priv->label_widget && GTK_IS_LABEL (priv->label_widget)) |
|
| 1560 gtk_label_set_use_markup (GTK_LABEL (priv->label_widget), use_markup); |
|
| 1561 |
|
| 1562 g_object_notify (G_OBJECT (expander), "use-markup"); |
|
| 1563 } |
|
| 1564 } |
|
| 1565 |
|
| 1566 /** |
|
| 1567 * gtk_expander_get_use_markup: |
|
| 1568 * @expander: a #GtkExpander |
|
| 1569 * |
|
| 1570 * Returns whether the label's text is interpreted as marked up with |
|
| 1571 * the <link linkend="PangoMarkupFormat">Pango text markup |
|
| 1572 * language</link>. See gtk_expander_set_use_markup (). |
|
| 1573 * |
|
| 1574 * Return value: %TRUE if the label's text will be parsed for markup |
|
| 1575 * |
|
| 1576 * Since: 2.4 |
|
| 1577 **/ |
|
| 1578 gboolean |
|
| 1579 gtk_expander_get_use_markup (GtkExpander *expander) |
|
| 1580 { |
|
| 1581 g_return_val_if_fail (GTK_IS_EXPANDER (expander), FALSE); |
|
| 1582 |
|
| 1583 return expander->priv->use_markup; |
|
| 1584 } |
|
| 1585 |
|
| 1586 /** |
|
| 1587 * gtk_expander_set_label_widget: |
|
| 1588 * @expander: a #GtkExpander |
|
| 1589 * @label_widget: the new label widget |
|
| 1590 * |
|
| 1591 * Set the label widget for the expander. This is the widget |
|
| 1592 * that will appear embedded alongside the expander arrow. |
|
| 1593 * |
|
| 1594 * Since: 2.4 |
|
| 1595 **/ |
|
| 1596 void |
|
| 1597 gtk_expander_set_label_widget (GtkExpander *expander, |
|
| 1598 GtkWidget *label_widget) |
|
| 1599 { |
|
| 1600 GtkExpanderPrivate *priv; |
|
| 1601 |
|
| 1602 g_return_if_fail (GTK_IS_EXPANDER (expander)); |
|
| 1603 g_return_if_fail (label_widget == NULL || GTK_IS_WIDGET (label_widget)); |
|
| 1604 g_return_if_fail (label_widget == NULL || label_widget->parent == NULL); |
|
| 1605 |
|
| 1606 priv = expander->priv; |
|
| 1607 |
|
| 1608 if (priv->label_widget == label_widget) |
|
| 1609 return; |
|
| 1610 |
|
| 1611 if (priv->label_widget) |
|
| 1612 { |
|
| 1613 gtk_widget_set_state (priv->label_widget, GTK_STATE_NORMAL); |
|
| 1614 gtk_widget_unparent (priv->label_widget); |
|
| 1615 } |
|
| 1616 |
|
| 1617 priv->label_widget = label_widget; |
|
| 1618 |
|
| 1619 if (label_widget) |
|
| 1620 { |
|
| 1621 priv->label_widget = label_widget; |
|
| 1622 |
|
| 1623 gtk_widget_set_parent (label_widget, GTK_WIDGET (expander)); |
|
| 1624 |
|
| 1625 if (priv->prelight) |
|
| 1626 gtk_widget_set_state (label_widget, GTK_STATE_PRELIGHT); |
|
| 1627 } |
|
| 1628 |
|
| 1629 if (GTK_WIDGET_VISIBLE (expander)) |
|
| 1630 gtk_widget_queue_resize (GTK_WIDGET (expander)); |
|
| 1631 |
|
| 1632 g_object_freeze_notify (G_OBJECT (expander)); |
|
| 1633 g_object_notify (G_OBJECT (expander), "label-widget"); |
|
| 1634 g_object_notify (G_OBJECT (expander), "label"); |
|
| 1635 g_object_thaw_notify (G_OBJECT (expander)); |
|
| 1636 } |
|
| 1637 |
|
| 1638 /** |
|
| 1639 * gtk_expander_get_label_widget: |
|
| 1640 * @expander: a #GtkExpander |
|
| 1641 * |
|
| 1642 * Retrieves the label widget for the frame. See |
|
| 1643 * gtk_expander_set_label_widget(). |
|
| 1644 * |
|
| 1645 * Return value: the label widget, or %NULL if there is none. |
|
| 1646 * |
|
| 1647 * Since: 2.4 |
|
| 1648 **/ |
|
| 1649 GtkWidget * |
|
| 1650 gtk_expander_get_label_widget (GtkExpander *expander) |
|
| 1651 { |
|
| 1652 g_return_val_if_fail (GTK_IS_EXPANDER (expander), NULL); |
|
| 1653 |
|
| 1654 return expander->priv->label_widget; |
|
| 1655 } |
|
| 1656 |
|
| 1657 #define __GTK_EXPANDER_C__ |
|
| 1658 |
|
| 1659 #endif /* Gtk 2.4 */ |
|