wxRuby試食
詳細
更新:やっと行番号を表示して幅を適応することに成功しました~
wxRubyの一番面白いところはwxWidgetsに糖衣を1枚加えた文法です.
インストール済み
gem install wxruby
その後、インストール
gem install wx_sugar
これはparamだけでなくname=>valueのような糖衣は、attr_*を使用できます.ファミリーはインスタンス変数を暴露し、do...endブロックでlayoutやメニューを作る能力もあり、比較的爽やかな点はblockでイベントを処理することもできます.
使い方を簡単に説明します:param_name=>valueのような糖衣:例えばwxRubyのある関数f(a,b)、wx_があるsugarの後、f(:a=>5,:b=>'string')と書いて呼び出すことができます.
次のプログラムでは、wxAUIとwxStyledTextCtrlを使用します.目的は、非常に長いテキストファイルで、複数のキーワードを同時に検索し、コンテキストと位置決めのリンクを含むインデックスを作成することです.
multi_searcher.rb
プログラムで使用するerbテンプレートreport.html.erb:
位置
コンテキスト
'>
更新:やっと行番号を表示して幅を適応することに成功しました~
wxRubyの一番面白いところはwxWidgetsに糖衣を1枚加えた文法です.
インストール済み
gem install wxruby
その後、インストール
gem install wx_sugar
これはparamだけでなくname=>valueのような糖衣は、attr_*を使用できます.ファミリーはインスタンス変数を暴露し、do...endブロックでlayoutやメニューを作る能力もあり、比較的爽やかな点はblockでイベントを処理することもできます.
使い方を簡単に説明します:param_name=>valueのような糖衣:例えばwxRubyのある関数f(a,b)、wx_があるsugarの後、f(:a=>5,:b=>'string')と書いて呼び出すことができます.
次のプログラムでは、wxAUIとwxStyledTextCtrlを使用します.目的は、非常に長いテキストファイルで、複数のキーワードを同時に検索し、コンテキストと位置決めのリンクを含むインデックスを作成することです.
multi_searcher.rb
require 'rubygems'
require 'wx'
require 'wx_sugar/all'
require 'erb'
require 'ya2yaml'
include Wx
$KCODE = 'utf8'
def min(a, b)
a >= b ? b : a
end
def max(a, b)
a >= b ? a : b
end
class KeywordsPane < Panel
def initialize(parent, options = {})
super(parent, options.merge!(:size => [500, 500]))
arrange_vertically do
add @keyword = TextCtrl.new(self, :style => Wx::TE_MULTILINE, :size => [-1, 200]), :proportion => 1
arrange_horizontally do
add @status = StaticText.new(self, :label => '', :size => [150, -1]), :proportion => 1
add Button.new(self, :label => ' ') do |button|
evt_button(button) do |event|
#search
get_parent.filecontent_pane.search(@keyword.get_value)
end
end
end
end
end
attr_reader :keyword, :status
end
class ReportPane < Panel
def initialize(parent, options = {})
super(parent, options.merge!(:size => [500, 500]))
arrange_vertically do
add @report = HtmlWindow.new(self), :proportion => 1 do |report|
evt_html_link_clicked(report) do | event |
position = event.get_link_info.get_href.sub(/position\:\/\//, '').split(',')
get_parent.filecontent_pane.file.set_selection position[0].to_i, position[1].to_i
end
end
add Button.new(self, :label => ' ') do |button|
evt_button(button) do |event|
ask4file = FileDialog.new(self, :style => FD_SAVE, :message => ' ', :wildcard => 'HTML files(*.html)|*.html')
File.new(ask4file.get_path, 'w').write @report_text if ask4file.show_modal == Wx::ID_OK
end
end
end
end
attr_reader :report
attr_writer :report_text
end
class FilecontentPane < Panel
def initialize(parent, options = {})
super(parent, options.merge!(:size => [500, 500]))
arrange_vertically do
add Button.new(self, :label => ' ') do |button|
evt_button(button) do |event|
#open file
ask4file = FileDialog.new(self, :message => ' ')
@file.load_file(ask4file.get_path) if ask4file.show_modal == Wx::ID_OK
# auto adapt to the width of max line count
@file.set_margin_width 0, @file.text_width(33, "__#{@file.get_line_count}")
end
end
add @file = StyledTextCtrl.new(self), :proportion => 1
@file.set_margin_width 0, @file.text_width(33, '999') # show line number
add StaticText.new(self, :label => ' : Ctrl+ ')
end
end
def search(keywords)
keywords_a = keywords.split(', ')
@search_result = {}
file_length = @file.get_text_length
beg_pos = 0
keywords_a.each do |k|
@search_result[k] = []
@file.goto_pos 0
@file.search_anchor
while((beg_pos = @file.search_next(0,k)) != -1)
end_pos = beg_pos + k.length
context = @file.get_text_range max(beg_pos - 520, 0), min(end_pos + 520, file_length)
context.gsub! k, '\0'
# coord = [@file.line_from_position(beg_pos), @file.get_column(beg_pos)]
@search_result[k] << { :context => context, :position => [beg_pos, end_pos], :coord => [@file.line_from_position(beg_pos), @file.get_column(beg_pos)]}
get_parent.keywords_pane.status.set_label " #{k}... %3.2f%% ..." % (beg_pos * 100.0 / file_length)
@file.goto_pos end_pos + 1
@file.search_anchor
end
end
get_parent.keywords_pane.status.set_label ' , ...'
get_parent.report_pane.report.set_page report_text = ERB.new(File.read('report.html.erb'), 0, "%<>").result(binding)
get_parent.keywords_pane.status.set_label ''
get_parent.report_pane.report_text = report_text
end
attr_reader :file
end
class MyFrame < Frame
def initialize(title)
super(nil, :title => title, :size => [800, 600])
@mgr = AuiManager.new
@mgr.set_managed_window(self)
pi = AuiPaneInfo.new
pi.set_name('keywords_pane').set_caption(' , ( keyword1, keyword2):')
pi.top.set_maximize_button.set_close_button(false)
@mgr.add_pane(@keywords_pane = KeywordsPane.new(self), pi)
pi = AuiPaneInfo.new
pi.set_name('report_pane').set_caption(' ')
pi.left.set_maximize_button.set_close_button(false)
@mgr.add_pane(@report_pane = ReportPane.new(self), pi)
pi = AuiPaneInfo.new
pi.set_name('filecontent_pane').set_caption(' ')
pi.center.set_maximize_button.set_close_button(false)
@mgr.add_pane(@filecontent_pane = FilecontentPane.new(self), pi)
@mgr.update
end
attr_reader :keywords_pane, :report_pane, :filecontent_pane
end
class MyApp < App
def on_init
frame = MyFrame.new(' ')
frame.show
end
end
a = MyApp.new
a.main_loop
プログラムで使用するerbテンプレートreport.html.erb:
(見つかった場所)位置
コンテキスト
'>