eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'ActiveHelp':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: ActiveHelp


Inheritance:

   Object
   |
   +--EventListener
      |
      +--ActiveHelp
         |
         +--FlyByHelp

Package:
stx:libview2
Category:
Interface-Help
Version:
rev: 1.92 date: 2018/01/31 15:00:11
user: cg
file: ActiveHelp.st directory: libview2
module: stx stc-classLibrary: libview2
Author:
Claus Gittinger

Description:


The active help (tooltip) listener.

The one and only instance of myself intercepts incoming mouse & keyboard 
events for the display device, being especially interested in view-enter/
leave events. When such an event arrives, it asks the corresponding view
or its model for a help message and displays it via an ActiveHelpView.
Actually, the view is first asked if it would like to display it itself
- for example, in some information-view at the bottom of its main window.

The query for the helpText is repeated along the view's superView chain, 
until any model or view returns a nonNil answer for the 
#helpTextFor:<aSubView> at:<position> or #helpTextFor:<aSubView> message.

All I need for automatic help is some model/view/applicationModel along
the superview chain of the entered component, which responds to the
#helpTextFor: message with a non-nil (string-) answer.
I close down the help view after a while, if a key is pressed or the mouse
moved to another view.

Who should provide the helpText:
    the best place is the application object (an instance of ApplicationModel)
    or the topView, if it's a derived class of StandardSystemView.
    This should know about its components and return the string
    when asked via #helpTextFor:<aSubView>.
    See examples in FileBrowser, Launcher etc.

Be aware, that for applicationModels, there must be a link from the
topView to this applicationModel 
(set via: aTopView application:anApplicationModel)
otherwise, the helpManager has no means of finding the application which
corresponds to a view.

Who should display the helpText:
    by default, the helpListener opens a little popup view, which displays the
    returned help message. However, a nice trick which can be used by applications
    is to create an infoLabel as a subview of the topFrame (a la windows)
    and display the text right in the #helpTextFor: method. To cheat the
    help listener, this method should then return nil, to keep it silent.


Usage:
    If help is to be shown for all views (as enabled by the launchers help menu),
    use 'ActiveHelp start' and 'ActiveHelp stop'.

    Individual apps may enable/disable active help for themself by:
    'ActiveHelp startFor:app' or 'ActiveHelp stopFor:app', passing either
    the topView or the topViews application as argument.
    This is usually done by applications which want to show contextHelp in
    some infoView.
    Late note: thsi is no longer recommended - one such mouse watcher process is
    good enough for all views.
    


Related information:

    ActiveHelpView
    WindowGroup
    WindowEvent
    ApplicationModel
    StandardSystemView

Class protocol:

accessing
o  debugging

o  debugging: something
self debugging:true
self debugging:false

initialization
o  initialize

queries
o  currentHelpListener
return the activeHelp listener if activeHelp is turned on, nil otherwise
usage example(s):
     ActiveHelp currentHelpListener
     FlyByHelp currentHelpListener

o  delayTime

o  isActive
return true, if activeHelp is turned on
usage example(s):
     FlyByHelp isActive

o  showTime
set the number of seconds, a help messages is to be shown.
The default is 45 seconds.
0 means: show forever (i.e. until mouse is moved)

start & stop
o  start
start activeHelp for all apps
usage example(s):
     ActiveHelp start
     FlyByHelp start

o  startFor: anApplicationOrTopView
start activeHelp for a single app

o  stop
stop activeHelp for all (except for individual apps)
usage example(s):
     ActiveHelp stop
     FlyByHelp stop

o  stopFor: anAppOrTopView
stop activeHelp for a single app

times
o  delayTime: numberOfSeconds
set the delay (the time, the cursor has to be in the view
before help is shown). The default is 2 seconds.
usage example(s):
     ActiveHelp delayTime:0.5
     ActiveHelp delayTime:2
     ActiveHelp delayTime:10

o  showTime: numberOfSeconds
set the number of seconds, a help messages is to be shown.
The default is 30 seconds.
0 means: show forever (i.e. until mouse is moved)
usage example(s):
     ActiveHelp showTime:10
     ActiveHelp showTime:99999 
     ActiveHelp showTime:30


Instance protocol:

event handling
o  buttonMotion: buttonAndModifierState x: x y: y view: aView
handle motion events - prepare to show help

o  keyPress: key x: x y: y view: view
unconditionally hide the help view

o  pointerEnter: state x: x y: y view: aView
handle pointer entering a view; prepare to show help

o  pointerLeave: state view: aView
handle pointer leaving a view; hide help text

o  processEvent: ev
(comment from inherited method)
process an event; if true is returned, the event is considered to be
'eaten' by the listener, and not passed to the view.
If false is returned, the event is processed as usual.
Here, the event is dispatched into one of the button*/key* etc. methods

