X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;ds=sidebyside;f=gtk%2Fgtktoggleaction.c;h=46cea60965171facd51adb4cca318609dcbdceb7;hb=c8403f697edef57f33c66d3d8deb1488db86d949;hp=51f5113e5034526627b5922960b6e71e47628a26;hpb=9ae676b06baf394d0cee706264210126c293bfc1;p=~andy%2Fgtk diff --git a/gtk/gtktoggleaction.c b/gtk/gtktoggleaction.c index 51f5113e5..46cea6096 100644 --- a/gtk/gtktoggleaction.c +++ b/gtk/gtktoggleaction.c @@ -14,9 +14,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with the Gnome Library; see the file COPYING.LIB. If not, - * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ /* @@ -28,13 +26,30 @@ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ -#include +#include "config.h" +#include "gtkintl.h" #include "gtktoggleaction.h" -#include "gtktoggleactionprivate.h" #include "gtktoggletoolbutton.h" #include "gtktogglebutton.h" #include "gtkcheckmenuitem.h" +#include "gtkprivate.h" + + +/** + * SECTION:gtktoggleaction + * @Short_description: An action which can be toggled between two states + * @Title: GtkToggleAction + * + * A #GtkToggleAction corresponds roughly to a #GtkCheckMenuItem. It has an + * "active" state specifying whether the action has been checked or not. + */ + +struct _GtkToggleActionPrivate +{ + guint active : 1; + guint draw_as_radio : 1; +}; enum { @@ -42,43 +57,25 @@ enum LAST_SIGNAL }; -static void gtk_toggle_action_init (GtkToggleAction *action); -static void gtk_toggle_action_class_init (GtkToggleActionClass *class); +enum { + PROP_0, + PROP_DRAW_AS_RADIO, + PROP_ACTIVE +}; -GType -gtk_toggle_action_get_type (void) -{ - static GtkType type = 0; +G_DEFINE_TYPE (GtkToggleAction, gtk_toggle_action, GTK_TYPE_ACTION) - if (!type) - { - static const GTypeInfo type_info = - { - sizeof (GtkToggleActionClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) gtk_toggle_action_class_init, - (GClassFinalizeFunc) NULL, - NULL, - - sizeof (GtkToggleAction), - 0, /* n_preallocs */ - (GInstanceInitFunc) gtk_toggle_action_init, - }; - - type = g_type_register_static (GTK_TYPE_ACTION, - "GtkToggleAction", - &type_info, 0); - } - return type; -} +static void gtk_toggle_action_activate (GtkAction *action); +static void set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static GtkWidget *create_menu_item (GtkAction *action); -static void gtk_toggle_action_activate (GtkAction *action); -static void gtk_toggle_action_real_toggled (GtkToggleAction *action); -static void connect_proxy (GtkAction *action, - GtkWidget *proxy); -static void disconnect_proxy (GtkAction *action, - GtkWidget *proxy); static GObjectClass *parent_class = NULL; static guint action_signals[LAST_SIGNAL] = { 0 }; @@ -93,17 +90,57 @@ gtk_toggle_action_class_init (GtkToggleActionClass *klass) gobject_class = G_OBJECT_CLASS (klass); action_class = GTK_ACTION_CLASS (klass); + gobject_class->set_property = set_property; + gobject_class->get_property = get_property; + action_class->activate = gtk_toggle_action_activate; - action_class->connect_proxy = connect_proxy; - action_class->disconnect_proxy = disconnect_proxy; action_class->menu_item_type = GTK_TYPE_CHECK_MENU_ITEM; action_class->toolbar_item_type = GTK_TYPE_TOGGLE_TOOL_BUTTON; - klass->toggled = gtk_toggle_action_real_toggled; - + action_class->create_menu_item = create_menu_item; + + klass->toggled = NULL; + + /** + * GtkToggleAction:draw-as-radio: + * + * Whether the proxies for this action look like radio action proxies. + * + * This is an appearance property and thus only applies if + * #GtkActivatable:use-action-appearance is %TRUE. + */ + g_object_class_install_property (gobject_class, + PROP_DRAW_AS_RADIO, + g_param_spec_boolean ("draw-as-radio", + P_("Create the same proxies as a radio action"), + P_("Whether the proxies for this action look like radio action proxies"), + FALSE, + GTK_PARAM_READWRITE)); + + /** + * GtkToggleAction:active: + * + * Whether the toggle action should be active. + * + * Since: 2.10 + */ + g_object_class_install_property (gobject_class, + PROP_ACTIVE, + g_param_spec_boolean ("active", + P_("Active"), + P_("Whether the toggle action should be active"), + FALSE, + GTK_PARAM_READWRITE)); + /** + * GtkToggleAction::toggled: + * @toggleaction: the object which received the signal. + * + * Should be connected if you wish to perform an action + * whenever the #GtkToggleAction state is changed. + */ action_signals[TOGGLED] = - g_signal_new ("toggled", + g_signal_new (I_("toggled"), G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GtkToggleActionClass, toggled), @@ -117,84 +154,104 @@ gtk_toggle_action_class_init (GtkToggleActionClass *klass) static void gtk_toggle_action_init (GtkToggleAction *action) { - action->private_data = GTK_TOGGLE_ACTION_GET_PRIVATE (action); + action->private_data = G_TYPE_INSTANCE_GET_PRIVATE (action, + GTK_TYPE_TOGGLE_ACTION, + GtkToggleActionPrivate); action->private_data->active = FALSE; + action->private_data->draw_as_radio = FALSE; } -static void -gtk_toggle_action_activate (GtkAction *action) +/** + * gtk_toggle_action_new: + * @name: A unique name for the action + * @label: (allow-none): The label displayed in menu items and on buttons, + * or %NULL + * @tooltip: (allow-none): A tooltip for the action, or %NULL + * @stock_id: (allow-none): The stock icon to display in widgets representing + * the action, or %NULL + * + * Creates a new #GtkToggleAction object. To add the action to + * a #GtkActionGroup and set the accelerator for the action, + * call gtk_action_group_add_action_with_accel(). + * + * Return value: a new #GtkToggleAction + * + * Since: 2.4 + */ +GtkToggleAction * +gtk_toggle_action_new (const gchar *name, + const gchar *label, + const gchar *tooltip, + const gchar *stock_id) { - GtkToggleAction *toggle_action; - - g_return_if_fail (GTK_IS_TOGGLE_ACTION (action)); - - toggle_action = GTK_TOGGLE_ACTION (action); - - toggle_action->private_data->active = !toggle_action->private_data->active; - - gtk_toggle_action_toggled (toggle_action); + g_return_val_if_fail (name != NULL, NULL); + + return g_object_new (GTK_TYPE_TOGGLE_ACTION, + "name", name, + "label", label, + "tooltip", tooltip, + "stock-id", stock_id, + NULL); } static void -gtk_toggle_action_real_toggled (GtkToggleAction *action) +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { - GSList *slist; - - g_return_if_fail (GTK_IS_TOGGLE_ACTION (action)); - - for (slist = gtk_action_get_proxies (GTK_ACTION (action)); slist; slist = slist->next) + GtkToggleAction *action = GTK_TOGGLE_ACTION (object); + + switch (prop_id) { - GtkWidget *proxy = slist->data; - - gtk_action_block_activate_from (GTK_ACTION (action), proxy); - if (GTK_IS_CHECK_MENU_ITEM (proxy)) - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (proxy), - action->private_data->active); - else if (GTK_IS_TOGGLE_TOOL_BUTTON (proxy)) - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (proxy), - action->private_data->active); - else if (GTK_IS_TOGGLE_BUTTON (proxy)) - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (proxy), - action->private_data->active); - else { - g_warning ("Don't know how to toggle `%s' widgets", - G_OBJECT_TYPE_NAME (proxy)); - } - gtk_action_unblock_activate_from (GTK_ACTION (action), proxy); + case PROP_DRAW_AS_RADIO: + g_value_set_boolean (value, gtk_toggle_action_get_draw_as_radio (action)); + break; + case PROP_ACTIVE: + g_value_set_boolean (value, gtk_toggle_action_get_active (action)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; } } static void -connect_proxy (GtkAction *action, - GtkWidget *proxy) +set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - GtkToggleAction *toggle_action; - - toggle_action = GTK_TOGGLE_ACTION (action); - - /* do this before hand, so that we don't call the "activate" handler */ - if (GTK_IS_MENU_ITEM (proxy)) - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (proxy), - toggle_action->private_data->active); - else if (GTK_IS_TOGGLE_TOOL_BUTTON (proxy)) - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (proxy), - toggle_action->private_data->active); - else if (GTK_IS_TOGGLE_BUTTON (proxy)) - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (proxy), - toggle_action->private_data->active); - - (* GTK_ACTION_CLASS (parent_class)->connect_proxy) (action, proxy); + GtkToggleAction *action = GTK_TOGGLE_ACTION (object); + + switch (prop_id) + { + case PROP_DRAW_AS_RADIO: + gtk_toggle_action_set_draw_as_radio (action, g_value_get_boolean (value)); + break; + case PROP_ACTIVE: + gtk_toggle_action_set_active (action, g_value_get_boolean (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void -disconnect_proxy (GtkAction *action, - GtkWidget *proxy) +gtk_toggle_action_activate (GtkAction *action) { GtkToggleAction *toggle_action; + g_return_if_fail (GTK_IS_TOGGLE_ACTION (action)); + toggle_action = GTK_TOGGLE_ACTION (action); - (* GTK_ACTION_CLASS (parent_class)->disconnect_proxy) (action, proxy); + toggle_action->private_data->active = !toggle_action->private_data->active; + + g_object_notify (G_OBJECT (action), "active"); + + gtk_toggle_action_toggled (toggle_action); } /** @@ -231,15 +288,15 @@ gtk_toggle_action_set_active (GtkToggleAction *action, is_active = is_active != FALSE; if (action->private_data->active != is_active) - { - gtk_action_activate (GTK_ACTION (action)); - } + _gtk_action_emit_activate (GTK_ACTION (action)); } /** * gtk_toggle_action_get_active: * @action: the action object * + * Returns the checked state of the toggle action. + * * Returns: the checked state of the toggle action * * Since: 2.4 @@ -251,3 +308,78 @@ gtk_toggle_action_get_active (GtkToggleAction *action) return action->private_data->active; } + + +/** + * gtk_toggle_action_set_draw_as_radio: + * @action: the action object + * @draw_as_radio: whether the action should have proxies like a radio + * action + * + * Sets whether the action should have proxies like a radio action. + * + * Since: 2.4 + */ +void +gtk_toggle_action_set_draw_as_radio (GtkToggleAction *action, + gboolean draw_as_radio) +{ + g_return_if_fail (GTK_IS_TOGGLE_ACTION (action)); + + draw_as_radio = draw_as_radio != FALSE; + + if (action->private_data->draw_as_radio != draw_as_radio) + { + action->private_data->draw_as_radio = draw_as_radio; + + g_object_notify (G_OBJECT (action), "draw-as-radio"); + } +} + +/** + * gtk_toggle_action_get_draw_as_radio: + * @action: the action object + * + * Returns whether the action should have proxies like a radio action. + * + * Returns: whether the action should have proxies like a radio action. + * + * Since: 2.4 + */ +gboolean +gtk_toggle_action_get_draw_as_radio (GtkToggleAction *action) +{ + g_return_val_if_fail (GTK_IS_TOGGLE_ACTION (action), FALSE); + + return action->private_data->draw_as_radio; +} + +static GtkWidget * +create_menu_item (GtkAction *action) +{ + GtkToggleAction *toggle_action = GTK_TOGGLE_ACTION (action); + + return g_object_new (GTK_TYPE_CHECK_MENU_ITEM, + "draw-as-radio", toggle_action->private_data->draw_as_radio, + NULL); +} + + +/* Private */ + +/* + * _gtk_toggle_action_set_active: + * @toggle_action: a #GtkToggleAction + * @is_active: whether the action is active or not + * + * Sets the #GtkToggleAction:active property directly. This function does + * not emit signals or notifications: it is left to the caller to do so. + */ +void +_gtk_toggle_action_set_active (GtkToggleAction *toggle_action, + gboolean is_active) +{ + GtkToggleActionPrivate *priv = toggle_action->private_data; + + priv->active = is_active; +}