mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* ext/tk/*: Support new features of Tcl/Tk8.6b1 and minor bug fixes.
     ( [KNOWN BUG] Ruby/Tk on Ruby 1.9 will not work on Cygwin. )
* ext/tk/*: Unify sources between Ruby 1.8 & 1.9.
            Improve default_widget_set handling.
* ext/tk/*: Multi-TkInterpreter (multi-tk.rb) works on Ruby 1.8 & 1.9.
     ( [KNOWN BUG] On Ruby 1.8, join to a long term Thread on Tk
       callbacks may freeze. On Ruby 1.9, cannot create a second 
       master interpreter (creating slaves are OK); supported master
       interpreter is the default master interpreter only. )
* ext/tk/lib/tkextlib/*: Update supported versions of Tk extensions.
         Tcllib 1.8/Tklib 0.4.1  ==>  Tcllib 1.11.1/Tklib 0.5
         BWidgets 1.7            ==>  BWidgets 1.8
         TkTable 2.9             ==>  TkTable 2.10
         TkTreeCtrl 2005-12-02   ==>  TkTreeCtrl 2.2.9
         Tile 0.8.0/8.5.1        ==>  Tile 0.8.3/8.6b1
         IncrTcl 2005-02-14      ==>  IncrTcl 2008-12-15
         TclX 2005-02-07         ==>  TclX 2008-12-15
         Trofs 0.4.3             ==>  Trofs 0.4.4
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24063 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
		
	
			
		
			
				
	
	
		
			148 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			148 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
#
 | 
						|
# Tk::RbWidget::Editable_Listbox class
 | 
						|
#
 | 
						|
#   When "DoubleClick-1" on a listbox item, the entry box is opend on the
 | 
						|
#   item. And when hit "Return" key on the entry box after modifying the
 | 
						|
#   text, the entry box is closed and the item is changed. Or when hit
 | 
						|
#   "Escape" key, the entry box is closed without modification.
 | 
						|
#
 | 
						|
#                              by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
 | 
						|
#
 | 
						|
require 'tk'
 | 
						|
 | 
						|
module Tk
 | 
						|
  module RbWidget
 | 
						|
    class Editable_Listbox < TkListbox
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
 | 
						|
class Tk::RbWidget::Editable_Listbox < TkListbox
 | 
						|
  #------------------------------------
 | 
						|
  BindTag = TkBindTag.new_by_name(self.to_s.gsub(/::/, '#'))
 | 
						|
 | 
						|
  BindTag.bind('FocusIn', :widget){|w|
 | 
						|
    w.instance_eval{
 | 
						|
      if idx = @ebox.pos
 | 
						|
        see(idx) if bbox(idx).empty?
 | 
						|
        @ebox.focus(true)
 | 
						|
      end 
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  BindTag.bind('Double-1', :widget, :y){|w, y|
 | 
						|
    w.instance_eval{ _ebox_placer(nearest(y)) }
 | 
						|
  }
 | 
						|
 | 
						|
  BindTag.bind('Return', :widget){|w|
 | 
						|
    w.instance_eval{
 | 
						|
      if idx = index(:active)
 | 
						|
        _ebox_placer(idx)
 | 
						|
      end
 | 
						|
    }
 | 
						|
  }
 | 
						|
  #------------------------------------
 | 
						|
 | 
						|
  def configure(*args)
 | 
						|
    ret = super
 | 
						|
 | 
						|
    case cget(:state)
 | 
						|
    when 'normal'
 | 
						|
      # do nothing
 | 
						|
    when 'disabled'
 | 
						|
      _ebox_erase
 | 
						|
    else # unknown
 | 
						|
      # do nothing
 | 
						|
 | 
						|
    end
 | 
						|
 | 
						|
    ret
 | 
						|
  end
 | 
						|
 | 
						|
  def _ebox_move(idx)
 | 
						|
    return nil if cget(:state) == 'disabled'
 | 
						|
    x, y, w, h = bbox(idx)
 | 
						|
    return nil unless y && h
 | 
						|
    @ebox.place(:x => 0, :relwidth => 1.0,
 | 
						|
                :y => y - selectborderwidth,
 | 
						|
                :height => h + 2 * selectborderwidth)
 | 
						|
    @ebox.pos = idx
 | 
						|
    @ebox.focus
 | 
						|
  end
 | 
						|
 | 
						|
  def _ebox_placer(idx)
 | 
						|
    return nil unless _ebox_move(idx)
 | 
						|
    @ebox.value = listvariable.list[idx]
 | 
						|
    @ebox.xview_moveto(self.xview[0])
 | 
						|
  end
 | 
						|
 | 
						|
  def _ebox_erase
 | 
						|
    @ebox.place_forget
 | 
						|
    @ebox.pos = nil
 | 
						|
  end
 | 
						|
  private :_ebox_move, :_ebox_placer, :_ebox_erase
 | 
						|
 | 
						|
  def _setup_ebox_bindings
 | 
						|
    # bindings for entry
 | 
						|
    @ebox.bind('Return'){
 | 
						|
      list = listvariable.list
 | 
						|
      list[@ebox.pos] = @ebox.value if @ebox.pos
 | 
						|
      listvariable.value = list
 | 
						|
      _ebox_erase
 | 
						|
      focus
 | 
						|
    }
 | 
						|
 | 
						|
    @ebox.bind('Escape'){ _ebox_erase }
 | 
						|
  end
 | 
						|
  def _setup_listbox_bindings
 | 
						|
    # bindings for listbox
 | 
						|
    tags = bindtags
 | 
						|
    bindtags(tags.insert(tags.index(self) + 1, self.class::BindTag))
 | 
						|
  end
 | 
						|
  private :_setup_ebox_bindings,  :_setup_listbox_bindings
 | 
						|
 | 
						|
  def yview(*args)
 | 
						|
    if !@ebox.pos || bbox(@ebox.pos).empty?
 | 
						|
      @ebox.place_forget
 | 
						|
    else
 | 
						|
      _ebox_move(@ebox.pos)
 | 
						|
    end
 | 
						|
    super
 | 
						|
  end
 | 
						|
 | 
						|
  def create_self(keys)
 | 
						|
    super(keys)
 | 
						|
 | 
						|
    unless self.listvariable
 | 
						|
      self.listvariable = TkVariable.new(self.get(0, :end))
 | 
						|
    end
 | 
						|
 | 
						|
    @ebox = TkEntry.new(self){
 | 
						|
      @pos = nil
 | 
						|
      def self.pos; @pos; end
 | 
						|
      def self.pos=(idx); @pos = idx; end
 | 
						|
    }
 | 
						|
 | 
						|
    _setup_ebox_bindings
 | 
						|
    _setup_listbox_bindings
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
if $0 == __FILE__
 | 
						|
  #lbox0 = TkListbox.new.pack(:side=>:left)
 | 
						|
  #lbox0.insert(:end,     0,1,2,3,4,5,6,7,8,9,0,1,2,3)
 | 
						|
 | 
						|
  scr = TkScrollbar.new.pack(:side=>:right, :fill=>:y)
 | 
						|
 | 
						|
  lbox1 = Tk::RbWidget::Editable_Listbox.new.pack(:side=>:left)
 | 
						|
  lbox2 = Tk::RbWidget::Editable_Listbox.new.pack(:side=>:left)
 | 
						|
 | 
						|
  scr.assign(lbox1, lbox2)
 | 
						|
 | 
						|
  lbox1.insert(:end, *%w(a b c d e f g h i j k l m n))
 | 
						|
  lbox2.insert(:end,     0,1,2,3,4,5,6,7,8,9,0,1,2,3)
 | 
						|
 | 
						|
 | 
						|
  Tk.mainloop
 | 
						|
end
 |