#
# $Id: circulate.icn,v 1.5 2004/11/11 19:53:42 rparlett Exp $
#
# This file is in the public domain.
#
# Author: Robert Parlett (parlett@dial.pipex.com)
#

package gui
link graphics

$include "guih.icn"

class CirculateLabel:Label()
   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)
      }
   end
end

#
# Selection from a list
#
class Circulate : Component(selection, selection_list, b, l)
   #
   # Set the list from which selections are made.
   #
   # @param x the list of selection strings
   #
   method set_selection_list(x)
      self.selection_list := x
      self.set_selection(1)
      return x
   end

   #
   # Set the selection to the given index into the selection
   # list.
   #
   # @param x an index into the selection list
   #
   method set_selection(x)
      self.selection := x
      self.l.set_label(self.selection_list[self.selection])
      self.invalidate()
      return x
   end

   #
   # Return the current selection, as an index in the selection list.
   #
   # @return an integer, being the current selection
   #
   method get_selection()
      return self.selection
   end

   #
   # Called once at startup, and whenever the window is resized.
   #
   # @p
   method resize()
      /self.h_spec := WAttrib(self.cwin, "fheight") + 16
      compute_absolutes()

      #
      # Set button position and size
      #
      b.set_pos(BORDER_WIDTH, BORDER_WIDTH)
      b.set_size(self.h - 2 * BORDER_WIDTH, self.h - 2 * BORDER_WIDTH)
      b.resize()

      l.set_pos(self.h - BORDER_WIDTH + DEFAULT_TEXT_X_SURROUND, self.h / 2)
      l.set_align("l", "c")
      l.set_size(self.w - self.h - 2 * DEFAULT_TEXT_X_SURROUND, self.h - 2 * BORDER_WIDTH)
      l.resize()

      return
   end

   #
   # Display the object.  In this case, double buffering is not
   # necessary.
   #
   # @p
   method display(buffer_flag)
      EraseRectangle(self.cbwin, self.x, self.y, self.w, self.h)
      DrawSunkenRectangle(self.cbwin, self.x, self.y, self.w, self.h)
      l.display(1)
      b.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

   #
   # The handler for the button - move the selection forward.
   #
   # @p
   method on_button_pressed(ev)
      go_up(ev)
   end

   method go_up(e)
      if self.selection = 1 then
         set_selection(*self.selection_list)
      else
         self.set_selection(self.selection - 1)
      fire(SELECTION_CHANGED_EVENT, e)
   end

   method go_down(ev)
      set_selection(1 + self.selection % *self.selection_list)
      fire(SELECTION_CHANGED_EVENT, e)
   end

   method set_one(attr, val)
      case attr of {
         "selection" : set_selection(int_val(attr, val))
         "selection_list" : set_selection_list(val)
         default: self.Component.set_one(attr, val)
      }
   end

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

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

   initially(a[]) 
      self.Component.initially()
      self.l := CirculateLabel()
      self.l.clear_draw_border()
      self.l.set_accepts_focus()
      add(self.l)
      self.b := IconButton()
      self.b.clear_accepts_focus()
      self.b.connect(self, "on_button_pressed", ACTION_EVENT)
      add(self.b)
      b.set_draw_border()
      self.b.set_img("13,c1,_
~~~~0000~~~~~_
~~~000000~~~~_
~~00~~~~00~~~_
~00~~~~~~00~~_
~00~~~~~~00~~_
~00~~~~~~~~~~_
~00~~~~~~~~~~_
~00~~~~~~0~~~_
~00~~~~~000~~_
~00~~~~00000~_
~00~~~0000000_
~00~~~~~~00~~_
~00~~~~~~00~~_
~00~~~~~~00~~_
~~00~~~~00~~~_
~~~000000~~~~_
~~~~0000~~~~~_
")
      set_fields(a)
end