mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* sample/tkextlib/treectrl/random.rb: node deselection now works. * sample/tkextlib/treectrl/demo.rb: fixed typo. (popup menu on column header) git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@8275 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
		
			
				
	
	
		
			1307 lines
		
	
	
	
		
			39 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			1307 lines
		
	
	
	
		
			39 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
#!/usr/bin/env ruby
 | 
						|
 | 
						|
require 'tk'
 | 
						|
require 'tkextlib/treectrl'
 | 
						|
 | 
						|
$ScriptDir = File.dirname(File.expand_path(__FILE__))
 | 
						|
 | 
						|
$HasColumnCreate = Tk::TreeCtrl::HasColumnCreateCommand
 | 
						|
 | 
						|
$Version_1_1_OrLater = (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0)
 | 
						|
 | 
						|
if Hash.instance_methods.include?('key')
 | 
						|
  # probably ruby 1.9.x --> use Hash#key
 | 
						|
  # Because Hash#index show warning "Hash#index is deprecated; use Hash#key".
 | 
						|
else
 | 
						|
  # probably ruby 1.8.x --> use Hash#index
 | 
						|
  class Hash
 | 
						|
    alias key index
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
class TkTreeCtrl_demo
 | 
						|
  def initialize(dir)
 | 
						|
    @ScriptDir = dir || '.'
 | 
						|
 | 
						|
    @thisPlatform = Tk::PLATFORM['platform']
 | 
						|
    if @thisPlatform == 'unix' && Tk.windowingsystem == 'aqua'
 | 
						|
      @thisPlatform = 'macosx'
 | 
						|
    end
 | 
						|
 | 
						|
    @RandomN = [500]
 | 
						|
 | 
						|
    @images = Hash.new
 | 
						|
    @sel_images = Hash.new
 | 
						|
 | 
						|
    @popup = Hash.new
 | 
						|
    @mTree = Hash.new
 | 
						|
    @mHeader = Hash.new
 | 
						|
 | 
						|
    @non_clear_list = []
 | 
						|
 | 
						|
    @demoCmd = Hash.new
 | 
						|
    @demoFile = Hash.new
 | 
						|
 | 
						|
    # Get default colors
 | 
						|
    w = TkListbox.new
 | 
						|
    @SystemButtonFace    = w[:highlightbackground]
 | 
						|
    @SystemHighlight     = w[:selectbackground]
 | 
						|
    @SystemHighlightText = w[:selectforeground]
 | 
						|
    w.destroy
 | 
						|
 | 
						|
    ####################
 | 
						|
 | 
						|
    make_source_window()
 | 
						|
    make_menubar()
 | 
						|
    make_main_window()
 | 
						|
 | 
						|
    if $Version_1_1_OrLater
 | 
						|
      begin
 | 
						|
        @tree2[:backgroundimage]
 | 
						|
        @has_bgimg = true
 | 
						|
      rescue
 | 
						|
        @has_bgimg = false
 | 
						|
      end
 | 
						|
    else
 | 
						|
      @has_bgimg = false
 | 
						|
    end
 | 
						|
 | 
						|
    ####################
 | 
						|
 | 
						|
    make_list_popup()
 | 
						|
    make_header_popup()
 | 
						|
 | 
						|
    init_pics('sky')
 | 
						|
 | 
						|
    ####################
 | 
						|
 | 
						|
    @tree2.bind('ButtonPress-3', 
 | 
						|
                proc{|w, x, y, rootx, rooty|
 | 
						|
                  show_list_popup(w, x, y, rootx, rooty)
 | 
						|
                }, '%W %x %y %X %Y')
 | 
						|
 | 
						|
    # Allow "scan" bindings
 | 
						|
    if @thisPlatform == 'windows'
 | 
						|
      @tree2.bind_remove('Control-ButtonPress-3')
 | 
						|
    end
 | 
						|
 | 
						|
    ####################
 | 
						|
 | 
						|
    init_demo_scripts_module()
 | 
						|
    load_demo_scripts()
 | 
						|
    init_demo_list()
 | 
						|
 | 
						|
    ####################
 | 
						|
 | 
						|
    @tree1.notify_bind(@tree1, 'Selection', 
 | 
						|
                       proc{|c, t|
 | 
						|
                         if c == 1
 | 
						|
                           item = t.selection_get[0]
 | 
						|
                           demo_set(@demoCmd[item], @demoFile[item])
 | 
						|
                         end
 | 
						|
                       }, '%c %T')
 | 
						|
 | 
						|
    # When one item is selected in the demo list, display the styles in 
 | 
						|
    # that item.
 | 
						|
    # See DemoClear for why the tag "DontDelete" is used
 | 
						|
    @tree2.notify_bind('DontDelete', 'Selection', 
 | 
						|
                       proc{|c, t|
 | 
						|
                         display_styles_in_item(t.selection_get[0]) if c == 1
 | 
						|
                       }, '%c %T')
 | 
						|
  end
 | 
						|
 | 
						|
  ##########################
 | 
						|
 | 
						|
  def init_pics(*args)
 | 
						|
    args.each{|pat|
 | 
						|
      unless TkImage.names.find{|img| (name = @images.key(img)) && File.fnmatch(pat, name)}
 | 
						|
        Dir.glob(File.join(@ScriptDir, 'pics', "#{pat}.gif")).each{|file|
 | 
						|
          name = File.basename(file, '.gif')
 | 
						|
          img = TkPhotoImage.new(:file=>file)
 | 
						|
          @images[name] = img
 | 
						|
          @sel_images[name] = TkPhotoImage.new
 | 
						|
          @sel_images[name].copy(img)
 | 
						|
          Tk::TreeCtrl.image_tint(@sel_images[name], @SystemHighlight, 128)
 | 
						|
        }
 | 
						|
      end
 | 
						|
    }
 | 
						|
  end
 | 
						|
 | 
						|
  ##########################
 | 
						|
 | 
						|
  private
 | 
						|
 | 
						|
  def make_menubar
 | 
						|
    menuspec = [
 | 
						|
      [['File']]
 | 
						|
    ]
 | 
						|
    if Tk::PLATFORM['platform'] != 'unix'
 | 
						|
      TkConsole.create
 | 
						|
      TkConsole.eval('.console conf -height 8')
 | 
						|
      menuspec[0] << ['Console', proc{
 | 
						|
          if TkComm.bool(TkConsole.eval('winfo ismapped .'))
 | 
						|
            TkConsole.hide
 | 
						|
          else
 | 
						|
            TkConsole.show
 | 
						|
          end
 | 
						|
        }]
 | 
						|
    end
 | 
						|
    menuspec[0] << ['View Source', proc{toggle_source_window()}]
 | 
						|
    menuspec[0] << ['Quit', proc{exit}]
 | 
						|
    Tk.root.add_menubar(menuspec)
 | 
						|
  end
 | 
						|
 | 
						|
  def make_source_window
 | 
						|
    @src_top = TkToplevel.new
 | 
						|
    f = TkFrame.new(@src_top, :borderwidth=>0)
 | 
						|
    case @thisPlatform
 | 
						|
    when 'macintosh', 'macos'
 | 
						|
      font = TkFont.new(['Geneva', 9])
 | 
						|
    when 'unix'
 | 
						|
      font = TkFont.new(['Courier', -12])
 | 
						|
    else
 | 
						|
      font = TkFont.new(['Courier', 9])
 | 
						|
    end
 | 
						|
 | 
						|
    @src_txt = TkText.new(f, :font=>font, :tabs=>font.measure('1234'), 
 | 
						|
                          :wrap=>:none)
 | 
						|
    xscr = @src_txt.xscrollbar(TkScrollbar.new(f))
 | 
						|
    yscr = @src_txt.yscrollbar(TkScrollbar.new(f))
 | 
						|
 | 
						|
    f.pack(:expand=>true, :fill=>:both)
 | 
						|
    f.grid_columnconfigure(0, :weight=>1)
 | 
						|
    f.grid_rowconfigure(0, :weight=>1)
 | 
						|
    @src_txt.grid(:row=>0, :column=>0, :sticky=>:news)
 | 
						|
    xscr.grid(:row=>1, :column=>0, :sticky=>:we)
 | 
						|
    yscr.grid(:row=>0, :column=>1, :sticky=>:ns)
 | 
						|
 | 
						|
    @src_top.protocol('WM_DELETE_WINDOW', proc{@src_top.withdraw})
 | 
						|
    @src_top.geometry('-0+0')
 | 
						|
    @src_top.withdraw
 | 
						|
  end
 | 
						|
 | 
						|
  def show_source(file)
 | 
						|
    @src_top.title("Demo Source: #{file}")
 | 
						|
    @src_txt.value = IO.read(File.join(@ScriptDir, file))
 | 
						|
    @src_txt.set_insert('1.0')
 | 
						|
  end
 | 
						|
 | 
						|
  def toggle_source_window
 | 
						|
    if @src_top.winfo_mapped?
 | 
						|
      @src_top.withdraw
 | 
						|
    else
 | 
						|
      @src_top.deiconify
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  def tree_plus_scrollbars_in_a_frame(parent, h, v)
 | 
						|
    f = TkFrame.new(parent, :borderwidth=>1, :relief=>:sunken)
 | 
						|
    case @thisPlatform
 | 
						|
    when 'macintosh'
 | 
						|
      font = TkFont.new(['Geneva', 9])
 | 
						|
    when 'macos'
 | 
						|
      font = TkFont.new(['Lucida Grande', 11])
 | 
						|
    when 'unix'
 | 
						|
      font = TkFont.new(['Helvetica', -12])
 | 
						|
    else
 | 
						|
      # There is a bug on my Win98 box with Tk_MeasureChars() and
 | 
						|
      # MS Sans Serif 8.
 | 
						|
      font = TkFont.new(['MS Sans', 8])
 | 
						|
    end
 | 
						|
 | 
						|
    tree = Tk::TreeCtrl.new(f, :highlightthickness=>0, 
 | 
						|
                            :borderwidth=>0, :font=>font)
 | 
						|
    tree[:xscrollincrement] = 20
 | 
						|
    tree.debug_configure(:enable=>false, :display=>false)
 | 
						|
 | 
						|
    if h
 | 
						|
      h_scr = TkScrollbar.new(f, :orient=>:horizontal, 
 | 
						|
                              :command=>proc{|*args| tree.xview(*args)})
 | 
						|
      tree.notify_bind(h_scr, 'Scroll-x', 
 | 
						|
                       proc{|w, l, u| w.set(l, u)}, '%W %l %u')
 | 
						|
      h_scr.bind('ButtonPress-1', proc{tree.set_focus})
 | 
						|
    end
 | 
						|
 | 
						|
    if v
 | 
						|
      v_scr = TkScrollbar.new(f, :orient=>:vertical, 
 | 
						|
                              :command=>proc{|*args| tree.yview(*args)})
 | 
						|
      tree.notify_bind(v_scr, 'Scroll-y', 
 | 
						|
                       proc{|w, l, u| w.set(l, u)}, '%W %l %u')
 | 
						|
      v_scr.bind('ButtonPress-1', proc{tree.set_focus})
 | 
						|
    end
 | 
						|
 | 
						|
    f.grid_columnconfigure(0, :weight=>1)
 | 
						|
    f.grid_rowconfigure(0, :weight=>1)
 | 
						|
    tree.grid(:row=>0, :column=>0, :sticky=>:news)
 | 
						|
    h_scr.grid(:row=>1, :column=>0, :sticky=>:we) if h
 | 
						|
    v_scr.grid(:row=>0, :column=>1, :sticky=>:ns) if v
 | 
						|
 | 
						|
    [f, tree]
 | 
						|
  end
 | 
						|
 | 
						|
  def make_main_window
 | 
						|
    Tk.root.title('Tk::TreeCtrl Demo')
 | 
						|
 | 
						|
    case @thisPlatform
 | 
						|
    when 'macintosh', 'macosx'
 | 
						|
      Tk.root.geometry('+40+40')
 | 
						|
    else
 | 
						|
      Tk.root.geometry('+0+30')
 | 
						|
    end
 | 
						|
 | 
						|
    pane1 = TkPanedWindow.new(:orient=>:vertical, :borderwidth=>0)
 | 
						|
    pane2 = TkPanedWindow.new(:orient=>:horizontal, :borderwidth=>0)
 | 
						|
 | 
						|
    # Tree + scrollbar: demos
 | 
						|
    f1, @tree1 = tree_plus_scrollbars_in_a_frame(nil, false, true)
 | 
						|
    @tree1.configure(:showbuttons=>false, :showlines=>:false, 
 | 
						|
                    :showroot=>false, :height=>100)
 | 
						|
    if $HasColumnCreate
 | 
						|
      @tree1.column_create(:text=>'List of Demos', 
 | 
						|
                           :expand=>true, :button=>false)
 | 
						|
    else
 | 
						|
      @tree1.column_configure(0, :text=>'List of Demos', 
 | 
						|
                              :expand=>true, :button=>false)
 | 
						|
    end
 | 
						|
 | 
						|
    # Tree + scrollbar: styles + elements in list
 | 
						|
    f4, @tree4 = tree_plus_scrollbars_in_a_frame(nil, false, true)
 | 
						|
    @tree4.configure(:showroot=>false, :height=>140)
 | 
						|
    if $HasColumnCreate
 | 
						|
      @tree4.column_create(:text=>'Elements and Styles', 
 | 
						|
                           :expand=>true, :button=>false)
 | 
						|
    else
 | 
						|
      @tree4.column_configure(0, :text=>'Elements and Styles', 
 | 
						|
                              :expand=>true, :button=>false)
 | 
						|
    end
 | 
						|
 | 
						|
    # Tree + scrollbar: styles + elements in selected item
 | 
						|
    f3, @tree3 = tree_plus_scrollbars_in_a_frame(nil, false, true)
 | 
						|
    @tree3.configure(:showroot=>false)
 | 
						|
    if $HasColumnCreate
 | 
						|
      @tree3.column_create(:text=>'Styles in Item', 
 | 
						|
                           :expand=>true, :button=>false)
 | 
						|
    else
 | 
						|
      @tree3.column_configure(0, :text=>'Styles in Item', 
 | 
						|
                              :expand=>true, :button=>false)
 | 
						|
    end
 | 
						|
 | 
						|
    pane1.add(f1, f4, f3, :height=>150)
 | 
						|
    pane1.pack(:expand=>true, :fill=>:both)
 | 
						|
 | 
						|
    # Frame on right
 | 
						|
    f2_base = TkFrame.new
 | 
						|
 | 
						|
    # Tree + scrollbars
 | 
						|
    f2, @tree2 = tree_plus_scrollbars_in_a_frame(f2_base, true, true)
 | 
						|
    @tree2.configure(:indent=>19)
 | 
						|
    @tree2.debug_configure(:enable=>false, :display=>true, 
 | 
						|
                           :erasecolor=>'pink', :displaydelay=>30)
 | 
						|
 | 
						|
    # Give it a big border to debug drawing
 | 
						|
    @tree2.configure(:borderwidth=>6, :relief=>:ridge, :highlightthickness=>3)
 | 
						|
 | 
						|
    f2_base.grid_columnconfigure(0, :weight=>1)
 | 
						|
    f2_base.grid_rowconfigure(0, :weight=>1)
 | 
						|
    f2.grid(:row=>0, :column=>0, :sticky=>:news, :pady=>0)
 | 
						|
 | 
						|
    pane2.add(pane1, :width=>200)
 | 
						|
    pane2.add(f2_base, :width=>450)
 | 
						|
 | 
						|
    pane2.pack(:expand=>true, :fill=>:both)
 | 
						|
 | 
						|
    ###
 | 
						|
    # A treectrl widget can generate the following built-in events:
 | 
						|
    # <ActiveItem> called when the active item changes
 | 
						|
    # <Collapse-before> called before an item is closed
 | 
						|
    # <Collapse-after> called after an item is closed
 | 
						|
    # <Expand-before> called before an item is opened
 | 
						|
    # <Expand-after> called after an item is opened
 | 
						|
    # <Selection> called when items are added to or removed from the selection
 | 
						|
    # <Scroll-x> called when horizontal scroll position changes
 | 
						|
    # <Scroll-y> called when vertical scroll position changes
 | 
						|
    #
 | 
						|
    # The application programmer can define custom events to be
 | 
						|
    # generated by the "T notify generate" command. The following events
 | 
						|
    # are generated by the example bindings.
 | 
						|
 | 
						|
    @tree2.notify_install_event('Header')
 | 
						|
    @tree2.notify_install_detail('Header', 'invoke')
 | 
						|
 | 
						|
    @tree2.notify_install_event('Drag')
 | 
						|
    @tree2.notify_install_detail('Drag', 'begin')
 | 
						|
    @tree2.notify_install_detail('Drag', 'end')
 | 
						|
    @tree2.notify_install_detail('Drag', 'receive')
 | 
						|
 | 
						|
    @tree2.notify_install_event('Edit')
 | 
						|
    @tree2.notify_install_detail('Edit', 'accept')
 | 
						|
  end
 | 
						|
 | 
						|
  def make_list_popup
 | 
						|
    @popup[:bgimg] = TkVariable.new
 | 
						|
    @popup[:bgmode] = TkVariable.new
 | 
						|
    @popup[:debug] = Hash.new{|h, k| h[k] = TkVariable.new}
 | 
						|
    @popup[:doublebuffer] = TkVariable.new
 | 
						|
    @popup[:linestyle] = TkVariable.new
 | 
						|
    @popup[:orient] = TkVariable.new
 | 
						|
    @popup[:selectmode] = TkVariable.new
 | 
						|
    @popup[:show] = Hash.new{|h, k| h[k] = TkVariable.new}
 | 
						|
 | 
						|
    menuspec = [
 | 
						|
      [ 'Collapse', [], nil, '', {:menu_config=>{:tearoff=>false}} ], 
 | 
						|
 | 
						|
      [ 'Expand',   [], nil, '', {:menu_config=>{:tearoff=>false}} ]
 | 
						|
    ]
 | 
						|
 | 
						|
    # if $Version_1_1_OrLater
 | 
						|
    if @has_bgimg
 | 
						|
      menuspec << \
 | 
						|
      [ 'Background Image', 
 | 
						|
        [
 | 
						|
          [ 'none', [@popup[:bgimg], 'none'], nil, '', 
 | 
						|
            {:command=>proc{@tree2.backgroundimage = ''}} ], 
 | 
						|
          [ 'sky',  [@popup[:bgimg], 'sky'],  nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.backgroundimage = @images[@popup[:bgimg].value]}} ]
 | 
						|
        ], 
 | 
						|
        nil, '', {:menu_config=>{:tearoff=>false}}
 | 
						|
      ]
 | 
						|
    end
 | 
						|
 | 
						|
    menuspec.concat([
 | 
						|
      [ 'Background Mode', 
 | 
						|
        %w(column index row visindex).collect{|val|
 | 
						|
          [ val, [@popup[:bgmode], val] , nil, '', 
 | 
						|
            {:command=>proc{@tree2.backgroundmode = @popup[:bgmode].value}} ]
 | 
						|
        }, 
 | 
						|
        nil, '', {:menu_config=>{:tearoff=>false}}
 | 
						|
      ],
 | 
						|
 | 
						|
      [ 'Debug', 
 | 
						|
        [
 | 
						|
          [ 'Data',    @popup[:debug][:data],    nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.debug_configure(:data=>@popup[:debug][:data].value)
 | 
						|
              }
 | 
						|
            } ], 
 | 
						|
          [ 'Display', @popup[:debug][:display], nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.debug_configure(:display=>@popup[:debug][:display].value)
 | 
						|
              }
 | 
						|
            } ], 
 | 
						|
          [ 'Enable',  @popup[:debug][:enable],  nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.debug_configure(:enable=>@popup[:debug][:enable].value)
 | 
						|
              }
 | 
						|
            } ]
 | 
						|
        ], 
 | 
						|
        nil, '', {:menu_config=>{:tearoff=>false}}
 | 
						|
      ],
 | 
						|
 | 
						|
      [ 'Buffering', 
 | 
						|
        [
 | 
						|
          [ 'none',   [@popup[:doublebuffer], 'none'],   nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.doublebuffer = @popup[:doublebuffer].value
 | 
						|
              }
 | 
						|
            } ], 
 | 
						|
          [ 'item',   [@popup[:doublebuffer], 'item'],   nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.doublebuffer = @popup[:doublebuffer].value
 | 
						|
              }
 | 
						|
            } ], 
 | 
						|
          [ 'window', [@popup[:doublebuffer], 'window'], nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.doublebuffer = @popup[:doublebuffer].value
 | 
						|
              }
 | 
						|
            } ]
 | 
						|
        ],
 | 
						|
        nil, '', {:menu_config=>{:tearoff=>false}}
 | 
						|
      ],
 | 
						|
 | 
						|
      [ 'Line style', 
 | 
						|
        [
 | 
						|
          [ 'dot',   [@popup[:linestyle], 'dot'],   nil, '', 
 | 
						|
            {:command=>proc{@tree2.linestyle = @popup[:linestyle].value}} ], 
 | 
						|
          [ 'solid', [@popup[:linestyle], 'solid'], nil, '', 
 | 
						|
            {:command=>proc{@tree2.linestyle = @popup[:linestyle].value}} ]
 | 
						|
        ], 
 | 
						|
        nil, '', {:menu_config=>{:tearoff=>false}}
 | 
						|
      ],
 | 
						|
 | 
						|
      [ 'Orient', 
 | 
						|
        [
 | 
						|
          [ 'Horizontal', [@popup[:orient], 'horizontal'], nil, '', 
 | 
						|
            {:command=>proc{@tree2.orient = @popup[:orient].value}} ], 
 | 
						|
          [ 'Vertical',   [@popup[:orient], 'vertical'],   nil, '', 
 | 
						|
            {:command=>proc{@tree2.orient = @popup[:orient].value}} ]
 | 
						|
        ], 
 | 
						|
        nil, '', {:menu_config=>{:tearoff=>false}}
 | 
						|
      ],
 | 
						|
 | 
						|
      [ 'Selectmode', 
 | 
						|
        %w(list browse extended multiple single).collect{|val|
 | 
						|
          [ val, [@popup[:selectmode], val] , nil, '', 
 | 
						|
            {:command=>proc{@tree2.selectmode = @popup[:selectmode].value}} ]
 | 
						|
        }, 
 | 
						|
        nil, '', {:menu_config=>{:tearoff=>false}}
 | 
						|
      ],
 | 
						|
 | 
						|
      [ 'Show', 
 | 
						|
        [
 | 
						|
          [ 'Buttons', @popup[:show][:buttons], nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.showbuttons = @popup[:show][:buttons].value
 | 
						|
              }
 | 
						|
            } ], 
 | 
						|
          [ 'Header', @popup[:show][:header], nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.showheader = @popup[:show][:header].value
 | 
						|
              }
 | 
						|
            } ], 
 | 
						|
          [ 'Lines', @popup[:show][:lines], nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.showlines = @popup[:show][:lines].value
 | 
						|
              }
 | 
						|
            } ], 
 | 
						|
          [ 'Root', @popup[:show][:root], nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.showroot = @popup[:show][:root].value
 | 
						|
              }
 | 
						|
            } ], 
 | 
						|
          [ 'Root Button', @popup[:show][:rootbutton], nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.showrootbutton = @popup[:show][:rootbutton].value
 | 
						|
              }
 | 
						|
            } ]
 | 
						|
        ], 
 | 
						|
        nil, '', {:menu_config=>{:tearoff=>false}}
 | 
						|
      ],
 | 
						|
 | 
						|
      [ 'Visible', [], nil, '', {:menu_config=>{:tearoff=>false}} ]
 | 
						|
    ])
 | 
						|
 | 
						|
    m = TkMenu.new_menuspec(menuspec, @tree2, false)
 | 
						|
    @non_clear_list << m
 | 
						|
    @mTree[@tree2] = m
 | 
						|
  end
 | 
						|
 | 
						|
  def show_list_popup(w, x, y, rootx, rooty)
 | 
						|
    id = w.identify(x, y)
 | 
						|
    unless id.empty?
 | 
						|
      if id[0] == 'header'
 | 
						|
        col = id[1]
 | 
						|
        @popup[:column].value = col
 | 
						|
        @popup[:arrow].value = w.column_cget(col, :arrow)
 | 
						|
        @popup[:arrowside].value = w.column_cget(col, :arrowside)
 | 
						|
        @popup[:arrowgravity].value = w.column_cget(col, :arrowgravity)
 | 
						|
        @popup[:expand].value = w.column_cget(col, :expand)
 | 
						|
        @popup[:squeeze].value = w.column_cget(col, :squeeze)
 | 
						|
        @popup[:justify].value = w.column_cget(col, :justify)
 | 
						|
        @mHeader[w].popup(rootx, rooty)
 | 
						|
        return
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    m = @mTree[w].entrycget('Collapse', :menu)
 | 
						|
    m.delete(0, :end)
 | 
						|
    if $Version_1_1_OrLater
 | 
						|
      m.add_command(:label=>'All', :command=>proc{w.item_collapse(:all)})
 | 
						|
    else
 | 
						|
      m.add_command(:label=>'All', :command=>proc{w.collapse(:all)})
 | 
						|
    end
 | 
						|
    unless id.empty?
 | 
						|
      if id[0] == 'item'
 | 
						|
        item = id[1]
 | 
						|
        if $Version_1_1_OrLater
 | 
						|
          m.add_command(:label=>"Item #{item}", 
 | 
						|
                        :command=>proc{w.item_collapse(item)})
 | 
						|
          m.add_command(:label=>"Item #{item} (recurse)", 
 | 
						|
                        :command=>proc{w.item_collapse_recurse(item)})
 | 
						|
        else
 | 
						|
          m.add_command(:label=>"Item #{item}", 
 | 
						|
                        :command=>proc{w.collapse(item)})
 | 
						|
          m.add_command(:label=>"Item #{item} (recurse)", 
 | 
						|
                        :command=>proc{w.collapse_recurse(item)})
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    m = @mTree[w].entrycget('Expand', :menu)
 | 
						|
    m.delete(0, :end)
 | 
						|
    if $Version_1_1_OrLater
 | 
						|
      m.add_command(:label=>'All', :command=>proc{w.item_expand(:all)})
 | 
						|
    else
 | 
						|
      m.add_command(:label=>'All', :command=>proc{w.expand(:all)})
 | 
						|
    end
 | 
						|
    unless id.empty?
 | 
						|
      if id[0] == 'item'
 | 
						|
        item = id[1]
 | 
						|
        if $Version_1_1_OrLater
 | 
						|
          m.add_command(:label=>"Item #{item}", 
 | 
						|
                        :command=>proc{w.item_expand(item)})
 | 
						|
          m.add_command(:label=>"Item #{item} (recurse)", 
 | 
						|
                        :command=>proc{w.item_expand_recurse(item)})
 | 
						|
        else
 | 
						|
          m.add_command(:label=>"Item #{item}", 
 | 
						|
                        :command=>proc{w.expand(item)})
 | 
						|
          m.add_command(:label=>"Item #{item} (recurse)", 
 | 
						|
                        :command=>proc{w.expand_recurse(item)})
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    [:data, :display, :enable].each{|k|
 | 
						|
      @popup[:debug][k].value = w.debug_cget(k)
 | 
						|
    }
 | 
						|
    # if $Version_1_1_OrLater
 | 
						|
    if @has_bgimg
 | 
						|
      @popup[:bgimg].value = @images.key(w[:backgroundimage])
 | 
						|
    end
 | 
						|
    @popup[:bgmode].value = w[:backgroundmode]
 | 
						|
    @popup[:doublebuffer].value = w[:doublebuffer]
 | 
						|
    @popup[:linestyle].value = w[:linestyle]
 | 
						|
    @popup[:orient].value = w[:orient]
 | 
						|
    @popup[:selectmode].value = w[:selectmode]
 | 
						|
    @popup[:show][:buttons].value = w[:showbuttons]
 | 
						|
    @popup[:show][:header].value = w[:showheader]
 | 
						|
    @popup[:show][:lines].value = w[:showlines]
 | 
						|
    @popup[:show][:root].value = w[:showroot]
 | 
						|
    @popup[:show][:rootbutton].value = w[:showrootbutton]
 | 
						|
 | 
						|
    m = @mTree[w].entrycget('Visible', :menu)
 | 
						|
    m.delete(0, :end)
 | 
						|
    @popup[:visible] = []
 | 
						|
    (0...(w.numcolumns)).each{|i|
 | 
						|
      @popup[:visible][i] = TkVariable.new(w.column_cget(i, :visible))
 | 
						|
      txt = w.column_cget(i, :text)
 | 
						|
      img_name = w.column_cget(i, :image)
 | 
						|
      img_name = @images.key(img_name) if img_name.kind_of?(TkImage)
 | 
						|
      m.add_checkbutton(:variable=>@popup[:visible][i], 
 | 
						|
                        :label=>"Column #{i} \"#{txt}\" [#{img_name}]", 
 | 
						|
                        :command=>proc{w.column_configure(i, :visible=>@popup[:visible][i].value)})
 | 
						|
    }
 | 
						|
 | 
						|
    @mTree[w].popup(rootx, rooty)
 | 
						|
  end
 | 
						|
 | 
						|
  def make_header_popup
 | 
						|
    @popup[:column] = TkVariable.new unless @popup[:column]
 | 
						|
    @popup[:arrow] = TkVariable.new
 | 
						|
    @popup[:arrowside] = TkVariable.new
 | 
						|
    @popup[:arrowgravity] = TkVariable.new
 | 
						|
    @popup[:expand] = TkVariable.new
 | 
						|
    @popup[:squeeze] = TkVariable.new
 | 
						|
    @popup[:justify] = TkVariable.new
 | 
						|
 | 
						|
    menuspec = [
 | 
						|
      [ 'Arrow', 
 | 
						|
        [
 | 
						|
          [ 'None', [@popup[:arrow], 'none'], nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.column_configure(@popup[:column].value, :arrow=>:none)
 | 
						|
              }
 | 
						|
            } ],
 | 
						|
          [ 'Up', [@popup[:arrow], 'up'], nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.column_configure(@popup[:column].value, :arrow=>:up)
 | 
						|
              }
 | 
						|
            } ],
 | 
						|
          [ 'Down', [@popup[:arrow], 'down'], nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.column_configure(@popup[:column].value, :arrow=>:down)
 | 
						|
              }
 | 
						|
            } ],
 | 
						|
 | 
						|
          '---', 
 | 
						|
 | 
						|
          [ 'Side Left', [@popup[:arrowside], 'left'], nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.column_configure(@popup[:column].value, 
 | 
						|
                                        :arrowside=>:left)
 | 
						|
              }
 | 
						|
            } ],
 | 
						|
          [ 'Side Right', [@popup[:arrowside], 'right'], nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.column_configure(@popup[:column].value, 
 | 
						|
                                        :arrowside=>:right)
 | 
						|
              }
 | 
						|
            } ],
 | 
						|
 | 
						|
          '---', 
 | 
						|
 | 
						|
          [ 'Gravity Left', [@popup[:arrowgravity], 'left'], nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.column_configure(@popup[:column].value, 
 | 
						|
                                        :arrowgravity=>:left)
 | 
						|
              }
 | 
						|
            } ],
 | 
						|
          [ 'Gravity Right', [@popup[:arrowgravity], 'right'], nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.column_configure(@popup[:column].value, 
 | 
						|
                                        :arrowgravity=>:right)
 | 
						|
              }
 | 
						|
            } ],
 | 
						|
        ], 
 | 
						|
        nil, '', {:menu_config=>{:tearoff=>false}} ], 
 | 
						|
 | 
						|
      [ 'Expand',  @popup[:expand],  nil, '', 
 | 
						|
        {:command=>proc{
 | 
						|
            @tree2.column_configure(@popup[:column].value, 
 | 
						|
                                    :expand=>@popup[:expand].value)
 | 
						|
          }
 | 
						|
        } ],
 | 
						|
 | 
						|
      [ 'Squeeze', @popup[:squeeze], nil, '', 
 | 
						|
        {:command=>proc{
 | 
						|
            @tree2.column_configure(@popup[:column].value, 
 | 
						|
                                    :squeeze=>@popup[:squeeze].value)
 | 
						|
          }
 | 
						|
        } ],
 | 
						|
 | 
						|
      [ 'Justify', 
 | 
						|
        [
 | 
						|
          [ 'Left', [@popup[:justify], 'left'], nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.column_configure(@popup[:column].value, :justify=>:left)
 | 
						|
              }
 | 
						|
            } ],
 | 
						|
          [ 'Center', [@popup[:justify], 'center'], nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.column_configure(@popup[:column].value, 
 | 
						|
                                        :justify=>:center)
 | 
						|
              }
 | 
						|
            } ],
 | 
						|
          [ 'Right', [@popup[:justify], 'right'], nil, '', 
 | 
						|
            {:command=>proc{
 | 
						|
                @tree2.column_configure(@popup[:column].value, 
 | 
						|
                                        :justify=>:right)
 | 
						|
              }
 | 
						|
            } ]
 | 
						|
        ], 
 | 
						|
        nil, '', {:menu_config=>{:tearoff=>false}} ]
 | 
						|
    ]
 | 
						|
 | 
						|
    m = TkMenu.new_menuspec(menuspec, @tree2, false)
 | 
						|
    @non_clear_list << m
 | 
						|
    @mHeader[@tree2] = m
 | 
						|
  end
 | 
						|
 | 
						|
  ###########################
 | 
						|
 | 
						|
  def init_demo_scripts_module
 | 
						|
    @demo_scripts = Module.new
 | 
						|
 | 
						|
    master = self
 | 
						|
 | 
						|
    has_bgimg = @has_bgimg
 | 
						|
 | 
						|
    scriptDir = @ScriptDir
 | 
						|
 | 
						|
    thisPlatform = @thisPlatform
 | 
						|
 | 
						|
    randomN = @RandomN
 | 
						|
 | 
						|
    images = @images
 | 
						|
    sel_images = @sel_images
 | 
						|
 | 
						|
    systemButtonFace = @SystemButtonFace
 | 
						|
    systemHighlight  = @SystemHighlight
 | 
						|
    systemHighlightText = @SystemHighlightText
 | 
						|
 | 
						|
    proc_disp_styles_in_item = proc{|item| 
 | 
						|
      master.instance_eval{ display_styles_in_item(item) }
 | 
						|
    }
 | 
						|
 | 
						|
    @demo_scripts.instance_eval{
 | 
						|
      @master = master
 | 
						|
 | 
						|
      @has_bgimg = has_bgimg
 | 
						|
 | 
						|
      @display_styles_in_item = proc_disp_styles_in_item
 | 
						|
 | 
						|
      @Priv = TkVarAccess.new('::TreeCtrl::Priv')
 | 
						|
 | 
						|
      @ScriptDir = scriptDir
 | 
						|
 | 
						|
      @thisPlatform = thisPlatform
 | 
						|
 | 
						|
      @RandomN = randomN
 | 
						|
 | 
						|
      @images = images
 | 
						|
      @sel_images = sel_images
 | 
						|
 | 
						|
      @SystemButtonFace = systemButtonFace
 | 
						|
      @SystemHighlight  = systemHighlight
 | 
						|
      @SystemHighlightText = systemHighlightText
 | 
						|
    }
 | 
						|
 | 
						|
    class << @demo_scripts
 | 
						|
      def _get_binding
 | 
						|
        binding
 | 
						|
      end
 | 
						|
      private :_get_binding
 | 
						|
 | 
						|
      def load_demo(file)
 | 
						|
        puts "load \"#{file}\"" if $DEBUG
 | 
						|
        begin
 | 
						|
          eval(IO.readlines(file).join, _get_binding())
 | 
						|
        rescue Exception => e
 | 
						|
          bt = e.backtrace
 | 
						|
 | 
						|
          if bt[0] =~ /^([^:]+):(\d+):/
 | 
						|
            errline = $2.to_i
 | 
						|
          else
 | 
						|
            raise e
 | 
						|
          end
 | 
						|
 | 
						|
          if bt[1] =~ /^([^:]+):(\d+):/
 | 
						|
            bt.unshift("#{file}:#{errline - $2.to_i + 1}")
 | 
						|
            raise e
 | 
						|
          else
 | 
						|
            raise e
 | 
						|
          end
 | 
						|
        end
 | 
						|
      end
 | 
						|
 | 
						|
      def init_pics(*args)
 | 
						|
        @master.init_pics(*args)
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  def load_demo_scripts
 | 
						|
    # demo sources
 | 
						|
    [
 | 
						|
      'bitmaps',  
 | 
						|
      'explorer', 
 | 
						|
      'help', 
 | 
						|
      'imovie', 
 | 
						|
      'layout', 
 | 
						|
      'mailwasher', 
 | 
						|
      'outlook-folders', 
 | 
						|
      'outlook-newgroup', 
 | 
						|
      'random', 
 | 
						|
      'www-options'
 | 
						|
    ].each{|f|
 | 
						|
      @demo_scripts.load_demo(File.join(@ScriptDir, "#{f}.rb"))
 | 
						|
    }
 | 
						|
  end
 | 
						|
 | 
						|
  ###########################
 | 
						|
 | 
						|
  def init_demo_list
 | 
						|
    @tree1.element_create('e1', :text, 
 | 
						|
                          :fill=>[@SystemHighlightText, ['selected', 'focus']])
 | 
						|
    @tree1.element_create('e2', :rect, :showfocus=>true, 
 | 
						|
                          :fill=>[
 | 
						|
                            @SystemHighlight, ['selected', 'focus'], 
 | 
						|
                            'gray', ['selected', '!focus'], 
 | 
						|
                          ])
 | 
						|
    @tree1.style_create('s1')
 | 
						|
    @tree1.style_elements('s1', ['e2', 'e1'])
 | 
						|
 | 
						|
    # Tk listbox has linespace + 1 height
 | 
						|
    @tree1.style_layout('s1', 'e2', :union=>['e1'], 
 | 
						|
                        :ipadx=>2, :ipady=>[0, 1], :iexpand=>:e)
 | 
						|
 | 
						|
    if $Version_1_1_OrLater
 | 
						|
      @tree1.defaultstyle = 's1'
 | 
						|
    end
 | 
						|
 | 
						|
    ###
 | 
						|
    [
 | 
						|
      ["Random #{@RandomN[0]} Items", :demoRandom, 'random.rb'], 
 | 
						|
      ["Random #{@RandomN[0]} Items, Button Images", :demoRandom2, 'random.rb'], 
 | 
						|
      ["Outlook Express (Folders)", :demoOutlookFolders, 'outlook-folders.rb'],
 | 
						|
      ["Outlook Express (Newsgroup)", :demoOutlookNewsgroup, 'outlook-newgroup.rb'], 
 | 
						|
      ["Explorer (Details)", :demoExplorerDetails, 'explorer.rb'], 
 | 
						|
      ["Explorer (List)", :demoExplorerList, 'explorer.rb'], 
 | 
						|
      ["Explorer (Large icons)", :demoExplorerLargeIcons, 'explorer.rb'], 
 | 
						|
      ["Explorer (Small icons)", :demoExplorerSmallIcons, 'explorer.rb'], 
 | 
						|
      ["Internet Options", :demoInternetOptions, 'www-options.rb'], 
 | 
						|
      ["Help Contents", :demoHelpContents, 'help.rb'], 
 | 
						|
      ["Layout", :demoLayout, 'layout.rb'], 
 | 
						|
      ["MailWasher", :demoMailWasher, 'mailwasher.rb'], 
 | 
						|
      ["Bitmaps", :demoBitmaps, 'bitmaps.rb'], 
 | 
						|
      ["iMovie", :demoIMovie, 'imovie.rb']
 | 
						|
    ].each{|label, cmd, file|
 | 
						|
      item = @tree1.item_create
 | 
						|
      @tree1.item_lastchild(:root, item)
 | 
						|
      unless $Version_1_1_OrLater
 | 
						|
        @tree1.item_style_set(item, 0, 's1')
 | 
						|
      end
 | 
						|
      @tree1.item_text(item, 0, label)
 | 
						|
      @demoCmd[item] = cmd
 | 
						|
      @demoFile[item] = file
 | 
						|
    }
 | 
						|
 | 
						|
    @tree1.yview_moveto(0.0)
 | 
						|
  end
 | 
						|
 | 
						|
  def demo_set(cmd, file)
 | 
						|
    demo_clear()
 | 
						|
    clicks = Tk::Clock.clicks
 | 
						|
    @demo_scripts.__send__(cmd, @tree2)
 | 
						|
    clicks = Tk::Clock.clicks - clicks
 | 
						|
    puts "set list in #{'%.2g'%(clicks/1000000.0)} seconds (#{clicks} clicks)"
 | 
						|
    @tree2.xview_moveto(0)
 | 
						|
    @tree2.yview_moveto(0)
 | 
						|
    Tk.update
 | 
						|
    display_styles_in_list()
 | 
						|
    show_source(file)
 | 
						|
  end
 | 
						|
 | 
						|
  def display_styles_in_list
 | 
						|
    # Create elements and styles the first time this is called
 | 
						|
    if @tree4.style_names.empty?
 | 
						|
      @tree4.element_create('e1', :text, 
 | 
						|
                            :fill=>[@SystemHighlightText,['selected','focus']])
 | 
						|
      @tree4.element_create('e2', :text, 
 | 
						|
                            :fill=>[
 | 
						|
                              @SystemHighlightText, ['selected','focus'], 
 | 
						|
                              '', ['selected','!focus'], 
 | 
						|
                              'blue', []
 | 
						|
                            ])
 | 
						|
      @tree4.element_create('e3', :rect, :showfocus=>true, 
 | 
						|
                            :fill=>[
 | 
						|
                              @SystemHighlight, ['selected','focus'],
 | 
						|
                              'gray', ['selected', '!focus']
 | 
						|
                            ])
 | 
						|
 | 
						|
      @tree4.style_create('s1')
 | 
						|
      @tree4.style_elements('s1', ['e3', 'e1'])
 | 
						|
      @tree4.style_layout('s1', 'e3', :union=>['e1'], :ipadx=>1, :ipady=>[0,1])
 | 
						|
 | 
						|
      @tree4.style_create('s2')
 | 
						|
      @tree4.style_elements('s2', ['e3', 'e1', 'e2'])
 | 
						|
      @tree4.style_layout('s2', 'e1', :padx=>[0,4])
 | 
						|
      @tree4.style_layout('s2', 'e3', :union=>['e1', 'e2'], 
 | 
						|
                          :ipadx=>1, :ipady=>[0,1])
 | 
						|
    end
 | 
						|
 | 
						|
    # Clear the list
 | 
						|
    @tree4.item_delete(:all)
 | 
						|
    
 | 
						|
    # One item for each element in the demo list
 | 
						|
    @tree2.element_names.sort.each{|elem|
 | 
						|
      if $Version_1_1_OrLater
 | 
						|
        item = @tree4.item_create(:button=>true)
 | 
						|
        @tree4.item_collapse(item)
 | 
						|
      else
 | 
						|
        item = @tree4.item_create
 | 
						|
        @tree4.item_hasbutton(item, true)
 | 
						|
        @tree4.collapse(item)
 | 
						|
      end
 | 
						|
      @tree4.item_style_set(item, 0, 's1')
 | 
						|
      @tree4.item_text(item, 0, 
 | 
						|
                       "Element #{elem} (#{@tree2.element_type(elem)})")
 | 
						|
 | 
						|
      # One item for each configuration option for this element
 | 
						|
      @tree2.element_configinfo(elem).each{|name, x, y, default, current|
 | 
						|
        item2 = @tree4.item_create
 | 
						|
 | 
						|
        if default == current
 | 
						|
          @tree4.item_style_set(item2, 0, 's1')
 | 
						|
          @tree4.item_complex(item2, [
 | 
						|
                                ['e1', {:text=>"#{name} #{current.inspect}"}]
 | 
						|
                              ])
 | 
						|
        else
 | 
						|
          @tree4.item_style_set(item2, 0, 's2')
 | 
						|
          @tree4.item_complex(item2, [
 | 
						|
                                ['e1', {:text=>name}], 
 | 
						|
                                ['e2', {:text=>current.inspect}]
 | 
						|
                              ])
 | 
						|
        end
 | 
						|
 | 
						|
        @tree4.item_lastchild(item, item2)
 | 
						|
      }
 | 
						|
 | 
						|
      @tree4.item_lastchild(:root, item)
 | 
						|
    }
 | 
						|
 | 
						|
    # One item for each style in the demo list
 | 
						|
    @tree2.style_names.sort.each{|sty|
 | 
						|
      if $Version_1_1_OrLater
 | 
						|
        item = @tree4.item_create(:button=>true)
 | 
						|
        @tree4.item_collapse(item)
 | 
						|
      else
 | 
						|
        item = @tree4.item_create
 | 
						|
        @tree4.item_hasbutton(item, true)
 | 
						|
        @tree4.collapse(item)
 | 
						|
      end
 | 
						|
      @tree4.item_style_set(item, 0, 's1')
 | 
						|
      @tree4.item_text(item, 0, "Style #{sty}")
 | 
						|
 | 
						|
      # One item for each element in the style
 | 
						|
      @tree2.style_elements(sty).each{|elem|
 | 
						|
        if $Version_1_1_OrLater
 | 
						|
          item2 = @tree4.item_create(:button=>true)
 | 
						|
          @tree4.item_collapse(item2)
 | 
						|
        else
 | 
						|
          item2 = @tree4.item_create
 | 
						|
          @tree4.item_hasbutton(item2, true)
 | 
						|
          @tree4.collapse(item2)
 | 
						|
        end
 | 
						|
        @tree4.item_style_set(item2, 0, 's1')
 | 
						|
        @tree4.item_text(item2, 0, 
 | 
						|
                         "Element #{elem} (#{@tree2.element_type(elem)})")
 | 
						|
 | 
						|
        # One item for each layout option for this element in this style
 | 
						|
        @tree2.style_layout(sty, elem).each{|k, v|
 | 
						|
          item3 = @tree4.item_create
 | 
						|
          unless $Version_1_1_OrLater
 | 
						|
            @tree4.item_hasbutton(item3, false)
 | 
						|
          end
 | 
						|
          @tree4.item_style_set(item3, 0, 's1')
 | 
						|
          @tree4.item_text(item3, 0, "#{k} #{v.inspect}")
 | 
						|
          @tree4.item_lastchild(item2, item3)
 | 
						|
        }
 | 
						|
 | 
						|
        @tree4.item_lastchild(item, item2)
 | 
						|
      }
 | 
						|
 | 
						|
      @tree4.item_lastchild(:root, item)
 | 
						|
    }
 | 
						|
 | 
						|
    @tree4.xview_moveto(0)
 | 
						|
    @tree4.yview_moveto(0)
 | 
						|
  end
 | 
						|
 | 
						|
  def display_styles_in_item(item)
 | 
						|
    @tree3.column_configure(0, :text=>"Styles in item #{@tree2.index(item)}")
 | 
						|
 | 
						|
    # Create elements and styles the first time this is called
 | 
						|
    if @tree3.style_names.empty?
 | 
						|
      @tree3.element_create('e1', :text, 
 | 
						|
                            :fill=>[@SystemHighlightText,['selected','focus']])
 | 
						|
      @tree3.element_create('e2', :text, 
 | 
						|
                            :fill=>[
 | 
						|
                              @SystemHighlightText, ['selected','focus'], 
 | 
						|
                              '', ['selected','!focus'], 
 | 
						|
                              'blue', []
 | 
						|
                            ])
 | 
						|
      @tree3.element_create('e3', :rect, :showfocus=>true, 
 | 
						|
                            :fill=>[
 | 
						|
                              @SystemHighlight, ['selected','focus'],
 | 
						|
                              'gray', ['selected', '!focus']
 | 
						|
                            ])
 | 
						|
 | 
						|
      @tree3.style_create('s1')
 | 
						|
      @tree3.style_elements('s1', ['e3', 'e1'])
 | 
						|
      @tree3.style_layout('s1', 'e3', :union=>['e1'], :ipadx=>1, :ipady=>[0,1])
 | 
						|
 | 
						|
      @tree3.style_create('s2')
 | 
						|
      @tree3.style_elements('s2', ['e3', 'e1', 'e2'])
 | 
						|
      @tree3.style_layout('s2', 'e1', :padx=>[0,4])
 | 
						|
      @tree3.style_layout('s2', 'e3', :union=>['e1', 'e2'], 
 | 
						|
                          :ipadx=>1, :ipady=>[0,1])
 | 
						|
    end
 | 
						|
    # Clear the list
 | 
						|
    @tree3.item_delete(:all)
 | 
						|
 | 
						|
    # One item for each item-column
 | 
						|
    column = 0
 | 
						|
    @tree2.item_style_set(item).each{|sty|
 | 
						|
      item2 = @tree3.item_create
 | 
						|
      if $Version_1_1_OrLater
 | 
						|
        @tree3.item_collapse(item2)
 | 
						|
      else
 | 
						|
        @tree3.collapse(item2)
 | 
						|
      end
 | 
						|
      @tree3.item_style_set(item2, 0, 's1')
 | 
						|
      @tree3.item_element_configure(item2, 0, 'e1', 
 | 
						|
                                    :text=>"Column #{column}: Style #{sty}")
 | 
						|
 | 
						|
      button = false
 | 
						|
 | 
						|
      # One item for each element in this style
 | 
						|
      unless sty.to_s.empty?
 | 
						|
        @tree2.item_style_elements(item, column).each{|elem|
 | 
						|
          button = true
 | 
						|
          if $Version_1_1_OrLater
 | 
						|
            item3 = @tree3.item_create(:button=>true)
 | 
						|
          else
 | 
						|
            item3 = @tree3.item_create
 | 
						|
            @tree3.item_hasbutton(item3, true)
 | 
						|
          end
 | 
						|
          if $Version_1_1_OrLater
 | 
						|
            @tree3.item_collapse(item3)
 | 
						|
          else
 | 
						|
            @tree3.collapse(item3)
 | 
						|
          end
 | 
						|
          @tree3.item_style_set(item3, 0, 's1')
 | 
						|
          @tree3.item_element_configure(item3, 0, 'e1', 
 | 
						|
                                        :text=>"Element #{elem} (#{@tree2.element_type(elem)})")
 | 
						|
 | 
						|
          # One item for each configuration option in this element
 | 
						|
          @tree2.item_element_configinfo(item, column, elem) \
 | 
						|
          .each{|name, x, y, default, current|
 | 
						|
            item4 = @tree3.item_create
 | 
						|
            masterDefault = @tree2.element_cget(elem, name)
 | 
						|
            sameAsMaster = (masterDefault == current)
 | 
						|
            if !sameAsMaster && current == ''
 | 
						|
              sameAsMaster = true
 | 
						|
              current = masterDefault
 | 
						|
            end
 | 
						|
 | 
						|
            if sameAsMaster
 | 
						|
              @tree3.item_style_set(item4, 0, 's1')
 | 
						|
              @tree3.item_complex(item4, [
 | 
						|
                                    ['e1', 
 | 
						|
                                      {:text=>"#{name} #{current.inspect}"}]
 | 
						|
                                  ])
 | 
						|
            else
 | 
						|
              @tree3.item_style_set(item4, 0, 's2')
 | 
						|
              @tree3.item_complex(item4, [
 | 
						|
                                    ['e1', {:text=>name}], 
 | 
						|
                                    ['e2', {:text=>current.inspect}]
 | 
						|
                                  ])
 | 
						|
            end
 | 
						|
            @tree3.item_lastchild(item3, item4)
 | 
						|
          }
 | 
						|
          @tree3.item_lastchild(item2, item3)
 | 
						|
        }
 | 
						|
        if $Version_1_1_OrLater
 | 
						|
          @tree3.item_configure(item2, :button=>true) if button
 | 
						|
        else
 | 
						|
          @tree3.item_hasbutton(item2, true) if button
 | 
						|
        end
 | 
						|
      end
 | 
						|
      @tree3.item_lastchild(:root, item2)
 | 
						|
      column += 1
 | 
						|
    }
 | 
						|
 | 
						|
    @tree3.xview_moveto(0)
 | 
						|
    @tree3.yview_moveto(0)
 | 
						|
  end
 | 
						|
 | 
						|
  def demo_clear
 | 
						|
    # Clear the demo list
 | 
						|
    @tree2.item_delete(:all)
 | 
						|
 | 
						|
    # Clear all bindings on the demo list added by the previous demo.
 | 
						|
    # This is why DontDelete is used for the <Selection> binding.
 | 
						|
    @tree2.notify_bindinfo(@tree2).each{|ev|
 | 
						|
      @tree2.notify_bind_remove(@tree2, ev)
 | 
						|
    }
 | 
						|
 | 
						|
    # Clear all run-time states
 | 
						|
    @tree2.state_names.each{|st| @tree2.state_undefine(st) }
 | 
						|
 | 
						|
    # Clear the styles-in-item list
 | 
						|
    @tree3.item_delete(:all)
 | 
						|
 | 
						|
    # Delete columns in demo list
 | 
						|
    while (@tree2.numcolumns > 0)
 | 
						|
      @tree2.column_delete(0)
 | 
						|
    end
 | 
						|
 | 
						|
    # Delete all styles in demo list
 | 
						|
    @tree2.style_delete(*(@tree2.style_names))
 | 
						|
 | 
						|
    # Delete all elements in demo list
 | 
						|
    @tree2.element_delete(*(@tree2.element_names))
 | 
						|
 | 
						|
    if $Version_1_1_OrLater
 | 
						|
      @tree2.item_configure(:root, :button=>false)
 | 
						|
      @tree2.item_expand(:root)
 | 
						|
    else
 | 
						|
      @tree2.item_hasbutton(:root, false)
 | 
						|
      @tree2.expand(:root)
 | 
						|
    end
 | 
						|
 | 
						|
    # Restore some happy defaults to the demo list
 | 
						|
    # if $Version_1_1_OrLater
 | 
						|
    if @has_bgimg
 | 
						|
      @tree2.configure(:orient=>:vertical, :wrap=>'', 
 | 
						|
                       :xscrollincrement=>0, :yscrollincrement=>0, 
 | 
						|
                       :itemheight=>0, :showheader=>true, 
 | 
						|
                       :background=>'white', :scrollmargin=>0, 
 | 
						|
                       :xscrolldelay=>50, :yscrolldelay=>50, 
 | 
						|
                       :openbuttonimage=>'', :closedbuttonimage=>'', 
 | 
						|
                       :backgroundmode=>:row, :treecolumn=>0, :indent=>19, 
 | 
						|
                       :defaultstyle=>'', :backgroundimage=>'')
 | 
						|
    else
 | 
						|
      @tree2.configure(:orient=>:vertical, :wrap=>'', 
 | 
						|
                       :xscrollincrement=>0, :yscrollincrement=>0, 
 | 
						|
                       :itemheight=>0, :showheader=>true, 
 | 
						|
                       :background=>'white', :scrollmargin=>0, 
 | 
						|
                       :xscrolldelay=>50, :yscrolldelay=>50, 
 | 
						|
                       :openbuttonimage=>'', :closedbuttonimage=>'', 
 | 
						|
                       :backgroundmode=>:row, :treecolumn=>0, :indent=>19)
 | 
						|
    end
 | 
						|
 | 
						|
    # Restore default bindings to the demo list
 | 
						|
    @tree2.bindtags = [ @tree2, Tk::TreeCtrl, @tree2.winfo_toplevel, :all ]
 | 
						|
 | 
						|
    @tree2.winfo_children.each{|w| 
 | 
						|
      w.destroy unless @non_clear_list.include?(w)
 | 
						|
    }
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
TkTreeCtrl_demo.new($ScriptDir)
 | 
						|
 | 
						|
