diff options
author | Matthias Clasen <mclasen@redhat.com> | 2019-05-03 04:58:46 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2019-05-04 01:26:45 +0000 |
commit | 29bafd1e15aed22b3406b9aacc0378ac7737394c (patch) | |
tree | cccf21cda7575e739708f92eefb410b265cd4500 /docs | |
parent | 65697e3324047b8fc9347bc50d6067999628c227 (diff) | |
download | gtk+-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.xml | 373 | ||||
-rw-r--r-- | docs/reference/gtk/gtk4-docs.xml | 3 | ||||
-rw-r--r-- | docs/reference/gtk/meson.build | 2 |
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', |