Ruby on HTA
少し触っただけだけども、HTA + ActiveScriptRubyにぐっときた。
VisualuRubyよりも、もっともっとサクサク簡単なGUIを作りたいときに便利っぽい。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="jp" lang="ja-JP"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>サンプル</title> <script for="window" event="onload" language="RubyScript"> @window.resizeTo(400, 100) def btnOk_onclick @window.document.getElementById("lblOutput").innerHTML = "Hello World!!!" end </script> </head> <body> <input id="btnOk" type="submit" value="OK" onclick="btnOk_onclick" /> <span id="lblOutput">...</span> </body> </html>
ちょっとめんどくさい
イベントハンドラを定義したり(onclick="...")するのが面倒なんで、うまいことできないか考え中。
んで、とりあえずidが付いている要素にイベントハンドラを定義するような仕組みを作ってみた。
ついでにHTAにスタイルを設定してもっとネイティブのアプリっぽく。
hta-support.rb
class HTASupport # イベントハンドラ一覧 EVENTHANDLERS = [ "onblur", "onfocus", "onchange", "onselect", "onselectstart", "onsubmit", "onreset", "onabort", "onerror", "onload", "onunload", "onclick", "ondblclick", "onkeyup", "onkeydown", "onkeypress", "onmouseout", "onmouseover", "onmouseup", "onmousedown", "onmousemove", "ondragdrop" ] def initialize(window) @window = window set_event_handler end # idを持つ要素すべてにイベントハンドラを設定します def set_event_handler body = _d.getElementsByTagName("body").item(0) set_event_handler_recursive(body) end # idを持つ要素すべてにイベントハンドラを設定します def set_event_handler_recursive(elem) # Element以外だったら終了 return if elem.nodeType != 1 id = elem.getAttribute("id") if id != "" EVENTHANDLERS.each do |name| handler_name = "#{id}_#{name}" elem.attachEvent(name, Proc.new { if methods.include?(handler_name) __send__(handler_name) end }) end end # 子要素も処理する elem.childNodes.each do |i| set_event_handler_recursive(i) end end # windowへのショートカット def _w @window end # window.documentへのショートカット def _d _w.document end # window.document.getElementByIdへのショートカット def _e(id) _d.getElementById(id) end end
sample.rb - このファイルに処理を実装する
require "hta-support" class Sample < HTASupport def btnOk_onclick _e("lblOutput").innerHTML = "HelloWorld!!" end end
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="jp" lang="ja-JP"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>サンプル</title> <style> body { background-color: ButtonFace; } </style> <script for="window" event="onload" language="RubyScript"> require "sample" Sample.new(@window) @window.resizeTo(400, 100) </script> <hta:application applicationname="サンプル" version="1.0" singleinstance="no" showintaskbar="yes" navigable="no" windowstate="normal" border="dialog" innerborder="no" borderstyle="normal" contextmenu="yes" selection="yes" scroll="no" scrollflat="no" caption="yes" icon="explorer.exe" sysmenu="yes" maximizebutton="no" minimizebutton="yes" /> </head> <body> <input id="btnOk" type="submit" value="OK" /> <span id="lblOutput">...</span> </body> </html>
はまりどころ
openが何かの名前と衝突してるっぽくてうまく使えなかった。
そのときはKernel.openとすれば期待通りに動作する。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="jp" lang="ja-JP"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>サンプル</title> <script for="window" event="onload" language="RubyScript"> @window.resizeTo(400, 100) def btnOk_onclick open("a.txt", "w") do |f| f.puts "aaa" end end </script> </head> <body> <input id="btnOk" type="submit" value="OK" onclick="btnOk_onclick" /> <span id="lblOutput">...</span> </body> </html>