\r
++ Symbol Pronunciation ++\r
It is often useful to hear punctuation and other symbols pronounced as words when reading text, particularly when moving by character.\r
-Unfortunately, the pronunciation of symbols is inconsistent between speech synthesisers and many synthesisers do not speak many symbols and/or do not allow control over what symbols are spoken.\r
+Unfortunately, the pronunciation of symbols is inconsistent between speech synthesisers and many synthesisers do not speak many symbols and/or do not allow control over what symbols are spoken.\r
Therefore, NVDA allows information about symbol pronunciation to be provided.\r
\r
This is done for a locale by providing a file named symbols.dic in the directory for the locale.\r
This will all be covered in depth later.\r
\r
NVDA loads an App Module for an application as soon as it noticies the application is running.\r
-The App Module is unloaded once the application is closed or when NVDA is exiting. \r
+The App Module is unloaded once the application is closed or when NVDA is exiting.\r
\r
++ Example 1: An App Module that Beeps on Focus Change Events ++[Example1]\r
The following example App Module makes NVDA beep each time the focus changes within the notepad application.\r
Finally, open Notepad and move the focus around the application; e.g. move along the menu bar, open some dialog boxes, etc.\r
You should hear beeps each time the focus changes.\r
Note though that if you move outside of Notepad - for instance, to Windows Explorer - you do not hear beeps.\r
- \r
+\r
```\r
--- start ---\r
# Notepad App Module for NVDA\r
As with other examples in this guide, remember to delete the created app module when you are finished testing and then restart NVDA or reload plugins, so that original functionality is restored.\r
\r
++ Basics of a Global Plugin ++\r
-Global Plugin files have a .py extension, and should have a short unique name which identifies what they do. \r
+Global Plugin files have a .py extension, and should have a short unique name which identifies what they do.\r
\r
-Global Plugin files must be placed in the globalPlugins subdirectory of the user's NVDA user configuration directory.\r
+Global Plugin files must be placed in the globalPlugins subdirectory of the user's NVDA user configuration directory.\r
For more information on where to find the user configuration directory, please see the NVDA user guide.\r
\r
Global Plugins must define a class called GlobalPlugin, which inherits from globalPluginHandler.GlobalPlugin.\r
This class can then define event and script methods, gesture bindings and other code.\r
This will all be covered in depth later.\r
\r
-NVDA loads all global plugins as soon as it starts, and unloads them on exit. \r
+NVDA loads all global plugins as soon as it starts, and unloads them on exit.\r
\r
++ Example 2: a Global Plugin Providing a Script to Announce the NVDA Version ++\r
-The following example Global Plugin Allows you to press NVDA+shift+v while anywhere in the Operating System to find out NVDA's version. \r
+The following example Global Plugin Allows you to press NVDA+shift+v while anywhere in the Operating System to find out NVDA's version.\r
This example is only to show you the basic layout of a Global Plugin.\r
\r
Copy and paste the code between (but not including) the start and end markers into a new text file with a name of example2.py, which should be saved in the globalPlugins subdirectory.\r
\r
It then imports the globalPluginHandler module, so that the Global Plugin has access to the base GlobalPlugin class.\r
\r
-It also imports a few other modules, namely ui and versionInfo, which this specific plugin needs in order for it to perform the necessary actions to announce the version.\r
+It also imports a few other modules, namely ui and versionInfo, which this specific plugin needs in order for it to perform the necessary actions to announce the version.\r
\r
Next, it defines a class called GlobalPlugin, which is inherited from globalPluginHandler.GlobalPlugin.\r
\r
In this example, it defines a script method that performs the version announcement, and provides a binding from NVDA+shift+v to this script.\r
However, the details of the script and its binding are not important for the purposes of this example.\r
The most important part is the class itself.\r
- \r
+\r
As with other examples in this guide, remember to delete the created Global Plugin when finished testing and then restart NVDA or reload plugins, so that original functionality is restored.\r
\r
++ NVDA Objects ++\r
Similarly, a checkbox with a label of "I agree" would have a name of "I agree", a role of checkbox, and if currently checked, a state of checked.\r
\r
As there are many different GUI Toolkits and platform and accessibility APIs, NVDA Objects abstract these differences into a standard form that NVDA can use, regardless of the toolkit or API a particular control is made with.\r
-For example, the Ok button just discussed could be a widget in a Java application, an MSAA object, an IAccessible2 object or a UI Automation element. \r
+For example, the Ok button just discussed could be a widget in a Java application, an MSAA object, an IAccessible2 object or a UI Automation element.\r
\r
NVDA Objects have many properties.\r
Some of the most useful are:\r
Focusable, focused, selected, selectable, expanded, collapsed and checked are some examples of states.\r
- value: the value of the control; e.g. the percentage of a scroll bar or the current setting of a combo box.\r
- description: a sentence or two describing what the control does (usually the same as its tooltip).\r
-- location: the object's left, top, width and height positions in screen coordinates. \r
+- location: the object's left, top, width and height positions in screen coordinates.\r
- parent: this object's parent object.\r
For example, a list item object's parent would be the list containing it.\r
- next: the object directly after this one on the same level in logical order.\r
- firstChild: the first direct child object of this object.\r
For example, a list's first child would be the first list item.\r
- lastChild: the last direct child of this object.\r
- - children: a list of all the direct children of this object; e.g. all the menu items in a menu.\r
+- children: a list of all the direct children of this object; e.g. all the menu items in a menu.\r
-\r
\r
There are also a few simplified navigation properties such as simpleParent, simpleNext, simpleFirstChild and simpleLastChild.\r
- the Plugin may define its own custom NVDA Object classes which will be used to wrap a specific control to give it extra functionality, mutate its properties, etc.\r
-\r
\r
-Just like App Modules and Global Plugins, NVDA Objects can also define events, scripts and gesture bindings. \r
- \r
+Just like App Modules and Global Plugins, NVDA Objects can also define events, scripts and gesture bindings.\r
+\r
++ Scripts and Gesture Bindings ++\r
App Modules, Global Plugins and NVDA Objects can define special methods which can be bound to a particular piece of input such as a key press.\r
NVDA refers to these methods as scripts.\r
These dictionaries should contain gesture identifier strings pointing to the name of the requested script, without the "script_" prefix.\r
\r
There are more advanced ways of binding gestures in a more dynamic fashion, though the __gestures dictionary is the simplest.\r
- \r
+\r
A gesture identifier string is a simple string representation of a piece of input.\r
It consists of a two leter character code denoting the source of the input, an optional device in brackets, a colon (:) and one or more names separated by a plus (+) denoting the actual keys or input values.\r
\r
++ Example 3: A Global Plugin to Find out Window Class and Control ID ++\r
The following Global Plugin allows you to press NVDA+leftArrow to have the window class of the current focus announced, and NVDA+rightArrow to have the window control ID of the current focus announced.\r
This example shows you how to define one or more scripts and gesture bindings on a class such as an App Module, Global Plugin or NVDA Object.\r
- \r
+\r
Copy and paste the code between (but not including) the start and end markers into a new text file with a name of example3.py, which should be saved in the globalPlugins subdirectory.\r
Be very careful to keep all tabs and spaces intact.\r
\r
++ Events ++\r
When NVDA detects particular toolkit, API or Operating System events, it abstracts these and fires its own internal events on plugins and NVDA Objects.\r
\r
-Although most events are related to a specific NVDA Object (e.g. name change, gain focus, state change, etc.), these events can be handled at various levels. \r
+Although most events are related to a specific NVDA Object (e.g. name change, gain focus, state change, etc.), these events can be handled at various levels.\r
When an event is handled, it is stopped from going further down the chain.\r
However, code inside the event can choose to propagate it further if needed.\r
\r
- locationChange: physical screen location changes\r
-\r
\r
-There are many other events, though those listed above are usually the most useful.\r
+There are many other events, though those listed above are usually the most useful.\r
\r
For an example of an event handled by an App Module, please refer to [example 1 #Example1] (focus beeps in notepad).\r
\r
++ Example 4: A Sleep Mode App Module ++\r
\r
The following code can be copied and pasted in to a text file, then saved in the appModules directory with the name of the application you wish to enable sleep mode for.\r
-As always, the file must have a .py extension.\r
+As always, the file must have a .py extension.\r
\r
```\r
--- start ---\r
\r
--- end ---\r
```\r
- \r
+\r
++ Providing Custom NVDA Object Classes ++\r
Providing custom NVDA Object classes is probably the most powerful and useful way to improve the experience of an application in an NVDA plugin.\r
This method allows you to place all the needed logic for a particular control altogether in one NVDA Object class for that control, rather than scattering code for many controls across a plugin's events.\r
+\r
\r
Inside this method, you should decide which custom NVDA Object class(es) (if any) this NVDA Object should use by checking its properties, etc.\r
-If a custom class should be used, it must be inserted into the class list, usually at the beginning. \r
+If a custom class should be used, it must be inserted into the class list, usually at the beginning.\r
You can also remove classes chosen by NVDA from the class list, although this is rarely required.\r
\r
++ Example 5: Labelling the Notepad Edit Field using a Custom NVDA Object ++\r