                              The LiteClue Widget 


1. Copyright 

Copyright 1995 Computer Generation, Inc. You may reproduce this document 
without charge provided the copyright and disclaimer notices appear. The 
software described in this document is copyrighted under separate terms. See 
the source code available at ftp://ftp.compgen.com/pub/widgets/LiteClue.tar.Z

The software is provided "as is", without warranty of any kind, express or 
implied, including but not limited to the warranties of merchantability, 
fitness for a particular purpose and noninfringement. In no event shall 
Computer Generation, inc. nor the author(s) be liable for any claim, damages or 
other liability, whether in an action of contract, tort or otherwise, arising 
from, out of or in connection with the software or the use or other dealings in 
the software. 

The author welcomes comments and suggestions. 
Gary Aviv 
Computer Generation, Inc.,
gary@compgen.com
404-705-2811

Thanks to contributers:: J Satchell, Eric Marttila. 

If you wish to be on an Emailing list regarding this or other CGI widgets, 
please send a request to the above address. You will be notified when this or 
other widgets are upgraded or when new widgets become available. 

Updated: 06 January 1998 


2. Introduction 

LiteClue is a widget which pops a one line help message when the user passes 
the pointer over another "watched" widget. This is known by various names in 
the industry such as hints, clues, tips, bubble help and balloon help. 

Clues are particularly helpful for push buttons that contain graphic pixmaps 
rather than text. They obviate the need to place text within graphics in the 
button which creates internationalization problems. A clue may be attached to 
virtually any widget that has a window (no gadgets). LiteClue works with Motif 
but does not require it. 

None of this affects the behaviour of the watched widget itself. LiteClue 
monitors enter and leave events of the watched widget's window passively. 

LiteClue relies on EnterNotify and LeaveNotify events for the the widgets it is 
watching. This will normally prevent clues from poping up when the watched 
widgets are insensitive. See the function XcgLiteClueDispatchEvent for a way to 
bypass this limitation. 

LiteClue inherits behaviour and ewsources from OverrideShell. 

The class pointer is xcgLiteClueWidgetClass. 

The class name is xcgLiteClue. 


3. Version Information 

Version 1.2

 1.  R4 back compatibility 
 2.  Delay before pop up of help; XcgNwaitperiod resource (default 500 ms). 
 3.  Button press in watched widget pops down help. 


Version 1.3

 1.  Support of cancelWaitPeriod resource. this is the period after a help 
     popdown occurs in which the normal waitPeriod is suspended for the next 
     popup. 
 2.  minor fixes 


Version 1.4

 1.  Support for clues on insensitive widgets. See XcgLiteClueDispatch function 
     below. 



4. Distribution Kit 

The source distribution kit contains the following files: 

LiteClue.c LiteClue.h LiteClueP.h 
     The LiteClue widget source code 
LiteClueTest.c
     A small demonstration program 
Imake
     an Imake file. 
BUILD.COM
     a command file for building under DEC VMS 
LiteClue.html LiteClue.txt LiteClue.ps 
     Documentation in HTML, plain text and PostScript formats 

LiteClue has been compiled successfully on NCR MPRAS, Digital OSF/Unix, ULTRIX 
(XR4), Linux, VMS and probably many others. 

To build the test program: 

        xmkmf
        make

For VMS, see the file BUILD.COM. 

LiteClue is designed for X11R4 or higher. It checks XtSpecificationRelease at 
compile time. When compiled for X11R5 or higher, it uses font sets which gives 
it good internationalization support (see Section 10 below). However, you can 
also force it to use font structs instead by setting a compile time variable 
(see make file). 

When using font sets, you may get the message: 

Warning: Missing charsets in String to FontSet conversion
Warning: Unable to load any usable fontset

which means that your locale does not support the font's character sets. On 
many machine, the default C locale does not allow 8-bit characters or the 
iso88591 character set required by the default fonts. Fix this by setting your 
LANG environment variable. For example, on HP-UX in the US you set: 

        LANG=C.iso88591


5. Resources 

