[ruby-gnome2-doc-cvs] [Ruby-GNOME2 Project Website] create - tut-gtk2-mnstbs-tyu

Back to archive index

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.




ruby-gnome2-cvs メーリングリストの案内
Back to archive index