Sophie

Sophie

distrib > Fedora > 17 > i386 > media > updates > by-pkgid > 675c8c8167236dfcf8d66da674f931e8 > files > 653

erlang-doc-R15B-03.3.fc17.noarch.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns:fn="http://www.w3.org/2005/02/xpath-functions">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="../../../../doc/otp_doc.css" type="text/css">
<title>Erlang -- Events</title>
</head>
<body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000"><div id="container">
<script id="js" type="text/javascript" language="JavaScript" src="../../../../doc/js/flipmenu/flipmenu.js"></script><script id="js2" type="text/javascript" src="../../../../doc/js/erlresolvelinks.js"></script><script language="JavaScript" type="text/javascript">
            <!--
              function getWinHeight() {
                var myHeight = 0;
                if( typeof( window.innerHeight ) == 'number' ) {
                  //Non-IE
                  myHeight = window.innerHeight;
                } else if( document.documentElement && ( document.documentElement.clientWidth ||
                                                         document.documentElement.clientHeight ) ) {
                  //IE 6+ in 'standards compliant mode'
                  myHeight = document.documentElement.clientHeight;
                } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
                  //IE 4 compatible
                  myHeight = document.body.clientHeight;
                }
                return myHeight;
              }

              function setscrollpos() {
                var objf=document.getElementById('loadscrollpos');
                 document.getElementById("leftnav").scrollTop = objf.offsetTop - getWinHeight()/2;
              }

              function addEvent(obj, evType, fn){
                if (obj.addEventListener){
                obj.addEventListener(evType, fn, true);
                return true;
              } else if (obj.attachEvent){
                var r = obj.attachEvent("on"+evType, fn);
                return r;
              } else {
                return false;
              }
             }

             addEvent(window, 'load', setscrollpos);

             //--></script><div id="leftnav"><div class="innertube">
<img alt="Erlang logo" src="../../../../doc/erlang-logo.png"><br><small><a href="users_guide.html">User's Guide</a><br><a href="index.html">Reference Manual</a><br><a href="release_notes.html">Release Notes</a><br><a href="../pdf/gs-1.5.15.1.pdf">PDF</a><br><a href="../../../../doc/index.html">Top</a></small><p><strong>Graphics System (GS)</strong><br><strong>User's Guide</strong><br><small>Version 1.5.15.1</small></p>
<br><a href="javascript:openAllFlips()">Expand All</a><br><a href="javascript:closeAllFlips()">Contract All</a><p><small><strong>Chapters</strong></small></p>
<ul class="flipMenu" imagepath="../../../../doc/js/flipmenu">
<li id="no" title="GS - The Graphics System" expanded="false">GS - The Graphics System<ul>
<li><a href="gs_chapter1.html">
              Top of chapter
            </a></li>
<li title="Introduction"><a href="gs_chapter1.html#id62365">Introduction</a></li>
<li title="Basic Architecture of GS"><a href="gs_chapter1.html#id61203">Basic Architecture of GS</a></li>
</ul>
</li>
<li id="no" title="Interface Functions" expanded="false">Interface Functions<ul>
<li><a href="gs_chapter2.html">
              Top of chapter
            </a></li>
<li title="Overview"><a href="gs_chapter2.html#id61459">Overview</a></li>
<li title="A First Example"><a href="gs_chapter2.html#id57477">A First Example</a></li>
<li title="Creating Objects"><a href="gs_chapter2.html#id63683">Creating Objects</a></li>
<li title="Ownership"><a href="gs_chapter2.html#id59961">Ownership</a></li>
<li title="Naming Objects"><a href="gs_chapter2.html#id59975">Naming Objects</a></li>
</ul>
</li>
<li id="no" title="Options" expanded="false">Options<ul>
<li><a href="gs_chapter3.html">
              Top of chapter
            </a></li>
<li title="The Option Concept"><a href="gs_chapter3.html#id58188">The Option Concept</a></li>
<li title="The Option Tables"><a href="gs_chapter3.html#id64276">The Option Tables</a></li>
<li title="Config-Only Options"><a href="gs_chapter3.html#id64432">Config-Only Options</a></li>
<li title="Read-Only Options"><a href="gs_chapter3.html#id64553">Read-Only Options</a></li>
<li title="Data Types"><a href="gs_chapter3.html#id64674">Data Types</a></li>
</ul>
</li>
<li id="loadscrollpos" title="Events" expanded="true">Events<ul>
<li><a href="gs_chapter4.html">
              Top of chapter
            </a></li>
