1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
|
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">
<chapter>
<header>
<copyright>
<year>2000</year><year>2016</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
</legalnotice>
<title>Events</title>
<prepared></prepared>
<docno></docno>
<date></date>
<rev></rev>
<file>gs_chapter4.xml</file>
</header>
<section>
<title>Event Messages</title>
<p>Events are messages which are sent to the owner process of the object when the user interacts with the object in some way. A simple case is the user pressing a button. An event is then delivered to the owner process of the button (the process that created the button). In the following example, the program creates a button object and enables the events click and enter. This example shows that events are enabled in the same way as objects are configured with options.</p>
<p></p>
<code type="none"><![CDATA[
B = gs:create(button,Win, [{click,true},{enter,true}]),
event_loop(B).
]]></code>
<p>The process is now ready to receive click and enter events from the button. The events delivered are always five tuples and consist of:</p>
<code type="none"><![CDATA[
{gs, IdOrName, EventType, Data, Args}
]]></code>
<list type="bulleted">
<item><c><![CDATA[gs]]></c> is a tag which says it is an event from the <c><![CDATA[gs]]></c> graphics server.</item>
<item><c><![CDATA[IdOrName]]></c> contains the object identifier or the name of the object in which the event occurred.</item>
<item><c><![CDATA[EventType]]></c> contains the type of event which has occurred. In the example shown, it is either <c><![CDATA[click]]></c> or <c><![CDATA[enter]]></c>.</item>
<item><c><![CDATA[Data]]></c> is a field which the user can set to any Erlang term. It is very useful to have the object store arbitrary data which is delivered with the event.</item>
<item><c><![CDATA[Args]]></c> is a list which contains event specific information. In a motion event, the Args argument would contain the x and y coordinates.</item>
</list>
<p>There are two categories of events:</p>
<list type="bulleted">
<item><em>generic events</em></item>
<item><em>object specific events</em>.</item>
</list>
</section>
<section>
<title>Generic Events</title>
<p>Generic events are the same for all types of objects. The following table shows a list of generic event types which the graphics server can send to
a process. For generic events, the <c><![CDATA[Args]]></c> argument always contains the same data, independent of which object delivers it.</p>
<p>The following sub-sections explains the event types and what they are used for.</p>
<table>
<row>
<cell align="left" valign="middle"><em>Event</em></cell>
<cell align="left" valign="middle"><em>Args</em></cell>
<cell align="left" valign="middle"><em>Description</em></cell>
</row>
<row>
<cell align="left" valign="middle">buttonpress</cell>
<cell align="left" valign="middle">[ButtonNo,X,Y|_]</cell>
<cell align="left" valign="middle">A mouse button was pressed over the object.</cell>
</row>
<row>
<cell align="left" valign="middle">buttonrelease</cell>
<cell align="left" valign="middle">[ButtonNo,X,Y|_]</cell>
<cell align="left" valign="middle">A mouse button was released over the object. </cell>
</row>
<row>
<cell align="left" valign="middle">enter</cell>
<cell align="left" valign="middle">[]</cell>
<cell align="left" valign="middle">Delivered when the mouse pointer enters the objects area.</cell>
</row>
<row>
<cell align="left" valign="middle">focus</cell>
<cell align="left" valign="middle">[Int|_]</cell>
<cell align="left" valign="middle">Keyboard focus has changed. 0 means lost focus. 1 means gained focus.</cell>
</row>
<row>
<cell align="left" valign="middle">keypress</cell>
<cell align="left" valign="middle">[KeySym,Keycode, Shift, Control|_]</cell>
<cell align="left" valign="middle">A key has been pressed. </cell>
</row>
<row>
<cell align="left" valign="middle">leave</cell>
<cell align="left" valign="middle">[]</cell>
<cell align="left" valign="middle">Mouse pointer leaves the object.</cell>
</row>
<row>
<cell align="left" valign="middle">motion</cell>
<cell align="left" valign="middle">[X,Y|_]</cell>
<cell align="left" valign="middle">The mouse pointer is moving in the object. Used when tracking the mouse in a window.</cell>
</row>
<tcaption>Generic Event Types</tcaption>
</table>
<section>
<title>The Buttonpress and Buttonrelease Events</title>
<p>These events are generated when a mouse button is pressed or released inside the object frame of a window, or frame object type. The button events are not object specific (compare to click). The format of the buttonpress event is:</p>
<code type="none"><![CDATA[
{gs,ObjectId,buttonpress,Data,[MouseButton,X,Y|_]}
]]></code>
<p>The mouse button number which was pressed is the first argument in the <c><![CDATA[Args]]></c> field list. This number is either 1, 2 or 3, if you have a three button mouse. The <c><![CDATA[X]]></c> and <c><![CDATA[Y]]></c> coordinates are sent along to track in what position the user pressed down the button. These events are useful for programming things like "rubberbanding", which is to draw out an area with the mouse. In detail, this event can be described as pressing the mouse button at a specific coordinate and releasing it at another coordinate in order to define a rectangular area. This action is often used in combination with motion events.</p>
</section>
<section>
<title>The Enter and Leave Events</title>
<p>These events are generated when the mouse pointer (cursor) enters or leaves an object.</p>
</section>
<section>
<title>The Focus Event</title>
<p>The focus event tracks which object currently holds the keyboard focus. Only one object at a time can hold the keyboard focus. To have the keyboard focus means that all keypresses from the keyboard will be delivered to that object. The format of a focus event is:</p>
<code type="none"><![CDATA[
{gs,ObjectId,focus, Data,[FocusFlag|_]}
]]></code>
<p>The FocusFlag argument is either 1, which means that the object has gained keyboard focus, or 0, which means that the object has lost keyboard focus.</p>
</section>
<section>
<title>The Keypress Event</title>
<p>This event is generated by an object which receives text input from the user, like entry objects. It can also be generated by window objects. The format of a keypress event is:</p>
<code type="none"><![CDATA[
{gs,ObjectId,keypress,Data,[Keysym,Keycode,Shift,Control|_]}
]]></code>
<p>The <c><![CDATA[Keysym]]></c> argument is either the character key which was pressed, or a word which describes which key it was. Examples of <c><![CDATA[Keysyms]]></c> are; <c><![CDATA[a]]></c>,<c><![CDATA[b]]></c>,<c><![CDATA[c]]></c>.., 1,2,3..., <c><![CDATA['Return']]></c>, <c><![CDATA['Delete']]></c>, <c><![CDATA['Insert']]></c>, <c><![CDATA['Home']]></c>, <c><![CDATA['BackSpace']]></c>, <c><![CDATA['End']]></c>. The <c><![CDATA[Keycode]]></c> argument is the keycode number for the key that was pressed. Either the <c><![CDATA[Keysym]]></c> or the <c><![CDATA[Keycode]]></c> argument can be used to find out which key was pressed. The <c><![CDATA[Shift]]></c> argument contains either a 0 or a 1 to indicate if the Shift key was held down when the character key was pressed. The Control argument is similar to the Shift key argument, but applies to the Control key instead of the Shift key.</p>
</section>
<section>
<title>The Motion Event</title>
<p>The motion event is used to track the mouse position in a window. When the user moves the mouse pointer (cursor) to a new position a motion event is generated. The format of a motion event is:</p>
<code type="none"><![CDATA[
{gs,ObjectId,motion,Data,[X,Y|_]}
]]></code>
<p>The current x and y coordinates of the cursor are sent along in the <c><![CDATA[Args]]></c> field.</p>
</section>
</section>
<section>
<title>Object Specific Events</title>
<p>The click and doubleclick events are the object specific event types. Only some objects have these events and the <c><![CDATA[Args]]></c> field of the events vary for different type of objects. A click on a check button generates a click event where the data field contains the on/off value of the indicator. On the other hand, the click event for a list box contains information on which item was chosen.</p>
<table>
<row>
<cell align="left" valign="middle"><em>Event</em></cell>
<cell align="left" valign="middle"><em>Args</em></cell>
<cell align="left" valign="middle"><em>Description</em></cell>
</row>
<row>
<cell align="left" valign="middle">click</cell>
<cell align="left" valign="middle"><object specific></cell>
<cell align="left" valign="middle">Pressing a button or operating on a object in some predefined way. </cell>
</row>
<row>
<cell align="left" valign="middle">double-click</cell>
<cell align="left" valign="middle"><object specific></cell>
<cell align="left" valign="middle">Pressing the mouse button twice quickly. Useful with list boxes.</cell>
</row>
<tcaption>Object Specific Events</tcaption>
</table>
</section>
<section>
<title>Matching Events Against Object Identifiers</title>
<p>Events can be matched against the object identifier in the receive statement. The disadvantage of matching against identifiers is that the program must pass the object identifiers as arguments to the event loop.</p>
<codeinclude file="examples/ex3.erl" tag="" type="erl"></codeinclude>
</section>
<section>
<title>Matching Events Against Object Names</title>
<p>Another solution is to name the objects using the <c><![CDATA[create/4]]></c> function. In this way, the program does not have to pass any parameters which contain object identifiers for each function call made.</p>
<codeinclude file="examples/ex4.erl" tag="" type="erl"></codeinclude>
</section>
<section>
<title>Matching Events Against the Data Field</title>
<p>A third solution is to set the <c><![CDATA[data]]></c> option to some value and then match against this value. All built-in objects have an option called <c><![CDATA[data]]></c> which can be set to any Erlang term. For example, we could set the data field to a tuple <c><![CDATA[{Mod, Fun,Args}]]></c> and have the receiving function make an <c><![CDATA[apply]]></c> on the contents of the data field whenever certain events arrive.</p>
<codeinclude file="examples/ex5.erl" tag="" type="erl"></codeinclude>
</section>
<section>
<title>Experimenting with Events</title>
<p>A good way of learning how events work is to write a short demo program like the one shown below and test how different events work.</p>
<codeinclude file="examples/ex6.erl" tag="" type="erl"></codeinclude>
</section>
</chapter>
|