2019-05-03 04:58:46 +00:00
|
|
|
<?xml version="1.0"?>
|
|
|
|
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
|
|
|
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
|
|
|
|
]>
|
|
|
|
<refentry id="chap-actions">
|
|
|
|
<refmeta>
|
|
|
|
<refentrytitle>The GTK Action Model</refentrytitle>
|
|
|
|
<manvolnum>3</manvolnum>
|
|
|
|
<refmiscinfo>GTK Library</refmiscinfo>
|
|
|
|
</refmeta>
|
|
|
|
|
|
|
|
<refnamediv>
|
|
|
|
<refname>The GTK Action Model</refname>
|
|
|
|
<refpurpose>
|
|
|
|
How actions are used in GTK
|
|
|
|
</refpurpose>
|
|
|
|
</refnamediv>
|
|
|
|
|
|
|
|
|
|
|
|
<refsect1 id="actions-overview">
|
|
|
|
<title>Overview of actions in GTK</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
This chapter describes in detail how GTK uses actions to connect
|
|
|
|
activatable UI elements to callbacks. GTK inherits the underlying
|
|
|
|
architecture of GAction and GMenu for describing abstract actions
|
|
|
|
and menus from the GIO library.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<refsect2>
|
|
|
|
<title>Basics about actions</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
A GAction is essentially a way to tell the toolkit about a
|
|
|
|
piece of functionality in your program, and to give it a name.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Actions are purely functional. They do not contain any
|
|
|
|
presentational information.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
An action has four pieces of information associated with it:
|
|
|
|
<itemizedlist>
|
|
|
|
<listitem><para>
|
|
|
|
a name as an identifier (usually all-lowercase, untranslated
|
|
|
|
English string)
|
|
|
|
</para></listitem>
|
|
|
|
<listitem><para>
|
|
|
|
an enabled flag indicating if the action can be activated or
|
|
|
|
not (like the "sensitive" property on widgets)
|
|
|
|
</para></listitem>
|
|
|
|
<listitem><para>
|
|
|
|
an optional state value, for stateful actions (like a boolean
|
|
|
|
for toggles)
|
|
|
|
</para></listitem>
|
|
|
|
<listitem><para>
|
|
|
|
an optional parameter type, used when activating the action
|
|
|
|
</para></listitem>
|
|
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
An action supports two operations. You can activate it, which
|
|
|
|
requires passing a parameter of the correct type
|
|
|
|
And you can request to change the actions state (for stateful
|
|
|
|
actions) to a new state value of the correct type.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Here are some rules about an action:
|
|
|
|
<itemizedlist>
|
|
|
|
<listitem><para>
|
|
|
|
the name is immutable (in the sense that it will never
|
|
|
|
change) and it is never %NULL
|
|
|
|
</para></listitem>
|
|
|
|
<listitem><para>
|
|
|
|
the enabled flag can change
|
|
|
|
</para></listitem>
|
|
|
|
<listitem><para>
|
|
|
|
the parameter type is immutable
|
|
|
|
</para></listitem>
|
|
|
|
<listitem><para>
|
|
|
|
the parameter type is optional: it can be %NULL
|
|
|
|
</para></listitem>
|
|
|
|
<listitem><para>
|
|
|
|
if the parameter type is %NULL then action activation must
|
|
|
|
be done without a parameter (ie: a %NULL GVariant pointer)
|
|
|
|
</para></listitem>
|
|
|
|
<listitem><para>
|
|
|
|
if the parameter type is non-%NULL then the parameter must
|
|
|
|
have this type
|
|
|
|
</para></listitem>
|
|
|
|
<listitem><para>
|
|
|
|
the state can change, but it cannot change type
|
|
|
|
</para></listitem>
|
|
|
|
<listitem><para>
|
|
|
|
if the action was stateful when it was created, it will
|
|
|
|
always have a state and it will always have exactly the same
|
|
|
|
type (such as boolean or string)
|
|
|
|
</para></listitem>
|
|
|
|
<listitem><para>
|
|
|
|
if the action was stateless when it was created, it can never
|
|
|
|
have a state
|
|
|
|
</para></listitem>
|
|
|
|
<listitem><para>
|
|
|
|
you can only request state changes on stateful actions and it
|
|
|
|
is only possible to request that the state change to a value
|
|
|
|
of the same type as the existing state
|
|
|
|
</para></listitem>
|
|
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
An action does not have any sort of presentational information
|
|
|
|
such as a label, an icon or a way of creating a widget from it.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</refsect2>
|
|
|
|
|
|
|
|
<refsect2>
|
|
|
|
<title>Action state and parameters</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Most actions in your application will be stateless actions with
|
|
|
|
no parameters. These typically appear as menu items with no
|
|
|
|
special decoration. An example is "quit".
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Stateful actions are used to represent an action which has a
|
|
|
|
closely-associated state of some kind. A good example is a
|
|
|
|
"fullscreen" action. For this case, you'd expect to see a
|
|
|
|
checkmark next to the menu item when the fullscreen option
|
|
|
|
is active. This is usually called a toggle action, and it has
|
|
|
|
a boolean state. By convention, toggle actions have no parameter
|
|
|
|
type for activation: activating the action always toggles the
|
|
|
|
state.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Another common case is to have an action representing a
|
|
|
|
enumeration of possible values of a given type (typically
|
|
|
|
string). This is often called a radio action and is usually
|
|
|
|
represented in the user interface with radio buttons or radio
|
|
|
|
menu items, or sometimes a combobox. A good example is
|
|
|
|
"text-justify" with possible values "left", "center", and
|
|
|
|
"right". By convention, these types of actions have a parameter
|
|
|
|
type equal to their state type, and activating them with a
|
|
|
|
particular parameter value is equivalent to changing their
|
|
|
|
state to that value.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
This approach to handling radio buttons is different than many
|
|
|
|
other action systems such as GtkAction. With GAction, there is
|
|
|
|
only one action for "text-justify" and "left", "center" and
|
|
|
|
"right" are possible states on that action. There are not three
|
|
|
|
separate "justify-left", "justify-center" and "justify-right"
|
|
|
|
actions.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The final common type of action is a stateless action with a
|
|
|
|
parameter. This is typically used for actions like
|
|
|
|
"open-bookmark" where the parameter to the action would be
|
|
|
|
the identifier of the bookmark to open.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Because some types of actions cannot be invoked without a
|
|
|
|
parameter, it is often important to specify a parameter when
|
|
|
|
referring to the action from a place where it will be invoked
|
|
|
|
(such as from a radio button that sets the state to a particular
|
|
|
|
value or from a menu item that opens a specific bookmark). In
|
|
|
|
these contexts, the value used for the action parameter is
|
|
|
|
typically called the target of the action.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Even though toggle actions have a state, they do not have a
|
|
|
|
parameter. Therefore, a target value is not needed when
|
|
|
|
referring to them — they will always be toggled on activation.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Most APIs that allow using a GAction (such as GMenuModel and
|
|
|
|
GtkActionable) allow use of detailed action names. This is a
|
|
|
|
convenient way of specifying an action name and an action target
|
|
|
|
with a single string.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
In the case that the action target is a string with no unusual
|
|
|
|
characters (ie: only alpha-numeric, plus '-' and '.') then you
|
|
|
|
can use a detailed action name of the form "justify::left" to
|
|
|
|
specify the justify action with a target of left.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
In the case that the action target is not a string, or contains
|
|
|
|
unusual characters, you can use the more general format
|
|
|
|
"action-name(5)", where the "5" here is any valid text-format
|
|
|
|
GVariant (ie: a string that can be parsed by g_variant_parse()).
|
|
|
|
Another example is "open-bookmark('http://gnome.org/')".
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
You can convert between detailed action names and split-out
|
|
|
|
action names and target values using g_action_parse_detailed_action_name()
|
|
|
|
and g_action_print_detailed_action_name() but usually you will
|
|
|
|
not need to. Most APIs will provide both ways of specifying
|
|
|
|
actions with targets.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</refsect2>
|
|
|
|
|
|
|
|
<refsect2>
|
|
|
|
<title>Action scopes</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Actions are always scoped to a particular object on which they
|
|
|
|
operate.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
In GTK, actions are typically scoped to either an application
|
|
|
|
or a window, but any widget can have actions associated with it.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Actions scoped to windows should be the actions that
|
|
|
|
specifically impact that window. These are actions like
|
|
|
|
"fullscreen" and "close", or in the case that a window contains
|
|
|
|
a document, "save" and "print".
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Actions that impact the application as a whole rather than one
|
|
|
|
specific window are scoped to the application. These are actions
|
|
|
|
like "about" and "preferences".
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
If a particular action is scoped to a window then it is scoped
|
|
|
|
to a specific window. Another way of saying this: if your
|
|
|
|
application has a "fullscreen" action that applies to windows
|
|
|
|
and it has three windows, then it will have three fullscreen
|
|
|
|
actions: one for each window.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Having a separate action per-window allows for each window to
|
|
|
|
have a separate state for each instance of the action as well
|
|
|
|
as being able to control the enabled state of the action on a
|
|
|
|
per-window basis.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2019-06-15 04:15:37 +00:00
|
|
|
Actions are added to their relevant scope (application,
|
|
|
|
window or widget) either using the GActionMap interface,
|
|
|
|
or by using gtk_widget_insert_action_group(). Actions that
|
|
|
|
will be the same for all instances of a widget class can
|
|
|
|
be added globally using gtk_widget_class_install_action().
|
2019-05-03 04:58:46 +00:00
|
|
|
</para>
|
|
|
|
|
|
|
|
</refsect2>
|
|
|
|
|
|
|
|
<refsect2>
|
|
|
|
<title>Action groups and action maps</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Actions rarely occurs in isolation. It is common to have groups
|
|
|
|
of related actions, which are represented by instances of the
|
|
|
|
GActionGroup interface.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Action maps are a variant of action groups that allow to change
|
|
|
|
the name of the action as it is looked up. In GTK, the convention
|
|
|
|
is to add a prefix to the action name to indicate the scope of
|
|
|
|
the actions, such as "app." for the actions with application scope
|
|
|
|
or "win." for those with window scope.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
When referring to actions on a GActionMap only the name of the
|
|
|
|
action itself is used (ie: "quit", not "app.quit"). The
|
|
|
|
"app.quit" form is only used when referring to actions from
|
|
|
|
places like a GMenu or GtkActionable widget where the scope
|
|
|
|
of the action is not already known.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
GtkApplication and GtkApplicationWindow implement the GActionMap
|
|
|
|
interface, so you can just add actions directly to them. For
|
|
|
|
other widgets, use gtk_widget_insert_action_group() to add
|
|
|
|
actions to it.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
If you want to insert several actions at the same time, it is
|
|
|
|
typically faster and easier to use GActionEntry.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</refsect2>
|
|
|
|
|
|
|
|
<refsect2>
|
|
|
|
<title>Connecting actions to widgets</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Any widget that implements the GtkActionable interface can
|
|
|
|
be connected to an action just by setting the ::action-name
|
|
|
|
property. If the action has a parameter, you will also need
|
|
|
|
to set the ::action-target property.
|
2019-12-28 14:55:05 +00:00
|
|
|
Widgets that implement GtkActionable include GtkSwitch, GtkButton,
|
|
|
|
and their respective subclasses.
|
2019-05-03 04:58:46 +00:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2019-06-15 04:15:37 +00:00
|
|
|
Another way of obtaining widgets that are connected to actions
|
|
|
|
is to create a menu using a GMenu menu model. GMenu provides an
|
2019-05-03 04:58:46 +00:00
|
|
|
abstract way to describe typical menus: nested groups of items
|
|
|
|
where each item can have a label, and icon, and an action.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Typical uses of GMenu inside GTK are to set up an application
|
2019-05-04 09:39:35 +00:00
|
|
|
menu or menubar with gtk_application_set_app_menu() or
|
2019-05-03 04:58:46 +00:00
|
|
|
gtk_application_set_menubar(). Another, maybe more common use
|
|
|
|
is to create a popover for a menubutton, using
|
|
|
|
gtk_menu_button_set_menu_model().
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Unlike traditional menus, those created from menu models don't
|
|
|
|
have keyboard accelerators associated with menu items. Instead,
|
|
|
|
GtkApplication offers the gtk_application_set_accels_for_action()
|
|
|
|
API to associate keyboard shortcuts with actions.
|
|
|
|
</para>
|
|
|
|
</refsect2>
|
|
|
|
|
|
|
|
<refsect2>
|
|
|
|
<title>Activation</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
When a widget with a connected action is activated, GTK finds
|
|
|
|
the action to activate by walking up the widget hierarchy,
|
|
|
|
looking for a matching action, ending up at the GtkApplication.
|
|
|
|
</para>
|
|
|
|
</refsect2>
|
|
|
|
|
|
|
|
<refsect2>
|
|
|
|
<title>Built-in Actions</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
GTK uses actions for its own purposes in a number places. These
|
|
|
|
built-in actions can sometimes be activated by applications, and
|
|
|
|
you should avoid naming conflicts with them when creating your
|
|
|
|
own actions.
|
|
|
|
<variablelist>
|
|
|
|
<varlistentry>
|
|
|
|
<term>default.activate</term>
|
|
|
|
<listitem><para>Activates the default widget in a context
|
|
|
|
(typically a GtkWindow, GtkDialog or GtkPopover)
|
|
|
|
</para></listitem>
|
|
|
|
</varlistentry>
|
2019-06-15 04:15:37 +00:00
|
|
|
<varlistentry>
|
|
|
|
<term>clipboard.cut, clipboard.copy, clipboard.paste</term>
|
|
|
|
<listitem><para>Clipboard operations on entries, text view
|
|
|
|
and labels, typically used in the context menu
|
|
|
|
</para></listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>selection.delete, selection.select-all</term>
|
|
|
|
<listitem><para>Selection operations on entries, text view
|
|
|
|
and labels
|
|
|
|
</para></listitem>
|
|
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
|
|
<term>color.select, color.customize</term>
|
|
|
|
<listitem><para>Operations on colors in GtkColorChooserWidget.
|
|
|
|
These actions are unusual in that they have the non-trivial
|
|
|
|
parameter type (dddd).
|
|
|
|
</para></listitem>
|
|
|
|
</varlistentry>
|
2019-05-03 04:58:46 +00:00
|
|
|
</variablelist>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</refsect2>
|
|
|
|
|
|
|
|
</refsect1>
|
|
|
|
</refentry>
|