<li title="Event Messages"><a href="gs_chapter4.html#id65002">Event Messages</a></li>
<li title="Generic Events"><a href="gs_chapter4.html#id65107">Generic Events</a></li>
<li title="Object Specific Events"><a href="gs_chapter4.html#id65547">Object Specific Events</a></li>
<li title="Matching Events Against Object Identifiers"><a href="gs_chapter4.html#id65664">Matching Events Against Object Identifiers</a></li>
<li title="Matching Events Against Object Names"><a href="gs_chapter4.html#id65689">Matching Events Against Object Names</a></li>
<li title="Matching Events Against the Data Field"><a href="gs_chapter4.html#id65716">Matching Events Against the Data Field</a></li>
<li title="Experimenting with Events"><a href="gs_chapter4.html#id65756">Experimenting with Events</a></li>
</ul>
</li>
<li id="no" title="Fonts" expanded="false">Fonts<ul>
<li><a href="gs_chapter5.html">
              Top of chapter
            </a></li>
<li title="The Font Model"><a href="gs_chapter5.html#id65831">The Font Model</a></li>
</ul>
</li>
<li id="no" title="Default Values" expanded="false">Default Values<ul>
<li><a href="gs_chapter6.html">
              Top of chapter
            </a></li>
<li title="The Default Value Model"><a href="gs_chapter6.html#id66044">The Default Value Model</a></li>
</ul>
</li>
<li id="no" title="The Packer" expanded="false">The Packer<ul>
<li><a href="gs_chapter7.html">
              Top of chapter
            </a></li>
<li title="The Packer"><a href="gs_chapter7.html#id66217">The Packer</a></li>
</ul>
</li>
<li id="no" title="Built-In Objects" expanded="false">Built-In Objects<ul>
<li><a href="gs_chapter8.html">
              Top of chapter
            </a></li>
<li title="Overview"><a href="gs_chapter8.html#id66484">Overview</a></li>
<li title="Generic Options"><a href="gs_chapter8.html#id66791">Generic Options</a></li>
<li title="Window"><a href="gs_chapter8.html#id67843">Window</a></li>
<li title="Button"><a href="gs_chapter8.html#id68226">Button</a></li>
<li title="Label"><a href="gs_chapter8.html#id68734">Label</a></li>
<li title="Frame"><a href="gs_chapter8.html#id68905">Frame</a></li>
<li title="Entry"><a href="gs_chapter8.html#id69050">Entry</a></li>
<li title="Listbox"><a href="gs_chapter8.html#id69366">Listbox</a></li>
<li title="Canvas"><a href="gs_chapter8.html#id70050">Canvas</a></li>
<li title="Menu"><a href="gs_chapter8.html#id72195">Menu</a></li>
<li title="Grid"><a href="gs_chapter8.html#id80608">Grid</a></li>
<li title="Editor"><a href="gs_chapter8.html#id81434">Editor</a></li>
<li title="Scale"><a href="gs_chapter8.html#id82183">Scale</a></li>
</ul>
</li>
</ul>
</div></div>
<div id="content">
<div class="innertube">
<h1>4 Events</h1>
  

  <h3><a name="id65002">4.1 
        Event Messages</a></h3>
    
    <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>
    <div class="example"><pre>
B = gs:create(button,Win, [{click,true},{enter,true}]),
event_loop(B).
    </pre></div>
    <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>
    <div class="example"><pre>
{gs, IdOrName, EventType, Data, Args}
    </pre></div>
    <ul>
      <li>
<span class="code">gs</span> is a tag which says it is an event from the <span class="code">gs</span> graphics server.</li>
      <li>
<span class="code">IdOrName</span> contains the object identifier or the name of the object in which the event occurred.</li>
      <li>
<span class="code">EventType</span> contains the type of event which has occurred. In the example shown, it  is either <span class="code">click</span> or <span class="code">enter</span>.</li>
      <li>
<span class="code">Data</span> 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.</li>
      <li>
<span class="code">Args</span> is a list which contains event specific information. In a motion event, the Args argument would contain the x and y coordinates.</li>
    </ul>
    <p>There are two categories of events:</p>
    <ul>
      <li><strong>generic events</strong></li>
      <li>
<strong>object specific events</strong>.</li>
    </ul>
  

  <h3><a name="id65107">4.2 
        Generic Events</a></h3>
    
    <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 <span class="code">Args</span> 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 border="1" cellpadding="2" cellspacing="0">
<tr>
        <td align="left" valign="middle"><strong>Event</strong></td>
        <td align="left" valign="middle"><strong>Args</strong></td>
        <td align="left" valign="middle"><strong>Description</strong></td>
      </tr>
