Newsgroups: comp.lang.smalltalk
Path: cantaloupe.srv.cs.cmu.edu!rochester!udel!gatech!howland.reston.ans.net!torn!nott!cunews!dbuck
From: dbuck@superior.carleton.ca (Dave Buck)
Subject: Re: [VW2] Detect mouse moving over a widget
X-Nntp-Posting-Host: superior.carleton.ca
Message-ID: <DFC5n4.Cpn@cunews.carleton.ca>
Sender: news@cunews.carleton.ca (News Administrator)
Organization: Carleton University, Ottawa, Canada
References: <43uqv7$ake@vixen.cso.uiuc.edu>
Date: Sat, 23 Sep 1995 02:01:52 GMT
Lines: 64

In article <43uqv7$ake@vixen.cso.uiuc.edu>, longdj  <longdj@aol.com> wrote:
>Hello,
>
>Does anyone have an idea on how to detect if the mouse pointer has moved over
>a widget?  I want to be able to detect that the user has moved the mouse to a
>pushbutton (but hasn't pushed it yet) so I can display some help on a status line
>or wherever.
>
>Is this possible?  Any help/pointers would be appreciated.

In VisualWorks, anything is possible.  You just have to decide how
much work you want to go through to do it.

In response to your question, you could try something like this:

1) Create a new instance variable.  Here, I've called it
statusLinePoller.

2) In a postOpenWith method, create a block to run at background
priority.  This block scans through all the views on this window to
see if they contain the cursorPoint.  If so, it writes some text into
the status line.  In this example, I just wrote the label of the
widget into a static label on the window:

postOpenWith: aBuilder
    statusLinePoller := [
        [true] whileTrue: [  | point viewSpecWrapper string |
            self builder window isActive ifTrue: [
                point := self builder window sensor cursorPoint.
                viewSpecWrapper := self builder namedComponents
                    detect: [:wrapper | wrapper containsPoint: point]
                    ifNone: [nil].
                viewSpecWrapper isNil
                    ifTrue: [string := '']
                    ifFalse: [string := view spec name asString].
                (self builder componentAt: #labelID) labelString: string]]]
        forkAt: Processor userBackgroundPriority

3) You need to terminate the process you started.  As far as I know,
you can do this by implemeting a noticeOfWindowClose: method for the
ApplicationModel subclass you are creating:

 noticeOfWindowClose: aWindow 
     statusLinePoller terminate.

This technique could be cleaned up by putting the stuff inside the
block into a separate method.  You should also keep track of the
string that's currently in the status line and not change it if it
doesn't need to be changed.

This technique can also be extended to map the label strings to real
help strings.  I'll leave that as an exercise to the reader :-).

If anybody else has a better way to do this or takes objection to my
use of builders and spec wrappers, I'd love to hear your alternatives
(no sarcasm intended).

David Buck
dbuck@ccs.carleton.ca
_________________________________
| David K. Buck                 |
| dbuck@ccs.carleton.ca         |
| The Object People             |
|_______________________________|
