ruby-****@sourc*****
ruby-****@sourc*****
2009年 2月 28日 (土) 01:48:14 JST
------------------------- REMOTE_ADDR = 74.15.84.244 REMOTE_HOST = URL = http://ruby-gnome2.sourceforge.jp/hiki.cgi?tut-gtk2-mnstbs-tyu ------------------------- TITLE = tut-gtk2-mnstbs-tyu KEYWORD = = Menus and Toolbars {{link "tut-mnstbs-gtk2-csti", "tut-gtk2-mnstbs", "tut-gtk", "tut-gtk2-dynui"}} == Test Your Understanding As always, at the end of a chapter I suggest you try to write the provided exercises on your own. If you have read and tried out all the examples and exercises so far you should be able to accomplish this with the help of the code you've worked on so far. :Exercise #1: At the end of sessions in chapter (7) "The Text View Widget" you created a simple text editor using Gtk::TextView widget. In this exercise, expand on that application and provide a ((*toolbar*)) for actions instead of a vertical box filled with Gtk::Button widgets. While manual toolbar creation is possible, in most applications you will want to utilize the Gtk::UIManager method of toolbar creation. Therefore, use it also in this exercise. Also make use of Built-in stock items. ((*toolbar2.ui*) <ui> <toolbar name="Toolbar"> <toolitem name="FileNew" action="New"/> <toolitem name="FileOpen" action="Open"/> <toolitem name="FileSave" action="Save"/> <separator/> <toolitem name="EditCut" action="Cut"/> <toolitem name="EditCopy" action="Copy"/> <toolitem name="EditPaste" action="Paste"/> </toolbar> </ui> {{image_right("mnstbs-tyu1.png")}} {{br}} ((*simtextedit-ui1.rb*)) #!/usr/bin/env ruby require 'gtk2' # Make sure "texteditor" will be part of the closures class TextEditor attr_accessor :textview, :search end texeditor = TextEditor.new # Verify that the user want to create a new document. # If so, delete all of the text from the buffer. new_clicked = Proc.new do dialog = Gtk::MessageDialog.new( nil, Gtk::Dialog::MODAL, Gtk::MessageDialog::QUESTION, Gtk::MessageDialog::BUTTONS_YES_NO, "All changes will be lost. Do you want to continue?" ) dialog.title = "Information" dialog.run do |r| texeditor.textview.buffer.text = "" if r == Gtk::Dialog::RESPONSE_YES end dialog.destroy end # Replace the content of the current buffer with the # content of a file. open_clicked = Proc.new do dialog = Gtk::FileChooserDialog.new( "Choose a file ...", nil, Gtk::FileChooser::ACTION_OPEN, nil, [ Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL ], [ Gtk::Stock::APPLY, Gtk::Dialog::RESPONSE_APPLY ] ) dialog.run do |response| if response == Gtk::Dialog::RESPONSE_APPLY file = dialog.filename content = IO.readlines(file) texeditor.textview.buffer.text = content.to_s end end dialog.destroy end # Save the content of the current buffer to a file. save_clicked = Proc.new do dialog = Gtk::FileChooserDialog.new( "Save the file ...", nil, Gtk::FileChooser::ACTION_SAVE, nil, [ Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL ], [ Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_APPLY ] ) dialog.run do |response| if response == Gtk::Dialog::RESPONSE_APPLY file = dialog.filename content = texeditor.textview.buffer.text # Open for writing, write and close. File.open(file, "w") { |f| f << content } end end dialog.destroy end # Copy the selected text to the clipboard and remove it from the buffer. cut_clicked = Proc.new do clipboard = Gtk::Clipboard.get(Gdk::Selection::CLIPBOARD) texeditor.textview.buffer.cut_clipboard(clipboard, true) end # Copy the selected text to the clipboard. copy_clicked = Proc.new do |te| clipboard = Gtk::Clipboard.get(Gdk::Selection::CLIPBOARD) texeditor.textview.buffer.copy_clipboard(clipboard) end # Delete any selected text and insert the clipboard # content into the document. paste_clicked = Proc.new do clipboard = Gtk::Clipboard.get(Gdk::Selection::CLIPBOARD) texeditor.textview.buffer.paste_clipboard(clipboard, nil, true) end # Search for a text string from the current cursor position # if there is no selected text, or one character after the # cursor if there is. def find_clicked(txted) find = txted.search.text first, last, success = txted.textview.buffer.selection_bounds first = txted.textview.buffer.start_iter unless success # forward_search(find, flags, limit=(nil==entire text buffer)) first, last = first.forward_search(find, Gtk::TextIter::SEARCH_TEXT_ONLY, last) # Select the instance on the screen if the string is found. # Otherwise, tell the user it has failed. if (first) mark = txted.textview.buffer.create_mark(nil, first, false) # Scrolls the Gtk::TextView the minimum distance so # that mark is contained within the visible area. txted.textview.scroll_mark_onscreen(mark) txted.textview.buffer.delete_mark(mark) txted.textview.buffer.select_range(first, last) else # Gtk::MessageDialog.new(parent, flags, message_type, button_type, message = nil) dialogue = Gtk::MessageDialog.new( nil, Gtk::Dialog::MODAL, Gtk::MessageDialog::INFO, Gtk::MessageDialog::BUTTONS_OK, "The text was not found!" ) dialogue.run dialogue.destroy end first = last = nil # camcel any previous selections end entries = [ [ "New", Gtk::Stock::NEW, nil, nil, "Create a new file", new_clicked ], [ "Open", Gtk::Stock::OPEN, nil, nil, "Open an existing file", open_clicked ], [ "Save", Gtk::Stock::SAVE, nil, nil, "Save the document to a file", save_clicked ], [ "Cut", Gtk::Stock::CUT, nil, nil, "Cut the selection to the clipboard", cut_clicked ], [ "Copy", Gtk::Stock::COPY, nil, nil, "Copy the selection to the clipboard", copy_clicked ], [ "Paste", Gtk::Stock::PASTE, nil, nil, "Paste text from the clipboard", paste_clicked ] ] window = Gtk::Window.new(Gtk::Window::TOPLEVEL) window.resizable = true window.title = "Simple Text Editor & Toolbar" window.border_width = 10 window.signal_connect('delete_event') { Gtk.main_quit } window.set_size_request(300, 200) texeditor.textview = Gtk::TextView.new texeditor.search = Gtk::Entry.new texeditor.search.text = "Search for ..." find = Gtk::Button.new(Gtk::Stock::FIND) find.signal_connect("clicked") { find_clicked(texeditor) } # Create a new action group and add all of the actions to it. group = Gtk::ActionGroup.new("MainActionGroup") group.add_actions(entries) # Create a new UI manager and build the menu bar and toolbar. uimanager = Gtk::UIManager.new uimanager.insert_action_group(group, 0); uimanager.add_ui("toolbar2.ui") # Retrieve the necessary widgets and associate accelerators. toolbar = uimanager.get_widget("/Toolbar") toolbar.toolbar_style = Gtk::Toolbar::Style::BOTH window.add_accel_group(uimanager.accel_group) scrolled_win = Gtk::ScrolledWindow.new scrolled_win.border_width = 5 scrolled_win.add(texeditor.textview) scrolled_win.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS) searchbar = Gtk::HBox.new(false, 5) searchbar.pack_start(texeditor.search, false, false, 0); searchbar.pack_start(find, false, false, 0); vbox = Gtk::VBox.new(false, 5) vbox.pack_start(toolbar, false, false, 0) vbox.pack_start(scrolled_win, true, true, 0) vbox.pack_start(searchbar, false, false, 0) window.add(vbox) window.show_all Gtk.main :Exercise #2: In the next exercise, implement the same application as above, but use a menu bar instead of toolbar this time. You should continue to use the Gtk:UIManager. ((*toolbar2.ui*) <ui> <menubar name="MenuBar"> <menu name="FileMenu" action="File"> <menuitem name="FileNew" action="New"/> <menuitem name="FileOpen" action="Open"/> <menuitem name="FileSave" action="Save"/> </menu> <menu name="EditMenu" action="Edit"> <menuitem name="EditCut" action="Cut"/> <menuitem name="EditCopy" action="Copy"/> <menuitem name="EditPaste" action="Paste"/> </menu> </menubar> </ui> {{image_left("mnstbs-tyu2.png")}} {{br}} ((*simtextedit-ui2.rb*)) #!/usr/bin/env ruby require 'gtk2' # Make sure "texteditor" will be part of the closures class TextEditor attr_accessor :textview, :search end texeditor = TextEditor.new # Verify that the user want to create a new document. # If so, delete all of the text from the buffer. new_clicked = Proc.new do dialog = Gtk::MessageDialog.new( nil, Gtk::Dialog::MODAL, Gtk::MessageDialog::QUESTION, Gtk::MessageDialog::BUTTONS_YES_NO, "All changes will be lost. Do you want to continue?" ) dialog.title = "Information" dialog.run do |r| texeditor.textview.buffer.text = "" if r == Gtk::Dialog::RESPONSE_YES end dialog.destroy end # Replace the content of the current buffer with the # content of a file. open_clicked = Proc.new do dialog = Gtk::FileChooserDialog.new( "Choose a file ...", nil, Gtk::FileChooser::ACTION_OPEN, nil, [ Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL ], [ Gtk::Stock::APPLY, Gtk::Dialog::RESPONSE_APPLY ] ) dialog.run do |response| if response == Gtk::Dialog::RESPONSE_APPLY file = dialog.filename content = IO.readlines(file) texeditor.textview.buffer.text = content.to_s end end dialog.destroy end # Save the content of the current buffer to a file. save_clicked = Proc.new do dialog = Gtk::FileChooserDialog.new( "Save the file ...", nil, Gtk::FileChooser::ACTION_SAVE, nil, [ Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL ], [ Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_APPLY ] ) dialog.run do |response| if response == Gtk::Dialog::RESPONSE_APPLY file = dialog.filename content = texeditor.textview.buffer.text # Open for writing, write and close. File.open(file, "w") { |f| f << content } end end dialog.destroy end # Copy the selected text to the clipboard and remove it from the buffer. cut_clicked = Proc.new do clipboard = Gtk::Clipboard.get(Gdk::Selection::CLIPBOARD) texeditor.textview.buffer.cut_clipboard(clipboard, true) end # Copy the selected text to the clipboard. copy_clicked = Proc.new do |te| clipboard = Gtk::Clipboard.get(Gdk::Selection::CLIPBOARD) texeditor.textview.buffer.copy_clipboard(clipboard) end # Delete any selected text and insert the clipboard # content into the document. paste_clicked = Proc.new do clipboard = Gtk::Clipboard.get(Gdk::Selection::CLIPBOARD) texeditor.textview.buffer.paste_clipboard(clipboard, nil, true) end # Search for a text string from the current cursor position # if there is no selected text, or one character after the # cursor if there is. def find_clicked(txted) find = txted.search.text first, last, success = txted.textview.buffer.selection_bounds first = txted.textview.buffer.start_iter unless success # forward_search(find, flags, limit=(nil==entire text buffer)) first, last = first.forward_search(find, Gtk::TextIter::SEARCH_TEXT_ONLY, last) # Select the instance on the screen if the string is found. # Otherwise, tell the user it has failed. if (first) mark = txted.textview.buffer.create_mark(nil, first, false) # Scrolls the Gtk::TextView the minimum distance so # that mark is contained within the visible area. txted.textview.scroll_mark_onscreen(mark) txted.textview.buffer.delete_mark(mark) txted.textview.buffer.select_range(first, last) else # Gtk::MessageDialog.new(parent, flags, message_type, button_type, message = nil) dialogue = Gtk::MessageDialog.new( nil, Gtk::Dialog::MODAL, Gtk::MessageDialog::INFO, Gtk::MessageDialog::BUTTONS_OK, "The text was not found!" ) dialogue.run dialogue.destroy end first = last = nil # camcel any previous selections end entries = [ [ "File", nil, "_File", nil, nil, nil ], [ "New", Gtk::Stock::NEW, nil, nil, "Create a new file", new_clicked ], [ "Open", Gtk::Stock::OPEN, nil, nil, "Open an existing file", open_clicked ], [ "Save", Gtk::Stock::SAVE, nil, nil, "Save the document to a file", save_clicked ], [ "Edit", nil, "_Edit", nil, nil, nil ], [ "Cut", Gtk::Stock::CUT, nil, nil, "Cut the selection to the clipboard", cut_clicked ], [ "Copy", Gtk::Stock::COPY, nil, nil, "Copy the selection to the clipboard", copy_clicked ], [ "Paste", Gtk::Stock::PASTE, nil, nil, "Paste text from the clipboard", paste_clicked ] ] window = Gtk::Window.new(Gtk::Window::TOPLEVEL) window.resizable = true window.title = "Simple Text Editor & Toolbar" window.border_width = 10 window.signal_connect('delete_event') { Gtk.main_quit } window.set_size_request(300, 200) texeditor.textview = Gtk::TextView.new texeditor.search = Gtk::Entry.new texeditor.search.text = "Search for ..." find = Gtk::Button.new(Gtk::Stock::FIND) find.signal_connect("clicked") { find_clicked(texeditor) } # Create a new action group and add all of the actions to it. group = Gtk::ActionGroup.new("MainActionGroup") group.add_actions(entries) # Create a new UI manager and build the menu bar and toolbar. uimanager = Gtk::UIManager.new uimanager.insert_action_group(group, 0) uimanager.add_ui("menu2.ui") # Retrieve the necessary widgets and associate accelerators. menu = uimanager.get_widget("/MenuBar") scrolled_win = Gtk::ScrolledWindow.new scrolled_win.border_width = 5 scrolled_win.add(texeditor.textview) scrolled_win.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS) searchbar = Gtk::HBox.new(false, 5) searchbar.pack_start(texeditor.search, false, false, 0); searchbar.pack_start(find, false, false, 0); vbox = Gtk::VBox.new(false, 5) vbox.pack_start(menu, false, false, 0) vbox.pack_start(scrolled_win, true, true, 0) vbox.pack_start(searchbar, false, false, 0) window.add(vbox) window.show_all Gtk.main :Exercise #3: Modify the first application from "Exercise #1", to include the the ((*toolbar*)) as a child of a handle box.