<tr>
        <td align="left" valign="middle">buttonpress</td>
        <td align="left" valign="middle">[ButtonNo,X,Y|_]</td>
        <td align="left" valign="middle">A mouse button was pressed over the object.</td>
      </tr>
<tr>
        <td align="left" valign="middle">buttonrelease</td>
        <td align="left" valign="middle">[ButtonNo,X,Y|_]</td>
        <td align="left" valign="middle">A mouse button was released over the object. </td>
      </tr>
<tr>
        <td align="left" valign="middle">enter</td>
        <td align="left" valign="middle">[]</td>
        <td align="left" valign="middle">Delivered when the mouse pointer enters the objects area.</td>
      </tr>
<tr>
        <td align="left" valign="middle">focus</td>
        <td align="left" valign="middle">[Int|_]</td>
        <td align="left" valign="middle">Keyboard focus has changed. 0 means lost focus. 1 means gained focus.</td>
      </tr>
<tr>
        <td align="left" valign="middle">keypress</td>
        <td align="left" valign="middle">[KeySym,Keycode, Shift, Control|_]</td>
        <td align="left" valign="middle">A key has been pressed. </td>
      </tr>
<tr>
        <td align="left" valign="middle">leave</td>
        <td align="left" valign="middle">[]</td>
        <td align="left" valign="middle">Mouse pointer leaves the object.</td>
      </tr>
<tr>
        <td align="left" valign="middle">motion</td>
        <td align="left" valign="middle">[X,Y|_]</td>
        <td align="left" valign="middle">The mouse pointer is moving in the object. Used when tracking the mouse in a window.</td>
      </tr>
</table>
<em>Table
        4.1:
         
        Generic Event Types</em>

    <h4>The Buttonpress and Buttonrelease Events</h4>
      
      <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>
      <div class="example"><pre>
{gs,ObjectId,buttonpress,Data,[MouseButton,X,Y|_]}
      </pre></div>
      <p>The mouse button number which was pressed is the first argument in the <span class="code">Args</span> field list. This number is either 1, 2 or 3, if you have a three button mouse. The <span class="code">X</span> and <span class="code">Y</span> 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>
    

    <h4>The Enter and Leave Events</h4>
      
      <p>These events are generated when the mouse pointer (cursor) enters or leaves an object.</p>
    

    <h4>The Focus Event</h4>
      
      <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>
      <div class="example"><pre>
{gs,ObjectId,focus, Data,[FocusFlag|_]}
      </pre></div>
      <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>
    

    <h4>The Keypress Event</h4>
      
      <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>
      <div class="example"><pre>
{gs,ObjectId,keypress,Data,[Keysym,Keycode,Shift,Control|_]}
      </pre></div>
      <p>The <span class="code">Keysym</span> argument is either the character key which was pressed, or a word which describes which key it was. Examples of <span class="code">Keysyms</span> are; <span class="code">a</span>,<span class="code">b</span>,<span class="code">c</span>.., 1,2,3..., <span class="code">'Return'</span>, <span class="code">'Delete'</span>, <span class="code">'Insert'</span>, <span class="code">'Home'</span>, <span class="code">'BackSpace'</span>, <span class="code">'End'</span>.  The <span class="code">Keycode</span> argument is the keycode number for the key that was pressed. Either the <span class="code">Keysym</span> or the <span class="code">Keycode</span> argument can be used to find out which key was pressed.  The <span class="code">Shift</span> 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>
    

    <h4>The Motion Event</h4>
      
      <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>
      <div class="example"><pre>
{gs,ObjectId,motion,Data,[X,Y|_]}
      </pre></div>
      <p>The current x and y coordinates of the cursor are sent along in the <span class="code">Args</span> field.</p>
    
  

  <h3><a name="id65547">4.3 
        Object Specific Events</a></h3>
    
    <p>The click and doubleclick events are the object specific event types. Only some objects have these events and the <span class="code">Args</span> 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 border="1" cellpadding="2" cellspacing="0">
<tr>
        <td align="left" valign="middle"><strong>Event</strong></td>
        <td align="left" valign="middle"><strong>Args</strong></td>
        <td align="left" valign="middle"><strong>Description</strong></td>
      </tr>
<tr>
        <td align="left" valign="middle">click</td>
        <td align="left" valign="middle">&lt;object specific&gt;</td>
        <td align="left" valign="middle">Pressing a button or operating on a object in some predefined way. </td>
      </tr>
<tr>
        <td align="left" valign="middle">double-click</td>
        <td align="left" valign="middle">&lt;object specific&gt;</td>
        <td align="left" valign="middle">Pressing the mouse button twice quickly. Useful with list boxes.</td>
      </tr>
