mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
171 lines
4.2 KiB
Ruby
171 lines
4.2 KiB
Ruby
|
#
|
||
|
# tkalignbox.rb : align widgets with same width/height
|
||
|
#
|
||
|
# by Hidetoshi NAGAI
|
||
|
#
|
||
|
# The box size depends on 'reqheight' and 'reqwidth' of contained widgets.
|
||
|
# If you want to give the box size when those requested sizes are 0,
|
||
|
# please set box.propagate = false (See the test routine at the tail of
|
||
|
# this file).
|
||
|
|
||
|
require 'tk'
|
||
|
|
||
|
class TkAlignBox < TkFrame
|
||
|
def initialize(*args)
|
||
|
super(*args)
|
||
|
@max_width = 0
|
||
|
@max_height = 0
|
||
|
@propagate = true
|
||
|
@widgets = []
|
||
|
end
|
||
|
|
||
|
def _set_framesize
|
||
|
fail RuntimeError, "TkAlignBox is an abstruct class"
|
||
|
end
|
||
|
private :_set_framesize
|
||
|
|
||
|
def _place_config(widget, idx, cnt)
|
||
|
fail RuntimeError, "TkAlignBox is an abstruct class"
|
||
|
end
|
||
|
private :_place_config
|
||
|
|
||
|
def align
|
||
|
widgets = []
|
||
|
@widgets.each{|w| widgets << w if w.winfo_exist?}
|
||
|
@widgets = widgets
|
||
|
cnt = @widgets.size.to_f
|
||
|
@widgets.each_with_index{|w, idx| _place_config(w, idx, cnt)}
|
||
|
@widgets = widgets
|
||
|
_set_framesize if @propagate
|
||
|
self
|
||
|
end
|
||
|
|
||
|
def add(*widgets)
|
||
|
widgets.each{|w|
|
||
|
unless w.kind_of? TkWindow
|
||
|
fail RuntimeError, "#{w.inspect} is not a widget instance."
|
||
|
end
|
||
|
@widgets.delete(w)
|
||
|
@widgets << w
|
||
|
sz = w.winfo_reqwidth
|
||
|
@max_width = sz if @max_width < sz
|
||
|
sz = w.winfo_reqheight
|
||
|
@max_height = sz if @max_height < sz
|
||
|
}
|
||
|
align
|
||
|
self
|
||
|
end
|
||
|
|
||
|
def <<(widget)
|
||
|
add(widget)
|
||
|
end
|
||
|
|
||
|
def insert(idx, widget)
|
||
|
unless widget.kind_of? TkWindow
|
||
|
fail RuntimeError, "#{widget.inspect} is not a widget instance."
|
||
|
end
|
||
|
@widgets.delete(widget)
|
||
|
@widgets[idx,0] = widget
|
||
|
sz = widget.winfo_reqwidth
|
||
|
@max_width = sz if @max_width < sz
|
||
|
sz = widget.winfo_reqheight
|
||
|
@max_height = sz if @max_height < sz
|
||
|
align
|
||
|
self
|
||
|
end
|
||
|
|
||
|
def delete(idx)
|
||
|
ret = @widgets.delete_at(idx)
|
||
|
@req_size = 0
|
||
|
@widget.each{|w|
|
||
|
sz = w.winfo_reqwidth
|
||
|
@max_width = sz if @max_width < sz
|
||
|
sz = w.winfo_reqheight
|
||
|
@max_height = sz if @max_height < sz
|
||
|
}
|
||
|
align
|
||
|
ret
|
||
|
end
|
||
|
|
||
|
attr_accessor :propagate
|
||
|
end
|
||
|
|
||
|
class TkHBox < TkAlignBox
|
||
|
def _set_framesize
|
||
|
bd = self.borderwidth
|
||
|
self.width(@max_width * @widgets.size + 2 * bd)
|
||
|
self.height(@max_height + 2 * bd)
|
||
|
end
|
||
|
def _place_config(widget, idx, cnt)
|
||
|
widget.place_in(self, 'relx'=>idx/cnt, 'relwidth'=>1.0/cnt,
|
||
|
'relheight'=>1.0)
|
||
|
end
|
||
|
end
|
||
|
TkHLBox = TkHBox
|
||
|
|
||
|
class TkHRBox < TkHBox
|
||
|
def _place_config(widget, idx, cnt)
|
||
|
widget.place_in(self, 'relx'=>(cnt - idx - 1)/cnt, 'relwidth'=>1.0/cnt,
|
||
|
'relheight'=>1.0)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
class TkVBox < TkAlignBox
|
||
|
def _set_framesize
|
||
|
self.width(@max_width + 2 * bd)
|
||
|
self.height(@max_height * @widgets.size + 2 * bd)
|
||
|
end
|
||
|
def _place_config(widget, idx, cnt)
|
||
|
widget.place_in(self, 'rely'=>idx/cnt, 'relheight'=>1.0/cnt,
|
||
|
'relwidth'=>1.0)
|
||
|
end
|
||
|
end
|
||
|
TkVTBox = TkVBox
|
||
|
|
||
|
class TkVBBox < TkVBox
|
||
|
def _place_config(widget, idx, cnt)
|
||
|
widget.place_in(self, 'rely'=>(cnt - idx - 1)/cnt, 'relheight'=>1.0/cnt,
|
||
|
'relwidth'=>1.0)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
################################################
|
||
|
# test
|
||
|
################################################
|
||
|
if __FILE__ == $0
|
||
|
f = TkHBox.new(:borderwidth=>3, :relief=>'ridge').pack
|
||
|
f.add(TkButton.new(f, :text=>'a'),
|
||
|
TkButton.new(f, :text=>'aa', :font=>'Helvetica 16'),
|
||
|
TkButton.new(f, :text=>'aaa'),
|
||
|
TkButton.new(f, :text=>'aaaa'))
|
||
|
|
||
|
f = TkVBox.new(:borderwidth=>5, :relief=>'groove').pack
|
||
|
f.add(TkButton.new(f, :text=>'a'),
|
||
|
TkButton.new(f, :text=>'aa', :font=>'Helvetica 30'),
|
||
|
TkButton.new(f, :text=>'aaa'),
|
||
|
TkButton.new(f, :text=>'aaaa'))
|
||
|
|
||
|
f = TkHRBox.new(:borderwidth=>3, :relief=>'raised').pack(:fill=>:x)
|
||
|
f.add(TkButton.new(f, :text=>'a'),
|
||
|
TkButton.new(f, :text=>'aa'),
|
||
|
TkButton.new(f, :text=>'aaa'))
|
||
|
|
||
|
f = TkVBBox.new(:borderwidth=>3, :relief=>'ridge').pack(:fill=>:x)
|
||
|
f.propagate = false
|
||
|
f.height 100
|
||
|
f.add(TkFrame.new(f){|ff|
|
||
|
TkButton.new(ff, :text=>'a').pack(:pady=>4, :padx=>6,
|
||
|
:fill=>:both, :expand=>true)
|
||
|
},
|
||
|
TkFrame.new(f){|ff|
|
||
|
TkButton.new(ff, :text=>'aa').pack(:pady=>4, :padx=>6,
|
||
|
:fill=>:both, :expand=>true)
|
||
|
},
|
||
|
TkFrame.new(f){|ff|
|
||
|
TkButton.new(ff, :text=>'aaaa').pack(:pady=>4, :padx=>6,
|
||
|
:fill=>:both, :expand=>true)
|
||
|
})
|
||
|
|
||
|
Tk.mainloop
|
||
|
end
|