List Box with OOPs

Date:    Tue, 13 Feb 1996 10:03:31 +1200
From:    Mike Nelson <miken@TERABYTE.CO.NZ>
Subject: Re: How to select in a list box ?- Object-oriented code


>        I am very new to director and I would like to know
>        if the user can select a line in a listbox and how caN
>        I GET this line back.
I've just built an object that handles all this stuff. I'll include it here, and you can either use it as is or try to figure out which bits you need. My thing handles scrolling (which is damn hard) and adding/removing lines, but you may not need that.

You "make" a list box 10 lines long using field "your field" by going:

  global ListBoxObj
  set ListBoxObj = birth(script "listbox", the number of cast "your field", 10)
and then attach a script to the field which says:
on mouseup
  global ListBoxObj
  mouseclick(ListBoxObj)
end

Here it goes:

CAST NAME "listbox"

-- scrollable list box object

property datalist     -- a list of data lines, to be put into display field
when scrolling
property dataindex    -- index into data list corresponding to the top line
of the display window
property maxdisplines -- number of lines that fit in the display window
property dispCN       -- cast number of display field
property chosenlinenum -- number of line in display field that is hilighted
(0 if none)
property selectcallback -- text to do when user clicks on a line

on birth me, fieldnum, fieldlines, selectfunc
  set datalist = [ ]
  set dataindex = 1
  set maxdisplines = fieldlines
  set dispCN = fieldnum
  set chosenlinenum = 0
  set selectcallback = selectfunc
  if voidP(selectcallback) then set selectcallback = ""
  return me
end


on refresh me
  -- remove all data from datalist
  -- clear datalist
  set datalist = [ ]
  set dataindex = 1
  set chosenlinenum = 0
  -- display no lines
  display me
end

on display me
  -- fill display window from dataindex onwards
  set disp = ""

  -- ensure data fills up the whole window if there is more than one windowful
  set numdata = count(datalist)
  if numdata > maxdisplines then
  
    -- more than one windowful
    -- make sure index is not past the last windowful
    set indexoflastpage = numdata - maxdisplines + 1
    if dataindex > indexoflastpage then
      set dataindex = indexoflastpage
    end if
  else
    -- all data will fit on one screen
    set dataindex = 1
  end if


  set numlines = min(numdata, maxdisplines)
  set lastline = dataindex + numlines - 1

  repeat with linenum = dataindex to lastline
    set newline = getat(datalist, linenum) & return
    set disp = disp & newline
  end repeat
  if disp = "" then put " " into disp
  put disp into field dispCN


  -- display line hilited whatever happened
  selectline me, chosenlinenum
end


on scrollup me
  -- when up arrow is pressed
  -- reveals the line above and scrolls the bottom line off the display window


  if dataindex > 1 then
    -- can reveal a previous line
    set dataindex = dataindex - 1
    set newline = getat(datalist, dataindex) & return

    -- insert data line at top of field
    put newline before field dispCN
    delete line maxdisplines+1 of field dispCN

    -- hilight new line
    movehilite me, +1
  end if
end


on scrolldown me
  -- when down arrow is pressed
  -- reveals the line below and scrolls the top line off the display window


  -- see if there are any more lines to scroll down (after possible load
from disk)
  if dataindex+maxdisplines+1 > count(datalist) then
    -- still no joy
  else
    -- there are some more lines, so reveal next one
    set dataindex = dataindex + 1
    set newline = getat(datalist, dataindex+maxdisplines) & return
    -- insert at bottom of field
    put newline into line maxdisplines+1 of field dispCN
    delete line 1 of field dispCN


    -- hilight new line
    movehilite me, -1
  end if
end

-- features to add and remove lines

on addline me, dataline
  -- append a line to the datalist
  add datalist, dataline

  -- deselect chosen line first
  selectline me, 0

  -- show the last screenful of data (including the new line) in the data window
  set dataindex = count(datalist)  -- display routine will make a full window
  display me
end


on removeline me, rellinenum
  -- remove a line from the list
  -- rellinenum is the line in the window, not in the data


  -- delete line from display, then show watch cursor while refreshing properly
  delete line rellinenum of field dispCN
  cursor 4

  -- deselect chosen line before redisplay
  selectline me, 0

  -- remove from list
  set listpos = dataindex + rellinenum - 1
  deleteAt datalist, listpos

  -- redisplay all the data in the data window
  display me

  -- restore cursor
  cursor 0
end

on removeselectedline me
  -- remove the line that is currently hilited from the list
  -- remove line
  removeline me, chosenlinenum
end


-- features to maintain a selected line


on selectline me, rellinenum
  -- mark a line in the window as selected and hilight it
  -- rellinenum is the line in the window, not in the data

  set chosenlinenum = rellinenum

  -- hilight/unhilight it
  if chosenlinenum = 0 then
    set the hilite of cast dispCN = false
  else
    hilite line chosenlinenum of field dispCN
  end if
end

on movehilite me, linesdown
  -- moves hilite down (or up) some lines: used in scrollup and scrolldown
handlers


-- hilight new line
  if chosenlinenum > 0 then
    set newlinenum = chosenlinenum + linesdown


-- do not allow hilite to scroll off the window
    if newlinenum > 0 and newlinenum <= maxdisplines then
      -- linenum is valid
      set chosenlinenum = newlinenum
    end if
  end if

  -- display new/old line hilited whatever happened
  selectline me, chosenlinenum
end


on getchosenline me
  -- returns the text of the selected line
  if chosenlinenum then
    return line chosenlinenum of field dispCN
  else
    return ""
  end if
end

-- event handlers

on MouseClick me, ch
  set li = the mouseline

  -- hilight the line
  selectline me, li

  if li > 0 then
    -- do selection callback
    do SelectCallback
  end if
end