LiteClue adds the following resources to those it inherits. The resource class 
is obtained by replacing the N by a C in the resource name (eg: XtNfontSet is 
the name XtNfontSet is the class. The access types are C (resource may be set 
at create time), S (may be se using XtSetValues), or G (may be read using 
XtGetValues). 


XtNfontSet
     Type = FontSet, Default = "-adobe-new century 
     schoolbook-bold-r-normal-*-12-*, Access = CG
     The font used to display the clue. For Xt Release 4 or less, the resource 
     name XtNfont and the type is FontStruct. 
     
XtNforeground
     Type = Pixel, Default = "black", Access = CSG
     The color used to render the clue text 
     
XcgNwaitperiod
     Type = Integer, Default = 500, Access = CSG
     The delay from the time the pointer enters the watched widget until the 
     help is popped up in milliseconds. 
     
XcgNcancelWaitPeriod
     Type = Integer, Default = 2000, Access = CSG
     The period (in milliseconds) after a help popdown occurs in which the 
     normal waitPeriod is suspended. If the pointer should re-enter a watched 
     widget during this period help pops up immediately rather than waiting 
     waitPeriod milliseconds. 


The background color resource XtNbackground of the clue popup is inherited from 
OverrideShell. 


6. Callbacks 

LiteClue adds no new callbacks over those it inherits. 


7. Translations 

LiteClue has no translations. 


8. LiteClue API 

LiteClue contains the following functions that control the widget behaviour. 


8.1 XcgLiteClueAddWidget -- Add a widget to be watched. 

Function
     A widget will be added to the LiteClue watched list. Clues are given for 
     sensitive watched widgets when the pointer enters its window. If the 
     widget is already watched, the passed text replaces its current clue text. 
     If text is null, the widget is still added, if it is not already in the 
     list, but no clue will appear. Text may be specified with 
     XcgLiteClueAddWidget in a subsequent call. When text is null and the 
     widget is already in the list, its text is not changed. When a widget will 
     is added to the watched list, it automatically becomes sensitive. 
     Otherwise, its sensitivity is not changed. A watched widget which is not 
     sensitive retains its context but clues are suppressed. None of this 
     affects the behaviour of the watched widget itself. LiteClue monitors 
     enter and leave events of the watched widget's window passively. 

C-call
     void XcgLiteClueAddWidget(Widget w, Widget watch, char * text, int size, 
     int option ) 

Input
     w    LiteClue widget 
     watch 
          the widget for which clues will be given 
     text 
          pointer to buffer containing text. Must be null terminated 
     size 
          size of text, if 0, it will be computed (strlen) 
     option 
          option mask - must be zero 

Output
     Nothing 


8.2 XcgLiteClueDeleteWidget -- Delete a widget that is watched. 

Function
     A widget is deleted from the watched list and its resources are freed. 
     LiteClue is no longer given for the widget. If the widget is not watched, 
     nothing is done. None of this affects the behaviour of the watched widget 
     itself, just whether a clue is poped for the widget. 

C-call
     void XcgLiteClueDeleteWidget(Widget w, Widget watch) 

     w    LiteClue widget 
     watch 
          the widget to remove from watched list 

Output
     Nothing 


8.3 XcgLiteClueSetSensitive - Enable/disable clues for watched widget. 

Function
     When a watched widget is sensitive, a clue is poped up when the pointer 
     enters its window. When a watched widget is insensitive, the widget is 
     retained in the watched list but no clue is poped. The sensitivity of a 
     watched widget relative to clues is set or reset by this function. The Xt 
     sensitivity of the watched widget is not altered by this function. 

C-call
     void XcgLiteClueSetSensitive(Widget w, Widget watch, Boolean sensitive) 

     w    LiteClue widget 
     watch 
          the widget to alter sensitivity 
     sensitive
          True - restore sensitivity
          False - make insensitivity 

Output
     Nothing 


8.4 XcgLiteClueGetSensitive - Get sensitivity setting for watched widget. 

Function
     When a watched widget is sensitive, a clue is poped up when the pointer 
     enters its window. When a watched widget is insensitive, the widget is 
     retained in the watched list but no clue is poped. The sensitivity state 
     of a watched widget relative to clues is returned by this function. The Xt 
     sensitivity of a widget is a totally independent concept. 

C-call
     Boolean XcgLiteClueGetSensitive (Widget w, Widget watch) 

     w    LiteClue widget 
     watch 
          the widget for which to get sensitivity state. If NULL first watched 
          widget is used. If there are no watched widgets, False is returned. 

Output
     Nothing 

Return
     True - watched widget is sensitive
     False - watched widget is not sensitive 


8.5 XcgLiteClueDispatchEvent -- Dispatch event from main X event loop 

Function
     This function may be used to enable clues for insensitive watched widgets. 
     Normally, XtAppMainLoop (which calls XtDispatchEvent) will not deliver 
     EnterNotify and LeaveNotify events to widgets that are not sensitive 
     (XtSetSensitive). This prevents clues from poping up for these widgets. To 
     bypass this limitation, you can break out XtAppMainLoop and add a call to 
     XcgLiteClueDispatchEvent ass follows: 

     MyXtAppMainLoop(XtAppContext app)
     {
         XEvent event;
         for (;;) {
             XtAppNextEvent(app, &event);
             XcgLiteClueDispatchEvent(w, event) ;
             XtDispatchEvent(&event);
         }
     }

C-call
     Boolean XcgLiteClueDispatchEvent (Widget w, XEvent *event) 

     w    LiteClue widget 
     event 
          received event, normally from call to XtAppNextEvent. 

Output
     Nothing 

Return
     True - event was dispatched to non-sensitive watched widget. 
     False 
          - not a EnterNotify or LeaveNotify event or window in event is not a 
          non-sensitive watched widget. 


9. Sample Use 

Since LiteClue is a shell widget , you make an instance of the shell as in this 
example: 

        Widget liteClue, toplevel ;
        ...
        toplevel = XtVaAppInitialize(&AppContext,
        ...
        liteClue = XtVaCreatePopupShell( "LiteClue_shell",
                xcgLiteClueWidgetClass, toplevel, ..., NULL);

If you want to change the font used by LiteClue, you could add the fontSet 
resource at create time as in: 

#define RES_CONVERT( res_name, res_value) \
       XtVaTypedArg, (res_name), XmRString, (res_value), strlen(res_value) + 1

        liteClue = XtVaCreatePopupShell( "LiteClue_shell",
                xcgLiteClueWidgetClass, toplevel,
                 RES_CONVERT(XtNfontSet, \
                        "-adobe-new century schoolbook-bold-r-normal-*-18-*"),
                NULL);

You need only create a single instance of the widget for the application. To 
attach help to a widget (usually a push button) use the function 
XcgLiteClueAddWidget (Section 8.1) as in: 

        button_widg = XtVaCreateManagedWidget("Button1", xmPushButtonWidgetClass,
        ...
        XcgLiteClueAddWidget(liteClue, button_widg,  "Help Message", 0, 0);

In order to enable clues for insensitive widgets you will need to replace the 
standard call to XtAppMainLoop with the code as illustrated in the function 
XcgLiteClueDispatchEvent. 


10. Internationalization 

The LiteClue widget is designed to allow the display of internationalized text. 
This has been tested on a limited basis with Japanese. 

In order to make use of internationalization, you must have support in your 
operating system for the desired locale and must have the needed fonts. In some 
cases, you may use the X provided locale support instead. At initialization, 
you should have code that looks something like: 

        if (setlocale(LC_ALL,"") == NULL)
                fprintf(stderr, "LiteCluetest: Can't set locale\n");
        if (!XSupportsLocale())
        {
                fprintf(stderr, "LiteCluetest: X does not support locale\n");
                setlocale(LC_ALL,NULL) ;
        }
        if (XSetLocaleModifiers("") == NULL)
                fprintf(stderr, "LiteCluetest: Can't XSetLocaleModifiers\n");

If you need the X locale package, add the following: 

        #define X_LOCALE
        #include <X11/Xlocale.h>

LiteClue makes use of the XR5 Font Set technology. All font resources are 
converted to Font Sets. For example, for Japanese you will need three fonts for 
each font set: 

*XcgLiteClue.fontSet: \
-sony-fixed-medium-r-normal--0-110-100-100-c-0-jisx0201.1976-0,\
-adobe-new century schoolbook-medium-r-normal-*-14-*,\
-jis-fixed-medium-r-normal--16-110-100-100-c-160-jisx0208.1983-0

Finally, you must set the environment symbol LANG to the appropriate locale. 
For Japanese, one possibility is "LANG=ja_JP.eucJP". 