
#  $Id: _list.icn,v 1.1 2003-05-31 06:09:03 jeffery Exp $

##
#
#  This component is for selecting one string from a list of
#  several.  When a button is pressed a list appears (possibly
#  with a scroll bar) from which one item can be selected.
#
#  An event is generated whenever an item is selected from the
#  list.
#
#  @example
#  @ l := List()
#  @ l$set_selection_list(["Red", "Green", "Yellow", "Blue", "Orange"])
#  @ l$set_size(120)
#  @ l$set_pos(100, 100)
#  @ l$set_selection(2)  # Green will be the first selection
#  @ self$add(l)
#
class List : Component : DropDown(
   b,
   l,
   constant_label
   )

   ##
   #  Set the selected item.
   #  @param x   An index into the list of selectable items.
   #
   method set_selection(x)
     self.selection := x
     self.l$set_label(\self.constant_label | self.selection_list[self.selection])
     self$redisplay()
     return x
   end

   ##
   #  The given string will always appear in the text part of the
   #  component, rather than the currently selected item.
   #
   method set_constant_label(x)
      return self.constant_label := x
   end

   method firstly()
      self$Component.firstly()
      self.b$firstly()
      self.l$firstly()
      self.l$set_label(\self.constant_label | self.selection_list[self.selection])
   end

   method finally()
      #
      # Disposed with text list showing, just get rid of it
      #
      if \self.tl then {
         self$close_TextList()
         self$unique_end()
      }

      self$Component.finally()
      self.b$finally()
      self.l$finally()
   end

   method resize()
      local bw

      if /self.selection_list then
         error("no selection list specified")

      #
      # Re-sized with text list showing, just get rid of it
      #
      if \self.tl then {
         self$close_TextList()
         self$unique_end()
      }

      /self.h_spec := WAttrib(self.cwin, "fheight") + 2 * DEFAULT_TEXT_Y_SURROUND
      self$Component.resize()

      bw := self.h - 2 * BORDER_WIDTH

      #
      # Set button position and size
      #
      b$set_pos(self.w - BORDER_WIDTH - bw, BORDER_WIDTH)
      b$set_size(bw, bw)
      b$resize()

      #
      # Set label position and size
      #
      l$set_pos(BORDER_WIDTH + DEFAULT_TEXT_X_SURROUND, BORDER_WIDTH)
      l$set_size(self.w - bw - 2 * BORDER_WIDTH - 2 * DEFAULT_TEXT_X_SURROUND,  self.h - 2 * BORDER_WIDTH)

      l$resize()

      return
   end

   method display(buffer_flag)
      #
      # Draw text element
      #
      EraseRectangle(self.cbwin, self.x, self.y, self.w, self.h)
      DrawSunkenRectangle(self.cbwin, self.x, self.y, self.w, self.h,-2)
      #
      # Draw button and list
      #
      self.b$display(1)
      self.l$display(1)
      self$do_shading(self.cbwin)
      if /buffer_flag then
         CopyArea(self.cbwin, self.cwin, self.x, self.y, self.w, self.h, self.x, self.y)
   end

   method handle_event(e)
      local tmp, E

      if \tl then {
         if E := b$handle_event(e) then {
            if E$get_code() = 0 then {
               #
               # Button pressed whilst list open; just close
               #
               self$close_TextList()
               self$unique_end(1)
            } else
               self.tl.is_held := &null
         } else if E := tl$handle_event(e) then {
            if E$get_code() = 1 then {
               #
               # Selection in list - close textlist, amend label, return event.
               #
               tmp := tl$get_selections()[1]
               self$close_TextList()
               self$unique_end(1)
               if self.selection := \tmp then {
                  if /self.constant_label then
                     self.l$set_label(self.selection_list[self.selection])
                  return _Event(e, self, 0)
               }
            }
         } else if integer(e) = (&lpress | &rpress | &mpress) & not(tl$in_region()) then {
            #
            # Mouse click outside textlist.  Close.
            #
            self$close_TextList()
            self$unique_end()
         }
      } else {
         if b$handle_event(e)$get_code() = 0 then {
            #
            # Button pressed whilst no list; open list
            #
            self$open_TextList()
            self.tl.is_held := 1
            self$unique_start()
         }
      }
   end

   method final_setup(x, y)
      self$Component.final_setup(x, y)
      self.b$final_setup(x, self)
      self.l$final_setup(x, self)
   end

   initially(argv[])
      self$Component.initially()
      self.l := Label()
      self.l$set_label("")
      self.b := IconButton()
      self.b$toggle_draw_border()
      self.b$set_img(img_style("arrow_down"))
      self.selection := 1
      if *argv > 0 then set_fields(argv)
end
