[ruby-gnome2-doc-cvs] [Ruby-GNOME2 Project Website] update - tut-gtk2-mnstbs-tb

Zurück zum Archiv-Index

ruby-****@sourc***** ruby-****@sourc*****
2012年 12月 10日 (月) 02:40:56 JST


-------------------------
REMOTE_ADDR = 184.145.81.223
REMOTE_HOST = 
        URL = http://ruby-gnome2.sourceforge.jp/hiki.cgi?tut-gtk2-mnstbs-tb
-------------------------
@@ -555,16 +555,261 @@
 
 {{br}}
 
+
+
+# (9.6.2.2)
 === Dragging a Toolbar Within a Window
 
+# 9.6.2.2 ((<Dragging a Toolbar Within a Window|tut-gtk2-mnstbs-tb#Dragging a Toolbar Within a Window>))
 
 
+Most of contemporary GUI systems allow users to rearrange their display by dragging some of the displayed widget to new locations within a window and if it makes sense even to a new widget or a location in a different window all together.
 
 
+This feature is commonly called drag-and-drop or short dnd feature. We devoted entire chapter to document and explain the dnd facilities and features. The above 'detaching-toolbar-w-HandleBox.rb' example program does not really fall within the drag-and-drop categories, but not surprisingly, our next 'dnd-toolbar.rb' example does. Though, this next example logically rather nicely fits into this chapter, no attempt will be made here to explain the Gtk dnd metaphor. You are encouraged to read at least the '((<DnD Introduction|tut-gtk2-dnd-intro#Drag And Drop Introduction>))' article. In it, we revisit the 'dnd-toolbar.rb' program, albeit in a bit different (object-oriented) form, and add proper explanations of the included dnd features.
+
+Since this is the chapter about toolbars, this version of 'dnd-toolbar.rb' program is included here for the completion sake, so you can run and compare it, not so much programmatically but operationally, to the above 'detaching-toolbar-w-HandleBox.rb' example.
+
+
 :Providing extra drag-sensitive spot on the toolbar:
 
-    Perhaps you remember we mentioned that users may find discovering a 'dnd-sensitive' spot on a toolbar a bit tricky. Well, we can alleviate this problem by making a toolbar item that will be used as an 'auxiliary drag-and drop handle'. {{image_left("menui-as-aux-drag-sensitive-spot.png")}} In our 'dnd-toolbox.rb' example program you can do this by turning our tool button with the the 'baby-GNU' image labelled 'My stuff' into such a handle (see the small image on the left). However this will make this tool-button useless for any other actions, you may have planed for it before. You can try it out by uncommenting the 'my_stuff.use_drag_window = true' in our example program. Search for the following code segment.
+    Perhaps you remember we mentioned that users may find discovering a 'dnd-sensitive' spot on a toolbar a bit tricky. Well, we can alleviate this problem by making a toolbar item that will be used as an 'auxiliary drag-and drop handle'. {{image_left("menui-as-aux-drag-sensitive-spot.png")}} In our 'dnd-toolbar.rb' example program you can do this by turning our tool button with the the 'baby-GNU' image labelled 'My stuff' into such a handle (see the small image on the left). However this will make this tool-button useless for any other actions, you may have planed for it before. You can try it out by uncommenting the 'my_stuff.use_drag_window = true' in our example program. Search for the following code segment.
 
      # -- Provide additional drag-sensitive spot on the toolbar ----
      #    However the original intent (action) of this button is lost!!!
      #my_stuff.use_drag_window = true
