#
# $Id: editlist.icn,v 1.4 2006-06-22 17:33:46 rparlett Exp $
#
# This file is in the public domain.
#
# Author: Robert Parlett (parlett@dial.pipex.com)
#

package gui
link graphics

$include "guih.icn"

class EditListTextField:TextField()
   method keeps(e)
      return e === (Key_Up | Key_Down | Key_Left | Key_Right)
   end

   method handle_event(e)
      if \self.has_focus then {
         if e === Key_Up then
            parent.go_up(e)
         else if e === Key_Down then 
            parent.go_down(e)
      }
      self.TextField.handle_event(e)
   end
end

#
# This component functions in the same way as List above, but
# the item selected may be edited by the user.  An extra
# method is therefore supplied to get the content, as it may
# not correspond to an element of the list.
#
# A SELECTION_CHANGED_EVENT is generated when an item in the
# list is selected.  Also, the embedded textfield's
# CONTENT_CHANGED and ACTION_EVENT events are forwarded
# as though they were from this component itself.
#
class EditList : DropDown(
   tf,                      #          
   no_default               #
   )

   #
   # Set the text field's filter (see {TextField} for details).
   # @param c  The filter
   #
   method set_filter(c)
      return self.tf.set_filter(c)
   end

   method firstly()
      self.DropDown.firstly()
      if /self.no_default then {
         #
         # Initialize textfield to default, neither set_contents or set_selection
         # having been called.
         #
         tf.set_contents(self.selection_list[self.selection])
      }
   end

   #
   # Return the contents of the selected item (which may have
   # been edited).
   #
   method get_contents()
      return self.tf.get_contents()
   end

   #
   # Set the initial contents of the text to the given string.
   #
   method set_contents(x)
      self.no_default := 1
      return self.tf.set_contents(x)
   end

   method apply_selection()
      self.no_default := 1
      self.tf.set_contents(self.selection_list[self.selection])
   end

   method resize()
      local bw

      if /self.selection_list then
         fatal("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.compute_absolutes()

      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 TextField position and size
      #
      tf.set_pos(BORDER_WIDTH, BORDER_WIDTH)
      tf.set_size(self.w - bw - 2 * BORDER_WIDTH,  self.h - 2 * BORDER_WIDTH)
      tf.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)
      #
      # Draw button and list
      #
      self.b.display(1)
      self.tf.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 on_textfield(ev)
      # Fire the event with self as source.
      fire(ev.get_type(), ev)
   end

   method set_one(attr, val)
      case attr of {
         "selection" : set_selection(int_val(attr, val))
         "filter" : set_filter(cset_val(attr, val))
         "contents" : set_contents(string_val(attr, val))
         default: self.DropDown.set_one(attr, val)
      }
   end

   #
   # Manage our own focus/accelerator handling so that the textfield always gets the focus.
   #
   method find_focus()
      if self.is_unshaded() & self.in_region() & self.is_unhidden() then
         return tf
   end

   method find_accel(e)
      if self.Component.find_accel(e) then
         return tf
   end

   initially(a[])
      self.DropDown.initially()
      self.tf := EditListTextField()
      self.tf.set_parent(self)
      every self.tf.connect(self, "on_textfield", CONTENT_CHANGED_EVENT | ACTION_EVENT)
      self.tf.toggle_draw_border()
      self.add(tf)
      self.selection := 1
      set_fields(a)
end
