Kouhei Sutou
kous****@users*****
Tue Apr 25 00:43:18 JST 2006
Index: kazehakase/data/ext/ruby/kz/ruby-dialog.rb diff -u kazehakase/data/ext/ruby/kz/ruby-dialog.rb:1.1 kazehakase/data/ext/ruby/kz/ruby-dialog.rb:1.2 --- kazehakase/data/ext/ruby/kz/ruby-dialog.rb:1.1 Sat Jan 14 19:34:55 2006 +++ kazehakase/data/ext/ruby/kz/ruby-dialog.rb Tue Apr 25 00:43:18 2006 @@ -35,28 +35,41 @@ @default_font_size = 14 init_dialog @dialog.show_all + @entry.grab_focus end - + + def _(str) + Kz.gettext(str) + end + def init_dialog - @dialog = Gtk::Dialog.new + @dialog = Gtk::Dialog.new(_("Ruby dialog")) @dialog.set_size_request(400, 300) @dialog.signal_connect("destroy") do |widget, event| false end - init_text_view + init_history + init_output_area + init_input_area init_buttons + init_redirector end - + + def init_history + @history = [] + end + + def init_output_area + init_text_view + end + def init_text_view @view = Gtk::TextView.new - @view.set_wrap_mode(Gtk::TextTag::WRAP_WORD_CHAR) + @view.wrap_mode = Gtk::TextTag::WRAP_WORD_CHAR + @view.editable = false @buffer =****@view***** - init_eval_mark + init_mark init_tags - @view.signal_connect("key_press_event") do |widget, event| - handle_input(event) - false - end @buffer.signal_connect_after("insert_text") do |widget, iter, text, len| start =****@buffe*****_iter_at_offset(iter.offset - len) @buffer.apply_tag(@all_tag, start, iter) @@ -66,14 +79,49 @@ @dialog.vbox.pack_start(sw, true, true, 0) end - def init_eval_mark - start_iter =****@buffe*****_iter - @eval_mark =****@buffe*****_mark("ruby-start", start_iter, true) + def init_input_area + init_history_spin_button + init_input_entry + + input_hbox = Gtk::HBox.new + input_hbox.pack_start(@history_spin, false, true, 0) + input_hbox.pack_start(@entry, true, true, 0) + @dialog.vbox.pack_start(input_hbox, false, true, 0) + end + + def init_history_spin_button + adjustment = Gtk::Adjustment.new(@history.size, 0, @history.size, 1, 4, 0) + @history_spin = Gtk::SpinButton.new(adjustment, 1, 0) + @history_spin.signal_connect("value-changed") do |widget, type| + update_input_entry if widget.value < @history.size + false + end + end + + def init_input_entry + @entry = Gtk::Entry.new + @entry.signal_connect("key_press_event") do |widget, event| + handle_input(event) + end + @entry + end + + def update_input_entry + @entry.text = @history[@history_spin.value] + @entry.position = -1 + end + + def init_mark + @end_mark =****@buffe*****_mark("end", @buffer.end_iter, true) end def init_tags result_tag_prop = {:foreground => "HotPink"} @result_tag =****@buffe*****_tag("result", result_tag_prop) + input_tag_prop = {:foreground => "Green"} + @input_tag =****@buffe*****_tag("input", input_tag_prop) + output_tag_prop = {:foreground => "Blue"} + @output_tag =****@buffe*****_tag("output", output_tag_prop) all_tag_prop = { :family => "monospace", :size_points => @default_font_size @@ -82,21 +130,63 @@ end def handle_input(event) + handled = false case event.keyval when Gdk::Keyval::GDK_Return - text =****@buffe*****_text(@buffer.get_iter_at_mark(@eval_mark), - @buffer.end_iter) - if /\A\s*\z/m !~ text - @buffer.insert(@buffer.end_iter, "\n>> ") - @buffer.insert(@buffer.end_iter, - eval_text(text).inspect, - @result_tag) + text =****@entry***** + unless text.empty? + eval_print(text) + @history << text + @history_spin.adjustment.upper =****@histo***** + @history_spin.value =****@histo***** end - @buffer.place_cursor(@buffer.end_iter) - @buffer.move_mark(@eval_mark, @buffer.end_iter) + @entry.text = "" + when Gdk::Keyval::GDK_p + handled = previous_history if event.state.control_mask? + when Gdk::Keyval::GDK_Up + handled = previous_history + handled = true + when Gdk::Keyval::GDK_n + handled = next_history if event.state.control_mask? + when Gdk::Keyval::GDK_Down + handled = next_history + handled = true end + handled end - + + def previous_history + handled = false + if @history_spin.value > 0 + @history_spin.value -= 1 + update_input_entry + handled = true + end + handled + end + + def next_history + handled = false + if @history_spin.value < @history.size + update_input_entry + @history_spin.value += 1 + handled = true + end + handled + end + + def eval_print(text) + @buffer.insert(@buffer.end_iter, ">> ") + @buffer.insert(@buffer.end_iter, text, @input_tag) + @buffer.insert(@buffer.end_iter, "\n") + result = eval_text(text).inspect + @buffer.insert(@buffer.end_iter, "=> ") + @buffer.insert(@buffer.end_iter, result, @result_tag) + @buffer.insert(@buffer.end_iter, "\n") + @buffer.move_mark(@end_mark, @buffer.end_iter) + @view.scroll_to_mark(@end_mark, 0, false, 0, 1) + end + def add_scrooled_window(widget) sw = Gtk::ScrolledWindow.new sw.border_width = 5 @@ -106,11 +196,11 @@ end def init_buttons - init_spin_button + init_font_size_spin_button init_exit_button end - def init_spin_button + def init_font_size_spin_button adjustment = Gtk::Adjustment.new(@default_font_size, 8, 72, 1, 4, 0) button = Gtk::SpinButton.new(adjustment, 1, 0) button.signal_connect("value-changed") do |widget, type| @@ -129,10 +219,31 @@ @dialog.action_area.add(button) end + def init_redirector + @buffer_out = Object.new + @buffer_out.instance_variable_set("@buffer", @buffer) + @buffer_out.instance_variable_set("@output_tag", @output_tag) + class << @buffer_out + def write(str) + @buffer.insert(@buffer.end_iter, str, @output_tag) + end + end + end + def eval_text(text) - @sandbox.evaluate(text) + redirect do + @sandbox.evaluate(text) + end rescue Exception $! end + + def redirect + stdout = $stdout + $stdout = @buffer_out + yield + ensure + $stdout = stdout + end end end