[Borges-users] TreeMenu Component
Kaspar Schiess
eule at space.ch
Wed Apr 14 21:08:15 EDT 2004
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hello all,
I have developed a small component that could be useful to everyone:
Rendering a main menu in hierarchical tree form.
Here's how to use this:
class MyComponent < Borges::Component
~ def initialize
~ @treemenu = Borges::TreeMenu.new
~ @treemenu.add('First Item') do inform('first item') end
~ s = @treemenu.add('Second Item') do inform('second item') end
~ s.add('First Child')
~ s.add('Second Child') do inform('second child') end
~ end
~ def render_content_on(r)
~ r.table do
~ r.table_row do
~ r.table_data do
~ r.render(@treemenu)
~ end
~ r.table_data do
~ # render content area here
~ end
~ end
~ end
~ end
end
Will result in a page that has two parts, left part will contain a tree
menu that looks like this:
First Item
Second Item
~ First Child
~ Second Child
Your comment is welcome.
kaspar - code philosopher
- -- stolen off the net --
The one day you'd sell your birthright for something, birthrights are
a glut.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFAfX4PFifl4CA0ImQRAhMBAKCQ0adCIzb8+sg40RFqt6otSAmnxQCggPQy
FDWI1h9kZ9z0uR3rl9b1rwc=
=fpyb
-----END PGP SIGNATURE-----
-------------- next part --------------
# A tree menu is a menu that has different levels of display.
# This for example could be a tree menu:
#
# First Item
# First Subitem
# Second Subitem
# Second Item
#
# Such a menu would be constructed by the following code:
#
# n1 = tree.add('First Item')
# tree.add('First Subitem', n1)
# tree.add('Second Subitem', n1)
# tree.add('Second Item')
#
# (Ident reflect meaning.) Now adding actions to that:
#
# n1 = tree.add('First Item') do puts 'first' end
# tree.add('First Subitem', n1)
# tree.add('Second Subitem', n1) do puts 'second sub' end
# tree.add('Second Item')
#
# Outputting the not so useful 'first' and 'second sub' strings
# to the console when clicked.
#
# The tree menu is rendered inside a component like this (of course):
#
# def render_content_on(r)
# ...
# r.render(@treemenu) # assuming your tree menu sits in @treemenu
# ...
# end
class Borges::TreeMenu
attr_reader :root, :selection
TreeItem = Struct.new('TreeItem',
:label, :block, :subs, :parent, :container
)
# support lazy adding
class TreeItem
def add(text, &block)
self.container.add(text, self, &block)
end
def clear
self.container.clear(self)
end
end
def initialize
@root = TreeItem.new(
'root', nil, [], nil, self
)
@selection = nil
end
def add(text, node=self.root, &block)
child = TreeItem.new(
text, block, [], node, self
)
node.subs << child
child
end
def clear(node=self.root)
node.subs.clear
end
def is_parent_of?(node, parent)
until node.nil?
return true if node == parent
node = node.parent
end
false
end
def item_action(subnode)
@selection = subnode
# node requested action
if subnode.block
if subnode.block.arity == 0
subnode.block.call
else
subnode.block.call(subnode)
end
end
end
private :item_action
def render_on(r, node=self.root, level=1)
r.css_class "menu#{level}"
r.div do
node.subs.each do |subnode|
if is_parent_of?(@selection, subnode)
if @selection == subnode
r.text(subnode.label)
else
r.anchor(subnode.label) do item_action(subnode) end
end
r.break
self.render_on(r, subnode, level+1)
else
# draw node that has not yet been selected
r.anchor(subnode.label) do item_action(subnode) end
r.break
end
end # node.each
end # div
end
end
More information about the Borges-users
mailing list