2 * Copyright © 2010 Codethink Limited
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General
15 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 * Authors: Ryan Lortie <desrt@desrt.ca>
22 #include "gsimpleaction.h"
28 * SECTION:gsimpleaction
29 * @title: GSimpleAction
30 * @short_description: A simple GAction implementation
33 * A #GSimpleAction is the obvious simple implementation of the #GAction
34 * interface. This is the easiest way to create an action for purposes of
35 * adding it to a #GSimpleActionGroup.
37 * See also #GtkAction.
43 * #GSimpleAction is an opaque data structure and can only be accessed
44 * using the following functions.
49 GObject parent_instance
;
52 GVariantType
*parameter_type
;
56 gboolean state_set_already
;
59 typedef GObjectClass GSimpleActionClass
;
61 static void g_simple_action_iface_init (GActionInterface
*iface
);
62 G_DEFINE_TYPE_WITH_CODE (GSimpleAction
, g_simple_action
, G_TYPE_OBJECT
,
63 G_IMPLEMENT_INTERFACE (G_TYPE_ACTION
, g_simple_action_iface_init
))
82 static guint g_simple_action_signals
[NR_SIGNALS
];
85 g_simple_action_get_name (GAction
*action
)
87 GSimpleAction
*simple
= G_SIMPLE_ACTION (action
);
92 static const GVariantType
*
93 g_simple_action_get_parameter_type (GAction
*action
)
95 GSimpleAction
*simple
= G_SIMPLE_ACTION (action
);
97 return simple
->parameter_type
;
100 static const GVariantType
*
101 g_simple_action_get_state_type (GAction
*action
)
103 GSimpleAction
*simple
= G_SIMPLE_ACTION (action
);
105 if (simple
->state
!= NULL
)
106 return g_variant_get_type (simple
->state
);
112 g_simple_action_get_state_hint (GAction
*action
)
114 GSimpleAction
*simple
= G_SIMPLE_ACTION (action
);
116 if (simple
->state_hint
!= NULL
)
117 return g_variant_ref (simple
->state_hint
);
123 g_simple_action_get_enabled (GAction
*action
)
125 GSimpleAction
*simple
= G_SIMPLE_ACTION (action
);
127 return simple
->enabled
;
131 g_simple_action_change_state (GAction
*action
,
134 GSimpleAction
*simple
= G_SIMPLE_ACTION (action
);
136 /* If the user connected a signal handler then they are responsible
137 * for handling state changes.
139 if (g_signal_has_handler_pending (action
, g_simple_action_signals
[SIGNAL_CHANGE_STATE
], 0, TRUE
))
140 g_signal_emit (action
, g_simple_action_signals
[SIGNAL_CHANGE_STATE
], 0, value
);
142 /* If not, then the default behaviour is to just set the state. */
144 g_simple_action_set_state (simple
, value
);
148 * g_simple_action_set_state:
149 * @simple: a #GSimpleAction
150 * @value: the new #GVariant for the state
152 * Sets the state of the action.
154 * This directly updates the 'state' property to the given value.
156 * This should only be called by the implementor of the action. Users
157 * of the action should not attempt to directly modify the 'state'
158 * property. Instead, they should call g_action_change_state() to
159 * request the change.
161 * If the @value GVariant is floating, it is consumed.
166 g_simple_action_set_state (GSimpleAction
*simple
,
169 g_return_if_fail (G_IS_SIMPLE_ACTION (simple
));
170 g_return_if_fail (value
!= NULL
);
173 const GVariantType
*state_type
;
175 state_type
= simple
->state
?
176 g_variant_get_type (simple
->state
) : NULL
;
177 g_return_if_fail (state_type
!= NULL
);
178 g_return_if_fail (g_variant_is_of_type (value
, state_type
));
181 g_variant_ref_sink (value
);
183 if (!simple
->state
|| !g_variant_equal (simple
->state
, value
))
186 g_variant_unref (simple
->state
);
188 simple
->state
= g_variant_ref (value
);
190 g_object_notify (G_OBJECT (simple
), "state");
193 g_variant_unref (value
);
197 g_simple_action_get_state (GAction
*action
)
199 GSimpleAction
*simple
= G_SIMPLE_ACTION (action
);
201 return simple
->state
? g_variant_ref (simple
->state
) : NULL
;
205 g_simple_action_activate (GAction
*action
,
208 GSimpleAction
*simple
= G_SIMPLE_ACTION (action
);
210 g_return_if_fail (simple
->parameter_type
== NULL
?
212 (parameter
!= NULL
&&
213 g_variant_is_of_type (parameter
,
214 simple
->parameter_type
)));
216 if (parameter
!= NULL
)
217 g_variant_ref_sink (parameter
);
221 /* If the user connected a signal handler then they are responsible
222 * for handling activation.
224 if (g_signal_has_handler_pending (action
, g_simple_action_signals
[SIGNAL_ACTIVATE
], 0, TRUE
))
225 g_signal_emit (action
, g_simple_action_signals
[SIGNAL_ACTIVATE
], 0, parameter
);
227 /* If not, do some reasonable defaults for stateful actions. */
228 else if (simple
->state
)
230 /* If we have no parameter and this is a boolean action, toggle. */
231 if (parameter
== NULL
&& g_variant_is_of_type (simple
->state
, G_VARIANT_TYPE_BOOLEAN
))
233 gboolean was_enabled
= g_variant_get_boolean (simple
->state
);
234 g_simple_action_change_state (action
, g_variant_new_boolean (!was_enabled
));
237 /* else, if the parameter and state type are the same, do a change-state */
238 else if (g_variant_is_of_type (simple
->state
, g_variant_get_type (parameter
)))
239 g_simple_action_change_state (action
, parameter
);
243 if (parameter
!= NULL
)
244 g_variant_unref (parameter
);
248 g_simple_action_set_property (GObject
*object
,
253 GSimpleAction
*action
= G_SIMPLE_ACTION (object
);
258 action
->name
= g_strdup (g_value_get_string (value
));
261 case PROP_PARAMETER_TYPE
:
262 action
->parameter_type
= g_value_dup_boxed (value
);
266 action
->enabled
= g_value_get_boolean (value
);
270 /* The first time we see this (during construct) we should just
271 * take the state as it was handed to us.
273 * After that, we should make sure we go through the same checks
276 if (!action
->state_set_already
)
278 action
->state
= g_value_dup_variant (value
);
279 action
->state_set_already
= TRUE
;
282 g_simple_action_set_state (action
, g_value_get_variant (value
));
287 g_assert_not_reached ();
292 g_simple_action_get_property (GObject
*object
,
297 GAction
*action
= G_ACTION (object
);
302 g_value_set_string (value
, g_simple_action_get_name (action
));
305 case PROP_PARAMETER_TYPE
:
306 g_value_set_boxed (value
, g_simple_action_get_parameter_type (action
));
310 g_value_set_boolean (value
, g_simple_action_get_enabled (action
));
313 case PROP_STATE_TYPE
:
314 g_value_set_boxed (value
, g_simple_action_get_state_type (action
));
318 g_value_take_variant (value
, g_simple_action_get_state (action
));
322 g_assert_not_reached ();
327 g_simple_action_finalize (GObject
*object
)
329 GSimpleAction
*simple
= G_SIMPLE_ACTION (object
);
331 g_free (simple
->name
);
332 if (simple
->parameter_type
)
333 g_variant_type_free (simple
->parameter_type
);
335 g_variant_unref (simple
->state
);
336 if (simple
->state_hint
)
337 g_variant_unref (simple
->state_hint
);
339 G_OBJECT_CLASS (g_simple_action_parent_class
)
344 g_simple_action_init (GSimpleAction
*simple
)
346 simple
->enabled
= TRUE
;
350 g_simple_action_iface_init (GActionInterface
*iface
)
352 iface
->get_name
= g_simple_action_get_name
;
353 iface
->get_parameter_type
= g_simple_action_get_parameter_type
;
354 iface
->get_state_type
= g_simple_action_get_state_type
;
355 iface
->get_state_hint
= g_simple_action_get_state_hint
;
356 iface
->get_enabled
= g_simple_action_get_enabled
;
357 iface
->get_state
= g_simple_action_get_state
;
358 iface
->change_state
= g_simple_action_change_state
;
359 iface
->activate
= g_simple_action_activate
;
363 g_simple_action_class_init (GSimpleActionClass
*class)
365 GObjectClass
*object_class
= G_OBJECT_CLASS (class);
367 object_class
->set_property
= g_simple_action_set_property
;
368 object_class
->get_property
= g_simple_action_get_property
;
369 object_class
->finalize
= g_simple_action_finalize
;
372 * GSimpleAction::activate:
373 * @simple: the #GSimpleAction
374 * @parameter: (nullable): the parameter to the activation, or %NULL if it has
377 * Indicates that the action was just activated.
379 * @parameter will always be of the expected type, i.e. the parameter type
380 * specified when the action was created. If an incorrect type is given when
381 * activating the action, this signal is not emitted.
383 * Since GLib 2.40, if no handler is connected to this signal then the
384 * default behaviour for boolean-stated actions with a %NULL parameter
385 * type is to toggle them via the #GSimpleAction::change-state signal.
386 * For stateful actions where the state type is equal to the parameter
387 * type, the default is to forward them directly to
388 * #GSimpleAction::change-state. This should allow almost all users
389 * of #GSimpleAction to connect only one handler or the other.
393 g_simple_action_signals
[SIGNAL_ACTIVATE
] =
394 g_signal_new (I_("activate"),
395 G_TYPE_SIMPLE_ACTION
,
396 G_SIGNAL_RUN_LAST
| G_SIGNAL_MUST_COLLECT
,
398 g_cclosure_marshal_VOID__VARIANT
,
403 * GSimpleAction::change-state:
404 * @simple: the #GSimpleAction
405 * @value: (nullable): the requested value for the state
407 * Indicates that the action just received a request to change its
410 * @value will always be of the correct state type, i.e. the type of the
411 * initial state passed to g_simple_action_new_stateful(). If an incorrect
412 * type is given when requesting to change the state, this signal is not
415 * If no handler is connected to this signal then the default
416 * behaviour is to call g_simple_action_set_state() to set the state
417 * to the requested value. If you connect a signal handler then no
418 * default action is taken. If the state should change then you must
419 * call g_simple_action_set_state() from the handler.
421 * An example of a 'change-state' handler:
422 * |[<!-- language="C" -->
424 * change_volume_state (GSimpleAction *action,
426 * gpointer user_data)
430 * requested = g_variant_get_int32 (value);
432 * // Volume only goes from 0 to 10
433 * if (0 <= requested && requested <= 10)
434 * g_simple_action_set_state (action, value);
438 * The handler need not set the state to the requested value.
439 * It could set it to any value at all, or take some other action.
443 g_simple_action_signals
[SIGNAL_CHANGE_STATE
] =
444 g_signal_new (I_("change-state"),
445 G_TYPE_SIMPLE_ACTION
,
446 G_SIGNAL_RUN_LAST
| G_SIGNAL_MUST_COLLECT
,
448 g_cclosure_marshal_VOID__VARIANT
,
453 * GSimpleAction:name:
455 * The name of the action. This is mostly meaningful for identifying
456 * the action once it has been added to a #GSimpleActionGroup.
460 g_object_class_install_property (object_class
, PROP_NAME
,
461 g_param_spec_string ("name",
463 P_("The name used to invoke the action"),
466 G_PARAM_CONSTRUCT_ONLY
|
467 G_PARAM_STATIC_STRINGS
));
470 * GSimpleAction:parameter-type:
472 * The type of the parameter that must be given when activating the
477 g_object_class_install_property (object_class
, PROP_PARAMETER_TYPE
,
478 g_param_spec_boxed ("parameter-type",
479 P_("Parameter Type"),
480 P_("The type of GVariant passed to activate()"),
483 G_PARAM_CONSTRUCT_ONLY
|
484 G_PARAM_STATIC_STRINGS
));
487 * GSimpleAction:enabled:
489 * If @action is currently enabled.
491 * If the action is disabled then calls to g_action_activate() and
492 * g_action_change_state() have no effect.
496 g_object_class_install_property (object_class
, PROP_ENABLED
,
497 g_param_spec_boolean ("enabled",
499 P_("If the action can be activated"),
502 G_PARAM_STATIC_STRINGS
));
505 * GSimpleAction:state-type:
507 * The #GVariantType of the state that the action has, or %NULL if the
508 * action is stateless.
512 g_object_class_install_property (object_class
, PROP_STATE_TYPE
,
513 g_param_spec_boxed ("state-type",
515 P_("The type of the state kept by the action"),
518 G_PARAM_STATIC_STRINGS
));
521 * GSimpleAction:state:
523 * The state of the action, or %NULL if the action is stateless.
527 g_object_class_install_property (object_class
, PROP_STATE
,
528 g_param_spec_variant ("state",
530 P_("The state the action is in"),
533 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
|
534 G_PARAM_STATIC_STRINGS
));
538 * g_simple_action_set_enabled:
539 * @simple: a #GSimpleAction
540 * @enabled: whether the action is enabled
542 * Sets the action as enabled or not.
544 * An action must be enabled in order to be activated or in order to
545 * have its state changed from outside callers.
547 * This should only be called by the implementor of the action. Users
548 * of the action should not attempt to modify its enabled flag.
553 g_simple_action_set_enabled (GSimpleAction
*simple
,
556 g_return_if_fail (G_IS_SIMPLE_ACTION (simple
));
560 if (simple
->enabled
!= enabled
)
562 simple
->enabled
= enabled
;
563 g_object_notify (G_OBJECT (simple
), "enabled");
568 * g_simple_action_set_state_hint:
569 * @simple: a #GSimpleAction
570 * @state_hint: (nullable): a #GVariant representing the state hint
572 * Sets the state hint for the action.
574 * See g_action_get_state_hint() for more information about
575 * action state hints.
580 g_simple_action_set_state_hint (GSimpleAction
*simple
,
581 GVariant
*state_hint
)
583 g_return_if_fail (G_IS_SIMPLE_ACTION (simple
));
585 if (simple
->state_hint
!= NULL
)
587 g_variant_unref (simple
->state_hint
);
588 simple
->state_hint
= NULL
;
591 if (state_hint
!= NULL
)
592 simple
->state_hint
= g_variant_ref (state_hint
);
596 * g_simple_action_new:
597 * @name: the name of the action
598 * @parameter_type: (nullable): the type of parameter that will be passed to
599 * handlers for the #GSimpleAction::activate signal, or %NULL for no parameter
601 * Creates a new action.
603 * The created action is stateless. See g_simple_action_new_stateful() to create
604 * an action that has state.
606 * Returns: a new #GSimpleAction
611 g_simple_action_new (const gchar
*name
,
612 const GVariantType
*parameter_type
)
614 g_return_val_if_fail (name
!= NULL
, NULL
);
616 return g_object_new (G_TYPE_SIMPLE_ACTION
,
618 "parameter-type", parameter_type
,
623 * g_simple_action_new_stateful:
624 * @name: the name of the action
625 * @parameter_type: (nullable): the type of the parameter that will be passed to
626 * handlers for the #GSimpleAction::activate signal, or %NULL for no parameter
627 * @state: the initial state of the action
629 * Creates a new stateful action.
631 * All future state values must have the same #GVariantType as the initial
634 * If the @state #GVariant is floating, it is consumed.
636 * Returns: a new #GSimpleAction
641 g_simple_action_new_stateful (const gchar
*name
,
642 const GVariantType
*parameter_type
,
645 return g_object_new (G_TYPE_SIMPLE_ACTION
,
647 "parameter-type", parameter_type
,