Difference between revisions of "GUI Guidelines"

From GnuCash
Jump to: navigation, search
(1. Draft)
 
m (Markups in Text: typo)
 
(34 intermediate revisions by 2 users not shown)
Line 1: Line 1:
This page collects rules for the GUI. You should mind them while [[CodingStandard|coding]] or [[Translation|translating]].
+
This page collects rules for the GUI. You should mind them while [[CodingStandard|coding]] or preparing translation ([[I18N]]).
= Mnemonics and Accelerators =
+
 
*'''Accelerators''' are keyboard "hot-keys" like ctrl-c for copy
+
= General =
*'''Mnemonics''' are part of the menu label, the underscore, so they would be included in the msgid.
+
;GnuCash >= 3 is GTK3 based: [https://developer.gnome.org/gtk3/stable/ GTK+ 3 Reference Manual - GNOME Developer Center].
== Possible Problems==
+
;Use the gtkbuilder glade for rapid prototyping and preview: [https://developer.gnome.org/gtkmm-tutorial/stable/chapter-builder.html Glade und Gtk::Builder]
from [https://lists.gnucash.org/logs/2018/01/04.html IRC]:
+
:[http://blog.borovsak.si/2009/09/glade3-tutorial-1-introduction.html Glade3 tutorial]
* First off, mnemonics work differently for different widgets. e.g. on buttons they work like accelerators: <alt>F operates the button with that mnemonic--as long as there isn't an accelerator set to <alt>F because accelerators are handled first by gtkevent. Menuitem mnemonics work without a modifier key if one has the containing menu open.
+
 
* Mnemonics can be attached to any widget via gtk_label_new_with_mnemonic() and gtk_label_set_mnemonic_widget(), so it would be easy to go crazy and have them everywhere.
+
== GUI Resolution ==
* But we also need to be careful to ensure that they're turned off when focus is inside an edit because <alt> is used to extend the keyboard on Macs. For example to type ö I use <alt>u followed by o. We've had several bugs on Gramps where some mnemonic grabbed the <alt>u and prevented users from typing umlauts.
+
The '''maximum size''' of ''all GUI elements'' restricts users to have at least the same resolution on their device to run GnuCash flawless. [https://bugs.gnucash.org/show_bug.cgi?id=797857 Bug 797857 - Edit->Preferences: Help/Close buttons unreachable] remembered us about this restriction.
 +
For
 +
;GnuCash 3 and up: the limit is {{GUI Resolution}}. In the
 +
;GnuCash 2.x series: it was 800x600.
 +
 
 +
= GUI Elements =
 +
 
 +
== Buttons and Icons ==
 +
For [https://docs.google.com/document/d/1KCVPoYQBqMbDP11tHPpjW6uaEHrvLUmcDPqKAppCY8o/pub GTK+ 3.10 Stock Items Deprecation] announced on [https://mail.gnome.org/archives/gtk-devel-list/2013-July/msg00000.html gtk-devel-list/2013-July] and the
 +
[https://docs.google.com/spreadsheets/d/1HavJQRPpMuq-N0GoN1wJR-9KEGXpKy3-NEPpZZkUGJY/pub?output=html Replacement Table] watch the current discussion starting with [https://lists.gnucash.org/pipermail/gnucash-devel/2019-May/043890.html gnucash-devel/2019-May].
 +
 
 +
Standard '''icons''' are now specified in the XDG [https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html Icon Naming Specification]. This will allow each theme to use its own set.
 +
 
 +
== Toolbars ==
 +
Keep often used actions like <tt>Report options</tt> at the beginning of the list.
 +
 
 +
== Menus ==
 +
Menu elements should have a
 +
* [[#Mnemonics|mnemonic]] in their label and they should have a
 +
* [[#Tooltips_and_Descriptions_of_Preferences|tooltip]].
 +
;Ellipses: If a label ''specifies an action'', but further user interaction is required before, the label should have a trailing horizontal ellipse <tt>…</tt> (<code>altGr</code>+<code>.</code>), but not for dialogs like <tt>Properties</tt>, <tt>Preferences</tt>, … See details at the bottom of https://developer.gnome.org/hig/stable/writing-style.html
 +
 
 +
=== Mnemonics and Accelerators ===
 +
Gtk+ provides two means of creating "hot-keys" for keyboard operation of menu items and controls: [https://developer.gnome.org/gtk3/unstable/gtk3-Keyboard-Accelerators.html Accelerators] and special labels called '''mnemonics'''.
 +
 
 +
==== Accelerators ====
 +
Accelerators are normally assigned only to menu items, but they can be assigned to any control using a [https://developer.gnome.org/gtk3/unstable/GtkAccelLabel.html GtkAccelLabel]. ''"Can" does '''not''' mean "should"!'' Pressing the character together with the configured modifiers calls whatever function is linked to the control. Accelerators can be over-ridden by users using [https://developer.gnome.org/gtk3/unstable/gtk3-Accelerator-Maps.html an accelerator map]. Accelerators can be set in GtkBuilder/Glade files using the <tt>accelerator</tt> element.
 +
 
 +
;macOS Note: In most cases macOS prefers the <code>command</code> key to the <code>control</code> key as a modifier. Gtk provides a macro <tt>GDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR</tt> that selects the correct modifier depending on OS. It should be used in most cases rather than <tt>GDK_CONTROL_MASK</tt>. As noted below under [[#Mnemonics|Mnemonics]] macOS uses the <code>alt</code> modifier key to extend the keyboard, so it should be used only with another not-<code>shift</code> modifier key in accelerators. Note that on macOS GDK_MOD2_MASK is the <code>command</code> key while on X11 it's <code>numlock</code> so either one must conditionally set accelerator modifiers (not possible in Glade), rely on an accelerator map to get a useable accelerator set, or restrict the modifiers to <code>control</code>+<code>alt</code> and <tt>GDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR</tt>. Unfortunately [https://glade.gnome.org/ Glade] does not support GdkModifierIntent and Gtk+ has supported it in GtkBuilder files only since 3.20 so it can be used only in accelerators defined in code.
 +
 
 +
;GtkShortcuts: The <tt>GtkShortcutsWindow</tt> is a convenient way to display all of GnuCash's accelerators to the user. Unfortunately it wasn't introduced until Gtk+-3.20.0 and we want to support
 +
::Gtk+-3.10 for GnuCash 3.x and
 +
::Gtk+-3.18 for GnuCash 4.x, so don't implement it now.
 +
 
 +
==== Mnemonics ====
 +
Mnemonics can be set on [https://developer.gnome.org/gtk3/unstable/GtkMenuItem.html#gtk-menu-item-new-with-mnemonic menu items] as well as [https://developer.gnome.org/gtk3/unstable/GtkButton.html#gtk-button-new-with-mnemonic buttons] or indeed any control by [https://developer.gnome.org/gtk3/unstable/GtkLabel.html#gtk-label-set-mnemonic-widget attaching] it to the [https://developer.gnome.org/gtk3/unstable/GtkLabel.html#gtk-label-new-with-mnemonic relevant label]. ''However'' one should be aware that menu-item mnemonics work quite differently: Mnemonics on controls operate like accelerators: Holding <code>alt</code> will reveal underlines on the mnemonic characters for the focused window or dialog and pressing an underlined character will operate the respective control. If the focused window has a menu bar associated with it the menu bar will be revealed if it's hidden and the mnemonics will be shown; pressing the mnemonic for a menu bar item will open that menu. At this point the <code>alt</code> can be released and the menu navigated by pressing the mnemonic keys alone. In addition to the linked functions, mnemonics can be set in GtkBuilder/Glade files with the <tt>use_underline</tt> and (on GtkLabels, not needed for GtkButtons) <tt>mnemonic_widget</tt> properties.
 +
 
 +
;Mnemonics have two problems on Macs: First, they don't work on the menu. Keyboard menu navigation is accomplished by pressing <code>ctrl</code>+<code>F2</code> (don't forget to also press <code>fn</code> on keyboards that use one unless you've flipped the <code>fn</code> key behavior in Keyboard Preferences) to activate the menubar and then navigating with the cursor keys.
 +
:Second, macOS used the <code>alt</code> key to extend the keyboard; for example on a US keyboard one would type <code>alt</code>+<code>e</code> to get <tt>é</tt> or <code>alt</code>+<code>o</code> to get <tt>ø</tt>. Setting a mnemonic  will grab the event before the text control gets it and prevent that character from being typed.
 +
 
 +
Note that when one creates a mnemonic with an underscore the underscore becomes part of the label string that is a msgid for translation, so the same label with different mnemonics will result in multiple strings for translation. This is a good thing because it allows translators to select appropriate mnemonics for their languages.
 +
 
 +
== Labels ==
 +
;No trailing colons or spaces: They were removed before GnuCash 3.8.
 +
;Mnemonics are desired: See [[#Mnemonics]].
 +
 
 +
= Textual content =
 +
== Storing in Glade or program ==
 +
* Store ''simple static'' text in the glade file. Then they are already available while you preview the GUI element.
 +
* Store dynamic text in the corresponding progam file.
 +
* For ''composed'' text it depends:
 +
:For some GUI elements it is easier to split the output element in 2 or more.
 +
:If that is not possible you have to compose them in the program.
 +
 
 +
== Menu Entry Descriptions ==
 +
Sometimes you need to describe menu entries in other texts like tool tips, tip of the day, ...
 +
 
 +
In that case use "->" without spaces as separator of the levels.
 +
:;Example: "File->Open…"
 +
Avoid "->" for other contexts like
 +
:;range: "1 … 10, A … Z" or
 +
:;conversion: "commodity -> currency" or "number to string".
 +
 
 +
== Quoting in Strings ==
 +
To get a unique appearance, the current team prefers ASCII double quotes <code>"</code> over single quotes <code>'</code> or non-ASCII characters.
 +
;So ''developers'' should use in '''C''' etc.: <syntaxhighlight lang="C">
 +
Msg= "Prefix \"Quotation\" Suffix."
 +
</syntaxhighlight>
 +
;In '''XML''' it is more complex:
 +
:;Glade: <syntaxhighlight lang="xml">
 +
<tag>Prefix "Quotation" Suffix.</tag>
 +
</syntaxhighlight>
 +
:;DocBook: For attributes: <syntaxhighlight lang="xml">
 +
<sometag someattribute="value">Text</sometag>
 +
</syntaxhighlight>
 +
::In text: <syntaxhighlight lang="xml">
 +
<p>Prefix <quote>Quotation</quote> Suffix.</p>
 +
</syntaxhighlight>
 +
::;Note: Depending on the semantic context there are more appropriate markups like <citation>, <guilabel>, <keycap>, ...
 +
;HTML has several, depending on the context: <syntaxhighlight lang="html">
 +
<p>Inline: normal <q>Quotation</q>, <code>Computer code</code> and <kbd>Keyboard input</kbd>. <em>Emphasis</em> and <strong>Strong</strong> should be preferred over <i>idiomatic</i> and <b>Bold</b>.</p>
 +
<blockquote>A text
 +
over several lines
 +
</blockquote>
 +
</syntaxhighlight>
 +
''Translation teams'' are free to choose their locale common symbols as shown in [https://en.wikipedia.org/wiki/Quotation_mark Quotation mark].
 +
:;Tip: Best practice is to note the convention in a comment in the header of the .po file.
 +
 
 +
== Markups in Text ==
 +
Try to avoid them:
 +
* If you have bold elements in longer texts, it can be an indicator to split the text in several sections, each consisting of a header and a body. Then you can assign attributes to the header label.
 +
 
 +
* '''Labels''' can get attributes in several ways:
 +
# Stylesheet, preferred: In Glade <tt>common</tt> tab, <tt>style class</tt> or direct <syntaxhighlight lang="xml"><property name="label" translatable="yes">Highlighted text</property>
 +
<style>
 +
  <class name="gnc-class-highlight"/>
 +
</style></syntaxhighlight> The classes are defined in [https://github.com/Gnucash/gnucash/blob/stable/gnucash/gnucash-fallback.css gnucash/gnucash-fallback.css]
 +
# Glade attributes: In Glade <tt>general</tt> tab, select <tt>attributes</tt>, click <tt>edit attributes</tt> and select <tt>weight</tt>:<tt>bold</tt> or direct <syntaxhighlight lang="xml">
 +
<property name="label" translatable="yes">Bold text</property>
 +
<attributes>
 +
  <attribute name="weight" value="bold"/>
 +
</attributes>
 +
</syntaxhighlight>
 +
# Use Markup as least desired: In Glade <tt>general</tt> tab, select <tt>Use Markup</tt> and enter the markups in the label text or direct <syntaxhighlight lang="xml">
 +
<property name="label" translatable="yes">&lt;b&gt;Bold&lt;/b&gt; and normal text</property>
 +
<property name="use_markup">True</property>
 +
</syntaxhighlight>
 +
 
 +
== Tooltips and Descriptions of Preferences ==
 +
Tooltips should contain at least one full sentence.
 +
;Purpose:
 +
:#Describe the impact of the GUI element,
 +
:#give the user a clue about the "normal" state.
 +
The separator between menu elements is "->" like "Menu->SubMenu->MenuItem".
 +
 
 +
;Tooltips of ''preferences'':
 +
: have usually 3 occurences:
 +
# glade: Edit->Preferences->... <syntaxhighlight lang="xml"><property name="tooltip_text" translatable="yes">your text</property></syntaxhighlight>
 +
# gschema (xml), displayed in RegEdit, dconf-editor, ...: <syntaxhighlight lang="xml"><description>your text</description></syntaxhighlight>
 +
# gnucash-manual/custom-gnucash... (docbook xml): <syntaxhighlight lang="xml">  <listitem>
 +
    <para><guilabel>Include grand total</guilabel>: If checked, show in the <emphasis>Summarybar</emphasis> a grand total of all accounts converted to the default currency.</para>
 +
  </listitem></syntaxhighlight>
 +
 
 +
Use for all the same text to keep it simple for translators. They should not feel like in the [https://en.wikipedia.org/wiki/Colossal_Cave_Adventure colossal cave adventure]: <syntaxhighlight lang="console">
 +
You are in a maze of twisty little passages, all alike.
 +
You are in a maze of twisty little passages, all different.
 +
You are in a little maze of twisty passages, all different.
 +
You are in a little maze of twisting passages, all different.
 +
:
 +
</syntaxhighlight>
 +
 
 +
Follow the rules for [[Settings Wording]].
 +
 
 +
=Reference=
 +
 
 +
==Human Interface Guidelines==
 +
As long as we use GTK, [{{URL:Gnome-HIG}} GNOMEs HIG] is the primary source. But sometimes the comparision with other HIGs, can be useful:
 +
:[https://developer.apple.com/design/human-interface-guidelines/macos/overview/themes/ macOS Human Interface Guidelines]
 +
:[https://docs.microsoft.com/en-us/windows/win32/uxguide/guidelines Win32 apps Guidelines]
 +
: [https://hig.kde.org/index.html  KDE Human Interface Guidelines]

Latest revision as of 01:12, 20 April 2024

This page collects rules for the GUI. You should mind them while coding or preparing translation (I18N).

General

GnuCash >= 3 is GTK3 based
GTK+ 3 Reference Manual - GNOME Developer Center.
Use the gtkbuilder glade for rapid prototyping and preview
Glade und Gtk::Builder
Glade3 tutorial

GUI Resolution

The maximum size of all GUI elements restricts users to have at least the same resolution on their device to run GnuCash flawless. Bug 797857 - Edit->Preferences: Help/Close buttons unreachable remembered us about this restriction. For

GnuCash 3 and up
the limit is 1024x768. In the
GnuCash 2.x series
it was 800x600.

GUI Elements

Buttons and Icons

For GTK+ 3.10 Stock Items Deprecation announced on gtk-devel-list/2013-July and the Replacement Table watch the current discussion starting with gnucash-devel/2019-May.

Standard icons are now specified in the XDG Icon Naming Specification. This will allow each theme to use its own set.

Toolbars

Keep often used actions like Report options at the beginning of the list.

Menus

Menu elements should have a

Ellipses
If a label specifies an action, but further user interaction is required before, the label should have a trailing horizontal ellipse (altGr+.), but not for dialogs like Properties, Preferences, … See details at the bottom of https://developer.gnome.org/hig/stable/writing-style.html

Mnemonics and Accelerators

Gtk+ provides two means of creating "hot-keys" for keyboard operation of menu items and controls: Accelerators and special labels called mnemonics.

Accelerators

Accelerators are normally assigned only to menu items, but they can be assigned to any control using a GtkAccelLabel. "Can" does not mean "should"! Pressing the character together with the configured modifiers calls whatever function is linked to the control. Accelerators can be over-ridden by users using an accelerator map. Accelerators can be set in GtkBuilder/Glade files using the accelerator element.

macOS Note
In most cases macOS prefers the command key to the control key as a modifier. Gtk provides a macro GDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR that selects the correct modifier depending on OS. It should be used in most cases rather than GDK_CONTROL_MASK. As noted below under Mnemonics macOS uses the alt modifier key to extend the keyboard, so it should be used only with another not-shift modifier key in accelerators. Note that on macOS GDK_MOD2_MASK is the command key while on X11 it's numlock so either one must conditionally set accelerator modifiers (not possible in Glade), rely on an accelerator map to get a useable accelerator set, or restrict the modifiers to control+alt and GDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR. Unfortunately Glade does not support GdkModifierIntent and Gtk+ has supported it in GtkBuilder files only since 3.20 so it can be used only in accelerators defined in code.
GtkShortcuts
The GtkShortcutsWindow is a convenient way to display all of GnuCash's accelerators to the user. Unfortunately it wasn't introduced until Gtk+-3.20.0 and we want to support
Gtk+-3.10 for GnuCash 3.x and
Gtk+-3.18 for GnuCash 4.x, so don't implement it now.

Mnemonics

Mnemonics can be set on menu items as well as buttons or indeed any control by attaching it to the relevant label. However one should be aware that menu-item mnemonics work quite differently: Mnemonics on controls operate like accelerators: Holding alt will reveal underlines on the mnemonic characters for the focused window or dialog and pressing an underlined character will operate the respective control. If the focused window has a menu bar associated with it the menu bar will be revealed if it's hidden and the mnemonics will be shown; pressing the mnemonic for a menu bar item will open that menu. At this point the alt can be released and the menu navigated by pressing the mnemonic keys alone. In addition to the linked functions, mnemonics can be set in GtkBuilder/Glade files with the use_underline and (on GtkLabels, not needed for GtkButtons) mnemonic_widget properties.

Mnemonics have two problems on Macs
First, they don't work on the menu. Keyboard menu navigation is accomplished by pressing ctrl+F2 (don't forget to also press fn on keyboards that use one unless you've flipped the fn key behavior in Keyboard Preferences) to activate the menubar and then navigating with the cursor keys.
Second, macOS used the alt key to extend the keyboard; for example on a US keyboard one would type alt+e to get é or alt+o to get ø. Setting a mnemonic will grab the event before the text control gets it and prevent that character from being typed.

Note that when one creates a mnemonic with an underscore the underscore becomes part of the label string that is a msgid for translation, so the same label with different mnemonics will result in multiple strings for translation. This is a good thing because it allows translators to select appropriate mnemonics for their languages.

Labels

No trailing colons or spaces
They were removed before GnuCash 3.8.
Mnemonics are desired
See #Mnemonics.

Textual content

Storing in Glade or program

  • Store simple static text in the glade file. Then they are already available while you preview the GUI element.
  • Store dynamic text in the corresponding progam file.
  • For composed text it depends:
For some GUI elements it is easier to split the output element in 2 or more.
If that is not possible you have to compose them in the program.

Menu Entry Descriptions

Sometimes you need to describe menu entries in other texts like tool tips, tip of the day, ...

In that case use "->" without spaces as separator of the levels.

Example
"File->Open…"

Avoid "->" for other contexts like

range
"1 … 10, A … Z" or
conversion
"commodity -> currency" or "number to string".

Quoting in Strings

To get a unique appearance, the current team prefers ASCII double quotes " over single quotes ' or non-ASCII characters.

So developers should use in C etc.
Msg= "Prefix \"Quotation\" Suffix."
In XML it is more complex
Glade
<tag>Prefix "Quotation" Suffix.</tag>
DocBook
For attributes:
<sometag someattribute="value">Text</sometag>
In text:
<p>Prefix <quote>Quotation</quote> Suffix.</p>
Note
Depending on the semantic context there are more appropriate markups like <citation>, <guilabel>, <keycap>, ...
HTML has several, depending on the context
<p>Inline: normal <q>Quotation</q>, <code>Computer code</code> and <kbd>Keyboard input</kbd>. <em>Emphasis</em> and <strong>Strong</strong> should be preferred over <i>idiomatic</i> and <b>Bold</b>.</p>
<blockquote>A text 
over several lines
</blockquote>

Translation teams are free to choose their locale common symbols as shown in Quotation mark.

Tip
Best practice is to note the convention in a comment in the header of the .po file.

Markups in Text

Try to avoid them:

  • If you have bold elements in longer texts, it can be an indicator to split the text in several sections, each consisting of a header and a body. Then you can assign attributes to the header label.
  • Labels can get attributes in several ways:
  1. Stylesheet, preferred: In Glade common tab, style class or direct
    <property name="label" translatable="yes">Highlighted text</property>
    <style>
      <class name="gnc-class-highlight"/>
    </style>
    
    The classes are defined in gnucash/gnucash-fallback.css
  2. Glade attributes: In Glade general tab, select attributes, click edit attributes and select weight:bold or direct
    <property name="label" translatable="yes">Bold text</property>
    <attributes>
      <attribute name="weight" value="bold"/>
    </attributes>
    
  3. Use Markup as least desired: In Glade general tab, select Use Markup and enter the markups in the label text or direct
    <property name="label" translatable="yes">&lt;b&gt;Bold&lt;/b&gt; and normal text</property>
    <property name="use_markup">True</property>
    

Tooltips and Descriptions of Preferences

Tooltips should contain at least one full sentence.

Purpose
  1. Describe the impact of the GUI element,
  2. give the user a clue about the "normal" state.

The separator between menu elements is "->" like "Menu->SubMenu->MenuItem".

Tooltips of preferences
have usually 3 occurences:
  1. glade: Edit->Preferences->...
    <property name="tooltip_text" translatable="yes">your text</property>
    
  2. gschema (xml), displayed in RegEdit, dconf-editor, ...:
    <description>your text</description>
    
  3. gnucash-manual/custom-gnucash... (docbook xml):
      <listitem>
        <para><guilabel>Include grand total</guilabel>: If checked, show in the <emphasis>Summarybar</emphasis> a grand total of all accounts converted to the default currency.</para>
      </listitem>
    
Use for all the same text to keep it simple for translators. They should not feel like in the colossal cave adventure:
You are in a maze of twisty little passages, all alike.
You are in a maze of twisty little passages, all different. 
You are in a little maze of twisty passages, all different.
You are in a little maze of twisting passages, all different.
:

Follow the rules for Settings Wording.

Reference

Human Interface Guidelines

As long as we use GTK, GNOMEs HIG is the primary source. But sometimes the comparision with other HIGs, can be useful:

macOS Human Interface Guidelines
Win32 apps Guidelines
KDE Human Interface Guidelines