mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/tk/lib/tk/itemconfig.rb: bug fix on 'itemconfiginfo' method, and
modify to make it easy to override 'itemconfiginfo' method. * ext/tk/lib/tkextlib/tile/treeview.rb : support Tile 0.7.8. * ext/tk/lib/tkextlib/version.rb : [new] add Tk::Tkextlib_RELEASE_DATE to get the information from scripts. * ext/tk/lib/tk.rb: load 'tkextlib/version.rb', and update RELEASE_DATE. * ext/tk/lib/tkextlib/SUPPORT_STATUS: update. * ext/tk/sample/editable_listbox.rb: [new] the listbox with editable items. It's one of the example about usage of Place geometry manager. * ext/tk/sample/tktextio.rb: improve the functions of TkTextIO class. Those are required by 'irbtkw.rbw'. * ext/tk/sample/irbtkw.rbw: [new] IRB on Ruby/Tk. It doesn't need any real console. IRB works on a text widget without I/O blocking. That is, thread switching on IRB will work properly, even if on Windows. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11283 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
ced53248ff
commit
2ec88c167b
10 changed files with 1692 additions and 206 deletions
25
ChangeLog
25
ChangeLog
|
@ -1,3 +1,28 @@
|
|||
Mon Nov 6 15:41:55 2006 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
||||
|
||||
* ext/tk/lib/tk/itemconfig.rb: ext/tk/lib/tk/itemconfig.rb: bug
|
||||
fix on 'itemconfiginfo' method, and modify to make it easy to
|
||||
override 'itemconfiginfo' method.
|
||||
|
||||
* ext/tk/lib/tkextlib/tile/treeview.rb : support Tile 0.7.8.
|
||||
|
||||
* ext/tk/lib/tkextlib/version.rb : [new] add Tk::Tkextlib_RELEASE_DATE
|
||||
to get the information from scripts.
|
||||
|
||||
* ext/tk/lib/tk.rb: load 'tkextlib/version.rb', and update RELEASE_DATE
|
||||
|
||||
* ext/tk/lib/tkextlib/SUPPORT_STATUS: update.
|
||||
|
||||
* ext/tk/sample/editable_listbox.rb: [new] the listbox with editable
|
||||
items. It's one of the example about usage of Place geometry manager.
|
||||
|
||||
* ext/tk/sample/tktextio.rb: improve the functions of TkTextIO class.
|
||||
Those are required by 'irbtkw.rbw'.
|
||||
|
||||
* ext/tk/sample/irbtkw.rbw: [new] IRB on Ruby/Tk. It doesn't need any
|
||||
real console. IRB works on a text widget without I/O blocking. That
|
||||
is, thread switching on IRB will work properly, even if on Windows.
|
||||
|
||||
Mon Nov 6 00:42:05 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* parse.y (arg_dup_check): vid may be nameless internal id.
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2006-11-06 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
||||
|
||||
* lib/tkextlib/version.rb: keep release date of tkextlib on
|
||||
"Tk::Tkextlib_RELEASE_DATE".
|
||||
|
||||
* lib/tkextlib/tile/treeview.rb : support Tile 0.7.8.
|
||||
Now, you can handle tree items as objects.
|
||||
|
||||
2006-10-04 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
||||
|
||||
* lib/tkextlib/tile.rb, lib/tkextlib/tile/* : support Tile 0.7.6.
|
||||
|
|
|
@ -4597,7 +4597,7 @@ end
|
|||
#Tk.freeze
|
||||
|
||||
module Tk
|
||||
RELEASE_DATE = '2006-09-01'.freeze
|
||||
RELEASE_DATE = '2006-11-06'.freeze
|
||||
|
||||
autoload :AUTO_PATH, 'tk/variable'
|
||||
autoload :TCL_PACKAGE_PATH, 'tk/variable'
|
||||
|
@ -4609,6 +4609,7 @@ end
|
|||
|
||||
# call setup script for Tk extension libraries (base configuration)
|
||||
begin
|
||||
require 'tkextlib/version.rb'
|
||||
require 'tkextlib/setup.rb'
|
||||
rescue LoadError
|
||||
# ignore
|
||||
|
|
|
@ -289,7 +289,7 @@ module TkItemConfigMethod
|
|||
self
|
||||
end
|
||||
|
||||
def itemconfiginfo(tagOrId, slot = nil)
|
||||
def __itemconfiginfo_core(tagOrId, slot = nil)
|
||||
if TkComm::GET_CONFIGINFO_AS_ARRAY
|
||||
if (slot && slot.to_s =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/)
|
||||
fontkey = $2
|
||||
|
@ -594,7 +594,7 @@ module TkItemConfigMethod
|
|||
if v.empty?
|
||||
conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = nil
|
||||
else
|
||||
conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = TkVarAccess.new
|
||||
conf[__item_configinfo_struct(tagid(tagOrId))[:current_value]] = TkVarAccess.new(v)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1020,13 +1020,18 @@ module TkItemConfigMethod
|
|||
end
|
||||
end
|
||||
end
|
||||
private :__itemconfiginfo_core
|
||||
|
||||
def itemconfiginfo(tagOrId, slot = nil)
|
||||
__itemconfiginfo_core(tagOrId, slot)
|
||||
end
|
||||
|
||||
def current_itemconfiginfo(tagOrId, slot = nil)
|
||||
if TkComm::GET_CONFIGINFO_AS_ARRAY
|
||||
if slot
|
||||
org_slot = slot
|
||||
begin
|
||||
conf = itemconfiginfo(tagOrId, slot)
|
||||
conf = __itemconfiginfo_core(tagOrId, slot)
|
||||
if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \
|
||||
|| conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 )
|
||||
return {conf[0] => conf[-1]}
|
||||
|
@ -1037,7 +1042,7 @@ module TkItemConfigMethod
|
|||
"there is a configure alias loop about '#{org_slot}'"
|
||||
else
|
||||
ret = {}
|
||||
itemconfiginfo(tagOrId).each{|conf|
|
||||
__itemconfiginfo_core(tagOrId).each{|conf|
|
||||
if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \
|
||||
|| conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 )
|
||||
ret[conf[0]] = conf[-1]
|
||||
|
@ -1047,7 +1052,7 @@ module TkItemConfigMethod
|
|||
end
|
||||
else # ! TkComm::GET_CONFIGINFO_AS_ARRAY
|
||||
ret = {}
|
||||
itemconfiginfo(slot).each{|key, conf|
|
||||
itemconfiginfo(tagOrId, slot).each{|key, conf|
|
||||
ret[key] = conf[-1] if conf.kind_of?(Array)
|
||||
}
|
||||
ret
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
[ current support status of Tcl/Tk extensions ]
|
||||
|
||||
*******<<< RELEASE_DATE of the libraries : 2006/10/04 >>>*******
|
||||
*** RELEASE_DATE of the libraries => see 'tkextlib/version.rb' ***
|
||||
|
||||
The following list shows *CURRENT* status when this file was modifyed
|
||||
at last. If you want to add other Tcl/Tk extensions to the planed list
|
||||
|
@ -83,7 +83,7 @@ BLT 2.4z http://sourceforge.net/projects/blt
|
|||
TkTreeCtrl CVS/Hd(2005-12-02)
|
||||
http://sourceforge.net/projects/tktreectrl ==> treectrl
|
||||
|
||||
Tile CVS/Hd(2006-10-01)
|
||||
Tile 0.7.8
|
||||
http://sourceforge.net/projects/tktable ==> tile
|
||||
|
||||
|
||||
|
|
|
@ -9,10 +9,360 @@ module Tk
|
|||
module Tile
|
||||
class Treeview < TkWindow
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module TreeviewConfig
|
||||
module Tk::Tile::TreeviewConfig
|
||||
include TkItemConfigMethod
|
||||
|
||||
def __item_configinfo_struct(id)
|
||||
# maybe need to override
|
||||
{:key=>0, :alias=>nil, :db_name=>nil, :db_class=>nil,
|
||||
:default_value=>nil, :current_value=>1}
|
||||
end
|
||||
private :__item_configinfo_struct
|
||||
|
||||
def __itemconfiginfo_core(tagOrId, slot = nil)
|
||||
if TkComm::GET_CONFIGINFO_AS_ARRAY
|
||||
if (slot && slot.to_s =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/)
|
||||
fontkey = $2
|
||||
return [slot.to_s, tagfontobj(tagid(tagOrId), fontkey)]
|
||||
else
|
||||
if slot
|
||||
slot = slot.to_s
|
||||
case slot
|
||||
when /^(#{__tile_specific_item_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
begin
|
||||
# On tile-0.7.{2-8}, 'state' options has no '-' at its head.
|
||||
val = tk_call(*(__item_confinfo_cmd(tagid(tagOrId)) << slot))
|
||||
rescue
|
||||
# Maybe, 'state' option has '-' in future.
|
||||
val = tk_call(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))
|
||||
end
|
||||
return [slot, val]
|
||||
|
||||
when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/
|
||||
method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[slot]
|
||||
optval = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))
|
||||
begin
|
||||
val = method.call(tagOrId, optval)
|
||||
rescue => e
|
||||
warn("Warning:: #{e.message} (when #{method}lcall(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG
|
||||
val = optval
|
||||
end
|
||||
return [slot, val]
|
||||
|
||||
when /^(#{__item_methodcall_optkeys(tagid(tagOrId)).keys.join('|')})$/
|
||||
method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[slot]
|
||||
return [slot, self.__send__(method, tagOrId)]
|
||||
|
||||
when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
begin
|
||||
val = number(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))
|
||||
rescue
|
||||
val = nil
|
||||
end
|
||||
return [slot, val]
|
||||
|
||||
when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
val = num_or_str(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))
|
||||
return [slot, val]
|
||||
|
||||
when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
begin
|
||||
val = bool(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))
|
||||
rescue
|
||||
val = nil
|
||||
end
|
||||
return [slot, val]
|
||||
|
||||
when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
val = simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))
|
||||
return [slot, val]
|
||||
|
||||
when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))
|
||||
if val =~ /^[0-9]/
|
||||
return [slot, list(val)]
|
||||
else
|
||||
return [slot, val]
|
||||
end
|
||||
|
||||
when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))
|
||||
return [slot, val]
|
||||
|
||||
when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))
|
||||
if val.empty?
|
||||
return [slot, nil]
|
||||
else
|
||||
return [slot, TkVarAccess.new(val)]
|
||||
end
|
||||
|
||||
else
|
||||
val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))
|
||||
if val.index('{')
|
||||
return [slot, tk_split_list(val)]
|
||||
else
|
||||
return [slot, tk_tcl2ruby(val)]
|
||||
end
|
||||
end
|
||||
|
||||
else # ! slot
|
||||
ret = Hash[*(tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)))), false, false))].to_a.collect{|conf|
|
||||
conf[0] = conf[0][1..-1] if conf[0][0] == ?-
|
||||
case conf[0]
|
||||
when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/
|
||||
method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[conf[0]]
|
||||
optval = conf[1]
|
||||
begin
|
||||
val = method.call(tagOrId, optval)
|
||||
rescue => e
|
||||
warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG
|
||||
val = optval
|
||||
end
|
||||
conf[1] = val
|
||||
|
||||
when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
# do nothing
|
||||
|
||||
when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
begin
|
||||
conf[1] = number(conf[1])
|
||||
rescue
|
||||
conf[1] = nil
|
||||
end
|
||||
|
||||
when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
conf[1] = num_or_str(conf[1])
|
||||
|
||||
when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
begin
|
||||
conf[1] = bool(conf[1])
|
||||
rescue
|
||||
conf[1] = nil
|
||||
end
|
||||
|
||||
when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
conf[1] = simplelist(conf[1])
|
||||
|
||||
when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
if conf[1] =~ /^[0-9]/
|
||||
conf[1] = list(conf[1])
|
||||
end
|
||||
|
||||
when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
if conf[1].empty?
|
||||
conf[1] = nil
|
||||
else
|
||||
conf[1] = TkVarAccess.new(conf[1])
|
||||
end
|
||||
|
||||
else
|
||||
if conf[1].index('{')
|
||||
conf[1] = tk_split_list(conf[1])
|
||||
else
|
||||
conf[1] = tk_tcl2ruby(conf[1])
|
||||
end
|
||||
end
|
||||
|
||||
conf
|
||||
}
|
||||
|
||||
__item_font_optkeys(tagid(tagOrId)).each{|optkey|
|
||||
optkey = optkey.to_s
|
||||
fontconf = ret.assoc(optkey)
|
||||
if fontconf
|
||||
ret.delete_if{|inf| inf[0] =~ /^(|latin|ascii|kanji)#{optkey}$/}
|
||||
fontconf[1] = tagfontobj(tagid(tagOrId), optkey)
|
||||
ret.push(fontconf)
|
||||
end
|
||||
}
|
||||
|
||||
__item_methodcall_optkeys(tagid(tagOrId)).each{|optkey, method|
|
||||
ret << [optkey.to_s, self.__send__(method, tagOrId)]
|
||||
}
|
||||
|
||||
ret
|
||||
end
|
||||
end
|
||||
|
||||
else # ! TkComm::GET_CONFIGINFO_AS_ARRAY
|
||||
if (slot && slot.to_s =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/)
|
||||
fontkey = $2
|
||||
return {slot.to_s => tagfontobj(tagid(tagOrId), fontkey)}
|
||||
else
|
||||
if slot
|
||||
slot = slot.to_s
|
||||
case slot
|
||||
when /^(#{__tile_specific_item_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
begin
|
||||
# On tile-0.7.{2-8}, 'state' option has no '-' at its head.
|
||||
val = tk_call(*(__item_confinfo_cmd(tagid(tagOrId)) << slot))
|
||||
rescue
|
||||
# Maybe, 'state' option has '-' in future.
|
||||
val = tk_call(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))
|
||||
end
|
||||
return {slot => val}
|
||||
|
||||
when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/
|
||||
method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[slot]
|
||||
optval = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))
|
||||
begin
|
||||
val = method.call(tagOrId, optval)
|
||||
rescue => e
|
||||
warn("Warning:: #{e.message} (when #{method}lcall(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG
|
||||
val = optval
|
||||
end
|
||||
return {slot => val}
|
||||
|
||||
when /^(#{__item_methodcall_optkeys(tagid(tagOrId)).keys.join('|')})$/
|
||||
method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[slot]
|
||||
return {slot => self.__send__(method, tagOrId)}
|
||||
|
||||
when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
begin
|
||||
val = number(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))
|
||||
rescue
|
||||
val = nil
|
||||
end
|
||||
return {slot => val}
|
||||
|
||||
when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
val = num_or_str(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))
|
||||
return {slot => val}
|
||||
|
||||
when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
begin
|
||||
val = bool(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))
|
||||
rescue
|
||||
val = nil
|
||||
end
|
||||
return {slot => val}
|
||||
|
||||
when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
val = simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}")))
|
||||
return {slot => val}
|
||||
|
||||
when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))
|
||||
if val =~ /^[0-9]/
|
||||
return {slot => list(val)}
|
||||
else
|
||||
return {slot => val}
|
||||
end
|
||||
|
||||
when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))
|
||||
return {slot => val}
|
||||
|
||||
when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))
|
||||
if val.empty?
|
||||
return {slot => nil}
|
||||
else
|
||||
return {slot => TkVarAccess.new(val)}
|
||||
end
|
||||
|
||||
else
|
||||
val = tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{slot}"))
|
||||
if val.index('{')
|
||||
return {slot => tk_split_list(val)}
|
||||
else
|
||||
return {slot => tk_tcl2ruby(val)}
|
||||
end
|
||||
end
|
||||
|
||||
else # ! slot
|
||||
ret = {}
|
||||
ret = Hash[*(tk_split_simplelist(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)))), false, false))].to_a.collect{|conf|
|
||||
conf[0] = conf[0][1..-1] if conf[0][0] == ?-
|
||||
|
||||
optkey = conf[0]
|
||||
case optkey
|
||||
when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/
|
||||
method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[optkey]
|
||||
optval = conf[1]
|
||||
begin
|
||||
val = method.call(tagOrId, optval)
|
||||
rescue => e
|
||||
warn("Warning:: #{e.message} (when #{method}.call(#{tagOrId.inspect}, #{optval.inspect})") if $DEBUG
|
||||
val = optval
|
||||
end
|
||||
conf[1] = val
|
||||
|
||||
when /^(#{__item_strval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
# do nothing
|
||||
|
||||
when /^(#{__item_numval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
begin
|
||||
conf[1] = number(conf[1])
|
||||
rescue
|
||||
conf[1] = nil
|
||||
end
|
||||
|
||||
when /^(#{__item_numstrval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
conf[1] = num_or_str(conf[1])
|
||||
|
||||
when /^(#{__item_boolval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
begin
|
||||
conf[1] = bool(conf[1])
|
||||
rescue
|
||||
conf[1] = nil
|
||||
end
|
||||
|
||||
when /^(#{__item_listval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
conf[1] = simplelist(conf[1])
|
||||
|
||||
when /^(#{__item_numlistval_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
if conf[1] =~ /^[0-9]/
|
||||
conf[1] = list(conf[1])
|
||||
end
|
||||
|
||||
when /^(#{__item_tkvariable_optkeys(tagid(tagOrId)).join('|')})$/
|
||||
if conf[1].empty?
|
||||
conf[1] = nil
|
||||
else
|
||||
conf[1] = TkVarAccess.new(conf[1])
|
||||
end
|
||||
|
||||
else
|
||||
if conf[1].index('{')
|
||||
return [slot, tk_split_list(conf[1])]
|
||||
else
|
||||
return [slot, tk_tcl2ruby(conf[1])]
|
||||
end
|
||||
end
|
||||
|
||||
ret[conf[0]] = conf[1]
|
||||
}
|
||||
|
||||
__item_font_optkeys(tagid(tagOrId)).each{|optkey|
|
||||
optkey = optkey.to_s
|
||||
fontconf = ret[optkey]
|
||||
if fontconf.kind_of?(Array)
|
||||
ret.delete(optkey)
|
||||
ret.delete('latin' << optkey)
|
||||
ret.delete('ascii' << optkey)
|
||||
ret.delete('kanji' << optkey)
|
||||
fontconf[1] = tagfontobj(tagid(tagOrId), optkey)
|
||||
ret[optkey] = fontconf
|
||||
end
|
||||
}
|
||||
|
||||
__item_methodcall_optkeys(tagid(tagOrId)).each{|optkey, method|
|
||||
ret[optkey.to_s] = self.__send__(method, tagOrId)
|
||||
}
|
||||
|
||||
ret
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
###################
|
||||
|
||||
def __item_cget_cmd(id)
|
||||
[self.path, id[0], id[1]]
|
||||
end
|
||||
|
@ -29,8 +379,12 @@ module Tk
|
|||
['width']
|
||||
when :column, 'column'
|
||||
super(id[1])
|
||||
when :tag, 'tag'
|
||||
super(id[1])
|
||||
when :heading, 'heading'
|
||||
super(id[1])
|
||||
else
|
||||
super(id[1])
|
||||
end
|
||||
end
|
||||
private :__item_numstrval_optkeys
|
||||
|
@ -41,8 +395,12 @@ module Tk
|
|||
super(id) + ['id']
|
||||
when :column, 'column'
|
||||
super(id[1])
|
||||
when :tag, 'tag'
|
||||
super(id[1])
|
||||
when :heading, 'heading'
|
||||
super(id[1])
|
||||
else
|
||||
super(id[1])
|
||||
end
|
||||
end
|
||||
private :__item_strval_optkeys
|
||||
|
@ -53,6 +411,8 @@ module Tk
|
|||
['open']
|
||||
when :column, 'column'
|
||||
super(id[1])
|
||||
when :tag, 'tag'
|
||||
super(id[1])
|
||||
when :heading, 'heading'
|
||||
super(id[1])
|
||||
end
|
||||
|
@ -67,10 +427,83 @@ module Tk
|
|||
[]
|
||||
when :heading, 'heading'
|
||||
[]
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
private :__item_listval_optkeys
|
||||
|
||||
def __item_val2ruby_optkeys(id)
|
||||
case id[0]
|
||||
when :item, 'item'
|
||||
{
|
||||
'tags'=>proc{|arg_id, val|
|
||||
simplelist(val).collect{|tag|
|
||||
Tk::Tile::Treeview::Tag.id2obj(self, tag)
|
||||
}
|
||||
}
|
||||
}
|
||||
when :column, 'column'
|
||||
{}
|
||||
when :heading, 'heading'
|
||||
{}
|
||||
else
|
||||
{}
|
||||
end
|
||||
end
|
||||
private :__item_val2ruby_optkeys
|
||||
|
||||
def __tile_specific_item_optkeys(id)
|
||||
case id[0]
|
||||
when :item, 'item'
|
||||
[]
|
||||
when :column, 'column'
|
||||
[]
|
||||
when :heading, 'heading'
|
||||
['state'] # On tile-0.7.{2-8}, 'state' options has no '-' at its head.
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
private :__item_val2ruby_optkeys
|
||||
|
||||
def itemconfiginfo(tagOrId, slot = nil)
|
||||
__itemconfiginfo_core(tagOrId, slot)
|
||||
end
|
||||
|
||||
def current_itemconfiginfo(tagOrId, slot = nil)
|
||||
if TkComm::GET_CONFIGINFO_AS_ARRAY
|
||||
if slot
|
||||
org_slot = slot
|
||||
begin
|
||||
conf = __itemconfiginfo_core(tagOrId, slot)
|
||||
if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \
|
||||
|| conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 )
|
||||
return {conf[0] => conf[-1]}
|
||||
end
|
||||
slot = conf[__item_configinfo_struct(tagid(tagOrId))[:alias]]
|
||||
end while(org_slot != slot)
|
||||
fail RuntimeError,
|
||||
"there is a configure alias loop about '#{org_slot}'"
|
||||
else
|
||||
ret = {}
|
||||
__itemconfiginfo_core(tagOrId).each{|conf|
|
||||
if ( ! __item_configinfo_struct(tagid(tagOrId))[:alias] \
|
||||
|| conf.size > __item_configinfo_struct(tagid(tagOrId))[:alias] + 1 )
|
||||
ret[conf[0]] = conf[-1]
|
||||
end
|
||||
}
|
||||
ret
|
||||
end
|
||||
else # ! TkComm::GET_CONFIGINFO_AS_ARRAY
|
||||
ret = {}
|
||||
itemconfiginfo(tagOrId, slot).each{|key, conf|
|
||||
ret[key] = conf[-1] if conf.kind_of?(Array)
|
||||
}
|
||||
ret
|
||||
end
|
||||
end
|
||||
|
||||
alias __itemcget itemcget
|
||||
alias __itemconfigure itemconfigure
|
||||
alias __itemconfiginfo itemconfiginfo
|
||||
|
@ -113,11 +546,40 @@ module Tk
|
|||
|
||||
# Treeview Heading
|
||||
def headingcget(tagOrId, option)
|
||||
if __tile_specific_item_optkeys([:heading, tagOrId]).index(option.to_s)
|
||||
begin
|
||||
# On tile-0.7.{2-8}, 'state' options has no '-' at its head.
|
||||
tk_call(*(__item_cget_cmd([:heading, tagOrId]) << option.to_s))
|
||||
rescue
|
||||
# Maybe, 'state' option has '-' in future.
|
||||
tk_call(*(__item_cget_cmd([:heading, tagOrId]) << "-#{option}"))
|
||||
end
|
||||
else
|
||||
__itemcget([:heading, tagOrId], option)
|
||||
end
|
||||
end
|
||||
def headingconfigure(tagOrId, slot, value=None)
|
||||
if slot.kind_of?(Hash)
|
||||
slot = _symbolkey2str(slot)
|
||||
sp_kv = []
|
||||
__tile_specific_item_optkeys([:heading, tagOrId]).each{|k|
|
||||
sp_kv << k << _get_eval_string(slot.delete(k)) if slot.has_key?(k)
|
||||
}
|
||||
tk_call(*(__item_config_cmd([:heading, tagOrId]).concat(sp_kv)))
|
||||
tk_call(*(__item_config_cmd([:heading, tagOrId]).concat(hash_kv(slot))))
|
||||
elsif __tile_specific_item_optkeys([:heading, tagOrId]).index(slot.to_s)
|
||||
begin
|
||||
# On tile-0.7.{2-8}, 'state' options has no '-' at its head.
|
||||
tk_call(*(__item_cget_cmd([:heading, tagOrId]) << slot.to_s << value))
|
||||
rescue
|
||||
# Maybe, 'state' option has '-' in future.
|
||||
tk_call(*(__item_cget_cmd([:heading, tagOrId]) << "-#{slot}" << value))
|
||||
end
|
||||
else
|
||||
__itemconfigure([:heading, tagOrId], slot, value)
|
||||
end
|
||||
self
|
||||
end
|
||||
def headingconfiginfo(tagOrId, slot=nil)
|
||||
__itemconfiginfo([:heading, tagOrId], slot)
|
||||
end
|
||||
|
@ -128,10 +590,317 @@ module Tk
|
|||
alias heading_configure headingconfigure
|
||||
alias heading_configinfo headingconfiginfo
|
||||
alias current_heading_configinfo current_headingconfiginfo
|
||||
|
||||
# Treeview Tag
|
||||
def tagcget(tagOrId, option)
|
||||
__itemcget([:tag, tagOrId], option)
|
||||
end
|
||||
def tagconfigure(tagOrId, slot, value=None)
|
||||
__itemconfigure([:tag, tagOrId], slot, value)
|
||||
end
|
||||
def tagconfiginfo(tagOrId, slot=nil)
|
||||
__itemconfiginfo([:tag, tagOrId], slot)
|
||||
end
|
||||
def current_tagconfiginfo(tagOrId, slot=nil)
|
||||
__current_itemconfiginfo([:tag, tagOrId], slot)
|
||||
end
|
||||
alias tag_cget tagcget
|
||||
alias tag_configure tagconfigure
|
||||
alias tag_configinfo tagconfiginfo
|
||||
alias current_tag_configinfo current_tagconfiginfo
|
||||
end
|
||||
|
||||
########################
|
||||
|
||||
class Tk::Tile::Treeview::Item < TkObject
|
||||
ItemID_TBL = TkCore::INTERP.create_table
|
||||
TkCore::INTERP.init_ip_env{ Tk::Tile::Treeview::Item::ItemID_TBL.clear }
|
||||
|
||||
def self.id2obj(tree, id)
|
||||
tpath = tree.path
|
||||
return id unless Tk::Tile::Treeview::Item::ItemID_TBL[tpath]
|
||||
(Tk::Tile::Treeview::Item::ItemID_TBL[tpath][id])? \
|
||||
Tk::Tile::Treeview::Item::ItemID_TBL[tpath][id]: id
|
||||
end
|
||||
|
||||
def self.assign(tree, id)
|
||||
tpath = tree.path
|
||||
if Tk::Tile::Treeview::Item::ItemID_TBL[tpath] &&
|
||||
Tk::Tile::Treeview::Item::ItemID_TBL[tpath][id]
|
||||
return Tk::Tile::Treeview::Item::ItemID_TBL[tpath][id]
|
||||
end
|
||||
|
||||
obj = self.allocate
|
||||
obj.instance_eval{
|
||||
@parent = @t = tree
|
||||
@tpath = tpath
|
||||
@path = @id = id
|
||||
}
|
||||
ItemID_TBL[tpath] = {} unless ItemID_TBL[tpath]
|
||||
Tk::Tile::Treeview::Item::ItemID_TBL[tpath][id] = obj
|
||||
obj
|
||||
end
|
||||
|
||||
def _insert_item(tree, parent_item, idx, keys={})
|
||||
keys = _symbolkey2str(keys)
|
||||
id = keys.delete('id')
|
||||
if id
|
||||
num_or_str(tk_call(tree, 'insert',
|
||||
parent_item, idx, '-id', id, *hash_kv(keys)))
|
||||
else
|
||||
num_or_str(tk_call(tree, 'insert', parent_item, idx, *hash_kv(keys)))
|
||||
end
|
||||
end
|
||||
private :_insert_item
|
||||
|
||||
def initialize(tree, parent_item = '', idx = 'end', keys = {})
|
||||
if parent_item.kind_of?(Hash)
|
||||
keys = parent_item
|
||||
idx = 'end'
|
||||
parent_item = ''
|
||||
elsif idx.kind_of?(Hash)
|
||||
keys = idx
|
||||
idx = 'end'
|
||||
end
|
||||
|
||||
@parent = @t = tree
|
||||
@tpath = tree.path
|
||||
@path = @id = _insert_item(@t, parent_item, idx, keys)
|
||||
ItemID_TBL[@tpath] = {} unless ItemID_TBL[@tpath]
|
||||
ItemID_TBL[@tpath][@id] = self
|
||||
end
|
||||
def id
|
||||
@id
|
||||
end
|
||||
|
||||
def cget(option)
|
||||
@t.itemcget(@id, option)
|
||||
end
|
||||
|
||||
def configure(key, value=None)
|
||||
@t.itemconfigure(@id, key, value)
|
||||
self
|
||||
end
|
||||
|
||||
def configinfo(key=nil)
|
||||
@t.itemconfiginfo(@id, key)
|
||||
end
|
||||
|
||||
def current_configinfo(key=nil)
|
||||
@t.current_itemconfiginfo(@id, key)
|
||||
end
|
||||
|
||||
def open?
|
||||
cget('open')
|
||||
end
|
||||
def open
|
||||
configure('open', true)
|
||||
self
|
||||
end
|
||||
def close
|
||||
configure('open', false)
|
||||
self
|
||||
end
|
||||
|
||||
def bbox(column=None)
|
||||
@t.bbox(@id, column)
|
||||
end
|
||||
|
||||
def children
|
||||
@t.children(@id)
|
||||
end
|
||||
def set_children(*items)
|
||||
@t.set_children(@id, *items)
|
||||
self
|
||||
end
|
||||
|
||||
def delete
|
||||
@t.delete(@id)
|
||||
self
|
||||
end
|
||||
|
||||
def detach
|
||||
@t.detach(@id)
|
||||
self
|
||||
end
|
||||
|
||||
def exist?
|
||||
@t.exist?(@id)
|
||||
end
|
||||
|
||||
def focus
|
||||
@t.focus_item(@id)
|
||||
end
|
||||
|
||||
def index
|
||||
@t.index(@id)
|
||||
end
|
||||
|
||||
def insert(idx='end', keys={})
|
||||
@t.insert(@id, idx, keys)
|
||||
end
|
||||
|
||||
def move(parent, idx)
|
||||
@t.move(@id, parent, idx)
|
||||
self
|
||||
end
|
||||
|
||||
def next_item
|
||||
@t.next_item(@id)
|
||||
end
|
||||
|
||||
def parent_item
|
||||
@t.parent_item(@id)
|
||||
end
|
||||
|
||||
def prev_item
|
||||
@t.prev_item(@id)
|
||||
end
|
||||
|
||||
def see
|
||||
@t.see(@id)
|
||||
self
|
||||
end
|
||||
|
||||
def selection_add
|
||||
@t.selection_add(@id)
|
||||
self
|
||||
end
|
||||
|
||||
def selection_remove
|
||||
@t.selection_remove(@id)
|
||||
self
|
||||
end
|
||||
|
||||
def selection_set
|
||||
@t.selection_set(@id)
|
||||
self
|
||||
end
|
||||
|
||||
def selection_toggle
|
||||
@t.selection_toggle(@id)
|
||||
self
|
||||
end
|
||||
|
||||
def get_directory
|
||||
@t.get_directory(@id)
|
||||
end
|
||||
alias get_dictionary get_directory
|
||||
|
||||
def get(col)
|
||||
@t.get(@id, col)
|
||||
end
|
||||
|
||||
def set(col, value)
|
||||
@t.set(@id, col, value)
|
||||
end
|
||||
end
|
||||
|
||||
########################
|
||||
|
||||
class Tk::Tile::Treeview::Root < Tk::Tile::Treeview::Item
|
||||
def self.new(tree, keys = {})
|
||||
tpath = tree.path
|
||||
if Tk::Tile::Treeview::Item::ItemID_TBL[tpath] &&
|
||||
Tk::Tile::Treeview::Item::ItemID_TBL[tpath]['']
|
||||
Tk::Tile::Treeview::Item::ItemID_TBL[tpath]['']
|
||||
else
|
||||
super(tree, keys)
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(tree, keys = {})
|
||||
@parent = @t = tree
|
||||
@tpath = tree.path
|
||||
@path = @id = ''
|
||||
unless Tk::Tile::Treeview::Item::ItemID_TBL[@tpath]
|
||||
Tk::Tile::Treeview::Item::ItemID_TBL[@tpath] = {}
|
||||
end
|
||||
Tk::Tile::Treeview::Item::ItemID_TBL[@tpath][@id] = self
|
||||
end
|
||||
end
|
||||
|
||||
########################
|
||||
|
||||
class Tk::Tile::Treeview::Tag < TkObject
|
||||
include TkTreatTagFont
|
||||
|
||||
TagID_TBL = TkCore::INTERP.create_table
|
||||
Tag_ID = ['tile_treeview_tag'.freeze, '00000'.taint].freeze
|
||||
|
||||
TkCore::INTERP.init_ip_env{ Tk::Tile::Treeview::Tag::TagID_TBL.clear }
|
||||
|
||||
def self.id2obj(tree, id)
|
||||
tpath = tree.path
|
||||
return id unless Tk::Tile::Treeview::Tag::TagID_TBL[tpath]
|
||||
(Tk::Tile::Treeview::Tag::TagID_TBL[tpath][id])? \
|
||||
Tk::Tile::Treeview::Tag::TagID_TBL[tpath][id]: id
|
||||
end
|
||||
|
||||
def initialize(tree, keys=nil)
|
||||
@parent = @t = tree
|
||||
@tpath = tree.path
|
||||
@path = @id = Tag_ID.join(TkCore::INTERP._ip_id_)
|
||||
TagID_TBL[@tpath] = {} unless TagID_TBL[@tpath]
|
||||
TagID_TBL[@tpath][@id] = self
|
||||
Tag_ID[1].succ!
|
||||
if keys && keys != None
|
||||
tk_call_without_enc(@tpath, 'tag', 'configure', *hash_kv(keys, true))
|
||||
end
|
||||
end
|
||||
def id
|
||||
@id
|
||||
end
|
||||
|
||||
def bind(seq, *args)
|
||||
if TkComm._callback_entry?(args[0]) || !block_given?
|
||||
cmd = args.shift
|
||||
else
|
||||
cmd = Proc.new
|
||||
end
|
||||
@t.tag_bind(@id, seq, cmd, *args)
|
||||
self
|
||||
end
|
||||
|
||||
def bind_append(seq, *args)
|
||||
if TkComm._callback_entry?(args[0]) || !block_given?
|
||||
cmd = args.shift
|
||||
else
|
||||
cmd = Proc.new
|
||||
end
|
||||
@t.tag_bind_append(@id, seq, cmd, *args)
|
||||
self
|
||||
end
|
||||
|
||||
def bind_remove(seq)
|
||||
@t.tag_bind_remove(@id, seq)
|
||||
self
|
||||
end
|
||||
|
||||
def bindinfo(seq=nil)
|
||||
@t.tag_bindinfo(@id, seq)
|
||||
end
|
||||
|
||||
def cget(option)
|
||||
@t.tagcget(@id, option)
|
||||
end
|
||||
|
||||
def configure(key, value=None)
|
||||
@t.tagconfigure(@id, key, value)
|
||||
self
|
||||
end
|
||||
|
||||
def configinfo(key=nil)
|
||||
@t.tagconfiginfo(@id, key)
|
||||
end
|
||||
|
||||
def current_configinfo(key=nil)
|
||||
@t.current_tagconfiginfo(@id, key)
|
||||
end
|
||||
end
|
||||
|
||||
########################
|
||||
|
||||
class Tk::Tile::Treeview < TkWindow
|
||||
include Tk::Tile::TileWidget
|
||||
include Scrollable
|
||||
|
@ -146,24 +915,38 @@ class Tk::Tile::Treeview < TkWindow
|
|||
WidgetClassName = 'Treeview'.freeze
|
||||
WidgetClassNames[WidgetClassName] = self
|
||||
|
||||
def __destroy_hook__
|
||||
Tk::Tile::Treeview::Item::ItemID_TBL.delete(@path)
|
||||
Tk::Tile::Treeview::Tag::ItemID_TBL.delete(@path)
|
||||
end
|
||||
|
||||
def self.style(*args)
|
||||
[self::WidgetClassName, *(args.map!{|a| _get_eval_string(a)})].join('.')
|
||||
end
|
||||
|
||||
def tagid(id)
|
||||
if id.kind_of?(Array)
|
||||
if id.kind_of?(Tk::Tile::Treeview::Item) ||
|
||||
id.kind_of?(Tk::Tile::Treeview::Tag)
|
||||
id.id
|
||||
elsif id.kind_of?(Array)
|
||||
[id[0], _get_eval_string(id[1])]
|
||||
else
|
||||
_get_eval_string(id)
|
||||
end
|
||||
end
|
||||
|
||||
def root
|
||||
Tk::Tile::Treeview::Root.new(self)
|
||||
end
|
||||
|
||||
def bbox(item, column=None)
|
||||
list(tk_send('item', 'bbox', item, column))
|
||||
end
|
||||
|
||||
def children(item)
|
||||
simplelist(tk_send_without_enc('children', item))
|
||||
simplelist(tk_send_without_enc('children', item)).collect{|id|
|
||||
Tk::Tile::Treeview::Item.id2obj(self, id)
|
||||
}
|
||||
end
|
||||
def set_children(item, *items)
|
||||
tk_send_without_enc('children', item,
|
||||
|
@ -185,21 +968,33 @@ class Tk::Tile::Treeview < TkWindow
|
|||
bool(tk_send_without_enc('exists', _get_eval_enc_str(item)))
|
||||
end
|
||||
|
||||
def focus_item(item = None)
|
||||
def focus_item(item = nil)
|
||||
if item
|
||||
tk_send('focus', item)
|
||||
item
|
||||
else
|
||||
id = tk_send('focus')
|
||||
(id.empty?)? nil: Tk::Tile::Treeview::Item.id2obj(self, id)
|
||||
end
|
||||
end
|
||||
|
||||
def identify(x, y)
|
||||
# tile-0.7.2 or previous
|
||||
ret = simplelist(tk_send('identify', x, y))
|
||||
case ret[0]
|
||||
when 'heading', 'separator', 'cell'
|
||||
when 'heading', 'separator'
|
||||
ret[-1] = num_or_str(ret[-1])
|
||||
when 'cell'
|
||||
ret[1] = Tk::Tile::Treeview::Item.id2obj(self, ret[1])
|
||||
ret[-1] = num_or_str(ret[-1])
|
||||
when 'item', 'row'
|
||||
ret[1] = Tk::Tile::Treeview::Item.id2obj(self, ret[1])
|
||||
end
|
||||
end
|
||||
|
||||
def row_identify(x, y)
|
||||
tk_send('identify', 'row', x, y)
|
||||
id = tk_send('identify', 'row', x, y)
|
||||
(id.empty?)? nil: Tk::Tile::Treeview::Item.id2obj(self, id)
|
||||
end
|
||||
|
||||
def column_identify(x, y)
|
||||
|
@ -210,38 +1005,47 @@ class Tk::Tile::Treeview < TkWindow
|
|||
number(tk_send('index', item))
|
||||
end
|
||||
|
||||
def insert(parent, idx, keys={})
|
||||
keys = _symbolkey2str(keys)
|
||||
id = keys.delete('id')
|
||||
if id
|
||||
num_or_str(tk_send('insert', parent, idx, '-id', id, *hash_kv(keys)))
|
||||
else
|
||||
num_or_str(tk_send('insert', parent, idx, *hash_kv(keys)))
|
||||
end
|
||||
# def insert(parent, idx='end', keys={})
|
||||
# keys = _symbolkey2str(keys)
|
||||
# id = keys.delete('id')
|
||||
# if id
|
||||
# num_or_str(tk_send('insert', parent, idx, '-id', id, *hash_kv(keys)))
|
||||
# else
|
||||
# num_or_str(tk_send('insert', parent, idx, *hash_kv(keys)))
|
||||
# end
|
||||
# end
|
||||
def insert(parent, idx='end', keys={})
|
||||
Tk::Tile::Treeview::Item.new(self, parent, idx, keys)
|
||||
end
|
||||
|
||||
def instate(spec, cmd=Proc.new)
|
||||
tk_send('instate', spec, cmd)
|
||||
end
|
||||
def state(spec=None)
|
||||
tk_send('state', spec)
|
||||
end
|
||||
# def instate(spec, cmd=Proc.new)
|
||||
# tk_send('instate', spec, cmd)
|
||||
# end
|
||||
# def state(spec=None)
|
||||
# tk_send('state', spec)
|
||||
# end
|
||||
|
||||
def move(item, parent, idx)
|
||||
tk_send('move', item, parent, idx)
|
||||
self
|
||||
end
|
||||
|
||||
def next(item)
|
||||
tk_send('next', item)
|
||||
def next_item(item)
|
||||
id = tk_send('next', item)
|
||||
(id.empty?)? nil: Tk::Tile::Treeview::Item.id2obj(self, id)
|
||||
end
|
||||
|
||||
def parent(item)
|
||||
tk_send('parent', item)
|
||||
def parent_item(item)
|
||||
if (id = tk_send('parent', item)).empty?
|
||||
Tk::Tile::Treeview::Root.new(self)
|
||||
else
|
||||
Tk::Tile::Treeview::Item.id2obj(self, id)
|
||||
end
|
||||
end
|
||||
|
||||
def prev(item)
|
||||
tk_send('prev', item)
|
||||
def prev_item(item)
|
||||
id = tk_send('prev', item)
|
||||
(id.empty?)? nil: Tk::Tile::Treeview::Item.id2obj(self, id)
|
||||
end
|
||||
|
||||
def see(item)
|
||||
|
@ -250,7 +1054,9 @@ class Tk::Tile::Treeview < TkWindow
|
|||
end
|
||||
|
||||
def selection
|
||||
simplelist(tk_send('selection'))
|
||||
simplelist(tk_send('selection')).collect{|id|
|
||||
Tk::Tile::Treeview::Item.id2obj(self, id)
|
||||
}
|
||||
end
|
||||
alias selection_get selection
|
||||
|
||||
|
|
6
ext/tk/lib/tkextlib/version.rb
Normal file
6
ext/tk/lib/tkextlib/version.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
#
|
||||
# release date of tkextlib
|
||||
#
|
||||
module Tk
|
||||
Tkextlib_RELEASE_DATE = '2006-11-06'.freeze
|
||||
end
|
69
ext/tk/sample/editable_listbox.rb
Normal file
69
ext/tk/sample/editable_listbox.rb
Normal file
|
@ -0,0 +1,69 @@
|
|||
#
|
||||
# Editable_TkListbox class
|
||||
#
|
||||
# When "DoubleClick-1" on a listbox item, the entry box is opend on the
|
||||
# item. And when hit "Return" key on the entry box after modifying the
|
||||
# text, the entry box is closed and the item is changed. Or when hit
|
||||
# "Escape" key, the entry box is closed without modification.
|
||||
#
|
||||
# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
|
||||
#
|
||||
require 'tk'
|
||||
|
||||
class Editable_TkListbox < TkListbox
|
||||
def _ebox_placer(coord_y)
|
||||
idx = self.nearest(coord_y)
|
||||
x, y, w, h = self.bbox(idx)
|
||||
@ebox.place(:x => 0, :relwidth => 1.0,
|
||||
:y => y - self.selectborderwidth,
|
||||
:height => h + 2 * self.selectborderwidth)
|
||||
@ebox.pos = idx
|
||||
@ebox.value = self.listvariable.list[idx]
|
||||
@ebox.focus
|
||||
end
|
||||
private :_ebox_placer
|
||||
|
||||
|
||||
def create_self(keys)
|
||||
super(keys)
|
||||
|
||||
unless self.listvariable
|
||||
self.listvariable = TkVariable.new(self.get(0, :end))
|
||||
end
|
||||
|
||||
@ebox = TkEntry.new(self){
|
||||
@pos = -1
|
||||
def self.pos; @pos; end
|
||||
def self.pos=(idx); @pos = idx; end
|
||||
}
|
||||
|
||||
@ebox.bind('Return'){
|
||||
list = self.listvariable.list
|
||||
list[@ebox.pos] = @ebox.value
|
||||
self.listvariable.value = list
|
||||
@ebox.place_forget
|
||||
@ebox.pos = -1
|
||||
}
|
||||
|
||||
@ebox.bind('Escape'){
|
||||
@ebox.place_forget
|
||||
@ebox.pos = -1
|
||||
}
|
||||
|
||||
self.bind('Double-1', '%y'){|y| _ebox_placer(y) }
|
||||
end
|
||||
end
|
||||
|
||||
if $0 == __FILE__
|
||||
scr = TkScrollbar.new.pack(:side=>:right, :fill=>:y)
|
||||
|
||||
lbox1 = Editable_TkListbox.new.pack(:side=>:left)
|
||||
lbox2 = Editable_TkListbox.new.pack(:side=>:left)
|
||||
|
||||
scr.assign(lbox1, lbox2)
|
||||
|
||||
lbox1.insert(:end, *%w(a b c d e f g h i j k l m n))
|
||||
lbox2.insert(:end, 0,1,2,3,4,5,6,7,8,9,0,1,2,3)
|
||||
|
||||
Tk.mainloop
|
||||
end
|
119
ext/tk/sample/irbtkw.rbw
Normal file
119
ext/tk/sample/irbtkw.rbw
Normal file
|
@ -0,0 +1,119 @@
|
|||
#!/usr/bin/env ruby
|
||||
#
|
||||
# irbtkw.rb : IRB console with Ruby/Tk
|
||||
#
|
||||
# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
|
||||
#
|
||||
release = '2006/11/06'
|
||||
|
||||
require 'tk'
|
||||
begin
|
||||
require 'tktextio'
|
||||
rescue LoadError
|
||||
require File.join(File.dirname(File.expand_path(__FILE__)), 'tktextio.rb')
|
||||
end
|
||||
|
||||
require 'irb'
|
||||
|
||||
# console setup
|
||||
top = TkToplevel.new(:title=>'IRB console')
|
||||
top.protocol(:WM_DELETE_WINDOW){ Tk.exit }
|
||||
|
||||
console = TkTextIO.new(top, :mode=>:console,
|
||||
:width=>80).pack(:side=>:left,
|
||||
:expand=>true, :fill=>:both)
|
||||
console.yscrollbar(TkScrollbar.new(top, :width=>10).pack(:before=>console,
|
||||
:side=>:right,
|
||||
:expand=>false,
|
||||
:fill=>:y))
|
||||
ev_loop = Thread.new{Tk.mainloop}
|
||||
|
||||
# window position control
|
||||
root = Tk.root
|
||||
|
||||
r_x = root.winfo_rootx
|
||||
r_y = root.winfo_rooty
|
||||
r_w = root.winfo_width
|
||||
|
||||
t_x = top.winfo_rootx
|
||||
t_y = top.winfo_rooty
|
||||
t_w = top.winfo_width
|
||||
|
||||
delta = 10
|
||||
|
||||
ratio = 0.8
|
||||
s_w = (ratio * root.winfo_screenwidth).to_i
|
||||
|
||||
if r_x < t_x
|
||||
r_x, t_x = t_x, r_x
|
||||
end
|
||||
if t_x + t_w + r_w + delta < s_w
|
||||
r_x = t_x + t_w + delta
|
||||
elsif t_w + r_w + delta < s_w
|
||||
r_x = s_w - r_w
|
||||
t_x = r_x - t_w
|
||||
else
|
||||
r_x = s_w - r_w
|
||||
t_x = 0
|
||||
end
|
||||
|
||||
root.geometry("+#{r_x}+#{r_y}")
|
||||
top.geometry("+#{t_x}+#{t_y}")
|
||||
|
||||
root.raise
|
||||
console.focus
|
||||
|
||||
# I/O setup
|
||||
$stdin = console
|
||||
$stdout = console
|
||||
$stderr = console
|
||||
|
||||
# dummy for rubyw.exe on Windows
|
||||
def STDIN.tty?
|
||||
true
|
||||
end
|
||||
|
||||
# IRB setup
|
||||
IRB.init_config(nil)
|
||||
IRB.conf[:USE_READLINE] = false
|
||||
IRB.init_error
|
||||
irb = IRB::Irb.new
|
||||
IRB.conf[:MAIN_CONTEXT] = irb.context
|
||||
|
||||
class IRB::StdioInputMethod
|
||||
def gets
|
||||
prompt = "\n" << @prompt
|
||||
$stdin.instance_eval{
|
||||
flush
|
||||
@prompt = prompt
|
||||
_set_console_line
|
||||
@prompt = nil
|
||||
_see_pos
|
||||
}
|
||||
|
||||
@line[@line_no += 1] = $stdin.gets
|
||||
end
|
||||
end
|
||||
|
||||
# IRB start
|
||||
$stdout.print("*** IRB console on Ruby/Tk (#{release}) ")
|
||||
irb_thread = Thread.new{
|
||||
catch(:IRB_EXIT){
|
||||
loop {
|
||||
begin
|
||||
irb.eval_input
|
||||
rescue Exception
|
||||
end
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.bind('Control-c'){
|
||||
console.insert('end', "^C\n")
|
||||
irb_thread.raise RubyLex::TerminateLineInput
|
||||
}
|
||||
|
||||
irb_thread.join
|
||||
|
||||
# exit
|
||||
Tk.exit
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env ruby
|
||||
#
|
||||
# sample class of handling I/O stream on a TkText widget
|
||||
# by Hidetoshi NAGAI
|
||||
# TkTextIO class :: handling I/O stream on a TkText widget
|
||||
# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
|
||||
#
|
||||
# NOTE: TkTextIO supports 'character' (not 'byte') access only.
|
||||
# So, for example, TkTextIO#getc returns a character, TkTextIO#pos
|
||||
|
@ -14,68 +14,375 @@
|
|||
# TkTextIO.
|
||||
#
|
||||
require 'tk'
|
||||
require 'tk/text'
|
||||
require 'tk/textmark'
|
||||
require 'thread'
|
||||
|
||||
class TkTextIO < TkText
|
||||
def create_self(keys)
|
||||
mode = nil
|
||||
ovwt = false
|
||||
text = nil
|
||||
wrap = 'char'
|
||||
show = :pos
|
||||
# keep safe level
|
||||
@@create_queues = proc{ [Queue.new, Mutex.new, Queue.new, Mutex.new] }
|
||||
|
||||
if keys.kind_of?(Hash)
|
||||
mode = keys.delete('mode')
|
||||
ovwt = keys.delete('overwrite')
|
||||
text = keys.delete('text')
|
||||
show = keys.delete('show') if keys.has_key?('show')
|
||||
wrap = keys.delete('wrap') || 'char'
|
||||
end
|
||||
OPT_DEFAULTS = {
|
||||
'mode' => nil,
|
||||
'overwrite' => false,
|
||||
'text' => nil,
|
||||
'show' => :pos,
|
||||
'wrap' => 'char',
|
||||
'sync' => true,
|
||||
'prompt' => nil,
|
||||
'prompt_cmd' => nil,
|
||||
'hist_size' => 1000,
|
||||
}
|
||||
|
||||
def create_self(keys)
|
||||
opts = _get_io_params((keys.kind_of?(Hash))? keys: {})
|
||||
|
||||
super(keys)
|
||||
|
||||
self['wrap'] = wrap
|
||||
insert('1.0', text)
|
||||
@count_var = TkVariable.new
|
||||
|
||||
@write_buffer = ''
|
||||
@read_buffer = ''
|
||||
@buf_size = 0
|
||||
@buf_max = 1024
|
||||
|
||||
@write_buf_queue, @write_buf_mutex,
|
||||
@read_buf_queue, @read_buf_mutex = @@create_queues.call
|
||||
|
||||
@idle_flush = TkTimer.new(:idle, 1, proc{ @flusher.run rescue nil })
|
||||
@timer_flush = TkTimer.new(250, -1, proc{ @flusher.run rescue nil })
|
||||
|
||||
@flusher = Thread.new{ loop { Thread.stop; flush() } }
|
||||
|
||||
@receiver = Thread.new{
|
||||
begin
|
||||
loop {
|
||||
str = @write_buf_queue.deq
|
||||
@write_buf_mutex.synchronize { @write_buffer << str }
|
||||
@idle_flush.start
|
||||
}
|
||||
ensure
|
||||
@flusher.kill
|
||||
end
|
||||
}
|
||||
|
||||
@timer_flush.start
|
||||
|
||||
_setup_io(opts)
|
||||
end
|
||||
private :create_self
|
||||
|
||||
def destroy
|
||||
@flusher.kill rescue nil
|
||||
|
||||
@idle_flush.stop rescue nil
|
||||
@timer_flush.stop rescue nil
|
||||
|
||||
@receiver.kill rescue nil
|
||||
|
||||
super()
|
||||
end
|
||||
|
||||
####################################
|
||||
|
||||
def _get_io_params(keys)
|
||||
opts = {}
|
||||
self.class.const_get(:OPT_DEFAULTS).each{|k, v|
|
||||
if keys.has_key?(k)
|
||||
opts[k] = keys.delete(k)
|
||||
else
|
||||
opts[k] = v
|
||||
end
|
||||
}
|
||||
opts
|
||||
end
|
||||
|
||||
def _setup_io(opts)
|
||||
unless defined? @txtpos
|
||||
@txtpos = TkTextMark.new(self, '1.0')
|
||||
else
|
||||
@txtpos.set('1.0')
|
||||
end
|
||||
@txtpos.gravity = :left
|
||||
|
||||
self.show_mode = show
|
||||
|
||||
@sync = true
|
||||
@overwrite = (ovwt)? true: false
|
||||
|
||||
@lineno = 0
|
||||
@line_offset = 0
|
||||
@count_var = TkVariable.new
|
||||
|
||||
@hist_max = opts['hist_size']
|
||||
@hist_index = 0
|
||||
@history = Array.new(@hist_max)
|
||||
@history[0] = ''
|
||||
|
||||
self['wrap'] = wrap
|
||||
|
||||
self.show_mode = opts['show']
|
||||
|
||||
self.value = opts['text'] if opts['text']
|
||||
|
||||
@overwrite = (opts['overwrite'])? true: false
|
||||
|
||||
@sync = opts['sync']
|
||||
|
||||
@prompt = opts['prompt']
|
||||
@prompt_cmd = opts['prompt_cmd']
|
||||
|
||||
@open = {:r => true, :w => true} # default is 'r+'
|
||||
|
||||
case mode
|
||||
when 'r'
|
||||
@console_mode = false
|
||||
@end_of_stream = false
|
||||
@console_buffer = nil
|
||||
|
||||
case opts['mode']
|
||||
when nil
|
||||
# do nothing
|
||||
|
||||
when :console, 'console'
|
||||
@console_mode = true
|
||||
# @console_buffer = TkTextIO.new(:mode=>'r')
|
||||
@console_buffer = self.class.new(:mode=>'r')
|
||||
self.show_mode = :insert
|
||||
|
||||
when 'r', 'rb'
|
||||
@open[:r] = true; @open[:w] = nil
|
||||
|
||||
when 'r+'
|
||||
when 'r+', 'rb+', 'r+b'
|
||||
@open[:r] = true; @open[:w] = true
|
||||
|
||||
when 'w'
|
||||
when 'w', 'wb'
|
||||
@open[:r] = nil; @open[:w] = true
|
||||
self.value=''
|
||||
|
||||
when 'w+'
|
||||
when 'w+', 'wb+', 'w+b'
|
||||
@open[:r] = true; @open[:w] = true
|
||||
self.value=''
|
||||
|
||||
when 'a'
|
||||
when 'a', 'ab'
|
||||
@open[:r] = nil; @open[:w] = true
|
||||
@txtpos = TkTextMark.new(self, 'end - 1 char')
|
||||
@txtpos.set('end - 1 char')
|
||||
@txtpos.gravity = :right
|
||||
|
||||
when 'a+'
|
||||
when 'a+', 'ab+', 'a+b'
|
||||
@open[:r] = true; @open[:w] = true
|
||||
@txtpos = TkTextMark.new(self, 'end - 1 char')
|
||||
@txtpos.set('end - 1 char')
|
||||
@txtpos.gravity = :right
|
||||
|
||||
else
|
||||
fail ArgumentError, "unknown mode `#{opts['mode']}'"
|
||||
end
|
||||
|
||||
unless defined? @ins_head
|
||||
@ins_head = TkTextMark.new(self, 'insert')
|
||||
@ins_head.gravity = :left
|
||||
end
|
||||
|
||||
unless defined? @ins_tail
|
||||
@ins_tail = TkTextMark.new(self, 'insert')
|
||||
@ins_tail.gravity = :right
|
||||
end
|
||||
|
||||
unless defined? @tmp_mark
|
||||
@tmp_mark = TkTextMark.new(self, 'insert')
|
||||
@tmp_mark.gravity = :left
|
||||
end
|
||||
|
||||
if @console_mode
|
||||
_set_console_line
|
||||
_setup_console_bindings
|
||||
end
|
||||
end
|
||||
private :_get_io_params, :_setup_io
|
||||
|
||||
def _set_console_line
|
||||
@tmp_mark.set(@ins_tail)
|
||||
|
||||
mark_set('insert', 'end')
|
||||
|
||||
prompt = ''
|
||||
prompt << @prompt_cmd.call if @prompt_cmd
|
||||
prompt << @prompt if @prompt
|
||||
insert(@tmp_mark, prompt)
|
||||
|
||||
@ins_head.set(@ins_tail)
|
||||
@ins_tail.set('insert')
|
||||
|
||||
@txtpos.set(@tmp_mark)
|
||||
|
||||
_see_pos
|
||||
end
|
||||
|
||||
def _replace_console_line(str)
|
||||
self.delete(@ins_head, @ins_tail)
|
||||
self.insert(@ins_head, str)
|
||||
end
|
||||
|
||||
def _get_console_line
|
||||
@tmp_mark.set(@ins_tail)
|
||||
s = self.get(@ins_head, @tmp_mark)
|
||||
_set_console_line
|
||||
s
|
||||
end
|
||||
private :_set_console_line, :_replace_console_line, :_get_console_line
|
||||
|
||||
def _cb_up
|
||||
@history[@hist_index].replace(self.get(@ins_head, @ins_tail))
|
||||
@hist_index += 1
|
||||
@hist_index -= 1 if @hist_index >= @hist_max || !@history[@hist_index]
|
||||
_replace_console_line(@history[@hist_index]) if @history[@hist_index]
|
||||
Tk.callback_break
|
||||
end
|
||||
def _cb_down
|
||||
@history[@hist_index].replace(self.get(@ins_head, @ins_tail))
|
||||
@hist_index -= 1
|
||||
@hist_index = 0 if @hist_index < 0
|
||||
_replace_console_line(@history[@hist_index]) if @history[@hist_index]
|
||||
Tk.callback_break
|
||||
end
|
||||
def _cb_left
|
||||
if @console_mode && compare('insert', '<=', @ins_head)
|
||||
mark_set('insert', @ins_head)
|
||||
Tk.callback_break
|
||||
end
|
||||
end
|
||||
def _cb_backspace
|
||||
if @console_mode && compare('insert', '<=', @ins_head)
|
||||
Tk.callback_break
|
||||
end
|
||||
end
|
||||
def _cb_ctrl_a
|
||||
if @console_mode
|
||||
mark_set('insert', @ins_head)
|
||||
Tk.callback_break
|
||||
end
|
||||
end
|
||||
private :_cb_up, :_cb_down, :_cb_left, :_cb_backspace, :_cb_ctrl_a
|
||||
|
||||
def _setup_console_bindings
|
||||
@bindtag = TkBindTag.new
|
||||
|
||||
tags = self.bindtags
|
||||
tags[tags.index(self)+1, 0] = @bindtag
|
||||
self.bindtags = tags
|
||||
|
||||
@bindtag.bind('Return'){
|
||||
insert('end - 1 char', "\n")
|
||||
if (str = _get_console_line)
|
||||
@read_buf_queue.push(str)
|
||||
|
||||
@history[0].replace(str.chomp)
|
||||
@history.pop
|
||||
@history.unshift('')
|
||||
@hist_index = 0
|
||||
end
|
||||
|
||||
Tk.update
|
||||
Tk.callback_break
|
||||
}
|
||||
@bindtag.bind('Alt-Return'){
|
||||
Tk.callback_continue
|
||||
}
|
||||
|
||||
@bindtag.bind('FocusIn'){
|
||||
if @console_mode
|
||||
mark_set('insert', @ins_tail)
|
||||
Tk.callback_break
|
||||
end
|
||||
}
|
||||
|
||||
ins_mark = TkTextMark.new(self, 'insert')
|
||||
|
||||
@bindtag.bind('ButtonPress'){
|
||||
if @console_mode
|
||||
ins_mark.set('insert')
|
||||
end
|
||||
}
|
||||
|
||||
@bindtag.bind('ButtonRelease-1'){
|
||||
if @console_mode && compare('insert', '<=', @ins_head)
|
||||
mark_set('insert', ins_mark)
|
||||
Tk.callback_break
|
||||
end
|
||||
}
|
||||
|
||||
@bindtag.bind('ButtonRelease-2', '%x %y'){|x, y|
|
||||
if @console_mode
|
||||
# paste a text at 'insert' only
|
||||
x1, y1, x2, y2 = bbox(ins_mark)
|
||||
unless x == x1 && y == y1
|
||||
Tk.event_generate(self, 'ButtonRelease-2', :x=>x1, :y=>y1)
|
||||
Tk.callback_break
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
@bindtag.bind('Up'){ _cb_up }
|
||||
@bindtag.bind('Control-p'){ _cb_up }
|
||||
|
||||
@bindtag.bind('Down'){ _cb_down }
|
||||
@bindtag.bind('Control-n'){ _cb_down }
|
||||
|
||||
@bindtag.bind('Left'){ _cb_left }
|
||||
@bindtag.bind('Control-b'){ _cb_left }
|
||||
|
||||
@bindtag.bind('BackSpace'){ _cb_backspace }
|
||||
@bindtag.bind('Control-h'){ _cb_backspace }
|
||||
|
||||
@bindtag.bind('Home'){ _cb_ctrl_a }
|
||||
@bindtag.bind('Control-a'){ _cb_ctrl_a }
|
||||
end
|
||||
private :_setup_console_bindings
|
||||
|
||||
def _block_read(size = nil, ret = '', block_mode = true)
|
||||
return '' if size == 0
|
||||
return nil if ! @read_buf_queue && @read_buffer.empty?
|
||||
ret = '' unless ret.kind_of?(String)
|
||||
ret.replace('') unless ret.empty?
|
||||
|
||||
if block_mode == nil # partial
|
||||
if @read_buffer.empty?
|
||||
ret << @read_buffer.slice!(0..-1)
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
if size.kind_of?(Numeric)
|
||||
loop{
|
||||
@read_buf_mutex.synchronize {
|
||||
buf_len = @read_buffer.length
|
||||
if buf_len >= size
|
||||
ret << @read_buffer.slice!(0, size)
|
||||
return ret
|
||||
else
|
||||
ret << @read_buffer.slice!(0..-1)
|
||||
size -= buf_len
|
||||
return ret unless @read_buf_queue
|
||||
end
|
||||
}
|
||||
@read_buffer << @read_buf_queue.pop
|
||||
}
|
||||
else # readline
|
||||
rs = (size)? size: $/
|
||||
rs = rs.to_s if rs.kind_of?(Regexp)
|
||||
loop{
|
||||
@read_buf_mutex.synchronize {
|
||||
if (str = @read_buffer.slice!(/\A(.*)(#{rs})/m))
|
||||
ret << str
|
||||
return ret
|
||||
else
|
||||
ret << @read_buffer.slice!(0..-1)
|
||||
return ret unless @read_buf_queue
|
||||
end
|
||||
}
|
||||
@read_buffer << @read_buf_queue.pop
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def _block_write
|
||||
###### currently, not support
|
||||
end
|
||||
private :_block_read, :_block_write
|
||||
|
||||
####################################
|
||||
|
||||
def <<(obj)
|
||||
_write(obj)
|
||||
|
@ -107,14 +414,15 @@ class TkTextIO < TkText
|
|||
nil
|
||||
end
|
||||
|
||||
def closed?
|
||||
close_read? && close_write?
|
||||
end
|
||||
def closed_read?
|
||||
def closed?(dir=nil)
|
||||
case dir
|
||||
when :r, 'r'
|
||||
!@open[:r]
|
||||
end
|
||||
def closed_write?
|
||||
when :w, 'w'
|
||||
!@open[:w]
|
||||
else
|
||||
!@open[:r] && !@open[:w]
|
||||
end
|
||||
end
|
||||
|
||||
def _check_readable
|
||||
|
@ -129,7 +437,7 @@ class TkTextIO < TkText
|
|||
|
||||
def each_line(rs = $/)
|
||||
_check_readable
|
||||
while(s = gets)
|
||||
while(s = self.gets(rs))
|
||||
yield(s)
|
||||
end
|
||||
self
|
||||
|
@ -138,7 +446,7 @@ class TkTextIO < TkText
|
|||
|
||||
def each_char
|
||||
_check_readable
|
||||
while(c = getc)
|
||||
while(c = self.getc)
|
||||
yield(c)
|
||||
end
|
||||
self
|
||||
|
@ -151,7 +459,7 @@ class TkTextIO < TkText
|
|||
alias eof eof?
|
||||
|
||||
def fcntl(*args)
|
||||
fail NotImplementedError, 'fcntl is not implemented on TkTextIO'
|
||||
fail NotImplementedError, "fcntl is not implemented on #{self.class}"
|
||||
end
|
||||
|
||||
def fsync
|
||||
|
@ -163,11 +471,19 @@ class TkTextIO < TkText
|
|||
end
|
||||
|
||||
def flush
|
||||
Tk.update if @open[:w] && @sync
|
||||
Thread.pass
|
||||
if @open[:w] || ! @write_buffer.empty?
|
||||
@write_buf_mutex.synchronize {
|
||||
_sync_write_buf(@write_buffer)
|
||||
@write_buffer[0..-1] = ''
|
||||
}
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
def getc
|
||||
return _block_read(1) if @console_mode
|
||||
|
||||
_check_readable
|
||||
return nil if eof?
|
||||
c = get(@txtpos)
|
||||
|
@ -177,6 +493,8 @@ class TkTextIO < TkText
|
|||
end
|
||||
|
||||
def gets(rs = $/)
|
||||
return _block_read(rs) if @console_mode
|
||||
|
||||
_check_readable
|
||||
return nil if eof?
|
||||
_readline(rs)
|
||||
|
@ -233,7 +551,6 @@ class TkTextIO < TkText
|
|||
alias tell pos
|
||||
|
||||
def pos=(idx)
|
||||
# @txtpos.set((idx.kind_of?(Numeric))? "1.0 + #{idx} char": idx)
|
||||
seek(idx, IO::SEEK_SET)
|
||||
idx
|
||||
end
|
||||
|
@ -306,6 +623,8 @@ class TkTextIO < TkText
|
|||
private :_read
|
||||
|
||||
def read(len=nil, buf=nil)
|
||||
return _block_read(len, buf) if @console_mode
|
||||
|
||||
_check_readable
|
||||
if len
|
||||
return "" if len == 0
|
||||
|
@ -321,6 +640,8 @@ class TkTextIO < TkText
|
|||
end
|
||||
|
||||
def readchar
|
||||
return _block_read(1) if @console_mode
|
||||
|
||||
_check_readable
|
||||
fail EOFError if eof?
|
||||
c = get(@txtpos)
|
||||
|
@ -334,6 +655,7 @@ class TkTextIO < TkText
|
|||
s = get(@txtpos, 'end - 1 char')
|
||||
@txtpos.set('end - 1 char')
|
||||
elsif rs == ''
|
||||
@count_var.value # make it global
|
||||
idx = tksearch_with_count([:regexp], @count_var,
|
||||
"\n(\n)+", @txtpos, 'end - 1 char')
|
||||
if idx
|
||||
|
@ -345,6 +667,7 @@ class TkTextIO < TkText
|
|||
@txtpos.set('end - 1 char')
|
||||
end
|
||||
else
|
||||
@count_var.value # make it global
|
||||
idx = tksearch_with_count(@count_var, rs, @txtpos, 'end - 1 char')
|
||||
if idx
|
||||
s = get(@txtpos, "#{idx} + #{@count_var.value} char")
|
||||
|
@ -363,12 +686,22 @@ class TkTextIO < TkText
|
|||
private :_readline
|
||||
|
||||
def readline(rs = $/)
|
||||
return _block_readline(rs) if @console_mode
|
||||
|
||||
_check_readable
|
||||
fail EOFError if eof?
|
||||
_readline(rs)
|
||||
end
|
||||
|
||||
def readlines(rs = $/)
|
||||
if @console_mode
|
||||
lines = []
|
||||
while (line = _block_readline(rs))
|
||||
lines << line
|
||||
end
|
||||
return lines
|
||||
end
|
||||
|
||||
_check_readable
|
||||
lines = []
|
||||
until(eof?)
|
||||
|
@ -379,7 +712,11 @@ class TkTextIO < TkText
|
|||
end
|
||||
|
||||
def readpartial(maxlen, buf=nil)
|
||||
#return @console_buffer.readpartial(maxlen, buf) if @console_mode
|
||||
return _block_read(maxlen, buf, nil) if @console_mode
|
||||
|
||||
_check_readable
|
||||
fail EOFError if eof?
|
||||
s = _read(maxlen)
|
||||
buf.replace(s) if buf.kind_of?(String)
|
||||
s
|
||||
|
@ -471,6 +808,8 @@ class TkTextIO < TkText
|
|||
end
|
||||
|
||||
def sysread(len, buf=nil)
|
||||
return _block_read(len, buf) if @console_mode
|
||||
|
||||
_check_readable
|
||||
fail EOFError if eof?
|
||||
s = _read(len)
|
||||
|
@ -492,6 +831,13 @@ class TkTextIO < TkText
|
|||
end
|
||||
|
||||
def ungetc(c)
|
||||
if @console_mode
|
||||
@read_buf_mutex.synchronize {
|
||||
@read_buffer[0,0] = c.chr
|
||||
}
|
||||
return nil
|
||||
end
|
||||
|
||||
_check_readable
|
||||
c = c.chr if c.kind_of?(Fixnum)
|
||||
if compare(@txtpos, '>', '1.0')
|
||||
|
@ -506,8 +852,10 @@ class TkTextIO < TkText
|
|||
nil
|
||||
end
|
||||
|
||||
=begin
|
||||
def _write(obj)
|
||||
s = _get_eval_string(obj)
|
||||
#s = _get_eval_string(obj)
|
||||
s = (obj.kind_of?(String))? obj: obj.to_s
|
||||
n = number(tk_call('string', 'length', s))
|
||||
delete(@txtpos, @txtpos + "#{n} char") if @overwrite
|
||||
self.insert(@txtpos, s)
|
||||
|
@ -518,6 +866,37 @@ class TkTextIO < TkText
|
|||
n
|
||||
end
|
||||
private :_write
|
||||
=end
|
||||
#=begin
|
||||
def _sync_write_buf(s)
|
||||
if (n = number(tk_call('string', 'length', s))) > 0
|
||||
delete(@txtpos, @txtpos + "#{n} char") if @overwrite
|
||||
self.insert(@txtpos, s)
|
||||
#Tk.update
|
||||
|
||||
@txtpos.set(@txtpos + "#{n} char")
|
||||
@txtpos.set('end - 1 char') if compare(@txtpos, '>=', :end)
|
||||
|
||||
@ins_head.set(@txtpos) if compare(@txtpos, '>', @ins_head)
|
||||
|
||||
_see_pos
|
||||
end
|
||||
self
|
||||
end
|
||||
private :_sync_write_buf
|
||||
|
||||
def _write(obj)
|
||||
s = (obj.kind_of?(String))? obj: obj.to_s
|
||||
n = number(tk_call('string', 'length', s))
|
||||
@write_buf_queue.enq(s)
|
||||
if @sync
|
||||
Thread.pass
|
||||
Tk.update
|
||||
end
|
||||
n
|
||||
end
|
||||
private :_write
|
||||
#=end
|
||||
|
||||
def write(obj)
|
||||
_check_writable
|
||||
|
@ -529,13 +908,19 @@ end
|
|||
# TEST
|
||||
####################
|
||||
if __FILE__ == $0
|
||||
ev_loop = Thread.new{Tk.mainloop}
|
||||
|
||||
f = TkFrame.new.pack
|
||||
tio = TkTextIO.new(f, :show=>:pos,
|
||||
#tio = TkTextIO.new(f, :show=>:nil,
|
||||
#tio = TkTextIO.new(f, :show=>:pos,
|
||||
tio = TkTextIO.new(f, :show=>:insert,
|
||||
:text=>">>> This is an initial text line. <<<\n\n"){
|
||||
yscrollbar(TkScrollbar.new(f).pack(:side=>:right, :fill=>:y))
|
||||
# yscrollbar(TkScrollbar.new(f).pack(:side=>:right, :fill=>:y))
|
||||
pack(:side=>:left, :fill=>:both, :expand=>true)
|
||||
}
|
||||
|
||||
Tk.update
|
||||
|
||||
$stdin = tio
|
||||
$stdout = tio
|
||||
$stderr = tio
|
||||
|
@ -599,5 +984,67 @@ if __FILE__ == $0
|
|||
|
||||
tio.seek(0, IO::SEEK_END)
|
||||
|
||||
Tk.mainloop
|
||||
STDOUT.print("tio.sync == #{tio.sync}\n")
|
||||
# tio.sync = false
|
||||
# STDOUT.print("tio.sync == #{tio.sync}\n")
|
||||
|
||||
(0..10).each{|i|
|
||||
STDOUT.print("#{i}\n")
|
||||
s = ''
|
||||
(0..1000).each{ s << '*' }
|
||||
print(s)
|
||||
}
|
||||
print("\n")
|
||||
print("\n=========================================================\n\n")
|
||||
|
||||
s = ''
|
||||
timer = TkTimer.new(:idle, -1, proc{
|
||||
#STDOUT.print("idle call\n")
|
||||
unless s.empty?
|
||||
print(s)
|
||||
s = ''
|
||||
end
|
||||
}).start
|
||||
(0..10).each{|i|
|
||||
STDOUT.print("#{i}\n")
|
||||
(0..1000).each{ s << '*' }
|
||||
}
|
||||
# timer.stop
|
||||
until s.empty?
|
||||
sleep 0.1
|
||||
end
|
||||
timer.stop
|
||||
|
||||
=begin
|
||||
tio.sync = false
|
||||
print("\n")
|
||||
#(0..10000).each{ putc('*') }
|
||||
(0..10).each{|i|
|
||||
STDOUT.print("#{i}\n")
|
||||
(0..1000).each{ putc('*') }
|
||||
}
|
||||
|
||||
(0..10).each{|i|
|
||||
STDOUT.print("#{i}\n")
|
||||
s = ''
|
||||
(0..1000).each{ s << '*' }
|
||||
print(s)
|
||||
}
|
||||
=end
|
||||
|
||||
num = 0
|
||||
# io = TkTextIO.new(:mode=>:console, :prompt=>'').pack
|
||||
#=begin
|
||||
io = TkTextIO.new(:mode=>:console,
|
||||
:prompt_cmd=>proc{
|
||||
s = "[#{num}]"
|
||||
num += 1
|
||||
s
|
||||
},
|
||||
:prompt=>'-> ').pack
|
||||
#=end
|
||||
Thread.new{loop{sleep 2; io.puts 'hoge'}}
|
||||
Thread.new{loop{p io.gets}}
|
||||
|
||||
ev_loop.join
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue