FlyByHelp.st
author Claus Gittinger <cg@exept.de>
Fri, 29 Aug 2003 21:34:08 +0200
changeset 1802 ef3539bf86b7
parent 1768 7011c938442e
child 1892 4c38a0c4369b
permissions -rw-r--r--
*** empty log message ***

"
 COPYRIGHT (c) 2001 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"

"{ Package: 'stx:libview2' }"

ActiveHelp subclass:#FlyByHelp
	instanceVariableNames:'currentFrame currentView currentHelpView showProcess closeProcess'
	classVariableNames:'DelayTime ShowTime TheOneAndOnlyHelpListener'
	poolDictionaries:''
	category:'Interface-Help'
!

!FlyByHelp class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 2001 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
! !

!FlyByHelp class methodsFor:'initialization'!

initialize
    "set default delay & help-display times"

    ShowTime := 10.
    DelayTime := 0.4.

    "
     FlyByHelp initialize
    "

    "Modified: 27.4.1996 / 15:07:27 / cg"
! !

!FlyByHelp class methodsFor:'start & stop'!

start
    "start activeHelp for all apps"

    TheOneAndOnlyHelpListener isNil ifTrue:[
        TheOneAndOnlyHelpListener := self new.
    ].
    TheOneAndOnlyHelpListener listenForAll

    "
     FlyByHelp start
     FlyByHelp stop
    "
!

stop
    "stop activeHelp for all (except for individual apps)"

    TheOneAndOnlyHelpListener notNil ifTrue:[
        TheOneAndOnlyHelpListener unlistenAll.
        TheOneAndOnlyHelpListener := nil.
    ].

    "
     FlyByHelp start
     FlyByHelp stop
    "
! !

!FlyByHelp methodsFor:'listening'!

buttonMotion:state x:x y:y view:aView
    aView == currentHelpView ifTrue:[^ self].
    super buttonMotion:state x:x y:y view:aView
!

pointerLeave:state view:aView
    aView == currentHelpView ifTrue:[^ self].
    super pointerLeave:state view:aView
! !

!FlyByHelp methodsFor:'private'!

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

    |text|

    aPointOrNil notNil ifTrue:[
        (aModel respondsTo:#flyByHelpTextFor:at:) ifTrue:[
            text := aModel flyByHelpTextFor:aView at:aPointOrNil.
        ].
    ].
    text isNil ifTrue:[
        (aModel respondsTo:#flyByHelpTextFor:) ifTrue:[
            text := aModel flyByHelpTextFor:aView.
        ].
    ].
    ^ text
!

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

    |text|

    aPointOrNil notNil ifTrue:[
        (aView respondsTo:#flyByHelpTextAt:) ifTrue:[
            text := aView flyByHelpTextAt:aPointOrNil.
        ].
    ].
    text isNil ifTrue:[
        (aView respondsTo:#flyByHelpText) ifTrue:[
            text := aView flyByHelpText.
        ].
    ].
    ^ text.
!

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

    |whereOnScreen|

    currentFrame notNil ifTrue:[
        whereOnScreen := aView graphicsDevice pointerPosition.

        (currentFrame notNil
        and:[(currentFrame insetBy:1@1) containsPoint:whereOnScreen]) ifFalse:[
            self hideHelp.
        ].
    ].

    "Modified: 28.5.1996 / 20:18:28 / cg"
!

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)"

    |text|

    (self interestedIn:aView) ifFalse:[
        ^ self
    ].

    text := self helpTextFor:aView at:aPointOrNil.
    lastHelpText = text ifTrue:[
        ^ self
    ].

    text size > 0 ifTrue:[
        (showItNow not and:[DelayTime > 0]) ifTrue:[
            self stopHelpDisplayProcess.
            showProcess := [
                    Delay waitForSeconds:DelayTime.
                    showProcess := nil.
                    self showHelp:text for:aView
            ] forkAt:(Processor userSchedulingPriority + 1).
        ] ifFalse:[
            self showHelp:text for:aView
        ]
    ] ifFalse:[
        self hideHelp
    ].
!

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

    aView isNil ifTrue:[^ false].
    aView topView == currentHelpView ifTrue:[^ false].

    ^ super interestedIn:aView
! !

!FlyByHelp methodsFor:'show & hide help'!

hideHelp
    "hide the help text"

    |p|

    lastHelpText := nil.
    self stopHelpDisplayProcess.

    currentHelpView notNil ifTrue:[
        [
            currentHelpView destroy.
            currentHelpView := nil.
            currentView := nil.
        ] valueUninterruptably
    ].
    currentFrame := nil.
    closeProcess notNil ifTrue:[
        p := closeProcess. closeProcess := nil.
        p terminate.
    ]

    "Modified: 28.6.1997 / 14:03:50 / cg"
!

showHelp:aHelpText for:view
    "show the help text for aView"

    |org p v dev|

    view == currentView ifTrue:[
        lastHelpText = aHelpText ifTrue:[
            ^ self
        ]
    ].

    lastHelpText := aHelpText.

    closeProcess notNil ifTrue:[
        p := closeProcess. closeProcess := nil.
        p terminate.
    ].
    currentHelpView notNil ifTrue:[
        self hideHelp
    ].

    org := view originRelativeTo:nil.
    currentFrame := org extent:view extent.
    org :=org + (view extent // 2).

    dev := view graphicsDevice.

    v := ActiveHelpView for:aHelpText withCRs onDevice:dev.

    org := dev pointerPosition.
    org := org + (0@18"24").
    (org x + v width) > dev width ifTrue:[
        org := (org x - v width) @ org y
    ].
    (org y + v height) > dev height ifTrue:[
        org := org x @ (org y - v height).
    ].

    v origin:org.
"/    currentHelpView open.
    v realize.
    v enableButtonMotionEvents.
    v enableMotionEvents.
    currentHelpView := v.

    currentView := view.
    closeProcess := [
            [
                (Delay forSeconds:ShowTime) wait.
                [
                    currentHelpView notNil ifTrue:[
                        currentHelpView destroy.
                        currentHelpView := nil.
                    ]
                ] valueUninterruptably
            ] ifCurtailed:[
                closeProcess := nil.
            ].
        ] newProcess.
    closeProcess priority:(Processor userSchedulingPriority + 1).
    closeProcess resume.

    "Modified: / 31.8.1995 / 19:20:45 / claus"
    "Modified: / 10.12.2001 / 21:28:26 / cg"
!

stopHelpDisplayProcess
    |p|

    showProcess notNil ifTrue:[
        p := showProcess. showProcess := nil.
        p terminate.
    ].

    "Created: 28.6.1997 / 14:03:17 / cg"
! !

!FlyByHelp class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libview2/FlyByHelp.st,v 1.10 2003-08-29 19:34:08 cg Exp $'
! !

FlyByHelp initialize!