select line text listing
text select

  text selection
From:         James Newton <jnewton@cqm.co.uk>
Subject:      Re: select line text listing

Nick Derewianka <nickd@e-media.com.au>
> I have to create a selectable text listing  (think of the winamp
> playlist)
> I need to be able to select a line of text.
> I would have liked to have used a text member...

> Can someone please point out to me the obvious solution that i have
> missed so that im not really going to have to roll my own widget...

Hi Nick,

There is no obvious solution... at least none that I have found.  But
you might not need to roll your own widget.  I can send you (and anyone
else who is interested) a 24 K movie with a couple of behaviors, one to
attach to the non-editable text sprite and the other to attach to one or
two rectangular shape sprites to create the hilite.

I tend to set the ink of the lower-numbered shape sprite to Reverse, and
the the ink of the higher-numbered shape sprite to Lightest.  This
allows me to create a colored hilite with an inversion effect.

If you want to create your own behavior, the three main handlers appear
below.  (Note that this extract does not set the properties).





property mySprite          -- sprite
property myRect            -- rect of mySprite
property myMember          -- member of mySprite
property myText            -- text of myMember
property myHiliteInstances -- list of instances of Behavior for Shapes
property myHiliteLine      -- currently hilited line of text

-- <handlers to set properties snipped>

on exitFrame(me) -----------------------------------------------------
  -- * Checks if the mouse is now over a new line, and if so, calls
  --   the instances of "Hilite Rect" behavior stored in
  --   myHiliteInstances with the rect of the new line as a parameter.

  mouseOverLine = pointToLine(mySprite, the mouseLoc)
  if myHiliteLine = mouseOverLine then
    -- There is no need to refresh the hilite rect
  end if

  myHiliteLine = mouseOverLine
  call(#hiliteRect, myHiliteInstances, me.getLineRect(myHiliteLine))
end hiliteLineUnderMouse

on getLineRect(me, whichLine) ----------------------------------------
  -- Called by exitFrame()
  -- Returns the rect of the line/paragraph of text identified by
  -- whichLine.

  currentScroll = myMember.scrollTop

  if whichLine < 1 then
    -- The mouse is not over the sprite: return a rect with zero area
    return rect (0, 0, 0, 0)

  else if whichLine = 1 then
    -- The current line starts at the top of the sprite
    top  = myRect.top

    -- Determine where the current line starts
    previousChars = myText.line[1..whichLine - 1].char.count
    top = myMember.charPosToLoc(previousChars)[2]
    top = top + myRect.top - currentScroll + 1
    -- Trim to the top of the sprite
    top = max(top, myRect.top)
  end if

  -- Determine where the current line ends
  lastChar = myText.line[1..whichLine].char.count
  bottom = myMember.charPosToLoc(lastChar)[2]
  bottom = bottom + myRect.top - currentScroll + 1
  -- Trim to the bottom of the sprite
  bottom = min(bottom, myRect.bottom)

  return rect(myRect.left, top, myRect.right, bottom)
end getLineRect


on hiliteRect(me, theRect) -------------------------------------------
  -- Called by the exitFrame() handler of the "Text Hilite"
  -- behavior on a separate sprite.

  sprite(me.spriteNum).rect = theRect
end hiliteLine 

Home shock + cgi Bits 'n pieces Director Lingo ShockLets Contact