#
# $Id: border.icn,v 1.3 2004/05/15 19:17:29 rparlett Exp $
#
# This file is in the public domain.
#
# Author: Robert Parlett (parlett@dial.pipex.com)
#

package gui
link graphics

$include "guih.icn"

#
# This class provides decorative borders.  Optionally, a
# single other component can be the title of the Border.  This
# would normally be a Label object, but it could also be a
# CheckBox or an Icon, or whatever is desired.
#
# @example
# @ b := Border()
# @
# @ # Add a Label as the title
# @
# @ l := Label()
# @ l.set_label("Title String")
# @ b.set_title(l)
# @ self.add(b)
#
class Border : Panel(
   internal_alignment, 
   title_obj,
   y1,
   h1
   )

   #
   # Set the alignment of the title object.  The input string should be
   # ``l'', ``c'' or ``r''.
   #
   method set_internal_alignment(x)
      return self.internal_alignment := x
   end

   #
   # Set the title object to c.
   #
   method set_title(c)
      title_obj := c
      add(c)
   end

   method display(buffer_flag)
      W := if /buffer_flag then self.cwin else self.cbwin

      EraseRectangle(W, self.x, self.y, self.w, self.h)
      DrawSunkenRectangle(W, self.x, y1, self.w, h1)
      DrawRaisedRectangle(W, self.x + BORDER_WIDTH, y1 + BORDER_WIDTH, self.w - 2 * BORDER_WIDTH, h1 - 2 * BORDER_WIDTH)

      if \title_obj then {
         case self.internal_alignment of {
            "c" : EraseRectangle(W, self.x + self.w / 2 - title_obj.w / 2 - BORDER_TEXT_SPACING, y1, title_obj.w + 2 * BORDER_TEXT_SPACING, 2 * BORDER_WIDTH)
            "l" : EraseRectangle(W, self.x + DEFAULT_TEXT_X_SURROUND, y1, title_obj.w + 2 * BORDER_TEXT_SPACING, 2 * BORDER_WIDTH)
            "r" : EraseRectangle(W, self.x + self.w - title_obj.w - DEFAULT_TEXT_X_SURROUND - 2 * BORDER_TEXT_SPACING, y1, title_obj.w + 2 * BORDER_TEXT_SPACING, 2 * BORDER_WIDTH)
         }         
      }

      every (!self.children).display(buffer_flag)
      self.do_shading(W)
   end

   method get_y_reference()
      return self.y1
   end

   method get_h_reference()
      return self.h1
   end

   method compute_absolutes()
      self.Component.compute_absolutes()
      y1 := self.y
      h1 := self.h
      if \title_obj then {
         title_obj.set_align(self.internal_alignment, "c")
         case self.internal_alignment of {
            "c" : title_obj.set_pos("50%", 0)
            "l" : title_obj.set_pos(DEFAULT_TEXT_X_SURROUND + BORDER_TEXT_SPACING, 0)
            "r" : title_obj.set_pos("100%-" || (DEFAULT_TEXT_X_SURROUND + BORDER_TEXT_SPACING), 0)
            default : fatal("incorrect internal_alignment specifier:" || image(self.internal_alignment))
         }
         #
         # Resize title_obj to work out y1, h1; note that title_obj will be resized again below
         # using the new y1, h1.
         #
         title_obj.resize()
         y1 := self.y + title_obj.h / 2
         h1 := self.h - title_obj.h / 2
      }
   end

   method set_one(attr, val)
      case attr of {
         "internal_alignment" : set_internal_alignment(string_val(attr, val))
         default: self.Panel.set_one(attr, val)
      }
   end

   initially(a[])
      self.Panel.initially()
      self.internal_alignment := "l"
      set_fields(a)
end