From 334325f72a08589acaeca6d9ef5171af42dfbe60 Mon Sep 17 00:00:00 2001 From: nagai Date: Sat, 26 Mar 2005 13:58:11 +0000 Subject: [PATCH] * ext/tk/lib/tk.rb (_callback_entry_class?): add for checking whether a class is available for a callback entry. * ext/tk/lib/tk.rb (after_cancel): add Tk.after_cancel(afterID) method. * ext/tk/lib/tk.rb (array2tk_list): change from private module method of TkComm to public module method. * ext/tk/lib/tk.rb (cget): add check that slot argument is not empty string. * ext/tk/lib/tk.rb (configinfo): ditto. * ext/tk/lib/tk/itemconfig.rb (itemcget): add check that slot argument is not empty string. * ext/tk/lib/tk/itemconfig.rb (itemconfiginfo): ditto. * ext/tk/lib/tk/entry.rb: add TkEntry#icursor and icursor= (alias of cursor and cursor= method). * ext/tk/lib/tk/font.rb: improve font treatment when the font name is empty string. * ext/tk/lib/tk/variable.rb: add :variable, :window and :procedure type. * ext/tk/lib/tk/variable.rb: improve treatment of array-type tkvariable. * ext/tk/lib/tkextlib/blt.rb: add commands for zooming. * ext/tk/lib/tkextlib/blt/*: bug fix. * ext/tk/lib/tkextlib/treectrl/tktreectrl.rb: bug fix and add methods to call TreeCtrl commands for bindings. * ext/tk/sample/tkextlib/blt/*: new sample scritps. * ext/tk/sample/tkextlib/treectrl/*: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@8195 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 43 + ext/tk/ChangeLog.tkextlib | 32 + ext/tk/lib/tk.rb | 30 +- ext/tk/lib/tk/entry.rb | 2 + ext/tk/lib/tk/font.rb | 113 +- ext/tk/lib/tk/itemconfig.rb | 16 +- ext/tk/lib/tk/variable.rb | 530 ++++++- ext/tk/lib/tkextlib/SUPPORT_STATUS | 15 +- ext/tk/lib/tkextlib/blt.rb | 41 + ext/tk/lib/tkextlib/blt/barchart.rb | 1 + ext/tk/lib/tkextlib/blt/bitmap.rb | 35 +- ext/tk/lib/tkextlib/blt/busy.rb | 42 +- ext/tk/lib/tkextlib/blt/component.rb | 251 +++- ext/tk/lib/tkextlib/blt/graph.rb | 1 + ext/tk/lib/tkextlib/blt/htext.rb | 5 + ext/tk/lib/tkextlib/blt/stripchart.rb | 1 + ext/tk/lib/tkextlib/blt/table.rb | 17 +- ext/tk/lib/tkextlib/treectrl/tktreectrl.rb | 280 +++- ext/tk/sample/tkextlib/blt/barchart5.rb | 101 ++ ext/tk/sample/tkextlib/blt/graph7.rb | 40 + ext/tk/sample/tkextlib/blt/graph7a.rb | 63 + ext/tk/sample/tkextlib/blt/graph7b.rb | 41 + ext/tk/sample/tkextlib/blt/graph7c.rb | 45 + .../sample/tkextlib/blt/images/buckskin.gif | Bin 0 -> 7561 bytes ext/tk/sample/tkextlib/blt/images/qv100.t.gif | Bin 0 -> 2694 bytes ext/tk/sample/tkextlib/blt/images/sample.gif | Bin 0 -> 186103 bytes ext/tk/sample/tkextlib/blt/plot1.rb | 9 + ext/tk/sample/tkextlib/blt/plot1b.rb | 10 + ext/tk/sample/tkextlib/blt/readme.txt | 2 + .../sample/tkextlib/blt/scripts/stipples.rb | 156 ++ ext/tk/sample/tkextlib/blt/winop1.rb | 40 + ext/tk/sample/tkextlib/blt/winop2.rb | 28 + ext/tk/sample/tkextlib/treectrl/bitmaps.rb | 75 + ext/tk/sample/tkextlib/treectrl/demo.rb | 1256 +++++++++++++++++ ext/tk/sample/tkextlib/treectrl/explorer.rb | 442 ++++++ ext/tk/sample/tkextlib/treectrl/help.rb | 405 ++++++ ext/tk/sample/tkextlib/treectrl/imovie.rb | 130 ++ ext/tk/sample/tkextlib/treectrl/layout.rb | 159 +++ ext/tk/sample/tkextlib/treectrl/mailwasher.rb | 269 ++++ .../tkextlib/treectrl/outlook-folders.rb | 124 ++ .../tkextlib/treectrl/outlook-newgroup.rb | 447 ++++++ .../sample/tkextlib/treectrl/pics/big-dll.gif | Bin 0 -> 437 bytes .../sample/tkextlib/treectrl/pics/big-exe.gif | Bin 0 -> 368 bytes .../tkextlib/treectrl/pics/big-file.gif | Bin 0 -> 466 bytes .../tkextlib/treectrl/pics/big-folder.gif | Bin 0 -> 459 bytes .../sample/tkextlib/treectrl/pics/big-txt.gif | Bin 0 -> 392 bytes .../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 .../tkextlib/treectrl/pics/folder-open.gif | Bin 0 -> 120 bytes .../treectrl/pics/help-book-closed.gif | Bin 0 -> 115 bytes .../tkextlib/treectrl/pics/help-book-open.gif | Bin 0 -> 128 bytes .../tkextlib/treectrl/pics/help-page.gif | Bin 0 -> 132 bytes .../tkextlib/treectrl/pics/imovie-01.gif | Bin 0 -> 5406 bytes .../tkextlib/treectrl/pics/imovie-02.gif | Bin 0 -> 5912 bytes .../tkextlib/treectrl/pics/imovie-03.gif | Bin 0 -> 4696 bytes .../tkextlib/treectrl/pics/imovie-04.gif | Bin 0 -> 5783 bytes .../tkextlib/treectrl/pics/imovie-05.gif | Bin 0 -> 3238 bytes .../tkextlib/treectrl/pics/imovie-06.gif | Bin 0 -> 3509 bytes .../tkextlib/treectrl/pics/imovie-07.gif | Bin 0 -> 2091 bytes .../treectrl/pics/internet-check-off.gif | Bin 0 -> 70 bytes .../treectrl/pics/internet-check-on.gif | Bin 0 -> 76 bytes .../tkextlib/treectrl/pics/internet-print.gif | Bin 0 -> 124 bytes .../treectrl/pics/internet-radio-off.gif | Bin 0 -> 68 bytes .../treectrl/pics/internet-radio-on.gif | Bin 0 -> 71 bytes .../treectrl/pics/internet-search.gif | Bin 0 -> 114 bytes .../treectrl/pics/internet-security.gif | Bin 0 -> 108 bytes .../tkextlib/treectrl/pics/mac-collapse.gif | Bin 0 -> 275 bytes .../tkextlib/treectrl/pics/mac-expand.gif | Bin 0 -> 277 bytes .../tkextlib/treectrl/pics/outlook-arrow.gif | Bin 0 -> 73 bytes .../tkextlib/treectrl/pics/outlook-clip.gif | Bin 0 -> 73 bytes .../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 .../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 .../tkextlib/treectrl/pics/outlook-read.gif | Bin 0 -> 304 bytes .../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 .../tkextlib/treectrl/pics/small-dll.gif | Bin 0 -> 311 bytes .../tkextlib/treectrl/pics/small-exe.gif | Bin 0 -> 115 bytes .../tkextlib/treectrl/pics/small-file.gif | Bin 0 -> 338 bytes .../tkextlib/treectrl/pics/small-folder.gif | Bin 0 -> 307 bytes .../tkextlib/treectrl/pics/small-txt.gif | Bin 0 -> 302 bytes .../tkextlib/treectrl/pics/unchecked.gif | Bin 0 -> 72 bytes ext/tk/sample/tkextlib/treectrl/random.rb | 505 +++++++ ext/tk/sample/tkextlib/treectrl/readme.txt | 2 + .../sample/tkextlib/treectrl/www-options.rb | 303 ++++ 95 files changed, 5898 insertions(+), 209 deletions(-) create mode 100644 ext/tk/sample/tkextlib/blt/barchart5.rb create mode 100644 ext/tk/sample/tkextlib/blt/graph7.rb create mode 100644 ext/tk/sample/tkextlib/blt/graph7a.rb create mode 100644 ext/tk/sample/tkextlib/blt/graph7b.rb create mode 100644 ext/tk/sample/tkextlib/blt/graph7c.rb create mode 100644 ext/tk/sample/tkextlib/blt/images/buckskin.gif create mode 100644 ext/tk/sample/tkextlib/blt/images/qv100.t.gif create mode 100644 ext/tk/sample/tkextlib/blt/images/sample.gif create mode 100644 ext/tk/sample/tkextlib/blt/plot1.rb create mode 100644 ext/tk/sample/tkextlib/blt/plot1b.rb create mode 100644 ext/tk/sample/tkextlib/blt/readme.txt create mode 100644 ext/tk/sample/tkextlib/blt/scripts/stipples.rb create mode 100644 ext/tk/sample/tkextlib/blt/winop1.rb create mode 100644 ext/tk/sample/tkextlib/blt/winop2.rb create mode 100644 ext/tk/sample/tkextlib/treectrl/bitmaps.rb create mode 100644 ext/tk/sample/tkextlib/treectrl/demo.rb create mode 100644 ext/tk/sample/tkextlib/treectrl/explorer.rb create mode 100644 ext/tk/sample/tkextlib/treectrl/help.rb create mode 100644 ext/tk/sample/tkextlib/treectrl/imovie.rb create mode 100644 ext/tk/sample/tkextlib/treectrl/layout.rb create mode 100644 ext/tk/sample/tkextlib/treectrl/mailwasher.rb create mode 100644 ext/tk/sample/tkextlib/treectrl/outlook-folders.rb create mode 100644 ext/tk/sample/tkextlib/treectrl/outlook-newgroup.rb create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/big-dll.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/big-exe.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/big-file.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/big-folder.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/big-txt.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/checked.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/file.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/folder-closed.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/folder-open.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/help-book-closed.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/help-book-open.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/help-page.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/imovie-01.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/imovie-02.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/imovie-03.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/imovie-04.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/imovie-05.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/imovie-06.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/imovie-07.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/internet-check-off.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/internet-check-on.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/internet-print.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/internet-radio-off.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/internet-radio-on.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/internet-search.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/internet-security.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/mac-collapse.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/mac-expand.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/outlook-arrow.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/outlook-clip.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/outlook-deleted.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/outlook-draft.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/outlook-folder.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/outlook-group.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/outlook-inbox.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/outlook-local.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/outlook-main.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/outlook-outbox.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/outlook-read-2.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/outlook-read.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/outlook-sent.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/outlook-server.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/outlook-unread.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/outlook-watch.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/sky.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/small-dll.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/small-exe.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/small-file.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/small-folder.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/small-txt.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/pics/unchecked.gif create mode 100644 ext/tk/sample/tkextlib/treectrl/random.rb create mode 100644 ext/tk/sample/tkextlib/treectrl/readme.txt create mode 100644 ext/tk/sample/tkextlib/treectrl/www-options.rb diff --git a/ChangeLog b/ChangeLog index 7010c42f72..841c8f12a1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,46 @@ +Sat Mar 26 22:51:33 2005 Hidetoshi NAGAI + + * ext/tk/lib/tk.rb (_callback_entry_class?): add for checking whether + a class is available for a callback entry. + + * ext/tk/lib/tk.rb (after_cancel): add Tk.after_cancel(afterID) method. + + * ext/tk/lib/tk.rb (array2tk_list): change from private module method + of TkComm to public module method. + + * ext/tk/lib/tk.rb (cget): add check that slot argument is not + empty string. + + * ext/tk/lib/tk.rb (configinfo): ditto. + + * ext/tk/lib/tk/itemconfig.rb (itemcget): add check that slot argument + is not empty string. + + * ext/tk/lib/tk/itemconfig.rb (itemconfiginfo): ditto. + + * ext/tk/lib/tk/entry.rb: add TkEntry#icursor and icursor= (alias of + cursor and cursor= method). + + * ext/tk/lib/tk/font.rb: improve font treatment when the font name is + empty string. + + * ext/tk/lib/tk/variable.rb: add :variable, :window and :procedure + type. + + * ext/tk/lib/tk/variable.rb: improve treatment of array-type + tkvariable. + + * ext/tk/lib/tkextlib/blt.rb: add commands for zooming. + + * ext/tk/lib/tkextlib/blt/*: bug fix. + + * ext/tk/lib/tkextlib/treectrl/tktreectrl.rb: bug fix and add methods + to call TreeCtrl commands for bindings. + + * ext/tk/sample/tkextlib/blt/*: new sample scritps. + + * ext/tk/sample/tkextlib/treectrl/*: ditto. + Fri Mar 25 10:53:16 2005 WATANABE Hirofumi * configure.in (WIN32_LEAN_AND_MEAN): removed because a lot of diff --git a/ext/tk/ChangeLog.tkextlib b/ext/tk/ChangeLog.tkextlib index c27ada6d01..85fd938e3a 100644 --- a/ext/tk/ChangeLog.tkextlib +++ b/ext/tk/ChangeLog.tkextlib @@ -1,3 +1,35 @@ +2005-03-26 Hidetoshi NAGAI + + * lib/tkextlib/blt.rb: add commands for zooming. + + * lib/tkextlib/blt/bitmap.rb (new_with_name): add for using + given name. + + * lib/tkextlib/blt/busy.rb: bug fix on Tk::BLT::Busy::Shild class. + + * lib/tkextlib/blt/component.rb: typo fix. + + * lib/tkextlib/blt/component.rb: fix lack of *_create methods + + * lib/tkextlib/blt/component.rb: proper call on xaxis_* and so on. + + * lib/tkextlib/blt/htext.rb: add TkVariable object to access + special Tcl variables. + + * ext/tk/lib/tkextlib/treectrl/tktreectrl.rb: typo fix. + + * ext/tk/lib/tkextlib/treectrl/tktreectrl.rb: proper treatment + of 'font' option of element_configure. + + * ext/tk/lib/tkextlib/treectrl/tktreectrl.rb: bug fix on item_sort. + + * ext/tk/lib/tkextlib/treectrl/tktreectrl.rb: add methods to + call TreeCtrl commands for bindings. + + * ext/tk/sample/tkextlib/blt/*: add some sample scripts. + + * ext/tk/sample/tkextlib/treectrl/*: add some sample scripts. + 2005-03-18 Hidetoshi NAGAI * lib/tkextlib/treectrl/tktreectrl.rb: bug fix and define some diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb index d246cd9a0c..61e76c29bc 100644 --- a/ext/tk/lib/tk.rb +++ b/ext/tk/lib/tk.rb @@ -448,7 +448,7 @@ end private_class_method :tk_split_escstr, :tk_split_sublist private_class_method :tk_split_list, :tk_split_simplelist - private_class_method :array2tk_list +# private_class_method :array2tk_list =begin ### --> definition is moved to TkUtil module @@ -583,6 +583,12 @@ end private :_toUTF8, :_fromUTF8 module_function :_toUTF8, :_fromUTF8 + def _callback_entry_class?(cls) + cls <= Proc || cls <= Method || cls <= TkCallbackEntry + end + private :_callback_entry_class? + module_function :_callback_entry_class? + def _callback_entry?(obj) obj.kind_of?(Proc) || obj.kind_of?(Method) || obj.kind_of?(TkCallbackEntry) end @@ -1301,6 +1307,10 @@ module TkCore tk_call_without_enc('after','idle',cmdid) end + def after_cancel(afterId) + tk_call_without_enc('after','cancel',afterId) + end + def windowingsystem tk_call_without_enc('tk', 'windowingsystem') end @@ -2612,7 +2622,12 @@ module TkConfigMethod end def cget(slot) + orig_slot = slot slot = slot.to_s + + if slot.length == 0 + fail ArgumentError, "Invalid option `#{orig_slot.inspect}'" + end if ( method = _symbolkey2str(__methodcall_optkeys)[slot] ) return self.__send__(method) @@ -2698,7 +2713,12 @@ module TkConfigMethod end else + orig_slot = slot slot = slot.to_s + if slot.length == 0 + fail ArgumentError, "Invalid option `#{orig_slot.inspect}'" + end + if ( conf = __keyonly_optkeys.find{|k, v| k.to_s == slot} ) defkey, undefkey = conf if value @@ -2727,7 +2747,8 @@ module TkConfigMethod def configinfo(slot = nil) if TkComm::GET_CONFIGINFO_AS_ARRAY - if (slot.to_s =~ /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/) + if (slot && + slot.to_s =~ /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/) fontkey = $2 conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{fontkey}")))) conf[__configinfo_struct[:key]] = @@ -2984,7 +3005,8 @@ module TkConfigMethod end else # ! TkComm::GET_CONFIGINFO_AS_ARRAY - if (slot.to_s =~ /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/) + if (slot && + slot.to_s =~ /^(|latin|ascii|kanji)(#{__font_optkeys.join('|')})$/) fontkey = $2 conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__confinfo_cmd << "-#{fontkey}")))) conf[__configinfo_struct[:key]] = @@ -4002,7 +4024,7 @@ end #Tk.freeze module Tk - RELEASE_DATE = '2005-03-14'.freeze + RELEASE_DATE = '2005-03-26'.freeze autoload :AUTO_PATH, 'tk/variable' autoload :TCL_PACKAGE_PATH, 'tk/variable' diff --git a/ext/tk/lib/tk/entry.rb b/ext/tk/lib/tk/entry.rb index 0fe553d55c..63051979e6 100644 --- a/ext/tk/lib/tk/entry.rb +++ b/ext/tk/lib/tk/entry.rb @@ -27,11 +27,13 @@ class TkEntry@latinfont, 'kanjifont'=>@kanjifont} + else + @compoundfont = @latinfont + @fontslot = {'font'=>@latinfont} + end + else + @latinfont = @id + 'l' + @kanjifont = @id + 'k' + @compoundfont = @id + 'c' + + if JAPANIZED_TK + tk_call('font', 'create', @latinfont, '-charset', 'iso8859') + tk_call('font', 'create', @kanjifont, '-charset', 'jisx0208.1983') + tk_call('font', 'create', @compoundfont, + '-compound', [@latinfont, @kanjifont]) + else + tk_call('font', 'create', @latinfont) + tk_call('font', 'create', @kanjifont) + tk_call('font', 'create', @compoundfont) + end + + @fontslot = {'font'=>@compoundfont} + end + + self + end + def initialize(ltn=nil, knj=nil, keys=nil) + ltn = '{}' if ltn == '' + knj = '{}' if knj == '' + # @id = Tk_FontID.join('') @id = Tk_FontID.join(TkCore::INTERP._ip_id_) Tk_FontID[1].succ! @@ -657,10 +711,17 @@ class TkFont end def create_compoundfont_tk8x(ltn, knj, keys) - create_latinfont(ltn) - create_kanjifont(knj) + if knj + create_latinfont(ltn) + create_kanjifont(knj) + else + cfnt = ltn + create_kanjifont(cfnt) + create_latinfont(cfnt) + end @compoundfont = @id + 'c' + if JAPANIZED_TK unless keys keys = {} @@ -735,6 +796,7 @@ class TkFont end if knj + compoundkeys = nil kanjikeys = {} begin actual_core(@kanjifont).each{|key,val| kanjikeys[key] = val} @@ -746,6 +808,17 @@ class TkFont end end + if cfnt + if cfnt.kind_of?(Hash) + compoundkeys = cfnt.dup + else + compoundkeys = {} + actual_core(cfnt).each{|key,val| compoundkeys[key] = val} + end + compoundkeys.update(_symbolkey2str(keys)) + keys = compoundkeys + end + @fontslot = {'font'=>@compoundfont} tk_call('font', 'configure', @compoundfont, *hash_kv(keys)) end @@ -754,11 +827,21 @@ class TkFont ################################### public ################################### + def inspect + sprintf("#<%s:%0x:%s>", self.class.inspect, self.__id__, @compoundfont) + end + def method_missing(id, *args) name = id.id2name case args.length when 1 - configure name, args[0] + if name[-1] == ?= + configure name[0..-2], args[0] + args[0] + else + configure name, args[0] + self + end when 0 begin configinfo name @@ -1099,6 +1182,7 @@ class TkFont alias ascii_metrics latin_metrics ################################### +=begin def dup src = self obj = super() @@ -1111,6 +1195,13 @@ class TkFont obj.instance_eval{ initialize(src) } obj end +=end + def dup + TkFont.new(self) + end + def clone + TkFont.new(self) + end end module TkFont::CoreMethods @@ -1140,6 +1231,8 @@ module TkFont::CoreMethods end def actual_core_tk8x(font, win=nil, option=nil) + font = '{}' if font == '' + if option == 'compound' || option == :compound "" elsif option @@ -1465,6 +1558,8 @@ module TkFont::CoreMethods end def latin_replace_core_tk8x(ltn) + ltn = '{}' if ltn == '' + if JAPANIZED_TK begin tk_call('font', 'delete', '@font_tmp') @@ -1528,6 +1623,8 @@ module TkFont::CoreMethods end def kanji_replace_core_tk8x(knj) + knj = '{}' if knj == '' + if JAPANIZED_TK begin tk_call('font', 'delete', '@font_tmp') @@ -1573,6 +1670,8 @@ module TkFont::CoreMethods end def measure_core_tk8x(font, win, text) + font = '{}' if font == '' + if win number(tk_call('font', 'measure', font, '-displayof', win, text)) @@ -1591,6 +1690,8 @@ module TkFont::CoreMethods end def metrics_core_tk8x(font, win, option=nil) + font = '{}' if font == '' + if option if win number(tk_call('font', 'metrics', font, diff --git a/ext/tk/lib/tk/itemconfig.rb b/ext/tk/lib/tk/itemconfig.rb index f0f13e63bd..72225e7522 100644 --- a/ext/tk/lib/tk/itemconfig.rb +++ b/ext/tk/lib/tk/itemconfig.rb @@ -6,6 +6,8 @@ require 'tkutil' require 'tk/itemfont.rb' module TkItemConfigOptkeys + include TkUtil + def __item_numval_optkeys(id) [] end @@ -119,8 +121,13 @@ module TkItemConfigMethod ################################################ def itemcget(tagOrId, option) + orig_opt = option option = option.to_s + if option.length == 0 + fail ArgumentError, "Invalid option `#{orig_opt.inspect}'" + end + if ( method = _symbolkey2str(__item_methodcall_optkeys(tagid(tagOrId)))[option] ) return self.__send__(method, tagOrId) end @@ -204,7 +211,12 @@ module TkItemConfigMethod end else + orig_slot = slot slot = slot.to_s + if slot.length == 0 + fail ArgumentError, "Invalid option `#{orig_slot.inspect}'" + end + if ( conf = __item_keyonly_optkeys(tagid(tagOrId)).find{|k, v| k.to_s == slot } ) defkey, undefkey = conf if value @@ -229,7 +241,7 @@ module TkItemConfigMethod def itemconfiginfo(tagOrId, slot = nil) if TkComm::GET_CONFIGINFO_AS_ARRAY - if (slot.to_s =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/) + if (slot && slot.to_s =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/) fontkey = $2 conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{fontkey}")))) conf[__item_configinfo_struct(tagid(tagOrId))[:key]] = @@ -487,7 +499,7 @@ module TkItemConfigMethod end else # ! TkComm::GET_CONFIGINFO_AS_ARRAY - if (slot.to_s =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/) + if (slot && slot.to_s =~ /^(|latin|ascii|kanji)(#{__item_font_optkeys(tagid(tagOrId)).join('|')})$/) fontkey = $2 conf = tk_split_simplelist(_fromUTF8(tk_call_without_enc(*(__item_confinfo_cmd(tagid(tagOrId)) << "-#{fontkey}")))) conf[__item_configinfo_struct(tagid(tagOrId))[:key]] = diff --git a/ext/tk/lib/tk/variable.rb b/ext/tk/lib/tk/variable.rb index e3a08dfdcf..982182c2a8 100644 --- a/ext/tk/lib/tk/variable.rb +++ b/ext/tk/lib/tk/variable.rb @@ -109,11 +109,12 @@ TkCore::INTERP.add_tk_procs('rb_var', 'args', <<-'EOL') end self end - def default_value=(val) + def set_default_value(val) @def_default = :val @default_val = val self end + alias default_value= set_default_value def default_proc(cmd = Proc.new) @def_default = :proc @default_val = cmd @@ -129,59 +130,111 @@ TkCore::INTERP.add_tk_procs('rb_var', 'args', <<-'EOL') def default_value_type @type end + def default_element_value_type(idxs) + if idxs.kind_of?(Array) + index = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',') + else + index = _get_eval_string(idxs, true) + end + @element_type[index] + end - def default_value_type=(type) + def _set_default_value_type_core(type, idxs) if type.kind_of?(Class) if type == NilClass - @type = nil + type = nil elsif type == Numeric - @type = :numeric + type = :numeric elsif type == TrueClass || type == FalseClass - @type = :bool + type = :bool elsif type == String - @type = :string + type = :string elsif type == Symbol - @type = :symbol + type = :symbol elsif type == Array - @type = :list + type = :list + elsif type <= TkVariable + type = :variable + elsif type <= TkWindow + type = :window + elsif TkComm._callback_entry_class?(type) + type = :procedure else - @type = nil + type = nil end else case(type) when nil - @type = nil + type = nil when :numeric, 'numeric' - @type = :numeric + type = :numeric when true, false, :bool, 'bool' - @type = :bool + type = :bool when :string, 'string' - @type = :string + type = :string when :symbol, 'symbol' - @type = :symbol + type = :symbol when :list, 'list' - @type = :list + type = :list when :numlist, 'numlist' - @type = :numlist + type = :numlist + when :variable, 'variable' + type = :variable + when :window, 'window' + type = :window + when :procedure, 'procedure' + type = :procedure else - self.default_value_type = type.class + return _set_default_value_type_core(type.class, idxs) end end - @type + if idxs + if idxs.kind_of?(Array) + index = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',') + else + index = _get_eval_string(idxs, true) + end + @element_type[index] = type + else + @type = type + end + type + end + private :_set_default_value_type_core + + def set_default_value_type(type) + _set_default_value_type_core(type, nil) + self + end + alias default_value_type= set_default_value_type + + def set_default_element_value_type(idxs, type) + _set_default_value_type_core(type, idxs) + self end - def _to_default_type(val) - return val unless @type + def _to_default_type(val, idxs = nil) + if idxs + if idxs.kind_of?(Array) + index = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',') + else + index = _get_eval_string(idxs, true) + end + type = @element_type[index] + else + type = @type + end + return val unless type if val.kind_of?(Hash) - val.keys.each{|k| val[k] = _to_default_type(val[k]) } + val.keys.each{|k| val[k] = _to_default_type(val[k], idxs) } val else begin - case(@type) + case(type) when :numeric number(val) when :bool - TkComm + TkComm.bool(val) when :string val when :symbol @@ -190,6 +243,12 @@ TkCore::INTERP.add_tk_procs('rb_var', 'args', <<-'EOL') tk_split_simplelist(val) when :numlist tk_split_simplelist(val).collect!{|v| number(v)} + when :variable + TkVarAccess.new(val) + when :window + TkComm.window(val) + when :procedure + TkComm.procedure(val) else val end @@ -200,6 +259,11 @@ TkCore::INTERP.add_tk_procs('rb_var', 'args', <<-'EOL') end private :_to_default_type + def _to_default_element_type(idxs, val) + _to_default_type(val, idxs) + end + private :_to_default_element_type + def initialize(val="", type=nil) # @id = Tk_VARIABLE_ID.join('') @id = Tk_VARIABLE_ID.join(TkCore::INTERP._ip_id_) @@ -213,6 +277,10 @@ TkCore::INTERP.add_tk_procs('rb_var', 'args', <<-'EOL') @trace_elem = nil @trace_opts = nil + @type = nil + var = self + @element_type = Hash.new{|k,v| var.default_value_type } + self.default_value_type = type begin @@ -326,14 +394,15 @@ TkCore::INTERP.add_tk_procs('rb_var', 'args', <<-'EOL') ! is_hash? end - def exist?(idx = nil) + def exist?(*elems) INTERP._invoke_without_enc('global', @id) - if idx - # array - TkComm.bool(tk_call('info', 'exist', "#{@id}")) && - TkComm.bool(tk_call('info', 'exist', "#{@id}(#{idx})")) - else + if elems.empty? TkComm.bool(tk_call('info', 'exist', @id)) + else + # array + index = elems.collect{|idx| _get_eval_string(idx, true)}.join(',') + TkComm.bool(tk_call('info', 'exist', "#{@id}")) && + TkComm.bool(tk_call('info', 'exist', "#{@id}(#{index})")) end end @@ -389,6 +458,7 @@ if USE_TCLs_SET_VARIABLE_FUNCTIONS end def value=(val) + val = val._value if !@type && @type != :variable && val.kind_of?(TkVariable) if val.kind_of?(Hash) self.clear val.each{|k, v| @@ -418,11 +488,10 @@ if USE_TCLs_SET_VARIABLE_FUNCTIONS end end - def [](*idxs) + def _element_value(*idxs) index = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',') begin - # _fromUTF8(INTERP._get_global_var2(@id, index)) - _to_default_type(_fromUTF8(INTERP._get_global_var2(@id, index))) + _fromUTF8(INTERP._get_global_var2(@id, index)) rescue => e case @def_default when :proc @@ -440,6 +509,8 @@ if USE_TCLs_SET_VARIABLE_FUNCTIONS def []=(*args) val = args.pop + type = default_element_value_type(args) + val = val._value if !type && type != :variable && val.kind_of?(TkVariable) index = args.collect{|idx| _get_eval_string(idx, true)}.join(',') _fromUTF8(INTERP._set_global_var2(@id, index, _get_eval_string(val, true))) #_fromUTF8(INTERP._set_global_var2(@id, _toUTF8(_get_eval_string(index)), @@ -448,11 +519,12 @@ if USE_TCLs_SET_VARIABLE_FUNCTIONS # _get_eval_string(val, true))) end - def unset(elem=nil) - if elem - INTERP._unset_global_var2(@id, _get_eval_string(elem, true)) - else + def unset(*elems) + if elems.empty? INTERP._unset_global_var(@id) + else + index = elems.collect{|idx| _get_eval_string(idx, true)}.join(',') + INTERP._unset_global_var2(@id, index) end end alias remove unset @@ -481,6 +553,7 @@ else end def value=(val) + val = val._value if !@type && @type != :variable && val.kind_of?(TkVariable) begin #s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"' s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"' @@ -530,11 +603,10 @@ else end end - def [](*idxs) + def _element_value(*idxs) index = idxs.collect{|idx| _get_eval_string(idx)}.join(',') begin - # INTERP._eval(Kernel.format('global %s; set %s(%s)', @id, @id, index)) - _to_default_type(INTERP._eval(Kernel.format('global %s; set %s(%s)', @id, @id, index))) + INTERP._eval(Kernel.format('global %s; set %s(%s)', @id, @id, index)) rescue => e case @def_default when :proc @@ -554,6 +626,8 @@ else def []=(*args) val = args.pop + type = default_element_value_type(args) + val = val._value if !type && type != :variable && val.kind_of?(TkVariable) index = args.collect{|idx| _get_eval_string(idx)}.join(',') INTERP._eval(Kernel.format('global %s; set %s(%s) %s', @id, @id, index, _get_eval_string(val))) @@ -565,37 +639,73 @@ else # _get_eval_string(val)) end - def unset(elem=nil) - if elem - INTERP._eval(Kernel.format('global %s; unset %s(%s)', - @id, @id, _get_eval_string(elem))) - #INTERP._eval(Kernel.format('unset %s(%s)', @id, tk_tcl2ruby(elem))) - #INTERP._eval('unset ' + @id + '(' + _get_eval_string(elem) + ')') - else + def unset(*elems) + if elems.empty? INTERP._eval(Kernel.format('global %s; unset %s', @id, @id)) #INTERP._eval(Kernel.format('unset %s', @id)) #INTERP._eval('unset ' + @id) + else + index = elems.collect{|idx| _get_eval_string(idx, true)}.join(',') + INTERP._eval(Kernel.format('global %s; unset %s(%s)', @id, @id, index)) + #INTERP._eval(Kernel.format('global %s; unset %s(%s)', + # @id, @id, _get_eval_string(elem))) + #INTERP._eval(Kernel.format('unset %s(%s)', @id, tk_tcl2ruby(elem))) + #INTERP._eval('unset ' + @id + '(' + _get_eval_string(elem) + ')') end end alias remove unset end - protected :_value + protected :_value, :_element_value def value _to_default_type(_value) end - def value_type=(val) - self.default_value_type = val - self.value=(val) + def [](*idxs) + _to_default_element_type(idxs, _element_value(*idxs)) + end + + def set_value(val) + self.value = val + self + end + + def set_element_value(idxs, val) + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self + end + + def set_value_type(val) + self.default_value_type = val.class + self.value = val + self + end + + alias value_type= set_value_type + + def set_element_value_type(idxs, val) + self.set_default_element_value_type(idxs, val.class) + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self end def numeric number(_value) end - def numeric=(val) + def numeric_element(*idxs) + number(_element_value(*idxs)) + end + def set_numeric(val) case val when Numeric self.value=(val) @@ -604,14 +714,39 @@ end else raise ArgumentError, "Numeric is expected" end - val + self end - def numeric_type=(val) + alias numeric= set_numeric + def set_numeric_element(idxs, val) + case val + when Numeric + val + when TkVariable + val = val.numeric + else + raise ArgumentError, "Numeric is expected" + end + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self + end + def set_numeric_type(val) @type = :numeric self.numeric=(val) + self + end + alias numeric_type= set_numeric_type + def set_numeric_element_type(idxs, val) + self.set_default_element_value_type(idxs, :numeric) + self.set_numeric_element(idxs, val) end def bool + TkComm.bool(_value) +=begin # see Tcl_GetBoolean man-page case _value.downcase when '0', 'false', 'no', 'off' @@ -619,8 +754,12 @@ end else true end +=end end - def bool=(val) + def bool_element(*idxs) + TkComm.bool(_element_value(*idxs)) + end + def set_bool(val) if ! val self.value = '0' else @@ -631,37 +770,216 @@ end self.value = '1' end end + self end - def bool_type=(val) + alias bool= set_bool + def set_bool_element(idxs, val) + if ! val + val = '0' + else + case val.to_s.downcase + when 'false', '0', 'no', 'off' + val = '0' + else + val = '1' + end + end + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self + end + def set_bool_type(val) @type = :bool self.bool=(val) + self + end + alias bool_type= set_bool_type + def set_bool_element_type(idxs, val) + self.set_default_element_value_type(idxs, :bool) + self.set_bool_element(idxs, val) + end + + def variable + TkVarAccess.new(self._value) + end + def variable_element(*idxs) + TkVarAccess.new(_element_value(*idxs)) + end + def set_variable(var) + var = var.id if var.kind_of?(TkVariable) + self.value = var + self + end + alias variable= set_variable + def set_variable_element(idxs, var) + var = var.id if var.kind_of?(TkVariable) + if idxs.kind_of?(Array) + self[*idxs]=var + else + self[idxs]=var + end + self + end + def set_variable_type(var) + @type = :variable + var = var.id if var.kind_of?(TkVariable) + self.value = var + self + end + alias variable_type= set_variable_type + def set_variable_element_type(idxs, var) + self.set_default_element_value_type(idxs, :variable) + self.set_variable_element(idxs, var) + end + + def window + TkComm.window(self._value) + end + def window_element(*idxs) + TkComm.window(_element_value(*idxs)) + end + def set_window(win) + win = win._value if win.kind_of?(TkVariable) + self.value = win + self + end + alias window= set_window + def set_window_element(idxs, win) + win = win._value if win.kind_of?(TkVariable) + if idxs.kind_of?(Array) + self[*idxs]=win + else + self[idxs]=win + end + self + end + def set_window_type(win) + @type = :window + self.window=(win) + self + end + alias window_type= set_window_type + def set_window_element_type(idxs, win) + self.set_default_element_value_type(idxs, :window) + self.set_window_element(idxs, win) + end + + def procedure + TkComm.procedure(self._value) + end + def procedure_element(*idxs) + TkComm.procedure(_element_value(*idxs)) + end + def set_procedure(cmd) + self.value = cmd + self + end + alias procedure= set_procedure + def set_procedure_element(idxs, cmd) + cmd = cmd._value if cmd.kind_of?(TkVariable) + if idxs.kind_of?(Array) + self[*idxs]=cmd + else + self[idxs]=cmd + end + self + end + def set_procedure_type(cmd) + @type = :procedure + self.procedure=(cmd) + self + end + alias procedure_type= set_procedure_type + def set_procedure_element_type(idxs, cmd) + self.set_default_element_value_type(idxs, :procedure) + self.set_proceure_element(idxs, cmd) end def to_i number(_value).to_i end + def element_to_i(*idxs) + number(_element_value(*idxs)).to_i + end def to_f number(_value).to_f end + def element_to_f(*idxs) + number(_element_value(*idxs)).to_f + end def to_s #string(value).to_s _value end - alias string= value= - def string_type=(val) + def element_to_s(*idxs) + _element_value(*idxs) + end + def string_element(*idxs) + _element_value(*idxs) + end + def set_string(val) + val = val._value if val.kind_of?(TkVariable) + self.value=val + self + end + alias string= set_string + def set_string_element(idxs, val) + val = val._value if val.kind_of?(TkVariable) + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self + end + def set_string_type(val) @type = :string - self.value=(val) + self.string=(val) + self + end + alias string_type= set_string_type + def set_string_element_type(idxs, val) + self.set_default_element_value_type(idxs, :string) + self.set_string_element(idxs, val) end def to_sym _value.intern end - alias symbol= value= - def symbol_type=(val) + alias symbol to_sym + def element_to_sym(*idxs) + _element_value(*idxs).intern + end + alias symbol_element element_to_sym + def set_symbol(val) + val = val._value if val.kind_of?(TkVariable) + self.value=val + self + end + alias symbol= set_symbol + def set_symbol_element(idxs, val) + val = val._value if val.kind_of?(TkVariable) + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self + end + def set_symbol_type(val) @type = :symbol self.value=(val) + self + end + alias symbol_type= set_symbol_type + def set_symbol_element_type(idxs, val) + self.set_default_element_value_type(idxs, :symbol) + self.set_symbol_element(idxs, val) end def list @@ -669,12 +987,19 @@ end tk_split_simplelist(_value) end alias to_a list + def list_element(*idxs) + tk_split_simplelist(_element_value(*idxs)) + end + alias element_to_a list_element def numlist list.collect!{|val| number(val)} end + def numlist_element(*idxs) + list_element(*idxs).collect!{|val| number(val)} + end - def list=(val) + def set_list(val) case val when Array self.value=(val) @@ -683,41 +1008,103 @@ end else raise ArgumentError, "Array is expected" end - val + self end - alias numlist= list= + alias list= set_list - def list_type=(val) + alias set_numlist set_list + alias numlist= set_numlist + + def set_list_element(idxs, val) + case val + when Array + val + when TkVariable + val = val.list + else + raise ArgumentError, "Array is expected" + end + if idxs.kind_of?(Array) + self[*idxs]=val + else + self[idxs]=val + end + self + end + alias set_numlist_element set_list_element + + def set_list_type(val) @type = :list self.list=(val) + self end - def numlist_type=(val) + alias list_type= set_list_type + def set_list_element_type(idxs, val) + self.set_default_element_value_type(idxs, :list) + self.set_list_element(idxs, val) + end + def set_numlist_type(val) @type = :numlist self.numlist=(val) + self + end + alias numlist_type= set_numlist_type + def set_numlist_element_type(idxs, val) + self.set_default_element_value_type(idxs, :numlist) + self.set_numlist_element(idxs, val) end def lappend(*elems) tk_call('lappend', @id, *elems) self end + def element_lappend(idxs, *elems) + if idxs.kind_of?(Array) + idxs = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',') + end + tk_call('lappend', "#{@id}(#{idxs})", *elems) + self + end def lindex(idx) tk_call('lindex', self._value, idx) end alias lget lindex + def element_lindex(elem_idxs, idx) + if elem_idxs.kind_of?(Array) + val = _element_value(*elem_idxs) + else + val = _element_value(elem_idxs) + end + tk_call('lindex', val, idx) + end + alias element_lget element_lindex def lget_i(idx) number(lget(idx)).to_i end + def element_lget_i(elem_idxs, idx) + number(element_lget(elem_idxs, idx)).to_i + end def lget_f(idx) number(lget(idx)).to_f end + def element_lget_f(elem_idxs, idx) + number(element_lget(elem_idxs, idx)).to_f + end def lset(idx, val) tk_call('lset', @id, idx, val) self end + def element_lset(elem_idxs, idx, val) + if elem_idxs.kind_of?(Array) + idxs = elem_idxs.collect{|i| _get_eval_string(i, true)}.join(',') + end + tk_call('lset', "#{@id}(#{idxs})", idx, val) + self + end def inspect #Kernel.format "#", @id @@ -823,7 +1210,8 @@ end # false if self is not an assoc array self._value == other else - false + # false + self._value == _get_eval_string(other) end end @@ -842,13 +1230,14 @@ end rescue other = other._value end - end - if other.kind_of?(Numeric) + elsif other.kind_of?(Numeric) begin return self.numeric <=> other rescue return self._value <=> other.to_s end + elsif other.kind_of?(Array) + return self.list <=> other else return self._value <=> other end @@ -1107,7 +1496,6 @@ end end end - class TkVarAccess ICONS TkImg 1.3 http://sf.net/projects/tkimg ==> tkimg +BLT 2.4z http://sourceforge.net/projects/blt + * see also tcltk-ext library on RAA + (http://raa.ruby-lang.org/) + ==> blt + +TkTreeCtrl 1.1 http://tktreectrl.sourceforge.net/ ==> treectrl + + ===< support (may be alpha or beta quality) >================================= @@ -84,19 +92,12 @@ TclX CVS/Hd(2005-02-07) ==> tclx (partial support; infox command and XPG/3 message catalogs only) -TkTreeCtrl 1.1 http://tktreectrl.sourceforge.net/ ==> treectrl - Tile 0.6 http://tktable.sourceforge.net/tile/ ==> tile ===< possibly available (not tested; alpha quality) >========================= -BLT 2.4z http://sourceforge.net/projects/blt - * see also tcltk-ext library on RAA - (http://raa.ruby-lang.org/) - ==> blt - winico CVS/Hd(2004-11-02) http://tktable.sourceforge.net ==> winico (win32 only) diff --git a/ext/tk/lib/tkextlib/blt.rb b/ext/tk/lib/tkextlib/blt.rb index 965886762e..60ed39a0cf 100644 --- a/ext/tk/lib/tkextlib/blt.rb +++ b/ext/tk/lib/tkextlib/blt.rb @@ -105,6 +105,47 @@ module Tk #################################################### + def self.active_legend(graph) + tk_call_without_enc('Blt_ActiveLegend', graph) + end + def self.crosshairs(graph) + tk_call_without_enc('Blt_Crosshairs', graph) + end + def self.zoom_stack(graph) + tk_call_without_enc('Blt_ZoomStack', graph) + end + def self.print_key(graph) + tk_call_without_enc('Blt_PrintKey', graph) + end + def self.closest_point(graph) + tk_call_without_enc('Blt_ClosestPoint', graph) + end + + module GraphCommand + def active_legend + tk_call_without_enc('Blt_ActiveLegend', @path) + self + end + def crosshairs + tk_call_without_enc('Blt_Crosshairs', @path) + self + end + def zoom_stack + tk_call_without_enc('Blt_ZoomStack', @path) + self + end + def print_key + tk_call_without_enc('Blt_PrintKey', @path) + self + end + def closest_point + tk_call_without_enc('Blt_ClosestPoint', @path) + self + end + end + + #################################################### + autoload :PlotComponent,'tkextlib/blt/component.rb' autoload :Barchart, 'tkextlib/blt/barchart.rb' diff --git a/ext/tk/lib/tkextlib/blt/barchart.rb b/ext/tk/lib/tkextlib/blt/barchart.rb index 624906b8bd..d8ecad834f 100644 --- a/ext/tk/lib/tkextlib/blt/barchart.rb +++ b/ext/tk/lib/tkextlib/blt/barchart.rb @@ -14,6 +14,7 @@ module Tk::BLT WidgetClassNames[WidgetClassName] = self include PlotComponent + include GraphCommand def __boolval_optkeys ['bufferelements', 'invertxy'] diff --git a/ext/tk/lib/tkextlib/blt/bitmap.rb b/ext/tk/lib/tkextlib/blt/bitmap.rb index 11ad5883d0..31cf8d4229 100644 --- a/ext/tk/lib/tkextlib/blt/bitmap.rb +++ b/ext/tk/lib/tkextlib/blt/bitmap.rb @@ -42,26 +42,41 @@ module Tk::BLT alias _new new def new(data, keys={}) - _new(:data, data, keys) + _new(:data, nil, data, keys) end alias define new + def new_with_name(name, data, keys={}) + _new(:data, name, data, keys) + end + alias define_with_name new_with_name + def compose(text, keys={}) - _new(:text, text, keys) + _new(:text, nil, text, keys) + end + + def compose_with_name(name, text, keys={}) + _new(:text, name, text, keys) end end - def initialize(type, data, keys = {}) - @id = BITMAP_ID.join(TkCore::INTERP._ip_id_) - BITMAP_ID[1].succ! - BITMAP_ID_TBL[@id] = self + def initialize(type, name, data, keys = {}) + if name + @id = name + else + @id = BITMAP_ID.join(TkCore::INTERP._ip_id_) + BITMAP_ID[1].succ! + BITMAP_ID_TBL[@id] = self + end @path = @id - if type == :text - tk_call('::blt::bitmap', 'compose', @id, *hash_kv(keys)) - else # :data - tk_call('::blt::bitmap', 'define', @id, *hash_kv(keys)) + unless bool(tk_call('::blt::bitmap', 'exists', @id)) + if type == :text + tk_call('::blt::bitmap', 'compose', @id, data, *hash_kv(keys)) + else # :data + tk_call('::blt::bitmap', 'define', @id, data, *hash_kv(keys)) + end end end diff --git a/ext/tk/lib/tkextlib/blt/busy.rb b/ext/tk/lib/tkextlib/blt/busy.rb index c0740dc2d7..4726e466f4 100644 --- a/ext/tk/lib/tkextlib/blt/busy.rb +++ b/ext/tk/lib/tkextlib/blt/busy.rb @@ -13,6 +13,27 @@ module Tk::BLT extend TkItemConfigMethod TkCommandNames = ['::blt::busy'.freeze].freeze + + ########################### + + class Shield < TkWindow + def self.shield_path(win) + win = window(win) unless win.kind_of?(TkWindow) + if win.kind_of?(TkToplevel) + win.path + '._Busy' + else + win.path + '_Busy' + end + end + + def initialize(win) + @path = self.class.shield_path(win) + end + end + + def self.shield_path(win) + Tk::BLT::Busy::Shield.shield_path(win) + end end end @@ -30,27 +51,6 @@ class << Tk::BLT::Busy ################################## - class Shield < TkWindow - def self.shield_path(win) - win = window(win) unless win.kind_of?(TkWindow) - if win.kind_of?(TkToplevel) - win.path + '._Busy' - else - win.path + '_Busy' - end - end - - def initialize(win) - @path = self.class.shield_path(win) - end - end - - def shield_path(win) - Tk::BLT::Busy::Shield.shield_path(win) - end - - ################################## - def hold(win, keys={}) tk_call('::blt::busy', 'hold', win, *hash_kv(keys)) end diff --git a/ext/tk/lib/tkextlib/blt/component.rb b/ext/tk/lib/tkextlib/blt/component.rb index 8e36946d0b..c5152ddab4 100644 --- a/ext/tk/lib/tkextlib/blt/component.rb +++ b/ext/tk/lib/tkextlib/blt/component.rb @@ -34,7 +34,7 @@ module Tk::BLT end private :__item_strval_optkeys - def _item_listval_optkeys(id) + def __item_listval_optkeys(id) ['bindtags'] end private :__item_listval_optkeys @@ -266,8 +266,9 @@ module Tk::BLT @cpath = @chart.path Axis::OBJ_TBL[@cpath][@axis] = self keys = _symbolkey2str(keys) - unless keys.delete['without_creating'] - @chart.axis_create(@axis, keys) + unless keys.delete('without_creating') + # @chart.axis_create(@axis, keys) + tk_call(@chart, 'axis', 'create', @axis, keys) end end @@ -420,8 +421,9 @@ module Tk::BLT @cpath = @chart.path Element::OBJ_TBL[@cpath][@element] = self keys = _symbolkey2str(keys) - unless keys.delete['without_creating'] - @chart.element_create(@element, keys) + unless keys.delete('without_creating') + # @chart.element_create(@element, keys) + tk_call(@chart, 'element', 'create', @element, keys) end end @@ -623,8 +625,9 @@ module Tk::BLT @cpath = @chart.path Pen::OBJ_TBL[@cpath][@pen] = self keys = _symbolkey2str(keys) - unless keys.delete['without_creating'] - @chart.pen_create(@pen, keys) + unless keys.delete('without_creating') + # @chart.pen_create(@pen, keys) + tk_call(@chart, 'pen', 'create', @pen, keys) end end @@ -784,6 +787,24 @@ module Tk::BLT idnum.to_i # 'item id' is an integer number end + def self.create_type(chart, type, keys={}) + args, fontkeys = _parse_create_args(keys) + idnum = tk_call_without_enc(chart.path, 'create', type, *args) + chart.marker_configure(idnum, fontkeys) unless fontkeys.empty? + id = idnum.to_i # 'item id' is an integer number + obj = self.allocate + obj.instance_eval{ + @parent = @chart = chart + @path = chart.path + @id = id + unless Tk::BLT::PlotComponent::MarkerID_TBL[@path] + Tk::BLT::PlotComponent::MarkerID_TBL[@path] = {} + end + Tk::BLT::PlotComponent::MarkerID_TBL[@path][@id] = self + } + obj + end + def initialize(parent, *args) @parent = @chart = parent @path = parent.path @@ -980,12 +1001,10 @@ module Tk::BLT ################### - def marker_create(type, *args) - type.create(self, *args) + def axis_create(id=nil, keys={}) + # tk_send('axis', 'create', tagid(id), keys) + Tk::BLT::PlotComponent::Axis.new(self, id, keys) end - - ################### - def axis_delete(*ids) tk_send('axis', 'delete', *(ids.collect{|id| tagid(id)})) self @@ -1033,6 +1052,10 @@ module Tk::BLT ################### + def element_create(id=nil, keys={}) + # tk_send('element', 'create', tagid(id), keys) + Tk::BLT::PlotComponent::Element.new(self, id, keys) + end def element_activate(id, *indices) tk_send('element', 'activate', tagid(id), *indices) self @@ -1109,6 +1132,10 @@ module Tk::BLT ################### + def pen_create(id=nil, keys={}) + # tk_send('pen', 'create', tagid(id), keys) + Tk::BLT::PlotComponent::Pen.new(self, id, keys) + end def pen_delete(*ids) tk_send('pen', 'delete', *(ids.collect{|id| tagid(id)})) self @@ -1137,6 +1164,28 @@ module Tk::BLT ################### + def marker_create(type, keys={}) + case type + when :text, 'text' + Tk::BLT::PlotComponent::TextMarker.new(self, keys) + when :line, 'line' + Tk::BLT::PlotComponent::LineMarker.new(self, keys) + when :bitmap, 'bitmap' + Tk::BLT::PlotComponent::BitmapMarker.new(self, keys) + when :image, 'image' + Tk::BLT::PlotComponent::ImageMarker.new(self, keys) + when :polygon, 'polygon' + Tk::BLT::PlotComponent::PolygonMarker.new(self, keys) + when :window, 'window' + Tk::BLT::PlotComponent::WindowMarker.new(self, keys) + else + if type.kind_of?(Tk::BLT::PlotComponent::Marker) + type.new(self, keys) + else + Tk::BLT::PlotComponent::Marker.create_type(self, type, keys) + end + end + end def marker_after(id, target=nil) if target tk_send_without_enc('marker', 'after', tagid(id), tagid(target)) @@ -1183,103 +1232,219 @@ module Tk::BLT ################### def xaxis_cget(option) - axis_cget('xaxis', option) + itemcget('xaxis', option) end def xaxis_configure(slot, value=None) - axis_configure('xaxis', slot, value) + itemconfigure('xaxis', slot, value) end def xaxis_configinfo(slot=nil) - axis_configinfo('xaxis', slot) + itemconfiginfo('xaxis', slot) end def current_xaxis_configinfo(slot=nil) - current_axis_configinfo('xaxis', slot) + current_itemconfiginfo('xaxis', slot) + end + def xaxis_bind(context, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([path, 'xaxis', 'bind'], context, cmd, *args) + self + end + def xaxis_bind_append(context, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([path, 'xaxis', 'bind'], context, cmd, *args) + self + end + def xaxis_bind_remove(context) + _bind_remove([path, 'xaxis', 'bind'], context) + self + end + def xaxis_bindinfo(context=nil) + _bindinfo([path, 'xaxis', 'bind'], context) end def xaxis_invtransform(val) - axis_invtransform('xaxis', val) + list(tk_send('xaxis', 'invtransform', val)) end def xaxis_limits - axis_limits('xaxis') + list(tk_send('xaxis', 'limits')) end def xaxis_transform(val) - axis_transform('xaxis', val) + list(tk_send('xaxis', 'transform', val)) end def xaxis_use(target=nil) - axis_use('xaxis', target) + if target + Axis.id2obj(self, tk_send('xaxis', 'use', tagid(target))) + else + Axis.id2obj(self, tk_send('xaxis', 'use')) + end end def x2axis_cget(option) - axis_cget('x2axis', option) + itemcget('x2axis', option) end def x2axis_configure(slot, value=None) - axis_configure('x2axis', slot, value) + itemconfigure('x2axis', slot, value) end def x2axis_configinfo(slot=nil) - axis_configinfo('x2axis', slot) + itemconfiginfo('x2axis', slot) end def current_x2axis_configinfo(slot=nil) - current_axis_configinfo('x2axis', slot) + current_itemconfiginfo('x2axis', slot) + end + def x2axis_bind(context, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([path, 'x2axis', 'bind'], context, cmd, *args) + self + end + def x2axis_bind_append(context, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([path, 'x2axis', 'bind'], context, cmd, *args) + self + end + def x2axis_bind_remove(context) + _bind_remove([path, 'x2axis', 'bind'], context) + self + end + def x2axis_bindinfo(context=nil) + _bindinfo([path, 'x2axis', 'bind'], context) end def x2axis_invtransform(val) - axis_invtransform('x2axis', val) + list(tk_send('x2axis', 'invtransform', val)) end def x2axis_limits - axis_limits('x2axis') + list(tk_send('x2axis', 'limits')) end def x2axis_transform(val) - axis_transform('x2axis', val) + list(tk_send('x2axis', 'transform', val)) end def x2axis_use(target=nil) - axis_use('x2axis', target) + if target + Axis.id2obj(self, tk_send('x2axis', 'use', tagid(target))) + else + Axis.id2obj(self, tk_send('x2axis', 'use')) + end end def yaxis_cget(option) - axis_cget('yaxis', option) + itemcget('yaxis', option) end def yaxis_configure(slot, value=None) - axis_configure('yaxis', slot, value) + itemconfigure('yaxis', slot, value) end def yaxis_configinfo(slot=nil) - axis_configinfo('yaxis', slot) + itemconfiginfo('yaxis', slot) end def current_yaxis_configinfo(slot=nil) - current_axis_configinfo('yaxis', slot) + current_itemconfiginfo('yaxis', slot) + end + def yaxis_bind(context, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([path, 'yaxis', 'bind'], context, cmd, *args) + self + end + def yaxis_bind_append(context, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([path, 'yaxis', 'bind'], context, cmd, *args) + self + end + def yaxis_bind_remove(context) + _bind_remove([path, 'yaxis', 'bind'], context) + self + end + def yaxis_bindinfo(context=nil) + _bindinfo([path, 'yaxis', 'bind'], context) end def yaxis_invtransform(val) - axis_invtransform('yaxis', val) + list(tk_send('yaxis', 'invtransform', val)) end def yaxis_limits - axis_limits('yaxis') + list(tk_send('yaxis', 'limits')) end def yaxis_transform(val) - axis_transform('yaxis', val) + list(tk_send('yaxis', 'transform', val)) end def yaxis_use(target=nil) - axis_use('yaxis', target) + if target + Axis.id2obj(self, tk_send('yaxis', 'use', tagid(target))) + else + Axis.id2obj(self, tk_send('yaxis', 'use')) + end end def y2axis_cget(option) - axis_cget('y2axis', option) + itemcget('y2axis', option) end def y2axis_configure(slot, value=None) - axis_configure('y2axis', slot, value) + itemconfigure('y2axis', slot, value) end def y2axis_configinfo(slot=nil) axis_configinfo('y2axis', slot) end def current_y2axis_configinfo(slot=nil) - current_axis_configinfo('y2axis', slot) + current_itemconfiginfo('y2axis', slot) + end + def y2axis_bind(context, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind([path, 'y2axis', 'bind'], context, cmd, *args) + self + end + def y2axis_bind_append(context, *args) + if TkComm._callback_entry?(args[0]) || !block_given? + cmd = args.shift + else + cmd = Proc.new + end + _bind_append([path, 'y2axis', 'bind'], context, cmd, *args) + self + end + def y2axis_bind_remove(context) + _bind_remove([path, 'y2axis', 'bind'], context) + self + end + def y2axis_bindinfo(context=nil) + _bindinfo([path, 'y2axis', 'bind'], context) end def y2axis_invtransform(val) - axis_invtransform('y2axis', val) + list(tk_send('y2axis', 'invtransform', val)) end def y2axis_limits - axis_limits('y2axis') + list(tk_send('y2axis', 'limits')) end def y2axis_transform(val) - axis_transform('y2axis', val) + list(tk_send('y2axis', 'transform', val)) end def y2axis_use(target=nil) - axis_use('y2axis', target) + if target + Axis.id2obj(self, tk_send('y2axis', 'use', tagid(target))) + else + Axis.id2obj(self, tk_send('y2axis', 'use')) + end end end end diff --git a/ext/tk/lib/tkextlib/blt/graph.rb b/ext/tk/lib/tkextlib/blt/graph.rb index 0c49a70ec4..b16c72458a 100644 --- a/ext/tk/lib/tkextlib/blt/graph.rb +++ b/ext/tk/lib/tkextlib/blt/graph.rb @@ -14,6 +14,7 @@ module Tk::BLT WidgetClassNames[WidgetClassName] = self include PlotComponent + include GraphCommand def __boolval_optkeys ['bufferelements', 'invertxy'] diff --git a/ext/tk/lib/tkextlib/blt/htext.rb b/ext/tk/lib/tkextlib/blt/htext.rb index 29da9aa87f..3bc35b7e10 100644 --- a/ext/tk/lib/tkextlib/blt/htext.rb +++ b/ext/tk/lib/tkextlib/blt/htext.rb @@ -9,6 +9,11 @@ require 'tkextlib/blt.rb' module Tk::BLT class Htext= 0) + # dummy :: # pkgIndex.tcl of TreeCtrl-1.0 doesn't support auto_load for # 'loupe' command (probably it is bug, I think). @@ -146,7 +151,7 @@ module Tk::TreeCtrl::ConfigMethod None when 'dragimage' - obj + None when 'element' obj @@ -155,7 +160,7 @@ module Tk::TreeCtrl::ConfigMethod obj when 'marquee' - obj + None when 'notify' obj @@ -171,6 +176,10 @@ module Tk::TreeCtrl::ConfigMethod def tagid(mixed_id) if mixed_id == 'debug' ['debug', None] + elsif mixed_id == 'dragimage' + ['dragimage', None] + elsif mixed_id == 'marquee' + ['marquee', None] elsif mixed_id.kind_of?(Array) [mixed_id[0], treectrl_tagid(*mixed_id)] else @@ -237,6 +246,17 @@ module Tk::TreeCtrl::ConfigMethod end private :__item_configinfo_struct + + def __item_font_optkeys(id) + if id.kind_of?(Array) && (id[0] == 'element' || + (id[0].kind_of?(Array) && id[0][1] == 'element')) + [] + else + ['font'] + end + end + private :__item_font_optkeys + def __item_numstrval_optkeys(id) if id == 'debug' ['displaydelay'] @@ -249,14 +269,28 @@ module Tk::TreeCtrl::ConfigMethod def __item_boolval_optkeys(id) if id == 'debug' ['data', 'display', 'enable'] + elsif id == 'dragimage' + ['visible'] + elsif id == 'marquee' + ['visible'] elsif id.kind_of?(Array) case id[0] + when 'item' + ['button', 'visible'] when 'column' ['button', 'expand', 'squeeze', 'sunken', 'visible', 'widthhack'] when 'element' ['filled', 'showfocus'] + when 'notify' + ['active'] + when 'style' + ['detach'] else - super(id) + if id[0].kind_of?(Array) && id[0][1] == 'element' + ['filled', 'showfocus'] + else + super(id) + end end else super(id) @@ -280,8 +314,14 @@ module Tk::TreeCtrl::ConfigMethod ['itembackground'] when 'element' ['relief'] + when 'style' + ['union'] else - [] + if id[0].kind_of?(Array) && id[0][1] == 'element' + ['relief'] + else + [] + end end else [] @@ -328,17 +368,17 @@ module Tk::TreeCtrl::ConfigMethod current_itemconfiginfo('debug', slot) end - def dragimage_cget(tagOrId, option) - itemcget(['dragimage', tagOrId], option) + def dragimage_cget(option) + itemcget('dragimage', option) end - def dragimage_configure(tagOrId, slot, value=None) - itemconfigure(['dragimage', tagOrId], slot, value) + def dragimage_configure(slot, value=None) + itemconfigure('dragimage', slot, value) end - def dragimage_configinfo(tagOrId, slot=nil) - itemconfiginfo(['dragimage', tagOrId], slot) + def dragimage_configinfo(slot=nil) + itemconfiginfo('dragimage', slot) end - def current_dragimage_configinfo(tagOrId, slot=nil) - current_itemconfiginfo(['dragimage', tagOrId], slot) + def current_dragimage_configinfo(slot=nil) + current_itemconfiginfo('dragimage', slot) end def element_cget(tagOrId, option) @@ -380,17 +420,17 @@ module Tk::TreeCtrl::ConfigMethod current_itemconfiginfo([['item', 'element'], [item, column, elem]], slot) end - def marquee_cget(tagOrId, option) - itemcget(['marquee', tagOrId], option) + def marquee_cget(option) + itemcget('marquee', option) end - def marquee_configure(tagOrId, slot, value=None) - itemconfigure(['marquee', tagOrId], slot, value) + def marquee_configure(slot, value=None) + itemconfigure('marquee', slot, value) end - def marquee_configinfo(tagOrId, slot=nil) - itemconfiginfo(['marquee', tagOrId], slot) + def marquee_configinfo(slot=nil) + itemconfiginfo('marquee', slot) end - def current_marquee_configinfo(tagOrId, slot=nil) - current_itemconfiginfo(['marquee', tagOrId], slot) + def current_marquee_configinfo(slot=nil) + current_itemconfiginfo('marquee', slot) end def notify_cget(win, pattern, option) @@ -757,17 +797,20 @@ class Tk::TreeCtrl end alias item_first_child item_firstchild - def item_hashbutton(item, st=None) + def item_hasbutton(item, st=None) if st == None - bool(tk_send('item', 'hashbutton')) + bool(tk_send('item', 'hasbutton')) else - tk_send('item', 'hashbutton', st) + tk_send('item', 'hasbutton', st) self end end - def item_hashbutton?(item) - item_hashbutton(item) + alias item_has_button item_hasbutton + + def item_hasbutton?(item) + item_hasbutton(item) end + alias item_has_button? item_hasbutton? def item_index(item) list(tk_send('item', 'index', item)) @@ -811,8 +854,8 @@ class Tk::TreeCtrl end alias item_next_sibling item_nextsibling - def item_numchildren() - number(tk_send('item', 'numchildren')) + def item_numchildren(item) + number(tk_send('item', 'numchildren', item)) end alias item_num_children item_numchildren alias item_children_size item_numchildren @@ -850,10 +893,10 @@ class Tk::TreeCtrl opts = opts.collect{|param| if param.kind_of?(Hash) param = _symbolkey2str(param) - if param.key('column') + if param.key?('column') key = '-column' desc = param.delete('column') - elsif param.key('element') + elsif param.key?('element') key = '-element' desc = param.delete('element') else @@ -863,7 +906,7 @@ class Tk::TreeCtrl if param.empty? param = None else - param = __conv_item_keyonly_opts(item, param).to_a + param = hash_kv(__conv_item_keyonly_opts(item, param)) end if key @@ -874,7 +917,7 @@ class Tk::TreeCtrl elsif param.kind_of?(Array) if param[2].kind_of?(Hash) - param[2] = __conv_item_keyonly_opts(item, param[2]).to_a + param[2] = hash_kv(__conv_item_keyonly_opts(item, param[2])) end param @@ -898,17 +941,15 @@ class Tk::TreeCtrl end private :_item_sort_core + def item_sort(item, *opts) + _item_sort_core(true, item, *opts) + end def item_sort_not_really(item, *opts) _item_sort_core(false, item, *opts) end - def item_sort(item, *opts) - _item_sort_core(true, item, *opts) - end - def item_state_forcolumn(item, column, *args) tk_send('item', 'state', 'forcolumn', item, column, *args) - self end alias item_state_for_column item_state_forcolumn @@ -922,7 +963,6 @@ class Tk::TreeCtrl def item_state_set(item, *args) tk_send('item', 'state', 'set', item, *args) - self end def item_style_elements(item, column) @@ -1230,7 +1270,8 @@ class Tk::TreeCtrl def _conv_style_layout_val(sty, val) case sty.to_s when 'padx', 'pady', 'ipadx', 'ipady' - number(val) + lst = list(val) + (lst.size == 1)? lst[0]: lst when 'detach' bool(val) when 'union' @@ -1256,6 +1297,7 @@ class Tk::TreeCtrl else ret = Hash.new Hash[*simplelist(tk_send('style', 'layout', style, elem))].each{|k, v| + k = k[1..-1] ret[k] = _conv_style_layout_val(k, v) } ret @@ -1599,18 +1641,20 @@ class Tk::TreeCtrl::Item < TkObject end alias first_child firstchild - def hashbutton(st=None) + def hasbutton(st=None) if st == None - @tree.item_hashbutton(@id) + @tree.item_hasbutton(@id) else - @tree.item_hashbutton(@id, st) + @tree.item_hasbutton(@id, st) self end end + alias has_button hasbutton - def hashbutton? - @tree.item_hashbutton(@id) + def hasbutton? + @tree.item_hasbutton(@id) end + alias has_button? hasbutton? def index @tree.item_index(@id) @@ -1685,6 +1729,10 @@ class Tk::TreeCtrl::Item < TkObject def sort(*opts) @tree.item_sort(@id, *opts) end + def sort_not_really(*opts) + @tree.item_sort_not_really(@id, *opts) + self + end def state_forcolumn(column, *args) @tree.item_state_forcolumn(@id, column, *args) @@ -1829,3 +1877,149 @@ class Tk::TreeCtrl::Style < TkObject end end end + +module Tk::TreeCtrl::BindCallback + include Tk + extend Tk +end + +class << Tk::TreeCtrl::BindCallback + def cursorCheck(w, x, y) + tk_call('::TreeCtrl::CursorCheck', w, x, y) + end + def cursorCheckAux(w) + tk_call('::TreeCtrl::CursorCheckAux', w) + end + def cursorCancel(w) + tk_call('::TreeCtrl::CursorCancel', w) + end + def buttonPress1(w, x, y) + tk_call('::TreeCtrl::ButtonPress1', w, x, y) + end + def doubleButton1(w, x, y) + tk_call('::TreeCtrl::DoubleButton1', w, x, y) + end + def motion1(w, x, y) + tk_call('::TreeCtrl::Motion1', w, x, y) + end + def leave1(w, x, y) + tk_call('::TreeCtrl::Leave1', w, x, y) + end + def release1(w, x, y) + tk_call('::TreeCtrl::Release1', w, x, y) + end + def beginSelect(w, el) + tk_call('::TreeCtrl::BeginSelect', w, el) + end + def motion(w, le) + tk_call('::TreeCtrl::Motion', w, el) + end + def beginExtend(w, el) + tk_call('::TreeCtrl::BeginExtend', w, el) + end + def beginToggle(w, el) + tk_call('::TreeCtrl::BeginToggle', w, el) + end + def cancelRepeat + tk_call('::TreeCtrl::CancelRepeat') + end + def autoScanCheck(w, x, y) + tk_call('::TreeCtrl::AutoScanCheck', w, x, y) + end + def autoScanCheckAux(w) + tk_call('::TreeCtrl::AutoScanCheckAux', w) + end + def autoScanCancel(w) + tk_call('::TreeCtrl::AutoScanCancel', w) + end + def up_down(w, n) + tk_call('::TreeCtrl::UpDown', w, n) + end + def left_right(w, n) + tk_call('::TreeCtrl::LeftRight', w, n) + end + def setActiveItem(w, idx) + tk_call('::TreeCtrl::SetActiveItem', w, idx) + end + def extendUpDown(w, amount) + tk_call('::TreeCtrl::ExtendUpDown', w, amount) + end + def dataExtend(w, el) + tk_call('::TreeCtrl::DataExtend', w, el) + end + def cancel(w) + tk_call('::TreeCtrl::Cancel', w) + end + def selectAll(w) + tk_call('::TreeCtrl::selectAll', w) + end + def marqueeBegin(w, x, y) + tk_call('::TreeCtrl::MarqueeBegin', w, x, y) + end + def marqueeUpdate(w, x, y) + tk_call('::TreeCtrl::MarqueeUpdate', w, x, y) + end + def marqueeEnd(w, x, y) + tk_call('::TreeCtrl::MarqueeEnd', w, x, y) + end + def scanMark(w, x, y) + tk_call('::TreeCtrl::ScanMark', w, x, y) + end + def scanDrag(w, x, y) + tk_call('::TreeCtrl::ScanDrag', w, x, y) + end + + # filelist-bindings + def fileList_button1(w, x, y) + tk_call('::TreeCtrl::FileListButton1', w, x, y) + end + def fileList_motion1(w, x, y) + tk_call('::TreeCtrl::FileListMotion1', w, x, y) + end + def fileList_motion(w, x, y) + tk_call('::TreeCtrl::FileListMotion', w, x, y) + end + def fileList_leave1(w, x, y) + tk_call('::TreeCtrl::FileListLeave1', w, x, y) + end + def fileList_release1(w, x, y) + tk_call('::TreeCtrl::FileListRelease1', w, x, y) + end + def fileList_edit(w, i, s, e) + tk_call('::TreeCtrl::FileListEdit', w, i, s, e) + end + def fileList_editCancel(w) + tk_call('::TreeCtrl::FileListEditCancel', w) + end + def fileList_autoScanCheck(w, x, y) + tk_call('::TreeCtrl::FileListAutoScanCheck', w, x, y) + end + def fileList_autoScanCheckAux(w) + tk_call('::TreeCtrl::FileListAutoScanCheckAux', w) + end + + def entryOpen(w, item, col, elem) + tk_call('::::TreeCtrl::EntryOpen', w, item, col, elem) + end + def entryExpanderOpen(w, item, col, elem) + tk_call('::TreeCtrl::EntryExpanderOpen', w, item, col, elem) + end + def entryClose(w, accept) + tk_call('::TreeCtrl::EntryClose', w, accept) + end + def entryExpanderKeypress(w) + tk_call('::TreeCtrl::EntryExpanderKeypress', w) + end + def textOpen(w, item, col, elem, width=0, height=0) + tk_call('::TreeCtrl::TextOpen', w, item, col, elem, width, height) + end + def textExpanderOpen(w, item, col, elem, width) + tk_call('::TreeCtrl::TextOpen', w, item, col, elem, width) + end + def textClose(w, accept) + tk_call('::TreeCtrl::TextClose', w, accept) + end + def textExpanderKeypress(w) + tk_call('::TreeCtrl::TextExpanderKeypress', w) + end +end diff --git a/ext/tk/sample/tkextlib/blt/barchart5.rb b/ext/tk/sample/tkextlib/blt/barchart5.rb new file mode 100644 index 0000000000..db181d10ca --- /dev/null +++ b/ext/tk/sample/tkextlib/blt/barchart5.rb @@ -0,0 +1,101 @@ +#!/usr/bin/env ruby +require 'tk' +require 'tkextlib/blt' + +load File.join(File.dirname(File.expand_path(__FILE__)), + 'scripts', 'stipples.rb') + +TkOption.add('*graph.x.Title', 'X Axis Label') +TkOption.add('*graph.y.Title', 'Y Axis Label') +TkOption.add('*graph.title', 'A Simple Barchart') +TkOption.add('*graph.x.Font', 'Times 10') +TkOption.add('*graph.Element.Relief', :raised) + +visual = Tk.root.winfo_screenvisual +if visual != 'staticgray' && visual != 'grayscale' + TkOption.add('*graph.LineMarker.color', 'yellow') + TkOption.add('*graph.Element.Background', 'white') + TkOption.add('*graph.Legend.activeForeground', 'pink') + TkOption.add('*print.background', 'yellow') + TkOption.add('*quit.background', 'red') + TkOption.add('*graph.background', 'palegreen') + TkOption.add('*graph.plotBackground', 'lightblue') +end + +htext = Tk::BLT::Htext.new(:widgetname=>'.htext', :text=><'print', :text=>'Print', + :command=>proc{ + $graph.postsript(:output=>'bar.ps') + }) + Tk::BLT::Htext::Htext_Widget.window.append(b) + } + +%% button. +%% + + ruby { + $graph = Tk::BLT::Barchart.new(:widgetname=>'.htext.graph', + :relief=>:raised, :borderwidth=>2) + $graph.xaxis_configure(:rotate=>90, :stepsize=>0) + Tk::BLT::Htext::Htext_Widget.window.append($graph, + :fill=>:both, :padx=>4) + } + +%% + Hit the %% + + ruby { + b = TkButton.new(Tk::BLT::Htext::Htext_Widget.window, + :widgetname=>'quit', :text=>'Quit', + :command=>proc{ exit }) + Tk::BLT::Htext::Htext_Widget.window.append(b) + } + +%% button when you've seen enough.%% + + ruby { + l = TkLabel.new(Tk::BLT::Htext::Htext_Widget.window, :bitmap=>'BLT') + Tk::BLT::Htext::Htext_Widget.window.append(l, :padx=>20) + } + +%% +EOD + +names = %w(One Two Three Four Five Six Seven Eight) +if visual == 'staticgray' || visual == 'grayscale' + fgcolors = %w(white white white white white white white white) + bgcolors = %w(black black black black black black black black) +else + fgcolors = %w(yellow orange red magenta purple blue cyan green) + bgcolors = %w(yellow4 orange4 red4 magenta4 purple4 blue4 cyan4 green4) +end + +numColors = names.length + +Tk::TCL_PRECISION.value = 15 + +x = Tk::BLT::Vector.new +y = Tk::BLT::Vector.new +x.seq(-5.0, 5.0, 0.2) +y.expr("sin(#{x})") +barWidth = 0.19 + +$graph.element_create('sin', :relief=>:raised, :borderwidth=>1, + :x=>x, :y=>y, :barwidth=>barWidth) + +Tk::BLT::Table.add(Tk.root, htext, :fill=>:both) + +Tk.root.minsize(0, 0) + +Tk::BLT.zoom_stack($graph) +Tk::BLT.crosshairs($graph) +Tk::BLT.active_legend($graph) +Tk::BLT.closest_point($graph) + +Tk.mainloop diff --git a/ext/tk/sample/tkextlib/blt/graph7.rb b/ext/tk/sample/tkextlib/blt/graph7.rb new file mode 100644 index 0000000000..27fbe53d97 --- /dev/null +++ b/ext/tk/sample/tkextlib/blt/graph7.rb @@ -0,0 +1,40 @@ +#!/usr/bin/env ruby +require 'tk' +require 'tkextlib/blt' + +length = 250000 +graph = Tk::BLT::Graph.new(:title=>"Scatter Plot\n#{length} points") +graph.xaxis_configure(:loose=>false, :title=>'X Axis Label') +graph.yaxis_configure(:title=>'Y Axis Label') +graph.legend_configure(:activerelief=>:sunken, :background=>'') + +Tk::BLT::Table.add(Tk.root, graph, [0,0], :fill=>:both) + +v_x = Tk::BLT::Vector.new(length) +v_y = Tk::BLT::Vector.new(length) +v_x.expr("random(#{v_x})") +v_y.expr("random(#{v_y})") +v_x.sort(v_y) + +plot = Tk::BLT::PlotComponent::Element.new(graph, :symbol=>:square, + :color=>'green4', :fill=>'green2', + :linewidth=>0, :outlinewidth=>1, + :pixels=>4, :label=>'plot', + :xdata=>v_x, :ydata=>v_y) + +Tk.root.minsize(0, 0) + +#graph.zoom_stack +#graph.crosshairs +#graph.active_legend +#graph.closest_point +Tk::BLT.zoom_stack(graph) +Tk::BLT.crosshairs(graph) +Tk::BLT.active_legend(graph) +Tk::BLT.closest_point(graph) + +Tk::BLT::Busy.hold(graph) +Tk.update +Tk::BLT::Busy.release(graph) + +Tk.mainloop diff --git a/ext/tk/sample/tkextlib/blt/graph7a.rb b/ext/tk/sample/tkextlib/blt/graph7a.rb new file mode 100644 index 0000000000..a014f72fc7 --- /dev/null +++ b/ext/tk/sample/tkextlib/blt/graph7a.rb @@ -0,0 +1,63 @@ +#!/usr/bin/env ruby +require 'tk' +require 'tkextlib/blt' + +file = File.join(File.dirname(File.expand_path(__FILE__)), + 'images', 'buckskin.gif') +bgTexture = TkPhotoImage.new(:file=>file) + +TkOption.add('*Graph.Tile', bgTexture) +TkOption.add('*Label.Tile', bgTexture) +TkOption.add('*Frame.Tile', bgTexture) +TkOption.add('*Htext.Tile', bgTexture) +TkOption.add('*TileOffset', 0) +TkOption.add('*HighlightThickness', 0) +TkOption.add('*Element.ScaleSybols', false) +TkOption.add('*Element.Smooth', :linear) +TkOption.add('*activeLine.Color', 'yellow4') +TkOption.add('*activeLine.Fill', 'yellow') +TkOption.add('*activeLine.LineWidth', 0) +TkOption.add('*Element.Pixels', 3) +TkOption.add('*Graph.halo', '7i') + +if Tk.root.winfo_screenvisual != 'staticgray' + TkOption.add('*print.background', 'yellow') + TkOption.add('*quit.background', 'red') +end + +length = 250000 +graph = Tk::BLT::Graph.new(:title=>"Scatter Plot\n#{length} points") +graph.xaxis_configure(:loose=>false, :title=>'X Axis Label') +graph.yaxis_configure(:title=>'Y Axis Label') +graph.legend_configure(:activerelief=>:sunken, :background=>'') + +Tk::BLT::Table.add(Tk.root, graph, [0,0], :fill=>:both) + +v_x = Tk::BLT::Vector.new(length) +v_y = Tk::BLT::Vector.new(length) +v_x.expr("random(#{v_x})") +v_y.expr("random(#{v_y})") +v_x.sort(v_y) + +plot = Tk::BLT::PlotComponent::Element.new(graph, :symbol=>:square, + :color=>'green4', :fill=>'green2', + :linewidth=>0, :outlinewidth=>1, + :pixels=>4, :label=>'plot', + :xdata=>v_x, :ydata=>v_y) + +Tk.root.minsize(0, 0) + +#graph.zoom_stack +#graph.crosshairs +#graph.active_legend +#graph.closest_point +Tk::BLT.zoom_stack(graph) +Tk::BLT.crosshairs(graph) +Tk::BLT.active_legend(graph) +Tk::BLT.closest_point(graph) + +Tk::BLT::Busy.hold(graph) +Tk.update +Tk::BLT::Busy.release(graph) + +Tk.mainloop diff --git a/ext/tk/sample/tkextlib/blt/graph7b.rb b/ext/tk/sample/tkextlib/blt/graph7b.rb new file mode 100644 index 0000000000..c589f18d86 --- /dev/null +++ b/ext/tk/sample/tkextlib/blt/graph7b.rb @@ -0,0 +1,41 @@ +#!/usr/bin/env ruby +require 'tk' +require 'tkextlib/blt' + +length = 250000 +graph = Tk::BLT::Graph.new(:title=>"Scatter Plot\n#{length} points") +graph.xaxis_configure(:loose=>false, :title=>'X Axis Label') +graph.yaxis_configure(:title=>'Y Axis Label') +graph.legend_configure(:activerelief=>:sunken, :background=>'') + +Tk::BLT::Table.add(Tk.root, graph, [0,0], :fill=>:both) + +x = Array.new(length) +y = Array.new(length) +(0...length).each{|i| + x[i] = rand + y[i] = rand +} + +plot = Tk::BLT::PlotComponent::Element.new(graph, :symbol=>:square, + :color=>'green4', :fill=>'green2', + :linewidth=>0, :outlinewidth=>1, + :pixels=>4, :label=>'plot', + :xdata=>x, :ydata=>y) + +Tk.root.minsize(0, 0) + +#graph.zoom_stack +#graph.crosshairs +#graph.active_legend +#graph.closest_point +Tk::BLT.zoom_stack(graph) +Tk::BLT.crosshairs(graph) +Tk::BLT.active_legend(graph) +Tk::BLT.closest_point(graph) + +Tk::BLT::Busy.hold(graph) +Tk.update +Tk::BLT::Busy.release(graph) + +Tk.mainloop diff --git a/ext/tk/sample/tkextlib/blt/graph7c.rb b/ext/tk/sample/tkextlib/blt/graph7c.rb new file mode 100644 index 0000000000..495b66f4af --- /dev/null +++ b/ext/tk/sample/tkextlib/blt/graph7c.rb @@ -0,0 +1,45 @@ +#!/usr/bin/env ruby +require 'tk' +require 'tkextlib/blt' + +length = 250000 +graph = Tk::BLT::Graph.new(:title=>"Scatter Plot\n#{length} points") +graph.xaxis_configure(:loose=>false, :title=>'X Axis Label') +graph.yaxis_configure(:title=>'Y Axis Label') +graph.legend_configure(:activerelief=>:sunken, :background=>'') + +Tk::BLT::Table.add(Tk.root, graph, [0,0], :fill=>:both) + +v_x = Tk::BLT::Vector.new(length) +v_y = Tk::BLT::Vector.new(length) +x = Array.new(length) +y = Array.new(length) +(0...length).each{|i| + x[i] = rand + y[i] = rand +} +v_x.set(x) +v_y.set(y) + +plot = Tk::BLT::PlotComponent::Element.new(graph, :symbol=>:square, + :color=>'green4', :fill=>'green2', + :linewidth=>0, :outlinewidth=>1, + :pixels=>4, :label=>'plot', + :xdata=>v_x, :ydata=>v_y) + +Tk.root.minsize(0, 0) + +#graph.zoom_stack +#graph.crosshairs +#graph.active_legend +#graph.closest_point +Tk::BLT.zoom_stack(graph) +Tk::BLT.crosshairs(graph) +Tk::BLT.active_legend(graph) +Tk::BLT.closest_point(graph) + +Tk::BLT::Busy.hold(graph) +Tk.update +Tk::BLT::Busy.release(graph) + +Tk.mainloop diff --git a/ext/tk/sample/tkextlib/blt/images/buckskin.gif b/ext/tk/sample/tkextlib/blt/images/buckskin.gif new file mode 100644 index 0000000000000000000000000000000000000000..e2d7be9d6280f77925a171b3fcfc8c9a53ac4d95 GIT binary patch literal 7561 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 D1jcKn literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/blt/images/qv100.t.gif b/ext/tk/sample/tkextlib/blt/images/qv100.t.gif new file mode 100644 index 0000000000000000000000000000000000000000..1e738ee86bbf7ba9366f6905eb5e8e6d12534330 GIT binary patch literal 2694 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 Gr~dJIl literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/blt/images/sample.gif b/ext/tk/sample/tkextlib/blt/images/sample.gif new file mode 100644 index 0000000000000000000000000000000000000000..1d8a4010c38cbe2d487433459f389e5e224ec2ad GIT binary patch literal 186103 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

