Back to index

im-sdk  12.3.91
gtkflatbutton.c
Go to the documentation of this file.
00001 /* GTK - The GIMP Toolkit
00002  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the
00016  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017  * Boston, MA 02111-1307, USA.
00018  */
00019 
00020 /*
00021  * Modified by the GTK+ Team and others 1997-2001.  See the AUTHORS
00022  * file for a list of people on the GTK+ Team.  See the ChangeLog
00023  * files for a list of changes.  These files are distributed with
00024  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
00025  */
00026 
00027 #ifdef HAVE_CONFIG_H
00028 #include <config.h>
00029 #endif
00030 
00031 #include <string.h>
00032 #include <gtk/gtkalignment.h>
00033 #include <gtk/gtklabel.h>
00034 
00035 #include "gtkflatbutton.h"
00036 
00037 #include <gtk/gtkmain.h>
00038 #include <gtk/gtkmarshal.h>
00039 #include <gtk/gtkimage.h>
00040 #include <gtk/gtkhbox.h>
00041 #include <gtk/gtkstock.h>
00042 #include <gtk/gtkiconfactory.h>
00043 //#include <gtk/gtkintl.h>
00044 
00045 #define P_(str)      (str)
00046 
00047 #define CHILD_SPACING     1
00048 
00049 static const GtkBorder default_default_border = { 1, 1, 1, 1 };
00050 static const GtkBorder default_default_outside_border = { 0, 0, 0, 0 };
00051 
00052 /* Time out before giving up on getting a key release when animating
00053  * the close button.
00054  */
00055 #define ACTIVATE_TIMEOUT 250
00056 
00057 enum {
00058   PRESSED,
00059   RELEASED,
00060   CLICKED,
00061   ENTER,
00062   LEAVE,
00063   ACTIVATE,
00064   LAST_SIGNAL
00065 };
00066 
00067 enum {
00068   PROP_0,
00069   PROP_LABEL,
00070   PROP_RELIEF,
00071   PROP_USE_UNDERLINE,
00072   PROP_USE_STOCK,
00073   PROP_FOCUS_ON_CLICK,
00074   PROP_XALIGN,
00075   PROP_YALIGN
00076 };
00077 
00078 #define GTK_FLAT_BUTTON_GET_PRIVATE(o)       (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_FLAT_BUTTON, GtkFlatButtonPrivate))
00079 typedef struct _GtkFlatButtonPrivate GtkFlatButtonPrivate;
00080 
00081 struct _GtkFlatButtonPrivate
00082 {
00083   gfloat       xalign;
00084   gfloat       yalign;
00085   GtkSettings *settings;
00086   guint        show_image_connection;
00087   GtkWidget   *image;
00088   guint        align_set : 1;
00089 };
00090 
00091 static void gtk_flat_button_class_init     (GtkFlatButtonClass   *klass);
00092 static void gtk_flat_button_init           (GtkFlatButton        *button);
00093 static void gtk_flat_button_destroy        (GtkObject        *object);
00094 static void gtk_flat_button_set_property   (GObject         *object,
00095                                        guint            prop_id,
00096                                        const GValue    *value,
00097                                        GParamSpec      *pspec);
00098 static void gtk_flat_button_get_property   (GObject         *object,
00099                                        guint            prop_id,
00100                                        GValue          *value,
00101                                        GParamSpec      *pspec);
00102 static void gtk_flat_button_screen_changed (GtkWidget        *widget,
00103                                    GdkScreen        *previous_screen);
00104 static void gtk_flat_button_realize        (GtkWidget        *widget);
00105 static void gtk_flat_button_unrealize      (GtkWidget        *widget);
00106 static void gtk_flat_button_map            (GtkWidget        *widget);
00107 static void gtk_flat_button_unmap          (GtkWidget        *widget);
00108 static void gtk_flat_button_size_request   (GtkWidget        *widget,
00109                                    GtkRequisition   *requisition);
00110 static void gtk_flat_button_size_allocate  (GtkWidget        *widget,
00111                                    GtkAllocation    *allocation);
00112 static gint gtk_flat_button_expose         (GtkWidget        *widget,
00113                                    GdkEventExpose   *event);
00114 static gint gtk_flat_button_button_press   (GtkWidget        *widget,
00115                                    GdkEventButton   *event);
00116 static gint gtk_flat_button_button_release (GtkWidget        *widget,
00117                                    GdkEventButton   *event);
00118 static gint gtk_flat_button_key_release    (GtkWidget        *widget,
00119                                    GdkEventKey      *event);
00120 static gint gtk_flat_button_enter_notify   (GtkWidget        *widget,
00121                                    GdkEventCrossing *event);
00122 static gint gtk_flat_button_leave_notify   (GtkWidget        *widget,
00123                                    GdkEventCrossing *event);
00124 static void gtk_real_button_pressed   (GtkFlatButton        *button);
00125 static void gtk_real_button_released  (GtkFlatButton        *button);
00126 static void gtk_real_button_activate  (GtkFlatButton         *button);
00127 static void gtk_flat_button_update_state   (GtkFlatButton        *button);
00128 static void gtk_flat_button_add            (GtkContainer   *container,
00129                                     GtkWidget      *widget);
00130 static GType gtk_flat_button_child_type    (GtkContainer     *container);
00131 static void gtk_flat_button_finish_activate (GtkFlatButton *button,
00132                                    gboolean   do_it);
00133 
00134 static GObject*      gtk_flat_button_constructor     (GType                  type,
00135                                        guint                  n_construct_properties,
00136                                        GObjectConstructParam *construct_params);
00137 static void gtk_flat_button_construct_child (GtkFlatButton             *button);
00138 
00139 
00140 static GtkBinClass *parent_class = NULL;
00141 static guint button_signals[LAST_SIGNAL] = { 0 };
00142 
00143 
00144 GType
00145 gtk_flat_button_get_type (void)
00146 {
00147   static GType button_type = 0;
00148 
00149   if (!button_type)
00150     {
00151       static const GTypeInfo button_info =
00152       {
00153        sizeof (GtkFlatButtonClass),
00154        NULL,         /* base_init */
00155        NULL,         /* base_finalize */
00156        (GClassInitFunc) gtk_flat_button_class_init,
00157        NULL,         /* class_finalize */
00158        NULL,         /* class_data */
00159        sizeof (GtkFlatButton),
00160        16,           /* n_preallocs */
00161        (GInstanceInitFunc) gtk_flat_button_init,
00162       };
00163 
00164       button_type = g_type_register_static (GTK_TYPE_BIN, "GtkFlatButton",
00165                                        &button_info, 0);
00166     }
00167 
00168   return button_type;
00169 }
00170 
00171 static void
00172 gtk_flat_button_class_init (GtkFlatButtonClass *klass)
00173 {
00174   GObjectClass *gobject_class;
00175   GtkObjectClass *object_class;
00176   GtkWidgetClass *widget_class;
00177   GtkContainerClass *container_class;
00178 
00179   gobject_class = G_OBJECT_CLASS (klass);
00180   object_class = (GtkObjectClass*) klass;
00181   widget_class = (GtkWidgetClass*) klass;
00182   container_class = (GtkContainerClass*) klass;
00183   
00184   parent_class = g_type_class_peek_parent (klass);
00185 
00186   gobject_class->constructor = gtk_flat_button_constructor;
00187   gobject_class->set_property = gtk_flat_button_set_property;
00188   gobject_class->get_property = gtk_flat_button_get_property;
00189 
00190   object_class->destroy = gtk_flat_button_destroy;
00191 
00192   widget_class->screen_changed = gtk_flat_button_screen_changed;
00193   widget_class->realize = gtk_flat_button_realize;
00194   widget_class->unrealize = gtk_flat_button_unrealize;
00195   widget_class->map = gtk_flat_button_map;
00196   widget_class->unmap = gtk_flat_button_unmap;
00197   widget_class->size_request = gtk_flat_button_size_request;
00198   widget_class->size_allocate = gtk_flat_button_size_allocate;
00199   widget_class->expose_event = gtk_flat_button_expose;
00200   widget_class->button_press_event = gtk_flat_button_button_press;
00201   widget_class->button_release_event = gtk_flat_button_button_release;
00202   widget_class->key_release_event = gtk_flat_button_key_release;
00203   widget_class->enter_notify_event = gtk_flat_button_enter_notify;
00204   widget_class->leave_notify_event = gtk_flat_button_leave_notify;
00205 
00206   container_class->child_type = gtk_flat_button_child_type;
00207   container_class->add = gtk_flat_button_add;
00208 
00209   klass->pressed = gtk_real_button_pressed;
00210   klass->released = gtk_real_button_released;
00211   klass->clicked = NULL;
00212   klass->enter = gtk_flat_button_update_state;
00213   klass->leave = gtk_flat_button_update_state;
00214   klass->activate = gtk_real_button_activate;
00215 
00216   g_object_class_install_property (gobject_class,
00217                                    PROP_LABEL,
00218                                    g_param_spec_string ("label",
00219                                                         P_("Label"),
00220                                                         P_("Text of the label widget inside the button, if the button contains a label widget"),
00221                                                         NULL,
00222                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
00223   
00224   g_object_class_install_property (gobject_class,
00225                                    PROP_USE_UNDERLINE,
00226                                    g_param_spec_boolean ("use_underline",
00227                                                   P_("Use underline"),
00228                                                   P_("If set, an underline in the text indicates the next character should be used for the mnemonic accelerator key"),
00229                                                         FALSE,
00230                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
00231   
00232   g_object_class_install_property (gobject_class,
00233                                    PROP_USE_STOCK,
00234                                    g_param_spec_boolean ("use_stock",
00235                                                   P_("Use stock"),
00236                                                   P_("If set, the label is used to pick a stock item instead of being displayed"),
00237                                                         FALSE,
00238                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
00239   
00240   g_object_class_install_property (gobject_class,
00241                                    PROP_FOCUS_ON_CLICK,
00242                                    g_param_spec_boolean ("focus_on_click",
00243                                                   P_("Focus on click"),
00244                                                   P_("Whether the button grabs focus when it is clicked with the mouse"),
00245                                                   TRUE,
00246                                                   G_PARAM_READWRITE));
00247   
00248   g_object_class_install_property (gobject_class,
00249                                    PROP_RELIEF,
00250                                    g_param_spec_enum ("relief",
00251                                                       P_("Border relief"),
00252                                                       P_("The border relief style"),
00253                                                       GTK_TYPE_RELIEF_STYLE,
00254                                                       GTK_RELIEF_NORMAL,
00255                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
00256   
00266   g_object_class_install_property (gobject_class,
00267                                    PROP_XALIGN,
00268                                    g_param_spec_float("xalign",
00269                                                       P_("Horizontal alignment for child"),
00270                                                       P_("Horizontal position of child in available space. 0.0 is left aligned, 1.0 is right aligned"),
00271                                                       0.0,
00272                                                       1.0,
00273                                                       0.5,
00274                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
00275 
00285   g_object_class_install_property (gobject_class,
00286                                    PROP_YALIGN,
00287                                    g_param_spec_float("yalign",
00288                                                       P_("Vertical alignment for child"),
00289                                                       P_("Vertical position of child in available space. 0.0 is top aligned, 1.0 is bottom aligned"),
00290                                                       0.0,
00291                                                       1.0,
00292                                                       0.5,
00293                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
00294 
00295   button_signals[PRESSED] =
00296     g_signal_new ("pressed",
00297                 G_OBJECT_CLASS_TYPE (object_class),
00298                 G_SIGNAL_RUN_FIRST,
00299                 G_STRUCT_OFFSET (GtkFlatButtonClass, pressed),
00300                 NULL, NULL,
00301                 gtk_marshal_VOID__VOID,
00302                 G_TYPE_NONE, 0);
00303   button_signals[RELEASED] =
00304     g_signal_new ("released",
00305                 G_OBJECT_CLASS_TYPE (object_class),
00306                 G_SIGNAL_RUN_FIRST,
00307                 G_STRUCT_OFFSET (GtkFlatButtonClass, released),
00308                 NULL, NULL,
00309                 gtk_marshal_VOID__VOID,
00310                 G_TYPE_NONE, 0);
00311   button_signals[CLICKED] =
00312     g_signal_new ("clicked",
00313                 G_OBJECT_CLASS_TYPE (object_class),
00314                 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
00315                 G_STRUCT_OFFSET (GtkFlatButtonClass, clicked),
00316                 NULL, NULL,
00317                 gtk_marshal_VOID__VOID,
00318                 G_TYPE_NONE, 0);
00319   button_signals[ENTER] =
00320     g_signal_new ("enter",
00321                 G_OBJECT_CLASS_TYPE (object_class),
00322                 G_SIGNAL_RUN_FIRST,
00323                 G_STRUCT_OFFSET (GtkFlatButtonClass, enter),
00324                 NULL, NULL,
00325                 gtk_marshal_VOID__VOID,
00326                 G_TYPE_NONE, 0);
00327   button_signals[LEAVE] =
00328     g_signal_new ("leave",
00329                 G_OBJECT_CLASS_TYPE (object_class),
00330                 G_SIGNAL_RUN_FIRST,
00331                 G_STRUCT_OFFSET (GtkFlatButtonClass, leave),
00332                 NULL, NULL,
00333                 gtk_marshal_VOID__VOID,
00334                 G_TYPE_NONE, 0);
00335 
00345   button_signals[ACTIVATE] =
00346     g_signal_new ("activate",
00347                 G_OBJECT_CLASS_TYPE (object_class),
00348                 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
00349                 G_STRUCT_OFFSET (GtkFlatButtonClass, activate),
00350                 NULL, NULL,
00351                 gtk_marshal_VOID__VOID,
00352                 G_TYPE_NONE, 0);
00353   widget_class->activate_signal = button_signals[ACTIVATE];
00354 
00355   gtk_widget_class_install_style_property (widget_class,
00356                                       g_param_spec_boxed ("default_border",
00357                                                         P_("Default Spacing"),
00358                                                         P_("Extra space to add for CAN_DEFAULT buttons"),
00359                                                         GTK_TYPE_BORDER,
00360                                                         G_PARAM_READABLE));
00361 
00362   gtk_widget_class_install_style_property (widget_class,
00363                                       g_param_spec_boxed ("default_outside_border",
00364                                                         P_("Default Outside Spacing"),
00365                                                         P_("Extra space to add for CAN_DEFAULT buttons that is always drawn outside the border"),
00366                                                         GTK_TYPE_BORDER,
00367                                                         G_PARAM_READABLE));
00368   gtk_widget_class_install_style_property (widget_class,
00369                                       g_param_spec_int ("child_displacement_x",
00370                                                       P_("Child X Displacement"),
00371                                                       P_("How far in the x direction to move the child when the button is depressed"),
00372                                                       G_MININT,
00373                                                       G_MAXINT,
00374                                                       0,
00375                                                       G_PARAM_READABLE));
00376   gtk_widget_class_install_style_property (widget_class,
00377                                       g_param_spec_int ("child_displacement_y",
00378                                                       P_("Child Y Displacement"),
00379                                                       P_("How far in the y direction to move the child when the button is depressed"),
00380                                                       G_MININT,
00381                                                       G_MAXINT,
00382                                                       0,
00383                                                       G_PARAM_READABLE));
00384 
00385   gtk_settings_install_property (g_param_spec_boolean ("gtk-button-images",
00386                                                  P_("Show button images"),
00387                                                  P_("Whether stock icons should be shown in buttons"),
00388                                                  TRUE,
00389                                                  G_PARAM_READWRITE));
00390   
00391   g_type_class_add_private (gobject_class, sizeof (GtkFlatButtonPrivate));  
00392 }
00393 
00394 static void
00395 gtk_flat_button_init (GtkFlatButton *button)
00396 {
00397   GtkFlatButtonPrivate *priv = GTK_FLAT_BUTTON_GET_PRIVATE (button);
00398 
00399   GTK_WIDGET_SET_FLAGS (button, GTK_CAN_FOCUS | GTK_RECEIVES_DEFAULT);
00400   GTK_WIDGET_SET_FLAGS (button, GTK_NO_WINDOW);
00401 
00402   button->label_text = NULL;
00403   
00404   button->constructed = FALSE;
00405   button->in_button = FALSE;
00406   button->button_down = FALSE;
00407   button->relief = GTK_RELIEF_NORMAL;
00408   button->use_stock = FALSE;
00409   button->use_underline = FALSE;
00410   button->depressed = FALSE;
00411   button->depress_on_activate = TRUE;
00412   button->focus_on_click = TRUE;
00413 
00414   priv->xalign = 0.5;
00415   priv->yalign = 0.5;
00416   priv->align_set = 0;
00417 }
00418 
00419 static void
00420 gtk_flat_button_destroy (GtkObject *object)
00421 {
00422   GtkFlatButton *button = GTK_FLAT_BUTTON (object);
00423   
00424   if (button->label_text)
00425     {
00426       g_free (button->label_text);
00427       button->label_text = NULL;
00428     }
00429   
00430   (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
00431 }
00432 
00433 static GObject*
00434 gtk_flat_button_constructor (GType                  type,
00435                      guint                  n_construct_properties,
00436                      GObjectConstructParam *construct_params)
00437 {
00438   GObject *object;
00439   GtkFlatButton *button;
00440 
00441   object = (* G_OBJECT_CLASS (parent_class)->constructor) (type,
00442                                                     n_construct_properties,
00443                                                     construct_params);
00444 
00445   button = GTK_FLAT_BUTTON (object);
00446   button->constructed = TRUE;
00447 
00448   if (button->label_text != NULL)
00449     gtk_flat_button_construct_child (button);
00450   
00451   return object;
00452 }
00453 
00454 
00455 static GType
00456 gtk_flat_button_child_type  (GtkContainer     *container)
00457 {
00458   if (!GTK_BIN (container)->child)
00459     return GTK_TYPE_WIDGET;
00460   else
00461     return G_TYPE_NONE;
00462 }
00463 
00464 static void
00465 maybe_set_alignment (GtkFlatButton *button,
00466                    GtkWidget *widget)
00467 {
00468   GtkFlatButtonPrivate *priv = GTK_FLAT_BUTTON_GET_PRIVATE (button);
00469 
00470   if (GTK_IS_MISC (widget))
00471     {
00472       GtkMisc *misc = GTK_MISC (widget);
00473       
00474       if (priv->align_set)
00475        gtk_misc_set_alignment (misc, priv->xalign, priv->yalign);
00476     }
00477   else if (GTK_IS_ALIGNMENT (widget))
00478     {
00479       GtkAlignment *alignment = GTK_ALIGNMENT (widget);
00480 
00481       if (priv->align_set)
00482        gtk_alignment_set (alignment, priv->xalign, priv->yalign, 
00483                         alignment->xscale, alignment->yscale);
00484     }
00485 }
00486 
00487 static void
00488 gtk_flat_button_add (GtkContainer *container,
00489               GtkWidget    *widget)
00490 {
00491   maybe_set_alignment (GTK_FLAT_BUTTON (container), widget);
00492 
00493   GTK_CONTAINER_CLASS (parent_class)->add (container, widget);
00494 }
00495 
00496 static void
00497 gtk_flat_button_set_property (GObject         *object,
00498                          guint            prop_id,
00499                          const GValue    *value,
00500                          GParamSpec      *pspec)
00501 {
00502   GtkFlatButton *button = GTK_FLAT_BUTTON (object);
00503   GtkFlatButtonPrivate *priv = GTK_FLAT_BUTTON_GET_PRIVATE (button);
00504 
00505   switch (prop_id)
00506     {
00507     case PROP_LABEL:
00508       gtk_flat_button_set_label (button, g_value_get_string (value));
00509       break;
00510     case PROP_RELIEF:
00511       gtk_flat_button_set_relief (button, g_value_get_enum (value));
00512       break;
00513     case PROP_USE_UNDERLINE:
00514       gtk_flat_button_set_use_underline (button, g_value_get_boolean (value));
00515       break;
00516     case PROP_USE_STOCK:
00517       gtk_flat_button_set_use_stock (button, g_value_get_boolean (value));
00518       break;
00519     case PROP_FOCUS_ON_CLICK:
00520       gtk_flat_button_set_focus_on_click (button, g_value_get_boolean (value));
00521       break;
00522     case PROP_XALIGN:
00523       gtk_flat_button_set_alignment (button, g_value_get_float (value), priv->yalign);
00524       break;
00525     case PROP_YALIGN:
00526       gtk_flat_button_set_alignment (button, priv->xalign, g_value_get_float (value));
00527       break;
00528     default:
00529       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
00530       break;
00531     }
00532 }
00533 
00534 static void
00535 gtk_flat_button_get_property (GObject         *object,
00536                          guint            prop_id,
00537                          GValue          *value,
00538                          GParamSpec      *pspec)
00539 {
00540   GtkFlatButton *button = GTK_FLAT_BUTTON (object);
00541   GtkFlatButtonPrivate *priv = GTK_FLAT_BUTTON_GET_PRIVATE (button);
00542 
00543   switch (prop_id)
00544     {
00545     case PROP_LABEL:
00546       g_value_set_string (value, button->label_text);
00547       break;
00548     case PROP_RELIEF:
00549       g_value_set_enum (value, gtk_flat_button_get_relief (button));
00550       break;
00551     case PROP_USE_UNDERLINE:
00552       g_value_set_boolean (value, button->use_underline);
00553       break;
00554     case PROP_USE_STOCK:
00555       g_value_set_boolean (value, button->use_stock);
00556       break;
00557     case PROP_FOCUS_ON_CLICK:
00558       g_value_set_boolean (value, button->focus_on_click);
00559       break;
00560     case PROP_XALIGN:
00561       g_value_set_float (value, priv->xalign);
00562       break;
00563     case PROP_YALIGN:
00564       g_value_set_float (value, priv->yalign);
00565       break;
00566     default:
00567       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
00568       break;
00569     }
00570 }
00571 
00572 GtkWidget*
00573 gtk_flat_button_new (void)
00574 {
00575   return g_object_new (GTK_TYPE_FLAT_BUTTON, NULL);
00576 }
00577 
00578 static gboolean
00579 show_image (GtkFlatButton *button)
00580 {
00581   GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (button));  
00582   gboolean show;
00583 
00584   g_object_get (settings, "gtk-button-images", &show, NULL);
00585 
00586   return show;
00587 }
00588 
00589 static void
00590 gtk_flat_button_construct_child (GtkFlatButton *button)
00591 {
00592   GtkFlatButtonPrivate *priv = GTK_FLAT_BUTTON_GET_PRIVATE (button);
00593   GtkStockItem item;
00594   GtkWidget *label;
00595   GtkWidget *hbox;
00596   GtkWidget *align;
00597   
00598   if (!button->constructed)
00599     return;
00600   
00601   if (button->label_text == NULL)
00602     return;
00603 
00604   if (GTK_BIN (button)->child)
00605     {
00606       gtk_container_remove (GTK_CONTAINER (button),
00607                          GTK_BIN (button)->child);
00608       priv->image = NULL;
00609     }
00610   
00611   if (button->use_stock &&
00612       gtk_stock_lookup (button->label_text, &item))
00613     {
00614       label = gtk_label_new_with_mnemonic (item.label);
00615 
00616       gtk_label_set_mnemonic_widget (GTK_LABEL (label), GTK_WIDGET (button));
00617       
00618       priv->image = gtk_image_new_from_stock (button->label_text, GTK_ICON_SIZE_BUTTON);
00619       g_object_set (priv->image, 
00620                   "visible", show_image (button),
00621                   "no_show_all", TRUE,
00622                   NULL);
00623       hbox = gtk_hbox_new (FALSE, 2);
00624 
00625       if (priv->align_set)
00626        align = gtk_alignment_new (priv->xalign, priv->yalign, 0.0, 0.0);
00627       else
00628        align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
00629        
00630       gtk_box_pack_start (GTK_BOX (hbox), priv->image, FALSE, FALSE, 0);
00631       gtk_box_pack_end (GTK_BOX (hbox), label, FALSE, FALSE, 0);
00632       
00633       gtk_container_add (GTK_CONTAINER (button), align);
00634       gtk_container_add (GTK_CONTAINER (align), hbox);
00635       gtk_widget_show_all (align);
00636 
00637       return;
00638     }
00639 
00640   if (button->use_underline)
00641     {
00642       label = gtk_label_new ("");
00643       gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), button->label_text);
00644       //label = gtk_label_new_with_mnemonic (button->label_text);
00645       gtk_label_set_mnemonic_widget (GTK_LABEL (label), GTK_WIDGET (button));
00646     }
00647   else
00648     {
00649       label = gtk_label_new ("");
00650       gtk_label_set_markup (GTK_LABEL (label), button->label_text);
00651       //label = gtk_label_new (button->label_text);
00652     }
00653 
00654   
00655   if (priv->align_set)
00656     gtk_misc_set_alignment (GTK_MISC (label), priv->xalign, priv->yalign);
00657 
00658   gtk_widget_show (label);
00659   gtk_container_add (GTK_CONTAINER (button), label);
00660 }
00661 
00662 
00663 GtkWidget*
00664 gtk_flat_button_new_with_label (const gchar *label)
00665 {
00666   return g_object_new (GTK_TYPE_FLAT_BUTTON, "label", label, NULL);
00667 }
00668 
00682 GtkWidget*
00683 gtk_flat_button_new_from_stock (const gchar *stock_id)
00684 {
00685   return g_object_new (GTK_TYPE_FLAT_BUTTON,
00686                        "label", stock_id,
00687                        "use_stock", TRUE,
00688                        "use_underline", TRUE,
00689                        NULL);
00690 }
00691 
00705 GtkWidget*
00706 gtk_flat_button_new_with_mnemonic (const gchar *label)
00707 {
00708   return g_object_new (GTK_TYPE_FLAT_BUTTON, "label", label, "use_underline", TRUE,  NULL);
00709 }
00710 
00711 void
00712 gtk_flat_button_pressed (GtkFlatButton *button)
00713 {
00714   g_return_if_fail (GTK_IS_FLAT_BUTTON (button));
00715 
00716   
00717   g_signal_emit (button, button_signals[PRESSED], 0);
00718 }
00719 
00720 void
00721 gtk_flat_button_released (GtkFlatButton *button)
00722 {
00723   g_return_if_fail (GTK_IS_FLAT_BUTTON (button));
00724 
00725   g_signal_emit (button, button_signals[RELEASED], 0);
00726 }
00727 
00728 void
00729 gtk_flat_button_clicked (GtkFlatButton *button)
00730 {
00731   g_return_if_fail (GTK_IS_FLAT_BUTTON (button));
00732 
00733   g_signal_emit (button, button_signals[CLICKED], 0);
00734 }
00735 
00736 void
00737 gtk_flat_button_enter (GtkFlatButton *button)
00738 {
00739   g_return_if_fail (GTK_IS_FLAT_BUTTON (button));
00740 
00741   g_signal_emit (button, button_signals[ENTER], 0);
00742 }
00743 
00744 void
00745 gtk_flat_button_leave (GtkFlatButton *button)
00746 {
00747   g_return_if_fail (GTK_IS_FLAT_BUTTON (button));
00748 
00749   g_signal_emit (button, button_signals[LEAVE], 0);
00750 }
00751 
00752 void
00753 gtk_flat_button_set_relief (GtkFlatButton *button,
00754                      GtkReliefStyle newrelief)
00755 {
00756   g_return_if_fail (GTK_IS_FLAT_BUTTON (button));
00757 
00758   if (newrelief != button->relief) 
00759     {
00760        button->relief = newrelief;
00761        g_object_notify (G_OBJECT (button), "relief");
00762        gtk_widget_queue_draw (GTK_WIDGET (button));
00763     }
00764 }
00765 
00766 GtkReliefStyle
00767 gtk_flat_button_get_relief (GtkFlatButton *button)
00768 {
00769   g_return_val_if_fail (button != NULL, GTK_RELIEF_NORMAL);
00770   g_return_val_if_fail (GTK_IS_FLAT_BUTTON (button), GTK_RELIEF_NORMAL);
00771 
00772   return button->relief;
00773 }
00774 
00775 static void
00776 gtk_flat_button_realize (GtkWidget *widget)
00777 {
00778   GtkFlatButton *button;
00779   GdkWindowAttr attributes;
00780   gint attributes_mask;
00781   gint border_width;
00782 
00783   button = GTK_FLAT_BUTTON (widget);
00784   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
00785 
00786   border_width = GTK_CONTAINER (widget)->border_width;
00787 
00788   attributes.window_type = GDK_WINDOW_CHILD;
00789   attributes.x = widget->allocation.x + border_width;
00790   attributes.y = widget->allocation.y + border_width;
00791   attributes.width = widget->allocation.width - border_width * 2;
00792   attributes.height = widget->allocation.height - border_width * 2;
00793   attributes.wclass = GDK_INPUT_ONLY;
00794   attributes.event_mask = gtk_widget_get_events (widget);
00795   attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
00796                          GDK_BUTTON_RELEASE_MASK |
00797                          GDK_ENTER_NOTIFY_MASK |
00798                          GDK_LEAVE_NOTIFY_MASK);
00799 
00800   attributes_mask = GDK_WA_X | GDK_WA_Y;
00801 
00802   widget->window = gtk_widget_get_parent_window (widget);
00803   g_object_ref (widget->window);
00804   
00805   button->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
00806                                     &attributes, attributes_mask);
00807   gdk_window_set_user_data (button->event_window, button);
00808 
00809   widget->style = gtk_style_attach (widget->style, widget->window);
00810 }
00811 
00812 static void
00813 gtk_flat_button_unrealize (GtkWidget *widget)
00814 {
00815   GtkFlatButton *button = GTK_FLAT_BUTTON (widget);
00816 
00817   if (button->activate_timeout)
00818     gtk_flat_button_finish_activate (button, FALSE);
00819 
00820   if (button->event_window)
00821     {
00822       gdk_window_set_user_data (button->event_window, NULL);
00823       gdk_window_destroy (button->event_window);
00824       button->event_window = NULL;
00825     }
00826   
00827   GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
00828 }
00829 
00830 static void
00831 gtk_flat_button_map (GtkWidget *widget)
00832 {
00833   GtkFlatButton *button = GTK_FLAT_BUTTON (widget);
00834   
00835   g_return_if_fail (GTK_IS_FLAT_BUTTON (widget));
00836 
00837   GTK_WIDGET_CLASS (parent_class)->map (widget);
00838 
00839   if (button->event_window)
00840     gdk_window_show (button->event_window);
00841 }
00842 
00843 static void
00844 gtk_flat_button_unmap (GtkWidget *widget)
00845 {
00846   GtkFlatButton *button = GTK_FLAT_BUTTON (widget);
00847     
00848   g_return_if_fail (GTK_IS_FLAT_BUTTON (widget));
00849 
00850   if (button->event_window)
00851     gdk_window_hide (button->event_window);
00852 
00853   GTK_WIDGET_CLASS (parent_class)->unmap (widget);
00854 }
00855 
00856 static void
00857 gtk_flat_button_get_props (GtkFlatButton *button,
00858                     GtkBorder *default_border,
00859                     GtkBorder *default_outside_border,
00860                     gboolean  *interior_focus)
00861 {
00862   GtkWidget *widget =  GTK_WIDGET (button);
00863   GtkBorder *tmp_border;
00864 
00865   if (default_border)
00866     {
00867       gtk_widget_style_get (widget, "default_border", &tmp_border, NULL);
00868 
00869       if (tmp_border)
00870        {
00871          *default_border = *tmp_border;
00872          g_free (tmp_border);
00873        }
00874       else
00875        *default_border = default_default_border;
00876     }
00877 
00878   if (default_outside_border)
00879     {
00880       gtk_widget_style_get (widget, "default_outside_border", &tmp_border, NULL);
00881 
00882       if (tmp_border)
00883        {
00884          *default_outside_border = *tmp_border;
00885          g_free (tmp_border);
00886        }
00887       else
00888        *default_outside_border = default_default_outside_border;
00889     }
00890 
00891   if (interior_focus)
00892     gtk_widget_style_get (widget, "interior_focus", interior_focus, NULL);
00893 }
00894        
00895 static void
00896 gtk_flat_button_size_request (GtkWidget      *widget,
00897                       GtkRequisition *requisition)
00898 {
00899   GtkFlatButton *button = GTK_FLAT_BUTTON (widget);
00900   GtkBorder default_border;
00901   gint focus_width;
00902   gint focus_pad;
00903 
00904   gtk_flat_button_get_props (button, &default_border, NULL, NULL);
00905   gtk_widget_style_get (GTK_WIDGET (widget),
00906                      "focus-line-width", &focus_width,
00907                      "focus-padding", &focus_pad,
00908                      NULL);
00909  
00910   requisition->width = (GTK_CONTAINER (widget)->border_width + CHILD_SPACING +
00911                      GTK_WIDGET (widget)->style->xthickness) * 2;
00912   requisition->height = (GTK_CONTAINER (widget)->border_width + CHILD_SPACING +
00913                       GTK_WIDGET (widget)->style->ythickness) * 2;
00914 
00915   if (GTK_WIDGET_CAN_DEFAULT (widget))
00916     {
00917       requisition->width += default_border.left + default_border.right;
00918       requisition->height += default_border.top + default_border.bottom;
00919     }
00920 
00921   if (GTK_BIN (button)->child && GTK_WIDGET_VISIBLE (GTK_BIN (button)->child))
00922     {
00923       GtkRequisition child_requisition;
00924 
00925       gtk_widget_size_request (GTK_BIN (button)->child, &child_requisition);
00926 
00927       requisition->width += child_requisition.width;
00928       requisition->height += child_requisition.height;
00929     }
00930   
00931   requisition->width += 2 * (focus_width + focus_pad);
00932   requisition->height += 2 * (focus_width + focus_pad);
00933 }
00934 
00935 static void
00936 gtk_flat_button_size_allocate (GtkWidget     *widget,
00937                        GtkAllocation *allocation)
00938 {
00939   GtkFlatButton *button = GTK_FLAT_BUTTON (widget);
00940   GtkAllocation child_allocation;
00941 
00942   gint border_width = GTK_CONTAINER (widget)->border_width;
00943   gint xthickness = GTK_WIDGET (widget)->style->xthickness;
00944   gint ythickness = GTK_WIDGET (widget)->style->ythickness;
00945   GtkBorder default_border;
00946   gint focus_width;
00947   gint focus_pad;
00948 
00949   gtk_flat_button_get_props (button, &default_border, NULL, NULL);
00950   gtk_widget_style_get (GTK_WIDGET (widget),
00951                      "focus-line-width", &focus_width,
00952                      "focus-padding", &focus_pad,
00953                      NULL);
00954  
00955                          
00956   widget->allocation = *allocation;
00957 
00958   if (GTK_WIDGET_REALIZED (widget))
00959     gdk_window_move_resize (button->event_window,
00960                          widget->allocation.x + border_width,
00961                          widget->allocation.y + border_width,
00962                          widget->allocation.width - border_width * 2,
00963                          widget->allocation.height - border_width * 2);
00964 
00965   if (GTK_BIN (button)->child && GTK_WIDGET_VISIBLE (GTK_BIN (button)->child))
00966     {
00967       child_allocation.x = widget->allocation.x + border_width + CHILD_SPACING + xthickness;
00968       child_allocation.y = widget->allocation.y + border_width + CHILD_SPACING + ythickness;
00969       
00970       child_allocation.width = MAX (1, widget->allocation.width - (CHILD_SPACING + xthickness) * 2 -
00971                                 border_width * 2);
00972       child_allocation.height = MAX (1, widget->allocation.height - (CHILD_SPACING + ythickness) * 2 -
00973                                  border_width * 2);
00974 
00975       if (GTK_WIDGET_CAN_DEFAULT (button))
00976        {
00977          child_allocation.x += default_border.left;
00978          child_allocation.y += default_border.top;
00979          child_allocation.width =  MAX (1, child_allocation.width - default_border.left - default_border.right);
00980          child_allocation.height = MAX (1, child_allocation.height - default_border.top - default_border.bottom);
00981        }
00982 
00983       if (GTK_WIDGET_CAN_FOCUS (button))
00984        {
00985          child_allocation.x += focus_width + focus_pad;
00986          child_allocation.y += focus_width + focus_pad;
00987          child_allocation.width =  MAX (1, child_allocation.width - (focus_width + focus_pad) * 2);
00988          child_allocation.height = MAX (1, child_allocation.height - (focus_width + focus_pad) * 2);
00989        }
00990 
00991       if (button->depressed)
00992        {
00993          gint child_displacement_x;
00994          gint child_displacement_y;
00995          
00996          gtk_widget_style_get (widget,
00997                             "child_displacement_x", &child_displacement_x, 
00998                             "child_displacement_y", &child_displacement_y,
00999                             NULL);
01000          child_allocation.x += child_displacement_x;
01001          child_allocation.y += child_displacement_y;
01002        }
01003 
01004       gtk_widget_size_allocate (GTK_BIN (button)->child, &child_allocation);
01005     }
01006 }
01007 
01008 void
01009 _gtk_flat_button_paint (GtkFlatButton    *button,
01010                  GdkRectangle *area,
01011                  GtkStateType  state_type,
01012                  GtkShadowType shadow_type,
01013                  const gchar  *main_detail,
01014                  const gchar  *default_detail)
01015 {
01016   GtkWidget *widget;
01017   gint width, height;
01018   gint x, y;
01019   gint border_width;
01020   GtkBorder default_border;
01021   GtkBorder default_outside_border;
01022   gboolean interior_focus;
01023   gint focus_width;
01024   gint focus_pad;
01025    
01026   if (GTK_WIDGET_DRAWABLE (button))
01027     {
01028       widget = GTK_WIDGET (button);
01029       border_width = GTK_CONTAINER (widget)->border_width;
01030 
01031       gtk_flat_button_get_props (button, &default_border, &default_outside_border, &interior_focus);
01032       gtk_widget_style_get (GTK_WIDGET (widget),
01033                          "focus-line-width", &focus_width,
01034                          "focus-padding", &focus_pad,
01035                          NULL); 
01036        
01037       x = widget->allocation.x + border_width;
01038       y = widget->allocation.y + border_width;
01039       width = widget->allocation.width - border_width * 2;
01040       height = widget->allocation.height - border_width * 2;
01041 
01042       if (GTK_WIDGET_HAS_DEFAULT (widget) &&
01043          GTK_FLAT_BUTTON (widget)->relief == GTK_RELIEF_NORMAL)
01044        {
01045          gtk_paint_box (widget->style, widget->window,
01046                       GTK_STATE_NORMAL, GTK_SHADOW_IN,
01047                       area, widget, "buttondefault",
01048                       x, y, width, height);
01049 
01050          x += default_border.left;
01051          y += default_border.top;
01052          width -= default_border.left + default_border.right;
01053          height -= default_border.top + default_border.bottom;
01054        }
01055       else if (GTK_WIDGET_CAN_DEFAULT (widget))
01056        {
01057          x += default_outside_border.left;
01058          y += default_outside_border.top;
01059          width -= default_outside_border.left + default_outside_border.right;
01060          height -= default_outside_border.top + default_outside_border.bottom;
01061        }
01062        
01063       if (!interior_focus && GTK_WIDGET_HAS_FOCUS (widget))
01064        {
01065          x += focus_width + focus_pad;
01066          y += focus_width + focus_pad;
01067          width -= 2 * (focus_width + focus_pad);
01068          height -= 2 * (focus_width + focus_pad);
01069        }
01070 
01071       if (button->relief != GTK_RELIEF_NONE || button->depressed ||
01072          GTK_WIDGET_STATE(widget) == GTK_STATE_PRELIGHT)
01073        gtk_paint_box (widget->style, widget->window,
01074                      state_type,
01075                      shadow_type, area, widget, "button",
01076                      x, y, width, height);
01077        
01078       if (GTK_WIDGET_HAS_FOCUS (widget))
01079        {
01080          if (interior_focus)
01081            {
01082              x += widget->style->xthickness + focus_pad;
01083              y += widget->style->ythickness + focus_pad;
01084              width -= 2 * (widget->style->xthickness + focus_pad);
01085              height -=  2 * (widget->style->ythickness + focus_pad);
01086            }
01087          else
01088            {
01089              x -= focus_width + focus_pad;
01090              y -= focus_width + focus_pad;
01091              width += 2 * (focus_width + focus_pad);
01092              height += 2 * (focus_width + focus_pad);
01093            }
01094 
01095          gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget),
01096                         area, widget, "button",
01097                         x, y, width, height);
01098        }
01099     }
01100 }
01101 
01102 static gboolean
01103 gtk_flat_button_expose (GtkWidget      *widget,
01104                  GdkEventExpose *event)
01105 {
01106   if (GTK_WIDGET_DRAWABLE (widget))
01107     {
01108       GtkFlatButton *button = GTK_FLAT_BUTTON (widget);
01109 
01110       if (GTK_WIDGET_STATE (widget) != GTK_STATE_NORMAL && 
01111                 GTK_WIDGET_STATE (widget) != GTK_STATE_INSENSITIVE) {
01112           _gtk_flat_button_paint (button, &event->area,
01113                       GTK_WIDGET_STATE (widget),
01114                       button->depressed ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
01115                       "button", "buttondefault");
01116       }
01117       
01118       (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
01119     }
01120   
01121   return FALSE;
01122 }
01123 
01124 static gboolean
01125 gtk_flat_button_button_press (GtkWidget      *widget,
01126                       GdkEventButton *event)
01127 {
01128   GtkFlatButton *button;
01129 
01130   if (event->type == GDK_BUTTON_PRESS)
01131     {
01132       button = GTK_FLAT_BUTTON (widget);
01133 
01134       if (button->focus_on_click && !GTK_WIDGET_HAS_FOCUS (widget))
01135        gtk_widget_grab_focus (widget);
01136 
01137       if (event->button == 1)
01138        gtk_flat_button_pressed (button);
01139     }
01140 
01141   return TRUE;
01142 }
01143 
01144 static gboolean
01145 gtk_flat_button_button_release (GtkWidget      *widget,
01146                         GdkEventButton *event)
01147 {
01148   GtkFlatButton *button;
01149 
01150   if (event->button == 1)
01151     {
01152       button = GTK_FLAT_BUTTON (widget);
01153       gtk_flat_button_released (button);
01154     }
01155 
01156   return TRUE;
01157 }
01158 
01159 static gboolean
01160 gtk_flat_button_key_release (GtkWidget   *widget,
01161                      GdkEventKey *event)
01162 {
01163   GtkFlatButton *button = GTK_FLAT_BUTTON (widget);
01164 
01165   if (button->activate_timeout)
01166     {
01167       gtk_flat_button_finish_activate (button, TRUE);
01168       return TRUE;
01169     }
01170   else if (GTK_WIDGET_CLASS (parent_class)->key_release_event)
01171     return GTK_WIDGET_CLASS (parent_class)->key_release_event (widget, event);
01172   else
01173     return FALSE;
01174 }
01175 
01176 static gboolean
01177 gtk_flat_button_enter_notify (GtkWidget        *widget,
01178                       GdkEventCrossing *event)
01179 {
01180   GtkFlatButton *button;
01181   GtkWidget *event_widget;
01182 
01183   button = GTK_FLAT_BUTTON (widget);
01184   event_widget = gtk_get_event_widget ((GdkEvent*) event);
01185 
01186   if ((event_widget == widget) &&
01187       (event->detail != GDK_NOTIFY_INFERIOR))
01188     {
01189       button->in_button = TRUE;
01190       gtk_flat_button_enter (button);
01191     }
01192 
01193   return FALSE;
01194 }
01195 
01196 static gboolean
01197 gtk_flat_button_leave_notify (GtkWidget        *widget,
01198                       GdkEventCrossing *event)
01199 {
01200   GtkFlatButton *button;
01201   GtkWidget *event_widget;
01202 
01203   button = GTK_FLAT_BUTTON (widget);
01204   event_widget = gtk_get_event_widget ((GdkEvent*) event);
01205 
01206   if ((event_widget == widget) &&
01207       (event->detail != GDK_NOTIFY_INFERIOR))
01208     {
01209       button->in_button = FALSE;
01210       gtk_flat_button_leave (button);
01211     }
01212 
01213   return FALSE;
01214 }
01215 
01216 static void
01217 gtk_real_button_pressed (GtkFlatButton *button)
01218 {
01219   if (button->activate_timeout)
01220     return;
01221   
01222   button->button_down = TRUE;
01223   gtk_flat_button_update_state (button);
01224 }
01225 
01226 static void
01227 gtk_real_button_released (GtkFlatButton *button)
01228 {
01229   if (button->button_down)
01230     {
01231       button->button_down = FALSE;
01232 
01233       if (button->activate_timeout)
01234        return;
01235       
01236       if (button->in_button)
01237        gtk_flat_button_clicked (button);
01238 
01239       gtk_flat_button_update_state (button);
01240     }
01241 }
01242 
01243 static gboolean
01244 button_activate_timeout (gpointer data)
01245 {
01246   GDK_THREADS_ENTER ();
01247   
01248   gtk_flat_button_finish_activate (data, TRUE);
01249 
01250   GDK_THREADS_LEAVE ();
01251 
01252   return FALSE;
01253 }
01254 
01255 static void
01256 gtk_real_button_activate (GtkFlatButton *button)
01257 {
01258   GtkWidget *widget = GTK_WIDGET (button);
01259   
01260   if (GTK_WIDGET_REALIZED (button) && !button->activate_timeout)
01261     {
01262       if (gdk_keyboard_grab (button->event_window, TRUE,
01263                           gtk_get_current_event_time ()) == 0)
01264        {
01265          gtk_grab_add (widget);
01266          
01267          button->activate_timeout = g_timeout_add (ACTIVATE_TIMEOUT,
01268                                               button_activate_timeout,
01269                                               button);
01270          button->button_down = TRUE;
01271          gtk_flat_button_update_state (button);
01272          gtk_widget_queue_draw (GTK_WIDGET (button));
01273        }
01274     }
01275 }
01276 
01277 static void
01278 gtk_flat_button_finish_activate (GtkFlatButton *button,
01279                          gboolean   do_it)
01280 {
01281   GtkWidget *widget = GTK_WIDGET (button);
01282   
01283   g_source_remove (button->activate_timeout);
01284   button->activate_timeout = 0;
01285 
01286   gdk_display_keyboard_ungrab (gtk_widget_get_display (widget),
01287                             gtk_get_current_event_time ());
01288   gtk_grab_remove (widget);
01289 
01290   button->button_down = FALSE;
01291 
01292   gtk_flat_button_update_state (button);
01293   gtk_widget_queue_draw (GTK_WIDGET (button));
01294 
01295   if (do_it)
01296     gtk_flat_button_clicked (button);
01297 }
01298 
01310 void
01311 gtk_flat_button_set_label (GtkFlatButton   *button,
01312                     const gchar *label)
01313 {
01314   gchar *new_label;
01315   
01316   g_return_if_fail (GTK_IS_FLAT_BUTTON (button));
01317 
01318   new_label = g_strdup (label);
01319   g_free (button->label_text);
01320   button->label_text = new_label;
01321   
01322   gtk_flat_button_construct_child (button);
01323   
01324   g_object_notify (G_OBJECT (button), "label");
01325 }
01326 
01340 G_CONST_RETURN gchar *
01341 gtk_flat_button_get_label (GtkFlatButton *button)
01342 {
01343   g_return_val_if_fail (GTK_IS_FLAT_BUTTON (button), NULL);
01344   
01345   return button->label_text;
01346 }
01347 
01356 void
01357 gtk_flat_button_set_use_underline (GtkFlatButton *button,
01358                            gboolean   use_underline)
01359 {
01360   g_return_if_fail (GTK_IS_FLAT_BUTTON (button));
01361 
01362   use_underline = use_underline != FALSE;
01363 
01364   if (use_underline != button->use_underline)
01365     {
01366       button->use_underline = use_underline;
01367   
01368       gtk_flat_button_construct_child (button);
01369       
01370       g_object_notify (G_OBJECT (button), "use_underline");
01371     }
01372 }
01373 
01384 gboolean
01385 gtk_flat_button_get_use_underline (GtkFlatButton *button)
01386 {
01387   g_return_val_if_fail (GTK_IS_FLAT_BUTTON (button), FALSE);
01388   
01389   return button->use_underline;
01390 }
01391 
01400 void
01401 gtk_flat_button_set_use_stock (GtkFlatButton *button,
01402                        gboolean   use_stock)
01403 {
01404   g_return_if_fail (GTK_IS_FLAT_BUTTON (button));
01405 
01406   use_stock = use_stock != FALSE;
01407 
01408   if (use_stock != button->use_stock)
01409     {
01410       button->use_stock = use_stock;
01411   
01412       gtk_flat_button_construct_child (button);
01413       
01414       g_object_notify (G_OBJECT (button), "use_stock");
01415     }
01416 }
01417 
01428 gboolean
01429 gtk_flat_button_get_use_stock (GtkFlatButton *button)
01430 {
01431   g_return_val_if_fail (GTK_IS_FLAT_BUTTON (button), FALSE);
01432   
01433   return button->use_stock;
01434 }
01435 
01448 void
01449 gtk_flat_button_set_focus_on_click (GtkFlatButton *button,
01450                             gboolean   focus_on_click)
01451 {
01452   g_return_if_fail (GTK_IS_FLAT_BUTTON (button));
01453   
01454   focus_on_click = focus_on_click != FALSE;
01455 
01456   if (button->focus_on_click != focus_on_click)
01457     {
01458       button->focus_on_click = focus_on_click;
01459       
01460       g_object_notify (G_OBJECT (button), "focus_on_click");
01461     }
01462 }
01463 
01476 gboolean
01477 gtk_flat_button_get_focus_on_click (GtkFlatButton *button)
01478 {
01479   g_return_val_if_fail (GTK_IS_FLAT_BUTTON (button), FALSE);
01480   
01481   return button->focus_on_click;
01482 }
01483 
01497 void
01498 gtk_flat_button_set_alignment (GtkFlatButton *button,
01499                        gfloat     xalign,
01500                        gfloat     yalign)
01501 {
01502   GtkFlatButtonPrivate *priv;
01503 
01504   g_return_if_fail (GTK_IS_FLAT_BUTTON (button));
01505   
01506   priv = GTK_FLAT_BUTTON_GET_PRIVATE (button);
01507 
01508   priv->xalign = xalign;
01509   priv->yalign = yalign;
01510   priv->align_set = 1;
01511 
01512   maybe_set_alignment (button, GTK_BIN (button)->child);
01513 
01514   g_object_freeze_notify (G_OBJECT (button));
01515   g_object_notify (G_OBJECT (button), "xalign");
01516   g_object_notify (G_OBJECT (button), "yalign");
01517   g_object_thaw_notify (G_OBJECT (button));
01518 }
01519 
01530 void
01531 gtk_flat_button_get_alignment (GtkFlatButton *button,
01532                        gfloat    *xalign,
01533                        gfloat    *yalign)
01534 {
01535   GtkFlatButtonPrivate *priv;
01536 
01537   g_return_if_fail (GTK_IS_FLAT_BUTTON (button));
01538   
01539   priv = GTK_FLAT_BUTTON_GET_PRIVATE (button);
01540  
01541   if (xalign) 
01542     *xalign = priv->xalign;
01543 
01544   if (yalign)
01545     *yalign = priv->yalign;
01546 }
01547 
01557 void
01558 _gtk_flat_button_set_depressed (GtkFlatButton *button,
01559                         gboolean   depressed)
01560 {
01561   GtkWidget *widget = GTK_WIDGET (button);
01562 
01563   depressed = depressed != FALSE;
01564 
01565   if (depressed != button->depressed)
01566     {
01567       button->depressed = depressed;
01568       gtk_widget_queue_resize (widget);
01569     }
01570 }
01571 
01572 static void
01573 gtk_flat_button_update_state (GtkFlatButton *button)
01574 {
01575   gboolean depressed;
01576   GtkStateType new_state;
01577 
01578   if (button->activate_timeout)
01579     depressed = button->depress_on_activate;
01580   else
01581     depressed = button->in_button && button->button_down;
01582 
01583   if (button->in_button && (!button->button_down || !depressed))
01584     new_state = GTK_STATE_PRELIGHT;
01585   else
01586     new_state = depressed ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL;
01587 
01588   _gtk_flat_button_set_depressed (button, depressed); 
01589   gtk_widget_set_state (GTK_WIDGET (button), new_state);
01590 }
01591 
01592 static void 
01593 show_image_change_notify (GtkFlatButton *button)
01594 {
01595   GtkFlatButtonPrivate *priv = GTK_FLAT_BUTTON_GET_PRIVATE (button);
01596 
01597   if (priv->image) 
01598     g_object_set (priv->image, "visible", show_image (button), NULL);
01599 }
01600 
01601 static void
01602 gtk_flat_button_screen_changed (GtkWidget *widget,
01603                         GdkScreen *previous_screen)
01604 {
01605   GtkFlatButtonPrivate *priv = GTK_FLAT_BUTTON_GET_PRIVATE (widget);
01606   GtkSettings *settings;
01607 
01608   if (gtk_widget_has_screen (widget))
01609     settings = gtk_widget_get_settings (widget);
01610   else
01611     settings = NULL;
01612 
01613   if (settings == priv->settings)
01614     return;
01615 
01616   if (priv->settings)
01617     {
01618       g_signal_handler_disconnect (priv->settings, priv->show_image_connection);
01619       g_object_unref (priv->settings);
01620     }
01621 
01622   if (settings)
01623     {
01624       priv->show_image_connection =
01625        g_signal_connect_swapped (settings,
01626                               "notify::gtk-button-images",
01627                               G_CALLBACK (show_image_change_notify),
01628                               widget);
01629 
01630       g_object_ref (settings);
01631       priv->settings = settings;
01632     }
01633   else
01634     priv->settings = NULL;
01635 
01636   show_image_change_notify (GTK_FLAT_BUTTON (widget));
01637 }