# # $Id: menucomponent.icn,v 1.5 2004/06/27 16:20:28 rparlett Exp $ # # This file is in the public domain. # # Author: Robert Parlett (parlett@dial.pipex.com) # package gui link graphics import lang import util $include "guih.icn" # # This is the superclass of all the objects that make up the # menu system (other than the top level {Components} of course). # It encapsulates the basic labels and images to display a menu # item. The functionality of an actual menu is in the subclass, # {SubMenu}. # class MenuComponent : SetFields : Connectable: Object( label, # label_x, # label_y, # label_h, # label_left_w, # label_right_w, # label_mid_w, # is_sub_menu_flag, # parent_component, # is_shaded_flag, # label_left, # img_left, # img_left_h, # img_left_w, # label_right, # img_right, # img_right_h, # img_right_w, # parent, # accel ) method fatal(s) stop("gui : error whilst processing object " || lang::get_class_name(self) || " : " || s) end method set_parent(x) return self.parent := x end # # Set the optional left label to the given string. # method set_label_left(x) self.label_left := x possibly_invalidate() end # # Set the optional right label to the given string. # method set_label_right(x) self.label_right := x possibly_invalidate() end # # Set the optional left image to the given Icon image. # method set_img_left(x) self.img_left := x self.img_left_w := img_width(self.img_left) self.img_left_h := img_height(self.img_left) possibly_invalidate() end # # Set the optional right image to the given Icon image. # method set_img_right(x) self.img_right := x self.img_right_w := img_width(self.img_right) self.img_right_h := img_height(self.img_right) possibly_invalidate() end # # Succeed iff the component is shaded # method is_shaded() return \self.is_shaded_flag end # # Toggle whether or not the item is shaded. If it is, it is # displayed in a filtered way and will not accept input. # method toggle_is_shaded() if /self.is_shaded_flag then self.is_shaded_flag := 1 else self.is_shaded_flag := &null possibly_invalidate() end # # Set the shaded status of the component to shaded. # method set_is_shaded() self.is_shaded_flag := 1 possibly_invalidate() end # # Set the shaded status of the component to not shaded. # method clear_is_shaded() self.is_shaded_flag := &null possibly_invalidate() end # # Invalidate the parent {Component} if this is the root of the menu hierarchy. # method possibly_invalidate() if /self.parent then (\self.parent_component).invalidate() end method set_parent_component(x) return self.parent_component := x end method is_sub_menu() return \self.is_sub_menu_flag end # # Get the label. # method get_label() return self.label end # # Set the centre label to the given string. # method set_label(x) return self.label := x end # # Display the label at its position using the given widths for the left, middle # and right elements. # method display_label(lw, mw, rw) cw := self.parent_component.cbwin # # Draw the left label or image # if \self.label_left then left_string(cw, self.label_x + DEFAULT_TEXT_X_SURROUND, self.label_y + self.label_h / 2, self.label_left) else if \self.img_left then DrawImageEx(cw, self.label_x + DEFAULT_TEXT_X_SURROUND, self.label_y + (self.label_h - img_left_h) / 2, img_left) # # Draw the right label or image # if \self.label_right then left_string(cw, self.label_x + lw + mw, self.label_y + self.label_h / 2, self.label_right) else if \self.img_right then DrawImageEx(cw, self.label_x + lw + mw, self.label_y + (self.label_h - img_right_h) / 2, img_right) # # Draw the centre label # left_string(cw, self.label_x + lw + DEFAULT_TEXT_X_SURROUND, self.label_y + self.label_h / 2, self.label, self.accel) # # Filter if shaded # if \self.is_shaded_flag then FilterRectangle(cw, self.label_x, self.label_y, mw + lw + rw, self.label_h) end # # Set the mnemonic key, which will be used with the Alt key to provide keyboard # shortcuts. # method set_accel(k) self.accel := k end # # Get the mnemonic key. # method get_accel() return self.accel end # # Invoked by the menu system to set the component's label position. # method set_label_pos(x, y) self.label_x := x self.label_y := y end # # Close the menu system, possibly discarding the current event. # method close_all(discard) parent_component.set_which_open() parent_component.unique_end(discard) end # # Called when the menu component is selected # method succeed(ev) close_all(1) fire(ACTION_EVENT, ev) end # # Compute the size fields. # method size_label() cw := self.parent_component.cwin if /self.label then fatal("no label specified") self.label_h := WAttrib(cw, "fheight") + 2 * DEFAULT_TEXT_Y_SURROUND # # Set the left hand sizes; the left hand label has DEFAULT_TEXT_X_SURROUND to its left. # if \self.label_left then self.label_left_w := TextWidth(cw, self.label_left) + DEFAULT_TEXT_X_SURROUND else if \self.img_left then { self.label_left_w := self.img_left_w + DEFAULT_TEXT_X_SURROUND self.label_h <:= self.img_left_h + 2 * DEFAULT_TEXT_Y_SURROUND } else self.label_left_w := 0 # # Set the right hand sizes; this has DEFAULT_TEXT_X_SURROUND to its right. # if \self.label_right then self.label_right_w := TextWidth(cw, self.label_right) + DEFAULT_TEXT_X_SURROUND else if \self.img_right then { self.label_right_w := self.img_right_w + DEFAULT_TEXT_X_SURROUND self.label_h <:= self.img_right_h + 2 * DEFAULT_TEXT_Y_SURROUND } else self.label_right_w := 0 # # Space for the string and DEFAULT_TEXT_X_SURROUND either side. # self.label_mid_w := TextWidth(cw, self.label) + 2 * DEFAULT_TEXT_X_SURROUND end method set_one(attr, val) case attr of { "label" : set_label(string_val(attr, val)) "label_left" : set_label_left(string_val(attr, val)) "label_right" : set_label_right(string_val(attr, val)) "accel" : set_accel(string_val(attr, val)) "is_shaded" : if test_flag(attr, val) then set_is_shaded() else clear_is_shaded() default : field_error("Unknown attribute " || attr) } end initially() self.Connectable.initially() end