</table>
<em>Table
        4.2:
         
        Object Specific Events</em>
  

  <h3><a name="id65664">4.4 
        Matching Events Against Object Identifiers</a></h3>
    
    <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>
<div class="example"><pre>

-module(ex3).
-copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
-vsn('$Revision: /main/release/2 $ ').

-export([init/0]).

init() -&gt;
    S = gs:start(),
    W = gs:create(window,S,[{width,300},{height,200}]),
    B1 = gs:create(button,W,[{label, {text,"Button1"}},{y,0}]),
    B2 = gs:create(button,W,[{label, {text,"Button2"}},{y,40}]),
    gs:config(W, {map,true}),
    loop(B1,B2).

loop(B1,B2) -&gt;
    receive
        {gs,B1,click,_Data,_Arg} -&gt; % button 1 pressed
            io:format("Button 1 pressed!~n",[]),
            loop(B1,B2);
        {gs,B2,click,_Data,_Arg} -&gt; % button 2 pressed
            io:format("Button 2 pressed!~n",[]),
            loop(B1,B2)
    end.
</pre></div>  

  <h3><a name="id65689">4.5 
        Matching Events Against Object Names</a></h3>
    
    <p>Another solution is to name the objects using the <span class="code">create/4</span> function. In this way, the program does not have to pass any parameters which contain object identifiers for each function call made.</p>
<div class="example"><pre>

-module(ex4).
-copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
-vsn('$Revision: /main/release/2 $ ').

-export([init/0]).

init() -&gt;
    S = gs:start(),
    gs:create(window,win1,S,[{width,300},{height,200}]),
    gs:create(button,b1,win1,[{label, {text,"Button1"}},{y,0}]),
    gs:create(button,b2,win1,[{label, {text,"Button2"}},{y,40}]),
    gs:config(win1, {map,true}),
    loop(). %% look, no args!

loop() -&gt;
    receive
        {gs,b1,click,_,_} -&gt; % button 1 pressed
            io:format("Button 1 pressed!~n",[]),
            loop();
        {gs,b2,click,_,_} -&gt; % button 2 pressed
            io:format("Button 2 pressed!~n",[]),
            loop()
    end.
</pre></div>  

  <h3><a name="id65716">4.6 
        Matching Events Against the Data Field</a></h3>
    
    <p>A third solution is to set the <span class="code">data</span> option to some value and then match against this value. All built-in objects have an option called <span class="code">data</span> which can be set to any Erlang term. For example, we could set the data field to a tuple <span class="code">{Mod, Fun,Args}</span> and have the receiving function make an <span class="code">apply</span> on the contents of the data field whenever certain events arrive.</p>
<div class="example"><pre>

-module(ex5).
-copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
-vsn('$Revision: /main/release/2 $ ').

-export([start/0, init/0, b1/0, b2/0]).

start() -&gt;
    spawn(ex5, init, []).

init() -&gt;
    S = gs:start(),
    W = gs:create(window,S,[{map,true}]),       
    gs:create(button,W,[{label,{text,"Button1"}},{data,{ex5,b1,[]}},{y,0}]),
    gs:create(button,W,[{label,{text,"Button2"}},{data,{ex5,b2,[]}},{y,40}]),
    loop().

loop()-&gt;
    receive
        {gs,_,click,{M,F,A},_} -&gt; % any button pressed
            apply(M,F,A),
            loop()
    end.

b1() -&gt;
    io:format("Button 1 pressed!~n",[]).
b2() -&gt;
    io:format("Button 2 pressed!~n",[]).                
</pre></div>  

  <h3><a name="id65756">4.7 
        Experimenting with Events</a></h3>
    
    <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>
<div class="example"><pre>

-module(ex6).
-copyright('Copyright (c) 1991-97 Ericsson Telecom AB').
-vsn('$Revision: /main/release/2 $ ').

-export([start/0,init/0]).

start() -&gt;
    spawn(ex6,init,[]).

init() -&gt;
    S = gs:start(),
    W = gs:create(window,S,[{map,true},{keypress,true},
                            {buttonpress,true},{motion,true}]),
    gs:create(button,W,[{label,{text,"PressMe"}},{enter,true},
                        {leave,true}]),
    event_loop().

event_loop() -&gt;
    receive
        X -&gt;
            io:format("Got event: ~w~n",[X]),
            event_loop()
    end.
</pre></div>  
</div>
<div class="footer">
<hr>
<p>Copyright © 1997-2012 Ericsson AB. All Rights Reserved.</p>
</div>
</div>
</div></body>
</html>