# $Id: menubar.icn,v 1.1 2003-05-31 06:09:03 jeffery Exp $
##
# This class is the base from which menu systems are created,
# other than popup menus.
#
# Menu items are added to this class; they are not separate
# components added to the dialog itself.
#
# The default position is (0, 0); the default size is 100% of
# the width of the screen and a reasonable height based on the
# font specified.
#
class MenuBar : Component(
which_open,
menus
)
##
# Add the {Menu} c to the {MenuBar}. This will be one drop down
# menu. Items are then added to the {Menu}.
# @param c The {Menu} to add.
#
method add(c)
put(self.menus, c)
end
method finally(was_closed)
#
# Disposing with menu open - just close menu
#
if \self.which_open & /was_closed then {
self$set_which_open()
self$unique_end()
}
self$Component.finally()
end
method display(buffer_flag)
local m
EraseRectangle(self.cbwin, self.x, self.y, self.w, self.h)
DrawRaisedRectangle(self.cbwin, self.x, self.y, self.w, self.h,1)
#
# Draw the menu options with a raised rectangle around the open menu. m.label_mid_w gives the space for
# the menu label, which includes DEFAULT_TEXT_X_SURROUND either side of the label itself. m.label_x is the x position, so
# m.label_x + DEFAULT_TEXT_X_SURROUND put the string in the centre of its area.
#
every m := !menus do {
if m === \self.which_open then
DrawRaisedRectangle(self.cbwin, m.label_x, self.y + BORDER_WIDTH, m.label_mid_w, self.h - 2 * BORDER_WIDTH,1)
left_string(self.cbwin, m.label_x + DEFAULT_TEXT_X_SURROUND, self.y + self.h / 2, m$get_label())
if \m.is_shaded_flag then
FilterRectangle(self.cbwin, m.label_x, self.y + BORDER_WIDTH, m.label_mid_w, self.h - 2 * BORDER_WIDTH)
}
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
#
# Determine which of the menu labels is selected, if any. Assumes y pos already tested and in menu bar.
#
method which_button()
local m
every m := !self.menus do {
if /m.is_shaded_flag & m.label_x <= &x < m.label_x + m.label_mid_w then
return m
}
end
#
# Set the present open menu to x. If x null, no menu open.
#
method set_which_open(x)
#
# Do nothing if x presently open
#
if self.which_open ~=== x then {
(\self.which_open)$hide()
self.which_open := x
(\self.which_open)$display()
self$display()
}
return x
end
method handle_event(e)
local t, r
if self$in_region() then {
if integer(e) = (&lpress | &rpress | &mpress) then {
if t := which_button() then {
#
# Pressed on a label - open the menu, starting unique mode if needed.
#
if /self.which_open then
self$unique_start()
if t === self.which_open then {
#
# Clicked on menu already open - close all
#
self$set_which_open()
self$unique_end(1)
} else
self$set_which_open(t)
} else {
self$set_which_open()
self$unique_end(1)
}
} else if integer(e) = (&lrelease | &rrelease | &mrelease) & \self.which_open then {
#
# Released with menu open. If not on a label then close menu
#
if not(t := which_button()) then {
self$set_which_open()
self$unique_end(1)
}
} else if integer(e) = (&ldrag | &rdrag | &mdrag) & \self.which_open then {
#
# Drag onto a label with menu open
#
if t := which_button() then {
if t === self.which_open then
#
# Make present menu blank
#
t$set_which_open()
else
self$set_which_open(t)
} else
#
# Drag with menu open, but not on a label, blank present menu leaving
# sub menus open
#
self.which_open$hide_non_menu()
}
} else if \self.which_open then {
#
# Not on menu bar, but menu bar open. Let menu handle event.
#
r := self.which_open$handle_event(e)
case r$get_menu_code() of {
FAIL_1 : {
#
# Fail; don't pass event on to other components.
#
self$set_which_open()
self$unique_end(1)
fail
}
FAIL_2 : {
#
# Fail and pass event on to other components.
#
self$set_which_open()
self$unique_end()
fail
}
CONTINUE :
#
# Fail, but keep unique status.
#
fail
SUCCEED : {
#
# Succeed with event.
#
self$set_which_open()
self$unique_end(1)
return r
}
default : stop("internal error")
}
}
end
method resize()
local m, px
#
# Re-sized with menu open - just close menu
#
if \self.which_open then {
self$set_which_open()
self$unique_end()
}
/self.x_spec := 0
/self.y_spec := 0
/self.w_spec := "100%"
/self.h_spec := WAttrib(self.cwin, "fheight") + 2 * DEFAULT_TEXT_Y_SURROUND
self$Component.resize()
#
# Compute x, y for each sub-menu
#
px := self.x + BORDER_WIDTH
every m := !self.menus do {
m$set_parent_menu_bar(self)
m$set_abs_coords(px, self.y + self.h)
m$set_label_pos(px, self.y + BORDER_WIDTH)
m$set_label_size()
px +:= m.label_mid_w
m$resize()
}
end
initially(argv[])
self$Component.initially()
self.menus := []
if *argv > 0 then set_fields(argv)
end
This page produced by UniDoc on 2021/04/15 @ 23:59:43.