f 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, :label=>'foo') +plot.data([[1.0, 3.4], [1.1, 2.8], [1.2, 3.1], [1.4, 2.9]].flatten) + +Tk.mainloop diff --git a/ext/tk/sample/tkextlib/blt/plot1b.rb b/ext/tk/sample/tkextlib/blt/plot1b.rb new file mode 100644 index 0000000000..eb41e361f9 --- /dev/null +++ b/ext/tk/sample/tkextlib/blt/plot1b.rb @@ -0,0 +1,10 @@ +#!/usr/bin/env ruby +require 'tk' +require 'tkextlib/blt' + +graph = Tk::BLT::Graph.new.pack +plot = graph.element_create +plot.configure(:linewidth=>0, :label=>'foo', + :data=>[[1.0, 3.4], [1.1, 2.8], [1.2, 3.1], [1.4, 2.9]].flatten) + +Tk.mainloop diff --git a/ext/tk/sample/tkextlib/blt/readme.txt b/ext/tk/sample/tkextlib/blt/readme.txt new file mode 100644 index 0000000000..fe12dd88a3 --- /dev/null +++ b/ext/tk/sample/tkextlib/blt/readme.txt @@ -0,0 +1,2 @@ +The scripts and image files in this directory are based on demo files +of Tcl/Tk's BLT extention. diff --git a/ext/tk/sample/tkextlib/blt/scripts/stipples.rb b/ext/tk/sample/tkextlib/blt/scripts/stipples.rb new file mode 100644 index 0000000000..47f3c4d063 --- /dev/null +++ b/ext/tk/sample/tkextlib/blt/scripts/stipples.rb @@ -0,0 +1,156 @@ +$stipples = {} unless $stipples + +$stipples['bdiagonal1'] = Tk::BLT::Bitmap.new(<file) +else + fail RuntimeError, 'no image file' +end + +width = src.width +height = src.height + +TkOption.add('*Label.font', '*helvetica*10*') +TkOption.add('*Label.background', 'white') + +l_img0 = TkLabel.new(:image=>src) +l_hdr0 = TkLabel.new(:text=>"#{width} x #{height}") +l_ftr0 = TkLabel.new(:text=>'100%') +Tk.root.background('white') + +(2..10).each{|i| + iw = width/i + ih = height/i + r = '%6g'%(100.0/i) + dst = TkPhotoImage.new(:width=>iw, :height=>ih) + Tk::BLT::Winop.image_resample(src, dst, :sinc) + l_hdr = TkLabel.new(:text=>"#{iw} x #{ih}") + l_ftr = TkLabel.new(:text=>"#{r}%") + l_img = TkLabel.new(:image=>dst) + Tk::BLT::Table.add(Tk.root, + [0,i], l_hdr, + [1,i], l_img, + [2,i], l_ftr) + Tk.update +} + +Tk.mainloop diff --git a/ext/tk/sample/tkextlib/blt/winop2.rb b/ext/tk/sample/tkextlib/blt/winop2.rb new file mode 100644 index 0000000000..1f674ee893 --- /dev/null +++ b/ext/tk/sample/tkextlib/blt/winop2.rb @@ -0,0 +1,28 @@ +#!/usr/bin/env ruby +require 'tk' +require 'tkextlib/blt' + +file = File.join(File.dirname(File.expand_path(__FILE__)), + 'images', 'qv100.t.gif') +if File.exist?(file) + src = TkPhotoImage.new(:file=>file) +else + fail RuntimeError, 'no image file' +end + +width = src.width +height = src.height + +TkOption.add('*Label.font', '*helvetica*10*') +TkOption.add('*Label.background', 'white') + +[0, 90, 180, 270, 360, 45].each_with_index{|r, i| + dest = TkPhotoImage.new + Tk::BLT::Winop.image_rotate(src, dest, r) + l_txt = TkLabel.new(:text=>"#{r} degrees") + l_img = TkLabel.new(:image=>dest) + Tk::BLT::Table.add(Tk.root, [0,i], l_img, [1,i], l_txt) + Tk.update +} + +Tk.mainloop diff --git a/ext/tk/sample/tkextlib/treectrl/bitmaps.rb b/ext/tk/sample/tkextlib/treectrl/bitmaps.rb new file mode 100644 index 0000000000..c621e61fdc --- /dev/null +++ b/ext/tk/sample/tkextlib/treectrl/bitmaps.rb @@ -0,0 +1,75 @@ +# +# Demo: Bitmaps +# +def demoBitmaps(t) + if (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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/ext/tk/sample/tkextlib/treectrl/demo.rb b/ext/tk/sample/tkextlib/treectrl/demo.rb new file mode 100644 index 0000000000..1f822a6548 --- /dev/null +++ b/ext/tk/sample/tkextlib/treectrl/demo.rb @@ -0,0 +1,1256 @@ +#!/usr/bin/env ruby + +require 'tk' +require 'tkextlib/treectrl' + +$ScriptDir = File.dirname(File.expand_path(__FILE__)) + +$HasColumnCreate = Tk::TreeCtrl::HasColumnCreateCommand + +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() + 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| + pat = "#{pat}.gif" + unless TkImage.names.find{|img| (name = @images.key(img)) && File.fnmatch(pat, name)} + Dir.glob(File.join(@ScriptDir, 'pics', pat)).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.eval('.console conf -height 8') + menuspec[0] << ['Console', proc{ + if TkComm.bool(TkConsole.eval('winfo ismapped .')) + TkConsole.hide + else + TkConsole.show + end + }] + end + menuspec[0] << ['View Source', proc{toggle_source_window()}] + menuspec[0] << ['Quit', proc{exit}] + Tk.root.add_menubar(menuspec) + end + + def make_source_window + @src_top = TkToplevel.new + f = TkFrame.new(@src_top, :borderwidth=>0) + case @thisPlatform + when 'macintosh', 'macos' + font = TkFont.new(['Geneva', 9]) + when 'unix' + font = TkFont.new(['Courier', -12]) + else + font = TkFont.new(['Courier', 9]) + end + + @src_txt = TkText.new(f, :font=>font, :tabs=>font.measure('1234'), + :wrap=>:none) + xscr = @src_txt.xscrollbar(TkScrollbar.new(f)) + yscr = @src_txt.yscrollbar(TkScrollbar.new(f)) + + f.pack(:expand=>true, :fill=>:both) + f.grid_columnconfigure(0, :weight=>1) + f.grid_rowconfigure(0, :weight=>1) + @src_txt.grid(:row=>0, :column=>0, :sticky=>:news) + xscr.grid(:row=>1, :column=>0, :sticky=>:we) + yscr.grid(:row=>0, :column=>1, :sticky=>:ns) + + @src_top.protocol('WM_DELETE_WINDOW', proc{@src_top.withdraw}) + @src_top.geometry('-0+0') + @src_top.withdraw + end + + def show_source(file) + @src_top.title("Demo Source: #{file}") + @src_txt.value = IO.read(File.join(@ScriptDir, file)) + @src_txt.set_insert('1.0') + end + + def toggle_source_window + if @src_top.winfo_mapped? + @src_top.withdraw + else + @src_top.deiconify + end + end + + def tree_plus_scrollbars_in_a_frame(parent, h, v) + f = TkFrame.new(parent, :borderwidth=>1, :relief=>:sunken) + case @thisPlatform + when 'macintosh' + font = TkFont.new(['Geneva', 9]) + when 'macos' + font = TkFont.new(['Lucida Grande', 11]) + when 'unix' + font = TkFont.new(['Helvetica', -12]) + else + # There is a bug on my Win98 box with Tk_MeasureChars() and + # MS Sans Serif 8. + font = TkFont.new(['MS Sans', 8]) + end + + tree = Tk::TreeCtrl.new(f, :highlightthickness=>0, + :borderwidth=>0, :font=>font) + tree[:xscrollincrement] = 20 + tree.debug_configure(:enable=>false, :display=>false) + + if h + h_scr = TkScrollbar.new(f, :orient=>:horizontal, + :command=>proc{|*args| tree.xview(*args)}) + tree.notify_bind(h_scr, 'Scroll-x', + proc{|w, l, u| w.set(l, u)}, '%W %l %u') + h_scr.bind('ButtonPress-1', proc{tree.set_focus}) + end + + if v + v_scr = TkScrollbar.new(f, :orient=>:vertical, + :command=>proc{|*args| tree.yview(*args)}) + tree.notify_bind(v_scr, 'Scroll-y', + proc{|w, l, u| w.set(l, u)}, '%W %l %u') + v_scr.bind('ButtonPress-1', proc{tree.set_focus}) + end + + f.grid_columnconfigure(0, :weight=>1) + f.grid_rowconfigure(0, :weight=>1) + tree.grid(:row=>0, :column=>0, :sticky=>:news) + h_scr.grid(:row=>1, :column=>0, :sticky=>:we) if h + v_scr.grid(:row=>0, :column=>1, :sticky=>:ns) if v + + [f, tree] + end + + def make_main_window + Tk.root.title('Tk::TreeCtrl Demo') + + case @thisPlatform + when 'macintosh', 'macosx' + Tk.root.geometry('+40+40') + else + Tk.root.geometry('+0+30') + end + + pane1 = TkPanedWindow.new(:orient=>:vertical, :borderwidth=>0) + pane2 = TkPanedWindow.new(:orient=>:horizontal, :borderwidth=>0) + + # Tree + scrollbar: demos + f1, @tree1 = tree_plus_scrollbars_in_a_frame(nil, false, true) + @tree1.configure(:showbuttons=>false, :showlines=>:false, + :showroot=>false, :height=>100) + if $HasColumnCreate + @tree1.column_create(:text=>'List of Demos', + :expand=>true, :button=>false) + else + @tree1.column_configure(0, :text=>'List of Demos', + :expand=>true, :button=>false) + end + + # Tree + scrollbar: styles + elements in list + f4, @tree4 = tree_plus_scrollbars_in_a_frame(nil, false, true) + @tree4.configure(:showroot=>false, :height=>140) + if $HasColumnCreate + @tree4.column_create(:text=>'Elements and Styles', + :expand=>true, :button=>false) + else + @tree4.column_configure(0, :text=>'Elements and Styles', + :expand=>true, :button=>false) + end + + # Tree + scrollbar: styles + elements in selected item + f3, @tree3 = tree_plus_scrollbars_in_a_frame(nil, false, true) + @tree3.configure(:showroot=>false) + if $HasColumnCreate + @tree3.column_create(:text=>'Styles in Item', + :expand=>true, :button=>false) + else + @tree3.column_configure(0, :text=>'Styles in Item', + :expand=>true, :button=>false) + end + + pane1.add(f1, f4, f3, :height=>150) + pane1.pack(:expand=>true, :fill=>:both) + + # Frame on right + f2_base = TkFrame.new + + # Tree + scrollbars + f2, @tree2 = tree_plus_scrollbars_in_a_frame(f2_base, true, true) + @tree2.configure(:indent=>19) + @tree2.debug_configure(:enable=>false, :display=>true, + :erasecolor=>'pink', :displaydelay=>30) + + # Give it a big border to debug drawing + @tree2.configure(:borderwidth=>6, :relief=>:ridge, :highlightthickness=>3) + + f2_base.grid_columnconfigure(0, :weight=>1) + f2_base.grid_rowconfigure(0, :weight=>1) + f2.grid(:row=>0, :column=>0, :sticky=>:news, :pady=>0) + + pane2.add(pane1, :width=>200) + pane2.add(f2_base, :width=>450) + + pane2.pack(:expand=>true, :fill=>:both) + + ### + # A treectrl widget can generate the following built-in events: + # 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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[:sqeeeze].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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + @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 + + scriptDir = @ScriptDir + + thisPlatform = @thisPlatform + + randomN = @RandomN + + images = @images + sel_images = @sel_images + + systemButtonFace = @SystemButtonFace + systemHighlight = @SystemHighlight + systemHighlightText = @SystemHighlightText + + proc_disp_styles_in_item = proc{|item| + master.instance_eval{ display_styles_in_item(item) } + } + + @demo_scripts.instance_eval{ + @master = master + + @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) + eval(IO.readlines(file).join, _get_binding()) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + @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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + @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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + @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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + @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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + item3 = @tree3.item_create(:button=>true) + else + item3 = @tree3.item_create + @tree3.item_hasbutton(item3, true) + end + if (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + @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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + @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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + @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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + @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/ext/tk/sample/tkextlib/treectrl/explorer.rb b/ext/tk/sample/tkextlib/treectrl/explorer.rb new file mode 100644 index 0000000000..8ee002ef9e --- /dev/null +++ b/ext/tk/sample/tkextlib/treectrl/explorer.rb @@ -0,0 +1,442 @@ + +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) + 2 + hehght = 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 + if FileTest.executable?(file) + img = 'small-exe' + else + img = 'small-file' + end + 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 + if FileTest.executable?(file) + img = 'big-exe' + else + img = 'big-file' + end + 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 + if FileTest.executable?(file) + img = 'small-exe' + else + img = 'small-file' + end + 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/ext/tk/sample/tkextlib/treectrl/help.rb b/ext/tk/sample/tkextlib/treectrl/help.rb new file mode 100644 index 0000000000..01e075bdf8 --- /dev/null +++ b/ext/tk/sample/tkextlib/treectrl/help.rb @@ -0,0 +1,405 @@ +# +# Demo: Help contents +# +def demoHelpContents(t) + height = t.font.metrics(:linespace) + 2 + hehght = 18 if height < 18 + t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, + :itemheight=>height, :selectmode=>:browse) + + init_pics('help-*') + + if (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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=>[@SystemHighligh, ['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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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('Button1-Motion', + proc{|w, x, y| + if w.selection_get.length == 1 + if (TkPackage.vcompare(Tk::TreeCtrl.package_version, + '1.1') >= 0) + 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) + 2 + hehght = 18 if height < 18 + t.configure(:showroot=>false, :showbuttons=>false, :showlines=>false, + :itemheight=>height, :selectmode=>:browse) + + init_pics('help-*') + + if (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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('Button1-Motion', + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + w.item_collapse(item2) + else # TreeCtrl 1.0 + w.collapse(item2) + end + w.item_ancestors(item2).each{|i| + if (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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/ext/tk/sample/tkextlib/treectrl/imovie.rb b/ext/tk/sample/tkextlib/treectrl/imovie.rb new file mode 100644 index 0000000000..3c394fa125 --- /dev/null +++ b/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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 = t.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/ext/tk/sample/tkextlib/treectrl/layout.rb b/ext/tk/sample/tkextlib/treectrl/layout.rb new file mode 100644 index 0000000000..0ab65ac243 --- /dev/null +++ b/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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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/ext/tk/sample/tkextlib/treectrl/mailwasher.rb b/ext/tk/sample/tkextlib/treectrl/mailwasher.rb new file mode 100644 index 0000000000..b695db5104 --- /dev/null +++ b/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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.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' + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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/ext/tk/sample/tkextlib/treectrl/outlook-folders.rb b/ext/tk/sample/tkextlib/treectrl/outlook-folders.rb new file mode 100644 index 0000000000..e56ba3f889 --- /dev/null +++ b/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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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/ext/tk/sample/tkextlib/treectrl/outlook-newgroup.rb b/ext/tk/sample/tkextlib/treectrl/outlook-newgroup.rb new file mode 100644 index 0000000000..41b7fbb868 --- /dev/null +++ b/ext/tk/sample/tkextlib/treectrl/outlook-newgroup.rb @@ -0,0 +1,447 @@ +# +# Demo: Outlook Express newsgroup messages +# +def demoOutlookNewsgroup(t) + init_pics('outlook-*') + + height = t.font.metrics(:linespace) + 2 + hehght = 18 if height < 18 + t.configure(:itemheight=>height, :selectmode=>:browse, :showlines=>false, + :showroot=>false, :showrootbutton=>false, :showbuttons=>true) + + if (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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=>[ + @images['outlook-read-2Sel'], + ['selected', 'read', 'unread', '!open'], + @images['outlook-read-2'], ['read', 'unread', '!open'], + @images['outlook-readSel'], ['selected', 'read'], + @images['outlook-read'], ['read'], + @images['outlook-unreadSel'], ['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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + t.item_configure(item_i, :button=>true) + else # TreeCtrl 1.0 + t.item_hasbutton(item_i, true) + end + + # Collapse some messages + if (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + t.item_collapse(item_i) if rand(2) == 0 + else # TreeCtrl 1.0 + t.collapse(item_i) if rand(2) == 0 + end + end + + unless (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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) + 2 + hehght = 18 if height < 18 + t.configure(:itemheight=>height, :selectmode=>:browse, :showlines=>false, + :showroot=>false, :showrootbutton=>false, :showbuttons=>true) + + if (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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| + 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') + + t.notify_bind(t, 'Collapse-after', + proc{|w| + 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') + + (1...(msgCnt)).each{|i| + if rand(2) == 0 + if t.item_numchildren(i) > 0 + if (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + t.item_collapse(i) + else # TreeCtrl 1.0 + t.collapse(i) + end + end + end + } +end + +def anyUnreadDescendants(t, i) + itemList = [ t.item_firstchild(i) ] + while(itemList.length > 0) + 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/ext/tk/sample/tkextlib/treectrl/pics/big-dll.gif b/ext/tk/sample/tkextlib/treectrl/pics/big-dll.gif new file mode 100644 index 0000000000000000000000000000000000000000..09170c0e26ba2531a5f2bc82834c71894c792501 GIT binary patch literal 437 zcmZ?wbhEHbRA5kG*u($<#taN;3=A_F7|t*-{AU32jExn4vam8RFf-_YRDjer0qOdB zAgcclRP>)=|Ni~|ffP{9aSN?G|NKvCw(hjZ)?xU2O)ahGduVbNhikdstBkE`65Wcm zZRVVR9HR9@S1fE>yhz}Ba8QK|vxAqaRN|6Hufjzw)i1m%S>+qYe!(xDCt~*WONUrH zW>%fQ@Xf^KS@u5nQe80y#u$5+GVz9p;^-WbNt|6xab^inkwRjLLPkkRft9{~d3m{B zDM-Cua(=EtNj}irycC7}(h`N-{GwDn#?av40B7G22F3r}0iKS2kwB}B^bFWNa}(23 I85tR@0Zmb&GXMYp literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/big-exe.gif b/ext/tk/sample/tkextlib/treectrl/pics/big-exe.gif new file mode 100644 index 0000000000000000000000000000000000000000..e19aac1a2d6bf90a887bc77b9b1d0f3ac1ec1c88 GIT binary patch literal 368 zcmZ?wbhEHbRA5kG*u($<#taN;3=A_F7|t*-{AU32jExn4vam8RFf-_YRDjer0qOes zdIpC5|ABb_{{R1hGzc&^S?s#=Pv?Z^>b=4&hj#x@@L-WroRhI?ozBjU1*aH4znN7S zBWzOt+_0g*Vozt^i9pW7Ia=n8O(kAyqgJ24SbBPD+TyzgU$ynbPdqcQIvcxr{X6q- zY}2A2m+9Nq-~W8PuD;5{GIJA4Qd1P%J>3-2GILTD$`gwflJoP5ONvU9K@z3KnR)37p*g9E5Jiq) z9r;BHKA9z{Itpc(#hE2QMGA=}3K=CO1y=g{<>lpir6Bcs$@#eoCHX*e^HLP@OG^}T p^NUjT7(;`D1Dt(B7!?0=2Y5RAMFOoh(lcQ9%uP&BWn^Tq1^@RDjergO%1Z zfFMJCJ&^eS0;HPZ|9^)4`}h9`QmBCC%mojp)qBHVt?m4kpwYx~VD7yYZBr`CveyWB z{`C9w>Z;zX)tdLTza}&GdBht|dvS2u>SaP!lZrZwR2IBClDhT8gwp1_Z4=lV90dOL z%%8tjW^UZ(vt8T2ud)4cHQQaGiYxab^in zkwRjLLPkkRft9{~d3m{BDM-Cua(=EtNj}irycC7}(h`N-{GwDn#?av40B7G22F3r} Y0iKS2kwB}B^bFWNa}(2385tR@0R}#@tN;K2 literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/big-folder.gif b/ext/tk/sample/tkextlib/treectrl/pics/big-folder.gif new file mode 100644 index 0000000000000000000000000000000000000000..186c9749fde1c8405d5521a47c175ecdce93b820 GIT binary patch literal 459 zcmZ?wbhEHbRA5kG*u($<#taN;3=A_F7|t*-{AU32jExn4vam8RFfr(WRDjer18IGI zpftmT2@L1YC;UG@;s5^$|3AF{@Zkf*6f~0MXut{2)q5>o>$d-wKak3tH0On7M{?-0 z4I8&zE;#b>4xh{W{|*xZZa7NxpIB1VDX_O7AmpLRQYnsx^ea|trS`-+IqW_f${lC8 z^G|N{(yZVuulp`?7nZ$>oB!-=bwhk&a#3+ienNO_S!zjhNPTa4e`j4!P*v>gmh9Tx z{`8QHNxh936IM*uUzj&_@v4l98BMb%Y?xcLwqxC@#f5Rx_H1h2v^i?`z7BsE3B-P27WEi)%op**oz zAvr&z3%3<&78*C*j_gWVxhwa_sls2J73->N_*EDftO3BvSt9@d literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/folder-closed.gif b/ext/tk/sample/tkextlib/treectrl/pics/folder-closed.gif new file mode 100644 index 0000000000000000000000000000000000000000..0a064376c9755c2b3c9bf3ff4ee4efb40d593011 GIT binary patch literal 111 zcmZ?wbhEHbEd#T0gy@-H z1|5d34gQyMXLGw~^d&Mh#8}NtSQ@1Bao5J|!^>+f|2%heGw*5VFAQ7_ONw^-0QFh} E0G4Vdf&c&j literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/folder-open.gif b/ext/tk/sample/tkextlib/treectrl/pics/folder-open.gif new file mode 100644 index 0000000000000000000000000000000000000000..3fac27ffd99c45fcfe892b2e97b014859130d800 GIT binary patch literal 120 zcmZ?wbhEHb6kyEd#Sngw&Z| z8(5q&JMz0WvSyxjDp(R;+u%}?D#?(*!}q@A-ui&`y4?GxM6(o literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/help-book-closed.gif b/ext/tk/sample/tkextlib/treectrl/pics/help-book-closed.gif new file mode 100644 index 0000000000000000000000000000000000000000..0a0497bfa3df3e5236e11803a39df172a423849f GIT binary patch literal 115 zcmZ?wbhEHb6krfwP-0-vVE_UUy9r3wGt>jY{{8#^|NjpX2LomYk6kPW3U&&_g-i}Q zz3EzvaZQRUYcgk2$f{Wl&!+k5Ty8jUFWT?L?rF{j3Oq8)d)HO)n3^4H`#i-tPUYI_ JX%iV3tO1YQC+PqH literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/help-book-open.gif b/ext/tk/sample/tkextlib/treectrl/pics/help-book-open.gif new file mode 100644 index 0000000000000000000000000000000000000000..40656c51946bd18f917f79f514e5e2120965cad6 GIT binary patch literal 128 zcmZ?wbhEHb6krfwP-0-vVE_UUy9r3wGt>jY|Njj8_wWA?q`-jLH$wH+zorfDjvALb z->#W;=TdA$1P>E~hMf1Dc)>NfjC;7WE-(4Zw{hm$^6VEaTa^M@cqVkspI%U*nOAUm Y;oDayg61ZCShZMd_VFoOlo%PT0mS|?e*gdg literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/help-page.gif b/ext/tk/sample/tkextlib/treectrl/pics/help-page.gif new file mode 100644 index 0000000000000000000000000000000000000000..e1ce1d72f55647068380d431d3cd7f4e81b9d027 GIT binary patch literal 132 zcmZ?wbhEHb6krfwP-0+E{K>+~#lX&>!vF*zu_hp0UtiC_@c;jRhW-2ZgD5ay_N)-U z6X&{;;q;1TS5N&f4jQ^s6S%|~d*){D)Z*UBx~E7i?R0#vnBkmuwmrTECms}PtkCe3 c4?pGc>50O5hQ!lvgPb22RJiDQ3o%#&0M-;NCIA2c literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/imovie-01.gif b/ext/tk/sample/tkextlib/treectrl/pics/imovie-01.gif new file mode 100644 index 0000000000000000000000000000000000000000..5fd921555155e9463d722027e3ec97176d46d423 GIT binary patch literal 5406 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 literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/imovie-02.gif b/ext/tk/sample/tkextlib/treectrl/pics/imovie-02.gif new file mode 100644 index 0000000000000000000000000000000000000000..3d2d1c17c255fd629f544143c0a35f61c307d438 GIT binary patch literal 5912 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 MWN=Q5I|WSqUpmUGSO5S3 literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/imovie-03.gif b/ext/tk/sample/tkextlib/treectrl/pics/imovie-03.gif new file mode 100644 index 0000000000000000000000000000000000000000..9fccf12b512a6df718c892d1cbd1c26139525b41 GIT binary patch literal 4696 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 a-wVEcr=#Y(zvt_vj?1U&>$Jia5CA)K3oj4= literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/imovie-04.gif b/ext/tk/sample/tkextlib/treectrl/pics/imovie-04.gif new file mode 100644 index 0000000000000000000000000000000000000000..eff851c9bb78a4df14d27c2d3c202dd3de8736d2 GIT binary patch literal 5783 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 literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/imovie-05.gif b/ext/tk/sample/tkextlib/treectrl/pics/imovie-05.gif new file mode 100644 index 0000000000000000000000000000000000000000..ad00c827f673e5f9f21bebf085a2352b1536ad20 GIT binary patch literal 3238 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 V6UZ?hr?FbV;!*$r literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/internet-check-off.gif b/ext/tk/sample/tkextlib/treectrl/pics/internet-check-off.gif new file mode 100644 index 0000000000000000000000000000000000000000..e64866a394b797a4aabd7a701f1fee2f6f8dfdb2 GIT binary patch literal 70 zcmZ?wbhEHb6krfw00JEl0b(}*>Hq)#GpY9UXC8Q4J1<3WMOXfU(^>l}#W}Q=WOSt# TWhI)ex*U9VLiclbMh0sDt`-;o literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/internet-check-on.gif b/ext/tk/sample/tkextlib/treectrl/pics/internet-check-on.gif new file mode 100644 index 0000000000000000000000000000000000000000..cf652beff2e34919e62cb23c891bbe549b81f732 GIT binary patch literal 76 zcmZ?wbhEHb6krfw00JEl0b(}*>Hq)#GimqqXC8Q4J1<3WMc34&r`1leCTy)ts;p9c ak&>RiFZRpKg=zl$EALTI3F+jB|p)QYWG0;}Hq)#Gb#7Hq)#GpY6TuRP7hAJt%@)lpD&UG7~)f<)8fl)xwI U+h!jx+wd)HLyh;ZI0go50IkIslmGw# literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/internet-search.gif b/ext/tk/sample/tkextlib/treectrl/pics/internet-search.gif new file mode 100644 index 0000000000000000000000000000000000000000..1f9a0477019039538d9aa91da1442f5b75395b47 GIT binary patch literal 114 zcmZ?wbhEHb6krfwP-0-vVE_UUy9r3w15tfF!~g&P85sUE{NKNSKak06U!leGt6;8S zY)z7%an6~L6O|D=c-b^NGs-!2)mMA>FdYm%?=tZk(8lP%5Eyi| zKyCVyR7GRA>6dL+yqfnWyr?DN{x_bccT4Oo?({#G;%VLAkx2{;)&R$w BCPe@M literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/mac-collapse.gif b/ext/tk/sample/tkextlib/treectrl/pics/mac-collapse.gif new file mode 100644 index 0000000000000000000000000000000000000000..81302c80c1db6214da8c28761933f0effb99f2c9 GIT binary patch literal 275 zcmZ?wbhEHb6krfw*u($<#taN;3=A_F7|t*-{AU32jExn4vam8RurcU>RDjer0qL}~ zGaVfryLa!NIrIOSGyj1AD9EguvFpx1gHxW8J1m&lyZ*B%@W>W70MHf6_WGwic5-0lR*-t#hH2O z3ZXfvi4aAOU>*5I3O<=7sX7W}nZ=nUKt&3PB?=iOB?VUc`sL;2dZi%sddc~@3MKhK ybMsOZ@=Hq;a`TH)^%z5gg9Ds>Ll_kQa|d`j`b7e*HqtX-_smU9Pi16eum%8ow^?ie literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/mac-expand.gif b/ext/tk/sample/tkextlib/treectrl/pics/mac-expand.gif new file mode 100644 index 0000000000000000000000000000000000000000..0a2cd80040c01e3412b0be899b592ab4c83d777b GIT binary patch literal 277 zcmZ?wbhEHb6krfw*u($<#taN;3=A_F7|t*-{AU32jExn4vam8RurcU>RDjer0qL}~ zGaVfryLa!NIrIOSGyj1AD9EgyvFpyifW{XGmT*t$Hhnnpdnv0UOG4+~#lXy+~#lXy+~#lX&>!vF*zu_h3so}s?Je*gac|Ns97alwGuzhc)N zZ=fdC6vN4eDr`(HEy_n3m^nEU%lVYOiwbisEx@w!7Sq<795u3s+S^(D>|Esy gcD6ieI(3}om|(=Ft`kSB1ruHF&rZJU!N6b*06kwR=l}o! literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/outlook-draft.gif b/ext/tk/sample/tkextlib/treectrl/pics/outlook-draft.gif new file mode 100644 index 0000000000000000000000000000000000000000..f19585050f360b1f5bb320d8c5ca94dfd3e5a342 GIT binary patch literal 134 zcmZ?wbhEHb6krfwP-0+E{K>+~#lX&>!vF*zu_hp04@C9#|Nk@W-@pGqkOBi{?}}Y_ z!VQ`{)Az9U>^Qj9^+E20@M)J5%APwoG^M3Iea*+Dm|s{a+|+dL%4vbTrrthwCYeTo d>z+;)VOkQtr5!&*9Pggjd80A=d>0FYH2}_ZFZKWc literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/outlook-folder.gif b/ext/tk/sample/tkextlib/treectrl/pics/outlook-folder.gif new file mode 100644 index 0000000000000000000000000000000000000000..b3f733563b3c60f69e7697bbec47afc467a08668 GIT binary patch literal 133 zcmZ?wbhEHb6krfwP-0+E{K>+~#lX&>!vF*zu_hp0Utj8r?ugJBX#)5~IW!_ep;ryL9;K4pU)(y)a)J=CxbNrF9t0+ literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/outlook-group.gif b/ext/tk/sample/tkextlib/treectrl/pics/outlook-group.gif new file mode 100644 index 0000000000000000000000000000000000000000..29ad9b466e9653bcad907685f7de59e4d86ff12d GIT binary patch literal 144 zcmZ?wbhEHb6krfwP-0+E{K>+~#lX&>!vF*zu_hp04@C9#{}~wm|7Y00fB%0V#lXNE znz4)LK!N4gsJU%ZyfSrXneiN3tf?5mlg%J9bC%G-9}FuOyw(v2Fglo&GI>Qy*R2Dp soQk~C$2Tvj%v&%gXrX~>g5sr~h{>@WdtT(bY{<<&E!SQ%iGjfy0ED?Si~s-t literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/outlook-inbox.gif b/ext/tk/sample/tkextlib/treectrl/pics/outlook-inbox.gif new file mode 100644 index 0000000000000000000000000000000000000000..f41d80444408c144f46bbddd939d527bc0e3e82e GIT binary patch literal 133 zcmZ?wbhEHb6krfwP-0+E{K>+~#lX&>!vF*zu_hp04@C9#|Nk@W-@pGqkOBi{uZmrF z!VSb2RB9$2()##h_ScMSR~kcB1+i=K2*z+6kl<>y@&9JRvOruvgpr4V=?+`4j6jb} cgzl!MRW=LG8$L3e=+UZYQBpWVoRh&C0LAAikpKVy literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/outlook-local.gif b/ext/tk/sample/tkextlib/treectrl/pics/outlook-local.gif new file mode 100644 index 0000000000000000000000000000000000000000..0c74970d3222b2820f914701518d6c78fdf7b28c GIT binary patch literal 146 zcmZ?wbhEHb6krfwP-0+E{K>+~#lX&>!vF*zu_hp0Utj+~#lX*?!vF*zv1Sm1p`M|>z8*+{i2n@#|NjS4P#P?c zM6g5~oSfOSG(t?8>7=J1mz%;&5l4|$g^H{-O!B|gI;OlYIk9NUVa1EDCCYakX1K`w zv|!RQzOEylhHKIm1L0pWpIZO_2HWFm81^~Ih BHO&A3 literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/outlook-outbox.gif b/ext/tk/sample/tkextlib/treectrl/pics/outlook-outbox.gif new file mode 100644 index 0000000000000000000000000000000000000000..c7e80527a0af2c6d9cbb6b553a0aed5af61b03ed GIT binary patch literal 136 zcmZ?wbhEHb6krfwP-0+E{K>+~#lX&>!vF*zu_h3s9t8I9-~a#re-IZ8n0-BVamn;B z8qDDexO8yid13V=KDU-6_NJBzRo$sOk2Dm1+FK1d3sVai9~@znH(m3_G>lp4^dk3F zn`;>UFeo=FB$@B=O|oP@wBh&JDW}x*JYv22jb2R3oN{D^BeVE2(eCy4nydD{6RP-N zkuSu^p!lyLBqOs}Au%sAH?br&MZw+EO(88aCsm<5u~;EFKd-o?s5BWQQCggtm#z?+ zlbQ%orZS(2)wP?lMoSprm~kXWLSQBqQ1rLSLJUanUPQm>bspQ})k4>UI~ vMIpbmL?Ji7C{>R!G&nfG**Ani@jrKfr=wpa&}t(+19s2c#Pn1~Mh0sDn|5rR literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/outlook-read.gif b/ext/tk/sample/tkextlib/treectrl/pics/outlook-read.gif new file mode 100644 index 0000000000000000000000000000000000000000..a6f956207a247669246eb4958857024e8aae7c37 GIT binary patch literal 304 zcmZ?wbhEHb6krfw*u($<#taN;3=A_F7|t*-{AU32jExn4vam8RFfr(WRDjer0qOes z`WFlg`}gnv|NlQkCy-=z(%7XVsJqI6X#($_Zgs{xpL&*D4RHCDyKuP>^NP7wnVFq^ z_J7#Bnt4W_qb6&+QiA^VqAPC4)t>Hf@hiHK6MXEco)ClLzlM;E%wmPayv*FhlGGFh zcTYEkw9K4Th4RE=h2;Fa;*z4$WROH@ab{k+LTFBEB1DlRSVw-5f=^~is*XZgW^rZ- zP?17ni9$w6Nr9EVetCJhUMWbuUUGh}LP+~#lX&>!vF*zu_h3Mp}ro3>;L~}*uQ`Oe;~!c!0cJE z>rT3X7sHZXk!w3QD;`;v8SOa3^}FbW2m6>^H>!X1Y6@U1HH=YaIK{>((c8xND!t+F d6t!orM?RliH!np|m1)u*f%XcYFck&{YXDC@E;j%G literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/outlook-server.gif b/ext/tk/sample/tkextlib/treectrl/pics/outlook-server.gif new file mode 100644 index 0000000000000000000000000000000000000000..c950845d625b81db63c7c3f7814f7db8efdf7794 GIT binary patch literal 163 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 OJ+fI`6f*}5Q2#$qiTIlU literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/small-dll.gif b/ext/tk/sample/tkextlib/treectrl/pics/small-dll.gif new file mode 100644 index 0000000000000000000000000000000000000000..d8875ec23f5b550b3d12e3b0aa1c750383efeb56 GIT binary patch literal 311 zcmZ?wbhEHb6krfw*u($<#taN;3=A_F7|t*-{AU32jExn4vam8RFf-_YRDjer0qOdB zAgcclRP>)=|Ni~|ffP`Ur^Ti_p95xirVD;J>D7Hu(4A35plj|*Uq^<5)>S?X55o#2 z1P*+P+Qh5y?dQ`lVNd@LR_EMU7aiOw`FELP$g3qw-S$6NvBpJjwGe~izlM;E%wmPa zyv*FhlGGFhcTYEkw9K4Th4RE=h2;Fa;*z4$WROH@ab{k+LTFBEB1DlRSVw-5f=^~i zs*XZgW^rZ-P?17ni9$w6Nr9EVetCJhUMWbuUUGh}LP+~#lX&>!vF*zu_hp0UtiC_upbEi|NjpX2Lon{id}ca z4Nh^k@BP6h(DozYNA6q=0fw$g%ukD$70+)ubIqdg`ImFIH{3t-UHOy8I`M>)IaZ8) JFO(P=tN|+tC^P^7 literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/pics/small-file.gif b/ext/tk/sample/tkextlib/treectrl/pics/small-file.gif new file mode 100644 index 0000000000000000000000000000000000000000..f340662879b0be2da758413c5e7a99dc8a358994 GIT binary patch literal 338 zcmZ?wbhEHb6krfw*u($<#taN;3=A_F7|t*-{AU32jExn4vam8RurTO=RDjergBbM; z_4V~YH7`Kw82Q6fm;Yb4+LDh3g*5D<(WKlZ-L{6 zM(NWQx%XSvByX5kaFvOzaPy;V4WDZ~J}L)aaz;AJG?blw8niE=fQdozUqeVnX0bwI zUS@7$NotCMyQiB%T4qkFLV04bLUMjyaY<2WGDxDdI5RI@Av7m75u(TutRufj!6&mM zRY##LvpBN^s7N8PL?NT3q`*pFzr4I$uN0(SFF8L~p(Gz@ZeEH)erbt9Zhld!9%E>5 haDcOK2!rB(?f_3mzeu3fMtTP9p1FzXsf>&a)&RSDYM&LZ&2L`KFHe~KNw{Z30 z@8Oe;;=I9^l|#mZm}0P*Y?@&Et; literal 0 HcmV?d00001 diff --git a/ext/tk/sample/tkextlib/treectrl/random.rb b/ext/tk/sample/tkextlib/treectrl/random.rb new file mode 100644 index 0000000000..05b6c21236 --- /dev/null +++ b/ext/tk/sample/tkextlib/treectrl/random.rb @@ -0,0 +1,505 @@ +# +def random_N + @RandomN[0] || 500 +end + +# +# Demo: random N items +# +def demoRandom(t) + init_pics('folder-*', 'small-*') + + height = t.font.metrics(:linespace) + 2 + hehght = 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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] + item_j = nil + numChildren = t.item_numchildren(item_i) + if numChildren > 0 + if (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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'] = '' + if id.empty? + # Click outside any item + + elsif id[0] == 'header' + # Click in header + Tk::TreeCtrl::BindCallback.buttonPress1(w, x, y) + + else + # Click in item + where, item, arg1, arg2, arg3, arg4 = id + case arg1 + when 'button' + if (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + t.item_toggle(item) + else # TreeCtrl 1.0 + t.toggle(item) + end + + when 'line' + if (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 == e} + 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 == item} + 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 == ancestor} + ignore = true + break + end + } + next if ignore + + # Update the old parent of this moved item later + unless parentList.find{|val| val == item} + 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 = [ t.item_firstchild(item) ] + while itemList.length > 0 + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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 (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) + 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?(:auroscan, :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[2] if delay.kind_of?(Array) + else + delay = delay[1] if delay.kind_of?(Array) + end + case @Priv['buttonMode'] + when 'drag', 'marquee' + randomMotion(t, x, y) + end + @Priv[:autoscan, :scanning, 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/ext/tk/sample/tkextlib/treectrl/readme.txt b/ext/tk/sample/tkextlib/treectrl/readme.txt new file mode 100644 index 0000000000..9f26ac069c --- /dev/null +++ b/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 extention. diff --git a/ext/tk/sample/tkextlib/treectrl/www-options.rb b/ext/tk/sample/tkextlib/treectrl/www-options.rb new file mode 100644 index 0000000000..2b0f75e85e --- /dev/null +++ b/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