1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/ext/tk/lib/tktext.rb
nagai ea03c3fc2c configure.in, eval.c, signal.c: : add '--with-pthread-ext' option
to fix the pthread trouble on 'tcltklib'
ext/tcltklib/README.1st: add the description of '--with-pthread-ext'
ext/tk/lib/tktext.rb : add TkText#text_copy, text_cut, text_paste to
        support Tcl/Tk8.4's tk_textCopy, tk_textCut, tk_textPaste
ext/tk/lib/tk.rb : add TkMenu#set_focus support Tcl/Tk's tk_menuSetFocus


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4904 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2003-11-05 14:00:11 +00:00

1299 lines
29 KiB
Ruby

#
# tktext.rb - Tk text classes
# $Date$
# by Yukihiro Matsumoto <matz@caelum.co.jp>
require 'tk.rb'
require 'tkfont'
module TkTreatTextTagFont
include TkTreatItemFont
ItemCMD = ['tag'.freeze, 'configure'.freeze].freeze
def __conf_cmd(idx)
ItemCMD[idx]
end
def __item_pathname(tagOrId)
if tagOrId.kind_of?(TkTextTag)
self.path + ';' + tagOrId.id
else
self.path + ';' + tagOrId
end
end
end
class TkText<TkTextWin
ItemConfCMD = ['tag'.freeze, 'configure'.freeze].freeze
include TkTreatTextTagFont
include Scrollable
TkCommandNames = ['text'.freeze].freeze
WidgetClassName = 'Text'.freeze
WidgetClassNames[WidgetClassName] = self
def self.new(*args, &block)
obj = super(*args){}
obj.init_instance_variable
obj.instance_eval(&block) if defined? yield
obj
end
def init_instance_variable
@cmdtbl = []
@tags = {}
end
def __destroy_hook__
TTagID_TBL.delete(@path)
TMarkID_TBL.delete(@path)
end
def create_self(keys)
if keys and keys != None
tk_call 'text', @path, *hash_kv(keys)
else
tk_call 'text', @path
end
init_instance_variable
end
def index(index)
tk_send 'index', index
end
def value
tk_send 'get', "1.0", "end - 1 char"
end
def value= (val)
tk_send 'delete', "1.0", 'end'
tk_send 'insert', "1.0", val
end
def _addcmd(cmd)
@cmdtbl.push cmd
end
def _addtag(name, obj)
@tags[name] = obj
end
def tagid2obj(tagid)
if @tags[tagid]
@tags[tagid]
else
tagid
end
end
def tag_names(index=None)
tk_split_simplelist(tk_send('tag', 'names', index)).collect{|elt|
tagid2obj(elt)
}
end
def mark_names
tk_split_simplelist(tk_send('mark', 'names')).collect{|elt|
tagid2obj(elt)
}
end
def mark_gravity(mark, direction=nil)
if direction
tk_send 'mark', 'gravity', mark, direction
self
else
tk_send 'mark', 'gravity', mark
end
end
def mark_set(mark, index)
tk_send 'mark', 'set', mark, index
self
end
alias set_mark mark_set
def mark_unset(*marks)
tk_send 'mark', 'unset', *marks
self
end
alias unset_mark mark_unset
def mark_next(index)
tagid2obj(tk_send('mark', 'next', index))
end
alias next_mark mark_next
def mark_previous(index)
tagid2obj(tk_send('mark', 'previous', index))
end
alias previous_mark mark_previous
def image_cget(index, slot)
case slot.to_s
when 'text', 'label', 'show', 'data', 'file'
tk_send('image', 'cget', index, "-#{slot}")
else
tk_tcl2ruby(tk_send('image', 'cget', index, "-#{slot}"))
end
end
def image_configure(index, slot, value=None)
if slot.kind_of? Hash
tk_send('image', 'configure', index, *hash_kv(slot))
else
tk_send('image', 'configure', index, "-#{slot}", value)
end
self
end
def image_configinfo(index, slot = nil)
if slot
case slot.to_s
when 'text', 'label', 'show', 'data', 'file'
conf = tk_split_simplelist(tk_send('image', 'configure',
index, "-#{slot}"))
else
conf = tk_split_list(tk_send('image', 'configure',
index, "-#{slot}"))
end
conf[0] = conf[0][1..-1]
conf
else
tk_split_simplelist(tk_send('image', 'configure',
index)).collect{|conflist|
conf = tk_split_simplelist(conflist)
conf[0] = conf[0][1..-1]
case conf[0]
when 'text', 'label', 'show', 'data', 'file'
else
if conf[3]
if conf[3].index('{')
conf[3] = tk_split_list(conf[3])
else
conf[3] = tk_tcl2ruby(conf[3])
end
end
if conf[4]
if conf[4].index('{')
conf[4] = tk_split_list(conf[4])
else
conf[4] = tk_tcl2ruby(conf[4])
end
end
end
conf
}
end
end
def image_names
tk_split_simplelist(tk_send('image', 'names')).collect{|elt|
tagid2obj(elt)
}
end
def set_insert(index)
tk_send 'mark', 'set', 'insert', index
self
end
def set_current(index)
tk_send 'mark', 'set', 'current', index
self
end
def insert(index, chars, *tags)
if tags[0].kind_of? Array
# multiple chars-taglist argument
args = [chars]
while tags.size > 0
tags.shift.collect{|x|_get_eval_string(x)}.join(' ') # taglist
args << tags.shift if tags.size > 0 # chars
end
super index, *args
else
# single chars-taglist argument
super index, chars, tags.collect{|x|_get_eval_string(x)}.join(' ')
end
end
def destroy
@tags = {} unless @tags
@tags.each_value do |t|
t.destroy
end
super
end
def backspace
self.delete 'insert'
end
def compare(idx1, op, idx2)
bool(tk_send('compare', idx1, op, idx2))
end
def debug
bool(tk_send('debug'))
end
def debug=(boolean)
tk_send 'debug', boolean
self
end
def bbox(index)
list(tk_send('bbox', index))
end
def dlineinfo(index)
list(tk_send('dlineinfo', index))
end
def modified?
bool(tk_send('edit', 'modified'))
end
def modified(mode)
tk_send('edit', 'modified', mode)
self
end
def edit_redo
tk_send('edit', 'redo')
self
end
def edit_reset
tk_send('edit', 'reset')
self
end
def edit_separator
tk_send('edit', 'separator')
self
end
def edit_undo
tk_send('edit', 'undo')
self
end
def yview_pickplace(*what)
tk_send 'yview', '-pickplace', *what
self
end
def xview_pickplace(*what)
tk_send 'xview', '-pickplace', *what
self
end
def text_copy
# Tk8.4 feature
tk_call('tk_textCopy', @path)
end
def text_cut
# Tk8.4 feature
tk_call('tk_textCut', @path)
end
def text_paste
# Tk8.4 feature
tk_call('tk_textPaste', @path)
end
def tag_add(tag, index1, index2=None)
tk_send 'tag', 'add', tag, index1, index2
self
end
alias addtag tag_add
alias add_tag tag_add
def tag_delete(*tags)
tk_send 'tag', 'delete', *tags
if TkTextTag::TTagID_TBL[@path]
tags.each{|tag|
if tag.kind_of? TkTextTag
TTagID_TBL[@path].delete(tag.id)
else
TTagID_TBL[@path].delete(tag)
end
}
end
self
end
alias deltag tag_delete
alias delete_tag tag_delete
def tag_bind(tag, seq, cmd=Proc.new, args=nil)
_bind([@path, 'tag', 'bind', tag], seq, cmd, args)
self
end
def tag_bind_append(tag, seq, cmd=Proc.new, args=nil)
_bind_append([@path, 'tag', 'bind', tag], seq, cmd, args)
self
end
def tag_bind_remove(tag, seq)
_bind_remove([@path, 'tag', 'bind', tag], seq)
self
end
def tag_bindinfo(tag, context=nil)
_bindinfo([@path, 'tag', 'bind', tag], context)
end
def tag_cget(tag, key)
case key.to_s
when 'text', 'label', 'show', 'data', 'file'
tk_call(@path, 'tag', 'cget', tag, "-#{key}")
when 'font', 'kanjifont'
#fnt = tk_tcl2ruby(tk_send('tag', 'cget', tag, "-#{key}"))
fnt = tk_tcl2ruby(tk_send('tag', 'cget', tag, '-font'))
unless fnt.kind_of?(TkFont)
fnt = tagfontobj(tag, fnt)
end
if key.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/
# obsolete; just for compatibility
fnt.kanji_font
else
fnt
end
else
tk_tcl2ruby(tk_call(@path, 'tag', 'cget', tag, "-#{key}"))
end
end
def tag_configure(tag, key, val=None)
if key.kind_of? Hash
key = _symbolkey2str(key)
if ( key['font'] || key['kanjifont'] \
|| key['latinfont'] || key['asciifont'] )
tagfont_configure(tag, key)
else
tk_send 'tag', 'configure', tag, *hash_kv(key)
end
else
if key == 'font' || key == :font ||
key == 'kanjifont' || key == :kanjifont ||
key == 'latinfont' || key == :latinfont ||
key == 'asciifont' || key == :asciifont
if val == None
tagfontobj(tag)
else
tagfont_configure(tag, {key=>val})
end
else
tk_send 'tag', 'configure', tag, "-#{key}", val
end
end
self
end
def tag_configinfo(tag, key=nil)
if key
case key.to_s
when 'text', 'label', 'show', 'data', 'file'
conf = tk_split_simplelist(tk_send('tag','configure',tag,"-#{key}"))
when 'font', 'kanjifont'
conf = tk_split_simplelist(tk_send('tag','configure',tag,"-#{key}") )
conf[4] = tagfont_configinfo(tag, conf[4])
else
conf = tk_split_list(tk_send('tag','configure',tag,"-#{key}"))
end
conf[0] = conf[0][1..-1]
conf
else
ret = tk_split_simplelist(tk_send('tag', 'configure',
tag)).collect{|conflist|
conf = tk_split_simplelist(conflist)
conf[0] = conf[0][1..-1]
case conf[0]
when 'text', 'label', 'show', 'data', 'file'
else
if conf[3]
if conf[3].index('{')
conf[3] = tk_split_list(conf[3])
else
conf[3] = tk_tcl2ruby(conf[3])
end
end
if conf[4]
if conf[4].index('{')
conf[4] = tk_split_list(conf[4])
else
conf[4] = tk_tcl2ruby(conf[4])
end
end
end
conf
}
fontconf = ret.assoc('font')
if fontconf
ret.delete_if{|item| item[0] == 'font' || item[0] == 'kanjifont'}
fontconf[4] = tagfont_configinfo(tag, fontconf[4])
ret.push(fontconf)
else
ret
end
end
end
def tag_raise(tag, above=None)
tk_send 'tag', 'raise', tag, above
self
end
def tag_lower(tag, below=None)
tk_send 'tag', 'lower', tag, below
self
end
def tag_remove(tag, *index)
tk_send 'tag', 'remove', tag, *index
self
end
def tag_ranges(tag)
l = tk_split_simplelist(tk_send('tag', 'ranges', tag))
r = []
while key=l.shift
r.push [key, l.shift]
end
r
end
def tag_nextrange(tag, first, last=None)
tk_split_list(tk_send('tag', 'nextrange', tag, first, last))
end
def tag_prevrange(tag, first, last=None)
tk_split_list(tk_send('tag', 'prevrange', tag, first, last))
end
def window_cget(index, slot)
case slot.to_s
when 'text', 'label', 'show', 'data', 'file'
tk_send('window', 'cget', index, "-#{slot}")
when 'font', 'kanjifont'
#fnt = tk_tcl2ruby(tk_send('window', 'cget', index, "-#{slot}"))
fnt = tk_tcl2ruby(tk_send('window', 'cget', index, '-font'))
unless fnt.kind_of?(TkFont)
fnt = tagfontobj(index, fnt)
end
if slot.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/
# obsolete; just for compatibility
fnt.kanji_font
else
fnt
end
else
tk_tcl2ruby(tk_send('window', 'cget', index, "-#{slot}"))
end
end
def window_configure(index, slot, value=None)
if index.kind_of? TkTextWindow
index.configure(slot, value)
else
if slot.kind_of? Hash
tk_send('window', 'configure', index, *hash_kv(slot))
else
tk_send('window', 'configure', index, "-#{slot}", value)
end
end
self
end
def window_configinfo(win, slot = nil)
if slot
case slot.to_s
when 'text', 'label', 'show', 'data', 'file'
conf = tk_split_simplelist(tk_send('window', 'configure',
win, "-#{slot}"))
else
conf = tk_split_list(tk_send('window', 'configure',
win, "-#{slot}"))
end
conf[0] = conf[0][1..-1]
conf
else
tk_split_simplelist(tk_send('window', 'configure',
win)).collect{|conflist|
conf = tk_split_simplelist(conflist)
conf[0] = conf[0][1..-1]
case conf[0]
when 'text', 'label', 'show', 'data', 'file'
else
if conf[3]
if conf[3].index('{')
conf[3] = tk_split_list(conf[3])
else
conf[3] = tk_tcl2ruby(conf[3])
end
end
if conf[4]
if conf[4].index('{')
conf[4] = tk_split_list(conf[4])
else
conf[4] = tk_tcl2ruby(conf[4])
end
end
end
conf
}
end
end
def window_names
tk_split_simplelist(tk_send('window', 'names')).collect{|elt|
tagid2obj(elt)
}
end
def _ktext_length(txt)
if $KCODE !~ /n/i
return txt.gsub(/[^\Wa-zA-Z_\d]/, ' ').length
end
# $KCODE == 'NONE'
if JAPANIZED_TK
tk_call('kstring', 'length', txt).to_i
else
begin
tk_call('encoding', 'convertto', 'ascii', txt).length
rescue StandardError, NameError
# sorry, I have no plan
txt.length
end
end
end
private :_ktext_length
def search_with_length(pat,start,stop=None)
pat = pat.chr if pat.kind_of? Integer
if stop != None
return ["", 0] if compare(start,'>=',stop)
txt = get(start,stop)
if (pos = txt.index(pat))
match = $&
#pos = txt[0..(pos-1)].split('').length if pos > 0
pos = _ktext_length(txt[0..(pos-1)]) if pos > 0
if pat.kind_of? String
#return [index(start + " + #{pos} chars"), pat.split('').length]
return [index(start + " + #{pos} chars"),
_ktext_length(pat), pat.dup]
else
#return [index(start + " + #{pos} chars"), $&.split('').length]
return [index(start + " + #{pos} chars"),
_ktext_length(match), match]
end
else
return ["", 0]
end
else
txt = get(start,'end - 1 char')
if (pos = txt.index(pat))
match = $&
#pos = txt[0..(pos-1)].split('').length if pos > 0
pos = _ktext_length(txt[0..(pos-1)]) if pos > 0
if pat.kind_of? String
#return [index(start + " + #{pos} chars"), pat.split('').length]
return [index(start + " + #{pos} chars"),
_ktext_length(pat), pat.dup]
else
#return [index(start + " + #{pos} chars"), $&.split('').length]
return [index(start + " + #{pos} chars"),
_ktext_length(match), match]
end
else
txt = get('1.0','end - 1 char')
if (pos = txt.index(pat))
match = $&
#pos = txt[0..(pos-1)].split('').length if pos > 0
pos = _ktext_length(txt[0..(pos-1)]) if pos > 0
if pat.kind_of? String
#return [index("1.0 + #{pos} chars"), pat.split('').length]
return [index("1.0 + #{pos} chars"),
_ktext_length(pat), pat.dup]
else
#return [index("1.0 + #{pos} chars"), $&.split('').length]
return [index("1.0 + #{pos} chars"), _ktext_length(match), match]
end
else
return ["", 0]
end
end
end
end
def search(pat,start,stop=None)
search_with_length(pat,start,stop)[0]
end
def rsearch_with_length(pat,start,stop=None)
pat = pat.chr if pat.kind_of? Integer
if stop != None
return ["", 0] if compare(start,'<=',stop)
txt = get(stop,start)
if (pos = txt.rindex(pat))
match = $&
#pos = txt[0..(pos-1)].split('').length if pos > 0
pos = _ktext_length(txt[0..(pos-1)]) if pos > 0
if pat.kind_of? String
#return [index(stop + " + #{pos} chars"), pat.split('').length]
return [index(stop + " + #{pos} chars"), _ktext_length(pat), pat.dup]
else
#return [index(stop + " + #{pos} chars"), $&.split('').length]
return [index(stop + " + #{pos} chars"), _ktext_length(match), match]
end
else
return ["", 0]
end
else
txt = get('1.0',start)
if (pos = txt.rindex(pat))
match = $&
#pos = txt[0..(pos-1)].split('').length if pos > 0
pos = _ktext_length(txt[0..(pos-1)]) if pos > 0
if pat.kind_of? String
#return [index("1.0 + #{pos} chars"), pat.split('').length]
return [index("1.0 + #{pos} chars"), _ktext_length(pat), pat.dup]
else
#return [index("1.0 + #{pos} chars"), $&.split('').length]
return [index("1.0 + #{pos} chars"), _ktext_length(match), match]
end
else
txt = get('1.0','end - 1 char')
if (pos = txt.rindex(pat))
match = $&
#pos = txt[0..(pos-1)].split('').length if pos > 0
pos = _ktext_length(txt[0..(pos-1)]) if pos > 0
if pat.kind_of? String
#return [index("1.0 + #{pos} chars"), pat.split('').length]
return [index("1.0 + #{pos} chars"), _ktext_length(pat), pat.dup]
else
#return [index("1.0 + #{pos} chars"), $&.split('').length]
return [index("1.0 + #{pos} chars"), _ktext_length(match), match]
end
else
return ["", 0]
end
end
end
end
def rsearch(pat,start,stop=None)
rsearch_with_length(pat,start,stop)[0]
end
def dump(type_info, *index, &block)
args = type_info.collect{|inf| '-' + inf}
args << '-command' << block if block
str = tk_send('dump', *(args + index))
result = []
sel = nil
i = 0
while i < str.size
# retrieve key
idx = str.index(/ /, i)
result.push str[i..(idx-1)]
i = idx + 1
# retrieve value
case result[-1]
when 'text'
if str[i] == ?{
# text formed as {...}
val, i = _retrieve_braced_text(str, i)
result.push val
else
# text which may contain backslahes
val, i = _retrieve_backslashed_text(str, i)
result.push val
end
else
idx = str.index(/ /, i)
val = str[i..(idx-1)]
case result[-1]
when 'mark'
case val
when 'insert'
result.push TkTextMarkInsert.new(self)
when 'current'
result.push TkTextMarkCurrent.new(self)
when 'anchor'
result.push TkTextMarkAnchor.new(self)
else
result.push tk_tcl2ruby(val)
end
when 'tagon'
if val == 'sel'
if sel
result.push sel
else
result.push TkTextTagSel.new(self)
end
else
result.push tk_tcl2ruby(val)
end
when 'tagoff'
result.push tk_tcl2ruby(val)
when 'window'
result.push tk_tcl2ruby(val)
end
i = idx + 1
end
# retrieve index
idx = str.index(/ /, i)
if idx
result.push str[i..(idx-1)]
i = idx + 1
else
result.push str[i..-1]
break
end
end
kvis = []
until result.empty?
kvis.push [result.shift, result.shift, result.shift]
end
kvis # result is [[key1, value1, index1], [key2, value2, index2], ...]
end
def _retrieve_braced_text(str, i)
cnt = 0
idx = i
while idx < str.size
case str[idx]
when ?{
cnt += 1
when ?}
cnt -= 1
if cnt == 0
break
end
end
idx += 1
end
return str[i+1..idx-1], idx + 2
end
private :_retrieve_braced_text
def _retrieve_backslashed_text(str, i)
j = i
idx = nil
loop {
idx = str.index(/ /, j)
if str[idx-1] == ?\\
j += 1
else
break
end
}
val = str[i..(idx-1)]
val.gsub!(/\\( |\{|\})/, '\1')
return val, idx + 1
end
private :_retrieve_backslashed_text
def dump_all(*index, &block)
dump(['all'], *index, &block)
end
def dump_mark(*index, &block)
dump(['mark'], *index, &block)
end
def dump_tag(*index, &block)
dump(['tag'], *index, &block)
end
def dump_text(*index, &block)
dump(['text'], *index, &block)
end
def dump_window(*index, &block)
dump(['window'], *index, &block)
end
def dump_image(*index, &block)
dump(['image'], *index, &block)
end
end
class TkTextTag<TkObject
include TkTreatTagFont
TTagID_TBL = TkCore::INTERP.create_table
Tk_TextTag_ID = ['tag'.freeze, '00000'.taint].freeze
TkCore::INTERP.init_ip_env{ TTagID_TBL.clear }
def TkTextTag.id2obj(text, id)
tpath = text.path
return id unless TTagID_TBL[tpath]
TTagID_TBL[tpath][id]? TTagID_TBL[tpath][id]: id
end
def initialize(parent, *args)
if not parent.kind_of?(TkText)
fail format("%s need to be TkText", parent.inspect)
end
@parent = @t = parent
@tpath = parent.path
@path = @id = Tk_TextTag_ID.join
TTagID_TBL[@id] = self
TTagID_TBL[@tpath] = {} unless TTagID_TBL[@tpath]
TTagID_TBL[@tpath][@id] = self
Tk_TextTag_ID[1].succ!
#tk_call @t.path, "tag", "configure", @id, *hash_kv(keys)
if args != [] then
keys = args.pop
if keys.kind_of? Hash then
add(*args) if args != []
configure(keys)
else
args.push keys
add(*args)
end
end
@t._addtag id, self
end
def id
@id
end
def first
@id + '.first'
end
def last
@id + '.last'
end
def add(*index)
tk_call @t.path, 'tag', 'add', @id, *index
self
end
def remove(*index)
tk_call @t.path, 'tag', 'remove', @id, *index
self
end
def ranges
l = tk_split_simplelist(tk_call(@t.path, 'tag', 'ranges', @id))
r = []
while key=l.shift
r.push [key, l.shift]
end
r
end
def nextrange(first, last=None)
tk_split_list(tk_call(@t.path, 'tag', 'nextrange', @id, first, last))
end
def prevrange(first, last=None)
tk_split_list(tk_call(@t.path, 'tag', 'prevrange', @id, first, last))
end
def [](key)
cget key
end
def []=(key,val)
configure key, val
end
def cget(key)
case key.to_s
when 'text', 'label', 'show', 'data', 'file'
tk_call @t.path, 'tag', 'cget', @id, "-#{key}"
when 'font', 'kanjifont'
#fnt = tk_tcl2ruby(tk_call(@t.path, 'tag', 'cget', @id, "-#{key}"))
fnt = tk_tcl2ruby(tk_call(@t.path, 'tag', 'cget', @id, '-font'))
unless fnt.kind_of?(TkFont)
fnt = tagfontobj(@id, fnt)
end
if key.to_s == 'kanjifont' && JAPANIZED_TK && TK_VERSION =~ /^4\.*/
# obsolete; just for compatibility
fnt.kanji_font
else
fnt
end
else
tk_tcl2ruby(tk_call(@t.path, 'tag', 'cget', @id, "-#{key}"))
end
end
def configure(key, val=None)
@t.tag_configure @id, key, val
end
# def configure(key, val=None)
# if key.kind_of? Hash
# tk_call @t.path, 'tag', 'configure', @id, *hash_kv(key)
# else
# tk_call @t.path, 'tag', 'configure', @id, "-#{key}", val
# end
# end
# def configure(key, value)
# if value == FALSE
# value = "0"
# elsif value.kind_of? Proc
# value = install_cmd(value)
# end
# tk_call @t.path, 'tag', 'configure', @id, "-#{key}", value
# end
def configinfo(key=nil)
@t.tag_configinfo @id, key
end
def bind(seq, cmd=Proc.new, args=nil)
_bind([@t.path, 'tag', 'bind', @id], seq, cmd, args)
self
end
def bind_append(seq, cmd=Proc.new, args=nil)
_bind_append([@t.path, 'tag', 'bind', @id], seq, cmd, args)
self
end
def bind_remove(seq)
_bind_remove([@t.path, 'tag', 'bind', @id], seq)
self
end
def bindinfo(context=nil)
_bindinfo([@t.path, 'tag', 'bind', @id], context)
end
def raise(above=None)
tk_call @t.path, 'tag', 'raise', @id, above
self
end
def lower(below=None)
tk_call @t.path, 'tag', 'lower', @id, below
self
end
def destroy
tk_call @t.path, 'tag', 'delete', @id
TTagID_TBL[@tpath].delete(@id) if TTagID_TBL[@tpath]
self
end
end
class TkTextNamedTag<TkTextTag
def self.new(parent, name, *args)
if TTagID_TBL[parent.path] && TTagID_TBL[parent.path][name]
tagobj = TTagID_TBL[parent.path][name]
if args != [] then
keys = args.pop
if keys.kind_of? Hash then
tagobj.add(*args) if args != []
tagobj.configure(keys)
else
args.push keys
tagobj.add(*args)
end
end
return tagobj
else
super(parent, name, *args)
end
end
def initialize(parent, name, *args)
if not parent.kind_of?(TkText)
fail format("%s need to be TkText", parent.inspect)
end
@parent = @t = parent
@tpath = parent.path
@path = @id = name
TTagID_TBL[@tpath] = {} unless TTagID_TBL[@tpath]
TTagID_TBL[@tpath][@id] = self unless TTagID_TBL[@tpath][@id]
#if mode
# tk_call @t.path, "addtag", @id, *args
#end
if args != [] then
keys = args.pop
if keys.kind_of? Hash then
add(*args) if args != []
configure(keys)
else
args.push keys
add(*args)
end
end
@t._addtag id, self
end
end
class TkTextTagSel<TkTextNamedTag
def self.new(parent, *args)
super(parent, 'sel', *args)
end
end
class TkTextMark<TkObject
TMarkID_TBL = TkCore::INTERP.create_table
Tk_TextMark_ID = ['mark'.freeze, '00000'.taint].freeze
TkCore::INTERP.init_ip_env{ TMarkID_TBL.clear }
def TkTextMark.id2obj(text, id)
tpath = text.path
return id unless TMarkID_TBL[tpath]
TMarkID_TBL[tpath][id]? TMarkID_TBL[tpath][id]: id
end
def initialize(parent, index)
if not parent.kind_of?(TkText)
fail format("%s need to be TkText", parent.inspect)
end
@parent = @t = parent
@tpath = parent.path
@path = @id = Tk_TextMark_ID.join
TMarkID_TBL[@id] = self
TMarkID_TBL[@tpath] = {} unless TMarkID_TBL[@tpath]
TMarkID_TBL[@tpath][@id] = self
Tk_TextMark_ID[1].succ!
tk_call @t.path, 'mark', 'set', @id, index
@t._addtag id, self
end
def id
@id
end
def +(mod)
@id + ' + ' + mod
end
def -(mod)
@id + ' - ' + mod
end
def set(where)
tk_call @t.path, 'mark', 'set', @id, where
self
end
def unset
tk_call @t.path, 'mark', 'unset', @id
self
end
alias destroy unset
def gravity
tk_call @t.path, 'mark', 'gravity', @id
end
def gravity=(direction)
tk_call @t.path, 'mark', 'gravity', @id, direction
self
end
def next(index = nil)
if index
@t.tagid2obj(tk_call(@t.path, 'mark', 'next', index))
else
@t.tagid2obj(tk_call(@t.path, 'mark', 'next', @id))
end
end
def previous(index = nil)
if index
@t.tagid2obj(tk_call(@t.path, 'mark', 'previous', index))
else
@t.tagid2obj(tk_call(@t.path, 'mark', 'previous', @id))
end
end
end
class TkTextNamedMark<TkTextMark
def self.new(parent, name, *args)
if TMarkID_TBL[parent.path] && TMarkID_TBL[parent.path][name]
return TMarkID_TBL[parent.path][name]
else
super(parent, name, *args)
end
end
def initialize(parent, name, index=nil)
if not parent.kind_of?(TkText)
fail format("%s need to be TkText", parent.inspect)
end
@parent = @t = parent
@tpath = parent.path
@path = @id = name
TMarkID_TBL[@id] = self
TMarkID_TBL[@tpath] = {} unless TMarkID_TBL[@tpath]
TMarkID_TBL[@tpath][@id] = self unless TMarkID_TBL[@tpath][@id]
tk_call @t.path, 'mark', 'set', @id, index if index
@t._addtag id, self
end
end
class TkTextMarkInsert<TkTextNamedMark
def self.new(parent,*args)
super(parent, 'insert', *args)
end
end
class TkTextMarkCurrent<TkTextMark
def self.new(parent,*args)
super(parent, 'current', *args)
end
end
class TkTextMarkAnchor<TkTextMark
def self.new(parent,*args)
super(parent, 'anchor', *args)
end
end
class TkTextWindow<TkObject
def initialize(parent, index, keys)
if not parent.kind_of?(TkText)
fail format("%s need to be TkText", parent.inspect)
end
@t = parent
if index == 'end'
@path = TkTextMark.new(@t, tk_call(@t.path, 'index', 'end - 1 chars'))
elsif index.kind_of? TkTextMark
if tk_call(@t.path,'index',index.path) == tk_call(@t.path,'index','end')
@path = TkTextMark.new(@t, tk_call(@t.path, 'index', 'end - 1 chars'))
else
@path = TkTextMark.new(@t, tk_call(@t.path, 'index', index.path))
end
else
@path = TkTextMark.new(@t, tk_call(@t.path, 'index', index))
end
@path.gravity = 'left'
@index = @path.path
keys = _symbolkey2str(keys)
@id = keys['window']
if keys['create']
@p_create = keys['create']
if @p_create.kind_of? Proc
keys['create'] = install_cmd(proc{@id = @p_create.call; @id.path})
end
end
tk_call @t.path, 'window', 'create', @index, *hash_kv(keys)
end
def [](slot)
cget(slot)
end
def []=(slot, value)
configure(slot, value)
end
def cget(slot)
@t.window_cget(@index, slot)
end
def configure(slot, value=None)
if slot.kind_of? Hash
slot = _symbolkey2str(slot)
@id = slot['window'] if slot['window']
if slot['create']
self.create=value
slot['create']=nil
end
if slot.size > 0
tk_call(@t.path, 'window', 'configure', @index, *hash_kv(slot))
end
else
@id = value if slot == 'window' || slot == :window
if slot == 'create' || slot == :create
self.create=value
else
tk_call(@t.path, 'window', 'configure', @index, "-#{slot}", value)
end
end
self
end
def configinfo(slot = nil)
@t.window_configinfo(@index, slot)
end
def window
@id
end
def window=(value)
tk_call @t.path, 'window', 'configure', @index, '-window', value
@id = value
end
def create
@p_create
end
def create=(value)
@p_create = value
if @p_create.kind_of? Proc
value = install_cmd(proc{@id = @p_create.call})
end
tk_call @t.path, 'window', 'configure', @index, '-create', value
end
end
class TkTextImage<TkObject
def initialize(parent, index, keys)
if not parent.kind_of?(TkText)
fail format("%s need to be TkText", parent.inspect)
end
@t = parent
if index == 'end'
@path = TkTextMark.new(@t, tk_call(@t.path, 'index', 'end - 1 chars'))
elsif index.kind_of? TkTextMark
if tk_call(@t.path,'index',index.path) == tk_call(@t.path,'index','end')
@path = TkTextMark.new(@t, tk_call(@t.path, 'index', 'end - 1 chars'))
else
@path = TkTextMark.new(@t, tk_call(@t.path, 'index', index.path))
end
else
@path = TkTextMark.new(@t, tk_call(@t.path, 'index', index))
end
@path.gravity = 'left'
@index = @path.path
@id = tk_call(@t.path, 'image', 'create', @index, *hash_kv(keys))
end
def [](slot)
cget(slot)
end
def []=(slot, value)
configure(slot, value)
end
def cget(slot)
@t.image_cget(@index, slot)
end
def configure(slot, value=None)
@t.image_configure(@index, slot, value)
self
end
# def configure(slot, value)
# tk_call @t.path, 'image', 'configure', @index, "-#{slot}", value
# end
def configinfo(slot = nil)
@t.image_configinfo(@index, slot)
end
def image
img = tk_call(@t.path, 'image', 'configure', @index, '-image')
TkImage::Tk_IMGTBL[img]? TkImage::Tk_IMGTBL[img] : img
end
def image=(value)
tk_call @t.path, 'image', 'configure', @index, '-image', value
self
end
end