2 * Copyright © 2010 Codethink Limited
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 2 of the licence or (at
7 * 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
376 * Indicates that the action was just activated.
378 * @parameter will always be of the expected type. In the event that
379 * an incorrect type was given, no signal will be emitted.
381 * Since GLib 2.40, if no handler is connected to this signal then the
382 * default behaviour for boolean-stated actions with a %NULL parameter
383 * type is to toggle them via the #GSimpleAction::change-state signal.
384 * For stateful actions where the state type is equal to the parameter
385 * type, the default is to forward them directly to
386 * #GSimpleAction::change-state. This should allow almost all users
387 * of #GSimpleAction to connect only one handler or the other.
391 g_simple_action_signals
[SIGNAL_ACTIVATE
] =
392 g_signal_new (I_("activate"),
393 G_TYPE_SIMPLE_ACTION
,
394 G_SIGNAL_RUN_LAST
| G_SIGNAL_MUST_COLLECT
,
396 g_cclosure_marshal_VOID__VARIANT
,
401 * GSimpleAction::change-state:
402 * @simple: the #GSimpleAction
403 * @value: (nullable): the requested value for the state
405 * Indicates that the action just received a request to change its
408 * @value will always be of the correct state type. In the event that
409 * an incorrect type was given, no signal will be emitted.
411 * If no handler is connected to this signal then the default
412 * behaviour is to call g_simple_action_set_state() to set the state
413 * to the requested value. If you connect a signal handler then no
414 * default action is taken. If the state should change then you must
415 * call g_simple_action_set_state() from the handler.
417 * An example of a 'change-state' handler:
418 * |[<!-- language="C" -->
420 * change_volume_state (GSimpleAction *action,
422 * gpointer user_data)
426 * requested = g_variant_get_int32 (value);
428 * // Volume only goes from 0 to 10
429 * if (0 <= requested && requested <= 10)
430 * g_simple_action_set_state (action, value);
434 * The handler need not set the state to the requested value.
435 * It could set it to any value at all, or take some other action.
439 g_simple_action_signals
[SIGNAL_CHANGE_STATE
] =
440 g_signal_new (I_("change-state"),
441 G_TYPE_SIMPLE_ACTION
,
442 G_SIGNAL_RUN_LAST
| G_SIGNAL_MUST_COLLECT
,
444 g_cclosure_marshal_VOID__VARIANT
,
449 * GSimpleAction:name:
451 * The name of the action. This is mostly meaningful for identifying
452 * the action once it has been added to a #GSimpleActionGroup.
456 g_object_class_install_property (object_class
, PROP_NAME
,
457 g_param_spec_string ("name",
459 P_("The name used to invoke the action"),
462 G_PARAM_CONSTRUCT_ONLY
|
463 G_PARAM_STATIC_STRINGS
));
466 * GSimpleAction:parameter-type:
468 * The type of the parameter that must be given when activating the
473 g_object_class_install_property (object_class
, PROP_PARAMETER_TYPE
,
474 g_param_spec_boxed ("parameter-type",
475 P_("Parameter Type"),
476 P_("The type of GVariant passed to activate()"),
479 G_PARAM_CONSTRUCT_ONLY
|
480 G_PARAM_STATIC_STRINGS
));
483 * GSimpleAction:enabled:
485 * If @action is currently enabled.
487 * If the action is disabled then calls to g_action_activate() and
488 * g_action_change_state() have no effect.
492 g_object_class_install_property (object_class
, PROP_ENABLED
,
493 g_param_spec_boolean ("enabled",
495 P_("If the action can be activated"),
498 G_PARAM_STATIC_STRINGS
));
501 * GSimpleAction:state-type:
503 * The #GVariantType of the state that the action has, or %NULL if the
504 * action is stateless.
508 g_object_class_install_property (object_class
, PROP_STATE_TYPE
,
509 g_param_spec_boxed ("state-type",
511 P_("The type of the state kept by the action"),
514 G_PARAM_STATIC_STRINGS
));
517 * GSimpleAction:state:
519 * The state of the action, or %NULL if the action is stateless.
523 g_object_class_install_property (object_class
, PROP_STATE
,
524 g_param_spec_variant ("state",
526 P_("The state the action is in"),
529 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
|
530 G_PARAM_STATIC_STRINGS
));
534 * g_simple_action_set_enabled:
535 * @simple: a #GSimpleAction
536 * @enabled: whether the action is enabled
538 * Sets the action as enabled or not.
540 * An action must be enabled in order to be activated or in order to
541 * have its state changed from outside callers.
543 * This should only be called by the implementor of the action. Users
544 * of the action should not attempt to modify its enabled flag.
549 g_simple_action_set_enabled (GSimpleAction
*simple
,
552 g_return_if_fail (G_IS_SIMPLE_ACTION (simple
));
556 if (simple
->enabled
!= enabled
)
558 simple
->enabled
= enabled
;
559 g_object_notify (G_OBJECT (simple
), "enabled");
564 * g_simple_action_set_state_hint:
565 * @simple: a #GSimpleAction
566 * @state_hint: (nullable): a #GVariant representing the state hint
568 * Sets the state hint for the action.
570 * See g_action_get_state_hint() for more information about
571 * action state hints.
576 g_simple_action_set_state_hint (GSimpleAction
*simple
,
577 GVariant
*state_hint
)
579 g_return_if_fail (G_IS_SIMPLE_ACTION (simple
));
581 if (simple
->state_hint
!= NULL
)
583 g_variant_unref (simple
->state_hint
);
584 simple
->state_hint
= NULL
;
587 if (state_hint
!= NULL
)
588 simple
->state_hint
= g_variant_ref (state_hint
);
592 * g_simple_action_new:
593 * @name: the name of the action
594 * @parameter_type: (nullable): the type of parameter to the activate function
596 * Creates a new action.
598 * The created action is stateless. See g_simple_action_new_stateful().
600 * Returns: a new #GSimpleAction
605 g_simple_action_new (const gchar
*name
,
606 const GVariantType
*parameter_type
)
608 g_return_val_if_fail (name
!= NULL
, NULL
);
610 return g_object_new (G_TYPE_SIMPLE_ACTION
,
612 "parameter-type", parameter_type
,
617 * g_simple_action_new_stateful:
618 * @name: the name of the action
619 * @parameter_type: (nullable): the type of the parameter to the activate function
620 * @state: the initial state of the action
622 * Creates a new stateful action.
624 * @state is the initial state of the action. All future state values
625 * must have the same #GVariantType as the initial state.
627 * If the @state GVariant is floating, it is consumed.
629 * Returns: a new #GSimpleAction
634 g_simple_action_new_stateful (const gchar
*name
,
635 const GVariantType
*parameter_type
,
638 return g_object_new (G_TYPE_SIMPLE_ACTION
,
640 "parameter-type", parameter_type
,