[comp.sys.mac.hypercard] Making areas of field text clickable?

neves@aristotle.ils.nwu.edu (David Neves) (02/14/90)

Here is my problem.

I have many field texts.  I want to make most of the text in these
fields sensitive to clicks.  The 2 ways of doing this are:

1.  Have the field (on mousedown or mouseup) figure out what text the user has
clicked on.  This gets messy because the only RETURNs in the fields
are between paragraphs and the font is variable width.  To do this one
would have to write an XCMD that used the character width information
and a good guess as to the word wrap routine that Hypercard (in my
case, Supercard) was using.  

2.  Put buttons over all the text.  I don't want to do this by hand
because I might change the field width or the text font.  Both of
these would affect the positioning of words and so the buttons would
not longer be under the correct words.  

It is not trival to get a program to do this automatically.  The only
way that I could think of doing this is to start at the left part of
the field and gradually (pixel by pixel) select larger chunks of text
by using DRAG or CLICK.  Because the program is doing the dragging you
know the left and right pixel positions of the selected text
underneath.

Before we write this sad kludge I wonder if anyone else has run into
problem or see an obviously easier way of doing it.

p.s.
For those using Supercard there is a nasty bug in SEND.  You can only
SEND to cards that are being displayed in a window, not to cards that
are not at the front.
neves@ils.nwu.edu
Institute for the Learning Sciences, 1890 Maple, Evanston Il 60201

jdevoto@Apple.COM (Jeanne A. E. DeVoto) (02/14/90)

In article <3811@accuvax.nwu.edu> neves@aristotle.ils.nwu.edu
(David Neves) writes:
>I have many field texts.  I want to make most of the text in these
>fields sensitive to clicks.  The 2 ways of doing this are:
>1. [compute pixel widths, taking word wrap into account]
>2. [put buttons over the text]

Why on earth would you want to go to all this trouble?

Recall that a double-click selects a word. If the field is locked, it gets
mouseDown messages. So the following will get you the word clicked on:

on mouseDown
  set the lockText of the target to false -- so we can click w/o recursing
  click at the clickLoc
  click at the clickLoc                   -- double-click
  put the selection into clickedWord
  -- do whatever you're going to do, e.g. go to a card with that name
end mouseDown

You can put certain bells and whistles on this to e.g. refuse to do anything
if the word is not in a certain list of key words. But that's the basic idea.

If the field is not locked, you'll need to use a mouseWithin handler:

on mouseWithin
  if the selectedChunk is not empty then   -- user clicked
    if the selection is not empty then     -- double click
      -- do double-click action; "the selection" is word clicked on
    else
      -- do single-click action, if any
    end if
  end if
end mouseWithin
-- 
====== jeanne a. e. devoto ========================================
 jdevoto@apple.com  |  You may not distribute this article under a
 jdevoto@well.UUCP  |  compilation copyright without my permission.
___________________________________________________________________
 Apple Computer and I are not authorized  |        CI$: 72411,165
 to speak for each other.                 |  AppleLink: SQA.TEST

bskendig@phoenix.Princeton.EDU (Brian Kendig) (02/14/90)

In article <3811@accuvax.nwu.edu> neves@aristotle.ils.nwu.edu (David Neves) writes:
>I have many field texts.  I want to make most of the text in these
>fields sensitive to clicks.  The 2 ways of doing this are:

>1.  Have the field (on mousedown or mouseup) figure out what text the user has
>clicked on.  This gets messy because the only RETURNs in the fields
>are between paragraphs and the font is variable width.  To do this one
>would have to write an XCMD that used the character width information
>and a good guess as to the word wrap routine that Hypercard (in my
>case, Supercard) was using.  

That's the way, and although it's complicated, you don't need to
resort to an XCMD to deal with it.  Put a mouseUp handler into the
field script.  When activated, it should unlock the field, click twice
at the clickLoc, read the selectedText and/or the selectedChunk, lock
the field again, then process the read information.  You needn't worry
at all about the position of carriage returns in the field's text, nor
of the text's size and attributes.

