Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* ext/tk/lib/tkextlib/SUPPORT_STATUS: update to support libraries in
ActiveTcl8.4.12.0. * ext/tk/lib/tkextlib/tile/tnotebook.rb: add Tk::Tile::TNotebook#insert. * ext/tk/sample/tkextlib/tile/demo.rb: improve the look of a part of the demo. * ext/tk/sample/scrollframe.rb: add a new sample. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9669 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
- Loading branch information
nagai
committed
Dec 11, 2005
1 parent
5389506
commit 1ca94a0
Showing
5 changed files
with
266 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
# | ||
# Tk::ScrollFrame class | ||
# | ||
# This widget class is a frame widget with scrollbars. | ||
# The ScrollFrame doesn't propagate the size of embedded widgets. | ||
# When it is configured, scrollregion of the container is changed. | ||
# | ||
# Scrollbars can be toggled by Tk::ScrollFrame#vscroll & hscroll. | ||
# If horizontal or virtical scrollbar is turned off, the horizontal | ||
# or virtical size of embedded widgets is propagated. | ||
# | ||
# Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) | ||
# | ||
require 'tk' | ||
|
||
class Tk::ScrollFrame < TkFrame | ||
include TkComposite | ||
|
||
DEFAULT_WIDTH = 200 | ||
DEFAULT_HEIGHT = 200 | ||
|
||
def initialize_composite(keys={}) | ||
@frame.configure(:width=>DEFAULT_WIDTH, :height=>DEFAULT_HEIGHT) | ||
|
||
# create scrollbars | ||
@h_scroll = TkScrollbar.new(@frame, 'orient'=>'horizontal') | ||
@v_scroll = TkScrollbar.new(@frame, 'orient'=>'vertical') | ||
|
||
# create a canvas widget | ||
@canvas = TkCanvas.new(@frame, | ||
:borderwidth=>0, :selectborderwidth=>0, | ||
:highlightthickness=>0) | ||
|
||
# allignment | ||
TkGrid.rowconfigure(@frame, 0, 'weight'=>1, 'minsize'=>0) | ||
TkGrid.columnconfigure(@frame, 0, 'weight'=>1, 'minsize'=>0) | ||
@canvas.grid('row'=>0, 'column'=>0, 'sticky'=>'news') | ||
@frame.grid_propagate(false) | ||
|
||
# assign scrollbars | ||
@canvas.xscrollbar(@h_scroll) | ||
@canvas.yscrollbar(@v_scroll) | ||
|
||
# convert hash keys | ||
keys = _symbolkey2str(keys) | ||
|
||
# check options for the frame | ||
framekeys = {} | ||
if keys.key?('classname') | ||
keys['class'] = keys.delete('classname') | ||
end | ||
if @classname = keys.delete('class') | ||
framekeys['class'] = @classname | ||
end | ||
if @colormap = keys.delete('colormap') | ||
framekeys['colormap'] = @colormap | ||
end | ||
if @container = keys.delete('container') | ||
framekeys['container'] = @container | ||
end | ||
if @visual = keys.delete('visual') | ||
framekeys['visual'] = @visual | ||
end | ||
if @classname.kind_of? TkBindTag | ||
@db_class = @classname | ||
@classname = @classname.id | ||
elsif @classname | ||
@db_class = TkDatabaseClass.new(@classname) | ||
else | ||
@db_class = self.class | ||
@classname = @db_class::WidgetClassName | ||
end | ||
|
||
# create base frame | ||
@base = TkFrame.new(@canvas, framekeys) | ||
|
||
# embed base frame | ||
@cwin = TkcWindow.new(@canvas, [0, 0], :window=>@base, :anchor=>'nw') | ||
@canvas.scrollregion(@cwin.bbox) | ||
|
||
# binding to reset scrollregion | ||
@base.bind('Configure'){ _reset_scrollregion(nil, nil) } | ||
|
||
# set default receiver of method calls | ||
@path = @base.path | ||
|
||
# scrollbars ON | ||
vscroll(keys.delete('vscroll'){true}) | ||
hscroll(keys.delete('hscroll'){true}) | ||
|
||
# please check the differences of the following definitions | ||
option_methods( | ||
:scrollbarwidth | ||
) | ||
|
||
# set receiver widgets for configure methods (with alias) | ||
delegate_alias('scrollbarrelief', 'relief', @h_scroll, @v_scroll) | ||
|
||
# set receiver widgets for configure methods | ||
delegate('DEFAULT', @base) | ||
delegate('background', @frame, @base, @canvas, @h_scroll, @v_scroll) | ||
delegate('width', @frame) | ||
delegate('height', @frame) | ||
delegate('activebackground', @h_scroll, @v_scroll) | ||
delegate('troughcolor', @h_scroll, @v_scroll) | ||
delegate('repeatdelay', @h_scroll, @v_scroll) | ||
delegate('repeatinterval', @h_scroll, @v_scroll) | ||
delegate('borderwidth', @frame) | ||
delegate('relief', @frame) | ||
|
||
# do configure | ||
configure keys unless keys.empty? | ||
end | ||
|
||
# callback for Configure event | ||
def _reset_scrollregion(h_mod=nil, v_mod=nil) | ||
cx1, cy1, cx2, cy2 = @canvas.scrollregion | ||
x1, y1, x2, y2 = @cwin.bbox | ||
@canvas.scrollregion([x1, y1, x2, y2]) | ||
|
||
if h_mod.nil? && v_mod.nil? | ||
if x2 != cx2 && TkGrid.info(@h_scroll).size == 0 | ||
@frame.grid_propagate(true) | ||
@canvas.width = x2 | ||
Tk.update_idletasks | ||
@frame.grid_propagate(false) | ||
end | ||
if y2 != cy2 && TkGrid.info(@v_scroll).size == 0 | ||
@frame.grid_propagate(true) | ||
@canvas.height = y2 | ||
Tk.update_idletasks | ||
@frame.grid_propagate(false) | ||
end | ||
else | ||
@h_scroll.ungrid if h_mod == false | ||
@v_scroll.ungrid if v_mod == false | ||
|
||
h_flag = (TkGrid.info(@h_scroll).size == 0) | ||
v_flag = (TkGrid.info(@v_scroll).size == 0) | ||
|
||
@frame.grid_propagate(true) | ||
|
||
@canvas.width = (h_flag)? x2: @canvas.winfo_width | ||
@canvas.height = (v_flag)? y2: @canvas.winfo_height | ||
|
||
@h_scroll.grid('row'=>1, 'column'=>0, 'sticky'=>'ew') if h_mod | ||
@v_scroll.grid('row'=>0, 'column'=>1, 'sticky'=>'ns') if v_mod | ||
|
||
Tk.update_idletasks | ||
|
||
@frame.grid_propagate(false) | ||
end | ||
end | ||
private :_reset_scrollregion | ||
|
||
# forbid to change binding of @base frame | ||
def bind(*args) | ||
@frame.bind(*args) | ||
end | ||
def bind_append(*args) | ||
@frame.bind_append(*args) | ||
end | ||
def bind_remove(*args) | ||
@frame.bind_remove(*args) | ||
end | ||
def bindinfo(*args) | ||
@frame.bindinfo(*args) | ||
end | ||
|
||
# set width of scrollbar | ||
def scrollbarwidth(width = nil) | ||
if width | ||
@h_scroll.width(width) | ||
@v_scroll.width(width) | ||
else | ||
@h_scroll.width | ||
end | ||
end | ||
|
||
# vertical scrollbar : ON/OFF | ||
def vscroll(mode) | ||
Tk.update_idletasks | ||
st = TkGrid.info(@v_scroll) | ||
if mode && st.size == 0 then | ||
@v_scroll.grid('row'=>0, 'column'=>1, 'sticky'=>'ns') | ||
_reset_scrollregion(nil, true) | ||
elsif !mode && st.size != 0 then | ||
_reset_scrollregion(nil, false) | ||
else | ||
_reset_scrollregion(nil, nil) | ||
end | ||
self | ||
end | ||
|
||
# horizontal scrollbar : ON/OFF | ||
def hscroll(mode) | ||
Tk.update_idletasks | ||
st = TkGrid.info(@h_scroll) | ||
if mode && st.size == 0 then | ||
_reset_scrollregion(true, nil) | ||
elsif !mode && st.size != 0 then | ||
_reset_scrollregion(false, nil) | ||
else | ||
_reset_scrollregion(nil, nil) | ||
end | ||
self | ||
end | ||
end | ||
|
||
# test | ||
if __FILE__ == $0 | ||
f = Tk::ScrollFrame.new(:scrollbarwidth=>10, :width=>300, :height=>200) | ||
f.pack(:expand=>true, :fill=>:both) | ||
|
||
TkButton.new(f, :text=>'foo button', :command=>proc{puts 'foo'}).pack | ||
TkButton.new(f, :text=>'baaar button', :command=>proc{puts 'baaar'}).pack | ||
TkButton.new(f, :text=>'baz button', :command=>proc{puts 'baz'}).pack | ||
TkButton.new(f, :text=>'hoge hoge button', | ||
:command=>proc{puts 'hoge hoge'}).pack(:side=>:bottom) | ||
|
||
# f.hscroll(false) | ||
|
||
Tk.after(3000){ | ||
t = TkText.new(f).pack(:expand=>true, :fill=>:both) | ||
t.insert(:end, 'Here is a text widget') | ||
} | ||
|
||
Tk.after(6000){ f.vscroll(false) } | ||
|
||
Tk.after(9000){ f.vscroll(true) } | ||
|
||
Tk.after(12000){ f.hscroll(false) } | ||
|
||
Tk.after(15000){ f.hscroll(true) } | ||
|
||
Tk.mainloop | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters