class Table < Shoes::Widget
#state = :enabled (default) or :disabled
#sets the table responsive or non-responsive to clicks
attr_writer :state
#selected - returns the number of the curently selected row
attr_reader :selected
#block - sets a new Proc object to be called when row is clicked
attr_writer :block
#Sets up the table
#top, left - position of the top and left corner of the table
#height - number of rows to show without the vertical scrolling bar
#headers - array of arrays containing headers and widths of the collumns)
# in the form of ["title", width]
#items - array of arrays containing data to be displayed
#blk - optional Proc object with a block to be called when the row is clicked
def initialize opts = {}
@block=opts[:blk]||nil
@selected=nil
@state=:enabled
@height=opts[:rows]
@items=opts[:items]
@headers=opts[:headers]
@columns=@headers.size
mult = @items.size > @height ? 1:0
debug(mult)
nostroke
@width=2
@item=[]
@headers.each { |x| @width+=(x[1]+1) }
nostroke
fill red
@top=opts[:top]
@left=opts[:left]
@rec=rect :top => 0, :left => 0, :width=>@width+mult*12+2, :height=>31*(@height+1)+4
@lefty=0
@header=flow do
@headers.each_with_index do |h,l|
temp=(l==@headers.size-1 ? h[1]+12*mult : h[1])
debug("#{l} -> #{temp}")
flow :top=>2,:left=>@lefty+2,:width=>temp,:height=>29 do
rect(:top=>0,:left=>1,:width=>temp,:height=>29, :fill=>lightgrey)
p=para strong(h[0]), :top=>2, :align=>'center'
@lefty+=h[1]+1
end
end
end
@flot1=stack :width=>@width+mult*12+2, :height=>31*(@height), :scroll=>true, :top=>33, :left=>1 do
@items.each_with_index do |it, i|
inscription " "
@item[i]=stack :width=>@width-1, :top=>31*i, :left=>1 do
@lefty=0
rr=[]
@columns.times do |ei|
rr[ei]=rect(:top=>1, :left=>@lefty+1, :width=>@headers[ei][1]-1,:height=>29, :fill=>white)
it[ei]=" " if not it[ei] or it[ei]==""
inscription strong(it[ei]), :top=>31*i+3, :left=>@lefty+2, :width=>@headers[ei][1]-1, :align=>'center'
@lefty+=@headers[ei][1]+1
end
hover do
if @state==:enabled
@item[i].contents.each{|x| x.style(:fill=>dimgray)}
end
end
leave do
if @state==:enabled
if @selected
if @selected==i
@item[i].contents.each{|x| x.style(:fill=>salmon)}
else
@item[i].contents.each{|x| x.style(:fill=>white)}
end
else
@item[i].contents.each{|x| x.style(:fill=>white)}
end
end
end
click do
if @state==:enabled
if @selected
if @selected==i
@item[i].contents.each{|x| x.style(:fill=>white)}
@selected=nil
else
@item[@selected].contents.each{|x| x.style(:fill=>white)}
@item[i].contents.each{|x| x.style(:fill=>salmon)}
@selected=i
end
else
@item[i].contents.each{|x| x.style(:fill=>salmon)}
@selected=i
end
@block.call @items[i] if @selected and @block
end
end
end
end
end
end
#-------------------------------
#Allows for manual selection of the row
def set_selected(item_no)
if @selected
@selected=item_no
@item[@selected].contents.each{|x| x.contents[1].style(:fill=>salmon)}
end
end
#Updates the current list of items shown in the table
# items - array of items to show
# height - height of table in rows
def update_items(items, height=items.size)
height=height if height<=items.size
@rec.remove
@header.remove
@flot1.remove
initialize(:top=>@top, :left=>@left,:rows=>height, :headers=>@headers, :items=>items, :blk=>@block)
end
end
Shoes.app do
@t=nil
@z=Proc.new {|x| alert x}
@y=Proc.new {|x| alert "Hej: #{x}"}
stack do
@t= table(:top=>50, :left=>10, :rows=>5, :headers=>[[:Title1, 80], [:Title2, 50], ["A Bit Loner Title", 200]],:items=>[[1,"","dssd"],["ererer",:mle,"ss"],[2,:ale,"sdsdsd"],[3,:ale,"ss"],[4,:mle,"ss"]], :blk=>@z)
end
b1=button "hide" do
@t.hide
end
b2=button "show" do
@t.show
end
b3=button "disable" do
@t.state=:disbled
end
b4=button "enable" do
@t.state=:enabled
end
b5=button "update" do
@t.update_items([[1,:esdfsdd,"dssd"],[4,:mal],[2,:fle,"sdsdsd"],[1,:mdfle,"dssd"],[4,:ale,"ss"],[2,:ale,"sdsdsd"]],4)
@t.block=@y
end
b1.move(10,250)
b2.move(70,250)
b3.move(130,250)
b4.move(220,250)
b5.move(290,250)
end