##############################################
 | 
						|
 | 
						|
def cursor_window(top = nil)
 | 
						|
  top.destroy if top.kind_of?(TkWindow) && top.winfo_exist?
 | 
						|
  top = TkToplevel.new(:title=>'Cursor Window')
 | 
						|
 | 
						|
  c = TkCanvas.new(top, :background=>'white', 
 | 
						|
                   :width=>50*10, :highlightthickness=>0, 
 | 
						|
                   :borderwidth=>0).pack(:expand=>true, :fill=>:both)
 | 
						|
  cursors = %w(
 | 
						|
	X_cursor
 | 
						|
	arrow
 | 
						|
	based_arrow_down
 | 
						|
	based_arrow_up
 | 
						|
	boat
 | 
						|
	bogosity
 | 
						|
	bottom_left_corner
 | 
						|
	bottom_right_corner
 | 
						|
	bottom_side
 | 
						|
	bottom_tee
 | 
						|
	box_spiral
 | 
						|
	center_ptr
 | 
						|
	circle
 | 
						|
	clock
 | 
						|
	coffee_mug
 | 
						|
	cross
 | 
						|
	cross_reverse
 | 
						|
	crosshair
 | 
						|
	diamond_cross
 | 
						|
	dot
 | 
						|
	dotbox
 | 
						|
	double_arrow
 | 
						|
	draft_large
 | 
						|
	draft_small
 | 
						|
	draped_box
 | 
						|
	exchange
 | 
						|
	fleur
 | 
						|
	gobbler
 | 
						|
	gumby
 | 
						|
	hand1
 | 
						|
	hand2
 | 
						|
	heart
 | 
						|
	icon
 | 
						|
	iron_cross
 | 
						|
	left_ptr
 | 
						|
	left_side
 | 
						|
	left_tee
 | 
						|
	leftbutton
 | 
						|
	ll_angle
 | 
						|
	lr_angle
 | 
						|
	man
 | 
						|
	middlebutton
 | 
						|
	mouse
 | 
						|
	pencil
 | 
						|
	pirate
 | 
						|
	plus
 | 
						|
	question_arrow
 | 
						|
	right_ptr
 | 
						|
	right_side
 | 
						|
	right_tee
 | 
						|
	rightbutton
 | 
						|
	rtl_logo
 | 
						|
	sailboat
 | 
						|
	sb_down_arrow
 | 
						|
	sb_h_double_arrow
 | 
						|
	sb_left_arrow
 | 
						|
	sb_right_arrow
 | 
						|
	sb_up_arrow
 | 
						|
	sb_v_double_arrow
 | 
						|
	shuttle
 | 
						|
	sizing
 | 
						|
	spider
 | 
						|
	spraycan
 | 
						|
	star
 | 
						|
	target
 | 
						|
	tcross
 | 
						|
	top_left_arrow
 | 
						|
	top_left_corner
 | 
						|
	top_right_corner
 | 
						|
	top_side
 | 
						|
	top_tee
 | 
						|
	trek
 | 
						|
	ul_angle
 | 
						|
	umbrella
 | 
						|
	ur_angle
 | 
						|
	watch
 | 
						|
	xterm
 | 
						|
    )
 | 
						|
 | 
						|
  orig_cursor = c.cursor
 | 
						|
  col = 0
 | 
						|
  row = 0
 | 
						|
 | 
						|
  cursors.each{|cur|
 | 
						|
    x = col * 50
 | 
						|
    y = row * 40
 | 
						|
 | 
						|
    begin
 | 
						|
      c.cursor = cur
 | 
						|
 | 
						|
      r = TkcRectangle.new(c, x, y, x+50, y+40, 
 | 
						|
                           :fill=>'gray90', :outline=>'black', :width=>2)
 | 
						|
      t = TkcText.new(c, x+50/2, y+4, :text=>cur, :anchor=>:n, :width=>42)
 | 
						|
 | 
						|
      col += 1
 | 
						|
      if col >= 10
 | 
						|
        col = 0
 | 
						|
        row += 1
 | 
						|
      end
 | 
						|
 | 
						|
      r.bind('Enter', proc{c.cursor = cur; r.fill = 'linen'})
 | 
						|
      r.bind('Leave', proc{c.cursor = ''; r.fill = 'gray90'})
 | 
						|
 | 
						|
      t.bind('Enter', proc{c.cursor = cur})
 | 
						|
      t.bind('Leave', proc{c.cursor = ''})
 | 
						|
    rescue
 | 
						|
      c.cursor = orig_cursor
 | 
						|
    end
 | 
						|
  }
 | 
						|
 | 
						|
  c.cursor = orig_cursor
 | 
						|
  c.height = (row + 1) * 40
 | 
						|
