summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2019-05-03 04:58:46 +0000
committerMatthias Clasen <mclasen@redhat.com>2019-05-04 01:26:45 +0000
commit29bafd1e15aed22b3406b9aacc0378ac7737394c (patch)
treecccf21cda7575e739708f92eefb410b265cd4500 /docs
parent65697e3324047b8fc9347bc50d6067999628c227 (diff)
downloadgtk+-29bafd1e15aed22b3406b9aacc0378ac7737394c.tar.gz
docs: Add an actions overview
Add an introduction chapter explaining actions in detail. Most of this content is taken from the GAction HowDoI page.
Diffstat (limited to 'docs')
-rw-r--r--docs/reference/gtk/actions.xml373
-rw-r--r--docs/reference/gtk/gtk4-docs.xml3
-rw-r--r--docs/reference/gtk/meson.build2
3 files changed, 377 insertions, 1 deletions
diff --git a/docs/reference/gtk/actions.xml b/docs/reference/gtk/actions.xml
new file mode 100644
index 0000000000..3d789b0c79
--- /dev/null
+++ b/docs/reference/gtk/actions.xml
@@ -0,0 +1,373 @@
+<?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>
+ Actions are added to their relevant scope (application or
+ window) either using the GActionMap interface, or by using
+ gtk_widget_insert_action_group().
+ </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.
+ Widgets that implement GtkAction include GtkSwitch, GtkButton,
+ GtkMenuItem and their respective subclasses.
+ </para>
+
+ <para>
+ Another of obtaining widgets that are connected to actions is
+ to create a menu using a GMenu menu model. GMenu provides an
+ 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
+ menu or menubar with gtk_appication_set_app_menu() or
+ 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>
+ </variablelist>
+ </para>
+
+ </refsect2>
+
+ </refsect1>
+</refentry>
diff --git a/docs/reference/gtk/gtk4-docs.xml b/docs/reference/gtk/gtk4-docs.xml
index 17a5337c6f..26f6f028e5 100644
--- a/docs/reference/gtk/gtk4-docs.xml
+++ b/docs/reference/gtk/gtk4-docs.xml
@@ -24,8 +24,9 @@
<xi:include href="xml/getting_started.xml"/>
<xi:include href="resources.sgml" />
<xi:include href="xml/question_index.sgml" />
- <xi:include href="drawing-model.xml" />
+ <xi:include href="xml/drawing-model.xml" />
<xi:include href="xml/input-handling.xml" />
+ <xi:include href="xml/actions.xml" />
</part>
<part id="gtkobjects">
diff --git a/docs/reference/gtk/meson.build b/docs/reference/gtk/meson.build
index 75eb45be35..609cf28faf 100644
--- a/docs/reference/gtk/meson.build
+++ b/docs/reference/gtk/meson.build
@@ -333,6 +333,7 @@ images = [
]
content_files = [
+ 'actions.xml',
'broadway.xml',
'building.sgml',
'compiling.sgml',
@@ -368,6 +369,7 @@ content_files = [
]
expand_content_files = [
+ 'actions.xml',
'compiling.sgml',
'drawing-model.xml',
'glossary.xml',