summaryrefslogtreecommitdiff
path: root/ext/tk/sample/tkextlib/tkHTML/ss.rb
diff options
context:
space:
mode:
Diffstat (limited to 'ext/tk/sample/tkextlib/tkHTML/ss.rb')
-rw-r--r--ext/tk/sample/tkextlib/tkHTML/ss.rb404
1 files changed, 404 insertions, 0 deletions
diff --git a/ext/tk/sample/tkextlib/tkHTML/ss.rb b/ext/tk/sample/tkextlib/tkHTML/ss.rb
new file mode 100644
index 0000000000..e71c26f7dc
--- /dev/null
+++ b/ext/tk/sample/tkextlib/tkHTML/ss.rb
@@ -0,0 +1,404 @@
+#!/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'
+
+root = TkRoot.new(:title=>'HTML File Viewer', :iconname=>'HV')
+fswin = nil
+
+html = nil
+html_fs = nil
+
+hotkey = {}
+
+file = ARGV[0]
+
+
+# These are images to use with the actual image specified in a
+# "<img>" 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
+
+
+#
+# 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(' ')
+}
+
+# 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(' ')
+}
+
+#
+#
+hyper_cmd = proc{|*args|
+ puts "HyperlinkCommand: #{args.inspect}"
+}
+
+# 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)]
+
+ 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
+}
+
+#
+#
+form_cmd = proc{|n, cmd, *args|
+}
+
+#
+#
+images = {}
+old_imgs = {}
+big_imgs = {}
+
+#
+#
+move_big_image = proc{|b|
+ return unless big_imgs.key?(b)
+ b.copy(big_imgs[b])
+ big_imgs[b].delete
+ big_imgs.delete(b)
+}
+
+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
+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)
+ },
+ :fontcommand=>pick_font_fs,
+ :cursor=>:tcross) {
+ pack(:fill=>:both, :expand=>true)
+ token_handler('meta', proc{|*args| meta.call(self, *args)})
+ }
+
+ clear_screen.call
+ old_imgs.clear
+ refresh.call
+ Tk.update
+ html_fs.clipwin.focus
+}
+
+#
+#
+key_block = false
+
+key_press = proc{|w, keysym|
+ return if key_block
+ key_block = true
+ Tk.after(250, proc{key_block = false})
+
+ if hotkey.key?(keysym)
+ process_url.call(hotkey[keysym])
+ end
+ case keysym
+ when 'Escape'
+ if fswin && fswin.exist?
+ fullscreen_off.call
+ else
+ fullscreen.call
+ 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')
+
+Tk::HTML_Widget::ClippingWindow.bind('KeyPress', key_press, '%W %K')
+
+
+############################################
+#
+# 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]]
+]
+
+mbar = root.add_menubar(menu_spec)
+
+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)
+
+html.token_handler('meta', proc{|*args| meta.call(html, *args)})
+
+vscr = html.yscrollbar(TkScrollbar.new)
+hscr = html.xscrollbar(TkScrollbar.new)
+
+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)
+
+
+############################################
+
+html.clipwin.focus
+
+# If an arguent was specified, read it into the HTML widget.
+#
+Tk.update
+if file && file != ""
+ load_file.call(file)
+end
+
+############################################
+
+Tk.mainloop