* ext/tcltklib/tcltklib.c: add TclTkIp#_create_console() method to

create a Tcl/Tk's console window.
* ext/tk/lib/multi-tk.rb: support TclTkIp#_create_console() method.
* ext/tk/lib/remote-tk.rb: ditto.
* ext/tk/lib/tk/console.rb: ditto.
* ext/tk/lib/tk.rb: update RELEASE_DATE
* ext/tk/sample/demo-*/check2.rb: use 'return' in the Proc object.
* ext/tk/sample/tkextlib/**: ditto.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@8213 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nagai 2005-03-30 08:44:55 +00:00
parent 496cf2d757
commit 69ef4bae62
16 changed files with 594 additions and 442 deletions

View file

@ -6,401 +6,431 @@
require 'tk'
require 'tkextlib/tkHTML'
root = TkRoot.new(:title=>'HTML File Viewer', :iconname=>'HV')
fswin = nil
html = nil
html_fs = nil
hotkey = {}
file = ARGV[0]
class TkHTML_File_Viewer
include TkComm
# These are images to use with the actual image specified in a
# "<img>" markup can't be found.
#
biggray = TkPhotoImage.new(:data=><<'EOD')
@@biggray = TkPhotoImage.new(:data=><<'EOD')
R0lGODdhPAA+APAAALi4uAAAACwAAAAAPAA+AAACQISPqcvtD6OctNqLs968+w+G4kiW5omm
6sq27gvH8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNFgsAO///
EOD
smgray = TkPhotoImage.new(:data=><<'EOD')
@@smgray = TkPhotoImage.new(:data=><<'EOD')
R0lGODdhOAAYAPAAALi4uAAAACwAAAAAOAAYAAACI4SPqcvtD6OctNqLs968+w+G4kiW5omm
6sq27gvH8kzX9m0VADv/
EOD
def initialize(file = nil)
@root = TkRoot.new(:title=>'HTML File Viewer', :iconname=>'HV')
@fswin = nil
#
# A font chooser routine.
#
# html[:fontcommand] = pick_font
pick_font = proc{|size, attrs|
# puts "FontCmd: #{size} #{attrs}"
[ ((attrs =~ /fixed/)? 'courier': 'charter'),
(12 * (1.2**(size.to_f - 4.0))).to_i,
((attrs =~ /italic/)? 'italic': 'roman'),
((attrs =~ /bold/)? 'bold': 'normal') ].join(' ')
}
@html = nil
@html_fs = nil
# This routine is called to pick fonts for the fullscreen view.
#
baseFontSize = 24
pick_font_fs = proc{|size, attrs|
# puts "FontCmd: #{size} #{attrs}"
[ ((attrs =~ /fixed/)? 'courier': 'charter'),
(baseFontSize * (1.2**(size.to_f - 4.0))).to_i,
((attrs =~ /italic/)? 'italic': 'roman'),
((attrs =~ /bold/)? 'bold': 'normal') ].join(' ')
}
@hotkey = {}
#
#
hyper_cmd = proc{|*args|
puts "HyperlinkCommand: #{args.inspect}"
}
@applet_arg = TkVarAccess.new_hash('AppletArg')
# This routine is called to run an applet
#
applet_arg = TkVarAccess.new_hash('AppletArg')
run_applet = proc{|size, w, arglist|
applet_arg.value = Hash[*simplelist(arglist)]
@images = {}
@old_imgs = {}
@big_imgs = {}
return unless applet_arg.key?('src')
@last_dir = Dir.pwd
src = html.remove(applet_arg['src'])
@last_file = ''
applet_arg['window'] = w
applet_arg['fontsize'] = size
@key_block = false
begin
Tk.load_tclscript(src)
rescue => e
puts "Applet error: #{e.message}"
end
}
Tk::HTML_Widget::ClippingWindow.bind('1',
proc{|w, ksym| key_press(w, ksym)},
'%W Down')
Tk::HTML_Widget::ClippingWindow.bind('3',
proc{|w, ksym| key_press(w, ksym)},
'%W Up')
Tk::HTML_Widget::ClippingWindow.bind('2',
proc{|w, ksym| key_press(w, ksym)},
'%W Down')
#
#
form_cmd = proc{|n, cmd, *args|
}
Tk::HTML_Widget::ClippingWindow.bind('KeyPress',
proc{|w, ksym| key_press(w, ksym)},
'%W %K')
#
#
images = {}
old_imgs = {}
big_imgs = {}
############################################
#
# Build the half-size view of the page
#
menu_spec = [
[['File', 0],
['Open', proc{sel_load()}, 0],
['Full Screen', proc{fullscreen()}, 0],
['Refresh', proc{refresh()}, 0],
'---',
['Exit', proc{exit}, 1]]
]
#
#
move_big_image = proc{|b|
return unless big_imgs.key?(b)
b.copy(big_imgs[b])
big_imgs[b].delete
big_imgs.delete(b)
}
mbar = @root.add_menubar(menu_spec)
image_cmd = proc{|hs, *args|
fn = args[0]
if old_imgs.key?(fn)
return (images[fn] = old_imgs.delete(fn))
end
begin
img = TkPhotoImage.new(:file=>fn)
rescue
return ((hs)? smallgray: biggray)
end
if hs
img2 = TkPhotoImage.new
img2.copy(img, :subsample=>[2,2])
img.delete
img = img2
end
if img.width * img.height > 20000
b = TkPhotoImage.new(:width=>img.width, :height=>img.height)
big_imgs[b] = img
img = b
Tk.after_idle(proc{ move_big_image.call(b) })
end
images[fn] = img
img
}
#
# This routine is called for every <SCRIPT> markup
#
script_cmd = proc{|*args|
# puts "ScriptCmd: #{args.inspect}"
}
# This routine is called for every <APPLET> markup
#
applet_cmd = proc{|w, arglist|
# puts "AppletCmd: w=#{w} arglist=#{arglist}"
#TkLabel.new(w, :text=>"The Applet #{w}", :bd=>2, :relief=>raised)
}
# This binding fires when there is a click on a hyperlink
#
href_binding = proc{|w, x, y|
lst = w.href(x, y)
unless lst.empty?
process_url.call(lst)
end
}
#
#
last_dir = Dir.pwd
load_file = nil
sel_load = proc{
filetypes = [
['Html Files', ['.html', '.htm']],
['All Files', '*']
]
f = Tk.getOpenFile(:initialdir=>last_dir, :filetypes=>filetypes)
if f != ''
load_file.call(f)
last_dir = File.dirname(f)
end
}
# Clear the screen.
#
clear_screen = proc{
if html_fs && html_fs.exist?
w = html_fs
else
w = html
end
w.clear
old_imgs.clear
big_imgs.clear
hotkey.clear
images.each{|k, v| old_imgs[k] = v }
images.clear
}
# Read a file
#
read_file = proc{|name|
begin
fp = open(name, 'r')
ret = fp.read(File.size(name))
rescue
ret = nil
fp = nil
Tk.messageBox(:icon=>'error', :message=>"fail to open '#{name}'",
:type=>:ok)
ensure
fp.close if fp
end
ret
}
# Process the given URL
#
process_url = proc{|url|
case url[0]
when /^file:/
load_file.call(url[0][5..-1])
when /^exec:/
Tk.ip_eval(url[0][5..-1].tr('\\', ' '))
else
load_file.call(url[0])
end
}
# Load a file into the HTML widget
#
last_file = ''
load_file = proc{|name|
return unless (doc = read_file.call(name))
clear_screen.call
last_file = name
if html_fs && html_fs.exist?
w = html_fs
else
w = html
end
w.configure(:base=>name)
w.parse(doc)
w.configure(:cursor=>'top_left_arrow')
old_imgs.clear
}
# Refresh the current file.
#
refresh = proc{|*args|
load_file.call(last_file) if last_file
}
# This routine is called whenever a "<meta>" markup is seen.
#
meta = proc{|w, tag, alist|
v = Hash[*simplelist(alist)]
if v.kye?('key') && v.key?('href')
hotkey[v['key']] = w.resolve(v['href'])
end
if v.kye?('next')
hotkey['Down'] =v['next']
end
if v.kye?('prev')
hotkey['Up'] =v['prev']
end
if v.kye?('other')
hotkey['o'] =v['other']
end
}
# Go from full-screen mode back to window mode.
#
fullscreen_off = proc{
fswin.destroy
root.deiconify
Tk.update
root.raise
html.clipwin.focus
clear_screen.call
old_imgs.clear
refresh.call
}
# Go from window mode to full-screen mode.
#
fullscreen = proc{
if fswin && fswin.exist?
fswin.deiconify
Tk.update
fswin.raise
return
end
width = root.winfo_screenwidth
height = root.winfo_screenheight
fswin = TkToplevel.new(:overrideredirect=>true,
:geometry=>"#{width}x#{height}+0+0")
html_fs = Tk::HTML_Widget.new(fswin, :padx=>5, :pady=>9,
:formcommand=>form_cmd,
:imagecommand=>proc{image_cmd.call(0)},
:scriptcommand=>script_cmd,
:appletcommand=>applet_cmd,
:hyperlinkcommand=>hyper_cmd,
:bg=>'white', :tablerelief=>:raised,
:appletcommand=>proc{|*args|
run_applet('big', *args)
@html = Tk::HTML_Widget.new(:width=>512, :height=>384,
:padx=>5, :pady=>9,
:formcommand=>proc{|*args| form_cmd(*args)},
:imagecommand=>proc{|*args|
image_cmd(1, *args)
},
:fontcommand=>pick_font_fs,
:cursor=>:tcross) {
pack(:fill=>:both, :expand=>true)
token_handler('meta', proc{|*args| meta.call(self, *args)})
}
:scriptcommand=>proc{|*args|
script_cmd(*args)
},
:appletcommand=>proc{|*args|
applet_cmd(*args)
},
:hyperlinkcommand=>proc{|*args|
hyper_cmd(*args)
},
:fontcommand=>proc{|*args|
pick_font(*args)
},
:appletcommand=>proc{|*args|
run_applet('small', *args)
},
:bg=>'white', :tablerelief=>:raised)
clear_screen.call
old_imgs.clear
refresh.call
Tk.update
html_fs.clipwin.focus
}
@html.token_handler('meta', proc{|*args| meta(@html, *args)})
#
#
key_block = false
vscr = @html.yscrollbar(TkScrollbar.new)
hscr = @html.xscrollbar(TkScrollbar.new)
key_press = proc{|w, keysym|
return if key_block
key_block = true
Tk.after(250, proc{key_block = false})
Tk.grid(@html, vscr, :sticky=>:news)
Tk.grid(hscr, :sticky=>:ew)
@root.grid_columnconfigure(0, :weight=>1)
@root.grid_columnconfigure(1, :weight=>0)
@root.grid_rowconfigure(0, :weight=>1)
@root.grid_rowconfigure(1, :weight=>0)
if hotkey.key?(keysym)
process_url.call(hotkey[keysym])
end
case keysym
when 'Escape'
if fswin && fswin.exist?
fullscreen_off.call
else
fullscreen.call
############################################
@html.clipwin.focus
# If an arguent was specified, read it into the HTML widget.
#
Tk.update
if file && file != ""
load_file(file)
end
end
}
Tk::HTML_Widget::ClippingWindow.bind('1', key_press, '%W Down')
Tk::HTML_Widget::ClippingWindow.bind('3', key_press, '%W Up')
Tk::HTML_Widget::ClippingWindow.bind('2', key_press, '%w Down')
#
# A font chooser routine.
#
# html[:fontcommand] = pick_font
def pick_font(size, attrs)
# puts "FontCmd: #{size} #{attrs}"
[ ((attrs =~ /fixed/)? 'courier': 'charter'),
(12 * (1.2**(size.to_f - 4.0))).to_i,
((attrs =~ /italic/)? 'italic': 'roman'),
((attrs =~ /bold/)? 'bold': 'normal') ].join(' ')
end
Tk::HTML_Widget::ClippingWindow.bind('KeyPress', key_press, '%W %K')
# This routine is called to pick fonts for the fullscreen view.
#
def pick_font_fs(size, attrs)
baseFontSize = 24
# puts "FontCmd: #{size} #{attrs}"
[ ((attrs =~ /fixed/)? 'courier': 'charter'),
(baseFontSize * (1.2**(size.to_f - 4.0))).to_i,
((attrs =~ /italic/)? 'italic': 'roman'),
((attrs =~ /bold/)? 'bold': 'normal') ].join(' ')
end
############################################
#
# Build the half-size view of the page
#
menu_spec = [
[['File', 0],
['Open', sel_load, 0],
['Full Screen', fullscreen, 0],
['Refresh', refresh, 0],
'---',
['Exit', proc{exit}, 1]]
]
#
#
def hyper_cmd(*args)
puts "HyperlinkCommand: #{args.inspect}"
end
mbar = root.add_menubar(menu_spec)
# This routine is called to run an applet
#
def run_applet(size, w, arglist)
applet_arg.value = Hash[*simplelist(arglist)]
html = Tk::HTML_Widget.new(:width=>512, :height=>384,
:padx=>5, :pady=>9,
:formcommand=>form_cmd,
:imagecommand=>proc{|*args|
image_cmd.call(1, *args)
},
:scriptcommand=>script_cmd,
:appletcommand=>applet_cmd,
:hyperlinkcommand=>hyper_cmd,
:fontcommand=>pick_font,
:appletcommand=>proc{|*args|
run_applet.call('small', *args)
},
:bg=>'white', :tablerelief=>:raised)
return unless @applet_arg.key?('src')
html.token_handler('meta', proc{|*args| meta.call(html, *args)})
src = @html.remove(@applet_arg['src'])
vscr = html.yscrollbar(TkScrollbar.new)
hscr = html.xscrollbar(TkScrollbar.new)
@applet_arg['window'] = w
@applet_arg['fontsize'] = size
Tk.grid(html, vscr, :sticky=>:news)
Tk.grid(hscr, :sticky=>:ew)
Tk.root.grid_columnconfigure(0, :weight=>1)
Tk.root.grid_columnconfigure(1, :weight=>0)
Tk.root.grid_rowconfigure(0, :weight=>1)
Tk.root.grid_rowconfigure(1, :weight=>0)
begin
Tk.load_tclscript(src)
rescue => e
puts "Applet error: #{e.message}"
end
end
#
#
def form_cmd(n, cmd, *args)
# p [n, cmd, *args]
end
############################################
#
#
def move_big_image(b)
return unless @big_imgs.key?(b)
b.copy(@big_imgs[b])
@big_imgs[b].delete
@big_imgs.delete(b)
end
html.clipwin.focus
def image_cmd(hs, *args)
fn = args[0]
# If an arguent was specified, read it into the HTML widget.
#
Tk.update
if file && file != ""
load_file.call(file)
if @old_imgs.key?(fn)
return (@images[fn] = @old_imgs.delete(fn))
end
begin
img = TkPhotoImage.new(:file=>fn)
rescue
return ((hs)? @@smallgray: @@biggray)
end
if hs
img2 = TkPhotoImage.new
img2.copy(img, :subsample=>[2,2])
img.delete
img = img2
end
if img.width * img.height > 20000
b = TkPhotoImage.new(:width=>img.width, :height=>img.height)
@big_imgs[b] = img
img = b
Tk.after_idle(proc{ move_big_image(b) })
end
@images[fn] = img
img
end
#
# This routine is called for every <SCRIPT> markup
#
def script_cmd(*args)
# puts "ScriptCmd: #{args.inspect}"
end
# This routine is called for every <APPLET> markup
#
def applet_cmd(w, arglist)
# puts "AppletCmd: w=#{w} arglist=#{arglist}"
#TkLabel.new(w, :text=>"The Applet #{w}", :bd=>2, :relief=>raised)
end
# This binding fires when there is a click on a hyperlink
#
def href_binding(w, x, y)
lst = w.href(x, y)
unless lst.empty?
process_url(lst)
end
end
#
#
def sel_load
filetypes = [
['Html Files', ['.html', '.htm']],
['All Files', '*']
]
f = Tk.getOpenFile(:initialdir=>@last_dir, :filetypes=>filetypes)
if f != ''
load_file(f)
@last_dir = File.dirname(f)
end
end
# Clear the screen.
#
def clear_screen
if @html_fs && @html_fs.exist?
w = @html_fs
else
w = @html
end
w.clear
@old_imgs.clear
@big_imgs.clear
@hotkey.clear
@images.each{|k, v| @old_imgs[k] = v }
@images.clear
end
# Read a file
#
def read_file(name)
begin
fp = open(name, 'r')
ret = fp.read(File.size(name))
rescue
ret = nil
fp = nil
Tk.messageBox(:icon=>'error', :message=>"fail to open '#{name}'",
:type=>:ok)
ensure
fp.close if fp
end
ret
end
# Process the given URL
#
def process_url(url)
case url[0]
when /^file:/
load_file(url[0][5..-1])
when /^exec:/
Tk.ip_eval(url[0][5..-1].tr('\\', ' '))
else
load_file(url[0])
end
end
# Load a file into the HTML widget
#
def load_file(name)
return unless (doc = read_file(name))
clear_screen()
@last_file = name
if @html_fs && @html_fs.exist?
w = @html_fs
else
w = @html
end
w.configure(:base=>name)
w.parse(doc)
w.configure(:cursor=>'top_left_arrow')
@old_imgs.clear
end
# Refresh the current file.
#
def refresh(*args)
load_file(@last_file) if @last_file
end
# This routine is called whenever a "<meta>" markup is seen.
#
def meta(w, tag, alist)
v = Hash[*simplelist(alist)]
if v.key?('key') && v.key?('href')
@hotkey[v['key']] = w.resolve(v['href'])
end
if v.key?('next')
@hotkey['Down'] =v['next']
end
if v.key?('prev')
@hotkey['Up'] =v['prev']
end
if v.key?('other')
@hotkey['o'] =v['other']
end
end
# Go from full-screen mode back to window mode.
#
def fullscreen_off
@fswin.destroy
@root.deiconify
Tk.update
@root.raise
@html.clipwin.focus
clear_screen()
@old_imgs.clear
refresh()
end
# Go from window mode to full-screen mode.
#
def fullscreen
if @fswin && @fswin.exist?
@fswin.deiconify
Tk.update
@fswin.raise
return
end
width = @root.winfo_screenwidth
height = @root.winfo_screenheight
@fswin = TkToplevel.new(:overrideredirect=>true,
:geometry=>"#{width}x#{height}+0+0")
@html_fs = Tk::HTML_Widget.new(@fswin, :padx=>5, :pady=>9,
:formcommand=>proc{|*args|
form_cmd(*args)
},
:imagecommand=>proc{|*args|
image_cmd(0, *args)
},
:scriptcommand=>proc{|*args|
script_cmd(*args)
},
:appletcommand=>proc{|*args|
applet_cmd(*args)
},
:hyperlinkcommand=>proc{|*args|
hyper_cmd(*args)
},
:appletcommand=>proc{|*args|
run_applet('big', *args)
},
:fontcommand=>proc{|*args|
pick_font_fs(*args)
},
:bg=>'white', :tablerelief=>:raised,
:cursor=>:tcross) {
pack(:fill=>:both, :expand=>true)
token_handler('meta', proc{|*args| meta(self, *args)})
}
clear_screen()
@old_imgs.clear
refresh()
Tk.update
@html_fs.clipwin.focus
end
#
#
def key_press(w, keysym)
return if @key_block
@key_block = true
Tk.after(250, proc{@key_block = false})
if @hotkey.key?(keysym)
process_url(@hotkey[keysym])
end
case keysym
when 'Escape'
if @fswin && @fswin.exist?
fullscreen_off()
else
fullscreen()
end
end
end
end
############################################
TkHTML_File_Viewer.new(file)
Tk.mainloop