end
 | 
						|
 | 
						|
cursor_window()
 | 
						|
 | 
						|
##############################################
 | 
						|
 | 
						|
# A little screen magnifier for X11
 | 
						|
if Tk::PLATFORM['platform'] == 'unix' && Tk.windowingsystem != 'aqua'
 | 
						|
  def show_loupe(setting=nil)
 | 
						|
    loupe = (setting.kind_of?(Hash))? setting: {}
 | 
						|
    loupe[:zoom] = 3 unless loupe[:zoom]
 | 
						|
    loupe[:x] = 0 unless loupe[:x]
 | 
						|
    loupe[:y] = 0 unless loupe[:y]
 | 
						|
    loupe[:auto] = true unless loupe[:auto]
 | 
						|
    loupe[:delay] = 500 unless loupe[:delay]
 | 
						|
    loupe[:image] = 
 | 
						|
      TkPhotoImage.new(:width=>150, :height=>150) unless loupe[:image]
 | 
						|
 | 
						|
    top = TkToplevel.new(:geometry=>'-0+30', 
 | 
						|
                         :title=>'A little screen magnifier for X11')
 | 
						|
    TkLabel.new(top, :image=>loupe[:image]).pack
 | 
						|
 | 
						|
    TkTimer.new(proc{loupe[:delay]}, -1, proc{
 | 
						|
                  x, y = TkWinfo.pointerxy(Tk.root)
 | 
						|
                  if loupe[:auto] || loupe[:x] != x || loupe[:y] != y
 | 
						|
                    w = loupe[:image].width
 | 
						|
                    h = loupe[:image].height
 | 
						|
                    Tk::TreeCtrl.loupe(loupe[:image], x, y, w, h, loupe[:zoom])
 | 
						|
                    loupe[:x] = x
 | 
						|
                    loupe[:y] = y
 | 
						|
                  end
 | 
						|
                }).start
 | 
						|
  end
 | 
						|
 | 
						|
  show_loupe()
 | 
						|
end
 | 
						|
 | 
						|
##############################################
 | 
						|
 | 
						|
Tk.mainloop
 |