help texts
o  helpTextFor: aView at: aDevicePointOrNil
retrieve helptext for aView as a string;
walk along the view's superView chain,
asking models and views encountered while walking.
The first one who understands and returns a nonNil answer to the
#helpTextFor:at: or #helpTextFor: message ends this search and the
returned string is returned.

o  helpTextFromModel: aModelOrTopView view: aView at: aPointOrNil
helper: ask aModel for its helpText.

o  helpTextFromView: aView at: aPointOrNil
helper: ask aView for its helpText.

private
o  handleMouseIn: aView x: x y: y
handle motion events - if the mousepointer left the
previous helped view, hide the help

o  hideIfPointerLeft: aView
hide help, if the pointer is not in aView

o  interestedIn: aView
return true, if I am interested in aView (either listeningForAll,
or in my list of apps)

o  targetViewInitiatesHelpViaSensor
true if the target view is asked to show the help via the sensor;
false, if I do it myself synchronously.

queries
o  delayTime

o  showTime
how long shall the help be shown;
0 means: forever (until user moves the mouse);
>0 means that number of seconds

show & hide help
o  hideHelp
hide the help text - nothing done here

o  hideHelpIgnoringErrors
hide the help text

o  initiateHelpFor: aView at: aPointOrNil
ask aView for helpText, passing x/y coordinates;
start a timeout process to display this helpText after some delay;
Normally used internally, but can also be used by widgets to force
re-negotiation of the displayed helpText
(for example in a menu, when the selection changes)

o  initiateHelpFor: aView at: aPointOrNil now: showItNow
ask aView for helpText, passing x/y coordinates;
start a timeout process to display this helpText after some delay;
Normally used internally, but can also be used by widgets to force
re-negotiation of the displayed helpText
(for example in a menu, when the selection changes)

o  stopHelpDisplayProcess

start & stop
o  listenFor: anAppOrTopView
start listening

o  listenForAll
start listening

o  start

o  stop

o  unlistenAll
stop listening

o  unlistenFor: anApp
stop listening for an app


Demonstration:


    ActiveHelp start


    ActiveHelp stop


Examples:


Active Help for a single view or app (whatever the global settings are): Can be initiated by an app when its opened.
      |app top myAppClass|

      Class withoutUpdatingChangesDo:[
          myAppClass := ApplicationModel 
                          subclass:#'Demos::DemoApp'
                          instanceVariableNames:''
                          classVariableNames:''
                          poolDictionaries:''
                          category:'demos'.

          myAppClass 
              compile:'helpTextFor:aView    Transcript showCR:''hello''. ^ ''this is some helpText'''.

      ].
      app := myAppClass new.

      top := StandardSystemView new.
      top extent:300@100.
      top application:app.
      top open.

      ActiveHelp startFor:app.

      Class withoutUpdatingChangesDo:[
          myAppClass removeFromSystem
      ]
Active Help (for all views): (make certain that activeHelp is turned on ... ... otherwise, you will see nothing) the following example uses a Plug as a model replacement. In concrete application, you would create a method to implement the helpText query message.
      |app top button1 button2|

      app := Plug new.
      app respondTo:#helpTextFor:
               with:[:view | 
                             view == button1 ifTrue:[
                               'this is button1'
                             ] ifFalse:[
                               view == button2 ifTrue:[
                                 'some help for button2'
                               ] ifFalse:[
                                 nil
                               ]
                             ]
                    ].

      top := StandardSystemView new.
      top extent:300@100.
      button1 := Button label:'b1' in:top.
      button1 origin:0.0@0.0 corner:0.5@30. 
      button2 := Button label:'b2' in:top.
      button2 origin:0.5@0.0 corner:1.0@30.
      top model:app. '<-- normally this would be: top application:app'.
      top open
(make certain that activeHelp is turned on ... ... otherwise, you will see nothing) alternatively, display of the helpMessage in a local, private view:
      |app top button1 button2 infoView|

      app := Plug new.
      app respondTo:#helpTextFor:
               with:[:view | infoView label:'info ...'.
                             view == button1 ifTrue:[
                               infoView label:'this is button1'
                             ].
                             view == button2 ifTrue:[
                               infoView label:'some help for button2'
                             ].
                             nil
                    ].

      top := StandardSystemView new.
      top extent:300@100.
      button1 := Button label:'b1' in:top.
      button1 origin:0.0@0.0 corner:0.5@30. 
      button2 := Button label:'b2' in:top.
      button2 origin:0.5@0.0 corner:1.0@30.
      infoView := Label label:'info ...' in:top.
      infoView level:-1; origin:0.0@1.0 corner:1.0@1.0.
      infoView topInset:(infoView preferredExtent y negated - 3);
               leftInset:3; 
               rightInset:3; 
               bottomInset:3;
               adjust:#left.
      top model:app. '<-- normally this would be: top application:app'.
      top open


ST/X 7.1.0.0; WebServer 1.663 at exept.de:8081; Wed, 20 Mar 2019 23:43:34 GMT