The hard part is figuring out what to do with the stuff you read by
automatically double-clicking.  I decided to process the
selectedChunk.  I would use the text from the beginning of the word
double-clicked on to the next space after it.  (Remember that the
selectedChunk returns phrases like `char 123 to 127 of card field
"Text"', so it's not terribly bad to take care of.  I would use the
text from `char 128 of cd fld "Text"' to the next space, determined
seperately, to avoid having hyphens and slashes break my words.)

>2.  Put buttons over all the text.  I don't want to do this by hand
>because I might change the field width or the text font.  Both of
>these would affect the positioning of words and so the buttons would
>not longer be under the correct words.  

No!  No!  Aack!  Don't *do* that!

>It is not trival to get a program to do this automatically.  The only
>way that I could think of doing this is to start at the left part of
>the field and gradually (pixel by pixel) select larger chunks of text
>by using DRAG or CLICK.  Because the program is doing the dragging you
>know the left and right pixel positions of the selected text
>underneath.

As always with HyperCard and the Macintosh, the best solution is the
most intuitive one.  The one you suggest ain't intuitive.

>Before we write this sad kludge I wonder if anyone else has run into
>problem or see an obviously easier way of doing it.

I have, actually, and if sufficiently persuaded and/or kicked hard
enough, I might decide to put it into a sample stack for Public
Consumption.  Or I might decide to rewrite it.  Ya nevah know.

     << Brian >>

-- 
| Brian S. Kendig      \ Macintosh |   Engineering,   | bskendig             |
| Computer Engineering |\ Thought  |  USS Enterprise  | @phoenix.Princeton.EDU
| Princeton University |_\ Police  | -= NCC-1701-D =- | @PUCC.BITNET         |
|   Systems Engineering, NASA Space Station Freedom / General Electric WP3   |

neves@aristotle.ils.nwu.edu (David Neves) (02/15/90)

In article <13831@phoenix.Princeton.EDU> bskendig@phoenix.Princeton.EDU (Brian Kendig) writes:
>
>That's the way, and although it's complicated, you don't need to
>resort to an XCMD to deal with it.  Put a mouseUp handler into the
>field script.  When activated, it should unlock the field, click twice
>at the clickLoc, read the selectedText and/or the selectedChunk, lock
>the field again, then process the read information.  You needn't worry
>at all about the position of carriage returns in the field's text, nor
>of the text's size and attributes.
Yes!  I had forgotten that selectedchunk will return the loction of
the click.  Since I want phrases to be clickable I would have to lock
the screen so that the first word selection doesn't show up.  Unfortunately
Supercard has another bug where the screen shows selections even when
locked.  Maybe its time to go to Hypercard!
-Thanks again, david
neves@ils.nwu.edu
Institute for the Learning Sciences, 1890 Maple, Evanston Il 60201

tim@hoptoad.uucp (Tim Maroney) (02/16/90)

In article <3811@accuvax.nwu.edu> neves@aristotle.ils.nwu.edu (David Neves)
writes:
>I have many field texts.  I want to make most of the text in these
>fields sensitive to clicks.  The 2 ways of doing this are:
>
>1.  Have the field (on mousedown or mouseup) figure out what text the user has
>clicked on.  This gets messy because the only RETURNs in the fields
>are between paragraphs and the font is variable width.  To do this one
>would have to write an XCMD that used the character width information
>and a good guess as to the word wrap routine that Hypercard (in my
>case, Supercard) was using.  

No, you can use a trick I've used to good effect.  On a click in a
locked text field, unlock the field, and do two clicks yourself with
the click command.  This will select whatever word of text was clicked
on, and you can use "the selection" and the related functions to figure
things out.
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"Strong men tremble when they hear it.
 They've got cause enough to fear it;
 It's even blacker than they smear it!
 No one mentions -- my name." - Bill Sykes, "Oliver"

taylorj@yvax.byu.edu (02/17/90)

>Yes!  I had forgotten that selectedchunk will return the loction of
>the click.

There's a neat trick to make phrases or any other group of more than one word
double-clickable.  Use option-space instead of space.  Option-space is treated
the same as a letter so HyperCard thinks it's all one word.  Of course, this
also means your phrases can't wrap across lines, but every silver cloud has a
grey lining!


Jim Taylor
Microcomputer Support for Curriculum
Brigham Young University
taylorh@yvax.byu.edu