From fcbf63e62c627deae76c1b8cb8c0876c536ed811 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Mon, 16 Mar 2020 18:49:26 +0900 Subject: Fresh start --- .../ext/tk/sample/tkextlib/treectrl/bitmaps.rb | 76 ++ jni/ruby/ext/tk/sample/tkextlib/treectrl/demo.rb | 1305 ++++++++++++++++++++ .../ext/tk/sample/tkextlib/treectrl/explorer.rb | 430 +++++++ jni/ruby/ext/tk/sample/tkextlib/treectrl/help.rb | 404 ++++++ jni/ruby/ext/tk/sample/tkextlib/treectrl/imovie.rb | 130 ++ jni/ruby/ext/tk/sample/tkextlib/treectrl/layout.rb | 159 +++ .../ext/tk/sample/tkextlib/treectrl/mailwasher.rb | 269 ++++ .../tk/sample/tkextlib/treectrl/outlook-folders.rb | 124 ++ .../sample/tkextlib/treectrl/outlook-newgroup.rb | 448 +++++++ .../tk/sample/tkextlib/treectrl/pics/big-dll.gif | Bin 0 -> 437 bytes .../tk/sample/tkextlib/treectrl/pics/big-exe.gif | Bin 0 -> 368 bytes .../tk/sample/tkextlib/treectrl/pics/big-file.gif | Bin 0 -> 466 bytes .../sample/tkextlib/treectrl/pics/big-folder.gif | Bin 0 -> 459 bytes .../tk/sample/tkextlib/treectrl/pics/big-txt.gif | Bin 0 -> 392 bytes .../tk/sample/tkextlib/treectrl/pics/checked.gif | Bin 0 -> 78 bytes .../ext/tk/sample/tkextlib/treectrl/pics/file.gif | Bin 0 -> 279 bytes .../tkextlib/treectrl/pics/folder-closed.gif | Bin 0 -> 111 bytes .../sample/tkextlib/treectrl/pics/folder-open.gif | Bin 0 -> 120 bytes .../tkextlib/treectrl/pics/help-book-closed.gif | Bin 0 -> 115 bytes .../tkextlib/treectrl/pics/help-book-open.gif | Bin 0 -> 128 bytes .../tk/sample/tkextlib/treectrl/pics/help-page.gif | Bin 0 -> 132 bytes .../tk/sample/tkextlib/treectrl/pics/imovie-01.gif | Bin 0 -> 5406 bytes .../tk/sample/tkextlib/treectrl/pics/imovie-02.gif | Bin 0 -> 5912 bytes .../tk/sample/tkextlib/treectrl/pics/imovie-03.gif | Bin 0 -> 4696 bytes .../tk/sample/tkextlib/treectrl/pics/imovie-04.gif | Bin 0 -> 5783 bytes .../tk/sample/tkextlib/treectrl/pics/imovie-05.gif | Bin 0 -> 3238 bytes .../tk/sample/tkextlib/treectrl/pics/imovie-06.gif | Bin 0 -> 3509 bytes .../tk/sample/tkextlib/treectrl/pics/imovie-07.gif | Bin 0 -> 2091 bytes .../tkextlib/treectrl/pics/internet-check-off.gif | Bin 0 -> 70 bytes .../tkextlib/treectrl/pics/internet-check-on.gif | Bin 0 -> 76 bytes .../tkextlib/treectrl/pics/internet-print.gif | Bin 0 -> 124 bytes .../tkextlib/treectrl/pics/internet-radio-off.gif | Bin 0 -> 68 bytes .../tkextlib/treectrl/pics/internet-radio-on.gif | Bin 0 -> 71 bytes .../tkextlib/treectrl/pics/internet-search.gif | Bin 0 -> 114 bytes .../tkextlib/treectrl/pics/internet-security.gif | Bin 0 -> 108 bytes .../sample/tkextlib/treectrl/pics/mac-collapse.gif | Bin 0 -> 275 bytes .../sample/tkextlib/treectrl/pics/mac-expand.gif | Bin 0 -> 277 bytes .../tkextlib/treectrl/pics/outlook-arrow.gif | Bin 0 -> 73 bytes .../sample/tkextlib/treectrl/pics/outlook-clip.gif | Bin 0 -> 73 bytes .../tkextlib/treectrl/pics/outlook-deleted.gif | Bin 0 -> 138 bytes .../tkextlib/treectrl/pics/outlook-draft.gif | Bin 0 -> 134 bytes .../tkextlib/treectrl/pics/outlook-folder.gif | Bin 0 -> 133 bytes .../tkextlib/treectrl/pics/outlook-group.gif | Bin 0 -> 144 bytes .../tkextlib/treectrl/pics/outlook-inbox.gif | Bin 0 -> 133 bytes .../tkextlib/treectrl/pics/outlook-local.gif | Bin 0 -> 146 bytes .../sample/tkextlib/treectrl/pics/outlook-main.gif | Bin 0 -> 174 bytes .../tkextlib/treectrl/pics/outlook-outbox.gif | Bin 0 -> 136 bytes .../tkextlib/treectrl/pics/outlook-read-2.gif | Bin 0 -> 343 bytes .../sample/tkextlib/treectrl/pics/outlook-read.gif | Bin 0 -> 304 bytes .../sample/tkextlib/treectrl/pics/outlook-sent.gif | Bin 0 -> 132 bytes .../tkextlib/treectrl/pics/outlook-server.gif | Bin 0 -> 163 bytes .../tkextlib/treectrl/pics/outlook-unread.gif | Bin 0 -> 303 bytes .../tkextlib/treectrl/pics/outlook-watch.gif | Bin 0 -> 98 bytes .../ext/tk/sample/tkextlib/treectrl/pics/sky.gif | Bin 0 -> 6454 bytes .../tk/sample/tkextlib/treectrl/pics/small-dll.gif | Bin 0 -> 311 bytes .../tk/sample/tkextlib/treectrl/pics/small-exe.gif | Bin 0 -> 115 bytes .../sample/tkextlib/treectrl/pics/small-file.gif | Bin 0 -> 338 bytes .../sample/tkextlib/treectrl/pics/small-folder.gif | Bin 0 -> 307 bytes .../tk/sample/tkextlib/treectrl/pics/small-txt.gif | Bin 0 -> 302 bytes .../tk/sample/tkextlib/treectrl/pics/unchecked.gif | Bin 0 -> 72 bytes jni/ruby/ext/tk/sample/tkextlib/treectrl/random.rb | 508 ++++++++ .../ext/tk/sample/tkextlib/treectrl/readme.txt | 2 + .../ext/tk/sample/tkextlib/treectrl/www-options.rb | 303 +++++ 63 files changed, 4158 insertions(+) create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/bitmaps.rb create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/demo.rb create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/explorer.rb create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/help.rb create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/imovie.rb create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/layout.rb create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/mailwasher.rb create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/outlook-folders.rb create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/outlook-newgroup.rb create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/big-dll.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/big-exe.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/big-file.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/big-folder.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/big-txt.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/checked.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/file.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/folder-closed.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/folder-open.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/help-book-closed.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/help-book-open.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/help-page.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-01.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-02.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-03.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-04.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-05.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-06.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-07.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-check-off.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-check-on.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-print.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-radio-off.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-radio-on.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-search.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-security.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/mac-collapse.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/mac-expand.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-arrow.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-clip.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-deleted.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-draft.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-folder.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-group.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-inbox.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-local.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-main.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-outbox.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-read-2.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-read.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-sent.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-server.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-unread.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-watch.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/sky.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/small-dll.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/small-exe.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/small-file.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/small-folder.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/small-txt.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/unchecked.gif create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/random.rb create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/readme.txt create mode 100644 jni/ruby/ext/tk/sample/tkextlib/treectrl/www-options.rb (limited to 'jni/ruby/ext/tk/sample/tkextlib/treectrl') diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/bitmaps.rb b/jni/ruby/ext/tk/sample/tkextlib/treectrl/bitmaps.rb new file mode 100644 index 0000000..0d8b37b --- /dev/null +++ b/jni/ruby/ext/tk/sample/tkextlib/treectrl/bitmaps.rb @@ -0,0 +1,76 @@ +# +# Demo: Bitmaps +# +def demoBitmaps(t) + #if $Version_1_1_OrLater + if @has_bgimg + t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, + :selectmode=>:browse, :orient=>:horizontal, :wrap=>'5 items', + :showheader=>false, :backgroundimage=>@images['sky']) + else + t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, + :selectmode=>:browse, :orient=>:horizontal, :wrap=>'5 items', + :showheader=>false) + end + + if $HasColumnCreate + t.column_create(:itembackground=>['gray90', []]) + else + t.column_configure(0, :itembackground=>['gray90', []]) + end + + t.element_create('elemTxt', :text, + :fill=>[@SystemHighlightText, ['selected', 'focus']]) + t.element_create('elemSelTxt', :rect, :showfocus=>true, + :fill=>[@SystemHighlight, ['selected', 'focus']]) + t.element_create('elemSelBmp', :rect, :outlinewidth=>4, + :outline=>[@SystemHighlight, ['selected', 'focus']]) + t.element_create('elemBmp', :bitmap, + :foreground=>[@SystemHighlight, ['selected', 'focus']], + :background=>'linen', + :bitmap=>['question' ['selected']]) + + s = t.style_create('STYLE', :orient=>:vertical) + t.style_elements(s, ['elemSelBmp', 'elemBmp', 'elemSelTxt', 'elemTxt']) + t.style_layout(s, 'elemSelBmp', :union=>'elemBmp', :ipadx=>6, :ipady=>6) + t.style_layout(s, 'elemBmp', :pady=>[0, 6], :expand=>:we) + t.style_layout(s, 'elemSelTxt', :union=>'elemTxt', :ipadx=>2) + t.style_layout(s, 'elemTxt', :expand=>:we) + + # Set default item style + if $Version_1_1_OrLater + t.defaultstyle = [s] + end + + bitmap_names = %w(error gray75 gray50 gray25 gray12 + hourglass info questhead question warning) + + bitmap_names.each{|name| + i = t.item_create + unless $Version_1_1_OrLater + t.item_style_set(i, 0, s) + end + t.item_text(i, 0, name) + t.item_element_configure(i, 0, 'elemBmp', :bitmap=>name) + t.item_lastchild(:root, i) + } + + bitmap_names.each{|name| + i = t.item_create + t.item_style_set(i, 0, s) + t.item_text(i, 0, name) + if true + t.item_element_configure(i, 0, 'elemBmp', :bitmap=>name, + :foreground=>['brown', ''], + :background=>['', '']) + else + t.item_element_configure(i, 0, 'elemBmp', :bitmap=>name, + :foreground=>[ + @SystemHighlight, ['selected', 'focus'], + 'brown', [] + ], + :background=>['', []]) + end + t.item_lastchild(:root, i) + } +end diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/demo.rb b/jni/ruby/ext/tk/sample/tkextlib/treectrl/demo.rb new file mode 100644 index 0000000..564a005 --- /dev/null +++ b/jni/ruby/ext/tk/sample/tkextlib/treectrl/demo.rb @@ -0,0 +1,1305 @@ +#!/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) +if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!! + # ruby 1.9.x --> use Hash#key + # Because Hash#index show warning "Hash#index is deprecated; use Hash#key". +else + # 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 '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 '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 '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: + # called when the active item changes + # called before an item is closed + # called after an item is closed + # called before an item is opened + # called after an item is opened + # called when items are added to or removed from the selection + # called when horizontal scroll position changes + # 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 + + def master._pub_display_styles_in_item(item) + display_styles_in_item(item) + end + proc_disp_styles_in_item = proc{|item| + master._pub_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 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 diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/explorer.rb b/jni/ruby/ext/tk/sample/tkextlib/treectrl/explorer.rb new file mode 100644 index 0000000..1b8c2a8 --- /dev/null +++ b/jni/ruby/ext/tk/sample/tkextlib/treectrl/explorer.rb @@ -0,0 +1,430 @@ + +def demoExplorerAux(t, dir_proc, file_proc) + base_dir = File.dirname(File.dirname(@ScriptDir)) + + clicks = Tk::Clock.clicks + globDirs = Dir.glob(File.join(base_dir, '*')).find_all{|file| + FileTest.directory?(file) + } + clickGlobDirs = Tk::Clock.clicks - clicks + + clicks = Tk::Clock.clicks + list = globDirs.sort + clickSortDirs = Tk::Clock.clicks - clicks + + clicks = Tk::Clock.clicks + list.each{|file| dir_proc.call(file)} + clickAddDirs = Tk::Clock.clicks - clicks + + clicks = Tk::Clock.clicks + globFiles = Dir.glob(File.join(base_dir, '*')).find_all{|file| + FileTest.file?(file) + } + clickGlobFiles = Tk::Clock.clicks - clicks + + clicks = Tk::Clock.clicks + list = globFiles.sort + clickSortFiles = Tk::Clock.clicks - clicks + + clicks = Tk::Clock.clicks + list.each{|file| file_proc.call(file)} + clickAddFiles = Tk::Clock.clicks - clicks + + gd = '%.2g' % (clickGlobDirs / 1000000.0) + sd = '%.2g' % (clickSortDirs / 1000000.0) + ad = '%.2g' % (clickAddDirs / 1000000.0) + gf = '%.2g' % (clickGlobFiles / 1000000.0) + sf = '%.2g' % (clickSortFiles / 1000000.0) + af = '%.2g' % (clickAddFiles / 1000000.0) + + puts "dirs(#{globDirs.length}) glob/sort/add #{gd}/#{sd}/#{ad} files(#{globFiles.length}) glob/sort/add #{gf}/#{sf}/#{af}" + + @Priv[:DirCnt, t] = globDirs.length +end + +# +# Demo: explorer files +# +def demoExplorerDetails(t) + height = t.font.metrics(:linespace) + height = 18 if height < 18 + + t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, + :itemheight=>height, :selectmode=>:extended, + :xscrollincrement=>20, :scrollmargin=>16, + :xscrolldelay=>[500, 50], :yscrolldelay=>[500, 50]) + + init_pics('small-*') + + if $HasColumnCreate + t.column_create(:text=>'Name', :tag=>'name', + :width=>200, :arrow=>:up, :arrowpad=>6) + t.column_create(:text=>'Size', :tag=>'size', :justify=>:right, + :width=>60, :arrowside=>:left, :arrowgravity=>:right) + t.column_create(:text=>'Type', :tag=>'type', :width=>120) + t.column_create(:text=>'Modified', :tag=>'modified', :width=>130) + else + t.column_configure(0, :text=>'Name', :tag=>'name', + :width=>200, :arrow=>:up, :arrowpad=>6) + t.column_configure(1, :text=>'Size', :tag=>'size', :justify=>:right, + :width=>60, :arrowside=>:left, :arrowgravity=>:right) + t.column_configure(2, :text=>'Type', :tag=>'type', :width=>120) + t.column_configure(3, :text=>'Modified', :tag=>'modified', :width=>130) + end + + t.element_create('e1', :image, + :image=>[ + @sel_images['small-folder'], ['selected'], + @images['small-folder'], [] + ]) + t.element_create('e2', :text, :lines=>1, + :fill=>[@SystemHighlightText, ['selected', 'focus']]) + t.element_create('txtType', :text, :lines=>1) + t.element_create('txtSize', :text, :lines=>1, + :datatype=>:integer, :format=>'%dKB') + t.element_create('txtDate', :text, :lines=>1, + :datatype=>:time, :format=>'%d/%m/%y %I:%M %p') + t.element_create('e4', :rect, :showfocus=>true, + :fill=>[ + @SystemHighlight, ['selected', 'focus'], + 'gray', ['selected', '!focus'] + ]) + + # image + text + s = t.style_create('styName', :orient=>:horizontal) + t.style_elements(s, ['e4', 'e1', 'e2']) + t.style_layout(s, 'e1', :expand=>:ns) + t.style_layout(s, 'e2', :padx=>[2,0], :squeeze=>:x, :expand=>:ns) + t.style_layout(s, 'e4', :union=>['e2'], :iexpand=>:ns, :ipadx=>2) + + # column 1: text + s = t.style_create('stySize') + t.style_elements(s, ['txtSize']) + t.style_layout(s, 'txtSize', :padx=>6, :squeeze=>:x, :expand=>:ns) + + # column 2: text + s = t.style_create('styType') + t.style_elements(s, ['txtType']) + t.style_layout(s, 'txtType', :padx=>6, :squeeze=>:x, :expand=>:ns) + + # column 3: text + s = t.style_create('styDate') + t.style_elements(s, ['txtDate']) + t.style_layout(s, 'txtDate', :padx=>6, :squeeze=>:x, :expand=>:ns) + + @Priv[:edit, t] = ['e2'] + @Priv[:sensitive, t] = [ ['name', 'styName', 'e1', 'e2'] ] + @Priv[:dragimage, t] = [ ['name', 'styName', 'e1', 'e2'] ] + + t.notify_bind(t, 'Edit-accept', + proc{|w, i, tt| w.item_text(i, 0, tt)}, '%T %I %t') + + dir_proc = proc{|file| + item = t.item_create + t.item_style_set(item, 0, 'styName', 2, 'styType', 3, 'styDate') + t.item_complex(item, + [['e2', {:text=>File.basename(file)}]], + [], + [['txtType', {:text=>'Folder'}]], + [['txtDate', {:data=>File.mtime(file).tv_sec}]]) + t.item_lastchild(:root, item) + } + + file_proc = proc{|file| + item = t.item_create + t.item_style_set(item, 0, 'styName', 1, 'stySize', + 2, 'styType', 3, 'styDate') + + ext = File.extname(file) + case ext + when '.dll' + img = 'small-dll' + when '.exe' + img = 'small-exe' + when '.txt' + img = 'small-txt' + else + img = 'small-file' + end + + type = ext.upcase + type = type[1..-1] << ' ' unless type.empty? + type << 'File' + + t.item_complex(item, + [ + ['e1', {:image=>[@sel_images[img], ['selected'], + @images[img], []]}], + ['e2', {:text=>File.basename(file)}] + ], + [ ['txtSize', {:data=>File.size(file)/1024 + 1}] ], + [ ['txtType', {:text=>type}] ], + [ ['txtDate', {:data=>File.mtime(file).tv_sec}] ] + ) + t.item_lastchild(:root, item) + } + + demoExplorerAux(t, dir_proc, file_proc) + + @SortColumn = 0 + t.notify_bind(t, 'Header-invoke', + proc{|w, c| explorerHeaderInvoke(t, w, c)}, '%T %C') + + t.bindtags = [ t, 'TreeCtrlFileList', Tk::TreeCtrl, t.winfo_toplevel, :all ] +end + +def explorerHeaderInvoke(t, w, c) + if (c == @SortColumn) + if t.column_cget(@SortColumn, :arrow) == 'down' + order = :increasing + arrow = :up + else + order = :decreasing + arrow = :down + end + else + if t.column_cget(@SortColumn, :arrow) == 'down' + order = :decreasing + arrow = :down + else + order = :increasing + arrow = :up + end + t.column_configure(@SortColumn, :arrow=>:none) + @SortColumn = c + end + + t.column_configure(c, :arrow=>arrow) + dirCount = TkComm.number(@Priv[:DirCnt, t]) + lastDir = dirCount - 1 + case t.column_cget(c, :tag) + when 'name' + if dirCount > 0 + t.item_sort(:root, order, {:last=>"root child #{lastDir}"}, + {:column=>c, :dictionary=>true}) + end + if dirCount < t.numitems - 1 + t.item_sort(:root, order, {:first=>"root child #{dirCount}"}, + {:column=>c, :dictionary=>true}) + end + + when 'size' + if dirCount < t.numitems - 1 + t.item_sort(:root, order, {:first=>"root child #{dirCount}"}, + {:column=>c, :integer=>true}, + {:column=>'name', :dictionary=>true}) + end + + when 'type' + if dirCount < t.numitems - 1 + t.item_sort(:root, order, {:first=>"root child #{dirCount}"}, + {:column=>c, :dictionary=>true}, + {:column=>'name', :dictionary=>true}) + end + + when 'modified' + if dirCount > 0 + t.item_sort(:root, order, {:last=>"root child #{lastDir}"}, + {:column=>c, :integer=>true}, + {:column=>'name', :dictionary=>true}) + end + if dirCount < t.numitems - 1 + t.item_sort(:root, order, {:first=>"root child #{dirCount}"}, + {:column=>c, :integer=>true}, + {:column=>'name', :dictionary=>true}) + end + + end +end + +def demoExplorerLargeIcons(t) + # Item height is 32 for icon, 4 padding, 3 lines of text + itemHeight = 32 + 4 + t.font.metrics(:linespace) * 3 + + t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, + :selectmode=>:extended, :wrap=>:window, :orient=>:horizontal, + :itemheight=>itemHeight, :showheader=>false, :scrollmargin=>16, + :xscrolldelay=>[500, 50], :yscrolldelay=>[500, 50]) + + init_pics('big-*') + + if $HasColumnCreate + t.column_create(:width=>75) + else + t.column_configure(0, :width=>75) + end + + t.element_create('elemImg', :image, + :image=>[ + @sel_images['big-folder'], ['selected'], + @images['big-folder'], [] + ]) + t.element_create('elemTxt', :text, :justify=>:center, + :lines=>1, :width=>71, :wrap=>:word, + :fill=>[@SystemHighlightText, ['selected', 'focus']]) + t.element_create('elemSel', :rect, :showfocus=>true, + :fill=>[ + @SystemHighlight, ['selected', 'focus'], + 'gray', ['selected'] + ]) + + # image + text + s = t.style_create('STYLE', :orient=>:vertical) + t.style_elements(s, ['elemSel', 'elemImg', 'elemTxt']) + t.style_layout(s, 'elemImg', :expand=>:we) + t.style_layout(s, 'elemTxt', + :pady=>[4,0], :padx=>2, :squeeze=>:x, :expand=>:we) + t.style_layout(s, 'elemSel', :union=>['elemTxt']) + + @Priv[:edit, t] = ['elemTxt'] + @Priv[:sensitive, t] = [ [0, 'STYLE', 'elemImg', 'elemTxt'] ] + @Priv[:dragimage, t] = [ [0, 'STYLE', 'elemImg', 'elemTxt'] ] + + t.notify_bind(t, 'Edit-accept', + proc{|w, i, tt| w.item_text(i, 0, tt)}, '%T %I %t') + + dir_proc = proc{|file| + item = t.item_create + t.item_style_set(item, 0, 'STYLE') + t.item_text(item, 0, File.basename(file)) + t.item_lastchild(:root, item) + } + + file_proc = proc{|file| + item = t.item_create + t.item_style_set(item, 0, 'STYLE') + + ext = File.extname(file) + case ext + when '.dll' + img = 'big-dll' + when '.exe' + img = 'big-exe' + when '.txt' + img = 'big-txt' + else + img = 'big-file' + end + + type = ext.upcase + type = type[1..-1] << ' ' unless type.empty? + type << 'File' + + t.item_complex(item, + [ + ['elemImg', {:image=>[@sel_images[img], ['selected'], + @images[img], []]}], + ['elemTxt', {:text=>File.basename(file)}] + ]) + t.item_lastchild(:root, item) + } + + demoExplorerAux(t, dir_proc, file_proc) + + t.activate(t.index('root firstchild')) + + t.notify_bind(t, 'ActiveItem', + proc{|w, a, c| + w.item_element_configure(a, 0, 'elemTxt', :lines=>'') + w.item_element_configure(c, 0, 'elemTxt', :lines=>3) + }, '%T %p %c') + + t.bindtags = [ t, 'TreeCtrlFileList', Tk::TreeCtrl, t.winfo_toplevel, :all ] +end + +# Tree is horizontal, wrapping occurs at right edge of window, each item +# is as wide as the smallest needed multiple of 110 pixels +def demoExplorerSmallIcons(t) + demoExplorerList(t) + t.configure(:orient=>:horizontal, :xscrollincrement=>0) + t.column_configure(0, :width=>'', :stepwidth=>110, :widthhack=>false) +end + +# Tree is vertical, wrapping occurs at bottom of window, each range has the +# same width (as wide as the longest item), xscrollincrement is by range +def demoExplorerList(t) + height = t.font.metrics(:linespace) + 2 + height = 18 if height < 18 + + t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, + :itemheight=>height, :selectmode=>:extended, :wrap=>:window, + :showheader=>false, :scrollmargin=>16, + :xscrolldelay=>[500, 50], :yscrolldelay=>[500, 50]) + + init_pics('small-*') + + if $HasColumnCreate + t.column_create(:widthhack=>true) + else + t.column_configure(0, :widthhack=>true) + end + + t.element_create('elemImg', :image, + :image=>[ + @sel_images['small-folder'], ['selected'], + @images['small-folder'], [] + ]) + t.element_create('elemTxt', :text, :lines=>1, + :fill=>[@SystemHighlightText, ['selected', 'focus']]) + t.element_create('elemSel', :rect, :showfocus=>true, + :fill=>[ + @SystemHighlight, ['selected', 'focus'], + 'gray', ['selected', '!focus'] + ]) + + # image + text + s = t.style_create('STYLE') + t.style_elements(s, ['elemSel', 'elemImg', 'elemTxt']) + t.style_layout(s, 'elemImg', :expand=>:ns) + t.style_layout(s, 'elemTxt', :squeeze=>:x, :expand=>:ns, :padx=>[2,0]) + t.style_layout(s, 'elemSel', :union=>['elemTxt'], :iexpand=>:ns, :ipadx=>2) + + @Priv[:edit, t] = ['elemTxt'] + @Priv[:sensitive, t] = [ [0, 'STYLE', 'elemImg', 'elemTxt'] ] + @Priv[:dragimage, t] = [ [0, 'STYLE', 'elemImg', 'elemTxt'] ] + + t.notify_bind(t, 'Edit-accept', + proc{|w, i, tt| w.item_text(i, 0, tt)}, '%T %I %t') + + dir_proc = proc{|file| + item = t.item_create + t.item_style_set(item, 0, 'STYLE') + t.item_text(item, 0, File.basename(file)) + t.item_lastchild(:root, item) + } + + file_proc = proc{|file| + item = t.item_create + t.item_style_set(item, 0, 'STYLE') + + ext = File.extname(file) + case ext + when '.dll' + img = 'small-dll' + when '.exe' + img = 'small-exe' + when '.txt' + img = 'small-txt' + else + img = 'small-file' + end + + type = ext.upcase + type = type[1..-1] << ' ' unless type.empty? + type << 'File' + + t.item_complex(item, + [ + ['elemImg', {:image=>[@sel_images[img], ['selected'], + @images[img], []]}], + ['elemTxt', {:text=>File.basename(file)}] + ]) + t.item_lastchild(:root, item) + } + + demoExplorerAux(t, dir_proc, file_proc) + + t.activate(t.item_firstchild(:root)) + + t.bindtags = [ t, 'TreeCtrlFileList', Tk::TreeCtrl, t.winfo_toplevel, :all ] +end diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/help.rb b/jni/ruby/ext/tk/sample/tkextlib/treectrl/help.rb new file mode 100644 index 0000000..31ec9eb --- /dev/null +++ b/jni/ruby/ext/tk/sample/tkextlib/treectrl/help.rb @@ -0,0 +1,404 @@ +# +# Demo: Help contents +# +def demoHelpContents(t) + height = t.font.metrics(:linespace) + height = 18 if height < 18 + t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, + :itemheight=>height, :selectmode=>:browse) + + init_pics('help-*') + + if $Version_1_1_OrLater + t.column_create(:text=>'Help Contents') + else # TreeCtrl 1.0 + t.column_configure(0, :text=>'Help Contents') + end + + # Define a new item state + t.state_define('mouseover') + + t.element_create('e1', :image, :image=>@images['help-page']) + t.element_create('e2', :image, :image=>[ + @images['help-book-open'], ['open'], + @images['help-book-closed'], [], + ]) + t.element_create('e3', :text, + :font=>[t.font.dup.underline(true), ['mouseover']], + :fill=>[ + @SystemHighlightText, ['selected', 'focus'], + 'blue', ['mouseover'] + ]) + t.element_create('e4', :rect, :showfocus=>true, + :fill=>[@SystemHighlight, ['selected', 'focus']]) + + # book + s = t.style_create('s1') + t.style_elements(s, ['e4', 'e1', 'e3']) + t.style_layout(s, 'e1', :padx=>[0,4], :expand=>:ns) + t.style_layout(s, 'e3', :expand=>:ns) + t.style_layout(s, 'e4', :union=>['e3'], :iexpand=>:ns, :ipadx=>2) + + # page + s = t.style_create('s2') + t.style_elements(s, ['e4', 'e2', 'e3']) + t.style_layout(s, 'e2', :padx=>[0,4], :expand=>:ns) + t.style_layout(s, 'e3', :expand=>:ns) + t.style_layout(s, 'e4', :union=>['e3'], :iexpand=>:ns, :ipadx=>2) + + parentList = [:root, '', '', '', '', '', ''] + parent = :root + [ + [0, 's1', "Welcome to Help"], + [0, 's2', "Introducing Windows 98"], + [1, 's2', "How to Use Help"], + [2, 's1', "Find a topic"], + [2, 's1', "Get more out of help"], + [1, 's2', "Register Your Software"], + [2, 's1', "Registering Windows 98 online"], + [1, 's2', "What's New in Windows 98"], + [2, 's1', "Innovative, easy-to-use features"], + [2, 's1', "Improved reliability"], + [2, 's1', "A faster operating system"], + [2, 's1', "True Web integration"], + [2, 's1', "More entertaining and fun"], + [1, 's2', "If You're New to Windows 98"], + [2, 's2', "Tips for Macintosh Users"], + [3, 's1', "Why does the mouse have two buttons?"] + ].each{|depth, style, text| + item = t.item_create + t.item_style_set(item, 0, style) + t.item_element_configure(item, 0, 'e3', :text=>text) + if $Version_1_1_OrLater + t.item_collapse(item) + else # TreeCtrl 1.0 + t.collapse(item) + end + t.item_lastchild(parentList[depth], item) + depth += 1 + parentList[depth] = item + } + + treeCtrlHelp = TkBindTag.new + + treeCtrlHelp.bind('Double-ButtonPress-1', + proc{|w, x, y| + if w.identify(x, y)[0] == 'header' + Tk::TreeCtrl::BindCallback.doubleButton1(w, x, y) + else + helpButton1(w, x, y) + end + Tk.callback_break + }, '%W %x %y') + + treeCtrlHelp.bind('ButtonPress-1', + proc{|w, x, y| + helpButton1(w, x, y) + Tk.callback_break + }, '%W %x %y') + + treeCtrlHelp.bind('Button1-Motion', + proc{|w, x, y| + helpMotion1(w, x, y) + Tk.callback_break + }, '%W %x %y') + + treeCtrlHelp.bind('Button1-Leave', + proc{|w, x, y| + helpLeave1(w, x, y) + Tk.callback_break + }, '%W %x %y') + + treeCtrlHelp.bind('ButtonRelease-1', + proc{|w, x, y| + helpRelease1(w, x, y) + Tk.callback_break + }, '%W %x %y') + + treeCtrlHelp.bind('Motion', proc{|w, x, y| helpMotion(w, x, y) }, '%W %x %y') + + treeCtrlHelp.bind('Leave', proc{|w, x, y| helpMotion(w, x, y) }, '%W %x %y') + + treeCtrlHelp.bind('KeyPress-Return', + proc{|w, x, y| + if w.selection_get.length == 1 + if $Version_1_1_OrLater + w.item_toggle(w.selection_get[0]) + else # TreeCtrl 1.0 + w.toggle(w.selection_get[0]) + end + end + Tk.callback_break + }, '%W %x %y') + + @Priv[:help, :prev] = '' + + t.bindtags = [ t, treeCtrlHelp, Tk::TreeCtrl, t.winfo_toplevel, :all ] +end + +# This is an alternate implementation that does not define a new item state +# to change the appearance of the item under the cursor. +def demoHelpContents2(t) + height = t.font.metrics(:linespace) + height = 18 if height < 18 + t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, + :itemheight=>height, :selectmode=>:browse) + + init_pics('help-*') + + if $Version_1_1_OrLater + t.column_create(:text=>'Help Contents') + else # TreeCtrl 1.0 + t.column_configure(0, :text=>'Help Contents') + end + + t.element_create('e1', :image, :image=>@images['help-page']) + t.element_create('e2', :image, :image=>[ + @images['help-book-open'], ['open'], + @images['help-book-closed'], [], + ]) + t.element_create('e3', :text, + :fill=>[ + @SystemHighlightText, ['selected', 'focus'], + 'blue', [] + ]) + t.element_create('e4', :rect, :showfocus=>true, + :fill=>[@SystemHighligh, ['selected', 'focus']]) + t.element_create('e5', :text, :font=>t.font.dup.underline(true), + :fill=>[ + @SystemHighlightText, ['selected', 'focus'], + 'blue', [] + ]) + + # book + s = t.style_create('s1') + t.style_elements(s, ['e4', 'e1', 'e3']) + t.style_layout(s, 'e1', :padx=>[0,4], :expand=>:ns) + t.style_layout(s, 'e3', :expand=>:ns) + t.style_layout(s, 'e4', :union=>['e3'], :iexpand=>:ns, :ipadx=>2) + + # page + s = t.style_create('s2') + t.style_elements(s, ['e4', 'e2', 'e3']) + t.style_layout(s, 'e2', :padx=>[0,4], :expand=>:ns) + t.style_layout(s, 'e3', :expand=>:ns) + t.style_layout(s, 'e4', :union=>['e3'], :iexpand=>:ns, :ipadx=>2) + + # book (focus) + s = t.style_create('s1.f') + t.style_elements(s, ['e4', 'e1', 'e5']) + t.style_layout(s, 'e1', :padx=>[0,4], :expand=>:ns) + t.style_layout(s, 'e5', :expand=>:ns) + t.style_layout(s, 'e4', :union=>['e5'], :iexpand=>:ns, :ipadx=>2) + + # page (focus) + s = t.style_create('s2') + t.style_elements(s, ['e4', 'e2', 'e5']) + t.style_layout(s, 'e2', :padx=>[0,4], :expand=>:ns) + t.style_layout(s, 'e5', :expand=>:ns) + t.style_layout(s, 'e4', :union=>['e5'], :iexpand=>:ns, :ipadx=>2) + + parentList = [:root, '', '', '', '', '', ''] + parent = :root + [ + [0, 's1', "Welcome to Help"], + [0, 's2', "Introducing Windows 98"], + [1, 's2', "How to Use Help"], + [2, 's1' "Find a topic"], + [2, 's1', "Get more out of help"], + [1, 's2', "Register Your Software"], + [2, 's1', "Registering Windows 98 online"], + [1, 's2', "What's New in Windows 98"], + [2, 's1', "Innovative, easy-to-use features"], + [2, 's1', "Improved reliability"], + [2, 's1', "A faster operating system"], + [2, 's1', "True Web integration"], + [2, 's1', "More entertaining and fun"], + [1, 's2', "If You're New to Windows 98"], + [2, 's2', "Tips for Macintosh Users"], + [3, 's1', "Why does the mouse have two buttons?"] + ].each{|depth, style, text| + item = t.item_create + t.item_style_set(item, 0, style) + t.item_element_configure(item, 0, 'e3', :text=>text) + if $Version_1_1_OrLater + t.item_collapse(item) + else # TreeCtrl 1.0 + t.collapse(item) + end + t.item_lastchild(parentList[depth], item) + depth += 1 + parentList[depth] = item + } + + treeCtrlHelp = TkBindTag.new + + treeCtrlHelp.bind('Double-ButtonPress-1', + proc{|w, x, y| + if w.identify(x, y)[0] == 'header' + Tk::TreeCtrl::BindCallback.doubleButton1(w, x, y) + else + helpButton1(w, x, y) + end + Tk.callback_break + }, '%W %x %y') + + treeCtrlHelp.bind('ButtonPress-1', + proc{|w, x, y| + helpButton1(w, x, y) + Tk.callback_break + }, '%W %x %y') + + treeCtrlHelp.bind('Button1-Motion', + proc{|w, x, y| + helpMotion1(w, x, y) + Tk.callback_break + }, '%W %x %y') + + treeCtrlHelp.bind('Button1-Leave', + proc{|w, x, y| + helpLeave1(w, x, y) + Tk.callback_break + }, '%W %x %y') + + treeCtrlHelp.bind('ButtonRelease-1', + proc{|w, x, y| + helpRelease1(w, x, y) + Tk.callback_break + }, '%W %x %y') + + treeCtrlHelp.bind('Motion', proc{|w, x, y| helpMotion(w, x, y) }, '%W %x %y') + + treeCtrlHelp.bind('Leave', proc{|w, x, y| helpMotion(w, x, y) }, '%W %x %y') + + treeCtrlHelp.bind('KeyPress-Return', + proc{|w, x, y| + if w.selection_get.length == 1 + w.item_toggle(w.selection_get[0]) + end + Tk.callback_break + }, '%W %x %y') + + @Priv[:help, :prev] = '' + + t.bindtags = [ t, treeCtrlHelp, Tk::TreeCtrl, t.winfo_toplevel, :all ] +end + +def helpButton1(w, x, y) + w.set_focus + id = w.identify(x, y) + @Priv['buttonMode'] = '' + if id[0] == 'header' + Tk::TreeCtrl::BindCallback.buttonPress1(w, x, y) + elsif id[0] == 'item' + item = id[1] + # didn't click an element + return if id.length != 6 + if w.selection_includes(item) + w.toggle(item) + return + end + if w.selection_get.length > 0 + item2 = w.selection_get[0] + if $Version_1_1_OrLater + w.item_collapse(item2) + else # TreeCtrl 1.0 + w.collapse(item2) + end + w.item_ancestors(item2).each{|i| + if $Version_1_1_OrLater + w.item_collapse(i) if w.compare(item, '!=', i) + else # TreeCtrl 1.0 + w.collapse(i) if w.compare(item, '!=', i) + end + } + end + w.activate(item) + if $Version_1_1_OrLater + w.item_ancestors(item).each{|i| + w.item_expand(i) + } + w.item_toggle(item) + else # TreeCtrl 1.0 + w.expand(*(w.item_ancestors(item))) + w.toggle(item) + end + w.selection_modify(item, :all) + end +end + +def helpMotion1(w, x, y) + case @Priv['buttonMode'] + when 'resize', 'header' + Tk::TreeCtrl::BindCallback.motion1(w, x, y) + end +end + +def helpLeave1(w, x, y) + # This is called when I do ButtonPress-1 on Unix for some reason, + # and buttonMode is undefined. + return unless @Priv.exist?('buttonMode') + case @Priv['buttonMode'] + when 'header' + w.column_configure(@Priv['column'], :sunken=>false) + end +end + +def helpRelease1(w, x, y) + case @Priv['buttonMode'] + when 'resize', 'header' + Tk::TreeCtrl::BindCallback.release1(w, x, y) + end + @Priv['buttonMode'] = '' +end + +def helpMotion(w, x, y) + id = w.identify(x, y) + if id.empty? + elsif id[0] == 'header' + elsif id[0] == 'item' + item = id[1] + if id.length == 6 + if @Priv[:help, :prev] != TkComm._get_eval_string(item) + if @Priv[:help, :prev] != '' + w.item_state_set(@Priv[:help, :prev], '!mouseover') + end + w.item_state_set(item, 'mouseover') + @Priv[:help, :prev] = item + end + return + end + end + if @Priv[:help, :prev] != '' + w.item_state_set(@Priv[:help, :prev], '!mouseover') + @Priv[:help, :prev] = '' + end +end + +# Alternate implementation doesn't rely on mouseover state +def helpMotion2(w, x, y) + id = w.identify(x, y) + if id[0] == 'header' + elsif !id.empty? + item = id[1] + if id.kength == 6 + if @Priv[:help, :prev] != TkComm._get_eval_string(item) + if @Priv[:help, :prev] != '' + style = w.item_style_set(@Priv[:help, :prev], 0) + style.sub!(/\.f$/, '') + w.item_style_map(@Priv[:help, :prev], 0, style, ['e5', 'e3']) + end + style = w.item_style_set(item, 0) + w.item_style_map(item, 0, style + '.f', ['e3', 'e5']) + @Priv[:help, :prev] = item + end + return + end + end + if @Priv[:help, :prev] != '' + style = w.item_style_set(@Priv[:help, :prev], 0) + style.sub!(/\.f$/, '') + w.item_style_map(@Priv[:help, :prev], 0, style, ['e5', 'e3']) + @Priv[:help, :prev] = '' + end +end diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/imovie.rb b/jni/ruby/ext/tk/sample/tkextlib/treectrl/imovie.rb new file mode 100644 index 0000000..72134eb --- /dev/null +++ b/jni/ruby/ext/tk/sample/tkextlib/treectrl/imovie.rb @@ -0,0 +1,130 @@ +# +# Demo: iMovie +# +def demoIMovie(t) + t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, + :selectmode=>:browse, :orient=>:horizontal, :wrap=>:window, + :showheader=>false, :background=>'#dcdcdc') + + if $HasColumnCreate + t.column_create + end + + init_pics('imovie-*') + + case @thisPlatform + when 'macintosh', 'macosx' + font1 = TkFont.new(['Geneva', 9]) + font2 = TkFont.new(['Geneva', 10]) + when 'unix' + font1 = TkFont.new(['Helvetica', -12]) + font2 = TkFont.new(['Helvetica', -14]) + else + font1 = TkFont.new(['Helvetica', 8]) + font2 = TkFont.new(['Helvetica', 10]) + end + + t.element_create('elemTime', :text, :font=>font1) + t.element_create('elemName', :text, :font=>font2, :lines=>1, :width=>80) + t.element_create('elemRect', :rect, :outline=>'#827878', :outlinewidth=>1, + :fill=>['#ffdc5a', ['selected'], 'white', []]) + t.element_create('elemImg', :image) + t.element_create('elemShadow', :rect, :outline=>'gray', :outlinewidth=>1, + :open=>:wn) + + s = t.style_create('STYLE', :orient=>:vertical) + t.style_elements(s, [ + 'elemShadow', 'elemRect', 'elemTime', + 'elemImg', 'elemName' + ]) + t.style_layout(s, 'elemShadow', :detach=>true, + :padx=>[1,2], :pady=>[1,2], :iexpand=>:es) + t.style_layout(s, 'elemTime', :padx=>[2,0]) + t.style_layout(s, 'elemImg', :pady=>[0,1]) + t.style_layout(s, 'elemName', :expand=>:we, :ipady=>[0,2], :padx=>[0,3], + :squeeze=>:x) + t.style_layout(s, 'elemRect', :union=>['elemTime', 'elemImg', 'elemName'], + :ipadx=>6, :padx=>[0,3], :pady=>[0,3]) + + # Set default item style + if $Version_1_1_OrLater + t.defaultstyle([s]) + end + + (0..4).each{|i| + [ + ['15:20', 'Clip 1', @images['imovie-01']], + ['19:18', 'Clip 2', @images['imovie-02']], + ['07:20', 'Clip 3', @images['imovie-03']], + ['07:20', 'Clip 4', @images['imovie-04']], + ['07:20', 'Clip 5', @images['imovie-05']], + ['07:20', 'Clip 6', @images['imovie-06']], + ['07:20', 'Clip 7', @images['imovie-07']] + ].each{|time, name, image| + item = t.item_create + unless $Version_1_1_OrLater + t.item_style_set(item, 0, s) + end + t.item_element_configure(item, 0, 'elemTime', :text=>time) + t.item_element_configure(item, 0, 'elemName', :text=>name) + t.item_element_configure(item, 0, 'elemImg', :image=>image) + t.item_lastchild(:root, item) + } + } + + t.notify_bind(t, 'Edit-accept', proc{|w, i, c, e, tt| + w.item_element_configure(i, c, e, :text=>tt) + }, '%T %I %C %E %t') + + iMovie = TkBindTag.new + iMovie.bind('ButtonPress-1', proc{|w, x, y| + iMovieButton1(w, x, y) + }, '%W %x %y') + + t.bindtags = [t, iMovie, Tk::TreeCtrl, t.winfo_toplevel, TkBindTag::ALL] +end + +def iMovieButton1(w, x, y) + w.set_focus + id = w.identify(x,y) + + if id.empty? + # Click outside any item + + elsif id[0] == 'header' + # Click in header + Tk::TreeCtrl::BindCallback.buttonPress1(w, x, y) + + elsif id[0] == 'item' + # Click in item + Tk::TreeCtrl::BindCallback.buttonPress1(w, x, y) + Tk.update + where, item, arg1, arg2, arg3, arg4 = id + case arg1 + when 'column' + i = id[1] + if id.length == 6 + e = id[-1] + if e == 'elemName' + exists = TkWinfo.exist?(w.path + '.entry') + Tk::TreeCtrl::BindCallback.entryOpen(w, i, 0, e) + ent = TkComm.window(w.path + '.entry') + unless exists + ent.configure(:borderwidth=>0, :justify=>:center, + :background=>'#ffdc5a') + x1, y1, x2, y2 = w.item_bbox(i, 0, e) + ent.place(:y=>y1 - 1) + end + ent.selection_clear + x1, y1, x2, y2 = w.item_bbox(i) + ent.place(:x=>x1 + 1, :width=>x2 - x1 - 5) + puts "@#{x - (x1 + 1)}" + # ent.icursor = ent.index("@#{x - (x1 + 1)}") + ent.icursor = ent.index(TkComm._at(x - (x1 + 1))) + end + end + end + end + + Tk.callback_break +end diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/layout.rb b/jni/ruby/ext/tk/sample/tkextlib/treectrl/layout.rb new file mode 100644 index 0000000..488abe2 --- /dev/null +++ b/jni/ruby/ext/tk/sample/tkextlib/treectrl/layout.rb @@ -0,0 +1,159 @@ +# +# Demo: Layout +# +def demoLayout(t) + t.configure(:showroot=>false, :showrootbutton=>true, :showbuttons=>true, + :showlines=>true, :itemheight=>0, :selectmode=>:browse) + + if $HasColumnCreate + t.column_create(:text=>'Layout') + else + t.column_configure(0, :text=>'Layout') + end + + t.element_create('e1', :rect, :width=>30, :height=>30, :fill=>'gray20') + t.element_create('e2', :rect, :width=>30, :height=>30, :fill=>'gray40', + :outline=>'blue', :outlinewidth=>3) + t.element_create('e3', :rect, :fill=>'gray60') + t.element_create('e4', :rect, :showfocus=>true, + :fill=>[ + @SystemHighlight, ['selected', 'focus'], 'gray80', [] + ]) + t.element_create('e5', :rect, :fill=>'{sky blue}', :width=>20, :height=>20) + t.element_create('e6', :rect, :fill=>'{sea green}', :width=>30, :height=>16) + t.element_create('e7', :rect, :fill=>'{sky blue}', :width=>30, :height=>16) + t.element_create('e8', :rect, :fill=>'gray70', :height=>1) + + s = t.style_create('s1') + t.style_elements(s, ['e4', 'e3', 'e1', 'e2', 'e5', 'e6', 'e7']) + t.style_layout(s, 'e1', :padx=>[28, 4], :pady=>4) + t.style_layout(s, 'e2', :expand=>:es, :padx=>[0, 38]) + t.style_layout(s, 'e3', :union=>['e1', 'e2'], :ipadx=>4, :ipady=>4, :pady=>2) + t.style_layout(s, 'e4', :detach=>true, :iexpand=>:es) + t.style_layout(s, 'e5', :detach=>true, :padx=>[2,0], :pady=>2, :iexpand=>:s) + t.style_layout(s, 'e6', :detach=>true, :expand=>:ws, + :padx=>[0,2], :pady=>[2,0]) + t.style_layout(s, 'e7', :detach=>true, :expand=>:wn, + :padx=>[0,2], :pady=>[0,2]) + + if $Version_1_1_OrLater + i = t.item_create(:button=>true) + else + i = t.item_create + t.item_hasbutton(i, true) + end + t.item_style_set(i, 0, s) + t.item_lastchild(:root, i) + parent = i + + i = t.item_create() + unless $Version_1_1_OrLater + t.item_hasbutton(i, false) + end + t.item_style_set(i, 0, s) + t.item_lastchild(parent, i) + + ### + + s = t.style_create('s2') + t.style_elements(s, ['e4', 'e3', 'e1']) + t.style_layout(s, 'e1', :padx=>8, :pady=>8, :iexpand=>:e) + t.style_layout(s, 'e3', :union=>['e1'], :ipadx=>[20,4], :ipady=>[4,12]) + t.style_layout(s, 'e4', :detach=>true, :iexpand=>:es) + + if $Version_1_1_OrLater + i = t.item_create(:button=>true) + else + i = t.item_create + t.item_hasbutton(i, true) + end + t.item_style_set(i, 0, s) + t.item_lastchild(:root, i) + + i2 = t.item_create() + unless $Version_1_1_OrLater + t.item_hasbutton(i2, false) + end + t.item_style_set(i2, 0, s) + t.item_lastchild(i, i2) + + ### + + s = t.style_create('s3') + t.style_elements(s, ['e4', 'e3', 'e1', 'e5', 'e6']) + t.style_layout(s, 'e4', :union=>['e1', 'e6'], :ipadx=>8, :ipady=>[8,0]) + t.style_layout(s, 'e3', :union=>['e1', 'e5'], :ipadx=>4, :ipady=>4) + t.style_layout(s, 'e5', :ipady=>[0,20]) + + if $Version_1_1_OrLater + i = t.item_create(:button=>true) + else + i = t.item_create + t.item_hasbutton(i, true) + end + t.item_style_set(i, 0, s) + t.item_lastchild(:root, i) + + i2 = t.item_create() + unless $Version_1_1_OrLater + t.item_hasbutton(i2, false) + end + t.item_style_set(i2, 0, s) + t.item_lastchild(i, i2) + + ### + + t.element_create('eb', :border, :background=>@SystemButtonFace, + :relief=>[:sunken, ['selected'], :raised, []], + :thickness=>2, :filled=>true) + t.element_create('et', :text) + + text = "Here is a text element surrounded by a border element.\nResize the column to watch me wrap." + + s = t.style_create('e4') + t.style_elements(s, ['eb', 'et']) + t.style_layout(s, 'eb', :union=>['et'], :ipadx=>2, :ipady=>2) + t.style_layout(s, 'et', :squeeze=>:x) + + if $Version_1_1_OrLater + i = t.item_create(:button=>true) + else + i = t.item_create + t.item_hasbutton(i, true) + end + t.item_style_set(i, 0, s) + t.item_text(i, 0, text) + t.item_lastchild(:root, i) + parent = i + + i = t.item_create() + unless $Version_1_1_OrLater + t.item_hasbutton(i, false) + end + t.item_style_set(i, 0, s) + t.item_text(i, 0, text) + t.item_lastchild(parent, i) + + ### + + styleNum = 5 + [ + [:horizontal, [:s, :ns, :n]], + [:vertical, [:e, :we, :w]] + ].each{|orient, expandList| + expandList.each{|expand| + s = t.style_create("s#{styleNum}", :orient=>orient) + t.style_elements(s, ['e4', 'e8', 'e2', 'e5', 'e6']) + t.style_layout(s, 'e4', :detach=>true, :iexpand=>:es) + t.style_layout(s, 'e8', :detach=>true, :expand=>:n, :iexpand=>:e) + t.style_layout(s, 'e2', :expand=>expand) + t.style_layout(s, 'e5', :expand=>expand) + t.style_layout(s, 'e6', :expand=>expand) + styleNum += 1 + + i = t.item_create() + t.item_style_set(i, 0, s) + t.item_lastchild(:root, i) + } + } +end diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/mailwasher.rb b/jni/ruby/ext/tk/sample/tkextlib/treectrl/mailwasher.rb new file mode 100644 index 0000000..1b51bb9 --- /dev/null +++ b/jni/ruby/ext/tk/sample/tkextlib/treectrl/mailwasher.rb @@ -0,0 +1,269 @@ +# +# Demo: MailWasher +# +def demoMailWasher(t) + init_pics('*checked') + + height = t.font.metrics(:linespace) + 2 + height = 18 if height < 18 + + t.configure(:showroot=>false, :showrootbutton=>false, :showbuttons=>false, + :showlines=>false, :itemheight=>height, :selectmode=>:browse, + :xscrollincrement=>1) + + pad = 4 + + if $Version_1_1_OrLater + t.column_create(:text=>'Delete', :textpadx=>pad, :tag=>'delete') + t.column_create(:text=>'Bounce', :textpadx=>pad, :tag=>'bounce') + t.column_create(:text=>'Status', :width=>80, :textpadx=>pad, + :tag=>'status') + t.column_create(:text=>'Size', :width=>40, :textpadx=>pad, + :justify=>:right, :tag=>'size') + t.column_create(:text=>'From', :width=>140, :textpadx=>pad, :tag=>'from') + t.column_create(:text=>'Subject', :width=>240, :textpadx=>pad, + :tag=>'subject') + t.column_create(:text=>'Received', :textpadx=>pad, :arrow=>:up, + :arrowpad=>[4,0], :tag=>'received') + t.column_create(:text=>'Attachments', :textpadx=>pad, :tag=>'attachments') + + t.state_define('CHECK') + + t.element_create('imgCheck', :image, :image=>[ + @images['checked'], ['CHECK'], @images['unchecked'], [] + ]) + + else # TreeCtrl 1.0 + t.column_configure(0, :text=>'Delete', :textpadx=>pad, :tag=>'delete') + t.column_configure(1, :text=>'Bounce', :textpadx=>pad, :tag=>'bounce') + t.column_configure(2, :text=>'Status', :width=>80, :textpadx=>pad, + :tag=>'status') + t.column_configure(3, :text=>'Size', :width=>40, :textpadx=>pad, + :justify=>:right, :tag=>'size') + t.column_configure(4, :text=>'From', :width=>140, :textpadx=>pad, + :tag=>'from') + t.column_configure(5, :text=>'Subject', :width=>240, :textpadx=>pad, + :tag=>'subject') + t.column_configure(6, :text=>'Received', :textpadx=>pad, :arrow=>:up, + :arrowpad=>[4,0], :tag=>'received') + t.column_configure(7, :text=>'Attachments', :textpadx=>pad, + :tag=>'attachments') + + t.element_create('imgOff', :image, :image=>@images['unchecked']) + t.element_create('imgOn', :image, :image=>@images['checked']) + end + + t.element_create('border', :rect, :open=>:nw, :outline=>'gray', + :outlinewidth=>1, :fill=>[@SystemHighlight, ['selected']]) + t.element_create('txtAny', :text, :lines=>1, + :fill=>[@SystemHighlightText, ['selected']]) + t.element_create('txtNone', :text, :text=>'none', :lines=>1, + :fill=>[@SystemHighlightText, ['selected']]) + t.element_create('txtYes', :text, :text=>'yes', :lines=>1, + :fill=>[@SystemHighlightText, ['selected']]) + t.element_create('txtNormal', :text, :text=>'Normal', :lines=>1, + :fill=>[@SystemHighlightText, ['selected'], '#006800', []]) + t.element_create('txtPossSpam', :text, :text=>'Possible Spam', :lines=>1, + :fill=>[@SystemHighlightText, ['selected'], '#787800', []]) + t.element_create('txtProbSpam', :text, :text=>'Probably Spam', :lines=>1, + :fill=>[@SystemHighlightText, ['selected'], '#FF9000', []]) + t.element_create('txtBlacklist', :text, :text=>'Blacklisted', :lines=>1, + :fill=>[@SystemHighlightText, ['selected'], '#FF5800', []]) + + if $Version_1_1_OrLater + s = t.style_create('styCheck') + t.style_elements(s, ['border', 'imgCheck']) + t.style_layout(s, 'border', :detach=>true, :iexpand=>:es) + t.style_layout(s, 'imgCheck', :expand=>:news) + else + ['Off', 'On'].each{|name| + s = t.style_create('sty' << name) + i = 'img' << name + t.style_elements(s, ['border', i]) + t.style_layout(s, 'border', :detach=>true, :iexpand=>:es) + t.style_layout(s, i, :expand=>:news) + } + end + + pad = 4 + + %w(Any None Yes Normal PossSpam ProbSpam Blacklist).each{|name| + s = t.style_create('sty' << name) + e = 'txt' << name + t.style_elements(s, ['border', e]) + t.style_layout(s, 'border', :detach=>true, :iexpand=>:es) + t.style_layout(s, e, :padx=>pad, :squeeze=>:x, :expand=>:ns) + } + + [ + ['baldy@spammer.com', "Your hair is thinning"], + ['flat@spammer.com', "Your breasts are too small"], + ['tiny@spammer.com', "Your penis is too small"], + ['dumbass@spammer.com', "You are not very smart"], + ['bankrobber@spammer.com', "You need more money"], + ['loser@spammer.com', "You need better friends"], + ['gossip@spammer.com', "Find out what your coworkers think about you"], + ['whoami@spammer.com', "Find out what you think about yourself"], + ['downsized@spammer.com', "You need a better job"], + ['poorhouse@spammer.com', "Your mortgage is a joke"], + ['spam4ever@spammer.com', "You need more spam"] + ].each{|frm, subj| + item = t.item_create + status = ['styNormal','styPossSpam','styProbSpam','styBlacklist'][rand(4)] + attachments = ['styNone','styYes'][rand(2)] + + if $Version_1_1_OrLater + delete = [false, true][rand(2)] + bounce = [false, true][rand(2)] + t.item_style_set(item, + 0, 'styCheck', 1, 'styCheck', 2, status, 3, 'styAny', + 4, 'styAny', 5, 'styAny', 6, 'styAny', 7, attachments) + t.item_state_forcolumn(item, 'delete', 'CHECK') if delete + t.item_state_forcolumn(item, 'bounce', 'CHECK') if bounce + + else # TreeCtrl 1.0 + delete = ['styOn', 'styOff'][rand(2)] + bounce = ['styOn', 'styOff'][rand(2)] + t.item_style_set(item, + 0, delete, 1, bounce, 2, status, 3, 'styAny', + 4, 'styAny', 5, 'styAny', 6, 'styAny', 7, attachments) + end + + bytes = 512 + rand(1024 * 12) + size = "#{bytes / 1024 + 1}KB" + seconds = Tk::Clock.seconds - rand(100000) + received = Tk::Clock.format(seconds, '%d/%m/%y %I:%M %p') + t.item_text(item, 3, size, 4, frm, 5, subj, 6, received) + t.item_lastchild(:root, item) + } + + sortColumn = 6 + t.notify_bind(t, 'Header-invoke', + proc{|c, w| + if c == sortColumn + if w.column_cget(sortColumn, :arrow) == 'down' + order = :increasing + arrow = :up + else + order = :decreasing + arrow = :down + end + else + if w.column_cget(sortColumn, :arrow) == 'down' + order = :decreasing + arrow = :down + else + order = :increasing + arrow = :up + end + w.column_configure(sortColumn, :arrow=>:none) + sortColumn = c + end + w.column_configure(c, :arrow=>arrow) + case w.column_cget(c, :tag) + when 'bounce', 'delete' + w.item_sort(:root, order, + { + :column=>c, + :command=>proc{|item1, item2| + compareOnOff(w, c, item1, item2) + } + }, + { :column=>'subject', :dictionary=>true }) + when 'status' + w.item_sort(:root, order, + { :column=>c, :dictionary=>true }) + when 'from' + w.item_sort(:root, order, + { :column=>c, :dictionary=>true }, + { :column=>'subject', :dictionary=>true }) + when 'subject' + w.item_sort(:root, order, + { :column=>c, :dictionary=>true }) + when 'size' + w.item_sort(:root, order, + { :column=>c, :dictionary=>true }, + { :column=>'subject', :dictionary=>true }) + when 'received' + w.item_sort(:root, order, + { :column=>c, :dictionary=>true }, + { :column=>'subject', :dictionary=>true }) + when 'attachments' + w.item_sort(:root, order, + { :column=>c, :dictionary=>true }, + { :column=>'subject', :dictionary=>true }) + end + }, '%C %T') + + mailWasher = TkBindTag.new + + if $Version_1_1_OrLater + mailWasher.bind('ButtonPress-1', + proc{|w, x, y| + id = w.identify(x, y) + if id.empty? + elsif id[0] == 'header' + else + what, item, where, arg1, arg2, arg3 = id + if where == 'column' + tag = w.column_cget(arg1, :tag) + if tag == 'delete' || tag == 'bounce' + w.item_state_forcolumn(item, arg1, '~CHECK') + end + end + end + }, '%W %x %y') + else # TreeCtrl 1.0 + mailWasher.bind('ButtonPress-1', + proc{|w, x, y| + id = w.identify(x, y) + if id.empty? + elsif id[0] == 'header' + else + what, item, where, arg1, arg2, arg3 = id + if where == 'column' + tag = w.column_cget(arg1, :tag) + if tag == 'delete' || tag == 'bounce' + style = w.item_style_set(item, arg1) + if style == 'styOn' + style = 'styOff' + else + style = 'styOn' + end + w.item_style_set(item, arg1, style) + @display_styles_in_item.call(item) + end + end + end + }, '%W %x %y') + end + + t.bindtags = [t, mailWasher, Tk::TreeCtrl, t.winfo_toplevel, TkBindTag::ALL] +end + +if $Version_1_1_OrLater + def compareOnOff(w, c, item1, item2) + s1 = w.item_state_forcolumn(item1, c) + s2 = w.item_state_forcolumn(item2, c) + if (s1 == s2) + 0 + elsif (s1 == 'CHECK') + -1 + else + 1 + end + end + +else # TreeCtrl 1.0 + def compareOnOff(w, c, item1, item2) + s1 = w.item_style_set(item1, c) + s2 = w.item_style_set(item2, c) + if (s1 == s2) + 0 + elsif (s1 == 'styOff') + -1 + else + 1 + end + end +end diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/outlook-folders.rb b/jni/ruby/ext/tk/sample/tkextlib/treectrl/outlook-folders.rb new file mode 100644 index 0000000..d966807 --- /dev/null +++ b/jni/ruby/ext/tk/sample/tkextlib/treectrl/outlook-folders.rb @@ -0,0 +1,124 @@ +# +# Demo: Outlook Express folder list +# +def demoOutlookFolders(t) + init_pics('outlook-*') + + height = t.font.metrics(:linespace) + 2 + height = 18 if height < 18 + + t.configure(:itemheight=>height, :selectmode=>:browse, :showlines=>true, + :showroot=>true, :showrootbutton=>false, :showbuttons=>true) + + if $HasColumnCreate + t.column_create(:text=>'Folders') + else + t.column_configure(0, :text=>'Folders') + end + + t.element_create('e1', :image) + t.element_create('e2', :text, :lines=>1, + :fill=>[@SystemHighlightText, ['selected', 'focus']]) + t.element_create('e3', :text, :lines=>1, :font=>t.font.dup.weight(:bold), + :fill=>[@SystemHighlightText, ['selected', 'focus']]) + t.element_create('e4', :text, :fill=>'blue') + t.element_create('e5', :image, :image=>@images['outlook-folder']) + t.element_create('e6', :rect, :showfocus=>true, + :fill=>[ + @SystemHighlight, ['selected', 'focus'], + 'gray', ['selected', '!focus'] + ]) + + # image + text + s = t.style_create('s1') + t.style_elements(s, ['e6', 'e1', 'e2']) + t.style_layout(s, 'e1', :expand=>:ns) + t.style_layout(s, 'e2', :padx=>[4,0], :expand=>:ns, :squeeze=>:x) + t.style_layout(s, 'e6', :union=>['e2'], :iexpand=>:ns, :ipadx=>2) + + # image + text + text + s = t.style_create('s2') + t.style_elements(s, ['e6', 'e1', 'e3', 'e4']) + t.style_layout(s, 'e1', :expand=>:ns) + t.style_layout(s, 'e3', :padx=>4, :expand=>:ns, :squeeze=>:x) + t.style_layout(s, 'e4', :expand=>:ns) + t.style_layout(s, 'e6', :union=>['e3'], :iexpand=>:ns, :ipadx=>2) + + # folder + text + s = t.style_create('s3') + t.style_elements(s, ['e6', 'e5', 'e2']) + t.style_layout(s, 'e5', :expand=>:ns) + t.style_layout(s, 'e2', :padx=>[4,0], :expand=>:ns, :squeeze=>:x) + t.style_layout(s, 'e6', :union=>['e2'], :iexpand=>:ns, :ipadx=>2) + + # folder + text + text + s = t.style_create('s4') + t.style_elements(s, ['e6', 'e5', 'e3', 'e4']) + t.style_layout(s, 'e5', :expand=>:ns) + t.style_layout(s, 'e3', :padx=>4, :expand=>:ns, :squeeze=>:x) + t.style_layout(s, 'e4', :expand=>:ns) + t.style_layout(s, 'e6', :union=>['e3'], :iexpand=>:ns, :ipadx=>2) + + t.item_style_set(:root, 0, 's1') + t.item_complex(:root, + [ + ['e1', {:image=>@images['outlook-main']}], + ['e2', {:text=>'Outlook Express'}] + ]) + + parentList = [:root, '', '', '', '', '', ''] + parent = :root + [ + [0, :local, "Local Folders", true, 0], + [1, :inbox, 'Inbox', false, 5], + [1, :outbox, 'Outbox', false, 0], + [1, :sent, "Sent Items", false, 0], + [1, :deleted, "Deleted Items", false, 50], + [1, :draft, 'Drafts', false, 0], + [1, :folder, "Messages to Dad", false, 0], + [1, :folder, "Messages to Sis", false, 0], + [1, :folder, "Messages to Me", false, 0], + [2, :folder, "2001", false, 0], + [2, :folder, "2000", false, 0], + [2, :folder, "1999", false, 0], + [0, :server, "news.gmane.org", true, 0], + [1, :group, "gmane.comp.lang.lua.general", false, 498] + ].each{|depth, img, text, button, unread| + if $Version_1_1_OrLater + item = t.item_create(:button=>button) + else + item = t.item_create + t.item_hasbutton(item, button) + end + if img == :folder + if unread != 0 + t.item_style_set(item, 0, 's4') + t.item_complex(item, + [['e3', {:text=>text}], ['e4', {:text=>"(#{unread})"}]]) + else + t.item_style_set(item, 0, 's3') + t.item_complex(item, [['e2', {:text=>text}]]) + end + else + if unread != 0 + t.item_style_set(item, 0, 's2') + t.item_complex(item, + [ + ['e1', {:image=>@images["outlook-#{img}"]}], + ['e3', {:text=>text}], + ['e4', {:text=>"(#{unread})"}] + ]) + else + t.item_style_set(item, 0, 's1') + t.item_complex(item, + [ + ['e1', {:image=>@images["outlook-#{img}"]}], + ['e2', {:text=>text}] + ]) + end + end + t.item_lastchild(parentList[depth], item) + depth += 1 + parentList[depth] = item + } +end diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/outlook-newgroup.rb b/jni/ruby/ext/tk/sample/tkextlib/treectrl/outlook-newgroup.rb new file mode 100644 index 0000000..3495522 --- /dev/null +++ b/jni/ruby/ext/tk/sample/tkextlib/treectrl/outlook-newgroup.rb @@ -0,0 +1,448 @@ +# +# Demo: Outlook Express newsgroup messages +# +def demoOutlookNewsgroup(t) + init_pics('outlook-*') + + height = t.font.metrics(:linespace) + height = 18 if height < 18 + t.configure(:itemheight=>height, :selectmode=>:browse, :showlines=>false, + :showroot=>false, :showrootbutton=>false, :showbuttons=>true) + + if $Version_1_1_OrLater + t.column_create(:image=>@images['outlook-clip'], :tag=>'clip') + t.column_create(:image=>@images['outlook-arrow'], :tag=>'arrow') + t.column_create(:image=>@images['outlook-watch'], :tag=>'watch') + t.column_create(:text=>'Subject', :width=>250, :tag=>'subject') + t.column_create(:text=>'From', :width=>150, :tag=>'from') + t.column_create(:text=>'Sent', :width=>150, :tag=>'sent') + t.column_create(:text=>'Size', :width=>60, :justify=>:right, :tag=>'size') + else # TreeCtrl 1.0 + t.column_configure(0, :image=>@images['outlook-clip'], :tag=>'clip') + t.column_configure(1, :image=>@images['outlook-arrow'], :tag=>'arrow') + t.column_configure(2, :image=>@images['outlook-watch'], :tag=>'watch') + t.column_configure(3, :text=>'Subject', :width=>250, :tag=>'subject') + t.column_configure(4, :text=>'From', :width=>150, :tag=>'from') + t.column_configure(5, :text=>'Sent', :width=>150, :tag=>'sent') + t.column_configure(6, :text=>'Size', :width=>60, :justify=>:right, + :tag=>'size') + end + + # Would be nice if I could specify a column -tag too + t.treecolumn = 3 + + # State for a read message + t.state_define('read') + + # State for a message with unread descendants + t.state_define('unread') + + t.element_create('elemImg', :image, + :image=>[ + @sel_images['outlook-read-2'], + ['selected', 'read', 'unread', '!open'], + @images['outlook-read-2'], ['read', 'unread', '!open'], + @sel_images['outlook-read'], ['selected', 'read'], + @images['outlook-read'], ['read'], + @sel_images['outlook-unread'], ['selected'], + @images['outlook-unread'], [] + ]) + t.element_create('elemTxt', :text, :lines=>1, + :fill=>[@SystemHighlightText, ['selected', 'focus']], + :font=>[ + t.font.dup.weight(:bold), ['read', 'unread', '!open'], + t.font.dup.weight(:bold), ['!read'] + ]) + t.element_create('sel.e', :rect, :open=>:e, :showfocus=>true, + :fill=>[ + @SystemHighlight, ['selected', 'focus'], + 'gray', ['selected', '!focus'] + ]) + t.element_create('sel.w', :rect, :open=>:w, :showfocus=>true, + :fill=>[ + @SystemHighlight, ['selected', 'focus'], + 'gray', ['selected', '!focus'] + ]) + t.element_create('sel.we', :rect, :open=>:we, :showfocus=>true, + :fill=>[ + @SystemHighlight, ['selected', 'focus'], + 'gray', ['selected', '!focus'] + ]) + + # Image + text + s = t.style_create('s1') + t.style_elements(s, ['sel.e', 'elemImg', 'elemTxt']) + t.style_layout(s, 'elemImg', :expand=>:ns) + t.style_layout(s, 'elemTxt', :padx=>[2,6], :squeeze=>:x, :expand=>:ns) + t.style_layout(s, 'sel.e', :union=>['elemTxt'], + :iexpand=>:nes, :ipadx=>[2,0]) + + # Text + s = t.style_create('s2.we') + t.style_elements(s, ['sel.we', 'elemTxt']) + t.style_layout(s, 'elemTxt', :padx=>6, :squeeze=>:x, :expand=>:ns) + t.style_layout(s, 'sel.we', :detach=>true, :iexpand=>:es) + + # Text + s = t.style_create('s2.w') + t.style_elements(s, ['sel.w', 'elemTxt']) + t.style_layout(s, 'elemTxt', :padx=>6, :squeeze=>:x, :expand=>:ns) + t.style_layout(s, 'sel.w', :detach=>true, :iexpand=>:es) + + # Set default item style + if $Version_1_1_OrLater + t.defaultstyle = ['', '', '', 's1', 's2.we', 's2.we', 's2.w'] + end + + msgCnt = 100 + thread = 0 + + @Message = Hash.new{|k, v| k[v] = Hash.new} + @Message[:count][0] = 0 + + items = [t.index(:root)] + + (1...(msgCnt)).each{|i| + item_i = t.item_create + item_j = nil + j = nil + loop { + j = rand(i) + item_j = items[j] + break if j == 0 + next if t.depth(item_j) == 5 + next if @Message[:count][@Message[:thread][item_j]] == 15 + break + } + t.item_lastchild(item_j, item_i) + + @Message[:read][item_i] = (rand(2) == 0) + if j == 0 + thread += 1 + @Message[:thread][item_i] = thread + @Message[:seconds][item_i] = (Tk::Clock.seconds - rand(500000)) + @Message[:seconds2][item_i] = @Message[:seconds][item_i] + @Message[:count][thread] = 1 + else + @Message[:thread][item_i] = @Message[:thread][item_j] + @Message[:seconds][item_i] = (@Message[:seconds2][item_j] + rand(10000)) + @Message[:seconds2][item_i] = @Message[:seconds][item_i] + @Message[:seconds2][item_j] = @Message[:seconds][item_i] + @Message[:count][@Message[:thread][item_j]] += 1 + end + items << item_i + } + + (1...(msgCnt)).each{|i| + item_i = items[i] + subject = "This is thread number #{@Message[:thread][item_i]}" + from = 'somebody@somewhere.net' + sent = Tk::Clock.format(@Message[:seconds][item_i], "%d/%m/%y %I:%M %p") + size = "#{1 + rand(10)}KB" + + # This message has been read + t.item_state_set(item_i, 'read') if @Message[:read][item_i] + + # This message has unread descendants + t.item_state_set(item_i, 'unread') if anyUnreadDescendants(t, item_i) + + if t.item_numchildren(item_i) > 0 + if $Version_1_1_OrLater + t.item_configure(item_i, :button=>true) + else # TreeCtrl 1.0 + t.item_hasbutton(item_i, true) + end + + # Collapse some messages + if $Version_1_1_OrLater + t.item_collapse(item_i) if rand(2) == 0 + else # TreeCtrl 1.0 + t.collapse(item_i) if rand(2) == 0 + end + end + + unless $Version_1_1_OrLater + t.item_style_set(item_i, 3, 's1', 4, 's2.we', 5, 's2.we', 6, 's2.w') + end + t.item_text(item_i, 3, subject, 4, from, 5, sent, 6, size) + } + + # Do something when the selection changes + t.notify_bind(t, 'Selection', + proc{|w| + if w.selection_count == 1 + # One item is selected + if @Message[:afterId][:id] + Tk.after_cancel(@Message[:afterId][:id]) + end + @Message[:afterId][:item] = w.selection_get[0] + @Message[:afterId][:id] = Tk.after(500, proc{ + messageReadDelayed(w) + }) + end + }, '%T') +end + +def messageReadDelayed(t) + @Message[:afterId].delete(:id) + i = @Message[:afterId][:item] + return unless t.selection_includes(i) + + # This message is not read + unless @Message[:read][i] + # Read the message + t.item_state_set(i, 'read') + @Message[:read][i] = true + + # Check ancestors (except root) + t.item_ancestors(i)[0..-2].each{|i2| + # This ancestor has no more unread descendants + t.item_state_set(i2, '!unread') unless anyUnreadDescendants(t, i2) + } + end +end + +# Alternate implementation which does not rely on run-time states +def demoOutlookNewsgroup2(t) + init_pics('outlook-*') + + height = t.font.metrics(:linespace) + height = 18 if height < 18 + t.configure(:itemheight=>height, :selectmode=>:browse, :showlines=>false, + :showroot=>false, :showrootbutton=>false, :showbuttons=>true) + + if $Version_1_1_OrLater + t.column_create(:image=>@images['outlook-clip'], :tag=>'clip') + t.column_create(:image=>@images['outlook-arrow'], :tag=>'arrow') + t.column_create(:image=>@images['outlook-watch'], :tag=>'watch') + t.column_create(:text=>'Subject', :width=>250, :tag=>'subject') + t.column_create(:text=>'From', :width=>150, :tag=>'from') + t.column_create(:text=>'Sent', :width=>150, :tag=>'sent') + t.column_create(:text=>'Size', :width=>60, :justify=>:right, :tag=>'size') + else # TreeCtrl 1.0 + t.column_configure(0, :image=>@images['outlook-clip'], :tag=>'clip') + t.column_configure(1, :image=>@images['outlook-arrow'], :tag=>'arrow') + t.column_configure(2, :image=>@images['outlook-watch'], :tag=>'watch') + t.column_configure(3, :text=>'Subject', :width=>250, :tag=>'subject') + t.column_configure(4, :text=>'From', :width=>150, :tag=>'from') + t.column_configure(5, :text=>'Sent', :width=>150, :tag=>'sent') + t.column_configure(6, :text=>'Size', :width=>60, :justify=>:right, + :tag=>'size') + end + + t.treecolumn = 3 + + t.element_create('image.unread', :image, :image=>@images['outlook-unread']) + t.element_create('image.read', :image, :image=>@images['outlook-read']) + t.element_create('image.read2', :image, :image=>@images['outlook-read-2']) + t.element_create('text.read', :text, :lines=>1, + :fill=>[@SystemHighlightText, ['selected', 'focus']]) + t.element_create('text.unread', :text, :lines=>1, + :fill=>[@SystemHighlightText, ['selected', 'focus']], + :font=>t.font.dup.weight(:bold)) + t.element_create('sel.e', :rect, :open=>:e, :showfocus=>true, + :fill=>[ + @SystemHighlight, ['selected', 'focus'], + 'gray', ['selected', '!focus'] + ]) + t.element_create('sel.w', :rect, :open=>:w, :showfocus=>true, + :fill=>[ + @SystemHighlight, ['selected', 'focus'], + 'gray', ['selected', '!focus'] + ]) + t.element_create('sel.we', :rect, :open=>:we, :showfocus=>true, + :fill=>[ + @SystemHighlight, ['selected', 'focus'], + 'gray', ['selected', '!focus'] + ]) + + # Image + text + s = t.style_create('unread') + t.style_elements(s, ['sel.e', 'image.unread', 'text.unread']) + t.style_layout(s, 'image.unread', :expand=>:ns) + t.style_layout(s, 'text.unread', :padx=>[2,6], :squeeze=>:x, :expand=>:ns) + t.style_layout(s, 'sel.e', :union=>['text.unread'], + :iexpand=>:nes, :ipadx=>[2,0]) + + # Image + text + s = t.style_create('read') + t.style_elements(s, ['sel.e', 'image.read', 'text.read']) + t.style_layout(s, 'image.read', :expand=>:ns) + t.style_layout(s, 'text.read', :padx=>[2,6], :squeeze=>:x, :expand=>:ns) + t.style_layout(s, 'sel.e', :union=>['text.read'], + :iexpand=>:nes, :ipadx=>[2,0]) + + # Image + text + s = t.style_create('read2') + t.style_elements(s, ['sel.e', 'image.read2', 'text.unread']) + t.style_layout(s, 'image.read2', :expand=>:ns) + t.style_layout(s, 'text.unread', :padx=>[2,6], :squeeze=>:x, :expand=>:ns) + t.style_layout(s, 'sel.e', :union=>['text.unread'], + :iexpand=>:nes, :ipadx=>[2,0]) + + # Text + s = t.style_create('unread.we') + t.style_elements(s, ['sel.we', 'text.unread']) + t.style_layout(s, 'text.unread', :padx=>6, :squeeze=>:x, :expand=>:ns) + t.style_layout(s, 'sel.we', :detach=>true, :iexpand=>:es) + + # Text + s = t.style_create('read.we') + t.style_elements(s, ['sel.we', 'text.read']) + t.style_layout(s, 'text.read', :padx=>6, :squeeze=>:x, :expand=>:ns) + t.style_layout(s, 'sel.we', :detach=>true, :iexpand=>:es) + + # Text + s = t.style_create('unread.w') + t.style_elements(s, ['sel.w', 'text.unread']) + t.style_layout(s, 'text.unread', :padx=>6, :squeeze=>:x, :expand=>:ns) + t.style_layout(s, 'sel.w', :detach=>true, :iexpand=>:es) + + # Text + s = t.style_create('read.w') + t.style_elements(s, ['sel.w', 'text.read']) + t.style_layout(s, 'text.read', :padx=>6, :squeeze=>:x, :expand=>:ns) + t.style_layout(s, 'sel.w', :detach=>true, :iexpand=>:es) + + msgCnt = 100 + thread = 0 + + @Message = Hash.new{|k, v| k[v] = Hash.new} + @Message[:count][0] = 0 + + (1...(msgCnt)).each{|i| + t.item_create + j = nil + loop { + j = rand(i) + break if j == 0 + next if t.depth(j) == 5 + next if @Message[:count][@Message[:thread][j]] == 15 + break + } + t.item_lastchild(j, i) + + @Message[:read][i] = (rand(2) == 0) + if j == 0 + thread += 1 + @Message[:thread][i] = thread + @Message[:seconds][i] = (Tk::Clock.seconds - rand(500000)) + @Message[:seconds2][i] = @Message[:seconds][i] + @Message[:count][thread] = 1 + else + @Message[:thread][i] = @Message[:thread][j] + @Message[:seconds][i] = (@Message[:seconds2][j] + rand(10000)) + @Message[:seconds2][i] = @Message[:seconds][i] + @Message[:seconds2][j] = @Message[:seconds][i] + @Message[:count][@Message[:thread][j]] += 1 + end + } + + (1...(msgCnt)).each{|i| + subject = "This is thread number #{@Message[:thread][i]}" + from = 'somebody@somewhere.net' + sent = Tk::Clock.format(@Message[:seconds][i], "%d/%m/%y %I:%M %p") + size = "#{1 + rand(10)}KB" + if @Message[:read][i] + style = 'read' + style2 = 'read2' + else + style = 'unread' + style2 = 'unread2' + end + t.item_style_set(i, 3, style, 4, "#{style2}.we", 5, "#{style2}.we", + 6, "#{style2}.w") + t.item_text(i, 3, subject, 4, from, 5, sent, 6, size) + if t.item_numchildren(i) > 0 + t.item_configure(item_i, :button=>true) + end + } + + # Do something when the selection changes + t.notify_bind(t, 'Selection', + proc{|w| + if w.selection_count == 1 + i = t.selection_get[0] + unless @Message[:read][i] + if t.item_isopen(i) || !anyUnreadDescendants(t, i) + # unread -> read + t.item_style_map(i, 'subject', 'read', + ['text.unread', 'text.read']) + t.item_style_map(i, 'from', 'read.we', + ['text.unread', 'text.read']) + t.item_style_map(i, 'sent', 'read.we', + ['text.unread', 'text.read']) + t.item_style_map(i, 'size', 'read.w', + ['text.unread', 'text.read']) + else + # unread -> read2 + t.item_style_map(i, 'subject', 'read2', + ['text.unread', 'text.unread']) + end + + @Message[:read][i] = true + @display_styles_in_item.call(i) + end + end + }, '%T') + + t.notify_bind(t, 'Expand-after', + proc{|w, i| + if @Messge[:read][i] && anyUnreadDescendants(t, i) + # read2 -> read + t.item_style_map(i, 'subject', 'read', + ['text.unread', 'text.read']) + # unread -> read + t.item_style_map(i, 'from', 'read.we', + ['text.unread', 'text.read']) + t.item_style_map(i, 'sent', 'read.we', + ['text.unread', 'text.read']) + t.item_style_map(i, 'size', 'read.w', + ['text.unread', 'text.read']) + end + }, '%T %I') + + t.notify_bind(t, 'Collapse-after', + proc{|w, i| + if @Messge[:read][i] && anyUnreadDescendants(t, i) + # read -> read2 + t.item_style_map(i, 'subject', 'read2', + ['text.read', 'text.unread']) + # read -> unread + t.item_style_map(i, 'from', 'unread.we', + ['text.read', 'text.unread']) + t.item_style_map(i, 'sent', 'unread.we', + ['text.read', 'text.unread']) + t.item_style_map(i, 'size', 'unread.w', + ['text.read', 'text.unread']) + end + }, '%T %I') + + (1...(msgCnt)).each{|i| + if rand(2) == 0 + if t.item_numchildren(i) > 0 + if $Version_1_1_OrLater + t.item_collapse(i) + else # TreeCtrl 1.0 + t.collapse(i) + end + end + end + } +end + +def anyUnreadDescendants(t, i) + itemList = [] + item = t.item_firstchild(i) + itemList.push(item) if item != '' + + while item = itemList.pop + return true unless @Message[:read][item] + + item2 = t.item_nextsibling(item) + itemList.push(item2) if item2 != '' + item2 = t.item_firstchild(item) + itemList.push(item2) if item2 != '' + end + false +end diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/big-dll.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/big-dll.gif new file mode 100644 index 0000000..09170c0 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/big-dll.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/big-exe.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/big-exe.gif new file mode 100644 index 0000000..e19aac1 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/big-exe.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/big-file.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/big-file.gif new file mode 100644 index 0000000..6c75231 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/big-file.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/big-folder.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/big-folder.gif new file mode 100644 index 0000000..186c974 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/big-folder.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/big-txt.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/big-txt.gif new file mode 100644 index 0000000..a934925 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/big-txt.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/checked.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/checked.gif new file mode 100644 index 0000000..3b9b176 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/checked.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/file.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/file.gif new file mode 100644 index 0000000..a64c2a0 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/file.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/folder-closed.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/folder-closed.gif new file mode 100644 index 0000000..0a06437 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/folder-closed.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/folder-open.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/folder-open.gif new file mode 100644 index 0000000..3fac27f Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/folder-open.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/help-book-closed.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/help-book-closed.gif new file mode 100644 index 0000000..0a0497b Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/help-book-closed.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/help-book-open.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/help-book-open.gif new file mode 100644 index 0000000..40656c5 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/help-book-open.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/help-page.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/help-page.gif new file mode 100644 index 0000000..e1ce1d7 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/help-page.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-01.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-01.gif new file mode 100644 index 0000000..5fd9215 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-01.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-02.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-02.gif new file mode 100644 index 0000000..3d2d1c1 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-02.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-03.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-03.gif new file mode 100644 index 0000000..9fccf12 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-03.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-04.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-04.gif new file mode 100644 index 0000000..eff851c Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-04.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-05.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-05.gif new file mode 100644 index 0000000..ad00c82 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-05.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-06.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-06.gif new file mode 100644 index 0000000..238bf16 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-06.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-07.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-07.gif new file mode 100644 index 0000000..a9287e1 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/imovie-07.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-check-off.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-check-off.gif new file mode 100644 index 0000000..e64866a Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-check-off.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-check-on.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-check-on.gif new file mode 100644 index 0000000..cf652be Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-check-on.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-print.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-print.gif new file mode 100644 index 0000000..7ac25b1 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-print.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-radio-off.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-radio-off.gif new file mode 100644 index 0000000..90ef629 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-radio-off.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-radio-on.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-radio-on.gif new file mode 100644 index 0000000..9de742c Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-radio-on.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-search.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-search.gif new file mode 100644 index 0000000..1f9a047 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-search.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-security.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-security.gif new file mode 100644 index 0000000..86d3943 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/internet-security.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/mac-collapse.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/mac-collapse.gif new file mode 100644 index 0000000..81302c8 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/mac-collapse.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/mac-expand.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/mac-expand.gif new file mode 100644 index 0000000..0a2cd80 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/mac-expand.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-arrow.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-arrow.gif new file mode 100644 index 0000000..b1c2afd Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-arrow.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-clip.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-clip.gif new file mode 100644 index 0000000..8578132 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-clip.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-deleted.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-deleted.gif new file mode 100644 index 0000000..7cc8369 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-deleted.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-draft.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-draft.gif new file mode 100644 index 0000000..f195850 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-draft.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-folder.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-folder.gif new file mode 100644 index 0000000..b3f7335 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-folder.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-group.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-group.gif new file mode 100644 index 0000000..29ad9b4 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-group.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-inbox.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-inbox.gif new file mode 100644 index 0000000..f41d804 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-inbox.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-local.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-local.gif new file mode 100644 index 0000000..0c74970 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-local.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-main.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-main.gif new file mode 100644 index 0000000..92325fa Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-main.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-outbox.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-outbox.gif new file mode 100644 index 0000000..c7e8052 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-outbox.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-read-2.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-read-2.gif new file mode 100644 index 0000000..2f15a3a Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-read-2.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-read.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-read.gif new file mode 100644 index 0000000..a6f9562 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-read.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-sent.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-sent.gif new file mode 100644 index 0000000..963b56c Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-sent.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-server.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-server.gif new file mode 100644 index 0000000..c950845 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-server.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-unread.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-unread.gif new file mode 100644 index 0000000..3df4b99 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-unread.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-watch.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-watch.gif new file mode 100644 index 0000000..87ec861 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/outlook-watch.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/sky.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/sky.gif new file mode 100644 index 0000000..b7fbf14 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/sky.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/small-dll.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/small-dll.gif new file mode 100644 index 0000000..d8875ec Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/small-dll.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/small-exe.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/small-exe.gif new file mode 100644 index 0000000..69d30be Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/small-exe.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/small-file.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/small-file.gif new file mode 100644 index 0000000..f340662 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/small-file.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/small-folder.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/small-folder.gif new file mode 100644 index 0000000..ad1b24d Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/small-folder.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/small-txt.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/small-txt.gif new file mode 100644 index 0000000..cdc7cbf Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/small-txt.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/unchecked.gif b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/unchecked.gif new file mode 100644 index 0000000..833e482 Binary files /dev/null and b/jni/ruby/ext/tk/sample/tkextlib/treectrl/pics/unchecked.gif differ diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/random.rb b/jni/ruby/ext/tk/sample/tkextlib/treectrl/random.rb new file mode 100644 index 0000000..43aca63 --- /dev/null +++ b/jni/ruby/ext/tk/sample/tkextlib/treectrl/random.rb @@ -0,0 +1,508 @@ +# +def random_N + @RandomN[0] || 500 +end + +# +# Demo: random N items +# +def demoRandom(t) + init_pics('folder-*', 'small-*') + + height = t.font.metrics(:linespace) + height = 18 if height < 18 + t.configure(:itemheight=>height, :selectmode=>:extended, + :showroot=>true, :showrootbutton=>true, :showbuttons=>true, + :showlines=>true, :scrollmargin=>16, + :xscrolldelay=>[500, 50], :yscrolldelay=>[500, 50]) + + if $Version_1_1_OrLater + t.column_create(:expand=>true, :text=>'Item', + :itembackground=>['#e0e8f0', []], :tag=>'item') + t.column_create(:text=>'Parent', :justify=>:center, + :itembackground=>['gray90', []], :tag=>'parent') + t.column_create(:text=>'Depth', :justify=>:center, + :itembackground=>['linen', []], :tag=>'depth') + else # TreeCtrl 1.0 + t.column_configure(0, :expand=>true, :text=>'Item', + :itembackground=>['#e0e8f0', []], :tag=>'item') + t.column_configure(1, :text=>'Parent', :justify=>:center, + :itembackground=>['gray90', []], :tag=>'parent') + t.column_configure(2, :text=>'Depth', :justify=>:center, + :itembackground=>['linen', []], :tag=>'depth') + end + + t.element_create('e1', :image, :image=>[ + @images['folder-open'], ['open'], + @images['folder-closed'], [] + ]) + t.element_create('e2', :image, :image=>@images['small-file']) + t.element_create('e3', :text, + :fill=>[@SystemHighlightText, ['selected', 'focus']]) + t.element_create('e4', :text, :fill=>'blue') + t.element_create('e6', :text) + t.element_create('e5', :rect, :showfocus=>true, + :fill=>[ + @SystemHighlight, ['selected', 'focus'], + 'gray', ['selected', '!focus'] + ]) + + s = t.style_create('s1') + t.style_elements(s, ['e5', 'e1', 'e3', 'e4']) + t.style_layout(s, 'e1', :padx=>[0,4], :expand=>:ns) + t.style_layout(s, 'e3', :padx=>[0,4], :expand=>:ns) + t.style_layout(s, 'e4', :padx=>[0,6], :expand=>:ns) + t.style_layout(s, 'e5', :union=>['e3'], :iexpand=>:ns, :ipadx=>2) + + s = t.style_create('s2') + t.style_elements(s, ['e5', 'e2', 'e3']) + t.style_layout(s, 'e2', :padx=>[0,4], :expand=>:ns) + t.style_layout(s, 'e3', :padx=>[0,4], :expand=>:ns) + t.style_layout(s, 'e5', :union=>['e3'], :iexpand=>:ns, :ipadx=>2) + + s = t.style_create('s3') + t.style_elements(s, ['e6']) + t.style_layout(s, 'e6', :padx=>6, :expand=>:ns) + + @Priv[:sensitive, t] = [ + [:item, 's1', 'e5', 'e1', 'e3'], + [:item, 's2', 'e5', 'e2', 'e3'] + ] + @Priv[:dragimage, t] = [ + [:item, 's1', 'e1', 'e3'], + [:item, 's2', 'e2', 'e3'] + ] + + clicks = Tk::Clock.clicks + items = [ t.index(:root) ] + (1...(random_N())).each{|i| + item_i = t.item_create + item_j = nil + loop { + j = rand(i) + item_j = items[j] + break if t.depth(item_j) < 5 + } + if $Version_1_1_OrLater + t.item_collapse(item_i) if rand(2) == 0 + else # TreeCtrl 1.0 + t.collapse(item_i) if rand(2) == 0 + end + if rand(2) == 0 + t.item_lastchild(item_j, item_i) + else + t.item_firstchild(item_j, item_i) + end + items << item_i + } + puts "created #{random_N() - 1} items in #{Tk::Clock.clicks - clicks} clicks" + + clicks = Tk::Clock.clicks + (0...(random_N())).each{|i| + item_i = items[i] + numChildren = t.item_numchildren(item_i) + if numChildren > 0 + if $Version_1_1_OrLater + t.item_configure(item_i, :button=>true) + else # TreeCtrl 1.0 + t.item_hasbutton(item_i, true) + end + t.item_style_set(item_i, 0, 's1', 1, 's3', 2, 's3') + t.item_complex(item_i, + [ ['e3', {:text=>"Item #{i}"}], + ['e4', {:text=>"(#{numChildren})"}] ], + [ ['e6', {:text=>"#{t.item_parent(item_i)}"}] ], + [ ['e6', {:text=>"#{t.depth(item_i)}"}] ]) + else + t.item_style_set(item_i, 1, 's3', 2, 's3', 0, 's2') + t.item_complex(item_i, + [ ['e3', {:text=>"Item #{i}"}] ], + [ ['e6', {:text=>"#{t.item_parent(item_i)}"}] ], + [ ['e6', {:text=>"#{t.depth(item_i)}"}] ]) + end + } + puts "configured #{random_N()} items in #{Tk::Clock.clicks - clicks} clicks" + + treeCtrlRandom = TkBindTag.new + + treeCtrlRandom.bind('Double-ButtonPress-1', + proc{|w, x, y| + Tk::TreeCtrl::BindCallback.doubleButton1(w, x, y) + Tk.callback_break + }, '%W %x %y') + + treeCtrlRandom.bind('Control-ButtonPress-1', + proc{|w, x, y| + @Priv['selectMode'] = :toggle + randomButton1(w, x, y) + Tk.callback_break + }, '%W %x %y') + + treeCtrlRandom.bind('Shift-ButtonPress-1', + proc{|w, x, y| + @Priv['selectMode'] = :add + randomButton1(w, x, y) + Tk.callback_break + }, '%W %x %y') + + treeCtrlRandom.bind('ButtonPress-1', + proc{|w, x, y| + @Priv['selectMode'] = :set + randomButton1(w, x, y) + Tk.callback_break + }, '%W %x %y') + + treeCtrlRandom.bind('Button1-Motion', + proc{|w, x, y| + randomMotion1(w, x, y) + Tk.callback_break + }, '%W %x %y') + + treeCtrlRandom.bind('Button1-Leave', + proc{|w, x, y| + randomLeave1(w, x, y) + Tk.callback_break + }, '%W %x %y') + + treeCtrlRandom.bind('ButtonRelease-1', + proc{|w, x, y| + randomRelease1(w, x, y) + Tk.callback_break + }, '%W %x %y') + + t.bindtags = [ t, treeCtrlRandom, Tk::TreeCtrl, t.winfo_toplevel, :all ] +end + +def randomButton1(t, x, y) + t.set_focus + id = t.identify(x, y) + puts id.inspect + @Priv['buttonMode'] = '' + + # Click outside any item + if id.empty? + t.selection_clear + + # Click in header + elsif id[0] == 'header' + Tk::TreeCtrl::BindCallback.buttonPress1(t, x, y) + + # Click in item + else + where, item, arg1, arg2, arg3, arg4 = id + case arg1 + when 'button' + if $Version_1_1_OrLater + t.item_toggle(item) + else # TreeCtrl 1.0 + t.toggle(item) + end + + when 'line' + if $Version_1_1_OrLater + t.item_toggle(arg2) + else # TreeCtrl 1.0 + t.toggle(arg2) + end + + when 'column' + ok = false + # Clicked an element + if id.length == 6 + column = id[3] + e = id[5] + @Priv.list_element(:sensitive, t).each{|lst| + c, s, *eList = TkComm.simplelist(lst) + next if column != t.column_index(c) + next if t.item_style_set(item, c) != s + next if eList.find{|le| le == e} == nil + ok = true + break + } + end + unless ok + t.selection_clear + return + end + + @Priv[:drag, :motion] = 0 + @Priv[:drag, :x] = t.canvasx(x) + @Priv[:drag, :y] = t.canvasy(y) + @Priv[:drop] = '' + + if @Priv['selectMode'] == 'add' + Tk::TreeCtrl::BindCallback.beginExtend(t, item) + elsif @Priv['selectMode'] == 'toggle' + Tk::TreeCtrl::BindCallback.beginToggle(t, item) + elsif ! t.selection_includes(item) + Tk::TreeCtrl::BindCallback.beginSelect(t, item) + end + t.activate(item) + + if t.selection_includes(item) + @Priv['buttonMode'] = 'drag' + end + end + end +end + +def randomMotion1(t, x, y) + case @Priv['buttonMode'] + when 'resize', 'header' + Tk::TreeCtrl::BindCallback.motion1(t, x, y) + when 'drag' + randomAutoScanCheck(t, x, y) + randomMotion(t, x, y) + end +end + +def randomMotion(t, x, y) + case @Priv['buttonMode'] + when 'resize', 'header' + Tk::TreeCtrl::BindCallback.motion1(t, x, y) + + when 'drag' + # Detect initial mouse movement + unless @Priv.bool_element(:drag, :motion) + @Priv[:selection] = t.selection_get + @Priv[:drop] = '' + t.dragimage_clear + # For each selected item, add 2nd and 3rd elements of + # column "item" to the dragimage + @Priv.list_element(:selection).each{|i| + @Priv.list_element(:dragimage,t).each{|lst| + c, s, *eList = TkComm.simplelist(lst) + if t.item_style_set(i, c) == s + t.dragimage_add(i, c, *eList) + end + } + } + @Priv[:drag,:motion] = true + end + + # Find the item under the cursor + cursor = 'X_cursor' + drop = '' + id = t.identify(x, y) + ok = false + if !id.empty? && id[0] == 'item' && id.length == 6 + item = id[1] + column = id[3] + e = id[5] + @Priv.list_element(:sensitive,t).each{|lst| + c, s, *eList = TkComm.simplelist(lst) + next if column != t.column_index(c) + next if t.item_style_set(item, c) != s + next unless eList.find{|val| val.to_s == e.to_s} + ok = true + break + } + ok = true if @Priv.list_element(:sensitive,t).find{|val| TkComm.simplelist(val).index(e)} + end + + if ok + # If the item is not in the pre-drag selection + # (i.e. not being dragged) see if we can drop on it + unless @Priv.list_element(:selection).find{|val| val.to_s == item.to_s} + drop = item + # We can drop if dragged item isn't an ancestor + @Priv.list_element(:selection).each{|item2| + if t.item_isancestor(item2, item) + drop = '' + break + end + } + if drop != '' + x1, y1, x2, y2 = t.item_bbox(drop) + if y < y1 + 3 + cursor = 'top_side' + @Priv[:drop,:pos] = 'prevsibling' + elsif y >= y2 - 3 + cursor = 'bottom_side' + @Priv[:drop,:pos] = 'nextsibling' + else + cursor = '' + @Priv[:drop,:pos] = 'lastchild' + end + end + end + end + + t[:cursor] = cursor if t[:cursor] != cursor + + # Select the item under the cursor (if any) and deselect + # the previous drop-item (if any) + t.selection_modify(drop, @Priv[:drop]) + @Priv[:drop] = drop + + # Show the dragimage in its new position + x = t.canvasx(x) - @Priv.numeric_element(:drag,:x) + y = t.canvasx(y) - @Priv.numeric_element(:drag,:y) + t.dragimage_offset(x, y) + t.dragimage_configure(:visible=>true) + end +end + +def randomLeave1(t, x, y) + # This is called when I do ButtonPress-1 on Unix for some reason, + # and buttonMode is undefined. + return unless @Priv.exist?('buttonMode') + case @Priv['buttonMode'] + when 'header' + Tk::TreeCtrl::BindCallback.leave1(t, x, y) + end +end + +def randomRelease1(t, x, y) + case @Priv['buttonMode'] + when 'resize', 'header' + Tk::TreeCtrl::BindCallback.release1(t, x, y) + when 'drag' + Tk::TreeCtrl::BindCallback.autoScanCancel(t) + t.dragimage_configure(:visible=>false) + t.selection_modify('', @Priv[:drop]) + t[:cursor] = '' + if @Priv[:drop] != '' + randomDrop(t, @Priv[:drop], @Priv.list_element(:selection), + @Priv[:drop, :pos]) + end + end + @Priv['buttonMode'] = '' +end + +def randomDrop(t, target, src, pos) + parentList = [] + case pos + when 'lastchild' + parent = target + when 'prevsibling' + parent = t.item_parent(target) + when 'nextsibling' + parent = t.item_parent(target) + end + src.each{|item| + # Ignore any item whose ancestor is also selected + ignore = false + t.item_ancestors(item).each{|ancestor| + if src.find{|val| val.to_s == ancestor.to_s} + ignore = true + break + end + } + next if ignore + + # Update the old parent of this moved item later + unless parentList.find{|val| val.to_s == item.to_s} + parentList << t.item_parent(item) + end + + # Add to target + t.__send__("item_#{pos}", target, item) + + # Update text: parent + t.item_element_configure(item, 'parent', 'e6', :text=>parent) + + # Update text: depth + t.item_element_configure(item, 'depth', 'e6', :text=>t.depth(item)) + + # Recursively update text: depth + itemList = [] + item = t.item_firstchild(item) + itemList << item if item != '' + + while item = itemList.pop + t.item_element_configure(item, 'depth', 'e6', :text=>t.depth(item)) + + item2 = t.item_nextsibling(item) + itemList << item2 if item2 != '' + + item2 = t.item_firstchild(item) + itemList << item2 if item2 != '' + end + } + + # Update items that lost some children + parentList.each{|item| + numChildren = t.item_numchildren(item) + if numChildren == 0 + if $Version_1_1_OrLater + t.item_configure(item, :button=>false) + else # TreeCtrl 1.0 + t.item_hasbutton(item, false) + end + t.item_style_map(item, 'item', 's2', ['e3', 'e3']) + else + t.item_element_configure(item, 'item', 'e4', :text=>"(#{numChildren})") + end + } + + # Update the target that gained some children + if t.item_style_set(parent, 0) != 's1' + if $Version_1_1_OrLater + t.item_configure(parent, :button=>true) + else # TreeCtrl 1.0 + t.item_hasbutton(parent, true) + end + t.item_style_map(parent, 'item', 's1', ['e3', 'e3']) + end + numChildren = t.item_numchildren(parent) + t.item_element_configure(parent, 'item', 'e4', :text=>"(#{numChildren})") +end + +# Same as TreeCtrl::AutoScanCheck, but calls RandomMotion and +# RandomAutoScanCheckAux +def randomAutoScanCheck(t, x, y) + x1, y1, x2, y2 = t.contentbox + margin = t.winfo_pixels(t.scrollmargin) + if x < x1 + margin || x >= x2 - margin || y < y1 + margin || y >= y2 - margin + if ! @Priv.exist?(:autoscan, :afterId, t) + if y >= y2 - margin + t.yview(:scroll, 1, :units) + delay = t.yscrolldelay + elsif y < y1 + margin + t.yview(:scroll, -1, :units) + delay = t.yscrolldelay + elsif x >= x2 - margin + t.xview(:scroll, 1, :units) + delay = t.xscrolldelay + elsif x < x1 + margin + t.xview(:scroll, -1, :units) + delay = t.xscrolldelay + end + if @Priv.exist?(:autoscan, :scanning, t) + delay = delay[1] if delay.kind_of?(Array) + else + delay = delay[0] if delay.kind_of?(Array) + @Priv[:autoscan, :scanning, t] = true + end + case @Priv['buttonMode'] + when 'drag', 'marquee' + randomMotion(t, x, y) + end + @Priv[:autoscan, :afterId, t] = + Tk.after(delay, proc{ randomAutoScanCheckAux(t) }) + end + return + end + Tk::TreeCtrl::BindCallback.autoScanCancel(t) +end + +def randomAutoScanCheckAux(t) + @Priv.unset(:autoscan, :afterId, t) + x = t.winfo_pointerx - t.winfo_rootx + y = t.winfo_pointery - t.winfo_rooty + randomAutoScanCheck(t, x, y) +end + +# +# Demo: random N items, button images +# +def demoRandom2(t) + demoRandom(t) + + init_pics('mac-*') + + t.configure(:openbuttonimage=>@images['mac-collapse'], + :closedbuttonimage=>@images['mac-expand'], + :showlines=>false) +end diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/readme.txt b/jni/ruby/ext/tk/sample/tkextlib/treectrl/readme.txt new file mode 100644 index 0000000..81e13b2 --- /dev/null +++ b/jni/ruby/ext/tk/sample/tkextlib/treectrl/readme.txt @@ -0,0 +1,2 @@ +The scripts and image files in this directory are based on demo files +of Tcl/Tk's TreeCtrl extension. diff --git a/jni/ruby/ext/tk/sample/tkextlib/treectrl/www-options.rb b/jni/ruby/ext/tk/sample/tkextlib/treectrl/www-options.rb new file mode 100644 index 0000000..6a3e9c2 --- /dev/null +++ b/jni/ruby/ext/tk/sample/tkextlib/treectrl/www-options.rb @@ -0,0 +1,303 @@ +def demoInternetOptions (t) + @Option = TkVarAccess.new_hash('::Option') + + height = t.font.metrics(:linespace) + 2 + height = 18 if height < 18 + t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, + :itemheight=>height, :selectmode=>:browse) + + init_pics('internet-*') + + if $HasColumnCreate + t.column_create(:text=>'Internet Options') + else + t.column_configure(0, :text=>'Internet Options') + end + + t.state_define('check') + t.state_define('radio') + t.state_define('on') + + t.element_create('e1', :image, :image=>[ + @images['internet-check-on'], ['check', 'on'], + @images['internet-check-off'], ['check'], + @images['internet-radio-on'], ['radio', 'on'], + @images['internet-radio-off'], ['radio'] + ]) + t.element_create('e2', :text, + :fill=>[@SystemHighlightText, ['selected', 'focus']]) + t.element_create('e3', :rect, :showfocus=>true, + :fill=>[@SystemHighlight, ['selected', 'focus']]) + + s = t.style_create('s1') + t.style_elements(s, ['e3', 'e1', 'e2']) + t.style_layout(s, 'e1', :padx=>[0,4], :expand=>:ns) + t.style_layout(s, 'e2', :expand=>:ns) + t.style_layout(s, 'e3', :union=>['e2'], :iexpand=>:ns, :ipadx=>2) + + parentList = [:root, '', '', '', '', '', ''] + parent = :root + [ + [0, :print, "Printing", "", ""], + [1, :off, "Print background colors and images", "o1", ""], + [0, :search, "Search from Address bar", "", ""], + [1, :search, "When searching", "", ""], + [2, :off, "Display results, and go to the most likely sites", + "o2", "r1"], + [2, :off, "Do not search from the Address bar", "o3", "r1"], + [2, :off, "Just display the results in the main window", + "o4", "r1"], + [2, :on, "Just go to the most likely site", "o5", "r1"], + [0, :security, "Security", "", ""], + [1, :on, "Check for publisher's certificate revocation", "o5", ""], + [1, :off, "Check for server certificate revocation (requires restart)", + "o6", ""] + ].each{|depth, setting, text, option, group| + item = t.item_create() + t.item_style_set(item, 0, 's1') + t.item_element_configure(item, 0, 'e2', :text=>text) + @Option[:option, item] = option + @Option[:group, item] = group + if setting == :on || setting == :off + @Option[:setting, item] = setting + if group == '' + t.item_state_set(item, 'check') + if setting == :on + t.item_state_set(item, 'on') + end + else + if setting == :on + @Option[:current, group] = item + t.item_state_set(item, 'on') + end + t.item_state_set(item, 'radio') + end + else + t.item_element_configure(item, 0, 'e1', + :image=>@images["internet-#{setting}"]) + end + t.item_lastchild(parentList[depth], item) + depth += 1 + parentList[depth] = item + } + + treeCtrlOption = TkBindTag.new + treeCtrlOption.bind('Double-ButtonPress-1', proc{|w, x, y| + Tk::TreeCtrl::BindCallback.doubleButton1(w, x, y) + }, '%W %x %y') + treeCtrlOption.bind('ButtonPress-1', proc{|w, x, y| + optionButton1(w, x, y) + Tk.callback_break + }, '%W %x %y') + treeCtrlOption.bind('Button1-Motion', proc{|w, x, y| + optionMotion1(w, x, y) + Tk.callback_break + }, '%W %x %y') + treeCtrlOption.bind('Button1-Leave', proc{|w, x, y| + optionLeave1(w, x, y) + Tk.callback_break + }, '%W %x %y') + treeCtrlOption.bind('ButtonRelease-1', proc{|w, x, y| + optionRelease1(w, x, y) + Tk.callback_break + }, '%W %x %y') + + t.bindtags = [ + t, treeCtrlOption, Tk::TreeCtrl, t.winfo_toplevel, TkBindTag::ALL + ] +end + +def optionButton1(w, x, y) + w.set_focus + id = w.identify(x, y) + if id[0] == 'header' + Tk::TreeCtrl::BindCallback.buttonPress1(w, x, y) + elsif id.empty? + @Priv['buttonMode'] = '' + else + @Priv['buttonMode'] = '' + item = id[1] + w.selection_modify(item, :all) + w.activate(item) + return if @Option[:option, item] == '' + group = @Option[:group, item] + if group == '' + # a checkbutton + w.item_state_set(item, '~on') + if @Option[:setting, item] == 'on' + setting = :off + else + setting = :on + end + @Option[:setting, item] = setting + else + # a radiobutton + current = @Option[:current, group] + return if current == item.to_s + w.item_state_set(current, '!on') + w.item_state_set(item, 'on') + @Option[:setting, item] = :on + @Option[:current, group] = item + end + end +end + +# Alternate implementation that doesn't rely on run-time styles +def demoInternetOptions_2(t) + height = t.font.metrics(:linespace) + 2 + height = 18 if height < 18 + t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, + :itemheight=>height, :selectmode=>:browse) + + init_pics('internet-*') + + t.column_configure(0, :text=>'Internet Options') + + t.element_create('e1', :image) + t.element_create('e2', :text, + :fill=>[@SystemHighlightText, ['selected', 'focus']]) + t.element_create('e3', :rect, :showfocus=>true, + :fill=>[@SystemHighlight, ['selected', 'focus']]) + + s = t.style_create('s1') + t.style_elements('s1', ['e3', 'e1', 'e2']) + t.style_layout(s, 'e1', :padx=>[0,4], :expand=>:ns) + t.style_layout(s, 'e2', :expand=>:ns) + t.style_layout(s, 'e3', :union=>['e2'], :iexpand=>:ns, :ipadx=>2) + + parentList = [:root, '', '', '', '', '', ''] + parent = :root + [ + [0, :print, "Printing", "", ""], + [1, :off, "Print background colors and images", "o1", ""], + [0, :search, "Search from Address bar", "", ""], + [1, :search, "When searching", "", ""], + [2, :off, "Display results, and go to the most likely sites", + "o2", "r1"], + [2, :off, "Do not search from the Address bar", "o3", "r1"], + [2, :off, "Just display the results in the main window", + "o4", "r1"], + [2, :on, "Just go to the most likely site", "o5", "r1"], + [0, :security, "Security", "", ""], + [1, :on, "Check for publisher's certificate revocation", "o5", ""], + [1, :off, "Check for server certificate revocation (requires restart)", + "o6", ""] + ].each{|depth, setting, text, option, group| + item = t.item_create() + t.item_style_set(item, 0, 's1') + t.item_element_configure(item, 0, 'e2', :text=>text) + @Option[:option, item] = option + @Option[:group, item] = group + if setting == :on || setting == :off + @Option[:setting, item] = setting + if group == '' + img = @images["internet-check-#{setting}"] + t.item_element_configure(item, 0, 'e1', :image=>img) + else + if setting == :on + @Option[:current, group] = item + end + img = @images["internet-radio-#{setting}"] + t.item_element_configure(item, 0, 'e1', :image=>img) + end + else + t.item_element_configure(item, 0, 'e1', + :image=>@images["internet-#{setting}"]) + end + t.item_lastchild(parentList[depth], item) + depth += 1 + parentList[depth] = item + } + + treeCtrlOption = TkBindTag.new + treeCtrlOption.bind('Double-ButtonPress-1', proc{|w, x, y| + Tk::TreeCtrl::BindCallback.doubleButton1(w, x, y) + }, '%W %x %y') + treeCtrlOption.bind('ButtonPress-1', proc{|w, x, y| + optionButton1(w, x, y) + Tk.callback_break + }, '%W %x %y') + treeCtrlOption.bind('Button1-Motion', proc{|w, x, y| + optionMotion1(w, x, y) + Tk.callback_break + }, '%W %x %y') + treeCtrlOption.bind('Button1-Leave', proc{|w, x, y| + optionLeave1(w, x, y) + Tk.callback_break + }, '%W %x %y') + treeCtrlOption.bind('ButtonRelease-1', proc{|w, x, y| + optionRelease1(w, x, y) + Tk.callback_break + }, '%W %x %y') + + t.bindtags = [ + t, treeCtrlOption, Tk::TreeCtrl, t.winfo_toplevel, TkBindTag::ALL + ] +end + +def optionButton1_2(w, x, y) + w.set_focus + id = w.identify(x, y) + if id[0] == 'header' + Tk::TreeCtrl::BindCallback.buttonPress1(w, x, y) + elsif id.empty? + @Priv['buttonMode'] = '' + else + @Priv['buttonMode'] = '' + item = id[1] + w.selection_modify(item, :all) + w.activate(item) + return if @Option[:option, item] == '' + group = @Option[:group, item] + if group == '' + # a checkbutton + if @Option[:setting, item] == 'on' + setting = :off + else + setting = :on + end + w.item_element_configure(item, 0, 'e1', + :image=>@images["internet-check-#{setting}"]) + @Option[:setting, item] = setting + else + # a radiobutton + current = @Option[:current, group] + return if current == item.to_s + w.item_element_configure(current, 0, 'e1', + :image=>@images["internet-radio-off"]) + w.item_element_configure(item, 0, 'e1', + :image=>@images["internet-radio-on"]) + @Option[:setting, item] = :on + @Option[:current, group] = item + end + end +end + +def optionMotion1(w, x, y) + case @Priv['buttonMode'] + when 'resize', 'header' + Tk::TreeCtrl::BindCallback.motion1(w, x, y) + end +end + +def optionLeave1(w, x, y) + # This is called when I do ButtonPress-1 on Unix for some reason, + # and buttonMode is undefined. + begin + mode = @Priv['buttonMode'] + rescue + else + case mode + when 'header' + t.column_configure(@Priv['column'], :sunken=>false) + end + end +end + +def optionRelease1(w, x, y) + case @Priv['buttonMode'] + when 'resize', 'header' + Tk::TreeCtrl::BindCallback.release1(w, x, y) + end + @Priv['buttonMode'] = '' +end -- cgit v1.2.3