#!/usr/bin/env ruby
#
# This script implements the "ss" application. "ss" implements
# a presentation slide-show based on HTML slides.
#
require 'tk'
require 'tkextlib/tkHTML'
file = ARGV[0]
class TkHTML_File_Viewer
include TkComm
# These are images to use with the actual image specified in a
# "" markup can't be found.
#
@@biggray = TkPhotoImage.new(:data=><<'EOD')
R0lGODdhPAA+APAAALi4uAAAACwAAAAAPAA+AAACQISPqcvtD6OctNqLs968+w+G4kiW5omm
6sq27gvH8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNFgsAO///
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
@html = nil
@html_fs = nil
@hotkey = {}
@applet_arg = TkVarAccess.new_hash('AppletArg')
@images = {}
@old_imgs = {}
@big_imgs = {}
@last_dir = Dir.pwd
@last_file = ''
@key_block = false
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')
Tk::HTML_Widget::ClippingWindow.bind('KeyPress',
proc{|w, ksym| key_press(w, ksym)},
'%W %K')
############################################
#
# 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]]
]
mbar = @root.add_menubar(menu_spec)
@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)
},
: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)
@html.token_handler('meta', proc{|*args| meta(@html, *args)})
vscr = @html.yscrollbar(TkScrollbar.new)
hscr = @html.xscrollbar(TkScrollbar.new)
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)
############################################
@html.clipwin.focus
# If an arguent was specified, read it into the HTML widget.
#
Tk.update
if file && file != ""
load_file(file)
end
end
#
# 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
# 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
#
#
def hyper_cmd(*args)
puts "HyperlinkCommand: #{args.inspect}"
end
# This routine is called to run an applet
#
def run_applet(size, w, arglist)
applet_arg.value = Hash[*simplelist(arglist)]
return unless @applet_arg.key?('src')
src = @html.remove(@applet_arg['src'])
@applet_arg['window'] = w
@applet_arg['fontsize'] = size
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
def image_cmd(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(b) })
end
@images[fn] = img
img
end
#
# This routine is called for every