+
+Following is the procedural version of 'dnd-toolbar.rb':
+
+((*dnd-toolbar.rb*))
+
+ #!/usr/bin/env ruby
+ require 'gtk2'
+ 
+ TBDND_ACTIONS = actions=Gdk::DragContext::ACTION_ASK   # _ASK,_COPY,_LINK,_MOVE,_DEFAULT,_PRIVATE
+ TBDND_TARGETS = [["toolbar", Gtk::Drag::TARGET_SAME_APP, 100]]
+ 
+ window = Gtk::Window.new("Drag-gable Toolbox")
+ window.resizable = true
+ window.border_width = 10
+ window.signal_connect('destroy') { Gtk.main_quit }
+ window.set_size_request(450, 400)
+ window.border_width = 5
+ 
+ # Create a toolbar with Cut, Copy, Paste and Select All
+ # toolbar items.
+ def create_toolbar(tb, entf)
+   cut       = Gtk::ToolButton.new(Gtk::Stock::CUT)
+   copy      = Gtk::ToolButton.new(Gtk::Stock::COPY)
+   paste     = Gtk::ToolButton.new(Gtk::Stock::PASTE)
+   selectall = Gtk::ToolButton.new(Gtk::Stock::SELECT_ALL)
+ 
+ # -- Depending on the status in the entry field cut, copy, paste and 
+ # -- select menu items should be made sensitive or insensitive, however
+ # -- that would introduce too much overhead to our example program here.
+ 
+ #  cut.sensitive = false
+ #  copy.sensitive = false
+ #  paste.sensitive = false
+ #  selectall.sensitive = false
+ 
+   separator = Gtk::SeparatorToolItem.new
+   mytb_menu = Gtk::MenuToolButton.new(Gtk::Stock::PREFERENCES)
+ 
+   # To be sure file exists use more elaborate check making the bixbuf
+   pixbuf = get_pixbuf_if_file_exists("gnu-baby-32x32.jpg")
+   my_stuff  = Gtk::ToolButton.new(
+       icon_widget=Gtk::Image.new(pixbuf), label="My Stuff")
+   # or if you are sure you you really have the image file:
+   my_stuff1 = Gtk::ToolButton.new(
+       icon_widget=Gtk::Image.new("gnu-head-42x42.jpg"), label="My Stuff-1")
+ 
+   # -- Provide additional drag-sensitive spot on the toolbar ----
+   #    However the original intent (action) of this button is lost!!!
+   #my_stuff.use_drag_window = true
+ 
+   # use Gtk::Widget#tooltip_text= instead of deprecated Gtk::Toolbar 
+   # methods utilizing deprecated Gtk::Tooltips class!
+   mytb_menu.tooltip_text = "Demonstrate that menus with submenus work."
+   cut.tooltip_text       = "Cut saves the selected text in the clipboard,\n" +
+                            "and removes it from the editable widget," 
+   copy.tooltip_text      = "Copy saves the selected text in the clipboard."
+   paste.tooltip_text     = "Paste retrieves last text saved in the clipboard\n" +
+                            "and places it at the cursor position in the edit field."
+   selectall.tooltip_text = "Select all the text in the edit field."
+   
+   tb.show_arrow = true
+   tb.toolbar_style = Gtk::Toolbar::Style::BOTH
+ 
+   tb.insert(0, mytb_menu)
+   tb.insert(1, my_stuff)
+   tb.insert(2, cut)
+   tb.insert(3, copy)
+   tb.insert(4, paste)
+   tb.insert(5, separator)
+   tb.insert(6, selectall)
+   tb.insert(7, my_stuff1)
+ 
+   cut.signal_connect('clicked')       { entf.cut_clipboard; p "Cut" }
+   copy.signal_connect('clicked')      { entf.copy_clipboard; p "Copy" }
+   paste.signal_connect('clicked')     { entf.paste_clipboard; p "Paste" }
+   # Select all of the text in the editable (Gtk::Editable#select_region)
+   selectall.signal_connect('clicked') { entf.select_region(0, -1); p "Sel. All" }
+   
+   my_stuff.signal_connect('clicked')  { p "My Stuff selected." }
+   my_stuff1.signal_connect('clicked') { p "My Stuff-1 selected." }
+   
+   menutearoff = Gtk::TearoffMenuItem.new
+   testi1 = Gtk::MenuItem.new("Test Item #1")
+   testi2 = Gtk::MenuItem.new("Test Item #2")
+   testi3 = Gtk::MenuItem.new("Test Item #3")
+   langi  = Gtk::MenuItem.new("Languages")
+   testi1.signal_connect('activate') { |w| puts "w=#{w.class}:Test Item-1 selected" }
+   testi2.signal_connect('activate') { |w| puts "w=#{w.class}:Test Item-2 selected" }
+   testi3.signal_connect('activate') { |w| puts "w=#{w.class}:Test Item-3 selected" }
+ 
+   # Create Test Menu
+   testmenu = Gtk::Menu.new
+   testmenu.append(menutearoff)
+   testmenu.append(testi1)
+   testmenu.append(testi2)
+   testmenu.append(testi3)
+   testmenu.append(langi)
+ 
+   langmenu = Gtk::Menu.new
+   langi.submenu = langmenu
+ 
+   english = Gtk::MenuItem.new("English")
+   french  = Gtk::MenuItem.new("French")
+   german  = Gtk::MenuItem.new("German")
+   russian = Gtk::MenuItem.new("Russian")
+   italian = Gtk::MenuItem.new("Italian")
+   langmenu.append(english)
+   langmenu.append(french)
+   langmenu.append(german)
+   langmenu.append(russian)
+   langmenu.append(italian)
+   
+   english.signal_connect('activate') { |w| puts "w=#{w.class}:English selected" }
+   french.signal_connect('activate')  { |w| puts "w=#{w.class}:French selected" }
+   german.signal_connect('activate')  { |w| puts "w=#{w.class}:German selected" }
+   russian.signal_connect('activate') { |w| puts "w=#{w.class}:Russian selected" }
+   italian.signal_connect('activate') { |w| puts "w=#{w.class}:Italian selected" }
+     
+   testmenu.show_all
+   mytb_menu.menu = testmenu
+ end
+ # Turn image file into pixbuf, and return nil in case of file error.
+ def get_pixbuf_if_file_exists(file)
+   begin
+     pixbuf = Gdk::Pixbuf.new(file)
+     rescue GLib::FileError => err
+       print "I/O ERROR (%s): %s\n" % [err.class, err]
+       pixbuf = nil
+   end
+   pixbuf
+ end
+ ## ----------
+ ## DnD Source
+ ## ----------
+ 
+ def set_dnd_source_frame_widget(widg)
+ 
+   Gtk::Drag.dest_unset(widg)    # cancel earlier dnd destibation setting
+   
+   widg.add_events(Gdk::Event::BUTTON_PRESS_MASK)
+   widg.signal_connect('button-press-event') do |w, e|
+ 
+     Gtk::Drag.begin(
+ 	widget=w,
+ 	targets=Gtk::TargetList.new(TBDND_TARGETS), # [["toolbar", Gtk::Drag::TARGET_SAME_APP, 100]]
+ 	actions=TBDND_ACTIONS,                      # Gdk::DragContext::ACTION_ASK
+ 	button=e.button,
+ 	e                              # Gdk::Event::DRAG_LEAVE
+     )
+   end
+ end
+ 
+ ## ---------------
+ ## DnD Destination
+ ## ---------------
+ 
+ def reverse_dnd_source_n_destination(src_widg, toolbar, dest_widg)
+   
+   # Remember in the continuation of this method the destination and
+   # source widgets are to be reversed
+   set_dnd_source_frame_widget(dest_widg)
+   set_dnd_destination_frame_widget(dest_widg, toolbar, src_widg)
+ end
+ 
+ def set_dnd_destination_frame_widget(src_widg, toolbar, dest_widg)
+ 
+   Gtk::Drag.dest_set(
+ 		widget=dest_widg,
+ 		flags=Gtk::Drag::DEST_DEFAULT_MOTION,
+ 		targets=TBDND_TARGETS,  # [["toolbar", Gtk::Drag::TARGET_SAME_APP, 100]]
+ 		actions=TBDND_ACTIONS,  # Gdk::DragContext::ACTION_ASK
+ 	)
+ 
+   dest_widg.signal_connect('drag-drop') do |w, e| 
+ 
+     src_widg.remove(toolbar)
+ 
+     if toolbar.orientation == Gtk::Orientation::HORIZONTAL
+       dest_widg.set_size_request(80, 350)
+       new_orientation = Gtk::Orientation::VERTICAL
+       src_widg.set_size_request(350, 10) # x,y ... reduce size of horizontal old source
+     else
+       dest_widg.set_size_request(350, -1)
+       new_orientation = Gtk::Orientation::HORIZONTAL
+       src_widg.set_size_request(10, 350) # x,y ... reduce size of vertical old source
+     end
+ 
+ ##    src_widg.parent.show_all
+     # src_widg.shadow_type = Gtk::SHADOW_NONE	# Gtk::SHADOW_IN
+ 
+     toolbar.orientation = new_orientation
+ 
+     dest_widg.add(toolbar)
+ ##    dest_widg.show_all
+ 
+     Gtk::Drag.source_unset(dest_widg)	# cancel earlier dnd source setting
+ 
+     # NOTE: by now source and destination are already reversed.
+     #       The next reverse will allow next dnd to start all
+     #       over again like nothing ever happened.
+     reverse_dnd_source_n_destination(src_widg, toolbar, dest_widg)
+   end
+ end
+ 
+ entry   = Gtk::Entry.new
+ entry.set_size_request(100, -1)
+ toolbar = Gtk::Toolbar.new
+ 
+ vtbframe = Gtk::Frame.new.set_size_request(10, -1)
+ htbframe = Gtk::Frame.new.set_size_request(200, 10)
+ 
+ vbox = Gtk::VBox.new(false, 0)               # (homogeneous, spacing)
+ hbox = Gtk::HBox.new(false, 0)
+ 
+ vbox.pack_start(htbframe,  false,  false, 0) # (child, expand, fill,  padding)
+ vbox.pack_start(hbox,      true,   true,  0)
+ hbox.pack_start(vtbframe,  false,  false, 0)
+ 
+ workspace = Gtk::VBox.new(false, 5)
+ workspace.pack_start(entry,                     false, false, 0)
+ workspace.pack_start(Gtk::Label.new("D-e-m-o"), true,  true,  0)
+ hbox.pack_start(workspace,                      true,  true,  0)
+ 
+ create_toolbar(toolbar, entry)
+ 
+ toolbar.set_size_request(300, -1)
+ htbframe.set_size_request(300, -1)
+ htbframe.add(toolbar)
+ 
+ set_dnd_source_frame_widget(htbframe)
+ set_dnd_destination_frame_widget(htbframe, toolbar, vtbframe)	# (src_tbfr, toolbar, dest_tbfr)
+ 
+ window.add(vbox)
+ window.show_all
+ Gtk.main




ruby-gnome2-cvs メーリングリストの案内
Zurück zum Archiv-Index