#
# $Id: menubutton.icn,v 1.3 2004/05/09 21:10:48 rparlett Exp $
#
# This file is in the public domain.
#
# Author: Robert Parlett (parlett@dial.pipex.com)
#

package gui
link graphics

$include "guih.icn"


#
# This is similar to {MenuBar}, but holds just a single
# drop-down menu, rather than several.  It may be placed anywhere on
# the dialog, whereas a {MenuBar} would invariably be placed along the top.
#
class MenuButton : Component(
   menu,                    #            
   img,                     #           
   is_open                  #
   )

   #
   # Set the menu to be displayed when the component is clicked.
   # @param c   The {Menu}.
   #
   method set_menu(c)
      return self.menu := c
   end

   #
   # Set the image to be displayed in the button.
   # @param x   The Icon to be displayed.
   #
   method set_img(x)
      return self.img := x
   end

   method finally()
      #
      # Disposing with menu open - just close menu
      #
      if \self.is_open then {
         self.set_which_open()
         self.unique_end()
      }
      self.Component.finally()
   end

   method display(buffer_flag)
      EraseRectangle(self.cbwin, self.x, self.y, self.w, self.h)
      DrawRaisedRectangle(self.cbwin, self.x, self.y, self.w, self.h)
      left_string(self.cbwin, self.x + DEFAULT_TEXT_X_SURROUND, self.y + self.h / 2, menu.get_label(), menu.get_accel())
      DrawImageEx(self.cbwin, self.x + 2 * DEFAULT_TEXT_X_SURROUND + TextWidth(self.cwin, menu.get_label()),  self.y + (self.h - img_height(self.img)) / 2, self.img)
      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

   #
   # Set the present open menu to x.  If x null, no menu open.
   #
   # @p
   method set_which_open(x)
      if self.is_open ~=== x then {
         (\self.is_open).hide()
         self.is_open := x
         (\self.is_open).display()
         self.display()
      }
      return x
   end

   method go_right()
   end

   method go_left()
   end

   method make_partial()
      set_which_open()
      self.unique_end()
   end

   method handle_press(e)
      if /self.is_open then {
         if self.in_region() then {
            self.unique_start()
            self.set_which_open(self.menu)
         }
      } else {
         if self.in_region() then {
            self.set_which_open()
            self.unique_end(1)
         } else {
            self.menu.handle_event(e)
         }
      }
   end

   method handle_release(e)
      if \self.is_open & not(in_region()) then
         self.menu.handle_event(e)
   end

   method handle_default(e)
      if /self.is_open then {
         if &meta & self.menu.accel === e then {
            self.unique_start()
            self.set_which_open(self.menu)
            self.menu.cursor_on()
         }
      } else {
         #
         # Menu bar open.  Let menu handle event.
         #
         self.menu.handle_event(e)
      }
   end

   method handle_event(e)
      if e === (&lpress | &rpress | &mpress) then 
         handle_press(e)
      else if e === (&lrelease | &rrelease | &mrelease) then 
         handle_release(e)
      else 
         handle_default(e)
   end

   method resize()
      #
      # Re-sized with menu open - just close menu
      #
      if \self.is_open then {
         self.set_which_open()
         self.unique_end()
      }

      if /self.menu then
         fatal("no menu set")

      /self.w_spec := TextWidth(self.cwin, self.menu.get_label()) + 3 * DEFAULT_TEXT_X_SURROUND + img_width(self.img)
      /self.h_spec := WAttrib(self.cwin, "fheight") +  2 * DEFAULT_TEXT_Y_SURROUND
      self.Component.resize()

      self.menu.set_parent_component(self)         
      self.menu.set_abs_coords(self.x, self.y + self.h)
      self.menu.size_label()
      self.menu.resize()
   end

   initially(a[])
      self.Component.initially()
      self.img := img_style("arrow_down")
      set_fields(a)
end