From 20b20bb72a77e1f8669c5983b17458d77392184f Mon Sep 17 00:00:00 2001 From: nagai Date: Thu, 22 May 2008 19:24:24 +0000 Subject: [PATCH] * ext/tk/tcltklib.c, ext/tk/tkutil/tkutil.c: fix memory leak. * ext/tk/lib/tk.rb: avoid trouble when finalize TclTkIp. * ext/tk/lib/tk.rb, ext/tk/lib/tk/*: help to fix troubles when use Ttk widgets on old Tk scripts. * ext/tk/sample/*: update and add demo stcipts. some of them are introduction about new features of Tcl/Tk8.5. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@16544 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 12 + ext/tk/lib/multi-tk.rb | 2 +- ext/tk/lib/tk.rb | 123 ++++- ext/tk/lib/tk/canvas.rb | 9 + ext/tk/lib/tk/canvastag.rb | 3 + ext/tk/lib/tk/composite.rb | 52 ++ ext/tk/lib/tk/image.rb | 19 +- ext/tk/lib/tk/itemconfig.rb | 57 ++- ext/tk/lib/tk/itemfont.rb | 33 +- ext/tk/lib/tk/menu.rb | 13 +- ext/tk/lib/tk/namespace.rb | 14 + ext/tk/lib/tk/panedwindow.rb | 23 +- ext/tk/lib/tk/text.rb | 34 +- ext/tk/lib/tk/textimage.rb | 4 + ext/tk/lib/tk/texttag.rb | 3 + ext/tk/lib/tk/textwindow.rb | 3 + ext/tk/lib/tkextlib/blt/component.rb | 101 +++- ext/tk/lib/tkextlib/blt/htext.rb | 1 + ext/tk/lib/tkextlib/blt/table.rb | 17 +- ext/tk/lib/tkextlib/blt/tabset.rb | 4 + ext/tk/lib/tkextlib/blt/ted.rb | 7 +- ext/tk/lib/tkextlib/blt/treeview.rb | 24 +- ext/tk/lib/tkextlib/blt/unix_dnd.rb | 10 +- ext/tk/lib/tkextlib/blt/watch.rb | 19 +- ext/tk/lib/tkextlib/bwidget/dialog.rb | 7 + ext/tk/lib/tkextlib/bwidget/dynamichelp.rb | 7 + ext/tk/lib/tkextlib/bwidget/listbox.rb | 3 + ext/tk/lib/tkextlib/bwidget/messagedlg.rb | 11 + ext/tk/lib/tkextlib/bwidget/tree.rb | 3 + ext/tk/lib/tkextlib/bwidget/widget.rb | 12 +- ext/tk/lib/tkextlib/iwidgets/buttonbox.rb | 5 +- ext/tk/lib/tkextlib/iwidgets/checkbox.rb | 5 +- ext/tk/lib/tkextlib/iwidgets/dialogshell.rb | 5 +- ext/tk/lib/tkextlib/iwidgets/menubar.rb | 5 +- ext/tk/lib/tkextlib/iwidgets/messagebox.rb | 5 +- ext/tk/lib/tkextlib/iwidgets/notebook.rb | 5 +- ext/tk/lib/tkextlib/iwidgets/panedwindow.rb | 5 +- ext/tk/lib/tkextlib/iwidgets/radiobox.rb | 5 +- ext/tk/lib/tkextlib/iwidgets/scrolledtext.rb | 23 +- ext/tk/lib/tkextlib/iwidgets/tabnotebook.rb | 5 +- ext/tk/lib/tkextlib/iwidgets/tabset.rb | 5 +- ext/tk/lib/tkextlib/tcllib/getstring.rb | 5 +- ext/tk/lib/tkextlib/tcllib/swaplist.rb | 5 +- ext/tk/lib/tkextlib/tcllib/tablelist_core.rb | 16 +- ext/tk/lib/tkextlib/tile/dialog.rb | 16 +- ext/tk/lib/tkextlib/tile/tentry.rb | 5 + ext/tk/lib/tkextlib/tile/tnotebook.rb | 24 +- ext/tk/lib/tkextlib/tile/tpaned.rb | 25 +- ext/tk/lib/tkextlib/tile/treeview.rb | 60 ++- ext/tk/lib/tkextlib/tktable/tktable.rb | 13 +- ext/tk/lib/tkextlib/treectrl/tktreectrl.rb | 57 ++- ext/tk/lib/tkextlib/version.rb | 2 +- ext/tk/lib/tkextlib/vu/pie.rb | 4 + ext/tk/sample/demos-en/anilabel.rb | 10 +- ext/tk/sample/demos-en/aniwave.rb | 8 +- ext/tk/sample/demos-en/arrow.rb | 8 +- ext/tk/sample/demos-en/bind.rb | 22 +- ext/tk/sample/demos-en/bitmap.rb | 10 +- ext/tk/sample/demos-en/button.rb | 2 +- ext/tk/sample/demos-en/check.rb | 14 +- ext/tk/sample/demos-en/check2.rb | 14 +- ext/tk/sample/demos-en/clrpick.rb | 22 +- ext/tk/sample/demos-en/colors.rb | 18 +- ext/tk/sample/demos-en/combo.rb | 96 ++++ ext/tk/sample/demos-en/cscroll.rb | 14 +- ext/tk/sample/demos-en/ctext.rb | 8 +- ext/tk/sample/demos-en/entry1.rb | 12 +- ext/tk/sample/demos-en/entry2.rb | 8 +- ext/tk/sample/demos-en/entry3.rb | 48 +- ext/tk/sample/demos-en/filebox.rb | 17 +- ext/tk/sample/demos-en/floor.rb | 14 +- ext/tk/sample/demos-en/floor2.rb | 14 +- ext/tk/sample/demos-en/form.rb | 8 +- ext/tk/sample/demos-en/goldberg.rb | 23 +- ext/tk/sample/demos-en/hscale.rb | 29 +- ext/tk/sample/demos-en/icon.rb | 20 +- ext/tk/sample/demos-en/image1.rb | 13 +- ext/tk/sample/demos-en/image2.rb | 22 +- ext/tk/sample/demos-en/image3.rb | 29 +- ext/tk/sample/demos-en/items.rb | 8 +- ext/tk/sample/demos-en/knightstour.rb | 271 ++++++++++ ext/tk/sample/demos-en/label.rb | 13 +- ext/tk/sample/demos-en/labelframe.rb | 8 +- ext/tk/sample/demos-en/mclist.rb | 117 +++++ ext/tk/sample/demos-en/menu.rb | 12 +- ext/tk/sample/demos-en/menu84.rb | 8 +- ext/tk/sample/demos-en/menubu.rb | 10 +- ext/tk/sample/demos-en/msgbox.rb | 10 +- ext/tk/sample/demos-en/msgbox2.rb | 91 ++++ ext/tk/sample/demos-en/paned1.rb | 14 +- ext/tk/sample/demos-en/paned2.rb | 8 +- ext/tk/sample/demos-en/pendulum.rb | 10 +- ext/tk/sample/demos-en/plot.rb | 8 +- ext/tk/sample/demos-en/puzzle.rb | 32 +- ext/tk/sample/demos-en/radio.rb | 12 +- ext/tk/sample/demos-en/radio2.rb | 17 +- ext/tk/sample/demos-en/radio3.rb | 19 +- ext/tk/sample/demos-en/ruler.rb | 8 +- ext/tk/sample/demos-en/sayings.rb | 8 +- ext/tk/sample/demos-en/search.rb | 12 +- ext/tk/sample/demos-en/spin.rb | 12 +- ext/tk/sample/demos-en/states.rb | 8 +- ext/tk/sample/demos-en/style.rb | 8 +- ext/tk/sample/demos-en/text.rb | 8 +- ext/tk/sample/demos-en/textpeer.rb | 14 +- ext/tk/sample/demos-en/toolbar.rb | 128 +++++ ext/tk/sample/demos-en/tree.rb | 119 +++++ ext/tk/sample/demos-en/ttkbut.rb | 139 +++++ ext/tk/sample/demos-en/ttkmenu.rb | 85 ++++ ext/tk/sample/demos-en/ttknote.rb | 89 ++++ ext/tk/sample/demos-en/ttkpane.rb | 213 ++++++++ ext/tk/sample/demos-en/ttkprogress.rb | 66 +++ ext/tk/sample/demos-en/twind.rb | 8 +- ext/tk/sample/demos-en/twind2.rb | 6 +- ext/tk/sample/demos-en/unicodeout.rb | 14 +- ext/tk/sample/demos-en/vscale.rb | 28 +- ext/tk/sample/demos-en/widget | 181 +++++-- ext/tk/sample/demos-jp/anilabel.rb | 10 +- ext/tk/sample/demos-jp/aniwave.rb | 8 +- ext/tk/sample/demos-jp/arrow.rb | 8 +- ext/tk/sample/demos-jp/bind.rb | 22 +- ext/tk/sample/demos-jp/bitmap.rb | 10 +- ext/tk/sample/demos-jp/button.rb | 3 +- ext/tk/sample/demos-jp/check.rb | 14 +- ext/tk/sample/demos-jp/check2.rb | 14 +- ext/tk/sample/demos-jp/clrpick.rb | 20 +- ext/tk/sample/demos-jp/colors.rb | 18 +- ext/tk/sample/demos-jp/combo.rb | 98 ++++ ext/tk/sample/demos-jp/cscroll.rb | 14 +- ext/tk/sample/demos-jp/ctext.rb | 8 +- ext/tk/sample/demos-jp/entry1.rb | 12 +- ext/tk/sample/demos-jp/entry2.rb | 8 +- ext/tk/sample/demos-jp/entry3.rb | 48 +- ext/tk/sample/demos-jp/filebox.rb | 17 +- ext/tk/sample/demos-jp/floor.rb | 14 +- ext/tk/sample/demos-jp/floor2.rb | 14 +- ext/tk/sample/demos-jp/form.rb | 8 +- ext/tk/sample/demos-jp/goldberg.rb | 23 +- ext/tk/sample/demos-jp/hscale.rb | 27 +- ext/tk/sample/demos-jp/icon.rb | 20 +- ext/tk/sample/demos-jp/image1.rb | 13 +- ext/tk/sample/demos-jp/image2.rb | 23 +- ext/tk/sample/demos-jp/image3.rb | 17 +- ext/tk/sample/demos-jp/items.rb | 8 +- ext/tk/sample/demos-jp/knightstour.rb | 273 ++++++++++ ext/tk/sample/demos-jp/label.rb | 13 +- ext/tk/sample/demos-jp/labelframe.rb | 8 +- ext/tk/sample/demos-jp/mclist.rb | 121 +++++ ext/tk/sample/demos-jp/menu.rb | 14 +- ext/tk/sample/demos-jp/menu84.rb | 8 +- ext/tk/sample/demos-jp/menu8x.rb | 12 +- ext/tk/sample/demos-jp/menubu.rb | 10 +- ext/tk/sample/demos-jp/msgbox.rb | 14 +- ext/tk/sample/demos-jp/msgbox2.rb | 90 ++++ ext/tk/sample/demos-jp/paned1.rb | 14 +- ext/tk/sample/demos-jp/paned2.rb | 8 +- ext/tk/sample/demos-jp/pendulum.rb | 10 +- ext/tk/sample/demos-jp/plot.rb | 8 +- ext/tk/sample/demos-jp/puzzle.rb | 32 +- ext/tk/sample/demos-jp/radio.rb | 12 +- ext/tk/sample/demos-jp/radio2.rb | 17 +- ext/tk/sample/demos-jp/radio3.rb | 19 +- ext/tk/sample/demos-jp/ruler.rb | 8 +- ext/tk/sample/demos-jp/sayings.rb | 8 +- ext/tk/sample/demos-jp/search.rb | 12 +- ext/tk/sample/demos-jp/spin.rb | 14 +- ext/tk/sample/demos-jp/states.rb | 8 +- ext/tk/sample/demos-jp/style.rb | 7 +- ext/tk/sample/demos-jp/text.rb | 8 +- ext/tk/sample/demos-jp/textpeer.rb | 14 +- ext/tk/sample/demos-jp/toolbar.rb | 136 +++++ ext/tk/sample/demos-jp/tree.rb | 120 +++++ ext/tk/sample/demos-jp/ttkbut.rb | 145 ++++++ ext/tk/sample/demos-jp/ttkmenu.rb | 91 ++++ ext/tk/sample/demos-jp/ttknote.rb | 97 ++++ ext/tk/sample/demos-jp/ttkpane.rb | 216 ++++++++ ext/tk/sample/demos-jp/ttkprogress.rb | 71 +++ ext/tk/sample/demos-jp/twind.rb | 6 +- ext/tk/sample/demos-jp/twind2.rb | 6 +- ext/tk/sample/demos-jp/unicodeout.rb | 14 +- ext/tk/sample/demos-jp/vscale.rb | 29 +- ext/tk/sample/demos-jp/widget | 208 ++++++-- ext/tk/sample/figmemo_sample.rb | 456 +++++++++++++++++ ext/tk/sample/tkextlib/treectrl/demo.rb | 7 +- ext/tk/tcltklib.c | 507 +++++++++++++------ ext/tk/tkutil/tkutil.c | 8 +- 186 files changed, 5715 insertions(+), 923 deletions(-) create mode 100644 ext/tk/sample/demos-en/combo.rb create mode 100644 ext/tk/sample/demos-en/knightstour.rb create mode 100644 ext/tk/sample/demos-en/mclist.rb create mode 100644 ext/tk/sample/demos-en/msgbox2.rb create mode 100644 ext/tk/sample/demos-en/toolbar.rb create mode 100644 ext/tk/sample/demos-en/tree.rb create mode 100644 ext/tk/sample/demos-en/ttkbut.rb create mode 100644 ext/tk/sample/demos-en/ttkmenu.rb create mode 100644 ext/tk/sample/demos-en/ttknote.rb create mode 100644 ext/tk/sample/demos-en/ttkpane.rb create mode 100644 ext/tk/sample/demos-en/ttkprogress.rb create mode 100644 ext/tk/sample/demos-jp/combo.rb create mode 100644 ext/tk/sample/demos-jp/knightstour.rb create mode 100644 ext/tk/sample/demos-jp/mclist.rb create mode 100644 ext/tk/sample/demos-jp/msgbox2.rb create mode 100644 ext/tk/sample/demos-jp/toolbar.rb create mode 100644 ext/tk/sample/demos-jp/tree.rb create mode 100644 ext/tk/sample/demos-jp/ttkbut.rb create mode 100644 ext/tk/sample/demos-jp/ttkmenu.rb create mode 100644 ext/tk/sample/demos-jp/ttknote.rb create mode 100644 ext/tk/sample/demos-jp/ttkpane.rb create mode 100644 ext/tk/sample/demos-jp/ttkprogress.rb create mode 100644 ext/tk/sample/figmemo_sample.rb diff --git a/ChangeLog b/ChangeLog index 7655554f61..d0c0ba6498 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +Fri May 23 04:22:19 2008 Hidetoshi NAGAI + + * ext/tk/tcltklib.c, ext/tk/tkutil/tkutil.c: fix memory leak. + + * ext/tk/lib/tk.rb: avoid trouble when finalize TclTkIp. + + * ext/tk/lib/tk.rb, ext/tk/lib/tk/*: help to fix troubles when + use Ttk widgets on old Tk scripts. + + * ext/tk/sample/*: update and add demo stcipts. some of them are + introduction about new features of Tcl/Tk8.5. + Fri May 23 03:48:10 2008 Akinori MUSHA * class.c (clone_method): Just use ruby_cref as cref. diff --git a/ext/tk/lib/multi-tk.rb b/ext/tk/lib/multi-tk.rb index b3b9e69539..ec718678f0 100644 --- a/ext/tk/lib/multi-tk.rb +++ b/ext/tk/lib/multi-tk.rb @@ -2431,7 +2431,7 @@ class MultiTkIp def mainloop(check_root = true, restart_on_dead = true) raise SecurityError, "no permission to manipulate" unless self.manipulable? - unless WITH_RUBY_VM ### Ruby 1.9 !!!!!!!!!!! + if WITH_RUBY_VM ### Ruby 1.9 !!!!!!!!!!! return @interp_thread.value if @interp_thread end diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb index e827d71ebc..c5d5b804d2 100644 --- a/ext/tk/lib/tk.rb +++ b/ext/tk/lib/tk.rb @@ -1298,7 +1298,7 @@ module TkCore }) << ' %W') INTERP.add_tk_procs(TclTkLib::FINALIZE_PROC_NAME, '', - "bind all <#{WIDGET_DESTROY_HOOK}> {}") + "catch { bind all <#{WIDGET_DESTROY_HOOK}> {} }") INTERP.add_tk_procs('rb_out', 'ns args', <<-'EOL') if [regexp {^::} $ns] { @@ -3245,11 +3245,13 @@ module TkTreatFont next else fnt = hash_kv(fnt) if fnt.kind_of?(Hash) - begin + unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ tk_call(*(__config_cmd << "-#{optkey}" << fnt)) - rescue => e - unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ - fail e + else + begin + tk_call(*(__config_cmd << "-#{optkey}" << fnt)) + rescue + # ignore end end end @@ -3305,11 +3307,13 @@ module TkTreatFont fobj = fontobj # create a new TkFont object else ltn = hash_kv(ltn) if ltn.kind_of?(Hash) - begin + unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ tk_call(*(__config_cmd << "-#{optkey}" << ltn)) - rescue => e - unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ - fail e + else + begin + tk_call(*(__config_cmd << "-#{optkey}" << ltn)) + rescue => e + # ignore end end next @@ -3363,11 +3367,13 @@ module TkTreatFont fobj = fontobj # create a new TkFont object else knj = hash_kv(knj) if knj.kind_of?(Hash) - begin + unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ tk_call(*(__config_cmd << "-#{optkey}" << knj)) - rescue => e - unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ - fail e + else + begin + tk_call(*(__config_cmd << "-#{optkey}" << knj)) + rescue => e + # ignore end end next @@ -3499,6 +3505,11 @@ module TkConfigMethod end private :__configinfo_struct + def __optkey_aliases + {} + end + private :__optkey_aliases + def __numval_optkeys [] end @@ -3613,6 +3624,11 @@ module TkConfigMethod fail ArgumentError, "Invalid option `#{orig_slot.inspect}'" end + alias_name, real_name = __optkey_aliases.find{|k, v| k.to_s == slot} + if real_name + slot = real_name.to_s + end + if ( method = _symbolkey2str(__val2ruby_optkeys())[slot] ) optval = tk_call_without_enc(*(__cget_cmd << "-#{slot}")) begin @@ -3687,14 +3703,35 @@ module TkConfigMethod unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ __cget_core(slot) else - __cget_core(slot) rescue nil + begin + __cget_core(slot) + rescue => e + if current_configinfo.has_key?(slot.to_s) + # error on known option + fail e + else + # unknown option + nil + end + end end end + def cget_strict(slot) + # never use TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ + __cget_core(slot) + end def __configure_core(slot, value=None) if slot.kind_of? Hash slot = _symbolkey2str(slot) + __optkey_aliases.each{|alias_name, real_name| + alias_name = alias_name.to_s + if slot.has_key?(alias_name) + slot[real_name.to_s] = slot.delete(alias_name) + end + } + __methodcall_optkeys.each{|key, method| value = slot.delete(key.to_s) self.__send__(method, value) if value @@ -3731,6 +3768,11 @@ module TkConfigMethod fail ArgumentError, "Invalid option `#{orig_slot.inspect}'" end + alias_name, real_name = __optkey_aliases.find{|k, v| k.to_s == slot} + if real_name + slot = real_name.to_s + end + if ( conf = __keyonly_optkeys.find{|k, v| k.to_s == slot} ) defkey, undefkey = conf if value @@ -3782,7 +3824,17 @@ module TkConfigMethod __configure_core(slot) unless slot.empty? end else - __configure_core(slot, value) rescue nil + begin + __configure_core(slot, value) + rescue => e + if current_configinfo.has_key?(slot.to_s) + # error on known option + fail e + else + # unknown option + nil + end + end end end self @@ -3818,6 +3870,12 @@ module TkConfigMethod else if slot slot = slot.to_s + + alias_name, real_name = __optkey_aliases.find{|k, v| k.to_s == slot} + if real_name + slot = real_name.to_s + end + case slot when /^(#{__val2ruby_optkeys().keys.join('|')})$/ method = _symbolkey2str(__val2ruby_optkeys())[slot] @@ -4191,6 +4249,12 @@ module TkConfigMethod else if slot slot = slot.to_s + + alias_name, real_name = __optkey_aliases.find{|k, v| k.to_s == slot} + if real_name + slot = real_name.to_s + end + case slot when /^(#{__val2ruby_optkeys().keys.join('|')})$/ method = _symbolkey2str(__val2ruby_optkeys())[slot] @@ -4786,6 +4850,13 @@ class TkWindow e tk_call_without_enc(cmd, @path) keys = __check_available_configure_options(keys) unless keys.empty? begin - tk_call_without_enc('destroy', @path) - rescue - # cannot destroy + # try to configure configure(keys) - else - # re-create widget - tk_call_without_enc(cmd, @path, *hash_kv(keys, true)) + rescue + # fail => includes options adaptable when creattion only? + begin + tk_call_without_enc('destroy', @path) + rescue + # cannot rescue options error + fail e + else + # re-create widget + tk_call_without_enc(cmd, @path, *hash_kv(keys, true)) + end end end end @@ -5389,7 +5466,7 @@ TkWidget = TkWindow #Tk.freeze module Tk - RELEASE_DATE = '2008-05-16'.freeze + RELEASE_DATE = '2008-05-23'.freeze autoload :AUTO_PATH, 'tk/variable' autoload :TCL_PACKAGE_PATH, 'tk/variable' diff --git a/ext/tk/lib/tk/canvas.rb b/ext/tk/lib/tk/canvas.rb index fceadd5e9c..36ea008a17 100644 --- a/ext/tk/lib/tk/canvas.rb +++ b/ext/tk/lib/tk/canvas.rb @@ -168,6 +168,8 @@ class Tk::Canvas e + if current_configinfo.has_key?(option.to_s) + # error on known option + fail e + else + # unknown option + nil + end + end + end + end def copy(src, *opts) if opts.size == 0 diff --git a/ext/tk/lib/tk/itemconfig.rb b/ext/tk/lib/tk/itemconfig.rb index abff676d78..9c6a98d0f8 100644 --- a/ext/tk/lib/tk/itemconfig.rb +++ b/ext/tk/lib/tk/itemconfig.rb @@ -8,6 +8,11 @@ require 'tk/itemfont.rb' module TkItemConfigOptkeys include TkUtil + def __item_optkey_aliases(id) + {} + end + private :__item_optkey_aliases + def __item_numval_optkeys(id) [] end @@ -165,6 +170,11 @@ module TkItemConfigMethod fail ArgumentError, "Invalid option `#{orig_opt.inspect}'" end + alias_name, real_name = __item_optkey_aliases(tagid(tagOrId)).find{|k, v| k.to_s == option} + if real_name + option = real_name.to_s + end + if ( method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[option] ) optval = tk_call_without_enc(*(__item_cget_cmd(tagid(tagOrId)) << "-#{option}")) begin @@ -242,20 +252,35 @@ module TkItemConfigMethod __itemcget_core(tagOrId, option) rescue => e begin - __itemcget_core(tagOrId) - # not tag error -> option is unknown - nil + if __current_itemconfiginfo(tagOrId).has_key?(option.to_s) + # not tag error & option is known -> error on known option + fail e + else + # not tag error & option is unknown + nil + end rescue fail e # tag error end end end end + def itemcget_strict(tagOrId, option) + # never use TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ + __itemcget_core(tagOrId, option) + end def __itemconfigure_core(tagOrId, slot, value=None) if slot.kind_of? Hash slot = _symbolkey2str(slot) + __item_optkey_aliases(tagid(tagOrId)).each{|alias_name, real_name| + alias_name = alias_name.to_s + if slot.has_key?(alias_name) + slot[real_name.to_s] = slot.delete(alias_name) + end + } + __item_methodcall_optkeys(tagid(tagOrId)).each{|key, method| value = slot.delete(key.to_s) self.__send__(method, tagOrId, value) if value @@ -292,6 +317,11 @@ module TkItemConfigMethod fail ArgumentError, "Invalid option `#{orig_slot.inspect}'" end + alias_name, real_name = __item_optkey_aliases(tagid(tagOrId)).find{|k, v| k.to_s == slot} + if real_name + slot = real_name.to_s + end + if ( conf = __item_keyonly_optkeys(tagid(tagOrId)).find{|k, v| k.to_s == slot } ) defkey, undefkey = conf if value @@ -350,8 +380,13 @@ module TkItemConfigMethod __itemconfigure_core(tagOrId, slot, value) rescue => e begin - __itemconfiginfo_core(tagOrId) - # not tag error -> option is unknown + if __current_itemconfiginfo(tagOrId).has_key?(slot.to_s) + # not tag error & option is known -> error on known option + fail e + else + # not tag error & option is unknown + nil + end rescue fail e # tag error end @@ -386,6 +421,12 @@ module TkItemConfigMethod else if slot slot = slot.to_s + + alias_name, real_name = __item_optkey_aliases(tagid(tagOrId)).find{|k, v| k.to_s == slot} + if real_name + slot = real_name.to_s + end + case slot when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/ method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[slot] @@ -757,6 +798,12 @@ module TkItemConfigMethod else if slot slot = slot.to_s + + alias_name, real_name = __item_optkey_aliases(tagid(tagOrId)).find{|k, v| k.to_s == slot} + if real_name + slot = real_name.to_s + end + case slot when /^(#{__item_val2ruby_optkeys(tagid(tagOrId)).keys.join('|')})$/ method = _symbolkey2str(__item_val2ruby_optkeys(tagid(tagOrId)))[slot] diff --git a/ext/tk/lib/tk/itemfont.rb b/ext/tk/lib/tk/itemfont.rb index 11d443b597..4c5c917c57 100644 --- a/ext/tk/lib/tk/itemfont.rb +++ b/ext/tk/lib/tk/itemfont.rb @@ -94,11 +94,14 @@ module TkTreatItemFont *(__item_config_cmd(tagid(tagOrId)) << {})) next else - begin + fnt = hash_kv(fnt) if fnt.kind_of?(Hash) + unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ tk_call(*(__item_config_cmd(tagid(tagOrId)) << "-#{optkey}" << fnt)) - rescue => e - unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ - fail e + else + begin + tk_call(*(__item_config_cmd(tagid(tagOrId)) << "-#{optkey}" << fnt)) + rescue => e + # ignore end end end @@ -153,11 +156,14 @@ module TkTreatItemFont elsif Tk::JAPANIZED_TK fobj = fontobj # create a new TkFont object else - begin + ltn = hash_kv(ltn) if ltn.kind_of?(Hash) + unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ tk_call(*(__item_config_cmd(tagid(tagOrId)) << "-#{optkey}" << ltn)) - rescue => e - unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ - fail e + else + begin + tk_call(*(__item_config_cmd(tagid(tagOrId)) << "-#{optkey}" << ltn)) + rescue => e + # ignore end end next @@ -210,11 +216,14 @@ module TkTreatItemFont elsif Tk::JAPANIZED_TK fobj = fontobj # create a new TkFont object else - begin + knj = hash_kv(knj) if knj.kind_of?(Hash) + unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ tk_call(*(__item_config_cmd(tagid(tagOrId)) << "-#{optkey}" << knj)) - rescue => e - unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ - fail e + else + begin + tk_call(*(__item_config_cmd(tagid(tagOrId)) << "-#{optkey}" << knj)) + rescue => e + # ignore end end next diff --git a/ext/tk/lib/tk/menu.rb b/ext/tk/lib/tk/menu.rb index 8ba3156293..3ae0548dd1 100644 --- a/ext/tk/lib/tk/menu.rb +++ b/ext/tk/lib/tk/menu.rb @@ -34,12 +34,13 @@ module TkMenuEntryConfig private :__item_val2ruby_optkeys alias entrycget itemcget + alias entrycget_strict itemcget_strict alias entryconfigure itemconfigure alias entryconfiginfo itemconfiginfo alias current_entryconfiginfo current_itemconfiginfo - private :itemcget, :itemconfigure - private :itemconfiginfo, :current_itemconfiginfo + private :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo end class Tk::Menu e + begin + if current_paneconfiginfo(win).has_key?(option.to_s) + # not tag error & option is known -> error on known option + fail e + else + # not tag error & option is unknown + nil + end + rescue + fail e # tag error + end + end + end + end def paneconfigure(win, key, value=nil) # win = win.epath if win.kind_of?(TkObject) diff --git a/ext/tk/lib/tk/text.rb b/ext/tk/lib/tk/text.rb index a4c63c70a3..4ec82bed1d 100644 --- a/ext/tk/lib/tk/text.rb +++ b/ext/tk/lib/tk/text.rb @@ -32,6 +32,9 @@ module TkTextTagConfig def tag_cget(tagOrId, option) itemcget(['tag', tagOrId], option) end + def tag_cget_strict(tagOrId, option) + itemcget_strict(['tag', tagOrId], option) + end def tag_configure(tagOrId, slot, value=None) itemconfigure(['tag', tagOrId], slot, value) end @@ -45,6 +48,9 @@ module TkTextTagConfig def window_cget(tagOrId, option) itemcget(['window', tagOrId], option) end + def window_cget_strict(tagOrId, option) + itemcget_strict(['window', tagOrId], option) + end def window_configure(tagOrId, slot, value=None) itemconfigure(['window', tagOrId], slot, value) end @@ -55,8 +61,8 @@ module TkTextTagConfig current_itemconfiginfo(['window', tagOrId], slot) end - private :itemcget, :itemconfigure - private :itemconfiginfo, :current_itemconfiginfo + private :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo end class Tk::Text e + begin + if current_image_configinfo(index).has_key?(slot.to_s) + # not tag error & option is known -> error on known option + fail e + else + # not tag error & option is unknown + nil + end + rescue + fail e # tag error + end + end + end + end + def image_configure(index, slot, value=None) if slot.kind_of?(Hash) _fromUTF8(tk_send_without_enc('image', 'configure', diff --git a/ext/tk/lib/tk/textimage.rb b/ext/tk/lib/tk/textimage.rb index d4c973213d..fb306a9c17 100644 --- a/ext/tk/lib/tk/textimage.rb +++ b/ext/tk/lib/tk/textimage.rb @@ -52,6 +52,10 @@ class TkTextImage e + begin + if current_itemconfiginfo(tagOrId).has_key?(option.to_s) + # error on known option + fail e + else + # unknown option + nil + end + rescue + fail e # tag error + end + end + end + end def itemconfiginfo(tagOrId, slot = nil) ret = __itemconfiginfo(tagid(tagOrId), slot) @@ -321,8 +373,8 @@ module Tk::BLT ret end - private :itemcget, :itemconfigure - private :itemconfiginfo, :current_itemconfiginfo + private :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo ################# @@ -428,6 +480,9 @@ module Tk::BLT def cget(option) @chart.axis_cget(@id, option) end + def cget_strict(option) + @chart.axis_cget_strict(@id, option) + end def configure(key, value=None) @chart.axis_configure(@id, key, value) self @@ -530,6 +585,9 @@ module Tk::BLT def cget(option) @chart.crosshair_cget(option) end + def cget_strict(option) + @chart.crosshair_cget_strict(option) + end def configure(key, value=None) @chart.crosshair_configure(key, value) self @@ -675,6 +733,9 @@ module Tk::BLT # @chart.element_cget(@id, option) @chart.__send__(@typename + '_cget', @id, option) end + def cget_strict(option) + @chart.__send__(@typename + '_cget_strict', @id, option) + end def configure(key, value=None) # @chart.element_configure(@id, key, value) @chart.__send__(@typename + '_configure', @id, key, value) @@ -775,6 +836,9 @@ module Tk::BLT def cget(option) @chart.gridline_cget(option) end + def cget_strict(option) + @chart.gridline_cget_strict(option) + end def configure(key, value=None) @chart.gridline_configure(key, value) self @@ -846,6 +910,9 @@ module Tk::BLT def cget(option) @chart.legend_cget(option) end + def cget_strict(option) + @chart.legend_cget_strict(option) + end def configure(key, value=None) @chart.legend_configure(key, value) self @@ -972,6 +1039,9 @@ module Tk::BLT def cget(option) @chart.pen_cget(@id, option) end + def cget_strict(option) + @chart.pen_cget_strict(@id, option) + end def configure(key, value=None) @chart.pen_configure(@id, key, value) self @@ -1039,6 +1109,9 @@ module Tk::BLT def cget(option) @chart.postscript_cget(option) end + def cget_strict(option) + @chart.postscript_cget_strict(option) + end def configure(key, value=None) @chart.postscript_configure(key, value) self @@ -1117,6 +1190,13 @@ module Tk::BLT fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) } + __item_optkey_aliases(nil).each{|alias_name, real_name| + alias_name = alias_name.to_s + if keys.has_key?(alias_name) + keys[real_name.to_s] = keys.delete(alias_name) + end + } + __item_methodcall_optkeys(nil).each{|key| key = key.to_s methodkeys[key] = keys.delete(key) if keys.key?(key) @@ -1192,6 +1272,9 @@ module Tk::BLT def cget(option) @chart.marker_cget(@id, option) end + def cget_strict(option) + @chart.marker_cget_strict(@id, option) + end def configure(key, value=None) @chart.marker_configure(@id, key, value) self @@ -1774,6 +1857,9 @@ module Tk::BLT def xaxis_cget(option) itemcget('xaxis', option) end + def xaxis_cget_strict(option) + itemcget_strict('xaxis', option) + end def xaxis_configure(slot, value=None) if slot.kind_of?(Hash) slot = _symbolkey2str(slot) @@ -1843,6 +1929,9 @@ module Tk::BLT def x2axis_cget(option) itemcget('x2axis', option) end + def x2axis_cget_strict(option) + itemcget_strict('x2axis', option) + end def x2axis_configure(slot, value=None) if slot.kind_of?(Hash) slot = _symbolkey2str(slot) @@ -1912,6 +2001,9 @@ module Tk::BLT def yaxis_cget(option) itemcget('yaxis', option) end + def yaxis_cget_strict(option) + itemcget_strict('yaxis', option) + end def yaxis_configure(slot, value=None) if slot.kind_of?(Hash) slot = _symbolkey2str(slot) @@ -1981,6 +2073,9 @@ module Tk::BLT def y2axis_cget(option) itemcget('y2axis', option) end + def y2axis_cget_strict(option) + itemcget_strict('y2axis', option) + end def y2axis_configure(slot, value=None) if slot.kind_of?(Hash) slot = _symbolkey2str(slot) diff --git a/ext/tk/lib/tkextlib/blt/htext.rb b/ext/tk/lib/tkextlib/blt/htext.rb index a0cf3dc036..0d9cb30185 100644 --- a/ext/tk/lib/tkextlib/blt/htext.rb +++ b/ext/tk/lib/tkextlib/blt/htext.rb @@ -22,6 +22,7 @@ module Tk::BLT WidgetClassNames[WidgetClassName] = self alias window_cget itemcget + alias window_cget_strict itemcget_strict alias window_configure itemconfigure alias window_configuinfo itemconfiginfo alias current_window_configuinfo current_itemconfiginfo diff --git a/ext/tk/lib/tkextlib/blt/table.rb b/ext/tk/lib/tkextlib/blt/table.rb index 0be9d8d42a..dfa10269ed 100644 --- a/ext/tk/lib/tkextlib/blt/table.rb +++ b/ext/tk/lib/tkextlib/blt/table.rb @@ -29,6 +29,9 @@ module Tk::BLT def blt_table_cget(*args) Tk::BLT::Table.cget(self, *args) end + def blt_table_cget_strict(*args) + Tk::BLT::Table.cget_strict(self, *args) + end def blt_table_configure(*args) Tk::BLT::Table.configure(self, *args) @@ -92,6 +95,9 @@ module Tk::BLT def blt_table_itemcget(*args) Tk::BLT::Table.itemcget(self, *args) end + def blt_table_itemcget_strict(*args) + Tk::BLT::Table.itemcget_strict(self, *args) + end def blt_table_itemconfigure(*args) Tk::BLT::Table.itemconfigure(self, *args) @@ -136,12 +142,13 @@ class << Tk::BLT::Table private :__item_pathname alias __itemcget itemcget + alias __itemcget_strict itemcget_strict alias __itemconfigure itemconfigure alias __itemconfiginfo itemconfiginfo alias __current_itemconfiginfo current_itemconfiginfo - private :__itemcget, :__itemconfigure - private :__itemconfiginfo, :__current_itemconfiginfo + private :__itemcget, :__itemcget_strict + private :__itemconfigure, :__itemconfiginfo, :__current_itemconfiginfo def __boolval_optkeys super() << 'propagate' @@ -176,6 +183,9 @@ class << Tk::BLT::Table def cget(container, option) __itemcget([container], option) end + def cget_strict(container, option) + __itemcget_strict([container], option) + end def configure(container, *args) __itemconfigure([container], *args) @@ -192,6 +202,9 @@ class << Tk::BLT::Table def itemcget(container, item, option) __itemcget([container, tagid(item)], option) end + def itemcget_strict(container, item, option) + __itemcget_strict([container, tagid(item)], option) + end def itemconfigure(container, *args) if args[-1].kind_of?(Hash) diff --git a/ext/tk/lib/tkextlib/blt/tabset.rb b/ext/tk/lib/tkextlib/blt/tabset.rb index 1a0f312c4c..ca81ad8f95 100644 --- a/ext/tk/lib/tkextlib/blt/tabset.rb +++ b/ext/tk/lib/tkextlib/blt/tabset.rb @@ -128,6 +128,9 @@ module Tk::BLT def cget(*args) @t.tab_cget(@id, *args) end + def cget_strict(*args) + @t.tab_cget_strict(@id, *args) + end def configure(*args) @t.tab_configure(@id, *args) end @@ -240,6 +243,7 @@ module Tk::BLT private :__item_pathname alias tab_cget itemcget + alias tab_cget_strict itemcget_strict alias tab_configure itemconfigure alias tab_configinfo itemconfiginfo alias current_tab_configinfo current_itemconfiginfo diff --git a/ext/tk/lib/tkextlib/blt/ted.rb b/ext/tk/lib/tkextlib/blt/ted.rb index 8b727c1eec..670265fc78 100644 --- a/ext/tk/lib/tkextlib/blt/ted.rb +++ b/ext/tk/lib/tkextlib/blt/ted.rb @@ -30,12 +30,15 @@ module Tk::BLT end private :__item_config_cmd - private :itemcget, :itemconfigure - private :itemconfiginfo, :current_itemconfiginfo + private :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo def cget(master, option) itemcget(master, option) end + def cget_strict(master, option) + itemcget_strict(master, option) + end def configure(master, slot, value=None) itemconfigure(master, slot, value) end diff --git a/ext/tk/lib/tkextlib/blt/treeview.rb b/ext/tk/lib/tkextlib/blt/treeview.rb index 672869bfa2..c5a5697186 100644 --- a/ext/tk/lib/tkextlib/blt/treeview.rb +++ b/ext/tk/lib/tkextlib/blt/treeview.rb @@ -98,6 +98,9 @@ module Tk::BLT::Treeview::ConfigMethod def column_cget(name, option) itemcget(['column', name], option) end + def column_cget_strict(name, option) + itemcget_strict(['column', name], option) + end def column_configure(name, slot, value=None) itemconfigure(['column', name], slot, value) end @@ -111,6 +114,9 @@ module Tk::BLT::Treeview::ConfigMethod def button_cget(option) itemcget('button', option) end + def button_cget_strict(option) + itemcget_strict('button', option) + end def button_configure(slot, value=None) itemconfigure('button', slot, value) end @@ -129,6 +135,14 @@ module Tk::BLT::Treeview::ConfigMethod ret end end + def entry_cget_strict(option) + ret = itemcget_strict('entry', option) + if option == 'bindtags' || option == :bindtags + ret.collect{|tag| TkBindTag.id2obj(tag)} + else + ret + end + end def entry_configure(slot, value=None) itemconfigure('entry', slot, value) end @@ -170,6 +184,9 @@ module Tk::BLT::Treeview::ConfigMethod def sort_cget(option) itemcget('sort', option) end + def sort_cget_strict(option) + itemcget_strict('sort', option) + end def sort_configure(slot, value=None) itemconfigure('sort', slot, value) end @@ -183,6 +200,9 @@ module Tk::BLT::Treeview::ConfigMethod def text_cget(option) itemcget('text', option) end + def text_cget_strict(option) + itemcget_strict('text', option) + end def text_configure(slot, value=None) itemconfigure('text', slot, value) end @@ -193,8 +213,8 @@ module Tk::BLT::Treeview::ConfigMethod current_itemconfiginfo('text', slot) end - private :itemcget, :itemconfigure - private :itemconfiginfo, :current_itemconfiginfo + private :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo end class Tk::BLT::Treeview diff --git a/ext/tk/lib/tkextlib/blt/unix_dnd.rb b/ext/tk/lib/tkextlib/blt/unix_dnd.rb index 7a994233a2..445002d7a5 100644 --- a/ext/tk/lib/tkextlib/blt/unix_dnd.rb +++ b/ext/tk/lib/tkextlib/blt/unix_dnd.rb @@ -30,12 +30,15 @@ module Tk::BLT end private :__item_config_cmd - private :itemcget, :itemconfigure - private :itemconfiginfo, :current_itemconfiginfo + private :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo def cget(win, option) itemcget(['cget', win], option) end + def cget_strict(win, option) + itemcget_strict(['cget', win], option) + end def configure(win, slot, value=None) itemconfigure(['configure', win], slot, value) end @@ -49,6 +52,9 @@ module Tk::BLT def token_cget(win, option) itemcget(['token', 'cget', win], option) end + def token_cget_strict(win, option) + itemcget_strict(['token', 'cget', win], option) + end def token_configure(win, slot, value=None) itemconfigure(['token', 'configure', win], slot, value) end diff --git a/ext/tk/lib/tkextlib/blt/watch.rb b/ext/tk/lib/tkextlib/blt/watch.rb index 2daf417e0b..219ff78e97 100644 --- a/ext/tk/lib/tkextlib/blt/watch.rb +++ b/ext/tk/lib/tkextlib/blt/watch.rb @@ -146,7 +146,7 @@ module Tk::BLT end end end - def cget(key) + def cget_strict(key) key = key.to_s begin info.assoc(key)[1] @@ -154,5 +154,22 @@ module Tk::BLT fail ArgumentError, "unknown option '#{key}'" end end + def cget(key) + unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ + cget_strict(key) + else + begin + cget_strict(key) + rescue => e + if current_configinfo.has_key?(key.to_s) + # error on known option + fail e + else + # unknown option + nil + end + end + end + end end end diff --git a/ext/tk/lib/tkextlib/bwidget/dialog.rb b/ext/tk/lib/tkextlib/bwidget/dialog.rb index 0ddee21d05..291ca4a962 100644 --- a/ext/tk/lib/tkextlib/bwidget/dialog.rb +++ b/ext/tk/lib/tkextlib/bwidget/dialog.rb @@ -59,6 +59,13 @@ class Tk::BWidget::Dialog end end + def cget_strict(slot) + if slot.to_s == 'relative' + super('parent') + else + super(slot) + end + end def cget(slot) if slot.to_s == 'relative' super('parent') diff --git a/ext/tk/lib/tkextlib/bwidget/dynamichelp.rb b/ext/tk/lib/tkextlib/bwidget/dynamichelp.rb index 224304f2ab..846e58062d 100644 --- a/ext/tk/lib/tkextlib/bwidget/dynamichelp.rb +++ b/ext/tk/lib/tkextlib/bwidget/dynamichelp.rb @@ -34,6 +34,13 @@ module Tk::BWidget::DynamicHelp ['DynamicHelp::configure'] end + def self.cget_strict(slot) + slot = slot.to_s + info = {} + self.current_configinfo.each{|k,v| info[k.to_s] = v if k.to_s == slot} + fail RuntimeError, "unknown option \"-#{slot}\"" if info.empty? + info.values[0] + end def self.cget(slot) self.current_configinfo(slot).values[0] end diff --git a/ext/tk/lib/tkextlib/bwidget/listbox.rb b/ext/tk/lib/tkextlib/bwidget/listbox.rb index d8cd72fec2..093fcb6fb3 100644 --- a/ext/tk/lib/tkextlib/bwidget/listbox.rb +++ b/ext/tk/lib/tkextlib/bwidget/listbox.rb @@ -297,6 +297,9 @@ class Tk::BWidget::ListBox::Item def cget(key) @listbox.itemcget(@id, key) end + def cget_strict(key) + @listbox.itemcget_strict(@id, key) + end def configure(key, val=None) @listbox.itemconfigure(@id, key, val) diff --git a/ext/tk/lib/tkextlib/bwidget/messagedlg.rb b/ext/tk/lib/tkextlib/bwidget/messagedlg.rb index cc8a996f46..b88461baf7 100644 --- a/ext/tk/lib/tkextlib/bwidget/messagedlg.rb +++ b/ext/tk/lib/tkextlib/bwidget/messagedlg.rb @@ -65,6 +65,17 @@ class Tk::BWidget::MessageDlg end @keys[slot] end + def cget_strict(slot) + slot = slot.to_s + if slot == 'relative' + slot = 'parent' + end + if winfo_exist? + val = super(slot) + @keys[slot] = val + end + @keys[slot] + end def configure(slot, value=None) if winfo_exist? diff --git a/ext/tk/lib/tkextlib/bwidget/tree.rb b/ext/tk/lib/tkextlib/bwidget/tree.rb index 7a46db575e..aed4512a73 100644 --- a/ext/tk/lib/tkextlib/bwidget/tree.rb +++ b/ext/tk/lib/tkextlib/bwidget/tree.rb @@ -358,6 +358,9 @@ class Tk::BWidget::Tree::Node def cget(key) @tree.itemcget(@id, key) end + def cget_strict(key) + @tree.itemcget_strict(@id, key) + end def configure(key, val=None) @tree.itemconfigure(@id, key, val) diff --git a/ext/tk/lib/tkextlib/bwidget/widget.rb b/ext/tk/lib/tkextlib/bwidget/widget.rb index 34e51308a5..a93364b567 100644 --- a/ext/tk/lib/tkextlib/bwidget/widget.rb +++ b/ext/tk/lib/tkextlib/bwidget/widget.rb @@ -29,6 +29,13 @@ module Tk::BWidget::Widget ['Widget::configure'] end + def self.cget_strict(slot) + slot = slot.to_s + info = {} + self.current_configinfo.each{|k,v| info[k.to_s] = v if k.to_s == slot} + fail RuntimeError, "unknown option \"-#{slot}\"" if info.empty? + info.values[0] + end def self.cget(slot) self.current_configinfo(slot).values[0] end @@ -105,9 +112,12 @@ module Tk::BWidget::Widget tk_call('Widget::setoption', win, option, value) end - def self.sub_cget(win, subwidget) + def self.sub_cget_strict(win, subwidget) tk_call('Widget::subcget', win, subwidget) end + def self.sub_cget(win, subwidget) + self.sub_cget_strict(win, subwidget) + end def self.sync_options(klass, subclass, subpath, options) tk_call('Widget::syncoptions', klass, subclass, subpath, options) diff --git a/ext/tk/lib/tkextlib/iwidgets/buttonbox.rb b/ext/tk/lib/tkextlib/iwidgets/buttonbox.rb index a055e07ac9..05d58c386f 100644 --- a/ext/tk/lib/tkextlib/iwidgets/buttonbox.rb +++ b/ext/tk/lib/tkextlib/iwidgets/buttonbox.rb @@ -47,12 +47,13 @@ class Tk::Iwidgets::Buttonbox end alias buttoncget itemcget + alias buttoncget_strict itemcget_strict alias buttonconfigure itemconfigure alias buttonconfiginfo itemconfiginfo alias current_buttonconfiginfo current_itemconfiginfo - private :itemcget, :itemconfigure - private :itemconfiginfo, :current_itemconfiginfo + private :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo #################################### diff --git a/ext/tk/lib/tkextlib/iwidgets/checkbox.rb b/ext/tk/lib/tkextlib/iwidgets/checkbox.rb index 7d2b41f806..c85d356c55 100644 --- a/ext/tk/lib/tkextlib/iwidgets/checkbox.rb +++ b/ext/tk/lib/tkextlib/iwidgets/checkbox.rb @@ -47,12 +47,13 @@ class Tk::Iwidgets::Checkbox end alias buttoncget itemcget + alias buttoncget_strict itemcget_strict alias buttonconfigure itemconfigure alias buttonconfiginfo itemconfiginfo alias current_buttonconfiginfo current_itemconfiginfo - private :itemcget, :itemconfigure - private :itemconfiginfo, :current_itemconfiginfo + private :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo #################################### diff --git a/ext/tk/lib/tkextlib/iwidgets/dialogshell.rb b/ext/tk/lib/tkextlib/iwidgets/dialogshell.rb index d6c668621d..8d43cc07ab 100644 --- a/ext/tk/lib/tkextlib/iwidgets/dialogshell.rb +++ b/ext/tk/lib/tkextlib/iwidgets/dialogshell.rb @@ -47,12 +47,13 @@ class Tk::Iwidgets::Dialogshell end alias buttoncget itemcget + alias buttoncget_strict itemcget_strict alias buttonconfigure itemconfigure alias buttonconfiginfo itemconfiginfo alias current_buttonconfiginfo current_itemconfiginfo - private :itemcget, :itemconfigure - private :itemconfiginfo, :current_itemconfiginfo + private :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo #################################### diff --git a/ext/tk/lib/tkextlib/iwidgets/menubar.rb b/ext/tk/lib/tkextlib/iwidgets/menubar.rb index dea3d34c2a..5aaefbe50d 100644 --- a/ext/tk/lib/tkextlib/iwidgets/menubar.rb +++ b/ext/tk/lib/tkextlib/iwidgets/menubar.rb @@ -62,12 +62,13 @@ class Tk::Iwidgets::Menubar end alias menucget itemcget + alias menucget_strict itemcget_strict alias menuconfigure itemconfigure alias menuconfiginfo itemconfiginfo alias current_menuconfiginfo current_itemconfiginfo - private :itemcget, :itemconfigure - private :itemconfiginfo, :current_itemconfiginfo + private :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo #################################### diff --git a/ext/tk/lib/tkextlib/iwidgets/messagebox.rb b/ext/tk/lib/tkextlib/iwidgets/messagebox.rb index 2bbbec7666..98ac32900c 100644 --- a/ext/tk/lib/tkextlib/iwidgets/messagebox.rb +++ b/ext/tk/lib/tkextlib/iwidgets/messagebox.rb @@ -47,12 +47,13 @@ class Tk::Iwidgets::Messagebox private :__item_boolval_optkeys alias typecget itemcget + alias typecget_strict itemcget_strict alias typeconfigure itemconfigure alias typeconfiginfo itemconfiginfo alias current_typeconfiginfo current_itemconfiginfo - private :itemcget, :itemconfigure - private :itemconfiginfo, :current_itemconfiginfo + private :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo #################################### diff --git a/ext/tk/lib/tkextlib/iwidgets/notebook.rb b/ext/tk/lib/tkextlib/iwidgets/notebook.rb index 268452afec..03b50633df 100644 --- a/ext/tk/lib/tkextlib/iwidgets/notebook.rb +++ b/ext/tk/lib/tkextlib/iwidgets/notebook.rb @@ -42,12 +42,13 @@ class Tk::Iwidgets::Notebook end alias pagecget itemcget + alias pagecget_strict itemcget_strict alias pageconfigure itemconfigure alias pageconfiginfo itemconfiginfo alias current_pageconfiginfo current_itemconfiginfo - private :itemcget, :itemconfigure - private :itemconfiginfo, :current_itemconfiginfo + private :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo #################################### diff --git a/ext/tk/lib/tkextlib/iwidgets/panedwindow.rb b/ext/tk/lib/tkextlib/iwidgets/panedwindow.rb index 035df0a5b8..3bf73d69fe 100644 --- a/ext/tk/lib/tkextlib/iwidgets/panedwindow.rb +++ b/ext/tk/lib/tkextlib/iwidgets/panedwindow.rb @@ -42,12 +42,13 @@ class Tk::Iwidgets::Panedwindow end alias panecget itemcget + alias panecget_strict itemcget_strict alias paneconfigure itemconfigure alias paneconfiginfo itemconfiginfo alias current_paneconfiginfo current_itemconfiginfo - private :itemcget, :itemconfigure - private :itemconfiginfo, :current_itemconfiginfo + private :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo #################################### diff --git a/ext/tk/lib/tkextlib/iwidgets/radiobox.rb b/ext/tk/lib/tkextlib/iwidgets/radiobox.rb index cfcbca1aad..e9d9521252 100644 --- a/ext/tk/lib/tkextlib/iwidgets/radiobox.rb +++ b/ext/tk/lib/tkextlib/iwidgets/radiobox.rb @@ -47,12 +47,13 @@ class Tk::Iwidgets::Radiobox end alias buttoncget itemcget + alias buttoncget_strict itemcget_strict alias buttonconfigure itemconfigure alias buttonconfiginfo itemconfiginfo alias current_buttonconfiginfo current_itemconfiginfo - private :itemcget, :itemconfigure - private :itemconfiginfo, :current_itemconfiginfo + private :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo #################################### diff --git a/ext/tk/lib/tkextlib/iwidgets/scrolledtext.rb b/ext/tk/lib/tkextlib/iwidgets/scrolledtext.rb index d85f232b37..d6436d202a 100644 --- a/ext/tk/lib/tkextlib/iwidgets/scrolledtext.rb +++ b/ext/tk/lib/tkextlib/iwidgets/scrolledtext.rb @@ -116,7 +116,7 @@ class Tk::Iwidgets::Scrolledtext get('-displaychars', *index) end - def image_cget(index, slot) + def image_cget_strict(index, slot) case slot.to_s when 'text', 'label', 'show', 'data', 'file' _fromUTF8(tk_send_without_enc('image', 'cget', @@ -127,6 +127,27 @@ class Tk::Iwidgets::Scrolledtext "-#{slot}"))) end end + def image_cget(index, slot) + unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ + image_cget_strict(index, slot) + else + begin + image_cget_strict(index, slot) + rescue => e + begin + if current_image_configinfo.has_key?(slot.to_s) + # error on known option + fail e + else + # unknown option + nil + end + rescue + fail e # tag error + end + end + end + end def image_configure(index, slot, value=None) if slot.kind_of? Hash diff --git a/ext/tk/lib/tkextlib/iwidgets/tabnotebook.rb b/ext/tk/lib/tkextlib/iwidgets/tabnotebook.rb index 382604102e..dbb90e5102 100644 --- a/ext/tk/lib/tkextlib/iwidgets/tabnotebook.rb +++ b/ext/tk/lib/tkextlib/iwidgets/tabnotebook.rb @@ -47,12 +47,13 @@ class Tk::Iwidgets::Tabnotebook end alias pagecget itemcget + alias pagecget_strict itemcget_strict alias pageconfigure itemconfigure alias pageconfiginfo itemconfiginfo alias current_pageconfiginfo current_itemconfiginfo - private :itemcget, :itemconfigure - private :itemconfiginfo, :current_itemconfiginfo + private :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo #################################### diff --git a/ext/tk/lib/tkextlib/iwidgets/tabset.rb b/ext/tk/lib/tkextlib/iwidgets/tabset.rb index 618260e8e3..300ba9dee0 100644 --- a/ext/tk/lib/tkextlib/iwidgets/tabset.rb +++ b/ext/tk/lib/tkextlib/iwidgets/tabset.rb @@ -42,12 +42,13 @@ class Tk::Iwidgets::Tabset end alias tabcget itemcget + alias tabcget_strict itemcget_strict alias tabconfigure itemconfigure alias tabconfiginfo itemconfiginfo alias current_tabconfiginfo current_itemconfiginfo - private :itemcget, :itemconfigure - private :itemconfiginfo, :current_itemconfiginfo + private :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo #################################### diff --git a/ext/tk/lib/tkextlib/tcllib/getstring.rb b/ext/tk/lib/tkextlib/tcllib/getstring.rb index bf5e54e8cf..fc5d8b26d9 100644 --- a/ext/tk/lib/tkextlib/tcllib/getstring.rb +++ b/ext/tk/lib/tkextlib/tcllib/getstring.rb @@ -87,7 +87,7 @@ class Tk::Tcllib::GetString_Dialog @variable.value end - def cget(slot) + def cget_strict(slot) slot = slot.to_s if slot == 'text' @text @@ -95,6 +95,9 @@ class Tk::Tcllib::GetString_Dialog @keys[slot] end end + def cget(slot) + cget_strict(slot) + end def configure(slot, value=None) if slot.kind_of?(Hash) diff --git a/ext/tk/lib/tkextlib/tcllib/swaplist.rb b/ext/tk/lib/tkextlib/tcllib/swaplist.rb index 97de0a27c1..1c813e36da 100644 --- a/ext/tk/lib/tkextlib/tcllib/swaplist.rb +++ b/ext/tk/lib/tkextlib/tcllib/swaplist.rb @@ -90,7 +90,7 @@ class Tk::Tcllib::Swaplist_Dialog end alias selected value - def cget(slot) + def cget_strict(slot) slot = slot.to_s if slot == 'complete_list' @complete_list @@ -100,6 +100,9 @@ class Tk::Tcllib::Swaplist_Dialog @keys[slot] end end + def cget(slot) + cget_strict(slot) + end def configure(slot, value=None) if slot.kind_of?(Hash) diff --git a/ext/tk/lib/tkextlib/tcllib/tablelist_core.rb b/ext/tk/lib/tkextlib/tcllib/tablelist_core.rb index a939a58331..d7a6c97210 100644 --- a/ext/tk/lib/tkextlib/tcllib/tablelist_core.rb +++ b/ext/tk/lib/tkextlib/tcllib/tablelist_core.rb @@ -70,6 +70,9 @@ module Tk::Tcllib::TablelistItemConfig def cell_cget(tagOrId, option) itemcget(['cell', tagOrId], option) end + def cell_cget_strict(tagOrId, option) + itemcget_strict(['cell', tagOrId], option) + end def cell_configure(tagOrId, slot, value=None) itemconfigure(['cell', tagOrId], slot, value) end @@ -80,6 +83,7 @@ module Tk::Tcllib::TablelistItemConfig current_itemconfiginfo(['cell', tagOrId], slot) end alias cellcget cell_cget + alias cellcget_strict cell_cget_strict alias cellconfigure cell_configure alias cellconfiginfo cell_configinfo alias current_cellconfiginfo current_cell_configinfo @@ -87,6 +91,9 @@ module Tk::Tcllib::TablelistItemConfig def column_cget(tagOrId, option) itemcget(['column', tagOrId], option) end + def column_cget_strict(tagOrId, option) + itemcget_strict(['column', tagOrId], option) + end def column_configure(tagOrId, slot, value=None) itemconfigure(['column', tagOrId], slot, value) end @@ -97,6 +104,7 @@ module Tk::Tcllib::TablelistItemConfig current_itemconfiginfo(['column', tagOrId], slot) end alias columncget column_cget + alias columncget_strict column_cget_strict alias columnconfigure column_configure alias columnconfiginfo column_configinfo alias current_columnconfiginfo current_column_configinfo @@ -104,6 +112,9 @@ module Tk::Tcllib::TablelistItemConfig def row_cget(tagOrId, option) itemcget(['row', tagOrId], option) end + def row_cget_strict(tagOrId, option) + itemcget_strict(['row', tagOrId], option) + end def row_configure(tagOrId, slot, value=None) itemconfigure(['row', tagOrId], slot, value) end @@ -114,12 +125,13 @@ module Tk::Tcllib::TablelistItemConfig current_itemconfiginfo(['row', tagOrId], slot) end alias rowcget row_cget + alias rowcget_strict row_cget_strict alias rowconfigure row_configure alias rowconfiginfo row_configinfo alias current_rowconfiginfo current_row_configinfo - private :itemcget, :itemconfigure - private :itemconfiginfo, :current_itemconfiginfo + private :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo end class Tk::Tcllib::Tablelist diff --git a/ext/tk/lib/tkextlib/tile/dialog.rb b/ext/tk/lib/tkextlib/tile/dialog.rb index b10378d7de..ef2d1fe577 100644 --- a/ext/tk/lib/tkextlib/tile/dialog.rb +++ b/ext/tk/lib/tkextlib/tile/dialog.rb @@ -54,9 +54,21 @@ class Tk::Tile::Dialog window(tk_call_without_enc('::ttk::dialog::clientframe', @path)) end - def cget(slot) - @keys[slot] + def cget_strict(slot) + @keys[slot.to_s] end + def cget(slot) + @keys[slot.to_s] + end +=begin + def cget(slot) + unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ + cget_strict(slot) + else + cget_strict(slot) rescue nil + end + end +=end def configure(slot, value=None) if slot.kind_of?(Hash) diff --git a/ext/tk/lib/tkextlib/tile/tentry.rb b/ext/tk/lib/tkextlib/tile/tentry.rb index 4b221fcb88..0bea98dcd9 100644 --- a/ext/tk/lib/tkextlib/tile/tentry.rb +++ b/ext/tk/lib/tkextlib/tile/tentry.rb @@ -27,6 +27,11 @@ class Tk::Tile::TEntry < Tk::Entry WidgetClassName = 'TEntry'.freeze WidgetClassNames[WidgetClassName] = self + def __optkey_aliases + {:vcmd=>:validatecommand, :invcmd=>:invalidcommand} + end + private :__optkey_aliases + def __boolval_optkeys super() << 'exportselection' end diff --git a/ext/tk/lib/tkextlib/tile/tnotebook.rb b/ext/tk/lib/tkextlib/tile/tnotebook.rb index 075059d5cc..4d65e363da 100644 --- a/ext/tk/lib/tkextlib/tile/tnotebook.rb +++ b/ext/tk/lib/tkextlib/tile/tnotebook.rb @@ -41,13 +41,35 @@ class Tk::Tile::TNotebook < TkWindow private :__item_methodcall_optkeys #alias tabcget itemcget + #alias tabcget_strict itemcget_strict alias tabconfigure itemconfigure alias tabconfiginfo itemconfiginfo alias current_tabconfiginfo current_itemconfiginfo - def tabcget(tagOrId, option) + def tabcget_strict(tagOrId, option) tabconfigure(tagOrId, option)[-1] end + def tabcget(tagOrId, option) + unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ + tabcget_strict(tagOrId, option) + else + begin + tabcget_strict(tagOrId, option) + rescue => e + begin + if current_tabconfiginfo(tagOrId).has_key?(option.to_s) + # not tag error & option is known -> error on known option + fail e + else + # not tag error & option is unknown + nil + end + rescue + fail e # tag error + end + end + end + end ################################ include Tk::Tile::TileWidget diff --git a/ext/tk/lib/tkextlib/tile/tpaned.rb b/ext/tk/lib/tkextlib/tile/tpaned.rb index f24b12e92e..d96ff43973 100644 --- a/ext/tk/lib/tkextlib/tile/tpaned.rb +++ b/ext/tk/lib/tkextlib/tile/tpaned.rb @@ -66,10 +66,33 @@ class Tk::Tile::TPaned < TkWindow self end - def panecget(pane, slot) + def panecget_strict(pane, slot) pane = _epath(pane) tk_tcl2ruby(tk_send_without_enc('pane', pane, "-#{slot}")) end + alias pane_cget_strict panecget_strict + + def panecget(pane, slot) + unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ + panecget_strict(pane, slot) + else + begin + panecget_strict(pane, slot) + rescue => e + begin + if current_paneconfiginfo(pane).has_key?(slot.to_s) + # not tag error & option is known -> error on known option + fail e + else + # not tag error & option is unknown + nil + end + rescue + fail e # tag error + end + end + end + end alias pane_cget panecget def paneconfigure(pane, key, value=nil) diff --git a/ext/tk/lib/tkextlib/tile/treeview.rb b/ext/tk/lib/tkextlib/tile/treeview.rb index 7f31b9c233..c978a1a07b 100644 --- a/ext/tk/lib/tkextlib/tile/treeview.rb +++ b/ext/tk/lib/tkextlib/tile/treeview.rb @@ -33,6 +33,12 @@ module Tk::Tile::TreeviewConfig else if slot slot = slot.to_s + + alias_name, real_name = __item_optkey_aliases(tagid(tagOrId)).find{|k, v| k.to_s == slot} + if real_name + slot = real_name.to_s + end + case slot when /^(#{__tile_specific_item_optkeys(tagid(tagOrId)).join('|')})$/ begin @@ -198,6 +204,12 @@ module Tk::Tile::TreeviewConfig else if slot slot = slot.to_s + + alias_name, real_name = __item_optkey_aliases(tagid(tagOrId)).find{|k, v| k.to_s == slot} + if real_name + slot = real_name.to_s + end + case slot when /^(#{__tile_specific_item_optkeys(tagid(tagOrId)).join('|')})$/ begin @@ -508,17 +520,21 @@ module Tk::Tile::TreeviewConfig end alias __itemcget itemcget + alias __itemcget_strict itemcget_strict alias __itemconfigure itemconfigure alias __itemconfiginfo itemconfiginfo alias __current_itemconfiginfo current_itemconfiginfo - private :__itemcget, :__itemconfigure - private :__itemconfiginfo, :__current_itemconfiginfo + private :__itemcget, :__itemcget_strict + private :__itemconfigure, :__itemconfiginfo, :__current_itemconfiginfo # Treeview Item def itemcget(tagOrId, option) __itemcget([:item, tagOrId], option) end + def itemcget_strict(tagOrId, option) + __itemcget_strict([:item, tagOrId], option) + end def itemconfigure(tagOrId, slot, value=None) __itemconfigure([:item, tagOrId], slot, value) end @@ -533,6 +549,9 @@ module Tk::Tile::TreeviewConfig def columncget(tagOrId, option) __itemcget([:column, tagOrId], option) end + def columncget_strict(tagOrId, option) + __itemcget_strict([:column, tagOrId], option) + end def columnconfigure(tagOrId, slot, value=None) __itemconfigure([:column, tagOrId], slot, value) end @@ -543,12 +562,13 @@ module Tk::Tile::TreeviewConfig __current_itemconfiginfo([:column, tagOrId], slot) end alias column_cget columncget + alias column_cget_strict columncget_strict alias column_configure columnconfigure alias column_configinfo columnconfiginfo alias current_column_configinfo current_columnconfiginfo # Treeview Heading - def headingcget(tagOrId, option) + def headingcget_strict(tagOrId, option) if __tile_specific_item_optkeys([:heading, tagOrId]).index(option.to_s) begin # On tile-0.7.{2-8}, 'state' options has no '-' at its head. @@ -558,7 +578,28 @@ module Tk::Tile::TreeviewConfig tk_call(*(__item_cget_cmd([:heading, tagOrId]) << "-#{option}")) end else - __itemcget([:heading, tagOrId], option) + __itemcget_strict([:heading, tagOrId], option) + end + end + def headingcget(tagOrId, option) + unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ + headingcget_strict(tagOrId, option) + else + begin + headingcget_strict(tagOrId, option) + rescue => e + begin + if current_headingconfiginfo(tagOrId).has_key?(option.to_s) + # not tag error & option is known -> error on known option + fail e + else + # not tag error & option is unknown + nil + end + rescue + fail e # tag error + end + end end end def headingconfigure(tagOrId, slot, value=None) @@ -590,6 +631,7 @@ module Tk::Tile::TreeviewConfig __current_itemconfiginfo([:heading, tagOrId], slot) end alias heading_cget headingcget + alias heading_cget_strict headingcget_strict alias heading_configure headingconfigure alias heading_configinfo headingconfiginfo alias current_heading_configinfo current_headingconfiginfo @@ -598,6 +640,9 @@ module Tk::Tile::TreeviewConfig def tagcget(tagOrId, option) __itemcget([:tag, tagOrId], option) end + def tagcget_strict(tagOrId, option) + __itemcget_strict([:tag, tagOrId], option) + end def tagconfigure(tagOrId, slot, value=None) __itemconfigure([:tag, tagOrId], slot, value) end @@ -608,6 +653,7 @@ module Tk::Tile::TreeviewConfig __current_itemconfiginfo([:tag, tagOrId], slot) end alias tag_cget tagcget + alias tag_cget_strict tagcget_strict alias tag_configure tagconfigure alias tag_configinfo tagconfiginfo alias current_tag_configinfo current_tagconfiginfo @@ -694,6 +740,9 @@ class Tk::Tile::Treeview::Item < TkObject def cget(option) @t.itemcget(@id, option) end + def cget_strict(option) + @t.itemcget_strict(@id, option) + end def configure(key, value=None) @t.itemconfigure(@id, key, value) @@ -933,6 +982,9 @@ class Tk::Tile::Treeview::Tag < TkObject def cget(option) @t.tagcget(@id, option) end + def cget_strict(option) + @t.tagcget_strict(@id, option) + end def configure(key, value=None) @t.tagconfigure(@id, key, value) diff --git a/ext/tk/lib/tkextlib/tktable/tktable.rb b/ext/tk/lib/tkextlib/tktable/tktable.rb index b5bf4ea6c3..f6cf24b40f 100644 --- a/ext/tk/lib/tkextlib/tktable/tktable.rb +++ b/ext/tk/lib/tkextlib/tktable/tktable.rb @@ -77,6 +77,9 @@ module Tk::TkTable::ConfigMethod def tag_cget(tagOrId, option) itemcget(['tag', tagid(tagOrId)], option) end + def tag_cget_strict(tagOrId, option) + itemcget_strict(['tag', tagid(tagOrId)], option) + end def tag_configure(tagOrId, slot, value=None) itemconfigure(['tag', tagid(tagOrId)], slot, value) end @@ -90,6 +93,9 @@ module Tk::TkTable::ConfigMethod def window_cget(tagOrId, option) itemcget(['window', tagid(tagOrId)], option) end + def window_cget_strict(tagOrId, option) + itemcget_strict(['window', tagid(tagOrId)], option) + end def window_configure(tagOrId, slot, value=None) if slot == :window || slot == 'window' value = _epath(value) @@ -108,8 +114,8 @@ module Tk::TkTable::ConfigMethod current_itemconfiginfo(['window', tagid(tagOrId)], slot) end - private :itemcget, :itemconfigure - private :itemconfiginfo, :current_itemconfiginfo + private :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo end ##################################################### @@ -194,6 +200,9 @@ class Tk::TkTable::CellTag def cget(key) @t.tag_cget(@id, key) end + def cget_strict(key) + @t.tag_cget_strict(@id, key) + end def configure(key, val=None) @t.tag_configure(@id, key, val) end diff --git a/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb b/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb index 5e86a19406..e10e6e299e 100644 --- a/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb +++ b/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb @@ -417,6 +417,9 @@ module Tk::TreeCtrl::ConfigMethod def column_cget(tagOrId, option) itemcget(['column', tagOrId], option) end + def column_cget_strict(tagOrId, option) + itemcget_strict(['column', tagOrId], option) + end def column_configure(tagOrId, slot, value=None) itemconfigure(['column', tagOrId], slot, value) end @@ -430,6 +433,9 @@ module Tk::TreeCtrl::ConfigMethod def column_dragcget(option) itemcget(['column', 'drag'], option) end + def column_dragcget_strict(option) + itemcget_strict(['column', 'drag'], option) + end def column_dragconfigure(slot, value=None) itemconfigure(['column', 'drag'], slot, value) end @@ -443,6 +449,9 @@ module Tk::TreeCtrl::ConfigMethod def debug_cget(option) itemcget('debug', option) end + def debug_cget_strict(option) + itemcget_strict('debug', option) + end def debug_configure(slot, value=None) itemconfigure('debug', slot, value) end @@ -456,6 +465,9 @@ module Tk::TreeCtrl::ConfigMethod def dragimage_cget(option) itemcget('dragimage', option) end + def dragimage_cget_strict(option) + itemcget_strict('dragimage', option) + end def dragimage_configure(slot, value=None) itemconfigure('dragimage', slot, value) end @@ -469,6 +481,9 @@ module Tk::TreeCtrl::ConfigMethod def element_cget(tagOrId, option) itemcget(['element', tagOrId], option) end + def element_cget_strict(tagOrId, option) + itemcget_strict(['element', tagOrId], option) + end def element_configure(tagOrId, slot, value=None) itemconfigure(['element', tagOrId], slot, value) end @@ -482,6 +497,9 @@ module Tk::TreeCtrl::ConfigMethod def item_cget(tagOrId, option) itemcget(['item', tagOrId], option) end + def item_cget_strict(tagOrId, option) + itemcget_strict(['item', tagOrId], option) + end def item_configure(tagOrId, slot, value=None) itemconfigure(['item', tagOrId], slot, value) end @@ -495,6 +513,9 @@ module Tk::TreeCtrl::ConfigMethod def item_element_cget(item, column, elem, option) itemcget([['item', 'element'], [item, column, elem]], option) end + def item_element_cget_strict(item, column, elem, option) + itemcget_strict([['item', 'element'], [item, column, elem]], option) + end def item_element_configure(item, column, elem, slot, value=None) itemconfigure([['item', 'element'], [item, column, elem]], slot, value) end @@ -508,6 +529,9 @@ module Tk::TreeCtrl::ConfigMethod def marquee_cget(option) itemcget('marquee', option) end + def marquee_cget_strict(option) + itemcget_strict('marquee', option) + end def marquee_configure(slot, value=None) itemconfigure('marquee', slot, value) end @@ -523,6 +547,17 @@ module Tk::TreeCtrl::ConfigMethod # "notify" doesn't have cget subcommand. current_itemconfiginfo(['notify', [win, pattern]])[option.to_s] end + def notify_cget_strict(win, pattern, option) + pattern = "<#{pattern}>" + # "notify" doesn't have cget subcommand. + info = current_itemconfiginfo(['notify', [win, pattern]]) + option = option.to_s + unless info.has_key?(option) + fail RuntimeError, "unknown option \"#{option}\"" + else + info[option] + end + end def notify_configure(win, pattern, slot, value=None) pattern = "<#{pattern}>" itemconfigure(['notify', [win, pattern]], slot, value) @@ -539,6 +574,9 @@ module Tk::TreeCtrl::ConfigMethod def style_cget(tagOrId, option) itemcget(['style', tagOrId], option) end + def style_cget_strict(tagOrId, option) + itemcget_strict(['style', tagOrId], option) + end def style_configure(tagOrId, slot, value=None) itemconfigure(['style', tagOrId], slot, value) end @@ -549,8 +587,8 @@ module Tk::TreeCtrl::ConfigMethod current_itemconfiginfo(['style', tagOrId], slot) end - private :itemcget, :itemconfigure - private :itemconfiginfo, :current_itemconfiginfo + private :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo end ############################################## @@ -1706,6 +1744,9 @@ class Tk::TreeCtrl::Column < TkObject def cget(opt) @tree.column_cget(@tree.column_index(@id), opt) end + def cget_strict(opt) + @tree.column_cget_strict(@tree.column_index(@id), opt) + end def configure(*args) @tree.column_configure(@tree.column_index(@id), *args) @@ -1806,6 +1847,9 @@ class Tk::TreeCtrl::Element < TkObject def cget(opt) @tree.element_cget(@id, opt) end + def cget_strict(opt) + @tree.element_cget_strict(@id, opt) + end def configure(*args) @tree.element_configure(@id, *args) @@ -1937,6 +1981,9 @@ class Tk::TreeCtrl::Item < TkObject def cget(opt) @tree.item_cget(@id, opt) end + def cget_strict(opt) + @tree.item_cget_strict(@id, opt) + end def configure(*args) @tree.item_configure(@id, *args) @@ -1970,6 +2017,9 @@ class Tk::TreeCtrl::Item < TkObject def element_cget(opt) @tree.item_element_cget(@id, opt) end + def element_cget_strict(opt) + @tree.item_element_cget_strict(@id, opt) + end def element_configure(*args) @tree.item_element_configure(@id, *args) @@ -2221,6 +2271,9 @@ class Tk::TreeCtrl::Style < TkObject def cget(opt) @tree.style_cget(@id, opt) end + def cget_strict(opt) + @tree.style_cget_strict(@id, opt) + end def configure(*args) @tree.style_configure(@id, *args) diff --git a/ext/tk/lib/tkextlib/version.rb b/ext/tk/lib/tkextlib/version.rb index f437dea7fd..434ed11a2e 100644 --- a/ext/tk/lib/tkextlib/version.rb +++ b/ext/tk/lib/tkextlib/version.rb @@ -2,5 +2,5 @@ # release date of tkextlib # module Tk - Tkextlib_RELEASE_DATE = '2008-05-14'.freeze + Tkextlib_RELEASE_DATE = '2008-05-23'.freeze end diff --git a/ext/tk/lib/tkextlib/vu/pie.rb b/ext/tk/lib/tkextlib/vu/pie.rb index 1975803db1..c1fb6857bf 100644 --- a/ext/tk/lib/tkextlib/vu/pie.rb +++ b/ext/tk/lib/tkextlib/vu/pie.rb @@ -177,6 +177,10 @@ class Tk::Vu::PieSlice @pie.itemcget(@id, slot) end + def cget_strict(slot) + @pie.itemcget_strict(@id, slot) + end + def configure(*args) @pie.itemconfigure(@id, *args) self diff --git a/ext/tk/sample/demos-en/anilabel.rb b/ext/tk/sample/demos-en/anilabel.rb index f063bc53a4..0b9bc7357e 100644 --- a/ext/tk/sample/demos-en/anilabel.rb +++ b/ext/tk/sample/demos-en/anilabel.rb @@ -15,8 +15,10 @@ $anilabel_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($anilabel_demo).pack(:fill=>:both, :expand=>true) + # label -msg = TkLabel.new($anilabel_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -25,7 +27,7 @@ msg = TkLabel.new($anilabel_demo) { msg.pack('side'=>'top') # frame -TkFrame.new($anilabel_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -43,8 +45,8 @@ TkFrame.new($anilabel_demo) {|frame| }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # create frame for label demo -f_left = TkLabelFrame.new($anilabel_demo, :text=>'Scrolling Texts') -f_right = TkLabelFrame.new($anilabel_demo, :text=>'GIF Image') +f_left = TkLabelFrame.new(base_frame, :text=>'Scrolling Texts') +f_right = TkLabelFrame.new(base_frame, :text=>'GIF Image') Tk.pack(f_left, f_right, 'side'=>'left', 'expand'=>'yes', 'fill'=>'both', 'padx'=>10, 'pady'=>10) diff --git a/ext/tk/sample/demos-en/aniwave.rb b/ext/tk/sample/demos-en/aniwave.rb index bdb8d217c0..63a04a7b98 100644 --- a/ext/tk/sample/demos-en/aniwave.rb +++ b/ext/tk/sample/demos-en/aniwave.rb @@ -16,8 +16,10 @@ $aniwave_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($aniwave_demo).pack(:fill=>:both, :expand=>true) + # create label -msg = TkLabel.new($aniwave_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -26,7 +28,7 @@ msg = TkLabel.new($aniwave_demo) { msg.pack('side'=>'top') # create frame -TkFrame.new($aniwave_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -113,4 +115,4 @@ class AnimatedWaveDemo end # Start the animation processing -AnimatedWaveDemo.new($aniwave_demo, :left).move +AnimatedWaveDemo.new(base_frame, :left).move diff --git a/ext/tk/sample/demos-en/arrow.rb b/ext/tk/sample/demos-en/arrow.rb index 4a589a0892..055cd2af3c 100644 --- a/ext/tk/sample/demos-en/arrow.rb +++ b/ext/tk/sample/demos-en/arrow.rb @@ -107,14 +107,16 @@ $arrow_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($arrow_demo).pack(:fill=>:both, :expand=>true) + # label -TkLabel.new($arrow_demo, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', +TkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', 'text'=>"This widget allows you to experiment with different widths and arrowhead shapes for lines in canvases. To change the line width or the shape of the arrowhead, drag any of the three boxes attached to the oversized arrow. The arrows on the right give examples at normal scale. The text at the bottom shows the configuration options as you'd enter them for a canvas line item."){ pack('side'=>'top') } # frame -$arrow_buttons = TkFrame.new($arrow_demo) {|frame| +$arrow_buttons = TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -132,7 +134,7 @@ $arrow_buttons = TkFrame.new($arrow_demo) {|frame| $arrow_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # canvas -$arrow_canvas = TkCanvas.new($arrow_demo, 'width'=>500, 'height'=>350, +$arrow_canvas = TkCanvas.new(base_frame, 'width'=>500, 'height'=>350, 'relief'=>'sunken', 'borderwidth'=>2) $arrow_canvas.pack('expand'=>'yes', 'fill'=>'both') diff --git a/ext/tk/sample/demos-en/bind.rb b/ext/tk/sample/demos-en/bind.rb index d4e6717483..665592a2bc 100644 --- a/ext/tk/sample/demos-en/bind.rb +++ b/ext/tk/sample/demos-en/bind.rb @@ -19,8 +19,10 @@ $bind_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($bind_demo).pack(:fill=>:both, :expand=>true) + # frame -TkFrame.new($bind_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -43,14 +45,14 @@ def tag_binding_for_bind_demo(tag, enter_style, leave_style) end # text -txt = TkText.new($bind_demo){|t| +txt = TkText.new(base_frame){|t| # setgrid 'true' #width 60 #height 24 font $font wrap 'word' - TkScrollbar.new($bind_demo) {|s| + TkScrollbar.new(base_frame) {|s| pack('side'=>'right', 'fill'=>'y') command proc{|*args| t.yview(*args)} t.yscrollcommand proc{|first,last| s.set first,last} @@ -94,32 +96,32 @@ txt = TkText.new($bind_demo){|t| } d1.bind('1', proc{ - eval_samplecode(`cat #{[$demo_dir,'items.rb'].join(File::Separator)}`) + eval_samplecode(`cat #{[$demo_dir,'items.rb'].join(File::Separator)}`, 'items.rb') }) d2.bind('1', proc{ - eval_samplecode(`cat #{[$demo_dir,'plot.rb'].join(File::Separator)}`) + eval_samplecode(`cat #{[$demo_dir,'plot.rb'].join(File::Separator)}`, 'plot.rb') }) d3.bind('1', proc{ - eval_samplecode(`cat #{[$demo_dir,'ctext.rb'].join(File::Separator)}`) + eval_samplecode(`cat #{[$demo_dir,'ctext.rb'].join(File::Separator)}`, 'ctext.rb') }) d4.bind('1', proc{ - eval_samplecode(`cat #{[$demo_dir,'arrow.rb'].join(File::Separator)}`) + eval_samplecode(`cat #{[$demo_dir,'arrow.rb'].join(File::Separator)}`, 'arrow.rb') }) d5.bind('1', proc{ - eval_samplecode(`cat #{[$demo_dir,'ruler.rb'].join(File::Separator)}`) + eval_samplecode(`cat #{[$demo_dir,'ruler.rb'].join(File::Separator)}`, 'ruler.rb') }) d6.bind('1', proc{ - eval_samplecode(`cat #{[$demo_dir,'cscroll.rb'].join(File::Separator)}`) + eval_samplecode(`cat #{[$demo_dir,'cscroll.rb'].join(File::Separator)}`, 'cscroll.rb') }) TkTextMarkInsert.new(t, '0.0') configure('state','disabled') } -txt.width 60 +txt.width 60 txt.height 24 diff --git a/ext/tk/sample/demos-en/bitmap.rb b/ext/tk/sample/demos-en/bitmap.rb index 7fd551c7a5..133adb0543 100644 --- a/ext/tk/sample/demos-en/bitmap.rb +++ b/ext/tk/sample/demos-en/bitmap.rb @@ -21,7 +21,7 @@ def bitmapRow(w,*args) TkFrame.new(row){|base| pack('side'=>'left', 'fill'=>'both', 'pady'=>'.25c', 'padx'=>'.25c') TkLabel.new(base, 'text'=>bitmap, 'width'=>9).pack('side'=>'bottom') - TkLabel.new(base, 'bitmap'=>bitmap).pack('side'=>'bottom') + Tk::Label.new(base, 'bitmap'=>bitmap).pack('side'=>'bottom') } end } @@ -40,14 +40,16 @@ $bitmap_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($bitmap_demo).pack(:fill=>:both, :expand=>true) + # label -TkLabel.new($bitmap_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left', +TkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left', 'text'=>"This window displays all of Tk's built-in bitmaps, along with the names you can use for them in Tcl scripts."){ pack('side'=>'top') } # frame -$bitmap_buttons = TkFrame.new($bitmap_demo) {|frame| +$bitmap_buttons = TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -65,7 +67,7 @@ $bitmap_buttons = TkFrame.new($bitmap_demo) {|frame| $bitmap_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # frame -TkFrame.new($bitmap_demo){|f| +TkFrame.new(base_frame){|f| bitmapRow(f,'error','gray25','gray50','hourglass') bitmapRow(f,'info','question','questhead','warning') pack('side'=>'top', 'expand'=>'yes', 'fill'=>'both') diff --git a/ext/tk/sample/demos-en/button.rb b/ext/tk/sample/demos-en/button.rb index 6614d99c92..5c03bd499b 100644 --- a/ext/tk/sample/demos-en/button.rb +++ b/ext/tk/sample/demos-en/button.rb @@ -29,7 +29,7 @@ msg = TkLabel.new($button_demo) { msg.pack('side'=>'top') # frame -$button_buttons = TkFrame.new($button_demo) {|frame| +$button_buttons = Tk::Frame.new($button_demo) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ diff --git a/ext/tk/sample/demos-en/check.rb b/ext/tk/sample/demos-en/check.rb index 971a8fea73..2951962a79 100644 --- a/ext/tk/sample/demos-en/check.rb +++ b/ext/tk/sample/demos-en/check.rb @@ -19,8 +19,10 @@ $check_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($check_demo).pack(:fill=>:both, :expand=>true) + # label -msg = TkLabel.new($check_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -34,7 +36,7 @@ brakes = TkVariable.new(0) sober = TkVariable.new(0) # frame -TkFrame.new($check_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -54,7 +56,7 @@ TkFrame.new($check_demo) {|frame| TkButton.new(frame) { text 'See Variables' command proc{ - showVars($check_demo, + showVars(base_frame, ['wipers', wipers], ['brakes', brakes], ['sober', sober]) } }.pack('side'=>'left', 'expand'=>'yes') @@ -63,8 +65,8 @@ TkFrame.new($check_demo) {|frame| # checkbutton -[ TkCheckButton.new($check_demo, 'text'=>'Wipers OK', 'variable'=>wipers), - TkCheckButton.new($check_demo, 'text'=>'Brakes OK', 'variable'=>brakes), - TkCheckButton.new($check_demo, 'text'=>'Driver Sober', 'variable'=>sober) +[ TkCheckButton.new(base_frame, 'text'=>'Wipers OK', 'variable'=>wipers), + TkCheckButton.new(base_frame, 'text'=>'Brakes OK', 'variable'=>brakes), + TkCheckButton.new(base_frame, 'text'=>'Driver Sober', 'variable'=>sober) ].each{|w| w.relief('flat'); w.pack('side'=>'top', 'pady'=>2, 'anchor'=>'w')} diff --git a/ext/tk/sample/demos-en/check2.rb b/ext/tk/sample/demos-en/check2.rb index 97d61fba0c..faea748a87 100644 --- a/ext/tk/sample/demos-en/check2.rb +++ b/ext/tk/sample/demos-en/check2.rb @@ -15,8 +15,10 @@ $check2_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($check2_demo).pack(:fill=>:both, :expand=>true) + # label -msg = TkLabel.new($check2_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -31,7 +33,7 @@ brakes = TkVariable.new(0) sober = TkVariable.new(0) # frame -TkFrame.new($check2_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkGrid(TkFrame.new(frame, :height=>2, :relief=>:sunken, :bd=>2), :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) TkGrid('x', @@ -59,15 +61,15 @@ TkFrame.new($check2_demo) {|frame| # checkbutton -TkCheckButton.new($check2_demo, :text=>'Safety Check', :variable=>safety, +TkCheckButton.new(base_frame, :text=>'Safety Check', :variable=>safety, :relief=>:flat, :onvalue=>'all', :offvalue=>'none', :tristatevalue=>'partial'){ pack('side'=>'top', 'pady'=>2, 'anchor'=>'w') } -[ TkCheckButton.new($check2_demo, 'text'=>'Wipers OK', 'variable'=>wipers), - TkCheckButton.new($check2_demo, 'text'=>'Brakes OK', 'variable'=>brakes), - TkCheckButton.new($check2_demo, 'text'=>'Driver Sober', 'variable'=>sober) +[ TkCheckButton.new(base_frame, 'text'=>'Wipers OK', 'variable'=>wipers), + TkCheckButton.new(base_frame, 'text'=>'Brakes OK', 'variable'=>brakes), + TkCheckButton.new(base_frame, 'text'=>'Driver Sober', 'variable'=>sober) ].each{|w| w.relief('flat') w.pack('side'=>'top', 'padx'=>15, 'pady'=>2, 'anchor'=>'w') diff --git a/ext/tk/sample/demos-en/clrpick.rb b/ext/tk/sample/demos-en/clrpick.rb index 9486fde314..431439d55d 100644 --- a/ext/tk/sample/demos-en/clrpick.rb +++ b/ext/tk/sample/demos-en/clrpick.rb @@ -4,6 +4,8 @@ # # widget demo prompts the user to select a color (called by 'widget') # +# Note: don't support ttk_wrapper. work with standard widgets only. +# # toplevel widget if defined?($clrpick_demo) && $clrpick_demo @@ -18,13 +20,18 @@ $clrpick_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($clrpick_demo).pack(:fill=>:both, :expand=>true) + # label -TkLabel.new($clrpick_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left', +#TkLabel.new($clrpick_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left', +Tk::Label.new($clrpick_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left', 'text'=>"Press the buttons below to choose the foreground and background colors for the widgets in this window.").pack('side'=>'top') # frame -TkFrame.new($clrpick_demo) {|frame| - TkButton.new(frame) { +#TkFrame.new($clrpick_demo) {|frame| +Tk::Frame.new($clrpick_demo) {|frame| + # TkButton.new(frame) { + Tk::Button.new(frame) { text 'Dismiss' command proc{ tmppath = $clrpick_demo @@ -33,20 +40,23 @@ TkFrame.new($clrpick_demo) {|frame| } }.pack('side'=>'left', 'expand'=>'yes') - TkButton.new(frame) { + # TkButton.new(frame) { + Tk::Button.new(frame) { text 'Show Code' command proc{showCode 'clrpick'} }.pack('side'=>'left', 'expand'=>'yes') }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # button -TkButton.new($clrpick_demo, 'text'=>'Set background color ...') {|b| +# TkButton.new($clrpick_demo, 'text'=>'Set background color ...') {|b| +Tk::Button.new($clrpick_demo, 'text'=>'Set background color ...') {|b| command(proc{setColor $clrpick_demo, b, 'background', ['background', 'highlightbackground']}) pack('side'=>'top', 'anchor'=>'c', 'pady'=>'2m') } -TkButton.new($clrpick_demo, 'text'=>'Set foreground color ...') {|b| +# TkButton.new($clrpick_demo, 'text'=>'Set foreground color ...') {|b| +Tk::Button.new($clrpick_demo, 'text'=>'Set foreground color ...') {|b| command(proc{setColor $clrpick_demo, b, 'foreground', ['foreground']}) pack('side'=>'top', 'anchor'=>'c', 'pady'=>'2m') } diff --git a/ext/tk/sample/demos-en/colors.rb b/ext/tk/sample/demos-en/colors.rb index 66fb0afa36..4300a660ae 100644 --- a/ext/tk/sample/demos-en/colors.rb +++ b/ext/tk/sample/demos-en/colors.rb @@ -20,8 +20,10 @@ $colors_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($colors_demo).pack(:fill=>:both, :expand=>true) + # label -msg = TkLabel.new($colors_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -30,7 +32,7 @@ msg = TkLabel.new($colors_demo) { msg.pack('side'=>'top') # frame -TkFrame.new($colors_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -49,7 +51,7 @@ TkFrame.new($colors_demo) {|frame| # frame colors_lbox = nil -TkFrame.new($colors_demo, 'borderwidth'=>10) {|w| +TkFrame.new(base_frame, 'borderwidth'=>10) {|w| s = TkScrollbar.new(w) colors_lbox = TkListbox.new(w) { setgrid 1 @@ -62,7 +64,15 @@ TkFrame.new($colors_demo, 'borderwidth'=>10) {|w| colors_lbox.pack('side'=>'left', 'expand'=>1, 'fill'=>'both') }.pack('side'=>'top', 'expand'=>'yes', 'fill'=>'y') -colors_lbox.bind('Double-1', proc{TkPalette.setPalette TkSelection.get}) +#colors_lbox.bind('Double-1', proc{TkPalette.setPalette TkSelection.get}) +colors_lbox.bind('Double-1', proc{ + begin + TkPalette.setPalette TkSelection.get + rescue => e + p e + Tk.tk_call_without_enc('destroy', '.___tk_set_palette') + end + }) ins_data = [ 'gray60','gray70','gray80','gray85','gray90','gray95', diff --git a/ext/tk/sample/demos-en/combo.rb b/ext/tk/sample/demos-en/combo.rb new file mode 100644 index 0000000000..0907d9e8ec --- /dev/null +++ b/ext/tk/sample/demos-en/combo.rb @@ -0,0 +1,96 @@ +# combo.rb -- +# +# This demonstration script creates several combobox widgets. +# +# based on "Id: combo.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp" + +if defined?($combo_demo) && $combo_demo + $combo_demo.destroy + $combo_demo = nil +end + +$combo_demo = TkToplevel.new {|w| + title("Combobox Demonstration") + iconname("combo") + positionWindow(w) +} + +base_frame = TkFrame.new($combo_demo).pack(:fill=>:both, :expand=>true) + +Ttk::Label.new(base_frame, :font=>$font, :wraplength=>'5i', :justify=>:left, + :text=><:top, :fill=>:x) +Three different combo-boxes are displayed below. \ +You can add characters to the first \ +one by pointing, clicking and typing, just as with an entry; pressing \ +Return will cause the current value to be added to the list that is \ +selectable from the drop-down list, and you can choose other values \ +by pressing the Down key, using the arrow keys to pick another one, \ +and pressing Return again. The second combo-box is fixed to a \ +particular value, and cannot be modified at all. The third one only \ +allows you to select values from its drop-down list of Australian \ +cities. +EOL + +## variables +firstValue = TkVariable.new +secondValue = TkVariable.new +ozCity = TkVariable.new + +## See Code / Dismiss buttons +Ttk::Frame.new(base_frame) {|frame| + sep = Ttk::Separator.new(frame) + Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + Ttk::Button.new(frame, :text=>'See Variables', + :image=>$image['view'], :compound=>:left, + :command=>proc{ + showVars(base_frame, + ['firstVariable', firstValue], + ['secondVariable', secondValue], + ['ozCity', ozCity]) + }), + Ttk::Button.new(frame, :text=>'See Code', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'combo'}), + Ttk::Button.new(frame, :text=>'Dismiss', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + $combo_demo.destroy + $combo_demo = nil + }), + :padx=>4, :pady=>4) + grid_columnconfigure(0, :weight=>1) + pack(:side=>:bottom, :fill=>:x) +} + +frame = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true) + +australianCities = [ + 'Canberra', 'Sydney', 'Melbourne', 'Perth', 'Adelaide', 'Brisbane', + 'Hobart', 'Darwin', 'Alice Springs' +] + + +secondValue.value = 'unchangable' +ozCity.value = 'Sydney' + +Tk.pack(Ttk::Labelframe.new(frame, :text=>'Fully Editable'){|f| + Ttk::Combobox.new(f, :textvariable=>firstValue){|b| + b.bind('Return', '%W'){|w| + w.values <<= w.value unless w.values.include?(w.value) + } + }.pack(:pady=>5, :padx=>10) + }, + + Ttk::LabelFrame.new(frame, :text=>'Disabled'){|f| + Ttk::Combobox.new(f, :textvariable=>secondValue, :state=>:disabled) . + pack(:pady=>5, :padx=>10) + }, + + Ttk::LabelFrame.new(frame, :text=>'Defined List Only'){|f| + Ttk::Combobox.new(f, :textvariable=>ozCity, :state=>:readonly, + :values=>australianCities) . + pack(:pady=>5, :padx=>10) + }, + + :side=>:top, :pady=>5, :padx=>10) diff --git a/ext/tk/sample/demos-en/cscroll.rb b/ext/tk/sample/demos-en/cscroll.rb index 0838dfbe08..259ed3bd8c 100644 --- a/ext/tk/sample/demos-en/cscroll.rb +++ b/ext/tk/sample/demos-en/cscroll.rb @@ -19,14 +19,16 @@ $cscroll_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($cscroll_demo).pack(:fill=>:both, :expand=>true) + # label -TkLabel.new($cscroll_demo, 'font'=>$font, 'wraplength'=>'4i', +TkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'4i', 'justify'=>'left', 'text'=>"This window displays a canvas widget that can be scrolled either using the scrollbars or by dragging with button 2 in the canvas. If you click button 1 on one of the rectangles, its indices will be printed on stdout."){ pack('side'=>'top') } # frame -$cscroll_buttons = TkFrame.new($cscroll_demo) {|frame| +$cscroll_buttons = TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -45,7 +47,7 @@ $cscroll_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # frame unless $tk_version =~ /^4\.[01]/ - $cscroll_grid = TkFrame.new($cscroll_demo) { + $cscroll_grid = TkFrame.new(base_frame) { pack('expand'=>'yes', 'fill'=>'both', 'padx'=>1, 'pady'=>1) } TkGrid.rowconfigure($cscroll_grid, 0, 'weight'=>1, 'minsize'=>0) @@ -53,7 +55,7 @@ unless $tk_version =~ /^4\.[01]/ end # canvas -$cscroll_canvas = TkCanvas.new($cscroll_demo, +$cscroll_canvas = TkCanvas.new(base_frame, 'relief'=>'sunken', 'borderwidth'=>2, 'scrollregion'=>['-11c', '-11c', '50c', '20c'] ) {|c| @@ -64,7 +66,7 @@ $cscroll_canvas = TkCanvas.new($cscroll_demo, 'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news') end - TkScrollbar.new($cscroll_demo, 'command'=>proc{|*args| c.yview(*args)}) {|vs| + TkScrollbar.new(base_frame, 'command'=>proc{|*args| c.yview(*args)}) {|vs| c.yscrollcommand(proc{|first,last| vs.set first,last}) if $tk_version =~ /^4\.[01]/ pack('side'=>'right', 'fill'=>'y') @@ -74,7 +76,7 @@ $cscroll_canvas = TkCanvas.new($cscroll_demo, end } - TkScrollbar.new($cscroll_demo, 'orient'=>'horiz', + TkScrollbar.new(base_frame, 'orient'=>'horiz', 'command'=>proc{|*args| c.xview(*args)}) {|hs| c.xscrollcommand(proc{|first,last| hs.set first,last}) if $tk_version =~ /^4\.[01]/ diff --git a/ext/tk/sample/demos-en/ctext.rb b/ext/tk/sample/demos-en/ctext.rb index 8c10880ed6..01374b0321 100644 --- a/ext/tk/sample/demos-en/ctext.rb +++ b/ext/tk/sample/demos-en/ctext.rb @@ -19,8 +19,10 @@ $ctext_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($ctext_demo).pack(:fill=>:both, :expand=>true) + # label -TkLabel.new($ctext_demo, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', +TkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', 'text'=>"This window displays a string of text to demonstrate the text facilities of canvas widgets. You can click in the boxes to adjust the position of the text relative to its positioning point or change its justification. The text also supports the following simple bindings for editing: 1. You can point, click, and type. 2. You can also select with button 1. @@ -33,7 +35,7 @@ TkLabel.new($ctext_demo, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', } # frame -$ctext_buttons = TkFrame.new($ctext_demo) {|frame| +$ctext_buttons = TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -51,7 +53,7 @@ $ctext_buttons = TkFrame.new($ctext_demo) {|frame| $ctext_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # canvas -$ctext_canvas = TkCanvas.new($ctext_demo, 'relief'=>'flat', +$ctext_canvas = TkCanvas.new(base_frame, 'relief'=>'flat', 'borderwidth'=>0, 'width'=>500, 'height'=>350) $ctext_canvas.pack('side'=>'top', 'expand'=>'yes', 'fill'=>'both') diff --git a/ext/tk/sample/demos-en/entry1.rb b/ext/tk/sample/demos-en/entry1.rb index 29bc693395..6f5b10fb71 100644 --- a/ext/tk/sample/demos-en/entry1.rb +++ b/ext/tk/sample/demos-en/entry1.rb @@ -15,8 +15,10 @@ $entry1_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($entry1_demo).pack(:fill=>:both, :expand=>true) + # label -msg = TkLabel.new($entry1_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '5i' justify 'left' @@ -25,7 +27,7 @@ msg = TkLabel.new($entry1_demo) { msg.pack('side'=>'top') # frame -TkFrame.new($entry1_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -42,9 +44,9 @@ TkFrame.new($entry1_demo) {|frame| }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # -e1 = TkEntry.new($entry1_demo, 'relief'=>'sunken') -e2 = TkEntry.new($entry1_demo, 'relief'=>'sunken') -e3 = TkEntry.new($entry1_demo, 'relief'=>'sunken') +e1 = TkEntry.new(base_frame, 'relief'=>'sunken') +e2 = TkEntry.new(base_frame, 'relief'=>'sunken') +e3 = TkEntry.new(base_frame, 'relief'=>'sunken') [e1,e2,e3].each{|w| w.pack('side'=>'top', 'padx'=>10, 'pady'=>5, 'fill'=>'x')} # diff --git a/ext/tk/sample/demos-en/entry2.rb b/ext/tk/sample/demos-en/entry2.rb index d4e58d7dd5..d67d04b56d 100644 --- a/ext/tk/sample/demos-en/entry2.rb +++ b/ext/tk/sample/demos-en/entry2.rb @@ -19,8 +19,10 @@ $entry2_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($entry2_demo).pack(:fill=>:both, :expand=>true) + # label -msg = TkLabel.new($entry2_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '5i' justify 'left' @@ -29,7 +31,7 @@ msg = TkLabel.new($entry2_demo) { msg.pack('side'=>'top') # frame -TkFrame.new($entry2_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -46,7 +48,7 @@ TkFrame.new($entry2_demo) {|frame| }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # frame -TkFrame.new($entry2_demo, 'borderwidth'=>10) {|w| +TkFrame.new(base_frame, 'borderwidth'=>10) {|w| # entry 1 s1 = TkScrollbar.new(w, 'relief'=>'sunken', 'orient'=>'horiz') e1 = TkEntry.new(w, 'relief'=>'sunken') { diff --git a/ext/tk/sample/demos-en/entry3.rb b/ext/tk/sample/demos-en/entry3.rb index 68f77a0d48..f7df3a5653 100644 --- a/ext/tk/sample/demos-en/entry3.rb +++ b/ext/tk/sample/demos-en/entry3.rb @@ -17,7 +17,9 @@ $entry3_demo = TkToplevel.new {|w| positionWindow(w) } -TkLabel.new($entry3_demo, +base_frame = TkFrame.new($entry3_demo).pack(:fill=>:both, :expand=>true) + +TkLabel.new(base_frame, :font=>$font, :wraplength=>'5i', :justify=>:left, :text=><:top) Four different entries are displayed below. You can add characters \ @@ -34,7 +36,7 @@ characters (silently ignoring further ones), and displaying them as \ asterisk characters. EOL -TkFrame.new($entry3_demo){|f| +TkFrame.new(base_frame){|f| pack(:side=>:bottom, :fill=>:x, :pady=>'2m') TkButton.new(f, :text=>'Dismiss', :width=>15, :command=>proc{ @@ -60,23 +62,41 @@ TkFrame.new($entry3_demo){|f| # count - Counter to control the number of times flashed def focusAndFlash(widget, fg, bg, count=5) return if count <= 0 - TkTimer.new(200, count, - proc{widget.configure(:foreground=>bg, :background=>fg)}, - proc{widget.configure(:foreground=>fg, :background=>bg)} - ).start + if fg && !fg.empty? && bg && !bg.empty? + TkTimer.new(200, count, + proc{widget.configure(:foreground=>bg, :background=>fg)}, + proc{widget.configure(:foreground=>fg, :background=>bg)} + ).start + else + # TkTimer.new(150, 3){Tk.bell}.start + Tk.bell + TkTimer.new(200, count, + proc{widget.configure(:foreground=>'white', + :background=>'black')}, + proc{widget.configure(:foreground=>'black', + :background=>'white')} + ).at_end{begin + widget.configure(:foreground=>fg, + :background=>bg) + rescue + # ignore + end}.start + end widget.focus(true) end -l1 = TkLabelFrame.new($entry3_demo, :text=>"Integer Entry") +l1 = TkLabelFrame.new(base_frame, :text=>"Integer Entry") TkEntry.new(l1, :validate=>:focus, :vcmd=>[ proc{|s| s == '' || /^[+-]?\d+$/ =~ s }, '%P' ]) {|e| - invalidcommand [proc{|w| focusAndFlash(w, e.fg, e.bg)}, '%W'] + fg = e.foreground + bg = e.background + invalidcommand [proc{|w| focusAndFlash(w, fg, bg)}, '%W'] pack(:fill=>:x, :expand=>true, :padx=>'1m', :pady=>'1m') } -l2 = TkLabelFrame.new($entry3_demo, :text=>"Length-Constrained Entry") +l2 = TkLabelFrame.new(base_frame, :text=>"Length-Constrained Entry") TkEntry.new(l2, :validate=>:key, :invcmd=>proc{Tk.bell}, :vcmd=>[proc{|s| s.length < 10}, '%P'] ).pack(:fill=>:x, :expand=>true, :padx=>'1m', :pady=>'1m') @@ -158,14 +178,14 @@ def validatePhoneChange(widget, vmode, idx, char) widget.insert(idx, $phoneNumberMap[char] || char) Tk.after_idle(proc{phoneSkipRight(widget, -1)}) return true - # Tk.update(true) # Don't work 'update' inter validation callback. - # It depends on Tcl/Tk side (tested on Tcl/Tk8.5a1). + # Tk.update(true) # <- Don't work 'update' inter validation callback. + # It depends on Tcl/Tk side (tested on Tcl/Tk8.5a1). end return false end -l3 = TkLabelFrame.new($entry3_demo, :text=>"US Phone-Number Entry") +l3 = TkLabelFrame.new(base_frame, :text=>"US Phone-Number Entry") TkEntry.new(l3, :validate=>:key, :invcmd=>proc{Tk.bell}, :textvariable=>entry3content, :vcmd=>[ @@ -184,14 +204,14 @@ TkEntry.new(l3, :validate=>:key, :invcmd=>proc{Tk.bell}, pack(:fill=>:x, :expand=>true, :padx=>'1m', :pady=>'1m') } -l4 = TkLabelFrame.new($entry3_demo, :text=>"Password Entry") +l4 = TkLabelFrame.new(base_frame, :text=>"Password Entry") TkEntry.new(l4, :validate=>:key, :show=>'*', :vcmd=>[ proc{|s| s.length <= 8}, '%P' ]).pack(:fill=>:x, :expand=>true, :padx=>'1m', :pady=>'1m') -TkFrame.new($entry3_demo){|f| +TkFrame.new(base_frame){|f| lower TkGrid.configure(l1, l2, :in=>f, :padx=>'3m', :pady=>'1m', :sticky=>:ew) TkGrid.configure(l3, l4, :in=>f, :padx=>'3m', :pady=>'1m', :sticky=>:ew) diff --git a/ext/tk/sample/demos-en/filebox.rb b/ext/tk/sample/demos-en/filebox.rb index 36b19de557..676c347409 100644 --- a/ext/tk/sample/demos-en/filebox.rb +++ b/ext/tk/sample/demos-en/filebox.rb @@ -17,12 +17,14 @@ $filebox_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($filebox_demo).pack(:fill=>:both, :expand=>true) + # label -TkLabel.new($filebox_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left', +TkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left', 'text'=>"Enter a file name in the entry box or click on the \"Browse\" buttons to select a file name using the file selection dialog.").pack('side'=>'top') # frame -TkFrame.new($filebox_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -40,7 +42,7 @@ TkFrame.new($filebox_demo) {|frame| # frame ['open', 'save'].each{|type| - TkFrame.new($filebox_demo) {|f| + TkFrame.new(base_frame) {|f| TkLabel.new(f, 'text'=>"Select a file to #{type}: ", 'anchor'=>'e')\ .pack('side'=>'left') @@ -48,7 +50,7 @@ TkFrame.new($filebox_demo) {|frame| pack('side'=>'left', 'expand'=>'yes', 'fill'=>'x') TkButton.new(f, 'text'=>'Browse ...', - 'command'=>proc{fileDialog $filebox_demo,e,type})\ + 'command'=>proc{fileDialog base_frame,e,type})\ .pack('side'=>'left') } @@ -58,7 +60,7 @@ TkFrame.new($filebox_demo) {|frame| $tk_strictMotif = TkVarAccess.new('tk_strictMotif') if ($tk_platform['platform'] == 'unix') - TkCheckButton.new($filebox_demo, + TkCheckButton.new(base_frame, 'text'=>'Use Motif Style Dialog', 'variable'=>$tk_strictMotif, 'onvalue'=>1, 'offvalue'=>0 ).pack('anchor'=>'c') @@ -91,7 +93,10 @@ def fileDialog(w,ent,operation) if file != "" ent.delete 0, 'end' ent.insert 0, file - ent.xview 'end' + # ent.xview 'end' + Tk.update_idletasks # need this for Tk::Tile::Entry + # (to find right position of 'xview'). + ent.xview(ent.index('end')) end end diff --git a/ext/tk/sample/demos-en/floor.rb b/ext/tk/sample/demos-en/floor.rb index 53adcf96b6..7023f2a72e 100644 --- a/ext/tk/sample/demos-en/floor.rb +++ b/ext/tk/sample/demos-en/floor.rb @@ -1590,14 +1590,16 @@ $floor_demo = TkToplevel.new {|w| minsize(100,100) } +base_frame = TkFrame.new($floor_demo).pack(:fill=>:both, :expand=>true) + # label -TkLabel.new($floor_demo, 'font'=>$font, 'wraplength'=>'8i', 'justify'=>'left', +TkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'8i', 'justify'=>'left', 'text'=>"This window contains a canvas widget showing the floorplan of Digital Equipment Corporation's Western Research Laboratory. It has three levels. At any given time one of the levels is active, meaning that you can see its room structure. To activate a level, click the left mouse button anywhere on it. As the mouse moves over the active level, the room under the mouse lights up and its room number appears in the \"Room:\" entry. You can also type a room number in the entry and the room will light up."){ pack('side'=>'top') } # frame -$floor_buttons = TkFrame.new($floor_demo) {|frame| +$floor_buttons = TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -1620,17 +1622,17 @@ $floorItems = {} # canvas if $tk_version =~ /^4\.[01]/ - $floor_canvas_frame = TkFrame.new($floor_demo,'bd'=>2,'relief'=>'sunken', + $floor_canvas_frame = TkFrame.new(base_frame,'bd'=>2,'relief'=>'sunken', 'highlightthickness'=>2) $floor_canvas = TkCanvas.new($floor_canvas_frame, 'width'=>900, 'height'=>500, 'borderwidth'=>0, 'highlightthickness'=>0) {|c| - TkScrollbar.new($floor_demo, 'orient'=>'horiz', + TkScrollbar.new(base_frame, 'orient'=>'horiz', 'command'=>proc{|*args| c.xview(*args)}){|hs| c.xscrollcommand(proc{|first,last| hs.set first,last}) pack('side'=>'bottom', 'fill'=>'x') } - TkScrollbar.new($floor_demo, 'command'=>proc{|*args| c.yview(*args)}){|vs| + TkScrollbar.new(base_frame, 'command'=>proc{|*args| c.yview(*args)}){|vs| c.yscrollcommand(proc{|first,last| vs.set first,last}) pack('side'=>'right', 'fill'=>'y') } @@ -1639,7 +1641,7 @@ if $tk_version =~ /^4\.[01]/ $floor_canvas.pack('expand'=>'yes', 'fill'=>'both') else - TkFrame.new($floor_demo) {|f| + TkFrame.new(base_frame) {|f| pack('side'=>'top', 'fill'=>'both', 'expand'=>'yes') h = TkScrollbar.new(f, 'highlightthickness'=>0, 'orient'=>'horizontal') diff --git a/ext/tk/sample/demos-en/floor2.rb b/ext/tk/sample/demos-en/floor2.rb index efaf9e250d..88b07aeee4 100644 --- a/ext/tk/sample/demos-en/floor2.rb +++ b/ext/tk/sample/demos-en/floor2.rb @@ -1590,14 +1590,16 @@ $floor2_demo = TkToplevel.new {|w| minsize(100,100) } +base_frame = TkFrame.new($floor2_demo).pack(:fill=>:both, :expand=>true) + # label -TkLabel.new($floor2_demo, 'font'=>$font, 'wraplength'=>'8i', 'justify'=>'left', +TkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'8i', 'justify'=>'left', 'text'=>"This window contains a canvas widget showing the floorplan of Digital Equipment Corporation's Western Research Laboratory. It has three levels. At any given time one of the levels is active, meaning that you can see its room structure. To activate a level, click the left mouse button anywhere on it. As the mouse moves over the active level, the room under the mouse lights up and its room number appears in the \"Room:\" entry. You can also type a room number in the entry and the room will light up."){ pack('side'=>'top') } # frame -$floor2_buttons = TkFrame.new($floor2_demo) {|frame| +$floor2_buttons = TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -1620,17 +1622,17 @@ $floorItems2 = {} # canvas if $tk_version =~ /^4\.[01]/ - $floor2_canvas_frame = TkFrame.new($floor2_demo,'bd'=>2,'relief'=>'sunken', + $floor2_canvas_frame = TkFrame.new(base_frame,'bd'=>2,'relief'=>'sunken', 'highlightthickness'=>2) $floor2_canvas = TkCanvas.new($floor2_canvas_frame, 'width'=>900, 'height'=>500, 'borderwidth'=>0, 'highlightthickness'=>0) {|c| - TkScrollbar.new($floor2_demo, 'orient'=>'horiz', + TkScrollbar.new(base_frame, 'orient'=>'horiz', 'command'=>proc{|*args| c.xview(*args)}){|hs| c.xscrollcommand(proc{|first,last| hs.set first,last}) pack('side'=>'bottom', 'fill'=>'x') } - TkScrollbar.new($floor2_demo, 'command'=>proc{|*args| c.yview(*args)}){|vs| + TkScrollbar.new(base_frame, 'command'=>proc{|*args| c.yview(*args)}){|vs| c.yscrollcommand(proc{|first,last| vs.set first,last}) pack('side'=>'right', 'fill'=>'y') } @@ -1639,7 +1641,7 @@ if $tk_version =~ /^4\.[01]/ $floor2_canvas.pack('expand'=>'yes', 'fill'=>'both') else - TkFrame.new($floor2_demo) {|f| + TkFrame.new(base_frame) {|f| pack('side'=>'top', 'fill'=>'both', 'expand'=>'yes') h = TkScrollbar.new(f, 'highlightthickness'=>0, 'orient'=>'horizontal') diff --git a/ext/tk/sample/demos-en/form.rb b/ext/tk/sample/demos-en/form.rb index dbb14302dc..3119752b1c 100644 --- a/ext/tk/sample/demos-en/form.rb +++ b/ext/tk/sample/demos-en/form.rb @@ -15,8 +15,10 @@ $form_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($form_demo).pack(:fill=>:both, :expand=>true) + # label -msg = TkLabel.new($form_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -25,7 +27,7 @@ msg = TkLabel.new($form_demo) { msg.pack('side'=>'top', 'fill'=>'x') # frame -TkFrame.new($form_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -44,7 +46,7 @@ TkFrame.new($form_demo) {|frame| # entry form_data = [] (1..5).each{|i| - f = TkFrame.new($form_demo, 'bd'=>2) + f = TkFrame.new(base_frame, 'bd'=>2) e = TkEntry.new(f, 'relief'=>'sunken', 'width'=>40) l = TkLabel.new(f) e.pack('side'=>'right') diff --git a/ext/tk/sample/demos-en/goldberg.rb b/ext/tk/sample/demos-en/goldberg.rb index 8d3f6d14f7..c6fa37c09c 100644 --- a/ext/tk/sample/demos-en/goldberg.rb +++ b/ext/tk/sample/demos-en/goldberg.rb @@ -54,6 +54,8 @@ $goldberg_demo = TkToplevel.new {|w| # positionWindow(w) } +base_frame = TkFrame.new($goldberg_demo).pack(:fill=>:both, :expand=>true) + =begin # label msg = TkLabel.new($goldberg_demo) { @@ -175,7 +177,8 @@ class TkGoldberg_Demo do_ctrl_frame do_detail_frame - msg = TkLabel.new(@parent, :bg=>@C['bg'], :fg=>'white') { + # msg = TkLabel.new(@parent, :bg=>@C['bg'], :fg=>'white') { + msg = Tk::Label.new(@parent, :bg=>@C['bg'], :fg=>'white') { font 'Arial 10' wraplength 600 justify 'left' @@ -185,7 +188,8 @@ class TkGoldberg_Demo frame = TkFrame.new(@parent, :bg=>@C['bg']) - TkButton.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) { + # TkButton.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) { + Tk::Button.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) { text 'Dismiss' command proc{ tmppath = $goldberg_demo @@ -194,12 +198,14 @@ class TkGoldberg_Demo } }.pack('side'=>'left') - TkButton.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) { + # TkButton.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) { + Tk::Button.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) { text 'See Code' command proc{showCode 'goldberg'} }.pack('side'=>'left', 'padx'=>5) - @show = TkButton.new(frame, :text=>'>>', :command=>proc{show_ctrl}, + # @show = TkButton.new(frame, :text=>'>>', :command=>proc{show_ctrl}, + @show = Tk::Button.new(frame, :text=>'>>', :command=>proc{show_ctrl}, :bg=>@C['bg'], :activebackground=>@C['bg']) @show.pack('side'=>'left') frame.place(:in=>@canvas, :relx=>1, :rely=>0, :anchor=>:ne) @@ -208,10 +214,11 @@ class TkGoldberg_Demo end def do_ctrl_frame - @start = TkButton.new(@parent, :text=>'Start', :bd=>6, + @start = Tk::Button.new(@parent, :text=>'Start', :bd=>6, :command=>proc{do_button(0)}) - @start.font(@start['font'].weight('bold')) - font = @start['font'] + if font = @start['font'] + @start.font(font.weight('bold')) + end @pause = TkCheckbutton.new(@parent, :text=>'Pause', :font=>font, :command=>proc{do_button(1)}, :relief=>:raised, @@ -1996,4 +2003,4 @@ class TkGoldberg_Demo end end -TkGoldberg_Demo.new($goldberg_demo) +TkGoldberg_Demo.new(base_frame) diff --git a/ext/tk/sample/demos-en/hscale.rb b/ext/tk/sample/demos-en/hscale.rb index 743c4b4852..e660216967 100644 --- a/ext/tk/sample/demos-en/hscale.rb +++ b/ext/tk/sample/demos-en/hscale.rb @@ -11,8 +11,9 @@ $hscale_demo = TkToplevel.new {|w| } positionWindow($hscale_demo) +base_frame = TkFrame.new($hscale_demo).pack(:fill=>:both, :expand=>true) -msg = TkLabel.new($hscale_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '3.5i' justify 'left' @@ -20,7 +21,7 @@ msg = TkLabel.new($hscale_demo) { } msg.pack('side'=>'top') -TkFrame.new($hscale_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc { @@ -36,7 +37,18 @@ TkFrame.new($hscale_demo) {|frame| }.pack('side'=>'left', 'expand'=>'yes') }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') -TkFrame.new($hscale_demo) {|frame| + +def setWidth(w, width) + width = width + 21 + x2 = width - 30 + if x2 < 21 + x2 = 21 + end + w.coords 'poly',20,15,20,35,x2,35,x2,45,width,25,x2,5,x2,15,20,15 + w.coords 'line',20,15,20,35,x2,35,x2,45,width,25,x2,5,x2,15,20,15 +end + +TkFrame.new(base_frame) {|frame| canvas = TkCanvas.new(frame) {|c| width 50 height 50 @@ -61,14 +73,3 @@ TkFrame.new($hscale_demo) {|frame| }.pack('side'=>'bottom', 'expand'=>'yes', 'anchor'=>'n') scale.set 75 }.pack('side'=>'top', 'fill'=>'x') - -def setWidth(w, width) - width = width + 21 - x2 = width - 30 - if x2 < 21 - x2 = 21 - end - w.coords 'poly',20,15,20,35,x2,35,x2,45,width,25,x2,5,x2,15,20,15 - w.coords 'line',20,15,20,35,x2,35,x2,45,width,25,x2,5,x2,15,20,15 -end - diff --git a/ext/tk/sample/demos-en/icon.rb b/ext/tk/sample/demos-en/icon.rb index 58aca2df07..a3921d2333 100644 --- a/ext/tk/sample/demos-en/icon.rb +++ b/ext/tk/sample/demos-en/icon.rb @@ -19,8 +19,10 @@ $icon_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($icon_demo).pack(:fill=>:both, :expand=>true) + # label -msg = TkLabel.new($icon_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '5i' justify 'left' @@ -29,7 +31,7 @@ msg = TkLabel.new($icon_demo) { msg.pack('side'=>'top') # frame -TkFrame.new($icon_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -63,16 +65,18 @@ TkBitmapImage.new('file'=>[$demo_dir,'..', letters = TkVariable.new # frame -TkFrame.new($icon_demo, 'borderwidth'=>10){|w| +TkFrame.new(base_frame, 'borderwidth'=>10){|w| TkFrame.new(w) {|f| - TkRadioButton.new(f){ + # TkRadioButton.new(f){ + Tk::RadioButton.new(f){ bitmap '@' + [$demo_dir,'..', 'images','letters.xbm'].join(File::Separator) variable letters value 'full' }.pack('side'=>'top', 'expand'=>'yes') - TkRadioButton.new(f){ + # TkRadioButton.new(f){ + Tk::RadioButton.new(f){ bitmap '@' + [$demo_dir,'..', 'images','noletter.xbm'].join(File::Separator) variable letters @@ -81,14 +85,16 @@ TkFrame.new($icon_demo, 'borderwidth'=>10){|w| }.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'5m') - TkCheckButton.new(w) { + # TkCheckButton.new(w) { + Tk::CheckButton.new(w) { image flagdown selectimage flagup indicatoron 0 selectcolor self['background'] }.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'5m') - TkCheckButton.new(w) { + # TkCheckButton.new(w) { + Tk::CheckButton.new(w) { bitmap '@' + [$demo_dir,'..', 'images','letters.xbm'].join(File::Separator) indicatoron 0 diff --git a/ext/tk/sample/demos-en/image1.rb b/ext/tk/sample/demos-en/image1.rb index 05c9705c9c..a9072bb308 100644 --- a/ext/tk/sample/demos-en/image1.rb +++ b/ext/tk/sample/demos-en/image1.rb @@ -18,8 +18,10 @@ $image1_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($image1_demo).pack(:fill=>:both, :expand=>true) + # label -msg = TkLabel.new($image1_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -28,7 +30,7 @@ msg = TkLabel.new($image1_demo) { msg.pack('side'=>'top') # frame -TkFrame.new($image1_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -54,7 +56,10 @@ TkPhotoImage.new('file'=>[$demo_dir,'..', 'images','earthris.gif'].join(File::Separator)) # label -[ TkLabel.new($image1_demo, 'image'=>image1a, 'bd'=>1, 'relief'=>'sunken'), - TkLabel.new($image1_demo, 'image'=>image1b, 'bd'=>1, 'relief'=>'sunken') +#[ TkLabel.new(base_frame, 'image'=>image1a, 'bd'=>1, 'relief'=>'sunken'), +# TkLabel.new(base_frame, 'image'=>image1b, 'bd'=>1, 'relief'=>'sunken') +#].each{|w| w.pack('side'=>'top', 'padx'=>'.5m', 'pady'=>'.5m')} +[ Tk::Label.new(base_frame, 'image'=>image1a, 'bd'=>1, 'relief'=>'sunken'), + Tk::Label.new(base_frame, 'image'=>image1b, 'bd'=>1, 'relief'=>'sunken') ].each{|w| w.pack('side'=>'top', 'padx'=>'.5m', 'pady'=>'.5m')} diff --git a/ext/tk/sample/demos-en/image2.rb b/ext/tk/sample/demos-en/image2.rb index 1aff7173be..1975dd6b02 100644 --- a/ext/tk/sample/demos-en/image2.rb +++ b/ext/tk/sample/demos-en/image2.rb @@ -19,8 +19,10 @@ $image2_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($image2_demo).pack(:fill=>:both, :expand=>true) + # label -msg = TkLabel.new($image2_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -29,7 +31,7 @@ msg = TkLabel.new($image2_demo) { msg.pack('side'=>'top') # frame -TkFrame.new($image2_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -53,21 +55,21 @@ $dirName = TkVariable.new([$demo_dir,'..','images'].join(File::Separator)) $image2a = TkPhotoImage.new # -TkLabel.new($image2_demo, 'text'=>'Directory:')\ +TkLabel.new(base_frame, 'text'=>'Directory:')\ .pack('side'=>'top', 'anchor'=>'w') -image2_e = TkEntry.new($image2_demo) { +image2_e = TkEntry.new(base_frame) { width 30 textvariable $dirName }.pack('side'=>'top', 'anchor'=>'w') -TkFrame.new($image2_demo, 'height'=>'3m', 'width'=>20)\ +TkFrame.new(base_frame, 'height'=>'3m', 'width'=>20)\ .pack('side'=>'top', 'anchor'=>'w') -TkLabel.new($image2_demo, 'text'=>'File:')\ +TkLabel.new(base_frame, 'text'=>'File:')\ .pack('side'=>'top', 'anchor'=>'w') -TkFrame.new($image2_demo){|w| +TkFrame.new(base_frame){|w| s = TkScrollbar.new(w) l = TkListbox.new(w) { width 20 @@ -86,9 +88,9 @@ TkFrame.new($image2_demo){|w| }.pack('side'=>'top', 'anchor'=>'w') # image -[ TkFrame.new($image2_demo, 'height'=>'3m', 'width'=>20), - TkLabel.new($image2_demo, 'text'=>'Image:'), - TkLabel.new($image2_demo, 'image'=>$image2a) +[ TkFrame.new(base_frame, 'height'=>'3m', 'width'=>20), + TkLabel.new(base_frame, 'text'=>'Image:'), + TkLabel.new(base_frame, 'image'=>$image2a) ].each{|w| w.pack('side'=>'top', 'anchor'=>'w')} # diff --git a/ext/tk/sample/demos-en/image3.rb b/ext/tk/sample/demos-en/image3.rb index e46d3796f2..43afab7ecd 100644 --- a/ext/tk/sample/demos-en/image3.rb +++ b/ext/tk/sample/demos-en/image3.rb @@ -19,27 +19,29 @@ $image3_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($image3_demo).pack(:fill=>:both, :expand=>true) + # -def loadDir(w) +def loadDir3(w) w.delete(0,'end') Dir.glob([$dirName,'*'].join(File::Separator)).sort.each{|f| w.insert('end',File.basename(f)) } end -# selectAndLoadDir -- +# selectAndLoadDir3 -- # This procedure pops up a dialog to ask for a directory to load into # the listobx and (if the user presses OK) reloads the directory # listbox from the directory named in the demo's entry. # # Arguments: # w - Name of the toplevel window of the demo. -def selectAndLoadDir(w, lbox) +def selectAndLoadDir3(w, lbox) dir = Tk.chooseDirectory(:initialdir=>$dirName.value, :parent=>w, :mustexist=>true) if dir.length > 0 $dirName.value = dir - loadDir(lbox) + loadDir3(lbox) end end @@ -49,7 +51,7 @@ end # label -msg = TkLabel.new($image3_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -58,7 +60,7 @@ msg = TkLabel.new($image3_demo) { msg.pack('side'=>'top') # frame -TkFrame.new($image3_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -86,11 +88,11 @@ end $image3a = TkPhotoImage.new # -image3_f = TkFrame.new($image3_demo).pack(:fill=>:both, :expand=>true) +image3_f = TkFrame.new(base_frame).pack(:fill=>:both, :expand=>true) -image3_df = TkLabelFrame.new($image3_demo, :text=>'Directory:') +image3_df = TkLabelFrame.new(base_frame, :text=>'Directory:') -image3_ff = TkLabelFrame.new($image3_demo, :text=>'File:', +image3_ff = TkLabelFrame.new(base_frame, :text=>'File:', :padx=>'2m', :pady=>'2m') image3_lbx = TkListbox.new(image3_ff, :width=>20, :height=>10) { pack(:side=>:left, :fill=>:y, :expand=>true) @@ -102,16 +104,17 @@ image3_lbx = TkListbox.new(image3_ff, :width=>20, :height=>10) { image3_ent = TkEntry.new(image3_df, :width=>30, :textvariable=>$dirName){ pack(:side=>:left, :fill=>:both, :padx=>'2m', :pady=>'2m', :expand=>true) - bind('Return', proc{loadDir(image3_lbx)}) + bind('Return', proc{loadDir3(image3_lbx)}) } TkButton.new(image3_df, :pady=>0, :padx=>'2m', :text=>"Select Dir.", - :command=>proc{selectAndLoadDir(image3_ent, image3_lbx)}) { + :command=>proc{selectAndLoadDir3(image3_ent, image3_lbx)}) { pack(:side=>:left, :fill=>:y, :padx=>[0, '2m'], :pady=>'2m') } -image3_if = TkLabelFrame.new($image3_demo, :text=>'Image:') {|f| - TkLabel.new(f, :image=>$image3a).pack(:padx=>'2m', :pady=>'2m') +image3_if = TkLabelFrame.new(base_frame, :text=>'Image:') {|f| + # TkLabel.new(f, :image=>$image3a).pack(:padx=>'2m', :pady=>'2m') + Tk::Label.new(f, :image=>$image3a).pack(:padx=>'2m', :pady=>'2m') } Tk.grid(image3_df, '-', diff --git a/ext/tk/sample/demos-en/items.rb b/ext/tk/sample/demos-en/items.rb index 23191b59b9..3fd44fd4f4 100644 --- a/ext/tk/sample/demos-en/items.rb +++ b/ext/tk/sample/demos-en/items.rb @@ -19,8 +19,10 @@ $items_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($items_demo).pack(:fill=>:both, :expand=>true) + # label -TkLabel.new($items_demo) { +TkLabel.new(base_frame) { font $font wraplength '5i' justify 'left' @@ -28,7 +30,7 @@ TkLabel.new($items_demo) { }.pack('side'=>'top') # frame -TkFrame.new($items_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -46,7 +48,7 @@ TkFrame.new($items_demo) {|frame| # frame cvs = nil -TkFrame.new($items_demo) {|cf| +TkFrame.new(base_frame) {|cf| # canvas cvs = TkCanvas.new(cf) {|c| focus diff --git a/ext/tk/sample/demos-en/knightstour.rb b/ext/tk/sample/demos-en/knightstour.rb new file mode 100644 index 0000000000..618fce5f02 --- /dev/null +++ b/ext/tk/sample/demos-en/knightstour.rb @@ -0,0 +1,271 @@ +# Based on the widget demo of Tcl/Tk8.5.2 +# The following is the original copyright text. +#---------------------------------------------------------------------------- +# Copyright (C) 2008 Pat Thoyts +# +# Calculate a Knight's tour of a chessboard. +# +# This uses Warnsdorff's rule to calculate the next square each +# time. This specifies that the next square should be the one that +# has the least number of available moves. +# +# Using this rule it is possible to get to a position where +# there are no squares available to move into. In this implementation +# this occurs when the starting square is d6. +# +# To solve this fault an enhancement to the rule is that if we +# have a choice of squares with an equal score, we should choose +# the one nearest the edge of the board. +# +# If the call to the Edgemost function is commented out you can see +# this occur. +# +# You can drag the knight to a specific square to start if you wish. +# If you let it repeat then it will choose random start positions +# for each new tour. +#---------------------------------------------------------------------------- +require 'tk' + +class Knights_Tour + # Return a list of accessible squares from a given square + def valid_moves(square) + moves = [] + [ + [-1,-2], [-2,-1], [-2,1], [-1,2], [1,2], [2,1], [2,-1], [1,-2] + ].each{|col_delta, row_delta| + col = (square % 8) + col_delta + row = (square.div(8)) + row_delta + moves << (row * 8 + col) if row > -1 && row < 8 && col > -1 && col < 8 + } + moves + end + + # Return the number of available moves for this square + def check_square(square) + valid_moves(square).find_all{|pos| ! @visited.include?(pos)}.length + end + + # Select the next square to move to. Returns -1 if there are no available + # squares remaining that we can move to. + def next_square(square) + minimum = 9 + nxt = -1 + valid_moves(square).each{|pos| + unless @visited.include?(pos) + cnt = check_square(pos) + if cnt < minimum + minimum = cnt + nxt = pos + elsif cnt == minimum + nxt = edgemost(nxt, pos) + end + end + } + nxt + end + + # Select the square nearest the edge of the board + def edgemost(nxt, pos) + col_A = 3 - ((3.5 - nxt % 8).abs.to_i) + col_B = 3 - ((3.5 - pos % 8).abs.to_i) + row_A = 3 - ((3.5 - nxt.div(8)).abs.to_i) + row_B = 3 - ((3.5 - pos.div(8)).abs.to_i) + (col_A * row_A < col_B * row_B)? nxt : pos + end + + # Display a square number as a standard chess square notation. + def _N(square) + '%c%d' % [(97 + square % 8), (square.div(8) + 1)] + end + + # Perform a Knight's move and schedule the next move. + def move_piece(last, square) + @log.insert(:end, "#{@visited.length}. #{_N last} -> #{_N square}\n", '') + @log.see(:end) + @board.itemconfigure(1+last, :state=>:normal, :outline=>'black') + @board.itemconfigure(1+square, :state=>:normal, :outline=>'red') + @knight.coords(@board.coords(1+square)[0..1]) + @visited << square + if (nxt = next_square(square)) != -1 + @after_id = Tk.after(@delay.numeric){move_piece(square, nxt) rescue nil} + else + @start_btn.state :normal + if @visited.length == 64 + if @initial == square + @log.insert :end, 'Closed tour!' + else + @log.insert :end, "Success\n", {} + Tk.after(@delay.numeric * 2){tour(rand(64))} if @continuous.bool + end + else + @log.insert :end, "FAILED!\n", {} + end + end + end + + # Begin a new tour of the board given a random start position + def tour(square = nil) + @visited.clear + @log.clear + @start_btn.state :disabled + 1.upto(64){|n| + @board.itemconfigure(n, :state=>:disabled, :outline=>'black') + } + unless square + square = @board.find_closest(*(@knight.coords << 0 << 65))[0].to_i - 1 + end + @initial = square + Tk.after_idle{ move_piece(@initial, @initial) rescue nil } + end + + def _stop + Tk.after_cancel(@after_id) rescue nil + end + + def _exit + _stop + $knightstour.destroy + end + + def set_delay(new) + @delay.numeric = new.to_i + end + + def drag_start(w, x, y) + w.dtag('selected') + w.addtag('selected', :withtag, 'current') + @dragging = [x, y] + end + + def drag_motion(w, x, y) + return unless @dragging + w.move('selected', x - @dragging[0], y - @dragging[1]) + @dragging = [x, y] + end + + def drag_end(w, x, y) + square = w.find_closest(x, y, 0, 65) + w.coords('selected', w.coords(square)[0..1]) + w.dtag('selected') + @dragging = nil + end + + def make_SeeDismiss + ## See Code / Dismiss + frame = Ttk::Frame.new($knightstour) + sep = Ttk::Separator.new(frame) + Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + Ttk::Button.new(frame, :text=>'See Code', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'knightstour'}), + Ttk::Button.new(frame, :text=>'Dismiss', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + $knightstour.destroy + $knightstour = nil + }), + :padx=>4, :pady=>4) + frame.grid_columnconfigure(0, :weight=>1) + frame + end + + def create_gui(parent = nil) + $knightstour.destroy rescue nil + $knightstour = Tk::Toplevel.new(parent, :title=>"Knight's tour") + $knightstour.withdraw + base_f = Ttk::Frame.new($knightstour) + @board = Tk::Canvas.new(base_f, :width=>240, :height=>240) + @log = Tk::Text.new(base_f, :width=>12, :height=>1, + :font=>'Arial 8', :background=>'white') + scr = @log.yscrollbar(Ttk::Scrollbar.new(base_f)) + + @visited = [] + @delay = TkVariable.new(600) + @continuous = TkVariable.new(false) + + tool_f = Ttk::Frame.new($knightstour) + label = Ttk::Label.new(tool_f, :text=>'Speed') + scale = Ttk::Scale.new(tool_f, :from=>8, :to=>2000, :variable=>@delay, + :command=>proc{|n| set_delay(n)}) + check = Ttk::Checkbutton.new(tool_f, :text=>'Repeat', + :variable=>@continuous) + @start_btn = Ttk::Button.new(tool_f, :text=>'Start', + :command=>proc{tour()}) + @exit_btn = Ttk::Button.new(tool_f, :text=>'Exit', + :command=>proc{_exit()}) + + 7.downto(0){|row| + 0.upto(7){|col| + if ((col & 1) ^ (row & 1)).zero? + fill = 'bisque' + dfill = 'bisque3' + else + fill = 'tan3' + dfill = 'tan4' + end + coords = [col * 30 + 4, row * 30 + 4, col * 30 + 30, row * 30 + 30] + @board.create(TkcRectangle, coords, + :fill=>fill, :disabledfill=>dfill, + :width=>2, :state=>:disabled) + } + } + + @knight_font = TkFont.new(:size=>-24) + @knight = TkcText.new(@board, 0, 0, :font=>@knight_font, + :text=>Tk::UTF8_String.new('\u265e'), + :anchor=>'nw', # :tags=>'knight', + :fill=>'black', :activefill=>'#600000') + @knight.coords(@board.coords(rand(64)+1)[0..1]) + @knight.bind('ButtonPress-1', '%W %x %y'){|w,x,y| drag_start(w,x,y)} + @knight.bind('Motion', '%W %x %y'){|w,x,y| drag_motion(w,x,y)} + @knight.bind('ButtonRelease-1', '%W %x %y'){|w,x,y| drag_end(w,x,y)} + + Tk.grid(@board, @log, scr, :sticky=>'news') + base_f.grid_rowconfigure(0, :weight=>1) + base_f.grid_columnconfigure(0, :weight=>1) + + Tk.grid(base_f, '-', '-', '-', '-', '-', :sticky=>'news') + widgets = [label, scale, check, @start_btn] + sg = nil + unless $RubyTk_WidgetDemo + widgets << @exit_btn + if Tk.windowingsystem != 'aqua' + #widgets.unshift(Ttk::SizeGrip.new(tool_f)) + Ttk::SizeGrip.new(tool_f).pack(:side=>:right, :anchor=>'se') + end + end + Tk.pack(widgets, :side=>:right) + if Tk.windowingsystem == 'aqua' + TkPack.configure(widgets, :padx=>[4, 4], :pady=>[12, 12]) + TkPack.configure(widgets[0], :padx=>[4, 24]) + TkPack.configure(widgets[-1], :padx=>[16, 4]) + end + + Tk.grid(tool_f, '-', '-', '-', '-', '-', :sticky=>'ew') + + if $RubyTk_WidgetDemo + Tk.grid(make_SeeDismiss(), '-', '-', '-', '-', '-', :sticky=>'ew') + end + + $knightstour.grid_rowconfigure(0, :weight=>1) + $knightstour.grid_columnconfigure(0, :weight=>1) + + $knightstour.bind('Control-F2'){TkConsole.show} + $knightstour.bind('Return'){@start_btn.invoke} + $knightstour.bind('Escape'){@exit_btn.invoke} + $knightstour.bind('Destroy'){ _stop } + $knightstour.protocol('WM_DELETE_WINDOW'){ _exit } + + $knightstour.deiconify + $knightstour.tkwait_destroy + end + + def initialize(parent = nil) + create_gui(parent) + end +end + +Tk.root.withdraw unless $RubyTk_WidgetDemo +Thread.new{Tk.mainloop} if __FILE__ == $0 +Knights_Tour.new diff --git a/ext/tk/sample/demos-en/label.rb b/ext/tk/sample/demos-en/label.rb index 55e07a5ebc..91e41e4a22 100644 --- a/ext/tk/sample/demos-en/label.rb +++ b/ext/tk/sample/demos-en/label.rb @@ -19,8 +19,10 @@ $label_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($label_demo).pack(:fill=>:both, :expand=>true) + # label -msg = TkLabel.new($label_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -29,7 +31,7 @@ msg = TkLabel.new($label_demo) { msg.pack('side'=>'top') # frame -TkFrame.new($label_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -47,8 +49,8 @@ TkFrame.new($label_demo) {|frame| }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # label demo -f_left = TkFrame.new($label_demo) -f_right = TkFrame.new($label_demo) +f_left = TkFrame.new(base_frame) +f_right = TkFrame.new(base_frame) [f_left, f_right].each{|w| w.pack('side'=>'left', 'expand'=>'yes', 'padx'=>10, 'pady'=>10, 'fill'=>'both')} @@ -59,7 +61,8 @@ f_right = TkFrame.new($label_demo) TkLabel.new(f_left, 'text'=>'Third label, sunken', 'relief'=>'sunken') ].each{|w| w.pack('side'=>'top', 'expand'=>'yes', 'pady'=>2, 'anchor'=>'w')} -TkLabel.new(f_right) { +# TkLabel.new(f_right) { +Tk::Label.new(f_right) { bitmap('@' + [$demo_dir,'..','images','face.xbm'].join(File::Separator)) borderwidth 2 relief 'sunken' diff --git a/ext/tk/sample/demos-en/labelframe.rb b/ext/tk/sample/demos-en/labelframe.rb index 842a4f6c04..c912ff4c52 100644 --- a/ext/tk/sample/demos-en/labelframe.rb +++ b/ext/tk/sample/demos-en/labelframe.rb @@ -17,8 +17,10 @@ $labelframe_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($labelframe_demo).pack(:fill=>:both, :expand=>true) + # Some information -TkLabel.new($labelframe_demo, +TkLabel.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, :text=><:top) Labelframes are used to group related widgets together. \ @@ -29,7 +31,7 @@ which supports a 'labelframe' widget. EOL # The bottom buttons -TkFrame.new($labelframe_demo){|f| +TkFrame.new(base_frame){|f| pack(:side=>:bottom, :fill=>:x, :pady=>'2m') TkButton.new(f, :text=>'Dismiss', :width=>15, :command=>proc{ @@ -43,7 +45,7 @@ TkFrame.new($labelframe_demo){|f| } # Demo area -w = TkFrame.new($labelframe_demo).pack(:side=>:bottom, :fill=>:both, +w = TkFrame.new(base_frame).pack(:side=>:bottom, :fill=>:both, :expand=>true) # A group of radiobuttons in a labelframe diff --git a/ext/tk/sample/demos-en/mclist.rb b/ext/tk/sample/demos-en/mclist.rb new file mode 100644 index 0000000000..a849eba515 --- /dev/null +++ b/ext/tk/sample/demos-en/mclist.rb @@ -0,0 +1,117 @@ +# mclist.rb -- +# +# This demonstration script creates a toplevel window containing a Ttk +# tree widget configured as a multi-column listbox. +# +# based on "Id: mclist.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp" + +if defined?($mclist_demo) && $mclist_demo + $mclist_demo.destroy + $mclist_demo = nil +end + +$mclist_demo = TkToplevel.new {|w| + title("Multi-Column List") + iconname("mclist") + positionWindow(w) +} + +base_frame = TkFrame.new($mclist_demo).pack(:fill=>:both, :expand=>true) + +## Explanatory text +Ttk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', + :justify=>:left, :anchor=>'n', :padding=>[10, 2, 10, 6], + :text=><:x) +Ttk is the new Tk themed widget set. \ +One of the widgets it includes is a tree widget, \ +which can be configured to display multiple columns of informational data \ +without displaying the tree itself. \ +This is a simple way to build a listbox that has multiple columns. \ +Clicking on the heading for a column will sort the data by that column. \ +You can also change the width of the columns \ +by dragging the boundary between them. +EOL + +## See Code / Dismiss +Ttk::Frame.new(base_frame) {|frame| + sep = Ttk::Separator.new(frame) + Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + Ttk::Button.new(frame, :text=>'See Code', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'mclist'}), + Ttk::Button.new(frame, :text=>'Dismiss', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + $mclist_demo.destroy + $mclist_demo = nil + }), + :padx=>4, :pady=>4) + grid_columnconfigure(0, :weight=>1) + pack(:side=>:bottom, :fill=>:x) +} + +container = Ttk::Frame.new(base_frame) +tree = Ttk::Treeview.new(base_frame, :columns=>%w(country capital currency), + :show=>:headings) +if Tk.windowingsystem != 'aqua' + vsb = tree.yscrollbar(Ttk::Scrollbar.new(base_frame)) + hsb = tree.xscrollbar(Ttk::Scrollbar.new(base_frame)) +else + vsb = tree.yscrollbar(Tk::Scrollbar.new(base_frame)) + hsb = tree.xscrollbar(Tk::Scrollbar.new(base_frame)) +end + +container.pack(:fill=>:both, :expand=>true) +Tk.grid(tree, vsb, :in=>container, :sticky=>'nsew') +Tk.grid(hsb, :in=>container, :sticky=>'nsew') +container.grid_columnconfigure(0, :weight=>1) +container.grid_rowconfigure(0, :weight=>1) + +## The data we're going to insert +data = [ + ['Argentina', 'Buenos Aires', 'ARS'], + ['Australia', 'Canberra', 'AUD'], + ['Brazil', 'Brazilia', 'BRL'], + ['Canada', 'Ottawa', 'CAD'], + ['China', 'Beijing', 'CNY'], + ['France', 'Paris', 'EUR'], + ['Germany', 'Berlin', 'EUR'], + ['India', 'New Delhi', 'INR'], + ['Italy', 'Rome', 'EUR'], + ['Japan', 'Tokyo', 'JPY'], + ['Mexico', 'Mexico City', 'MXN'], + ['Russia', 'Moscow', 'RUB'], + ['South Africa', 'Pretoria', 'ZAR'], + ['United Kingdom', 'London', 'GBP'], + ['United States', 'Washington, D.C.', 'USD'], +] + +## Code to insert the data nicely +font = Ttk::Style.lookup(tree[:style], :font) +cols = %w(country capital currency) +cols.zip(%w(Country Capital Currency)).each{|col, name| + tree.heading_configure(col, :text=>name, + :command=>proc{sort_by(tree, col, false)}) + tree.column_configure(col, :width=>TkFont.measure(font, name)) +} + +data.each{|country, capital, currency| + #tree.insert('', :end, :values=>[country, capital, currency]) + tree.insert(nil, :end, :values=>[country, capital, currency]) + cols.zip([country, capital, currency]).each{|col, val| + len = TkFont.measure(font, "#{val} ") + if tree.column_cget(col, :width) < len + tree.column_configure(col, :width=>len) + end + } +} + +## Code to do the sorting of the tree contents when clicked on +def sort_by(tree, col, direction) + tree.children(nil).map!{|row| [tree.get(row, col), row.id]} . + sort(&((direction)? proc{|x, y| y <=> x}: proc{|x, y| x <=> y})) . + each_with_index{|info, idx| tree.move(info[1], nil, idx)} + + tree.heading_configure(col, :command=>proc{sort_by(tree, col, ! direction)}) +end diff --git a/ext/tk/sample/demos-en/menu.rb b/ext/tk/sample/demos-en/menu.rb index 8370d2f5f0..bf6c22cb9d 100644 --- a/ext/tk/sample/demos-en/menu.rb +++ b/ext/tk/sample/demos-en/menu.rb @@ -15,8 +15,10 @@ $menu_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($menu_demo).pack(:fill=>:both, :expand=>true) + # menu frame -$menu_frame = TkFrame.new($menu_demo, 'relief'=>'raised', 'bd'=>2) +$menu_frame = TkFrame.new(base_frame, 'relief'=>'raised', 'bd'=>2) $menu_frame.pack('side'=>'top', 'fill'=>'x') begin @@ -26,7 +28,7 @@ rescue end # label -TkLabel.new($menu_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { +TkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { if $tk_platform['platform'] == 'macintosh' || windowingsystem == "classic" || windowingsystem == "aqua" text("This window contains a menubar with cascaded menus. You can invoke entries with an accelerator by typing Command+x, where \"x\" is the character next to the command key symbol. The rightmost menu can be torn off into a palette by dragging outside of its bounds and releasing the mouse.") @@ -36,7 +38,7 @@ TkLabel.new($menu_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { }.pack('side'=>'top') # frame -TkFrame.new($menu_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -105,7 +107,7 @@ TkMenubutton.new($menu_frame, 'text'=>'Cascades', 'underline'=>0) {|m| 'accelerator'=>"#{modifier}+G", 'underline'=>6) $menu_demo.bind("#{modifier}-g", proc{print "Goodbye\n"}) - TkMenu.new(m, 'tearoff'=>false) {|cascade_check| + TkMenu.new(cascade_menu, 'tearoff'=>false) {|cascade_check| cascade_menu.add('cascade', 'label'=>'Check buttons', 'menu'=>cascade_check, 'underline'=>0) oil = TkVariable.new(0) @@ -127,7 +129,7 @@ TkMenubutton.new($menu_frame, 'text'=>'Cascades', 'underline'=>0) {|m| invoke 3 } - TkMenu.new(m, 'tearoff'=>false) {|cascade_radio| + TkMenu.new(cascade_menu, 'tearoff'=>false) {|cascade_radio| cascade_menu.add('cascade', 'label'=>'Radio buttons', 'menu'=>cascade_radio, 'underline'=>0) pointSize = TkVariable.new diff --git a/ext/tk/sample/demos-en/menu84.rb b/ext/tk/sample/demos-en/menu84.rb index cb616d8461..4029ce5541 100644 --- a/ext/tk/sample/demos-en/menu84.rb +++ b/ext/tk/sample/demos-en/menu84.rb @@ -15,6 +15,8 @@ $menu84_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($menu84_demo).pack(:fill=>:both, :expand=>true) + begin windowingsystem = Tk.windowingsystem() rescue @@ -22,7 +24,7 @@ rescue end # label -TkLabel.new($menu84_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { +TkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { if $tk_platform['platform'] == 'macintosh' || windowingsystem == "classic" || windowingsystem == "aqua" text("This window contains a menubar with cascaded menus. You can invoke entries with an accelerator by typing Command+x, where \"x\" is the character next to the command key symbol. The rightmost menu can be torn off into a palette by dragging outside of its bounds and releasing the mouse.") @@ -33,7 +35,7 @@ TkLabel.new($menu84_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { menustatus = TkVariable.new(" ") -TkFrame.new($menu84_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkLabel.new(frame, 'textvariable'=>menustatus, 'relief'=>'sunken', 'bd'=>1, 'font'=>['Helvetica', '10'], 'anchor'=>'w').pack('side'=>'left', 'padx'=>2, @@ -43,7 +45,7 @@ TkFrame.new($menu84_demo) {|frame| # frame -TkFrame.new($menu84_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ diff --git a/ext/tk/sample/demos-en/menubu.rb b/ext/tk/sample/demos-en/menubu.rb index e2ddd07bc6..b37367e515 100644 --- a/ext/tk/sample/demos-en/menubu.rb +++ b/ext/tk/sample/demos-en/menubu.rb @@ -37,16 +37,18 @@ $menubu_demo = TkToplevel.new {|w| positionWindow($menubu_demo) +base_frame = TkFrame.new($menubu_demo).pack(:fill=>:both, :expand=>true) + # version check if $tk_version.to_f < 8.0 # label -TkLabel.new($menubu_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { +TkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { text("This is a demonstration of menubuttons. The \"Below\" menubutton pops its menu below the button; the \"Right\" button pops to the right, etc. There are two option menus directly below this text; one is just a standard menu and the other is a 16-color palette.") }.pack('side'=>'top') # frame -TkFrame.new($menubu_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -64,7 +66,7 @@ TkFrame.new($menubu_demo) {|frame| else ; # Tk8.x -body = TkFrame.new($menubu_demo) +body = TkFrame.new(base_frame) body.pack('expand'=>'yes', 'fill'=>'both') below = TkMenubutton.new(body) { @@ -159,7 +161,7 @@ center = TkFrame.new(body) { grid('row'=>1, 'column'=>1, 'sticky'=>'news') } -TkFrame.new($menubu_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc { diff --git a/ext/tk/sample/demos-en/msgbox.rb b/ext/tk/sample/demos-en/msgbox.rb index aab1b619cf..62b1f2b985 100644 --- a/ext/tk/sample/demos-en/msgbox.rb +++ b/ext/tk/sample/demos-en/msgbox.rb @@ -18,12 +18,14 @@ $msgbox_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($msgbox_demo).pack(:fill=>:both, :expand=>true) + # label -TkLabel.new($msgbox_demo, 'font'=>$font, 'wraplength'=>'4i', 'justify'=>'left', +TkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'4i', 'justify'=>'left', 'text'=>"Choose the icon and type option of the message box. Then press the \"Message Box\" button to see the message box.").pack('side'=>'top') # frame -TkFrame.new($msgbox_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -45,8 +47,8 @@ TkFrame.new($msgbox_demo) {|frame| }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # frame -$msgbox_leftframe = TkFrame.new($msgbox_demo) -$msgbox_rightframe = TkFrame.new($msgbox_demo) +$msgbox_leftframe = TkFrame.new(base_frame) +$msgbox_rightframe = TkFrame.new(base_frame) $msgbox_leftframe .pack('side'=>'left', 'expand'=>'yes', 'fill'=>'y', 'pady'=>'.5c', 'padx'=>'.5c') $msgbox_rightframe.pack('side'=>'left', 'expand'=>'yes', 'fill'=>'y', diff --git a/ext/tk/sample/demos-en/msgbox2.rb b/ext/tk/sample/demos-en/msgbox2.rb new file mode 100644 index 0000000000..6fe6c778b3 --- /dev/null +++ b/ext/tk/sample/demos-en/msgbox2.rb @@ -0,0 +1,91 @@ +# msgbox2.rb +# +# This demonstration script creates message boxes of various type +# +# message boxes widget demo (called by 'widget') +# + +# toplevel widget +if defined?($msgbox2_demo) && $msgbox2_demo + $msgbox2_demo.destroy + $msgbox2_demo = nil +end + +# demo toplevel widget +$msgbox2_demo = TkToplevel.new {|w| + title("Message Box Demonstration") + iconname("messagebox") + positionWindow(w) +} + +base_frame = TkFrame.new($msgbox2_demo).pack(:fill=>:both, :expand=>true) + +# label +TkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'4i', 'justify'=>'left', + 'text'=>"Choose the icon and type option of the message box. Then press the \"Message Box\" button to see the message box with both of a message and a detail.").pack('side'=>'top') + +# frame +TkFrame.new(base_frame) {|frame| + TkButton.new(frame) { + text 'Dismiss' + command proc{ + tmppath = $msgbox2_demo + $msgbox2_demo = nil + tmppath.destroy + } + }.pack('side'=>'left', 'expand'=>'yes') + + TkButton.new(frame) { + text 'Show Code' + command proc{showCode 'msgbox2'} + }.pack('side'=>'left', 'expand'=>'yes') + + TkButton.new(frame) { + text 'Message Box' + command proc{showMessageBox $msgbox2_demo} + }.pack('side'=>'left', 'expand'=>'yes') +}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') + +# frame +$msgbox_leftframe = TkFrame.new(base_frame) +$msgbox_rightframe = TkFrame.new(base_frame) +$msgbox_leftframe .pack('side'=>'left', 'expand'=>'yes', 'fill'=>'y', + 'pady'=>'.5c', 'padx'=>'.5c') +$msgbox_rightframe.pack('side'=>'left', 'expand'=>'yes', 'fill'=>'y', + 'pady'=>'.5c', 'padx'=>'.5c') + +TkLabel.new($msgbox_leftframe, 'text'=>'Icon').pack('side'=>'top') +TkFrame.new($msgbox_leftframe, 'relief'=>'ridge', 'bd'=>1, 'height'=>2)\ +.pack('side'=>'top', 'fill'=>'x', 'expand'=>'no') + +$msgboxIcon = TkVariable.new('info') +['error', 'info', 'question', 'warning'].each {|icon| + TkRadioButton.new($msgbox_leftframe, 'text'=>icon, 'variable'=>$msgboxIcon, + 'relief'=>'flat', 'value'=>icon, 'width'=>16, + 'anchor'=>'w').pack('side'=>'top', 'pady'=>2, + 'anchor'=>'w', 'fill'=>'x') +} + +TkLabel.new($msgbox_rightframe, 'text'=>'Type').pack('side'=>'top') +TkFrame.new($msgbox_rightframe, 'relief'=>'ridge', 'bd'=>1, 'height'=>2)\ +.pack('side'=>'top', 'fill'=>'x', 'expand'=>'no') + +$msgboxType = TkVariable.new('ok') +['abortretryignore', 'ok', 'okcancel', + 'retrycancel', 'yesno', 'yesnocancel'].each {|type| + TkRadioButton.new($msgbox_rightframe, 'text'=>type, 'variable'=>$msgboxType, + 'relief'=>'flat', 'value'=>type, 'width'=>16, + 'anchor'=>'w').pack('side'=>'top', 'pady'=>2, + 'anchor'=>'w', 'fill'=>'x') +} + +def showMessageBox(w) + button = Tk.messageBox('icon'=>$msgboxIcon.value, 'type'=>$msgboxType.value, + 'title'=>'Message', 'parent'=>w, + 'message'=>"\"#{$msgboxType.value}\" Type MessageBox", + 'detail'=>"This is a \"#{$msgboxType.value}\" type messagebox with the \"#{$msgboxIcon.value}\" icon. Please click one of the following button.") + + Tk.messageBox('icon'=>'info', 'type'=>'ok', 'parent'=>w, + 'message'=>"You have selected \"#{button}\"") +end + diff --git a/ext/tk/sample/demos-en/paned1.rb b/ext/tk/sample/demos-en/paned1.rb index 48ba86de02..26941b84a8 100644 --- a/ext/tk/sample/demos-en/paned1.rb +++ b/ext/tk/sample/demos-en/paned1.rb @@ -16,7 +16,9 @@ $paned1_demo = TkToplevel.new {|w| positionWindow(w) } -TkLabel.new($paned1_demo, +base_frame = TkFrame.new($paned1_demo).pack(:fill=>:both, :expand=>true) + +TkLabel.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, :text=><:top) The sash between the two coloured windows below can be used to divide the area between them. Use the left mouse button to resize without redrawing by just moving the sash, and use the middle mouse button to resize opaquely (always redrawing the windows in each position.) @@ -24,7 +26,7 @@ If your Tk library linked to Ruby doesn't include a 'panedwindow', this demo doe EOL # The bottom buttons -TkFrame.new($paned1_demo){|f| +TkFrame.new(base_frame){|f| pack(:side=>:bottom, :fill=>:x, :pady=>'2m') TkButton.new(f, :text=>'Dismiss', :width=>15, :command=>proc{ @@ -37,9 +39,9 @@ TkFrame.new($paned1_demo){|f| }).pack(:side=>:left, :expand=>true) } -TkPanedwindow.new($paned1_demo){|f| - pack(:side=>:top, :expand=>true, :fill=>:both, :pady=>2, :padx=>'2m') +TkPanedwindow.new(base_frame, :orient=>:horizontal){|f| + add(Tk::Label.new(f, :text=>"This is the\nleft side", :bg=>'yellow'), + Tk::Label.new(f, :text=>"This is the\nright side", :bg=>'cyan')) - add(TkLabel.new(f, :text=>"This is the\nleft side", :bg=>'yellow'), - TkLabel.new(f, :text=>"This is the\nright side", :bg=>'cyan')) + pack(:side=>:top, :expand=>true, :fill=>:both, :pady=>2, :padx=>'2m') } diff --git a/ext/tk/sample/demos-en/paned2.rb b/ext/tk/sample/demos-en/paned2.rb index 5911cadab6..0e62013886 100644 --- a/ext/tk/sample/demos-en/paned2.rb +++ b/ext/tk/sample/demos-en/paned2.rb @@ -16,7 +16,9 @@ $paned2_demo = TkToplevel.new {|w| positionWindow(w) } -TkLabel.new($paned2_demo, +base_frame = TkFrame.new($paned2_demo).pack(:fill=>:both, :expand=>true) + +TkLabel.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, :text=><:top) The sash between the two scrolled windows below can be used to divide the area between them. Use the left mouse button to resize without redrawing by just moving the sash, and use the middle mouse button to resize opaquely (always redrawing the windows in each position.) @@ -24,7 +26,7 @@ If your Tk library linked to Ruby doesn't include a 'panedwindow', this demo doe EOL # The bottom buttons -TkFrame.new($paned2_demo){|f| +TkFrame.new(base_frame){|f| pack(:side=>:bottom, :fill=>:x, :pady=>'2m') TkButton.new(f, :text=>'Dismiss', :width=>15, :command=>proc{ @@ -61,7 +63,7 @@ paneList.value = [ # ruby's array --> tcl's list ] # Create the pane itself -TkPanedwindow.new($paned2_demo, :orient=>:vertical){|f| +TkPanedwindow.new(base_frame, :orient=>:vertical){|f| pack(:side=>:top, :expand=>true, :fill=>:both, :pady=>2, :padx=>'2m') add(TkFrame.new(f){|paned2_top| diff --git a/ext/tk/sample/demos-en/pendulum.rb b/ext/tk/sample/demos-en/pendulum.rb index a3498d67cf..5f7d361170 100644 --- a/ext/tk/sample/demos-en/pendulum.rb +++ b/ext/tk/sample/demos-en/pendulum.rb @@ -18,8 +18,10 @@ $pendulum_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($pendulum_demo).pack(:fill=>:both, :expand=>true) + # create label -msg = TkLabel.new($pendulum_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -28,7 +30,7 @@ msg = TkLabel.new($pendulum_demo) { msg.pack('side'=>'top') # create frame -TkFrame.new($pendulum_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -49,7 +51,7 @@ TkFrame.new($pendulum_demo) {|frame| class PendulumAnimationDemo def initialize(frame) # Create some structural widgets - @pane = TkPanedWindow.new(frame).pack(:fill=>:both, :expand=>true) + @pane = TkPanedWindow.new(frame, :orient=>:horizontal).pack(:fill=>:both, :expand=>true) # @pane.add(@lf1 = TkLabelFrame.new(@pane, :text=>'Pendulum Simulation')) # @pane.add(@lf2 = TkLabelFrame.new(@pane, :text=>'Phase Space')) @lf1 = TkLabelFrame.new(@pane, :text=>'Pendulum Simulation') @@ -235,4 +237,4 @@ class PendulumAnimationDemo end # Start the animation processing -PendulumAnimationDemo.new($pendulum_demo) +PendulumAnimationDemo.new(base_frame) diff --git a/ext/tk/sample/demos-en/plot.rb b/ext/tk/sample/demos-en/plot.rb index 6d01deeef5..628c9df584 100644 --- a/ext/tk/sample/demos-en/plot.rb +++ b/ext/tk/sample/demos-en/plot.rb @@ -19,14 +19,16 @@ $plot_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($plot_demo).pack(:fill=>:both, :expand=>true) + # label -TkLabel.new($plot_demo, 'font'=>$font, 'wraplength'=>'4i', 'justify'=>'left', +TkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'4i', 'justify'=>'left', 'text'=>"This window displays a canvas widget containing a simple 2-dimensional plot. You can doctor the data by dragging any of the points with mouse button 1."){ pack('side'=>'top') } # frame -$plot_buttons = TkFrame.new($plot_demo) {|frame| +$plot_buttons = TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -47,7 +49,7 @@ $plot_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') plotFont = '-*-Helvetica-Medium-R-Normal--*-180-*-*-*-*-*-*' # canvas -$plot_canvas = TkCanvas.new($plot_demo,'relief'=>'raised','width'=>450,'height'=>300) +$plot_canvas = TkCanvas.new(base_frame,'relief'=>'raised','width'=>450,'height'=>300) $plot_canvas.pack('side'=>'top', 'fill'=>'x') # plot diff --git a/ext/tk/sample/demos-en/puzzle.rb b/ext/tk/sample/demos-en/puzzle.rb index 0885cf2975..43c61f519f 100644 --- a/ext/tk/sample/demos-en/puzzle.rb +++ b/ext/tk/sample/demos-en/puzzle.rb @@ -19,8 +19,10 @@ $puzzle_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($puzzle_demo).pack(:fill=>:both, :expand=>true) + # label -msg = TkLabel.new($puzzle_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -29,7 +31,7 @@ msg = TkLabel.new($puzzle_demo) { msg.pack('side'=>'top') # frame -TkFrame.new($puzzle_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -52,18 +54,27 @@ TkFrame.new($puzzle_demo) {|frame| # scrollbar widget and using its trough color. begin if Tk.windowingsystem() == 'aqua' - frameSize = 160 + frameWidth = 168 + frameHeight = 168 + elsif Tk.default_widget_set == :Ttk + frameWidth = 148 + frameHeight = 124 else - frameSize = 120 + frameWidth = 120 + frameHeight = 120 end rescue - frameSize = 120 + frameWidth = 120 + frameHeight = 120 end + +# depend_on_button_width = true +depend_on_button_width = false -s = TkScrollbar.new($puzzle_demo) -base = TkFrame.new($puzzle_demo) { - width frameSize - height frameSize +s = TkScrollbar.new(base_frame) +base = TkFrame.new(base_frame) { + width frameWidth + height frameHeight borderwidth 2 relief 'sunken' bg s['troughcolor'] @@ -87,6 +98,9 @@ order = [3,1,6,2,5,7,15,13,4,11,8,9,14,10,12] text num highlightthickness 0 command def_puzzleswitch_proc(w, num) + if depend_on_button_width && (w.winfo_reqwidth * 4 > base.width) + base.width = w.winfo_reqwidth * 4 + end }.place('relx'=>$xpos[num], 'rely'=>$ypos[num], 'relwidth'=>0.25, 'relheight'=>0.25) } diff --git a/ext/tk/sample/demos-en/radio.rb b/ext/tk/sample/demos-en/radio.rb index 96cdc4c54a..25cfac2134 100644 --- a/ext/tk/sample/demos-en/radio.rb +++ b/ext/tk/sample/demos-en/radio.rb @@ -19,8 +19,10 @@ $radio_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($radio_demo).pack(:fill=>:both, :expand=>true) + # label -msg = TkLabel.new($radio_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -33,7 +35,7 @@ size = TkVariable.new color = TkVariable.new # frame -TkFrame.new($radio_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -52,14 +54,14 @@ TkFrame.new($radio_demo) {|frame| TkButton.new(frame) { text 'See Variables' command proc{ - showVars($radio_demo, ['size', size], ['color', color]) + showVars(base_frame, ['size', size], ['color', color]) } }.pack('side'=>'left', 'expand'=>'yes') }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # frame -f_left = TkFrame.new($radio_demo) -f_right = TkFrame.new($radio_demo) +f_left = TkFrame.new(base_frame) +f_right = TkFrame.new(base_frame) f_left.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'.5c', 'pady'=>'.5c') f_right.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'.5c', 'pady'=>'.5c') diff --git a/ext/tk/sample/demos-en/radio2.rb b/ext/tk/sample/demos-en/radio2.rb index 2b56ccc9b1..6c02aef0cf 100644 --- a/ext/tk/sample/demos-en/radio2.rb +++ b/ext/tk/sample/demos-en/radio2.rb @@ -19,8 +19,10 @@ $radio2_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($radio2_demo).pack(:fill=>:both, :expand=>true) + # label -msg = TkLabel.new($radio2_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '5i' justify 'left' @@ -34,7 +36,7 @@ color = TkVariable.new align = TkVariable.new # frame -TkFrame.new($radio2_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -53,18 +55,18 @@ TkFrame.new($radio2_demo) {|frame| TkButton.new(frame) { text 'See Variables' command proc{ - showVars($radio2_demo, + showVars(base_frame, ['size', size], ['color', color], ['compound', align]) } }.pack('side'=>'left', 'expand'=>'yes') }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # frame -f_left = TkLabelFrame.new($radio2_demo, 'text'=>'Point Size', +f_left = TkLabelFrame.new(base_frame, 'text'=>'Point Size', 'pady'=>2, 'padx'=>2) -f_mid = TkLabelFrame.new($radio2_demo, 'text'=>'Color', +f_mid = TkLabelFrame.new(base_frame, 'text'=>'Color', 'pady'=>2, 'padx'=>2) -f_right = TkLabelFrame.new($radio2_demo, 'text'=>'Alignment', +f_right = TkLabelFrame.new(base_frame, 'text'=>'Alignment', 'pady'=>2, 'padx'=>2) f_left.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'.5c', 'pady'=>'.5c') f_mid.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'.5c', 'pady'=>'.5c') @@ -90,7 +92,8 @@ f_right.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'.5c', 'pady'=>'.5c') }.pack('side'=>'top', 'pady'=>2, 'fill'=>'x') } -label = TkLabel.new(f_right, 'text'=>'Label', 'bitmap'=>'questhead', +# label = TkLabel.new(f_right, 'text'=>'Label', 'bitmap'=>'questhead', +label = Tk::Label.new(f_right, 'text'=>'Label', 'bitmap'=>'questhead', 'compound'=>'left') label.configure('width'=>TkWinfo.reqwidth(label), 'compound'=>'top') label.height(TkWinfo.reqheight(label)) diff --git a/ext/tk/sample/demos-en/radio3.rb b/ext/tk/sample/demos-en/radio3.rb index 70c4abb3b5..9c9d75ef4a 100644 --- a/ext/tk/sample/demos-en/radio3.rb +++ b/ext/tk/sample/demos-en/radio3.rb @@ -19,8 +19,10 @@ $radio3_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($radio3_demo).pack(:fill=>:both, :expand=>true) + # label -msg = TkLabel.new($radio3_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '5i' justify 'left' @@ -34,14 +36,14 @@ color = TkVariable.new align = TkVariable.new # frame -TkFrame.new($radio3_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkGrid(TkFrame.new(frame, :height=>2, :relief=>:sunken, :bd=>2), :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) TkGrid('x', TkButton.new(frame, :text=>'See Variables', :image=>$image['view'], :compound=>:left, :command=>proc{ - showVars($radio3_demo, ['size', size], + showVars(base_frame, ['size', size], ['color', color], ['compound', align]) }), TkButton.new(frame, :text=>'See Code', @@ -61,17 +63,17 @@ TkFrame.new($radio3_demo) {|frame| } # frame -f_left = TkLabelFrame.new($radio3_demo, 'text'=>'Point Size', +f_left = TkLabelFrame.new(base_frame, 'text'=>'Point Size', 'pady'=>2, 'padx'=>2) -f_mid = TkLabelFrame.new($radio3_demo, 'text'=>'Color', +f_mid = TkLabelFrame.new(base_frame, 'text'=>'Color', 'pady'=>2, 'padx'=>2) -f_right = TkLabelFrame.new($radio3_demo, 'text'=>'Alignment', +f_right = TkLabelFrame.new(base_frame, 'text'=>'Alignment', 'pady'=>2, 'padx'=>2) f_left .grid('column'=>0, 'row'=>1, 'pady'=>'.5c', 'padx'=>'.5c', 'rowspan'=>2) f_mid .grid('column'=>1, 'row'=>1, 'pady'=>'.5c', 'padx'=>'.5c', 'rowspan'=>2) f_right.grid('column'=>2, 'row'=>1, 'pady'=>'.5c', 'padx'=>'.5c') -TkButton.new($radio3_demo, 'text'=>'Tristate', +TkButton.new(base_frame, 'text'=>'Tristate', 'command'=>proc{size.value = 'multi'; color.value = 'multi'}){ grid('column'=>2, 'row'=>2, 'pady'=>'.5c', 'padx'=>'.5c') } @@ -99,7 +101,8 @@ TkButton.new($radio3_demo, 'text'=>'Tristate', }.pack('side'=>'top', 'pady'=>2, 'fill'=>'x') } -label = TkLabel.new(f_right, 'text'=>'Label', 'bitmap'=>'questhead', +# label = TkLabel.new(f_right, 'text'=>'Label', 'bitmap'=>'questhead', +label = Tk::Label.new(f_right, 'text'=>'Label', 'bitmap'=>'questhead', 'compound'=>'left') label.configure('width'=>TkWinfo.reqwidth(label), 'compound'=>'top') label.height(TkWinfo.reqheight(label)) diff --git a/ext/tk/sample/demos-en/ruler.rb b/ext/tk/sample/demos-en/ruler.rb index 4299d57b4f..26cd4f3b1c 100644 --- a/ext/tk/sample/demos-en/ruler.rb +++ b/ext/tk/sample/demos-en/ruler.rb @@ -32,14 +32,16 @@ $ruler_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($ruler_demo).pack(:fill=>:both, :expand=>true) + # label -TkLabel.new($ruler_demo, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', +TkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', 'text'=>"This canvas widget shows a mock-up of a ruler. You can create tab stops by dragging them out of the well to the right of the ruler. You can also drag existing tab stops. If you drag a tab stop far enough up or down so that it turns dim, it will be deleted when you release the mouse button."){ pack('side'=>'top') } # frame -$ruler_buttons = TkFrame.new($ruler_demo) {|frame| +$ruler_buttons = TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -57,7 +59,7 @@ $ruler_buttons = TkFrame.new($ruler_demo) {|frame| $ruler_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # canvas -$ruler_canvas = TkCanvas.new($ruler_demo, 'width'=>'14.8c', 'height'=>'2.5c') +$ruler_canvas = TkCanvas.new(base_frame, 'width'=>'14.8c', 'height'=>'2.5c') $ruler_canvas.pack('side'=>'top', 'fill'=>'x') # diff --git a/ext/tk/sample/demos-en/sayings.rb b/ext/tk/sample/demos-en/sayings.rb index cef0f4ecf4..06ec7c1e75 100644 --- a/ext/tk/sample/demos-en/sayings.rb +++ b/ext/tk/sample/demos-en/sayings.rb @@ -20,8 +20,10 @@ $sayings_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($sayings_demo).pack(:fill=>:both, :expand=>true) + # label -msg = TkLabel.new($sayings_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -30,7 +32,7 @@ msg = TkLabel.new($sayings_demo) { msg.pack('side'=>'top') # frame -TkFrame.new($sayings_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -49,7 +51,7 @@ TkFrame.new($sayings_demo) {|frame| # frame sayings_lbox = nil -TkFrame.new($sayings_demo, 'borderwidth'=>10) {|w| +TkFrame.new(base_frame, 'borderwidth'=>10) {|w| sv = TkScrollbar.new(w) sh = TkScrollbar.new(w, 'orient'=>'horizontal') sayings_lbox = TkListbox.new(w) { diff --git a/ext/tk/sample/demos-en/search.rb b/ext/tk/sample/demos-en/search.rb index 3749423bbc..e1fc565e9d 100644 --- a/ext/tk/sample/demos-en/search.rb +++ b/ext/tk/sample/demos-en/search.rb @@ -79,8 +79,10 @@ $search_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($search_demo).pack(:fill=>:both, :expand=>true) + # frame -$search_buttons = TkFrame.new($search_demo) {|frame| +$search_buttons = TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -98,7 +100,7 @@ $search_buttons = TkFrame.new($search_demo) {|frame| $search_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # frame -TkFrame.new($search_demo) {|f| +TkFrame.new(base_frame) {|f| TkLabel.new(f, 'text'=>'File name:', 'width'=>13, 'anchor'=>'w').pack('side'=>'left') $search_fileName = TkVariable.new @@ -115,7 +117,7 @@ TkFrame.new($search_demo) {|f| .pack('side'=>'left', 'pady'=>5, 'padx'=>10) }.pack('side'=>'top', 'fill'=>'x') -TkFrame.new($search_demo) {|f| +TkFrame.new(base_frame) {|f| TkLabel.new(f, 'text'=>'Search string:', 'width'=>13, 'anchor'=>'w').pack('side'=>'left') $search_searchString = TkVariable.new @@ -133,9 +135,9 @@ TkFrame.new($search_demo) {|f| } }.pack('side'=>'top', 'fill'=>'x') -$search_text = TkText.new($search_demo, 'setgrid'=>true, 'wrap'=>'word') {|t| +$search_text = TkText.new(base_frame, 'setgrid'=>true, 'wrap'=>'word') {|t| $search_Tag = TkTextTag.new(t) - TkScrollbar.new($search_demo, 'command'=>proc{|*args| t.yview(*args)}) {|sc| + TkScrollbar.new(base_frame, 'command'=>proc{|*args| t.yview(*args)}) {|sc| t.yscrollcommand(proc{|first,last| sc.set first,last}) pack('side'=>'right', 'fill'=>'y') } diff --git a/ext/tk/sample/demos-en/spin.rb b/ext/tk/sample/demos-en/spin.rb index 58616b1e02..c2a3a8949b 100644 --- a/ext/tk/sample/demos-en/spin.rb +++ b/ext/tk/sample/demos-en/spin.rb @@ -15,7 +15,9 @@ $spin_demo = TkToplevel.new {|w| positionWindow(w) } -TkLabel.new($spin_demo, +base_frame = TkFrame.new($spin_demo).pack(:fill=>:both, :expand=>true) + +TkLabel.new(base_frame, :font=>$font, :wraplength=>'5i', :justify=>:left, :text=><:top) Three different spin-boxes are displayed below. \ @@ -34,7 +36,7 @@ this demo doesn't work. Please use later version of Tk \ which supports a 'spinbox' widget. EOL -TkFrame.new($spin_demo){|f| +TkFrame.new(base_frame){|f| pack(:side=>:bottom, :fill=>:x, :pady=>'2m') TkButton.new(f, :text=>'Dismiss', :width=>15, :command=>proc{ @@ -53,11 +55,11 @@ australianCities = [ ] [ - TkSpinbox.new($spin_demo, :from=>1, :to=>10, :width=>10, :validate=>:key, + TkSpinbox.new(base_frame, :from=>1, :to=>10, :width=>10, :validate=>:key, :validatecommand=>[ proc{|s| s == '' || /^[+-]?\d+$/ =~ s }, '%P' ]), - TkSpinbox.new($spin_demo, :from=>0, :to=>3, :increment=>0.5, + TkSpinbox.new(base_frame, :from=>0, :to=>3, :increment=>0.5, :format=>'%05.2f', :width=>10), - TkSpinbox.new($spin_demo, :values=>australianCities, :width=>10) + TkSpinbox.new(base_frame, :values=>australianCities, :width=>10) ].each{|sbox| sbox.pack(:side=>:top, :pady=>5, :padx=>10)} diff --git a/ext/tk/sample/demos-en/states.rb b/ext/tk/sample/demos-en/states.rb index d38c1245af..add0e84800 100644 --- a/ext/tk/sample/demos-en/states.rb +++ b/ext/tk/sample/demos-en/states.rb @@ -19,8 +19,10 @@ $states_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($states_demo).pack(:fill=>:both, :expand=>true) + # label -msg = TkLabel.new($states_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -29,7 +31,7 @@ msg = TkLabel.new($states_demo) { msg.pack('side'=>'top') # frame -TkFrame.new($states_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -48,7 +50,7 @@ TkFrame.new($states_demo) {|frame| # frame states_lbox = nil -TkFrame.new($states_demo, 'borderwidth'=>'.5c') {|w| +TkFrame.new(base_frame, 'borderwidth'=>'.5c') {|w| s = TkScrollbar.new(w) states_lbox = TkListbox.new(w) { setgrid 1 diff --git a/ext/tk/sample/demos-en/style.rb b/ext/tk/sample/demos-en/style.rb index 06952f41b8..c2fed23926 100644 --- a/ext/tk/sample/demos-en/style.rb +++ b/ext/tk/sample/demos-en/style.rb @@ -19,8 +19,10 @@ $style_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($style_demo).pack(:fill=>:both, :expand=>true) + # frame -TkFrame.new($style_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -37,14 +39,14 @@ TkFrame.new($style_demo) {|frame| }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # text -TkText.new($style_demo){|t| +txt = TkText.new(base_frame){|t| # setgrid 'true' #width 70 #height 32 wrap 'word' font $font - TkScrollbar.new($style_demo) {|s| + TkScrollbar.new(base_frame) {|s| pack('side'=>'right', 'fill'=>'y') command proc{|*args| t.yview(*args)} t.yscrollcommand proc{|first,last| s.set first,last} diff --git a/ext/tk/sample/demos-en/text.rb b/ext/tk/sample/demos-en/text.rb index 4bb4b6bc7e..3ce8cdfda8 100644 --- a/ext/tk/sample/demos-en/text.rb +++ b/ext/tk/sample/demos-en/text.rb @@ -19,6 +19,8 @@ $text_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($text_demo).pack(:fill=>:both, :expand=>true) + # version check if ((Tk::TK_VERSION.split('.').collect{|n| n.to_i} <=> [8,4]) < 0) undo_support = false @@ -27,7 +29,7 @@ else end # frame -TkFrame.new($text_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -44,7 +46,7 @@ TkFrame.new($text_demo) {|frame| }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # text -TkText.new($text_demo){|t| +TkText.new(base_frame){|t| relief 'sunken' bd 2 setgrid 1 @@ -53,7 +55,7 @@ TkText.new($text_demo){|t| undo true autoseparators true end - TkScrollbar.new($text_demo) {|s| + TkScrollbar.new(base_frame) {|s| pack('side'=>'right', 'fill'=>'y') command proc{|*args| t.yview(*args)} t.yscrollcommand proc{|first,last| s.set first,last} diff --git a/ext/tk/sample/demos-en/textpeer.rb b/ext/tk/sample/demos-en/textpeer.rb index d98ef170b4..c25ce15e5c 100644 --- a/ext/tk/sample/demos-en/textpeer.rb +++ b/ext/tk/sample/demos-en/textpeer.rb @@ -15,10 +15,12 @@ $textpeer_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($textpeer_demo).pack(:fill=>:both, :expand=>true) + count = [0] ## Define a widget that we peer from; it won't ever actually be shown though -first = TkText.new($textpeer_demo, :widgetname=>"text#{count[0] += 1}") +first = TkText.new(base_frame, :widgetname=>"text#{count[0] += 1}") first.insert :end,"This is a coupled pair of text widgets; they are peers to " first.insert :end,"each other. They have the same underlying data model, but " first.insert :end,"can show different locations, have different current edit " @@ -28,6 +30,8 @@ first.insert :end,"the Make Peer button beside the text widget to clone, and " first.insert :end,"delete a particular peer widget using the Delete Peer " first.insert :end,"button." +Tk.update_idletasks ## for 'first' widget + ## Procedures to make and kill clones; most of this is just so that the demo ## looks nice... def makeClone(count, win, txt) @@ -52,12 +56,12 @@ def killClone(win, cnt) end ## Now set up the GUI -makeClone(count, $textpeer_demo, first) -makeClone(count, $textpeer_demo, first) +makeClone(count, base_frame, first) +makeClone(count, base_frame, first) first.destroy ## See Code / Dismiss buttons -TkFrame.new($textpeer_demo){|f| +TkFrame.new(base_frame){|f| TkButton.new(f, :text=>'Dismiss', :width=>15, :command=>proc{ $textpeer_demo.destroy $textpeer_demo = nil @@ -69,4 +73,4 @@ TkFrame.new($textpeer_demo){|f| TkGrid.configure(f, '-', '-', :sticky=>'ew', :row=>5000) } -TkGrid.columnconfigure($textpeer_demo, 0, :weight=>1) +TkGrid.columnconfigure(base_frame, 0, :weight=>1) diff --git a/ext/tk/sample/demos-en/toolbar.rb b/ext/tk/sample/demos-en/toolbar.rb new file mode 100644 index 0000000000..700db68146 --- /dev/null +++ b/ext/tk/sample/demos-en/toolbar.rb @@ -0,0 +1,128 @@ +# toolbar.rb -- +# +# This demonstration script creates a toolbar that can be torn off. +# +# based on "Id: toolbar.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp" + +if defined?($toolbar_demo) && $toolbar_demo + $toolbar_demo.destroy + $toolbar_demo = nil +end + +$toolbar_demo = TkToplevel.new {|w| + title("Ttk Menu Buttons") + iconname("toolbar") + positionWindow(w) +} + +base_frame = Ttk::Frame.new($toolbar_demo).pack(:fill=>:both, :expand=>true) + +if Tk.windowingsystem != 'aqua' + msg = Ttk::Label.new(base_frame, :wraplength=>'4i', :text=><'4i', :text=><'toolbar') # for window title +sep = Ttk::Separator.new(base_frame) +to_base = Ttk::Frame.new(tbar_base, :cursor=>'fleur') +if Tk.windowingsystem != 'aqua' + to = Ttk::Separator.new(to_base, :orient=>:vertical) + to2 = Ttk::Separator.new(to_base, :orient=>:vertical) + to.pack(:fill=>:y, :expand=>true, :padx=>2, :side=>:left) + to2.pack(:fill=>:y, :expand=>true, :side=>:left) +end + +contents = Ttk::Frame.new(tbar_base) +Tk.grid(to_base, contents, :sticky=>'nsew') +tbar_base.grid_columnconfigure(contents, :weight=>1) +contents.grid_columnconfigure(1000, :weight=>1) + +if Tk.windowingsystem != 'aqua' + ## Bindings so that the toolbar can be torn off and reattached + to_base.bind('B1-Motion', '%X %Y'){|x, y| tbar_base.tearoff(to_base, x, y)} + to. bind('B1-Motion', '%X %Y'){|x, y| tbar_base.tearoff(to_base, x, y)} + to2. bind('B1-Motion', '%X %Y'){|x, y| tbar_base.tearoff(to_base, x, y)} + def tbar_base.tearoff(w, x, y) + on_win = TkWinfo.containing(x, y) + return unless (on_win && on_win.path =~ /^#{@path}(\.|$)/) + self.grid_remove + w.grid_remove + self.wm_manage + # self.wm_title('Toolbar') # if you don't want to use its widget name as a window title. + self.wm_protocol('WM_DELETE_WINDOW'){ self.untearoff(self) } + end + def tbar_base.untearoff(w) + self.wm_forget + w.grid + self.grid + end +end + +## Some content for the rest of the toplevel +text = TkText.new(base_frame, :width=>40, :height=>10) + +## Toolbar contents +tb_btn = Ttk::Button.new(tbar_base, :text=>'Button', :style=>'Toolbutton', + :command=>proc{text.insert(:end, "Button Pressed\n")}) +tb_chk = Ttk::Checkbutton.new(tbar_base, :text=>'Check', :style=>'Toolbutton', + :variable=>(check = TkVariable.new), + :command=>proc{ + text.insert(:end, "Check is #{check.value}\n") + }) +tb_mbtn = Ttk::Menubutton.new(tbar_base, :text=>'Menu') +tb_combo = Ttk::Combobox.new(tbar_base, :value=>TkFont.families, + :state=>:readonly) +tb_mbtn.menu(menu = Tk::Menu.new(tb_mbtn)) +menu.add(:command, :label=>'Just', :command=>proc{text.insert(:end, "Just\n")}) +menu.add(:command, :label=>'An', :command=>proc{text.insert(:end, "An\n")}) +menu.add(:command, :label=>'Example', + :command=>proc{text.insert(:end, "Example\n")}) +tb_combo.bind(''){ text.font.family = tb_combo.get } + +## Arrange contents +Tk.grid(tb_btn, tb_chk, tb_mbtn, tb_combo, + :in=>contents, :padx=>2, :sticky=>'ns') +Tk.grid(tbar_base, :sticky=>'ew') +Tk.grid(sep, :sticky=>'ew') +Tk.grid(msg, :sticky=>'ew') +Tk.grid(text, :sticky=>'nsew') +base_frame.grid_rowconfigure(text, :weight=>1) +base_frame.grid_columnconfigure(text, :weight=>1) + +## See Code / Dismiss buttons +Ttk::Frame.new(base_frame) {|frame| + sep = Ttk::Separator.new(frame) + Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + Ttk::Button.new(frame, :text=>'See Code', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'toolbar'}), + Ttk::Button.new(frame, :text=>'Dismiss', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + $toolbar_demo.destroy + $toolbar_demo = nil + }), + :padx=>4, :pady=>4) + grid_columnconfigure(0, :weight=>1) + Tk.grid(frame, :sticky=>'ew') +} diff --git a/ext/tk/sample/demos-en/tree.rb b/ext/tk/sample/demos-en/tree.rb new file mode 100644 index 0000000000..0c7f0e71a2 --- /dev/null +++ b/ext/tk/sample/demos-en/tree.rb @@ -0,0 +1,119 @@ +# tree.rb -- +# +# This demonstration script creates a toplevel window containing a Ttk +# tree widget. +# +# based on "Id: tree.tcl,v 1.4 2007/12/13 15:27:07 dgp Exp" + +if defined?($tree_demo) && $tree_demo + $tree_demo.destroy + $tree_demo = nil +end + +$tree_demo = TkToplevel.new {|w| + title("Directory Browser") + iconname("tree") + positionWindow(w) +} + +base_frame = TkFrame.new($tree_demo).pack(:fill=>:both, :expand=>true) + +## Explanatory text +Ttk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', + :justify=>:left, :anchor=>'n', :padding=>[10, 2, 10, 6], + :text=><:x) +Ttk is the new Tk themed widget set. \ +One of the widgets it includes is a tree widget, \ +which allows the user to browse a hierarchical data-set such as a filesystem. \ +The tree widget not only allows for the tree part itself, \ +but it also supports an arbitrary number of additional columns \ +which can show additional data (in this case, the size of the files \ +found in your filesystem). \ +You can also change the width of the columns \ +by dragging the boundary between them. +EOL + +## See Code / Dismiss +Ttk::Frame.new(base_frame) {|frame| + sep = Ttk::Separator.new(frame) + Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + Ttk::Button.new(frame, :text=>'See Code', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'tree'}), + Ttk::Button.new(frame, :text=>'Dismiss', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + $tree_demo.destroy + $tree_demo = nil + }), + :padx=>4, :pady=>4) + grid_columnconfigure(0, :weight=>1) + pack(:side=>:bottom, :fill=>:x) +} + +## Code to populate the roots of the tree (can be more than one on Windows) +def populate_roots(tree) + TkComm.simplelist(Tk.tk_call('file', 'volumes')).sort.each{|dir| + populate_tree(tree, tree.insert(nil, :end, :text=>dir, + :values=>[dir, 'directory'])) + } +end + +## Code to populate a node of the tree +def populate_tree(tree, node) + return if tree.get(node, :type) != 'directory' + + path = tree.get(node, :fullpath) + tree.delete(tree.children(node)) + Dir.glob("#{path}/*").sort.each{|f| + type = File.ftype(f) + id = tree.insert(node, :end, + :text=>File.basename(f), :values=>[f, type]).id + if type == 'directory' + ## Make it so that this node is openable + tree.insert(id, 0, :text=>'dummy') + tree.itemconfigure(id, :text=>File.basename(f)) + elsif type == 'file' + size = File.size(f) + if size >= 1024*1024*1024 + size = '%.1f GB' % (size.to_f/1024/1024/1024) + elsif size >= 1024*1024 + size = '%.1f MB' % (size.to_f/1024/1024) + elsif size >= 1024 + size = '%.1f KB' % (size.to_f/1024) + else + size = '%.1f bytes' % (size.to_f/1024) + end + tree.set(id, :size, size) + end + } + + # Stop this code from rerunning on the current node + tree.set(node, :type, 'processed_directory') +end + +## Create the tree and set it up +tree = Ttk::Treeview.new(base_frame, :columns=>%w(fullpath type size), + :displaycolumns=>['size']) +if Tk.windowingsystem != 'aqua' + vsb = tree.yscrollbar(Ttk::Scrollbar.new(base_frame)) + hsb = tree.xscrollbar(Ttk::Scrollbar.new(base_frame)) +else + vsb = tree.yscrollbar(Tk::Scrollbar.new(base_frame)) + hsb = tree.xscrollbar(Tk::Scrollbar.new(base_frame)) +end + +tree.heading_configure('#0', :text=>'Directory Structure') +tree.heading_configure('size', :text=>'File Size') +tree.column_configure('size', :stretch=>0, :width=>70) +populate_roots(tree) +tree.bind('', '%W'){|w| populate_tree(w, w.focus_item)} + +## Arrange the tree and its scrollbars in the toplevel +container = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true) +container.lower +Tk.grid(tree, vsb, :in=>container, :sticky=>'nsew') +Tk.grid(hsb, :in=>container, :sticky=>'nsew') +container.grid_columnconfigure(0, :weight=>1) +container.grid_rowconfigure(0, :weight=>1) diff --git a/ext/tk/sample/demos-en/ttkbut.rb b/ext/tk/sample/demos-en/ttkbut.rb new file mode 100644 index 0000000000..b5780f589a --- /dev/null +++ b/ext/tk/sample/demos-en/ttkbut.rb @@ -0,0 +1,139 @@ +# ttkbut.rb +# +# This demonstration script creates a toplevel window containing several +# simple Ttk widgets, such as labels, labelframes, buttons, checkbuttons and +# radiobuttons. +# +# based on "Id: ttkbut.tcl,v 1.4 2007/12/13 15:27:07 dgp Exp" + +if defined?($ttkbut_demo) && $ttkbut_demo + $ttkbut_demo.destroy + $ttkbut_demo = nil +end + +$ttkbut_demo = TkToplevel.new {|w| + title("Simple Ttk Widgets") + iconname("ttkbut") + positionWindow(w) +} + +base_frame = TkFrame.new($ttkbut_demo).pack(:fill=>:both, :expand=>true) + +Ttk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, + :text=><:top, :fill=>:x) +Ttk is the new Tk themed widget set. This is a Ttk themed label, \ +and below are three groups of Ttk widgets in Ttk labelframes. \ +The first group are all buttons that set the current application theme \ +when pressed. The second group contains three sets of checkbuttons, \ +with a separator widget between the sets. Note that the "Enabled" \ +button controls whether all the other themed widgets in this toplevel are \ +in the disabled state. The third group has a collection of linked \ +radiobuttons. +EOL + +## Add buttons for setting the theme +buttons = Ttk::Labelframe.new(base_frame, :text=>'Buttons') +# Ttk::Style.theme_names.each{|theme| +# Ttk::Button.new(buttons, :text=>theme, +# :command=>proc{Ttk::Style.theme_use theme}).pack(:pady=>2) +# } +Ttk.themes.each{|theme| + Ttk::Button.new(buttons, :text=>theme, + :command=>proc{Ttk.set_theme theme}).pack(:pady=>2) +} + +## Helper procedure for the top checkbutton +def setState(root, value, *excepts) + return if excepts.member?(root) + + ## Non-Ttk widgets (e.g. the toplevel) will fail, so make it silent + begin + root.state = value + rescue + end + + ## Recursively invoke on all children of this root that are in the same + ## toplevel widget + root.winfo_children.each{|w| + setState(w, value, *excepts) if w.winfo_toplevel == root.winfo_toplevel + } +end + +## Set up the checkbutton group +checks = Ttk::Labelframe.new(base_frame, :text=>'Checkbuttons') +enabled = TkVariable.new(true) +e = Ttk::Checkbutton.new(checks, :text=>'Enabled', :variable=>enabled, + :command=>proc{ + setState($ttkbut_demo, + ((enabled.bool)? "!disabled" : "disabled"), + e) + }) + +## See ttk_widget(n) for other possible state flags +sep1 = Ttk::Separator.new(checks) +sep2 = Ttk::Separator.new(checks) + +cheese = TkVariable.new +tomato = TkVariable.new +basil = TkVariable.new +oregano = TkVariable.new + +c1 = Ttk::Checkbutton.new(checks, :text=>'Cheese', :variable=>cheese) +c2 = Ttk::Checkbutton.new(checks, :text=>'Tomato', :variable=>tomato) +c3 = Ttk::Checkbutton.new(checks, :text=>'Basil', :variable=>basil) +c4 = Ttk::Checkbutton.new(checks, :text=>'Oregano', :variable=>oregano) + +Tk.pack(e, sep1, c1, c2, sep2, c3, c4, :fill=>:x, :pady=>2) + +## Set up the radiobutton group +radios = Ttk::Labelframe.new(base_frame, :text=>'Radiobuttons') + +happyness = TkVariable.new + +r1 = Ttk::Radiobutton.new(radios, :variable=>happyness, + :text=>'Great', :value=>'great') +r2 = Ttk::Radiobutton.new(radios, :variable=>happyness, + :text=>'Good', :value=>'good') +r3 = Ttk::Radiobutton.new(radios, :variable=>happyness, + :text=>'Ok', :value=>'ok') +r4 = Ttk::Radiobutton.new(radios, :variable=>happyness, + :text=>'Poor', :value=>'poor') +r5 = Ttk::Radiobutton.new(radios, :variable=>happyness, + :text=>'Awful', :value=>'awful') + +Tk.pack(r1, r2, r3, r4, r5, :fill=>:x, :padx=>3, :pady=>2) + +## See Code / Dismiss +Ttk::Frame.new(base_frame) {|frame| + sep = Ttk::Separator.new(frame) + Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + Ttk::Button.new(frame, :text=>'See Variables', + :image=>$image['view'], :compound=>:left, + :command=>proc{ + showVars(base_frame, ['enabled', enabled], + ['cheese', cheese], ['tomato', tomato], + ['basil', basil], ['oregano', oregano], + ['happyness', happyness]) + }), + Ttk::Button.new(frame, :text=>'See Code', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'ttkbut'}), + Ttk::Button.new(frame, :text=>'Dismiss', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + tmppath = $ttkbut_demo + $ttkbut_demo = nil + $showVarsWin[tmppath.path] = nil + tmppath.destroy + }), + :padx=>4, :pady=>4) + grid_columnconfigure(0, :weight=>1) + pack(:side=>:bottom, :fill=>:x, :expand=>true) +} + +## Arrange things neatly +f = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true) +f.lower +Tk.grid(buttons, checks, radios, :in=>f, :sticky=>'nwe', :pady=>2, :padx=>3) +f.grid_columnconfigure([0, 1, 2], :weight=>1, :uniform=>:yes) diff --git a/ext/tk/sample/demos-en/ttkmenu.rb b/ext/tk/sample/demos-en/ttkmenu.rb new file mode 100644 index 0000000000..75ecdb09c4 --- /dev/null +++ b/ext/tk/sample/demos-en/ttkmenu.rb @@ -0,0 +1,85 @@ +# ttkmenu.rb -- +# +# This demonstration script creates a toplevel window containing several Ttk +# menubutton widgets. +# +# based on "Id: ttkmenu.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp" + +if defined?($ttkmenu_demo) && $ttkmenu_demo + $ttkmenu_demo.destroy + $ttkmenu_demo = nil +end + +$ttkmenu_demo = TkToplevel.new {|w| + title("Ttk Menu Buttons") + iconname("ttkmenu") + positionWindow(w) +} + +base_frame = Ttk::Frame.new($ttkmenu_demo).pack(:fill=>:both, :expand=>true) + +Ttk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, + :text=><:top, :fill=>:x) +Ttk is the new Tk themed widget set, \ +and one widget that is available in themed form is the menubutton. \ +Below are some themed menu buttons \ +that allow you to pick the current theme in use. \ +Notice how picking a theme changes the way \ +that the menu buttons themselves look, \ +and that the central menu button is styled differently \ +(in a way that is normally suitable for toolbars). \ +However, there are no themed menus; the standard Tk menus were judged \ +to have a sufficiently good look-and-feel on all platforms, \ +especially as they are implemented as native controls in many places. +EOL + +Ttk::Separator.new(base_frame).pack(:side=>:top, :fill=>:x) + +## See Code / Dismiss +Ttk::Frame.new($ttkmenu_demo) {|frame| + sep = Ttk::Separator.new(frame) + Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + Ttk::Button.new(frame, :text=>'See Code', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'ttkmenu'}), + Ttk::Button.new(frame, :text=>'Dismiss', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + $ttkmenu_demo.destroy + $ttkmenu_demo = nil + }), + :padx=>4, :pady=>4) + grid_columnconfigure(0, :weight=>1) + pack(:side=>:bottom, :fill=>:x) +} + +b1 = Ttk::Menubutton.new(base_frame,:text=>'Select a theme',:direction=>:above) +b2 = Ttk::Menubutton.new(base_frame,:text=>'Select a theme',:direction=>:left) +b3 = Ttk::Menubutton.new(base_frame,:text=>'Select a theme',:direction=>:right) +b4 = Ttk::Menubutton.new(base_frame,:text=>'Select a theme',:direction=>:flush, + :style=>Ttk::Menubutton.style('Toolbutton')) +b5 = Ttk::Menubutton.new(base_frame,:text=>'Select a theme',:direction=>:below) + +b1.menu(m1 = Tk::Menu.new(b1, :tearoff=>false)) +b2.menu(m2 = Tk::Menu.new(b2, :tearoff=>false)) +b3.menu(m3 = Tk::Menu.new(b3, :tearoff=>false)) +b4.menu(m4 = Tk::Menu.new(b4, :tearoff=>false)) +b5.menu(m5 = Tk::Menu.new(b5, :tearoff=>false)) + +Ttk.themes.each{|theme| + m1.add(:command, :label=>theme, :command=>proc{Ttk.set_theme theme}) + m2.add(:command, :label=>theme, :command=>proc{Ttk.set_theme theme}) + m3.add(:command, :label=>theme, :command=>proc{Ttk.set_theme theme}) + m4.add(:command, :label=>theme, :command=>proc{Ttk.set_theme theme}) + m5.add(:command, :label=>theme, :command=>proc{Ttk.set_theme theme}) +} + +f = Ttk::Frame.new(base_frame).pack(:fill=>:x) +f1 = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true) +f.lower + +f.grid_anchor(:center) +TkGrid('x', b1, 'x', :in=>f, :padx=>3, :pady=>2) +TkGrid(b2, b4, b3, :in=>f, :padx=>3, :pady=>2) +TkGrid('x', b5, 'x', :in=>f, :padx=>3, :pady=>2) diff --git a/ext/tk/sample/demos-en/ttknote.rb b/ext/tk/sample/demos-en/ttknote.rb new file mode 100644 index 0000000000..c2a22b447a --- /dev/null +++ b/ext/tk/sample/demos-en/ttknote.rb @@ -0,0 +1,89 @@ +# ttknote.rb -- +# +# This demonstration script creates a toplevel window containing a Ttk +# notebook widget. +# +# based on "Id: ttknote.tcl,v 1.5 2007/12/13 15:27:07 dgp Exp" + +if defined?($ttknote_demo) && $ttknote_demo + $ttknote_demo.destroy + $ttknote_demo = nil +end + +$ttknote_demo = TkToplevel.new {|w| + title("Ttk Notebook Widget") + iconname("ttknote") + positionWindow(w) +} + +## See Code / Dismiss +Ttk::Frame.new($ttknote_demo) {|frame| + sep = Ttk::Separator.new(frame) + Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + Ttk::Button.new(frame, :text=>'See Code', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'ttknote'}), + Ttk::Button.new(frame, :text=>'Dismiss', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + $ttknote_demo.destroy + $ttknote_demo = nil + }), + :padx=>4, :pady=>4) + grid_columnconfigure(0, :weight=>1) + pack(:side=>:bottom, :fill=>:x) +} + +base_frame = Ttk::Frame.new($ttknote_demo).pack(:fill=>:both, :expand=>true) + +## Make the notebook and set up Ctrl+Tab traversal +notebook = Ttk::Notebook.new(base_frame).pack(:fill=>:both, :expand=>true, + :padx=>2, :pady=>3) +notebook.enable_traversal + +## Popuplate the first pane +f_msg = Ttk::Frame.new(notebook) +msg_m = Ttk::Label.new(f_msg, :font=>$font, :wraplength=>'4i', + :justify=>:left, :anchor=>'n', :text=><'Neat!', :underline=>0, + :command=>proc{ + neat.value = 'Yeah, I know...' + Tk.after_cancel(after_id) if after_id + after_id = Tk.after(500){neat.value = ''} + }) +msg_b.winfo_toplevel.bind('Alt-n'){ msg_b.focus; msg_b.invoke } +msg_l = Ttk::Label.new(f_msg, :textvariable=>neat) +notebook.add(f_msg, :text=>'Description', :underline=>0, :padding=>2) +Tk.grid(msg_m, '-', :sticky=>'new', :pady=>2) +Tk.grid(msg_b, msg_l, :pady=>[2, 4]) +f_msg.grid_rowconfigure(1, :weight=>1) +f_msg.grid_columnconfigure([0, 1], :weight=>1, :uniform=>1) + +## Populate the second pane. Note that the content doesn't really matter +f_disabled = Ttk::Frame.new(notebook) +notebook.add(f_disabled, :text=>'Disabled', :state=>:disabled) + +## Popuplate the third pane +f_editor = Ttk::Frame.new(notebook) +notebook.add(f_editor, :text=>'Text Editor', :underline=>0) +editor_t = Tk::Text.new(f_editor, :width=>40, :height=>10, :wrap=>:char) +if Tk.windowingsystem != 'aqua' + editor_s = editor_t.yscrollbar(Ttk::Scrollbar.new(f_editor)) +else + editor_s = editor_t.yscrollbar(Tk::Scrollbar.new(f_editor)) +end +editor_s.pack(:side=>:right, :fill=>:y, :padx=>[0,2], :pady=>2) +editor_t.pack(:fill=>:both, :expand=>true, :padx=>[2,0], :pady=>2) diff --git a/ext/tk/sample/demos-en/ttkpane.rb b/ext/tk/sample/demos-en/ttkpane.rb new file mode 100644 index 0000000000..56df613db4 --- /dev/null +++ b/ext/tk/sample/demos-en/ttkpane.rb @@ -0,0 +1,213 @@ +# ttkpane.rb -- +# +# This demonstration script creates a Ttk pane with some content. +# +# based on "Id: ttkpane.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp" + +if defined?($ttkpane_demo) && $ttkpane_demo + $ttkpane_demo.destroy + $ttkpane_demo = nil +end + +$ttkpane_demo = TkToplevel.new {|w| + title("Themed Nested Panes") + iconname("ttkpane") + positionWindow(w) +} + +base_frame = TkFrame.new($ttkpane_demo).pack(:fill=>:both, :expand=>true) + +Ttk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, + :text=><:top, :fill=>:x) +This demonstration shows off a nested set of themed paned windows. \ +Their sizes can be changed by grabbing the area \ +between each contained pane and dragging the divider. +EOL + +Ttk::Separator.new(base_frame).pack(:side=>:top, :fill=>:x) + +## See Code / Dismiss +Ttk::Frame.new(base_frame) {|frame| + sep = Ttk::Separator.new(frame) + Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + Ttk::Button.new(frame, :text=>'See Code', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'ttkpane'}), + Ttk::Button.new(frame, :text=>'Dismiss', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + $ttkpane_demo.destroy + $ttkpane_demo = nil + }), + :padx=>4, :pady=>4) + grid_columnconfigure(0, :weight=>1) + pack(:side=>:bottom, :fill=>:x) +} + +frame = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true) + +outer = Ttk::Panedwindow.new(frame, :orient=>:horizontal) +outer.add(in_left = Ttk::Panedwindow.new(outer, :orient=>:vertical)) +outer.add(in_right = Ttk::Panedwindow.new(outer, :orient=>:vertical)) +in_left.add(left_top = Ttk::Labelframe.new(in_left, :text=>'Button')) +in_left.add(left_bot = Ttk::Labelframe.new(in_left, :text=>'Clocks')) +in_right.add(right_top = Ttk::Labelframe.new(in_right, :text=>'Progress')) +in_right.add(right_bot = Ttk::Labelframe.new(in_right, :text=>'Text')) +if Tk.windowingsystem == 'aqua' + [left_top, left_bot, right_top, right_bot].each{|w| w.padding(3) } +end + +# Fill the button pane +Ttk::Button.new(left_top, :text=>'Press Me', + :command=>proc{ + Tk.messageBox(:type=>'ok', :icon=>'info', :message=>'Ouch!', + :detail=>'That hurt...', :parent=>base_frame, + :title=>'Button Pressed') + }).pack(:padx=>2, :pady=>5) + + +zones_list = [ + [':Europe/Berlin'], + [':America/Argentina/Buenos_Aires', ':America/Buenos_Aires'], + [':Africa/Johannesburg'], + [':Europe/London'], + [':America/Los_Angeles'], + [':Europe/Moscow'], + [':America/New_York'], + [':Asia/Singapore'], + [':Australia/Sydney'], + [':Asia/Tokyo'], +] + +zones = [] + +# Check tzinfo support +if $tk_major_ver > 8 || ($tk_major_ver == 8 && $tk_minor_ver >= 5) + tzinfo = :tcl + + # Force a pre-load of all the timezones needed; otherwise can end up + # poor-looking synch problems! + zones_list.each{|list| + list.each{|zone| + begin + Tk.tk_call('clock', 'format', '0', '-timezone', zone) + rescue RuntimeError + # ignore + else + zones << [zone, zone[%r<[^/:]+$>].tr('_', ' ')] + break + end + } + } + +else + begin + require 'tzinfo' + tzinfo = :tzinfo + rescue Exception + begin + require 'tzfile' + tzinfo = :tzfile + rescue Exception + tzinfo = nil + end + end + + case tzinfo + when :tzinfo + zones_list.each{|list| + list.each{|zone| + begin + tz = TZInfo::Timezone.get(zone[%r<[^:]+$>]) + rescue Exception + # ignore + else + zones << [tz, zone[%r<[^/:]+$>].tr('_', ' ')] + break + end + } + } + + when :tzfile + zones_list.each{|list| + list.each{|zone| + begin + tz = TZFile.create(zone[%r<[^:]+$>]) + rescue Exception + # ignore + else + zones << [tz, zone[%r<[^/:]+$>].tr('_', ' ')] + break + end + } + } + + else + [ -7, -4, -2, -1, 0, +1, +3, +8, +9, +10 ].each{|zone| + zones << [zone, 'UTC%+03d00' % zone] + } + end +end + +time = TkVariable.new_hash + +case tzinfo +when :tcl + update_proc = proc{|now, tz, label| + time[label] = Tk.tk_call('clock', 'format', now.tv_sec, + '-timezone', tz, '-format', '%T') + } +when :tzinfo + update_proc = proc{|now, tz, label| + time[label] = tz.utc_to_local(now).strftime('%H:%M:%S') + } +when :tzfile + update_proc = proc{|now, tz, label| + time[label] = tz.at(now.tv_sec).strftime('%H:%M:%S') + } +else + update_proc = proc{|now, tz, label| + time[label] = (now + (tz * 3600)).strftime('%H:%M:%S') + } +end + +# Fill the clocks pane +zones.each_with_index{|(zone, label), idx| + Ttk::Separator.new(left_bot).pack(:fill=>:x) if idx > 0 + Ttk::Label.new(left_bot, :text=>label, :anchor=>'w').pack(:fill=>:x) + Ttk::Label.new(left_bot, :textvariable=>time.ref(label), + :anchor=>'w').pack(:fill=>:x) +} + +# Timer start +every = proc{ + now = Time.now.utc + zones.each{|zone, label| update_proc.call(now, zone, label) } +} +TkRTTimer.new(1000, -1, every).start(0, every) + +# Fill the progress pane +Ttk::Progressbar.new(right_top, :mode=>:indeterminate).pack(:fill=>:both, :expand=>true).start + +# Fill the text pane +if Tk.windowingsystem != 'aqua' + # The trick with the ttk::frame makes the text widget look like it fits with + # the current Ttk theme despite not being a themed widget itself. It is done + # by styling the frame like an entry, turning off the border in the text + # widget, and putting the text widget in the frame with enough space to allow + # the surrounding border to show through (2 pixels seems to be enough). + f = Ttk::Frame.new(right_bot, :style=>Ttk::Entry) + txt = TkText.new(frame, :wrap=>:word, :width=>30, :borderwidth=>0) + txt.pack(:fill=>:both, :expand=>true, :in=>f, :pady=>2, :padx=>2) + scr = txt.yscrollbar(Ttk::Scrollbar.new(frame)) + scr.pack(:side=>:right, :fill=>:y, :in=>right_bot) + f.pack(:fill=>:both, :expand=>true) + outer.pack(:fill=>:both, :expand=>true) +else + txt = TkText.new(frame, :wrap=>:word, :width=>30, :borderwidth=>0) + scr = txt.yscrollbar(TkScrollbar.new(frame)) + scr.pack(:side=>:right, :fill=>:y, :in=>right_bot) + txt.pack(:fill=>:both, :expand=>true, :in=>right_bot) + outer.pack(:fill=>:both, :expand=>true, :padx=>10, :pady=>[6, 10]) +end diff --git a/ext/tk/sample/demos-en/ttkprogress.rb b/ext/tk/sample/demos-en/ttkprogress.rb new file mode 100644 index 0000000000..d1b882f546 --- /dev/null +++ b/ext/tk/sample/demos-en/ttkprogress.rb @@ -0,0 +1,66 @@ +# ttkprogress.rb -- +# +# This demonstration script creates several progress bar widgets. +# +# based on "Id: ttkprogress.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp" + +if defined?($ttkprogress_demo) && $ttkprogress_demo + $ttkprogress_demo.destroy + $ttkprogress_demo = nil +end + +$ttkprogress_demo = TkToplevel.new {|w| + title("Progress Bar Demonstration") + iconname("ttkprogress") + positionWindow(w) +} + +base_frame = TkFrame.new($ttkprogress_demo).pack(:fill=>:both, :expand=>true) + +Ttk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, + :text=><:top, :fill=>:x) +Below are two progress bars. \ +The top one is a \u201Cdeterminate\u201D progress bar, \ +which is used for showing how far through a defined task the program has got. \ +The bottom one is an \u201Cindeterminate\u201D progress bar, \ +which is used to show that the program is busy \ +but does not know how long for. Both are run here in self-animated mode, \ +which can be turned on and off using the buttons underneath. +EOL + +## See Code / Dismiss buttons +Ttk::Frame.new(base_frame) {|frame| + sep = Ttk::Separator.new(frame) + Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + Ttk::Button.new(frame, :text=>'See Code', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'ttkprogress'}), + Ttk::Button.new(frame, :text=>'Dismiss', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + $ttkprogress_demo.destroy + $ttkprogress_demo = nil + }), + :padx=>4, :pady=>4) + grid_columnconfigure(0, :weight=>1) + pack(:side=>:bottom, :fill=>:x) +} + +frame = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true) + +p1 = Ttk::Progressbar.new(frame, :mode=>:determinate) +p2 = Ttk::Progressbar.new(frame, :mode=>:indeterminate) + +start = Ttk::Button.new(frame, :text=>'Start Progress', + :command=>proc{ p1.start; p2.start }) +stop = Ttk::Button.new(frame, :text=>'Stop Progress', + :command=>proc{ p1.stop; p2.stop }) + +Tk.grid(p1, '-', :pady=>5, :padx=>10) +Tk.grid(p2, '-', :pady=>5, :padx=>10) +Tk.grid(start, stop, :padx=>10, :pady=>5) +start.grid_configure(:sticky=>'e') +stop.grid_configure(:sticky=>'w') +frame.grid_columnconfigure(:all, :weight=>1) + diff --git a/ext/tk/sample/demos-en/twind.rb b/ext/tk/sample/demos-en/twind.rb index f29e49f35a..65ee712ff7 100644 --- a/ext/tk/sample/demos-en/twind.rb +++ b/ext/tk/sample/demos-en/twind.rb @@ -19,8 +19,10 @@ $twind_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($twind_demo).pack(:fill=>:both, :expand=>true) + # frame -$twind_buttons = TkFrame.new($twind_demo) {|frame| +$twind_buttons = TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -39,13 +41,13 @@ $twind_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # frame $twind_text = nil -TkFrame.new($twind_demo, 'highlightthickness'=>2, 'borderwidth'=>2, +TkFrame.new(base_frame, 'highlightthickness'=>2, 'borderwidth'=>2, 'relief'=>'sunken') {|f| $twind_text = TkText.new(f, 'setgrid'=>'true', 'font'=>$font, 'width'=>'70', 'height'=>35, 'wrap'=>'word', 'highlightthickness'=>0, 'borderwidth'=>0 ){|t| TkScrollbar.new(f) {|s| - command proc{|*args| t.yview(args)} + command proc{|*args| t.yview(*args)} t.yscrollcommand proc{|first,last| s.set first,last} }.pack('side'=>'right', 'fill'=>'y') }.pack('expand'=>'yes', 'fill'=>'both') diff --git a/ext/tk/sample/demos-en/twind2.rb b/ext/tk/sample/demos-en/twind2.rb index c42e0999d7..43990c1151 100644 --- a/ext/tk/sample/demos-en/twind2.rb +++ b/ext/tk/sample/demos-en/twind2.rb @@ -15,8 +15,10 @@ $twind2_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($twind2_demo).pack(:fill=>:both, :expand=>true) + # frame -$twind2_buttons = TkFrame.new($twind2_demo) {|frame| +$twind2_buttons = TkFrame.new(base_frame) {|frame| TkGrid(TkFrame.new(frame, :height=>2, :relief=>:sunken, :bd=>2), :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) TkGrid('x', @@ -38,7 +40,7 @@ $twind2_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # frame $twind2_text = nil -TkFrame.new($twind2_demo, 'highlightthickness'=>2, 'borderwidth'=>2, +TkFrame.new(base_frame, 'highlightthickness'=>2, 'borderwidth'=>2, 'relief'=>'sunken') {|f| $twind2_text = TkText.new(f, 'setgrid'=>true, 'font'=>$font, # 'width'=>'70', 'height'=>35, 'wrap'=>'word', diff --git a/ext/tk/sample/demos-en/unicodeout.rb b/ext/tk/sample/demos-en/unicodeout.rb index 07e3bf52b5..9c230a2536 100644 --- a/ext/tk/sample/demos-en/unicodeout.rb +++ b/ext/tk/sample/demos-en/unicodeout.rb @@ -16,7 +16,9 @@ $unicodeout_demo = TkToplevel.new {|w| positionWindow(w) } -TkLabel.new($unicodeout_demo, +base_frame = TkFrame.new($unicodeout_demo).pack(:fill=>:both, :expand=>true) + +TkLabel.new(base_frame, :font=>$font, :wraplength=>'5.4i', :justify=>:left, :text=><:top) This is a sample of Tk's support for languages that use non-Western \ @@ -36,7 +38,7 @@ The strings are converted to the encoded string objects \ And the Tk::UTF8_String objects are passed to the label widgets. EOL -TkFrame.new($unicodeout_demo){|f| +TkFrame.new(base_frame){|f| pack(:side=>:bottom, :fill=>:x, :pady=>'2m') TkButton.new(f, :text=>'Dismiss', :width=>15, :command=>proc{ @@ -49,7 +51,7 @@ TkFrame.new($unicodeout_demo){|f| }).pack(:side=>:left, :expand=>true) } -wait_msg = TkLabel.new($unicodeout_demo, +wait_msg = TkLabel.new(base_frame, :text=>"Please wait while loading fonts...", :font=>"Helvetica 12 italic").pack @@ -63,8 +65,8 @@ class Unicodeout_SampleFrame < TkFrame # @@font = 'Newspaper 12' # @@font = '{New century schoolbook} 12' - def initialize() - super($unicodeout_demo) + def initialize(base) + super(base) grid_columnconfig(1, :weight=>1) end @@ -79,7 +81,7 @@ class Unicodeout_SampleFrame < TkFrame l.grid_config(:padx, '1m') end end -f = Unicodeout_SampleFrame.new +f = Unicodeout_SampleFrame.new(base_frame) f.pack(:expand=>true, :fill=>:both, :padx=>'2m', :pady=>'1m') # Processing when some characters are missing might take a while, so make diff --git a/ext/tk/sample/demos-en/vscale.rb b/ext/tk/sample/demos-en/vscale.rb index c0170467d5..b05ed12072 100644 --- a/ext/tk/sample/demos-en/vscale.rb +++ b/ext/tk/sample/demos-en/vscale.rb @@ -15,7 +15,9 @@ $vscale_demo = TkToplevel.new {|w| } positionWindow($vscale_demo) -msg = TkLabel.new($vscale_demo) { +base_frame = TkFrame.new($vscale_demo).pack(:fill=>:both, :expand=>true) + +msg = TkLabel.new(base_frame) { font $font wraplength '3.5i' justify 'left' @@ -23,7 +25,7 @@ msg = TkLabel.new($vscale_demo) { } msg.pack('side'=>'top', 'padx'=>'.5c') -TkFrame.new($vscale_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc { @@ -39,7 +41,17 @@ TkFrame.new($vscale_demo) {|frame| }.pack('side'=>'left', 'expand'=>'yes') }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') -TkFrame.new($vscale_demo) {|frame| +def setHeight(w, height) + height = height + 21 + y2 = height - 30 + if y2 < 21 + y2 = 21 + end + w.coords 'poly',15,20,35,20,35,y2,45,y2,25,height,5,y2,15,y2,15,20 + w.coords 'line',15,20,35,20,35,y2,45,y2,25,height,5,y2,15,y2,15,20 +end + +TkFrame.new(base_frame) {|frame| borderwidth 10 canvas = TkCanvas.new(frame) {|c| width 50 @@ -65,13 +77,3 @@ TkFrame.new($vscale_demo) {|frame| }.pack('side'=>'left', 'anchor'=>'ne') scale.set 75 }.pack - -def setHeight(w, height) - height = height + 21 - y2 = height - 30 - if y2 < 21 - y2 = 21 - end - w.coords 'poly',15,20,35,20,35,y2,45,y2,25,height,5,y2,15,y2,15,20 - w.coords 'line',15,20,35,20,35,y2,45,y2,25,height,5,y2,15,y2,15,20 -end diff --git a/ext/tk/sample/demos-en/widget b/ext/tk/sample/demos-en/widget index 4456f8ab5b..dc40f0a95f 100644 --- a/ext/tk/sample/demos-en/widget +++ b/ext/tk/sample/demos-en/widget @@ -14,6 +14,8 @@ require 'tk' ### $DEBUG=1 ########## +$RubyTk_WidgetDemo = true + #---------------------------------------------------------------- # The code below create the main window, consisting of a menu bar # and a text widget that explains how to use the program, plus lists @@ -103,14 +105,22 @@ EOD end # -TkMenubar.new($root, - [[['File', 0], - ['About ... ', proc{aboutBox}, 0, ''], - '---', - ['Quit', proc{exit}, 0, 'Meta-Q'] - ]]).pack('side'=>'top', 'fill'=>'x') +if $tk_major_ver >= 8 + $root.add_menubar([[['File', 0], + ['About ... ', proc{aboutBox}, 0, ''], + '---', + ['Quit', proc{exit}, 0, 'Ctrl-Q'] + ]]) +else + TkMenubar.new($root, + [[['File', 0], + ['About ... ', proc{aboutBox}, 0, ''], + '---', + ['Quit', proc{exit}, 0, 'Ctrl-Q'] + ]]).pack('side'=>'top', 'fill'=>'x') +end $root.bind('F1', proc{aboutBox}) -$root.bind('Meta-q', proc{exit}) +$root.bind('Control-q', proc{exit}) =begin TkFrame.new($root){|frame| @@ -316,6 +326,8 @@ txt.insert('end', "13. A simple user interface for viewing images. (if supported txt.insert('end', " \n ", tag_demospace) txt.insert('end', "14. Labelled frames (if supported)\n", tag_demo, "demo-labelframe") txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "15. The simple Themed Tk widgets (require Tile/Ttk extension)\n", tag_demo, "demo-ttkbut") +txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") txt.insert('end', "Listboxes\n", tag_title) @@ -326,6 +338,10 @@ txt.insert('end', "2. Colors: change the color scheme for the application.\n", " txt.insert('end', " \n ", tag_demospace) txt.insert('end', "3. A collection of famous sayings.\n", tag_demo, "demo-sayings") txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "4. A multi-column list of contries. (require Tile/Ttk extension)\n", tag_demo, "demo-mclist") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "5. A directory browser tree. (require Tile/Ttk extension)\n", tag_demo, "demo-tree") +txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") txt.insert('end', "Entries and Spin-boxes\n", tag_title) @@ -340,7 +356,9 @@ txt.insert('end', txt.insert('end', " \n ", tag_demospace) txt.insert('end', "4. Spin-boxes. (if supported)\n", tag_demo, "demo-spin") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "5. Simple Rolodex-like form.\n", tag_demo, "demo-form") +txt.insert('end', "5. Combo-boxes. (require Tile/Ttk extension)\n", tag_demo, "demo-combo") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "6. Simple Rolodex-like form.\n", tag_demo, "demo-form") txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") @@ -380,31 +398,43 @@ txt.insert('end', "7. A building floor plan. (another way to create canvas items txt.insert('end', " \n ", tag_demospace) txt.insert('end', "8. A simple scrollable canvas.\n", tag_demo, "demo-cscroll") txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "9. A Knight's tour of the chess board. (require Tile/Ttk extension)\n", tag_demo, "demo-knightstour") +txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") -txt.insert('end', "Scales\n", tag_title) +txt.insert('end', "Scales and Progress Bars\n", tag_title) txt.insert('end', " \n ", tag_demospace) txt.insert('end', "1. Vertical scale.\n", tag_demo.id, "demo-vscale") txt.insert('end', " \n ", tag_demospace) txt.insert('end', "2. Horizontal scale.\n", tag_demo.id, "demo-hscale") txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "3. Progress bar. (require Tile/Ttk extension)\n", tag_demo.id, "demo-ttkprogress") +txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") -txt.insert('end', "Paned Windows\n", tag_title) +txt.insert('end', "Paned Windows and Notebooks\n", tag_title) txt.insert('end', " \n ", tag_demospace) txt.insert('end', "1. Horizontal paned window. (if supported)\n", tag_demo.id, "demo-paned1") txt.insert('end', " \n ", tag_demospace) txt.insert('end', "2. Vertical paned window. (if supported)\n", tag_demo.id, "demo-paned2") txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "3. Themed nested panes. (require Tile/Ttk extension)\n", tag_demo.id, "demo-ttkpane") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "4. Notebook widget. (require Tile/Ttk extension)\n", tag_demo.id, "demo-ttknote") +txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") -txt.insert('end', "Menus\n", tag_title) +txt.insert('end', "Menus and Toolbars\n", tag_title) txt.insert('end', " \n ", tag_demospace) txt.insert('end', "1. Menus and cascades.\n", tag_demo, "demo-menu") txt.insert('end', " \n ", tag_demospace) txt.insert('end', "2. Menus and cascades. (if supported)\n", tag_demo, "demo-menu84") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "3. Menubuttons\n", tag_demo, "demo-menubu") +txt.insert('end', "3. Menubuttons.\n", tag_demo, "demo-menubu") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "4. Themed menu buttons. (require Tile/Ttk extension)\n", tag_demo, "demo-ttkmenu") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "5. Themed toolbar. (require Tile/Ttk extension)\n", tag_demo, "demo-toolbar") txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") @@ -412,9 +442,11 @@ txt.insert('end', "Common Dialogs\n", tag_title) txt.insert('end', " \n ", tag_demospace) txt.insert('end', "1. Message boxes.\n", tag_demo, "demo-msgbox") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "2. File selection dialog.\n", tag_demo, "demo-filebox") +txt.insert('end', "2. Message boxes with detail text. (if supported)\n", tag_demo, "demo-msgbox2") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "3. Color picker.\n", tag_demo, "demo-clrpick") +txt.insert('end', "3. File selection dialog.\n", tag_demo, "demo-filebox") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "4. Color picker.\n", tag_demo, "demo-clrpick") txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") @@ -470,7 +502,8 @@ def showVars1(parent, *args) end w = TkToplevel.new(parent) {|w| title "Variable values" - TkLabel.new(w) { + base = TkFrame.new(w).pack(:fill=>:both, :expand=>true) + TkLabel.new(base) { text "Variable values:" width 20 anchor 'center' @@ -492,7 +525,7 @@ def showVars1(parent, *args) .pack('side'=>'left', 'expand'=>'yes', 'fill'=>'x') }.pack('side'=>'top', 'anchor'=>'w', 'fill'=>'x') } - TkButton.new(w) { + TkButton.new(base) { text "OK" command proc{w.destroy} }.pack('side'=>'bottom', 'pady'=>2) @@ -507,10 +540,12 @@ def showVars2(parent, *args) rescue end end - $showVarsWin[parent.path] = TkToplevel.new(parent) {|w| + $showVarsWin[parent.path] = TkToplevel.new(parent) {|top| title "Variable values" - TkLabelFrame.new(w, :text=>"Variable values:", + base = TkFrame.new(top).pack(:fill=>:both, :expand=>true) + + TkLabelFrame.new(base, :text=>"Variable values:", :font=>{:family=>'Helvetica', :size=>14}){|f| args.each{|vnam,vbody| TkGrid(TkLabel.new(f, :text=>"#{vnam}: ", :anchor=>'w'), @@ -522,15 +557,15 @@ def showVars2(parent, *args) f.grid_columnconfig(1, :weight=>1) f.grid_rowconfig(100, :weight=>1) } - TkButton.new(w, :text=>"OK", :width=>8, :default=>:active, - :command=>proc{w.destroy}){|b| - w.bind('Return', proc{b.invoke}) - w.bind('Escape', proc{b.invoke}) + TkButton.new(base, :text=>"OK", :width=>8, :default=>:active, + :command=>proc{top.destroy}){|b| + top.bind('Return', proc{b.invoke}) + top.bind('Escape', proc{b.invoke}) b.grid(:sticky=>'e', :padx=>4, :pady=>[6, 4]) } - w.grid_columnconfig(0, :weight=>1) - w.grid_rowconfig(0, :weight=>1) + base.grid_columnconfig(0, :weight=>1) + base.grid_rowconfig(0, :weight=>1) } end @@ -624,10 +659,27 @@ def _null_binding end private :_null_binding -def eval_samplecode(code) +def eval_samplecode(code, file=nil) #eval(code) #_null_binding.pseudo_toplevel_eval{ eval(code) } - Thread.new{ _null_binding.pseudo_toplevel_eval{ eval(code) } } + #Thread.new{ _null_binding.pseudo_toplevel_eval{ eval(code) } } + Thread.new{ + _null_binding.pseudo_toplevel_eval{ + begin + if file + eval(code, binding, "(eval:#{file})") + else + eval(code) + end + rescue Exception=>e + #p e + TkBgError.show(e.class.inspect + ': ' + e.message + "\n" + + "\n---< backtrace of Ruby side >-----\n" + + e.backtrace.join("\n") + + "\n---< backtrace of Tk side >-------") + end + } + } Tk.update end @@ -647,7 +699,7 @@ def invoke(txt, idx) Tk.update # eval(IO.readlines("#{[$demo_dir, tag[5..-1]].join(File::Separator)}.rb").join, _null_binding) # Tk.update - eval_samplecode(IO.readlines("#{[$demo_dir, tag[5..-1]].join(File::Separator)}.rb").join) + eval_samplecode(IO.readlines("#{[$demo_dir, tag[5..-1]].join(File::Separator)}.rb").join, tag[5..-1] + '.rb') txt.cursor(cursor) $tag_visited.add("#{idx} linestart +1 chars", "#{idx} lineend +1 chars") @@ -704,20 +756,26 @@ def showCode1(demo) if $code_window == nil || TkWinfo.exist?($code_window) == false $code_window = TkToplevel.new(nil) f = TkFrame.new($code_window) + TkButton.new(f) { text "Dismiss" command proc{ $code_window.destroy $code_window = nil } - }.pack('side'=>'left', 'expand'=>'yes', 'pady'=>2) + }.pack('side'=>'right', 'expand'=>'false', 'pady'=>2, 'padx'=>25) TkButton.new(f) { text "Rerun Demo" # command proc{eval($code_text.get('1.0','end'), _null_binding)} - command proc{eval_samplecode($code_text.get('1.0','end'))} - }.pack('side'=>'left', 'expand'=>'yes', 'pady'=>2) -# f.pack('side'=>'bottom', 'expand'=>'yes', 'fill'=>'x') - f.pack('side'=>'bottom', 'fill'=>'x') + command proc{eval_samplecode($code_text.get('1.0','end'), '')} + }.pack('side'=>'right', 'expand'=>'false', 'pady'=>2) + + TkLabel.new(f,'text'=>'line:').pack('side'=>'left') + linenum =TkLabel.new(f,'text'=>'').pack('side'=>'left') + TkLabel.new(f,'text'=>' pos:').pack('side'=>'left') + posnum =TkLabel.new(f,'text'=>'').pack('side'=>'left') + + f.pack('side'=>'bottom', 'expand'=>'true', 'fill'=>'x') if $tk_version =~ /^4\.[01]/ s = TkScrollbar.new($code_window, 'orient'=>'vertical') @@ -776,6 +834,24 @@ def showCode1(demo) #$code_mark = TkTextMark.new($code_text, '1.0') #$code_text.set_insert('1.0') TkTextMarkInsert.new($code_text,'1.0') + + btag = TkBindTag.new + + set_linenum = proc{|w| + line, pos = w.index('insert').split('.') + linenum.text = line + posnum.text = pos + } + + btag.bind('Key', set_linenum, '%W') + btag.bind('Button', set_linenum, '%W') + + btags = $code_text.bindtags + btags.insert(btags.index($code_text.class) + 1, btag) + $code_text.bindtags = btags + + set_linenum.call($code_text) + fid.close end @@ -796,7 +872,13 @@ def showCode2(demo) tf.grid_columnconfigure(0, :weight=>1) bf = TkFrame.new($code_window) - + + lf = TkFrame.new(bf) + TkLabel.new(lf, :text=>'line:').pack(:side=>:left) + linenum =TkLabel.new(lf, :text=>'').pack(:side=>:left) + TkLabel.new(lf, :text=>' pos:').pack(:side=>:left) + posnum =TkLabel.new(lf, :text=>'').pack(:side=>:left) + b_dis = TkButton.new(bf, :text=>'Dismiss', :default=>:active, :command=>proc{ $code_window.destroy @@ -809,12 +891,12 @@ def showCode2(demo) b_run = TkButton.new(bf, :text=>'Rerun Demo', :command=>proc{ # eval($code_text.get('1.0','end'), _null_binding) - eval_samplecode($code_text.get('1.0','end')) + eval_samplecode($code_text.get('1.0','end'), '') }, :image=>$image['refresh'], :compound=>:left) - TkGrid('x', b_run, b_prn, b_dis, :padx=>4, :pady=>[6,4]) - bf.grid_columnconfigure(0, :weight=>1) + TkGrid(lf, 'x', b_run, b_prn, b_dis, :padx=>4, :pady=>[6,4]) + bf.grid_columnconfigure(1, :weight=>1) TkGrid(tf, :sticky=>'news') TkGrid(bf, :sticky=>'ew') @@ -838,6 +920,24 @@ def showCode2(demo) $code_text.delete('1.0', 'end') $code_text.insert('1.0', fid.read) TkTextMarkInsert.new($code_text,'1.0') + + btag = TkBindTag.new + + set_linenum = proc{|w| + line, pos = w.index('insert').split('.') + linenum.text = line + posnum.text = pos + } + + btag.bind('Key', set_linenum, '%W') + btag.bind('Button', set_linenum, '%W') + + btags = $code_text.bindtags + btags.insert(btags.index($code_text.class) + 1, btag) + $code_text.bindtags = btags + + set_linenum.call($code_text) + fid.close end @@ -931,12 +1031,13 @@ end # def aboutBox Tk.messageBox('icon'=>'info', 'type'=>'ok', 'title'=>'About Widget Demo', - 'message'=>"Ruby/Tk widget demonstration Ver.1.6.4-en\n\n" + + 'message'=>"Ruby/Tk widget demonstration Ver.1.7.0-en\n\n" + "based on demos of Tk8.1 -- 8.5 " + - "( Copyright:: " + + "( Copyright of Tcl/Tk demos:: " + "(c) 1996-1997 Sun Microsystems, Inc. / " + "(c) 1997-2000 Ajuba Solutions, Inc. / " + - "(c) 2001-2003 Donal K. Fellows )\n\n" + + "(c) 2001-2007 Donal K. Fellows / " + + "(c) 2002-2007 Daniel A. Steffen )\n\n" + "Your Ruby & Tk Version ::\n" + "Ruby#{RUBY_VERSION}(#{RUBY_RELEASE_DATE})[#{RUBY_PLATFORM}] / Tk#{$tk_patchlevel}#{(Tk::JAPANIZED_TK)? '-jp': ''}\n\n" + "Ruby/Tk release date :: tcltklib #{TclTkLib::RELEASE_DATE}; tk #{Tk::RELEASE_DATE}") @@ -958,7 +1059,7 @@ ARGV.each{|cmd| end #eval(IO.readlines("#{[$demo_dir, cmd].join(File::Separator)}.rb").join, # _null_binding) - eval_samplecode(IO.readlines("#{[$demo_dir, cmd].join(File::Separator)}.rb").join) + eval_samplecode(IO.readlines("#{[$demo_dir, cmd].join(File::Separator)}.rb").join, cmd + '.rb') } if no_launcher $root.withdraw # hide root window diff --git a/ext/tk/sample/demos-jp/anilabel.rb b/ext/tk/sample/demos-jp/anilabel.rb index c6e5c7385b..aee57f9f6a 100644 --- a/ext/tk/sample/demos-jp/anilabel.rb +++ b/ext/tk/sample/demos-jp/anilabel.rb @@ -17,8 +17,10 @@ $anilabel_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($anilabel_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -msg = TkLabel.new($anilabel_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -27,7 +29,7 @@ msg = TkLabel.new($anilabel_demo) { msg.pack('side'=>'top') # frame 生成 -TkFrame.new($anilabel_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -46,8 +48,8 @@ TkFrame.new($anilabel_demo) {|frame| }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # label demo 用フレーム生成 -f_left = TkLabelFrame.new($anilabel_demo, :text=>'Scrolling Texts') -f_right = TkLabelFrame.new($anilabel_demo, :text=>'GIF Image') +f_left = TkLabelFrame.new(base_frame, :text=>'Scrolling Texts') +f_right = TkLabelFrame.new(base_frame, :text=>'GIF Image') Tk.pack(f_left, f_right, 'side'=>'left', 'expand'=>'yes', 'fill'=>'both', 'padx'=>10, 'pady'=>10) diff --git a/ext/tk/sample/demos-jp/aniwave.rb b/ext/tk/sample/demos-jp/aniwave.rb index ec307dbc0c..8fa14f65fe 100644 --- a/ext/tk/sample/demos-jp/aniwave.rb +++ b/ext/tk/sample/demos-jp/aniwave.rb @@ -17,8 +17,10 @@ $aniwave_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($aniwave_demo).pack(:fill=>:both, :expand=>true) + # create label -msg = TkLabel.new($aniwave_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -27,7 +29,7 @@ msg = TkLabel.new($aniwave_demo) { msg.pack('side'=>'top') # create frame -TkFrame.new($aniwave_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -115,4 +117,4 @@ class AnimatedWaveDemo end # Start the animation processing -AnimatedWaveDemo.new($aniwave_demo, :left).move +AnimatedWaveDemo.new(base_frame, :left).move diff --git a/ext/tk/sample/demos-jp/arrow.rb b/ext/tk/sample/demos-jp/arrow.rb index b2c1067027..3c49e67b09 100644 --- a/ext/tk/sample/demos-jp/arrow.rb +++ b/ext/tk/sample/demos-jp/arrow.rb @@ -104,14 +104,16 @@ $arrow_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($arrow_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -TkLabel.new($arrow_demo, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', +TkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', 'text'=>"この widget で、キャンバスで使われるラインについて様々な幅や矢印の頭の形を試してみることができます。線の幅や矢印の形を変えるには、拡大された矢印についている 3つの四角をドラッグしてください。右側の矢印は普通の大きさでのサンプルを示しています。下のテキストはラインアイテムに対する設定オプションです。"){ pack('side'=>'top') } # frame 生成 -$arrow_buttons = TkFrame.new($arrow_demo) {|frame| +$arrow_buttons = TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -130,7 +132,7 @@ $arrow_buttons = TkFrame.new($arrow_demo) {|frame| $arrow_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # canvas 設定 -$arrow_canvas = TkCanvas.new($arrow_demo, 'width'=>500, 'height'=>350, +$arrow_canvas = TkCanvas.new(base_frame, 'width'=>500, 'height'=>350, 'relief'=>'sunken', 'borderwidth'=>2) $arrow_canvas.pack('expand'=>'yes', 'fill'=>'both') diff --git a/ext/tk/sample/demos-jp/bind.rb b/ext/tk/sample/demos-jp/bind.rb index 8985463b15..a1bcfdd2e7 100644 --- a/ext/tk/sample/demos-jp/bind.rb +++ b/ext/tk/sample/demos-jp/bind.rb @@ -16,8 +16,10 @@ $bind_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($bind_demo).pack(:fill=>:both, :expand=>true) + # frame 生成 -TkFrame.new($bind_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -41,14 +43,14 @@ def tag_binding_for_bind_demo(tag, enter_style, leave_style) end # text 生成 -txt = TkText.new($bind_demo){|t| +txt = TkText.new(base_frame){|t| # 生成 setgrid 'true' #width 60 #height 24 font $font wrap 'word' - TkScrollbar.new($bind_demo) {|s| + TkScrollbar.new(base_frame) {|s| pack('side'=>'right', 'fill'=>'y') command proc{|*args| t.yview(*args)} t.yscrollcommand proc{|first,last| s.set first,last} @@ -92,32 +94,32 @@ txt = TkText.new($bind_demo){|t| } d1.bind('1', proc{ - eval_samplecode(`cat #{[$demo_dir,'items.rb'].join(File::Separator)}`) + eval_samplecode(`cat #{[$demo_dir,'items.rb'].join(File::Separator)}`, 'items.rb') }) d2.bind('1', proc{ - eval_samplecode(`cat #{[$demo_dir,'plot.rb'].join(File::Separator)}`) + eval_samplecode(`cat #{[$demo_dir,'plot.rb'].join(File::Separator)}`, 'plot.rb') }) d3.bind('1', proc{ - eval_samplecode(`cat #{[$demo_dir,'ctext.rb'].join(File::Separator)}`) + eval_samplecode(`cat #{[$demo_dir,'ctext.rb'].join(File::Separator)}`, 'ctext.rb') }) d4.bind('1', proc{ - eval_samplecode(`cat #{[$demo_dir,'arrow.rb'].join(File::Separator)}`) + eval_samplecode(`cat #{[$demo_dir,'arrow.rb'].join(File::Separator)}`, 'arrow.rb') }) d5.bind('1', proc{ - eval_samplecode(`cat #{[$demo_dir,'ruler.rb'].join(File::Separator)}`) + eval_samplecode(`cat #{[$demo_dir,'ruler.rb'].join(File::Separator)}`, 'ruler.rb') }) d6.bind('1', proc{ - eval_samplecode(`cat #{[$demo_dir,'cscroll.rb'].join(File::Separator)}`) + eval_samplecode(`cat #{[$demo_dir,'cscroll.rb'].join(File::Separator)}`, 'cscroll.rb') }) TkTextMarkInsert.new(t, '0.0') configure('state','disabled') } -txt.width 60 +txt.width 60 txt.height 24 diff --git a/ext/tk/sample/demos-jp/bitmap.rb b/ext/tk/sample/demos-jp/bitmap.rb index 4594892c81..b6b0e54bbe 100644 --- a/ext/tk/sample/demos-jp/bitmap.rb +++ b/ext/tk/sample/demos-jp/bitmap.rb @@ -19,7 +19,7 @@ def bitmapRow(w,*args) TkFrame.new(row){|base| pack('side'=>'left', 'fill'=>'both', 'pady'=>'.25c', 'padx'=>'.25c') TkLabel.new(base, 'text'=>bitmap, 'width'=>9).pack('side'=>'bottom') - TkLabel.new(base, 'bitmap'=>bitmap).pack('side'=>'bottom') + Tk::Label.new(base, 'bitmap'=>bitmap).pack('side'=>'bottom') } end } @@ -38,14 +38,16 @@ $bitmap_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($bitmap_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -TkLabel.new($bitmap_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left', +TkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left', 'text'=>"このウィンドウには、Tk に組み込まれたすべてのビットマップが、それらの名前と共に表示されています。Tcl のスクリプト中では、それぞれの名前を用いて参照します。"){ pack('side'=>'top') } # frame 生成 -$bitmap_buttons = TkFrame.new($bitmap_demo) {|frame| +$bitmap_buttons = TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -64,7 +66,7 @@ $bitmap_buttons = TkFrame.new($bitmap_demo) {|frame| $bitmap_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # frame 設定 -TkFrame.new($bitmap_demo){|f| +TkFrame.new(base_frame){|f| bitmapRow(f,'error','gray25','gray50','hourglass') bitmapRow(f,'info','question','questhead','warning') pack('side'=>'top', 'expand'=>'yes', 'fill'=>'both') diff --git a/ext/tk/sample/demos-jp/button.rb b/ext/tk/sample/demos-jp/button.rb index 7e9457f5b4..18e42008c9 100644 --- a/ext/tk/sample/demos-jp/button.rb +++ b/ext/tk/sample/demos-jp/button.rb @@ -2,6 +2,7 @@ # # button widget demo (called by 'widget') # +# # toplevel widget が存在すれば削除する if defined?($button_demo) && $button_demo @@ -26,7 +27,7 @@ msg = TkLabel.new($button_demo) { msg.pack('side'=>'top') # frame 生成 -$button_buttons = TkFrame.new($button_demo) {|frame| +$button_buttons = Tk::Frame.new($button_demo) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' diff --git a/ext/tk/sample/demos-jp/check.rb b/ext/tk/sample/demos-jp/check.rb index 7545df80fa..b953e7f623 100644 --- a/ext/tk/sample/demos-jp/check.rb +++ b/ext/tk/sample/demos-jp/check.rb @@ -16,8 +16,10 @@ $check_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($check_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -msg = TkLabel.new($check_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -31,7 +33,7 @@ brakes = TkVariable.new(0) sober = TkVariable.new(0) # frame 生成 -TkFrame.new($check_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -52,7 +54,7 @@ TkFrame.new($check_demo) {|frame| TkButton.new(frame) { text '変数参照' command proc{ - showVars($check_demo, + showVars(base_frame, ['wipers', wipers], ['brakes', brakes], ['sober', sober]) } }.pack('side'=>'left', 'expand'=>'yes') @@ -61,8 +63,8 @@ TkFrame.new($check_demo) {|frame| # checkbutton 生成 -[ TkCheckButton.new($check_demo, 'text'=>'ワイパー OK', 'variable'=>wipers), - TkCheckButton.new($check_demo, 'text'=>'ブレーキ OK', 'variable'=>brakes), - TkCheckButton.new($check_demo, 'text'=>'運転手 素面', 'variable'=>sober) +[ TkCheckButton.new(base_frame, 'text'=>'ワイパー OK', 'variable'=>wipers), + TkCheckButton.new(base_frame, 'text'=>'ブレーキ OK', 'variable'=>brakes), + TkCheckButton.new(base_frame, 'text'=>'運転手 素面', 'variable'=>sober) ].each{|w| w.relief('flat'); w.pack('side'=>'top', 'pady'=>2, 'anchor'=>'w')} diff --git a/ext/tk/sample/demos-jp/check2.rb b/ext/tk/sample/demos-jp/check2.rb index 90c6dd736f..7f7cb9e932 100644 --- a/ext/tk/sample/demos-jp/check2.rb +++ b/ext/tk/sample/demos-jp/check2.rb @@ -16,8 +16,10 @@ $check2_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($check2_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -msg = TkLabel.new($check2_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -32,7 +34,7 @@ brakes = TkVariable.new(0) sober = TkVariable.new(0) # frame 生成 -TkFrame.new($check2_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkGrid(TkFrame.new(frame, :height=>2, :relief=>:sunken, :bd=>2), :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) TkGrid('x', @@ -60,15 +62,15 @@ TkFrame.new($check2_demo) {|frame| # checkbutton 生成 -TkCheckButton.new($check2_demo, :text=>'安全性検査', :variable=>safety, +TkCheckButton.new(base_frame, :text=>'安全性検査', :variable=>safety, :relief=>:flat, :onvalue=>'all', :offvalue=>'none', :tristatevalue=>'partial'){ pack('side'=>'top', 'pady'=>2, 'anchor'=>'w') } -[ TkCheckButton.new($check2_demo, 'text'=>'ワイパー OK', 'variable'=>wipers), - TkCheckButton.new($check2_demo, 'text'=>'ブレーキ OK', 'variable'=>brakes), - TkCheckButton.new($check2_demo, 'text'=>'運転手 素面', 'variable'=>sober) +[ TkCheckButton.new(base_frame, 'text'=>'ワイパー OK', 'variable'=>wipers), + TkCheckButton.new(base_frame, 'text'=>'ブレーキ OK', 'variable'=>brakes), + TkCheckButton.new(base_frame, 'text'=>'運転手 素面', 'variable'=>sober) ].each{|w| w.relief('flat') w.pack('side'=>'top', 'padx'=>15, 'pady'=>2, 'anchor'=>'w') diff --git a/ext/tk/sample/demos-jp/clrpick.rb b/ext/tk/sample/demos-jp/clrpick.rb index d81ecebc83..ce6b99ab94 100644 --- a/ext/tk/sample/demos-jp/clrpick.rb +++ b/ext/tk/sample/demos-jp/clrpick.rb @@ -2,6 +2,8 @@ # # widget demo prompts the user to select a color (called by 'widget') # +# Note: don't support ttk_wrapper. work with standard widgets only. +# # toplevel widget が存在すれば削除する if defined?($clrpick_demo) && $clrpick_demo @@ -17,12 +19,15 @@ $clrpick_demo = TkToplevel.new {|w| } # label 生成 -TkLabel.new($clrpick_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left', +#TkLabel.new($clrpick_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left', +Tk::Label.new($clrpick_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left', 'text'=>"以下のボタンを押して、このウィンドウ上にあるウィジェットの前景色と背景色を選択して下さい。").pack('side'=>'top') # frame 生成 -TkFrame.new($clrpick_demo) {|frame| - TkButton.new(frame) { +# TkFrame.new($clrpick_demo) {|frame| +Tk::Frame.new($clrpick_demo) {|frame| + # TkButton.new(frame) { + Tk::Button.new(frame) { #text '了解' text '閉じる' command proc{ @@ -32,20 +37,23 @@ TkFrame.new($clrpick_demo) {|frame| } }.pack('side'=>'left', 'expand'=>'yes') - TkButton.new(frame) { + # TkButton.new(frame) { + Tk::Button.new(frame) { text 'コード参照' command proc{showCode 'clrpick'} }.pack('side'=>'left', 'expand'=>'yes') }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # button 生成 -TkButton.new($clrpick_demo, 'text'=>'背景色を設定 ...') {|b| +# TkButton.new($clrpick_demo, 'text'=>'背景色を設定 ...') {|b| +Tk::Button.new($clrpick_demo, 'text'=>'背景色を設定 ...') {|b| command(proc{setColor $clrpick_demo, b, 'background', ['background', 'highlightbackground']}) pack('side'=>'top', 'anchor'=>'c', 'pady'=>'2m') } -TkButton.new($clrpick_demo, 'text'=>'前景色を設定 ...') {|b| +# TkButton.new($clrpick_demo, 'text'=>'前景色を設定 ...') {|b| +Tk::Button.new($clrpick_demo, 'text'=>'前景色を設定 ...') {|b| command(proc{setColor $clrpick_demo, b, 'foreground', ['foreground']}) pack('side'=>'top', 'anchor'=>'c', 'pady'=>'2m') } diff --git a/ext/tk/sample/demos-jp/colors.rb b/ext/tk/sample/demos-jp/colors.rb index 68b40e69f0..91817a947b 100644 --- a/ext/tk/sample/demos-jp/colors.rb +++ b/ext/tk/sample/demos-jp/colors.rb @@ -16,8 +16,10 @@ $colors_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($colors_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -msg = TkLabel.new($colors_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -26,7 +28,7 @@ msg = TkLabel.new($colors_demo) { msg.pack('side'=>'top') # frame 生成 -TkFrame.new($colors_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -46,7 +48,7 @@ TkFrame.new($colors_demo) {|frame| # frame 生成 colors_lbox = nil -TkFrame.new($colors_demo, 'borderwidth'=>10) {|w| +TkFrame.new(base_frame, 'borderwidth'=>10) {|w| s = TkScrollbar.new(w) colors_lbox = TkListbox.new(w) { setgrid 1 @@ -59,7 +61,15 @@ TkFrame.new($colors_demo, 'borderwidth'=>10) {|w| colors_lbox.pack('side'=>'left', 'expand'=>1, 'fill'=>'both') }.pack('side'=>'top', 'expand'=>'yes', 'fill'=>'y') -colors_lbox.bind('Double-1', proc{TkPalette.setPalette TkSelection.get}) +#colors_lbox.bind('Double-1', proc{TkPalette.setPalette TkSelection.get}) +colors_lbox.bind('Double-1', proc{ + begin + TkPalette.setPalette TkSelection.get + rescue => e + p e + Tk.tk_call_without_enc('destroy', '.___tk_set_palette') + end + }) ins_data = [ 'gray60','gray70','gray80','gray85','gray90','gray95', diff --git a/ext/tk/sample/demos-jp/combo.rb b/ext/tk/sample/demos-jp/combo.rb new file mode 100644 index 0000000000..da00d712ba --- /dev/null +++ b/ext/tk/sample/demos-jp/combo.rb @@ -0,0 +1,98 @@ +# -*- coding: euc-jp -*- +# +# combo.rb -- +# +# This demonstration script creates several combobox widgets. +# +# based on "Id: combo.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp" + +if defined?($combo_demo) && $combo_demo + $combo_demo.destroy + $combo_demo = nil +end + +$combo_demo = TkToplevel.new {|w| + title("Combobox Demonstration") + iconname("combo") + positionWindow(w) +} + +base_frame = TkFrame.new($combo_demo).pack(:fill=>:both, :expand=>true) + +Ttk::Label.new(base_frame, :font=>$font, :wraplength=>'5i', :justify=>:left, + :text=><:top, :fill=>:x) +以下では3種類のコンボボックスが表示されています.\ +最初のものは,エントリウィジェットと同じ様に,\ +ポイントしたり,クリックしたり,タイプしたりすることができます.\ +また,Returnキーを入力すれば現在の値がリストに追加され,\ +ドロップダウンリストから選択することができるようになります.\ +↓(下向き矢印)キーを押して表示されたリストから\ +矢印キーで他の候補を選んでReturnキーを押せば,値を選択できます.\ +2番目のコンボボックスは特定の値に固定されており,一切変更できません.\ +3番目のものはオーストラリアの都市のドロップダウンリストから\ +選択することだけが可能となっています. +EOL + +## variables +firstValue = TkVariable.new +secondValue = TkVariable.new +ozCity = TkVariable.new + +## See Code / Dismiss buttons +Ttk::Frame.new(base_frame) {|frame| + sep = Ttk::Separator.new(frame) + Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + Ttk::Button.new(frame, :text=>'変数参照', + :image=>$image['view'], :compound=>:left, + :command=>proc{ + showVars(base_frame, + ['firstVariable', firstValue], + ['secondVariable', secondValue], + ['ozCity', ozCity]) + }), + Ttk::Button.new(frame, :text=>'コード参照', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'combo'}), + Ttk::Button.new(frame, :text=>'閉じる', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + $combo_demo.destroy + $combo_demo = nil + }), + :padx=>4, :pady=>4) + grid_columnconfigure(0, :weight=>1) + pack(:side=>:bottom, :fill=>:x) +} + +frame = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true) + +australianCities = [ + 'キャンベラ', 'シドニー', 'メルボルン', 'パース', 'アデレード', + 'ブリスベーン', 'ホバート', 'ダーウィン', 'アリス スプリングス' +] + + +secondValue.value = '変更不可' +ozCity.value = 'シドニー' + +Tk.pack(Ttk::Labelframe.new(frame, :text=>'Fully Editable'){|f| + Ttk::Combobox.new(f, :textvariable=>firstValue){|b| + b.bind('Return', '%W'){|w| + w.values <<= w.value unless w.values.include?(w.value) + } + }.pack(:pady=>5, :padx=>10) + }, + + Ttk::LabelFrame.new(frame, :text=>'Disabled'){|f| + Ttk::Combobox.new(f, :textvariable=>secondValue, :state=>:disabled) . + pack(:pady=>5, :padx=>10) + }, + + Ttk::LabelFrame.new(frame, :text=>'Defined List Only'){|f| + Ttk::Combobox.new(f, :textvariable=>ozCity, :state=>:readonly, + :values=>australianCities) . + pack(:pady=>5, :padx=>10) + }, + + :side=>:top, :pady=>5, :padx=>10) diff --git a/ext/tk/sample/demos-jp/cscroll.rb b/ext/tk/sample/demos-jp/cscroll.rb index 0be26133c5..845952679a 100644 --- a/ext/tk/sample/demos-jp/cscroll.rb +++ b/ext/tk/sample/demos-jp/cscroll.rb @@ -16,14 +16,16 @@ $cscroll_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($cscroll_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -TkLabel.new($cscroll_demo, 'font'=>$font, 'wraplength'=>'4i', +TkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'4i', 'justify'=>'left', 'text'=>"このウィンドウにはスクロールバーやマウスのボタン2 でスクロールできるキャンバス widget が表示されています。四角の上でボタン1 をクリックすると、そのインデックスが標準出力に出力されます。"){ pack('side'=>'top') } # frame 生成 -$cscroll_buttons = TkFrame.new($cscroll_demo) {|frame| +$cscroll_buttons = TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -43,7 +45,7 @@ $cscroll_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # frame 設定 unless $tk_version =~ /^4\.[01]/ - $cscroll_grid = TkFrame.new($cscroll_demo) { + $cscroll_grid = TkFrame.new(base_frame) { pack('expand'=>'yes', 'fill'=>'both', 'padx'=>1, 'pady'=>1) } TkGrid.rowconfigure($cscroll_grid, 0, 'weight'=>1, 'minsize'=>0) @@ -51,7 +53,7 @@ unless $tk_version =~ /^4\.[01]/ end # canvas 設定 -$cscroll_canvas = TkCanvas.new($cscroll_demo, +$cscroll_canvas = TkCanvas.new(base_frame, 'relief'=>'sunken', 'borderwidth'=>2, 'scrollregion'=>['-11c', '-11c', '50c', '20c'] ) {|c| @@ -62,7 +64,7 @@ $cscroll_canvas = TkCanvas.new($cscroll_demo, 'rowspan'=>1, 'columnspan'=>1, 'sticky'=>'news') end - TkScrollbar.new($cscroll_demo, 'command'=>proc{|*args| c.yview(*args)}) {|vs| + TkScrollbar.new(base_frame, 'command'=>proc{|*args| c.yview(*args)}) {|vs| c.yscrollcommand(proc{|first,last| vs.set first,last}) if $tk_version =~ /^4\.[01]/ pack('side'=>'right', 'fill'=>'y') @@ -72,7 +74,7 @@ $cscroll_canvas = TkCanvas.new($cscroll_demo, end } - TkScrollbar.new($cscroll_demo, 'orient'=>'horiz', + TkScrollbar.new(base_frame, 'orient'=>'horiz', 'command'=>proc{|*args| c.xview(*args)}) {|hs| c.xscrollcommand(proc{|first,last| hs.set first,last}) if $tk_version =~ /^4\.[01]/ diff --git a/ext/tk/sample/demos-jp/ctext.rb b/ext/tk/sample/demos-jp/ctext.rb index f5daf7ca05..05ca732cfd 100644 --- a/ext/tk/sample/demos-jp/ctext.rb +++ b/ext/tk/sample/demos-jp/ctext.rb @@ -16,8 +16,10 @@ $ctext_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($ctext_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -TkLabel.new($ctext_demo, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', +TkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', 'text'=>"このウィンドウにはキャンバスwidgetのテキスト機能をデモするためのテキスト文字列が表示されています。マウスを四角の中に持っていき、クリックすると位置ぎめ用の点からの相対位置を変えたり、行揃えを変えたりすることができます。また以下のような編集のための簡単なバインディングをサポートしています。 1. マウスを持っていき、クリックし、入力できます。 @@ -29,7 +31,7 @@ TkLabel.new($ctext_demo, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', } # frame 生成 -$ctext_buttons = TkFrame.new($ctext_demo) {|frame| +$ctext_buttons = TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -48,7 +50,7 @@ $ctext_buttons = TkFrame.new($ctext_demo) {|frame| $ctext_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # canvas 生成 -$ctext_canvas = TkCanvas.new($ctext_demo, 'relief'=>'flat', +$ctext_canvas = TkCanvas.new(base_frame, 'relief'=>'flat', 'borderwidth'=>0, 'width'=>500, 'height'=>350) $ctext_canvas.pack('side'=>'top', 'expand'=>'yes', 'fill'=>'both') diff --git a/ext/tk/sample/demos-jp/entry1.rb b/ext/tk/sample/demos-jp/entry1.rb index d794282284..2be29c18d3 100644 --- a/ext/tk/sample/demos-jp/entry1.rb +++ b/ext/tk/sample/demos-jp/entry1.rb @@ -16,8 +16,10 @@ $entry1_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($entry1_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -msg = TkLabel.new($entry1_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '5i' justify 'left' @@ -26,7 +28,7 @@ msg = TkLabel.new($entry1_demo) { msg.pack('side'=>'top') # frame 生成 -TkFrame.new($entry1_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -44,9 +46,9 @@ TkFrame.new($entry1_demo) {|frame| }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # entry 生成 -e1 = TkEntry.new($entry1_demo, 'relief'=>'sunken') -e2 = TkEntry.new($entry1_demo, 'relief'=>'sunken') -e3 = TkEntry.new($entry1_demo, 'relief'=>'sunken') +e1 = TkEntry.new(base_frame, 'relief'=>'sunken') +e2 = TkEntry.new(base_frame, 'relief'=>'sunken') +e3 = TkEntry.new(base_frame, 'relief'=>'sunken') [e1,e2,e3].each{|w| w.pack('side'=>'top', 'padx'=>10, 'pady'=>5, 'fill'=>'x')} # 初期値挿入 diff --git a/ext/tk/sample/demos-jp/entry2.rb b/ext/tk/sample/demos-jp/entry2.rb index 528ad6dec4..2675b5d324 100644 --- a/ext/tk/sample/demos-jp/entry2.rb +++ b/ext/tk/sample/demos-jp/entry2.rb @@ -16,8 +16,10 @@ $entry2_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($entry2_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -msg = TkLabel.new($entry2_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '5i' justify 'left' @@ -26,7 +28,7 @@ msg = TkLabel.new($entry2_demo) { msg.pack('side'=>'top') # frame 生成 -TkFrame.new($entry2_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -44,7 +46,7 @@ TkFrame.new($entry2_demo) {|frame| }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # frame 生成 -TkFrame.new($entry2_demo, 'borderwidth'=>10) {|w| +TkFrame.new(base_frame, 'borderwidth'=>10) {|w| # entry 1 s1 = TkScrollbar.new(w, 'relief'=>'sunken', 'orient'=>'horiz') e1 = TkEntry.new(w, 'relief'=>'sunken') { diff --git a/ext/tk/sample/demos-jp/entry3.rb b/ext/tk/sample/demos-jp/entry3.rb index 46426af6ae..6b9cd4cf37 100644 --- a/ext/tk/sample/demos-jp/entry3.rb +++ b/ext/tk/sample/demos-jp/entry3.rb @@ -18,7 +18,9 @@ $entry3_demo = TkToplevel.new {|w| positionWindow(w) } -TkLabel.new($entry3_demo, +base_frame = TkFrame.new($entry3_demo).pack(:fill=>:both, :expand=>true) + +TkLabel.new(base_frame, :font=>$font, :wraplength=>'5i', :justify=>:left, :text=><:top) 以下には4種類のエントリボックスが表示されています.各エントリボックスは,\ @@ -39,7 +41,7 @@ TkLabel.new($entry3_demo, 入力された文字はアスタリスク記号に置き換えて表示されます. EOL -TkFrame.new($entry3_demo){|f| +TkFrame.new(base_frame){|f| pack(:side=>:bottom, :fill=>:x, :pady=>'2m') TkButton.new(f, :text=>'閉じる', :width=>15, :command=>proc{ @@ -65,23 +67,41 @@ TkFrame.new($entry3_demo){|f| # count - Counter to control the number of times flashed def focusAndFlash(widget, fg, bg, count=5) return if count <= 0 - TkTimer.new(100, count, - proc{widget.configure(:foreground=>bg, :background=>fg)}, - proc{widget.configure(:foreground=>fg, :background=>bg)} - ).start + if fg && !fg.empty? && bg && !bg.empty? + TkTimer.new(200, count, + proc{widget.configure(:foreground=>bg, :background=>fg)}, + proc{widget.configure(:foreground=>fg, :background=>bg)} + ).start + else + # TkTimer.new(150, 3){Tk.bell}.start + Tk.bell + TkTimer.new(200, count, + proc{widget.configure(:foreground=>'white', + :background=>'black')}, + proc{widget.configure(:foreground=>'black', + :background=>'white')} + ).at_end{begin + widget.configure(:foreground=>fg, + :background=>bg) + rescue + # ignore + end}.start + end widget.focus(true) end -l1 = TkLabelFrame.new($entry3_demo, :text=>"整数エントリ") +l1 = TkLabelFrame.new(base_frame, :text=>"整数エントリ") TkEntry.new(l1, :validate=>:focus, :vcmd=>[ proc{|s| s == '' || /^[+-]?\d+$/ =~ s }, '%P' ]) {|e| - invalidcommand [proc{|w| focusAndFlash(w, e.fg, e.bg)}, '%W'] + fg = e.foreground + bg = e.background + invalidcommand [proc{|w| focusAndFlash(w, fg, bg)}, '%W'] pack(:fill=>:x, :expand=>true, :padx=>'1m', :pady=>'1m') } -l2 = TkLabelFrame.new($entry3_demo, :text=>"長さ制約付きエントリ") +l2 = TkLabelFrame.new(base_frame, :text=>"長さ制約付きエントリ") TkEntry.new(l2, :validate=>:key, :invcmd=>proc{Tk.bell}, :vcmd=>[proc{|s| s.length < 10}, '%P'] ).pack(:fill=>:x, :expand=>true, :padx=>'1m', :pady=>'1m') @@ -162,15 +182,15 @@ def validatePhoneChange(widget, vmode, idx, char) widget.delete(idx) widget.insert(idx, $phoneNumberMap[char] || char) Tk.after_idle(proc{phoneSkipRight(widget, -1)}) - # Tk.update(true) # Don't work 'update' inter validation callback. - # It depends on Tcl/Tk side (tested on Tcl/Tk8.5a1). + # Tk.update(true) # <- Don't work 'update' inter validation callback. + # It depends on Tcl/Tk side (tested on Tcl/Tk8.5a1). return true end return false end -l3 = TkLabelFrame.new($entry3_demo, :text=>"米国電話番号エントリ") +l3 = TkLabelFrame.new(base_frame, :text=>"米国電話番号エントリ") TkEntry.new(l3, :validate=>:key, :invcmd=>proc{Tk.bell}, :textvariable=>entry3content, :vcmd=>[ @@ -189,14 +209,14 @@ TkEntry.new(l3, :validate=>:key, :invcmd=>proc{Tk.bell}, pack(:fill=>:x, :expand=>true, :padx=>'1m', :pady=>'1m') } -l4 = TkLabelFrame.new($entry3_demo, :text=>"パスワードエントリ") +l4 = TkLabelFrame.new(base_frame, :text=>"パスワードエントリ") TkEntry.new(l4, :validate=>:key, :show=>'*', :vcmd=>[ proc{|s| s.length <= 8}, '%P' ]).pack(:fill=>:x, :expand=>true, :padx=>'1m', :pady=>'1m') -TkFrame.new($entry3_demo){|f| +TkFrame.new(base_frame){|f| lower TkGrid.configure(l1, l2, :in=>f, :padx=>'3m', :pady=>'1m', :sticky=>:ew) TkGrid.configure(l3, l4, :in=>f, :padx=>'3m', :pady=>'1m', :sticky=>:ew) diff --git a/ext/tk/sample/demos-jp/filebox.rb b/ext/tk/sample/demos-jp/filebox.rb index 04b4810b3b..b8846d08a0 100644 --- a/ext/tk/sample/demos-jp/filebox.rb +++ b/ext/tk/sample/demos-jp/filebox.rb @@ -16,12 +16,14 @@ $filebox_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($filebox_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -TkLabel.new($filebox_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left', +TkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left', 'text'=>"エントリにファイル名を直接入力するか、\"Browse\" ボタンを押してファイル選択ダイアログからファイル名を選んで下さい。").pack('side'=>'top') # frame 生成 -TkFrame.new($filebox_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -40,7 +42,7 @@ TkFrame.new($filebox_demo) {|frame| # frame 生成 ['開く', '保存'].each{|type| - TkFrame.new($filebox_demo) {|f| + TkFrame.new(base_frame) {|f| TkLabel.new(f, 'text'=>"ファイルを#{type}: ", 'anchor'=>'e')\ .pack('side'=>'left') @@ -48,7 +50,7 @@ TkFrame.new($filebox_demo) {|frame| pack('side'=>'left', 'expand'=>'yes', 'fill'=>'x') TkButton.new(f, 'text'=>'Browse ...', - 'command'=>proc{fileDialog $filebox_demo,e,type})\ + 'command'=>proc{fileDialog base_frame,e,type})\ .pack('side'=>'left') } @@ -58,7 +60,7 @@ TkFrame.new($filebox_demo) {|frame| $tk_strictMotif = TkVarAccess.new('tk_strictMotif') if ($tk_platform['platform'] == 'unix') - TkCheckButton.new($filebox_demo, + TkCheckButton.new(base_frame, 'text'=>'Motifスタイルのダイアログを用いる', 'variable'=>$tk_strictMotif, 'onvalue'=>1, 'offvalue'=>0 ).pack('anchor'=>'c') @@ -91,7 +93,10 @@ def fileDialog(w,ent,operation) if file != "" ent.delete 0, 'end' ent.insert 0, file - ent.xview 'end' + # ent.xview 'end' + Tk.update_idletasks # need this for Tk::Tile::Entry + # (to find right position of 'xview'). + ent.xview(ent.index('end')) end end diff --git a/ext/tk/sample/demos-jp/floor.rb b/ext/tk/sample/demos-jp/floor.rb index b7d07bdafa..a2ec2e9969 100644 --- a/ext/tk/sample/demos-jp/floor.rb +++ b/ext/tk/sample/demos-jp/floor.rb @@ -1587,14 +1587,16 @@ $floor_demo = TkToplevel.new {|w| minsize(100,100) } +base_frame = TkFrame.new($floor_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -TkLabel.new($floor_demo, 'font'=>$font, 'wraplength'=>'8i', 'justify'=>'left', +TkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'8i', 'justify'=>'left', 'text'=>"このウィンドウにはディジタルエクイップメント社のウェスタンリサーチラボラトリ (DECWRL) の間取りが書かれたキャンバス widget が入っています。これは 3階建てで、常にそのうちの1階分が選択、つまりその間取りが表示されるようになっています。ある階を選択するには、その上でマウスの左ボタンをクリックしてください。マウスが選択されている階の上を動くと、その下にある部屋の色が変わり、部屋番号が「部屋番号:」エントリに表示されます。また、エントリに部屋番号を書くとその部屋の色が変わります。"){ pack('side'=>'top') } # frame 生成 -$floor_buttons = TkFrame.new($floor_demo) {|frame| +$floor_buttons = TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -1618,17 +1620,17 @@ $floorItems = {} # canvas 設定 if $tk_version =~ /^4\.[01]/ - $floor_canvas_frame = TkFrame.new($floor_demo,'bd'=>2,'relief'=>'sunken', + $floor_canvas_frame = TkFrame.new(base_frame,'bd'=>2,'relief'=>'sunken', 'highlightthickness'=>2) $floor_canvas = TkCanvas.new($floor_canvas_frame, 'width'=>900, 'height'=>500, 'borderwidth'=>0, 'highlightthickness'=>0) {|c| - TkScrollbar.new($floor_demo, 'orient'=>'horiz', + TkScrollbar.new(base_frame, 'orient'=>'horiz', 'command'=>proc{|*args| c.xview(*args)}){|hs| c.xscrollcommand(proc{|first,last| hs.set first,last}) pack('side'=>'bottom', 'fill'=>'x') } - TkScrollbar.new($floor_demo, 'command'=>proc{|*args| c.yview(*args)}){|vs| + TkScrollbar.new(base_frame, 'command'=>proc{|*args| c.yview(*args)}){|vs| c.yscrollcommand(proc{|first,last| vs.set first,last}) pack('side'=>'right', 'fill'=>'y') } @@ -1637,7 +1639,7 @@ if $tk_version =~ /^4\.[01]/ $floor_canvas.pack('expand'=>'yes', 'fill'=>'both') else - TkFrame.new($floor_demo) {|f| + TkFrame.new(base_frame) {|f| pack('side'=>'top', 'fill'=>'both', 'expand'=>'yes') h = TkScrollbar.new(f, 'highlightthickness'=>0, 'orient'=>'horizontal') diff --git a/ext/tk/sample/demos-jp/floor2.rb b/ext/tk/sample/demos-jp/floor2.rb index b7571a592f..d4381c5543 100644 --- a/ext/tk/sample/demos-jp/floor2.rb +++ b/ext/tk/sample/demos-jp/floor2.rb @@ -1587,14 +1587,16 @@ $floor2_demo = TkToplevel.new {|w| minsize(100,100) } +base_frame = TkFrame.new($floor2_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -TkLabel.new($floor2_demo, 'font'=>$font, 'wraplength'=>'8i', 'justify'=>'left', +TkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'8i', 'justify'=>'left', 'text'=>"このウィンドウにはディジタルエクイップメント社のウェスタンリサーチラボラトリ (DECWRL) の間取りが書かれたキャンバス widget が入っています。これは 3階建てで、常にそのうちの1階分が選択、つまりその間取りが表示されるようになっています。ある階を選択するには、その上でマウスの左ボタンをクリックしてください。マウスが選択されている階の上を動くと、その下にある部屋の色が変わり、部屋番号が「部屋番号:」エントリに表示されます。また、エントリに部屋番号を書くとその部屋の色が変わります。"){ pack('side'=>'top') } # frame 生成 -$floor2_buttons = TkFrame.new($floor2_demo) {|frame| +$floor2_buttons = TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -1618,17 +1620,17 @@ $floorItems2 = {} # canvas 設定 if $tk_version =~ /^4\.[01]/ - $floor2_canvas_frame = TkFrame.new($floor2_demo,'bd'=>2,'relief'=>'sunken', + $floor2_canvas_frame = TkFrame.new(base_frame,'bd'=>2,'relief'=>'sunken', 'highlightthickness'=>2) $floor2_canvas = TkCanvas.new($floor2_canvas_frame, 'width'=>900, 'height'=>500, 'borderwidth'=>0, 'highlightthickness'=>0) {|c| - TkScrollbar.new($floor2_demo, 'orient'=>'horiz', + TkScrollbar.new(base_frame, 'orient'=>'horiz', 'command'=>proc{|*args| c.xview(*args)}){|hs| c.xscrollcommand(proc{|first,last| hs.set first,last}) pack('side'=>'bottom', 'fill'=>'x') } - TkScrollbar.new($floor2_demo, 'command'=>proc{|*args| c.yview(*args)}){|vs| + TkScrollbar.new(base_frame, 'command'=>proc{|*args| c.yview(*args)}){|vs| c.yscrollcommand(proc{|first,last| vs.set first,last}) pack('side'=>'right', 'fill'=>'y') } @@ -1637,7 +1639,7 @@ if $tk_version =~ /^4\.[01]/ $floor2_canvas.pack('expand'=>'yes', 'fill'=>'both') else - TkFrame.new($floor2_demo) {|f| + TkFrame.new(base_frame) {|f| pack('side'=>'top', 'fill'=>'both', 'expand'=>'yes') h = TkScrollbar.new(f, 'highlightthickness'=>0, 'orient'=>'horizontal') diff --git a/ext/tk/sample/demos-jp/form.rb b/ext/tk/sample/demos-jp/form.rb index 637dd9a8ea..4de7056764 100644 --- a/ext/tk/sample/demos-jp/form.rb +++ b/ext/tk/sample/demos-jp/form.rb @@ -16,8 +16,10 @@ $form_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($form_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -msg = TkLabel.new($form_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -26,7 +28,7 @@ msg = TkLabel.new($form_demo) { msg.pack('side'=>'top', 'fill'=>'x') # frame 生成 -TkFrame.new($form_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -46,7 +48,7 @@ TkFrame.new($form_demo) {|frame| # entry 生成 form_data = [] (1..5).each{|i| - f = TkFrame.new($form_demo, 'bd'=>2) + f = TkFrame.new(base_frame, 'bd'=>2) e = TkEntry.new(f, 'relief'=>'sunken', 'width'=>40) l = TkLabel.new(f) e.pack('side'=>'right') diff --git a/ext/tk/sample/demos-jp/goldberg.rb b/ext/tk/sample/demos-jp/goldberg.rb index 8bf0104c16..a81c7ec70c 100644 --- a/ext/tk/sample/demos-jp/goldberg.rb +++ b/ext/tk/sample/demos-jp/goldberg.rb @@ -55,6 +55,8 @@ $goldberg_demo = TkToplevel.new {|w| # positionWindow(w) } +base_frame = TkFrame.new($goldberg_demo).pack(:fill=>:both, :expand=>true) + =begin # label msg = TkLabel.new($goldberg_demo) { @@ -177,7 +179,8 @@ class TkGoldberg_Demo do_ctrl_frame do_detail_frame - msg = TkLabel.new(@parent, :bg=>@C['bg'], :fg=>'white') { + # msg = TkLabel.new(@parent, :bg=>@C['bg'], :fg=>'white') { + msg = Tk::Label.new(@parent, :bg=>@C['bg'], :fg=>'white') { font 'Arial 10' wraplength 600 justify 'left' @@ -187,7 +190,8 @@ class TkGoldberg_Demo frame = TkFrame.new(@parent, :bg=>@C['bg']) - TkButton.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) { + # TkButton.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) { + Tk::Button.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) { text '閉じる' command proc{ tmppath = $goldberg_demo @@ -196,12 +200,14 @@ class TkGoldberg_Demo } }.pack('side'=>'left') - TkButton.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) { + # TkButton.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) { + Tk::Button.new(frame, :bg=>@C['bg'], :activebackground=>@C['bg']) { text 'コード参照' command proc{showCode 'goldberg'} }.pack('side'=>'left', 'padx'=>5) - @show = TkButton.new(frame, :text=>'>>', :command=>proc{show_ctrl}, + # @show = TkButton.new(frame, :text=>'>>', :command=>proc{show_ctrl}, + @show = Tk::Button.new(frame, :text=>'>>', :command=>proc{show_ctrl}, :bg=>@C['bg'], :activebackground=>@C['bg']) @show.pack('side'=>'left') frame.place(:in=>@canvas, :relx=>1, :rely=>0, :anchor=>:ne) @@ -210,10 +216,11 @@ class TkGoldberg_Demo end def do_ctrl_frame - @start = TkButton.new(@parent, :text=>'Start', :bd=>6, + @start = Tk::Button.new(@parent, :text=>'Start', :bd=>6, :command=>proc{do_button(0)}) - @start.font(@start['font'].weight('bold')) - font = @start['font'] + if font = @start['font'] + @start.font(font.weight('bold')) + end @pause = TkCheckbutton.new(@parent, :text=>'Pause', :font=>font, :command=>proc{do_button(1)}, :relief=>:raised, @@ -2001,4 +2008,4 @@ class TkGoldberg_Demo end end -TkGoldberg_Demo.new($goldberg_demo) +TkGoldberg_Demo.new(base_frame) diff --git a/ext/tk/sample/demos-jp/hscale.rb b/ext/tk/sample/demos-jp/hscale.rb index b636f0579f..5615aa50bd 100644 --- a/ext/tk/sample/demos-jp/hscale.rb +++ b/ext/tk/sample/demos-jp/hscale.rb @@ -12,8 +12,9 @@ $hscale_demo = TkToplevel.new {|w| } positionWindow($hscale_demo) +base_frame = TkFrame.new($hscale_demo).pack(:fill=>:both, :expand=>true) -msg = TkLabel.new($hscale_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '3.5i' justify 'left' @@ -23,7 +24,7 @@ msg = TkLabel.new($hscale_demo) { } msg.pack('side'=>'top') -TkFrame.new($hscale_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -40,7 +41,17 @@ TkFrame.new($hscale_demo) {|frame| }.pack('side'=>'left', 'expand'=>'yes') }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') -TkFrame.new($hscale_demo) {|frame| +def setWidth(w, width) + width = width + 21 + x2 = width - 30 + if x2 < 21 + x2 = 21 + end + w.coords 'poly',20,15,20,35,x2,35,x2,45,width,25,x2,5,x2,15,20,15 + w.coords 'line',20,15,20,35,x2,35,x2,45,width,25,x2,5,x2,15,20,15 +end + +TkFrame.new(base_frame) {|frame| canvas = TkCanvas.new(frame) {|c| width 50 height 50 @@ -65,13 +76,3 @@ TkFrame.new($hscale_demo) {|frame| }.pack('side'=>'bottom', 'expand'=>'yes', 'anchor'=>'n') scale.set 75 }.pack('side'=>'top', 'fill'=>'x') - -def setWidth(w, width) - width = width + 21 - x2 = width - 30 - if x2 < 21 - x2 = 21 - end - w.coords 'poly',20,15,20,35,x2,35,x2,45,width,25,x2,5,x2,15,20,15 - w.coords 'line',20,15,20,35,x2,35,x2,45,width,25,x2,5,x2,15,20,15 -end diff --git a/ext/tk/sample/demos-jp/icon.rb b/ext/tk/sample/demos-jp/icon.rb index 26382a57a7..a2ca6651dc 100644 --- a/ext/tk/sample/demos-jp/icon.rb +++ b/ext/tk/sample/demos-jp/icon.rb @@ -16,8 +16,10 @@ $icon_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($icon_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -msg = TkLabel.new($icon_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '5i' justify 'left' @@ -26,7 +28,7 @@ msg = TkLabel.new($icon_demo) { msg.pack('side'=>'top') # frame 生成 -TkFrame.new($icon_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -61,16 +63,18 @@ TkBitmapImage.new('file'=>[$demo_dir,'..', letters = TkVariable.new # frame 生成 -TkFrame.new($icon_demo, 'borderwidth'=>10){|w| +TkFrame.new(base_frame, 'borderwidth'=>10){|w| TkFrame.new(w) {|f| - TkRadioButton.new(f){ + # TkRadioButton.new(f){ + Tk::RadioButton.new(f){ bitmap '@' + [$demo_dir,'..', 'images','letters.xbm'].join(File::Separator) variable letters value 'full' }.pack('side'=>'top', 'expand'=>'yes') - TkRadioButton.new(f){ + # TkRadioButton.new(f){ + Tk::RadioButton.new(f){ bitmap '@' + [$demo_dir,'..', 'images','noletter.xbm'].join(File::Separator) variable letters @@ -79,14 +83,16 @@ TkFrame.new($icon_demo, 'borderwidth'=>10){|w| }.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'5m') - TkCheckButton.new(w) { + # TkCheckButton.new(w) { + Tk::CheckButton.new(w) { image flagdown selectimage flagup indicatoron 0 selectcolor self['background'] }.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'5m') - TkCheckButton.new(w) { + # TkCheckButton.new(w) { + Tk::CheckButton.new(w) { bitmap '@' + [$demo_dir,'..', 'images','letters.xbm'].join(File::Separator) indicatoron 0 diff --git a/ext/tk/sample/demos-jp/image1.rb b/ext/tk/sample/demos-jp/image1.rb index 3b56d240dc..d9435cc1a2 100644 --- a/ext/tk/sample/demos-jp/image1.rb +++ b/ext/tk/sample/demos-jp/image1.rb @@ -16,8 +16,10 @@ $image1_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($image1_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -msg = TkLabel.new($image1_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -26,7 +28,7 @@ msg = TkLabel.new($image1_demo) { msg.pack('side'=>'top') # frame 生成 -TkFrame.new($image1_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -53,7 +55,10 @@ TkPhotoImage.new('file'=>[$demo_dir,'..', 'images','earthris.gif'].join(File::Separator)) # label 生成 -[ TkLabel.new($image1_demo, 'image'=>image1a, 'bd'=>1, 'relief'=>'sunken'), - TkLabel.new($image1_demo, 'image'=>image1b, 'bd'=>1, 'relief'=>'sunken') +#[ TkLabel.new(base_frame, 'image'=>image1a, 'bd'=>1, 'relief'=>'sunken'), +# TkLabel.new(base_frame, 'image'=>image1b, 'bd'=>1, 'relief'=>'sunken') +#].each{|w| w.pack('side'=>'top', 'padx'=>'.5m', 'pady'=>'.5m')} +[ Tk::Label.new(base_frame, 'image'=>image1a, 'bd'=>1, 'relief'=>'sunken'), + Tk::Label.new(base_frame, 'image'=>image1b, 'bd'=>1, 'relief'=>'sunken') ].each{|w| w.pack('side'=>'top', 'padx'=>'.5m', 'pady'=>'.5m')} diff --git a/ext/tk/sample/demos-jp/image2.rb b/ext/tk/sample/demos-jp/image2.rb index de627448c1..1bb2c9e9c3 100644 --- a/ext/tk/sample/demos-jp/image2.rb +++ b/ext/tk/sample/demos-jp/image2.rb @@ -16,8 +16,10 @@ $image2_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($image2_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -msg = TkLabel.new($image2_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -26,7 +28,7 @@ msg = TkLabel.new($image2_demo) { msg.pack('side'=>'top') # frame 生成 -TkFrame.new($image2_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -51,21 +53,21 @@ $dirName = TkVariable.new([$demo_dir,'..','images'].join(File::Separator)) $image2a = TkPhotoImage.new # ファイル名入力部 -TkLabel.new($image2_demo, 'text'=>'ディレクトリ:')\ +TkLabel.new(base_frame, 'text'=>'ディレクトリ:')\ .pack('side'=>'top', 'anchor'=>'w') -image2_e = TkEntry.new($image2_demo) { +image2_e = TkEntry.new(base_frame) { width 30 textvariable $dirName }.pack('side'=>'top', 'anchor'=>'w') -TkFrame.new($image2_demo, 'height'=>'3m', 'width'=>20)\ +TkFrame.new(base_frame, 'height'=>'3m', 'width'=>20)\ .pack('side'=>'top', 'anchor'=>'w') -TkLabel.new($image2_demo, 'text'=>'ファイル:')\ +TkLabel.new(base_frame, 'text'=>'ファイル:')\ .pack('side'=>'top', 'anchor'=>'w') -TkFrame.new($image2_demo){|w| +TkFrame.new(base_frame){|w| s = TkScrollbar.new(w) l = TkListbox.new(w) { width 20 @@ -84,9 +86,10 @@ TkFrame.new($image2_demo){|w| }.pack('side'=>'top', 'anchor'=>'w') # image 配置 -[ TkFrame.new($image2_demo, 'height'=>'3m', 'width'=>20), - TkLabel.new($image2_demo, 'text'=>'画像:'), - TkLabel.new($image2_demo, 'image'=>$image2a) +[ TkFrame.new(base_frame, 'height'=>'3m', 'width'=>20), + TkLabel.new(base_frame, 'text'=>'画像:'), + # TkLabel.new(base_frame, 'image'=>$image2a) + Tk::Label.new(base_frame, 'image'=>$image2a) ].each{|w| w.pack('side'=>'top', 'anchor'=>'w')} # メソッド定義 diff --git a/ext/tk/sample/demos-jp/image3.rb b/ext/tk/sample/demos-jp/image3.rb index 36c1823745..12b8aafd8e 100644 --- a/ext/tk/sample/demos-jp/image3.rb +++ b/ext/tk/sample/demos-jp/image3.rb @@ -20,6 +20,8 @@ $image3_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($image3_demo).pack(:fill=>:both, :expand=>true) + # def loadDir3(w) w.delete(0,'end') @@ -50,7 +52,7 @@ end # label -msg = TkLabel.new($image3_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -59,7 +61,7 @@ msg = TkLabel.new($image3_demo) { msg.pack('side'=>'top') # frame -TkFrame.new($image3_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -88,11 +90,11 @@ end $image3a = TkPhotoImage.new # -image3_f = TkFrame.new($image3_demo).pack(:fill=>:both, :expand=>true) +image3_f = TkFrame.new(base_frame).pack(:fill=>:both, :expand=>true) -image3_df = TkLabelFrame.new($image3_demo, :text=>'ディレクトリ:') +image3_df = TkLabelFrame.new(base_frame, :text=>'ディレクトリ:') -image3_ff = TkLabelFrame.new($image3_demo, :text=>'ファイル:', +image3_ff = TkLabelFrame.new(base_frame, :text=>'ファイル:', :padx=>'2m', :pady=>'2m') image3_lbx = TkListbox.new(image3_ff, :width=>20, :height=>10) { pack(:side=>:left, :fill=>:y, :expand=>true) @@ -112,8 +114,9 @@ TkButton.new(image3_df, :pady=>0, :padx=>'2m', :text=>" pack(:side=>:left, :fill=>:y, :padx=>[0, '2m'], :pady=>'2m') } -image3_if = TkLabelFrame.new($image3_demo, :text=>'イメージ:') {|f| - TkLabel.new(f, :image=>$image3a).pack(:padx=>'2m', :pady=>'2m') +image3_if = TkLabelFrame.new(base_frame, :text=>'イメージ:') {|f| + # TkLabel.new(f, :image=>$image3a).pack(:padx=>'2m', :pady=>'2m') + Tk::Label.new(f, :image=>$image3a).pack(:padx=>'2m', :pady=>'2m') } Tk.grid(image3_df, '-', diff --git a/ext/tk/sample/demos-jp/items.rb b/ext/tk/sample/demos-jp/items.rb index c173d3b57f..64ceeff3ec 100644 --- a/ext/tk/sample/demos-jp/items.rb +++ b/ext/tk/sample/demos-jp/items.rb @@ -16,8 +16,10 @@ $items_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($items_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -TkLabel.new($items_demo) { +TkLabel.new(base_frame) { font $font wraplength '5i' justify 'left' @@ -25,7 +27,7 @@ TkLabel.new($items_demo) { }.pack('side'=>'top') # frame 生成 -TkFrame.new($items_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -44,7 +46,7 @@ TkFrame.new($items_demo) {|frame| # frame 生成 cvs = nil -TkFrame.new($items_demo) {|cf| +TkFrame.new(base_frame) {|cf| # canvas 生成 cvs = TkCanvas.new(cf) {|c| focus diff --git a/ext/tk/sample/demos-jp/knightstour.rb b/ext/tk/sample/demos-jp/knightstour.rb new file mode 100644 index 0000000000..d4595ea441 --- /dev/null +++ b/ext/tk/sample/demos-jp/knightstour.rb @@ -0,0 +1,273 @@ +# -*- coding: euc-jp -*- +# +# Based on the widget demo of Tcl/Tk8.5.2 +# The following is the original copyright text. +#---------------------------------------------------------------------------- +# Copyright (C) 2008 Pat Thoyts +# +# Calculate a Knight's tour of a chessboard. +# +# This uses Warnsdorff's rule to calculate the next square each +# time. This specifies that the next square should be the one that +# has the least number of available moves. +# +# Using this rule it is possible to get to a position where +# there are no squares available to move into. In this implementation +# this occurs when the starting square is d6. +# +# To solve this fault an enhancement to the rule is that if we +# have a choice of squares with an equal score, we should choose +# the one nearest the edge of the board. +# +# If the call to the Edgemost function is commented out you can see +# this occur. +# +# You can drag the knight to a specific square to start if you wish. +# If you let it repeat then it will choose random start positions +# for each new tour. +#---------------------------------------------------------------------------- +require 'tk' + +class Knights_Tour + # Return a list of accessible squares from a given square + def valid_moves(square) + moves = [] + [ + [-1,-2], [-2,-1], [-2,1], [-1,2], [1,2], [2,1], [2,-1], [1,-2] + ].each{|col_delta, row_delta| + col = (square % 8) + col_delta + row = (square.div(8)) + row_delta + moves << (row * 8 + col) if row > -1 && row < 8 && col > -1 && col < 8 + } + moves + end + + # Return the number of available moves for this square + def check_square(square) + valid_moves(square).find_all{|pos| ! @visited.include?(pos)}.length + end + + # Select the next square to move to. Returns -1 if there are no available + # squares remaining that we can move to. + def next_square(square) + minimum = 9 + nxt = -1 + valid_moves(square).each{|pos| + unless @visited.include?(pos) + cnt = check_square(pos) + if cnt < minimum + minimum = cnt + nxt = pos + elsif cnt == minimum + nxt = edgemost(nxt, pos) + end + end + } + nxt + end + + # Select the square nearest the edge of the board + def edgemost(nxt, pos) + col_A = 3 - ((3.5 - nxt % 8).abs.to_i) + col_B = 3 - ((3.5 - pos % 8).abs.to_i) + row_A = 3 - ((3.5 - nxt.div(8)).abs.to_i) + row_B = 3 - ((3.5 - pos.div(8)).abs.to_i) + (col_A * row_A < col_B * row_B)? nxt : pos + end + + # Display a square number as a standard chess square notation. + def _N(square) + '%c%d' % [(97 + square % 8), (square.div(8) + 1)] + end + + # Perform a Knight's move and schedule the next move. + def move_piece(last, square) + @log.insert(:end, "#{@visited.length}. #{_N last} -> #{_N square}\n", '') + @log.see(:end) + @board.itemconfigure(1+last, :state=>:normal, :outline=>'black') + @board.itemconfigure(1+square, :state=>:normal, :outline=>'red') + @knight.coords(@board.coords(1+square)[0..1]) + @visited << square + if (nxt = next_square(square)) != -1 + @after_id = Tk.after(@delay.numeric){move_piece(square, nxt) rescue nil} + else + @start_btn.state :normal + if @visited.length == 64 + if @initial == square + @log.insert :end, '周遊(closed tour)成功!' + else + @log.insert :end, "成功\n", {} + Tk.after(@delay.numeric * 2){tour(rand(64))} if @continuous.bool + end + else + @log.insert :end, "失敗!\n", {} + end + end + end + + # Begin a new tour of the board given a random start position + def tour(square = nil) + @visited.clear + @log.clear + @start_btn.state :disabled + 1.upto(64){|n| + @board.itemconfigure(n, :state=>:disabled, :outline=>'black') + } + unless square + square = @board.find_closest(*(@knight.coords << 0 << 65))[0].to_i - 1 + end + @initial = square + Tk.after_idle{ move_piece(@initial, @initial) rescue nil } + end + + def _stop + Tk.after_cancel(@after_id) rescue nil + end + + def _exit + _stop + $knightstour.destroy + end + + def set_delay(new) + @delay.numeric = new.to_i + end + + def drag_start(w, x, y) + w.dtag('selected') + w.addtag('selected', :withtag, 'current') + @dragging = [x, y] + end + + def drag_motion(w, x, y) + return unless @dragging + w.move('selected', x - @dragging[0], y - @dragging[1]) + @dragging = [x, y] + end + + def drag_end(w, x, y) + square = w.find_closest(x, y, 0, 65) + w.coords('selected', w.coords(square)[0..1]) + w.dtag('selected') + @dragging = nil + end + + def make_SeeDismiss + ## See Code / Dismiss + frame = Ttk::Frame.new($knightstour) + sep = Ttk::Separator.new(frame) + Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + Ttk::Button.new(frame, :text=>'コード参照', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'knightstour'}), + Ttk::Button.new(frame, :text=>'閉じる', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + $knightstour.destroy + $knightstour = nil + }), + :padx=>4, :pady=>4) + frame.grid_columnconfigure(0, :weight=>1) + frame + end + + def create_gui(parent = nil) + $knightstour.destroy rescue nil + $knightstour = Tk::Toplevel.new(parent, :title=>"Knight's tour") + $knightstour.withdraw + base_f = Ttk::Frame.new($knightstour) + @board = Tk::Canvas.new(base_f, :width=>240, :height=>240) + @log = Tk::Text.new(base_f, :width=>12, :height=>1, + :font=>'Arial 8', :background=>'white') + scr = @log.yscrollbar(Ttk::Scrollbar.new(base_f)) + + @visited = [] + @delay = TkVariable.new(600) + @continuous = TkVariable.new(false) + + tool_f = Ttk::Frame.new($knightstour) + label = Ttk::Label.new(tool_f, :text=>'実行速度') + scale = Ttk::Scale.new(tool_f, :from=>8, :to=>2000, :variable=>@delay, + :command=>proc{|n| set_delay(n)}) + check = Ttk::Checkbutton.new(tool_f, :text=>'反復', + :variable=>@continuous) + @start_btn = Ttk::Button.new(tool_f, :text=>'開始', + :command=>proc{tour()}) + @exit_btn = Ttk::Button.new(tool_f, :text=>'終了', + :command=>proc{_exit()}) + + 7.downto(0){|row| + 0.upto(7){|col| + if ((col & 1) ^ (row & 1)).zero? + fill = 'bisque' + dfill = 'bisque3' + else + fill = 'tan3' + dfill = 'tan4' + end + coords = [col * 30 + 4, row * 30 + 4, col * 30 + 30, row * 30 + 30] + @board.create(TkcRectangle, coords, + :fill=>fill, :disabledfill=>dfill, + :width=>2, :state=>:disabled) + } + } + + @knight_font = TkFont.new(:size=>-24) + @knight = TkcText.new(@board, 0, 0, :font=>@knight_font, + :text=>Tk::UTF8_String.new('\u265e'), + :anchor=>'nw', # :tags=>'knight', + :fill=>'black', :activefill=>'#600000') + @knight.coords(@board.coords(rand(64)+1)[0..1]) + @knight.bind('ButtonPress-1', '%W %x %y'){|w,x,y| drag_start(w,x,y)} + @knight.bind('Motion', '%W %x %y'){|w,x,y| drag_motion(w,x,y)} + @knight.bind('ButtonRelease-1', '%W %x %y'){|w,x,y| drag_end(w,x,y)} + + Tk.grid(@board, @log, scr, :sticky=>'news') + base_f.grid_rowconfigure(0, :weight=>1) + base_f.grid_columnconfigure(0, :weight=>1) + + Tk.grid(base_f, '-', '-', '-', '-', '-', :sticky=>'news') + widgets = [label, scale, check, @start_btn] + sg = nil + unless $RubyTk_WidgetDemo + widgets << @exit_btn + if Tk.windowingsystem != 'aqua' + #widgets.unshift(Ttk::SizeGrip.new(tool_f)) + Ttk::SizeGrip.new(tool_f).pack(:side=>:right, :anchor=>'se') + end + end + Tk.pack(widgets, :side=>:right) + if Tk.windowingsystem == 'aqua' + TkPack.configure(widgets, :padx=>[4, 4], :pady=>[12, 12]) + TkPack.configure(widgets[0], :padx=>[4, 24]) + TkPack.configure(widgets[-1], :padx=>[16, 4]) + end + + Tk.grid(tool_f, '-', '-', '-', '-', '-', :sticky=>'ew') + + if $RubyTk_WidgetDemo + Tk.grid(make_SeeDismiss(), '-', '-', '-', '-', '-', :sticky=>'ew') + end + + $knightstour.grid_rowconfigure(0, :weight=>1) + $knightstour.grid_columnconfigure(0, :weight=>1) + + $knightstour.bind('Control-F2'){TkConsole.show} + $knightstour.bind('Return'){@start_btn.invoke} + $knightstour.bind('Escape'){@exit_btn.invoke} + $knightstour.bind('Destroy'){ _stop } + $knightstour.protocol('WM_DELETE_WINDOW'){ _exit } + + $knightstour.deiconify + $knightstour.tkwait_destroy + end + + def initialize(parent = nil) + create_gui(parent) + end +end + +Tk.root.withdraw unless $RubyTk_WidgetDemo +Thread.new{Tk.mainloop} if __FILE__ == $0 +Knights_Tour.new diff --git a/ext/tk/sample/demos-jp/label.rb b/ext/tk/sample/demos-jp/label.rb index a1ecc2ec80..2e6b3e7e57 100644 --- a/ext/tk/sample/demos-jp/label.rb +++ b/ext/tk/sample/demos-jp/label.rb @@ -16,8 +16,10 @@ $label_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($label_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -msg = TkLabel.new($label_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -26,7 +28,7 @@ msg = TkLabel.new($label_demo) { msg.pack('side'=>'top') # frame 生成 -TkFrame.new($label_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -45,8 +47,8 @@ TkFrame.new($label_demo) {|frame| }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # label demo 用フレーム生成 -f_left = TkFrame.new($label_demo) -f_right = TkFrame.new($label_demo) +f_left = TkFrame.new(base_frame) +f_right = TkFrame.new(base_frame) [f_left, f_right].each{|w| w.pack('side'=>'left', 'expand'=>'yes', 'padx'=>10, 'pady'=>10, 'fill'=>'both')} @@ -57,7 +59,8 @@ f_right = TkFrame.new($label_demo) TkLabel.new(f_left, 'text'=>'3 番目。沈んでいます ', 'relief'=>'sunken') ].each{|w| w.pack('side'=>'top', 'expand'=>'yes', 'pady'=>2, 'anchor'=>'w')} -TkLabel.new(f_right) { +# TkLabel.new(f_right) { +Tk::Label.new(f_right) { bitmap('@' + [$demo_dir,'..','images','face.xbm'].join(File::Separator)) borderwidth 2 relief 'sunken' diff --git a/ext/tk/sample/demos-jp/labelframe.rb b/ext/tk/sample/demos-jp/labelframe.rb index f16b601ffd..11b0d27308 100644 --- a/ext/tk/sample/demos-jp/labelframe.rb +++ b/ext/tk/sample/demos-jp/labelframe.rb @@ -19,8 +19,10 @@ $labelframe_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($labelframe_demo).pack(:fill=>:both, :expand=>true) + # Some information -TkLabel.new($labelframe_demo, +TkLabel.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, :text=><:top) TkLabelFrame ウィジェットは関連する widget @@ -36,7 +38,7 @@ labelframe EOL # The bottom buttons -TkFrame.new($labelframe_demo){|f| +TkFrame.new(base_frame){|f| pack(:side=>:bottom, :fill=>:x, :pady=>'2m') TkButton.new(f, :text=>'閉じる', :width=>15, :command=>proc{ @@ -50,7 +52,7 @@ TkFrame.new($labelframe_demo){|f| } # Demo area -w = TkFrame.new($labelframe_demo).pack(:side=>:bottom, :fill=>:both, +w = TkFrame.new(base_frame).pack(:side=>:bottom, :fill=>:both, :expand=>true) # A group of radiobuttons in a labelframe diff --git a/ext/tk/sample/demos-jp/mclist.rb b/ext/tk/sample/demos-jp/mclist.rb new file mode 100644 index 0000000000..a7834d2668 --- /dev/null +++ b/ext/tk/sample/demos-jp/mclist.rb @@ -0,0 +1,121 @@ +# -*- coding: euc-jp -*- +# +# mclist.rb -- +# +# This demonstration script creates a toplevel window containing a Ttk +# tree widget configured as a multi-column listbox. +# +# based on "Id: mclist.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp" + +if defined?($mclist_demo) && $mclist_demo + $mclist_demo.destroy + $mclist_demo = nil +end + +$mclist_demo = TkToplevel.new {|w| + title("Multi-Column List") + iconname("mclist") + positionWindow(w) +} + +base_frame = TkFrame.new($mclist_demo).pack(:fill=>:both, :expand=>true) + +## Explanatory text +Ttk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', + :justify=>:left, :anchor=>'n', :padding=>[10, 2, 10, 6], + :text=><:x) +Ttkとは,テーマ指定可能な新しいウィジェット集合です.\ +Ttk::Treeviewウィジェットは\ +Ttkウィジェットセットに含まれるウィジェットの一つで,\ +それが保持する木構造のデータそのものまでは表示することなく,\ +示したい情報をマルチカラムで表示させることができます. +このサンプルは,複数のカラムを持ったリストボックスを作成する簡単な例です. +各カラムのタイトル(heading)をクリックすれば,\ +そのカラムの情報に基づいてリストの並べ替えがなされるはずです.\ +また,カラムのタイトル間の区切り部分をドラッグすることで,\ +カラムの幅を変更することも可能です. +EOL + +## See Code / Dismiss +Ttk::Frame.new(base_frame) {|frame| + sep = Ttk::Separator.new(frame) + Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + Ttk::Button.new(frame, :text=>'コード参照', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'mclist'}), + Ttk::Button.new(frame, :text=>'閉じる', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + $mclist_demo.destroy + $mclist_demo = nil + }), + :padx=>4, :pady=>4) + grid_columnconfigure(0, :weight=>1) + pack(:side=>:bottom, :fill=>:x) +} + +container = Ttk::Frame.new(base_frame) +tree = Ttk::Treeview.new(base_frame, :columns=>%w(country capital currency), + :show=>:headings) +if Tk.windowingsystem != 'aquq' + vsb = tree.yscrollbar(Ttk::Scrollbar.new(base_frame)) + hsb = tree.xscrollbar(Ttk::Scrollbar.new(base_frame)) +else + vsb = tree.yscrollbar(Tk::Scrollbar.new(base_frame)) + hsb = tree.xscrollbar(Tk::Scrollbar.new(base_frame)) +end + +container.pack(:fill=>:both, :expand=>true) +Tk.grid(tree, vsb, :in=>container, :sticky=>'nsew') +Tk.grid(hsb, :in=>container, :sticky=>'nsew') +container.grid_columnconfigure(0, :weight=>1) +container.grid_rowconfigure(0, :weight=>1) + +## The data we're going to insert +data = [ + ['アルゼンチン', 'ブエノスアイレス', 'ARS'], + ['オーストラリア', 'キャンベラ', 'AUD'], + ['ブラジル', 'ブラジリア', 'BRL'], + ['カナダ', 'オタワ', 'CAD'], + ['中国', '北京', 'CNY'], + ['フランス', 'パリ', 'EUR'], + ['ドイツ', 'ベルリン', 'EUR'], + ['インド', 'ニューデリー', 'INR'], + ['イタリア', 'ローマ', 'EUR'], + ['日本', '東京', 'JPY'], + ['メキシコ', 'メキシコシティ', 'MXN'], + ['ロシア', 'モスクワ', 'RUB'], + ['南アフリカ', 'プレトリア', 'ZAR'], + ['英国', 'ロンドン', 'GBP'], + ['アメリカ', 'ワシントン D.C.', 'USD'], +] + +## Code to insert the data nicely +font = Ttk::Style.lookup(tree[:style], :font) +cols = %w(country capital currency) +cols.zip(%w(国名 首都 通貨)).each{|col, name| + tree.heading_configure(col, :text=>name, + :command=>proc{sort_by(tree, col, false)}) + tree.column_configure(col, :width=>TkFont.measure(font, name)) +} + +data.each{|country, capital, currency| + #tree.insert('', :end, :values=>[country, capital, currency]) + tree.insert(nil, :end, :values=>[country, capital, currency]) + cols.zip([country, capital, currency]).each{|col, val| + len = TkFont.measure(font, "#{val} ") + if tree.column_cget(col, :width) < len + tree.column_configure(col, :width=>len) + end + } +} + +## Code to do the sorting of the tree contents when clicked on +def sort_by(tree, col, direction) + tree.children(nil).map!{|row| [tree.get(row, col), row.id]} . + sort(&((direction)? proc{|x, y| y <=> x}: proc{|x, y| x <=> y})) . + each_with_index{|info, idx| tree.move(info[1], nil, idx)} + + tree.heading_configure(col, :command=>proc{sort_by(tree, col, ! direction)}) +end diff --git a/ext/tk/sample/demos-jp/menu.rb b/ext/tk/sample/demos-jp/menu.rb index 6b9e5c9e5e..c3d95176b4 100644 --- a/ext/tk/sample/demos-jp/menu.rb +++ b/ext/tk/sample/demos-jp/menu.rb @@ -16,8 +16,10 @@ $menu_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($menu_demo).pack(:fill=>:both, :expand=>true) + # menu frame 生成 -$menu_frame = TkFrame.new($menu_demo, 'relief'=>'raised', 'bd'=>2) +$menu_frame = TkFrame.new(base_frame, 'relief'=>'raised', 'bd'=>2) $menu_frame.pack('side'=>'top', 'fill'=>'x') begin @@ -27,7 +29,7 @@ rescue end # label 生成 -TkLabel.new($menu_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { +TkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { if $tk_platform['platform'] == 'macintosh' || windowingsystem == "classic" || windowingsystem == "aqua" text("このウィンドウは様々なメニューとカスケードメニューから構成されています。Command-X を入力すると、Xがコマンドキー記号に続いて表示されている文字ならば、アクセラレータを使った項目起動を行うことができます。メニュー要素中、最後のものは、そのメニューの最初の項目を選択することで独立させることができます。") @@ -37,7 +39,7 @@ TkLabel.new($menu_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { }.pack('side'=>'top') # frame 生成 -TkFrame.new($menu_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -108,7 +110,8 @@ TkMenubutton.new($menu_frame, 'text'=>'Cascades', 'underline'=>0) {|m| 'accelerator'=>"#{modifier}+G", 'underline'=>6) $menu_demo.bind("#{modifier}-g", proc{print "Goodbye(さようなら)\n"}) - TkMenu.new(m, 'tearoff'=>false) {|cascade_check| + # TkMenu.new(m, 'tearoff'=>false) {|cascade_check| + TkMenu.new(cascade_menu, 'tearoff'=>false) {|cascade_check| cascade_menu.add('cascade', 'label'=>'Check buttons(チェックボタン)', 'menu'=>cascade_check, 'underline'=>0) oil = TkVariable.new(0) @@ -130,7 +133,8 @@ TkMenubutton.new($menu_frame, 'text'=>'Cascades', 'underline'=>0) {|m| invoke 3 } - TkMenu.new(m, 'tearoff'=>false) {|cascade_radio| + #TkMenu.new(m, 'tearoff'=>false) {|cascade_radio| + TkMenu.new(cascade_menu, 'tearoff'=>false) {|cascade_radio| cascade_menu.add('cascade', 'label'=>'Radio buttons(ラジオボタン)', 'menu'=>cascade_radio, 'underline'=>0) pointSize = TkVariable.new diff --git a/ext/tk/sample/demos-jp/menu84.rb b/ext/tk/sample/demos-jp/menu84.rb index 762cfa53b8..a631bacd43 100644 --- a/ext/tk/sample/demos-jp/menu84.rb +++ b/ext/tk/sample/demos-jp/menu84.rb @@ -16,6 +16,8 @@ $menu84_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($menu84_demo).pack(:fill=>:both, :expand=>true) + begin windowingsystem = Tk.windowingsystem() rescue @@ -23,7 +25,7 @@ rescue end # label -TkLabel.new($menu84_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { +TkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { if $tk_platform['platform'] == 'macintosh' || windowingsystem == "classic" || windowingsystem == "aqua" text("このウィンドウにはカスケードメニューを持つメニューバーが付けられています。Command+x ('x'はコマンドキーシンボルに続けて表示されている文字です) とタイプすることによっても項目の機能を呼び出すことができます。最後のメニューは、マウスでウィンドウの外にドラッグすることによって、独立したパレットとなるように切り放すことが可能です。") @@ -34,7 +36,7 @@ TkLabel.new($menu84_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { menustatus = TkVariable.new(" ") -TkFrame.new($menu84_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkLabel.new(frame, 'textvariable'=>menustatus, 'relief'=>'sunken', 'bd'=>1, 'font'=>['Helvetica', '10'], 'anchor'=>'w').pack('side'=>'left', 'padx'=>2, @@ -44,7 +46,7 @@ TkFrame.new($menu84_demo) {|frame| # frame -TkFrame.new($menu84_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' diff --git a/ext/tk/sample/demos-jp/menu8x.rb b/ext/tk/sample/demos-jp/menu8x.rb index 23efa7e790..9249f2491a 100644 --- a/ext/tk/sample/demos-jp/menu8x.rb +++ b/ext/tk/sample/demos-jp/menu8x.rb @@ -16,16 +16,18 @@ $menu8x_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($menu8x_demo).pack(:fill=>:both, :expand=>true) + # version check if $tk_version.to_f < 8.0 # label 生成 -TkLabel.new($menu8x_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { +TkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { text("実行しようとしたスクリプトは Tk8.0 以上で利用できる機能を利用しているため、あなたの Ruby#{VERSION}/Tk#{$tk_version}#{(Tk::JAPANIZED_TK)? 'jp': ''} では正常に実行できません。よってデモの実行を中止しました。ただし、下のコード参照ボタンを押すことで、実行が中止されたスクリプトのソースを参照することは可能です。") }.pack('side'=>'top') # frame 生成 -TkFrame.new($menu8x_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -51,7 +53,7 @@ rescue end # label 生成 -TkLabel.new($menu8x_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { +TkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { if $tk_platform['platform'] == 'macintosh' || windowingsystem == "classic" || windowingsystem == "aqua" text("このウィンドウは様々なメニューとカスケードメニューから構成されています。Command-X を入力すると、Xがコマンドキー記号に続いて表示されている文字ならば、アクセラレータを使った項目起動を行うことができます。メニュー要素中、最後のものは、そのメニューの最初の項目を選択することで独立させることができます。") @@ -62,14 +64,14 @@ TkLabel.new($menu8x_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { # 状態表示の生成 $menu8xstatus = TkVariable.new(" ") -TkFrame.new($menu8x_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkLabel.new(frame, 'textvariable'=>$menu8xstatus, 'relief'=>'sunken', 'bd'=>1, 'font'=>['Helvetica', '10'], 'anchor'=>'w')\ .pack('side'=>'left', 'padx'=>2, 'expand'=>'yes', 'fill'=>'both') }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>2) # frame 生成 -TkFrame.new($menu8x_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' diff --git a/ext/tk/sample/demos-jp/menubu.rb b/ext/tk/sample/demos-jp/menubu.rb index e73c393aa5..90dc367305 100644 --- a/ext/tk/sample/demos-jp/menubu.rb +++ b/ext/tk/sample/demos-jp/menubu.rb @@ -33,16 +33,18 @@ $menubu_demo = TkToplevel.new {|w| positionWindow($menubu_demo) +base_frame = TkFrame.new($menubu_demo).pack(:fill=>:both, :expand=>true) + # version check if $tk_version.to_f < 8.0 # label 生成 -TkLabel.new($menubu_demo,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { +TkLabel.new(base_frame,'font'=>$font,'wraplength'=>'4i','justify'=>'left') { text("実行しようとしたスクリプトは Tk8.0 以上で利用できる機能を利用しているため、あなたの Ruby#{VERSION}/Tk#{$tk_version}#{(Tk::JAPANIZED_TK)? 'jp': ''} では正常に実行できません。よってデモの実行を中止しました。ただし、下のコード参照ボタンを押すことで、実行が中止されたスクリプトのソースを参照することは可能です。") }.pack('side'=>'top') # frame 生成 -TkFrame.new($menubu_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -61,7 +63,7 @@ TkFrame.new($menubu_demo) {|frame| else ; # Tk8.x -body = TkFrame.new($menubu_demo) +body = TkFrame.new(base_frame) body.pack('expand'=>'yes', 'fill'=>'both') below = TkMenubutton.new(body) { @@ -156,7 +158,7 @@ center = TkFrame.new(body) { grid('row'=>1, 'column'=>1, 'sticky'=>'news') } -TkFrame.new($menubu_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' diff --git a/ext/tk/sample/demos-jp/msgbox.rb b/ext/tk/sample/demos-jp/msgbox.rb index 0fe5db7dd6..88380e08bd 100644 --- a/ext/tk/sample/demos-jp/msgbox.rb +++ b/ext/tk/sample/demos-jp/msgbox.rb @@ -16,12 +16,14 @@ $msgbox_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($msgbox_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -TkLabel.new($msgbox_demo, 'font'=>$font, 'wraplength'=>'4i', 'justify'=>'left', - 'text'=>"表示するアイコンとメッセージボックスの種類を選んで下さい。そして \"メッセージボックス\" ボタンを押すと、指定したメッセージボックスが表示されます。").pack('side'=>'top') +TkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'4i', 'justify'=>'left', + 'text'=>"まず表示するアイコンとメッセージボックスの種類を選んで下さい。その後に\"メッセージボックス\"ボタンを押すと、指定したメッセージボックスが表示されます。").pack('side'=>'top') # frame 生成 -TkFrame.new($msgbox_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -44,8 +46,8 @@ TkFrame.new($msgbox_demo) {|frame| }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # frame 生成 -$msgbox_leftframe = TkFrame.new($msgbox_demo) -$msgbox_rightframe = TkFrame.new($msgbox_demo) +$msgbox_leftframe = TkFrame.new(base_frame) +$msgbox_rightframe = TkFrame.new(base_frame) $msgbox_leftframe .pack('side'=>'left', 'expand'=>'yes', 'fill'=>'y', 'pady'=>'.5c', 'padx'=>'.5c') $msgbox_rightframe.pack('side'=>'left', 'expand'=>'yes', 'fill'=>'y', @@ -79,7 +81,7 @@ $msgboxType = TkVariable.new('ok') def showMessageBox(w) button = Tk.messageBox('icon'=>$msgboxIcon.value, 'type'=>$msgboxType.value, 'title'=>'Message', 'parent'=>w, - 'message'=>"これは \"#{$msgboxType.value}\" という種類のメッセージボックスで、\"#{$msgboxIcon.value}\" のアイコンが表示されています。") + 'message'=>"これは\"#{$msgboxType.value}\"という種類のメッセージボックスで、\"#{$msgboxIcon.value}\"のアイコンが表示されています。") Tk.messageBox('icon'=>'info', 'type'=>'ok', 'parent'=>w, 'message'=>"あなたは \"#{button}\" を押しましたね。") diff --git a/ext/tk/sample/demos-jp/msgbox2.rb b/ext/tk/sample/demos-jp/msgbox2.rb new file mode 100644 index 0000000000..d61f25129a --- /dev/null +++ b/ext/tk/sample/demos-jp/msgbox2.rb @@ -0,0 +1,90 @@ +# -*- coding: euc-jp -*- +# +# message boxes widget demo (called by 'widget') +# + +# toplevel widget が存在すれば削除する +if defined?($msgbox2_demo) && $msgbox2_demo + $msgbox2_demo.destroy + $msgbox2_demo = nil +end + +# demo 用の toplevel widget を生成 +$msgbox2_demo = TkToplevel.new {|w| + title("Message Box Demonstration") + iconname("messagebox") + positionWindow(w) +} + +base_frame = TkFrame.new($msgbox2_demo).pack(:fill=>:both, :expand=>true) + +# label 生成 +TkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'4i', 'justify'=>'left', + 'text'=>"まず表示するアイコンとメッセージボックスの種類を選んで下さい。その後に\"メッセージボックス\"ボタンを押すと、指定された形式で、メッセージと詳細テキストとを持ったメッセージボックスが表示されます。").pack('side'=>'top') + +# frame 生成 +TkFrame.new(base_frame) {|frame| + TkButton.new(frame) { + #text '了解' + text '閉じる' + command proc{ + tmppath = $msgbox2_demo + $msgbox2_demo = nil + tmppath.destroy + } + }.pack('side'=>'left', 'expand'=>'yes') + + TkButton.new(frame) { + text 'コード参照' + command proc{showCode 'msgbox2'} + }.pack('side'=>'left', 'expand'=>'yes') + + TkButton.new(frame) { + text 'メッセージボックス' + command proc{showMessageBox $msgbox2_demo} + }.pack('side'=>'left', 'expand'=>'yes') +}.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') + +# frame 生成 +$msgbox_leftframe = TkFrame.new(base_frame) +$msgbox_rightframe = TkFrame.new(base_frame) +$msgbox_leftframe .pack('side'=>'left', 'expand'=>'yes', 'fill'=>'y', + 'pady'=>'.5c', 'padx'=>'.5c') +$msgbox_rightframe.pack('side'=>'left', 'expand'=>'yes', 'fill'=>'y', + 'pady'=>'.5c', 'padx'=>'.5c') + +TkLabel.new($msgbox_leftframe, 'text'=>'アイコン').pack('side'=>'top') +TkFrame.new($msgbox_leftframe, 'relief'=>'ridge', 'bd'=>1, 'height'=>2)\ +.pack('side'=>'top', 'fill'=>'x', 'expand'=>'no') + +$msgboxIcon = TkVariable.new('info') +['error', 'info', 'question', 'warning'].each {|icon| + TkRadioButton.new($msgbox_leftframe, 'text'=>icon, 'variable'=>$msgboxIcon, + 'relief'=>'flat', 'value'=>icon, 'width'=>16, + 'anchor'=>'w').pack('side'=>'top', 'pady'=>2, + 'anchor'=>'w', 'fill'=>'x') +} + +TkLabel.new($msgbox_rightframe, 'text'=>'種類').pack('side'=>'top') +TkFrame.new($msgbox_rightframe, 'relief'=>'ridge', 'bd'=>1, 'height'=>2)\ +.pack('side'=>'top', 'fill'=>'x', 'expand'=>'no') + +$msgboxType = TkVariable.new('ok') +['abortretryignore', 'ok', 'okcancel', + 'retrycancel', 'yesno', 'yesnocancel'].each {|type| + TkRadioButton.new($msgbox_rightframe, 'text'=>type, 'variable'=>$msgboxType, + 'relief'=>'flat', 'value'=>type, 'width'=>16, + 'anchor'=>'w').pack('side'=>'top', 'pady'=>2, + 'anchor'=>'w', 'fill'=>'x') +} + +def showMessageBox(w) + button = Tk.messageBox('icon'=>$msgboxIcon.value, 'type'=>$msgboxType.value, + 'title'=>'Message', 'parent'=>w, + 'message'=>"\"#{$msgboxType.value}\"タイプのメッセージボックス", + 'detail'=>"これは\"#{$msgboxType.value}\"という種類のメッセージボックスで、\"#{$msgboxIcon.value}\"のアイコンが表示されています。下のボタンのいずれかを選択してクリックしてください。") + + Tk.messageBox('icon'=>'info', 'type'=>'ok', 'parent'=>w, + 'message'=>"あなたは \"#{button}\" を押しましたね。") +end + diff --git a/ext/tk/sample/demos-jp/paned1.rb b/ext/tk/sample/demos-jp/paned1.rb index 137e187417..f994e83ff1 100644 --- a/ext/tk/sample/demos-jp/paned1.rb +++ b/ext/tk/sample/demos-jp/paned1.rb @@ -18,7 +18,9 @@ $paned1_demo = TkToplevel.new {|w| positionWindow(w) } -TkLabel.new($paned1_demo, +base_frame = TkFrame.new($paned1_demo).pack(:fill=>:both, :expand=>true) + +TkLabel.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, :text=><:top) 下の色付けされた二つのウィンドウの間の仕切り枠は、一つの領域をそれぞれのウィンドウのために分割するためのものです。左ボタンで仕切りを操作すると、分割サイズ変更の操作途中では再表示はなされず、確定させたときに表示が更新されます。マウスによる仕切りの操作に追随してサイズを変更した表示がなわれるようにしたい場合は、マウスの中央ボタンを使ってください。 @@ -29,7 +31,7 @@ TkLabel.new($paned1_demo, EOL # The bottom buttons -TkFrame.new($paned1_demo){|f| +TkFrame.new(base_frame){|f| pack(:side=>:bottom, :fill=>:x, :pady=>'2m') TkButton.new(f, :text=>'閉じる', :width=>15, :command=>proc{ @@ -42,9 +44,9 @@ TkFrame.new($paned1_demo){|f| }).pack(:side=>:left, :expand=>true) } -TkPanedwindow.new($paned1_demo){|f| - pack(:side=>:top, :expand=>true, :fill=>:both, :pady=>2, :padx=>'2m') +TkPanedwindow.new(base_frame, :orient=>:horizontal){|f| + add(Tk::Label.new(f, :text=>"This is the\nleft side", :bg=>'yellow'), + Tk::Label.new(f, :text=>"This is the\nright side", :bg=>'cyan')) - add(TkLabel.new(f, :text=>"This is the\nleft side", :bg=>'yellow'), - TkLabel.new(f, :text=>"This is the\nright side", :bg=>'cyan')) + pack(:side=>:top, :expand=>true, :fill=>:both, :pady=>2, :padx=>'2m') } diff --git a/ext/tk/sample/demos-jp/paned2.rb b/ext/tk/sample/demos-jp/paned2.rb index b394432b1c..cdc8253402 100644 --- a/ext/tk/sample/demos-jp/paned2.rb +++ b/ext/tk/sample/demos-jp/paned2.rb @@ -18,7 +18,9 @@ $paned2_demo = TkToplevel.new {|w| positionWindow(w) } -TkLabel.new($paned2_demo, +base_frame = TkFrame.new($paned2_demo).pack(:fill=>:both, :expand=>true) + +TkLabel.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, :text=><:top) 下のスクロールバー付きのウィジェットが置かれた二つのウィンドウの間の仕切り枠は、一つの領域をそれぞれのウィンドウのために分割するためのものです。左ボタンで仕切りを操作すると、分割サイズ変更の操作途中では再表示はなされず、確定させたときに表示が更新されます。マウスによる仕切りの操作に追随してサイズを変更した表示がなわれるようにしたい場合は、マウスの中央ボタンを使ってください。 @@ -29,7 +31,7 @@ TkLabel.new($paned2_demo, EOL # The bottom buttons -TkFrame.new($paned2_demo){|f| +TkFrame.new(base_frame){|f| pack(:side=>:bottom, :fill=>:x, :pady=>'2m') TkButton.new(f, :text=>'閉じる', :width=>15, :command=>proc{ @@ -66,7 +68,7 @@ paneList.value = [ # ruby's array --> tcl's list ] # Create the pane itself -TkPanedwindow.new($paned2_demo, :orient=>:vertical){|f| +TkPanedwindow.new(base_frame, :orient=>:vertical){|f| pack(:side=>:top, :expand=>true, :fill=>:both, :pady=>2, :padx=>'2m') add(TkFrame.new(f){|paned2_top| diff --git a/ext/tk/sample/demos-jp/pendulum.rb b/ext/tk/sample/demos-jp/pendulum.rb index e19b57a2d6..b115f5be2c 100644 --- a/ext/tk/sample/demos-jp/pendulum.rb +++ b/ext/tk/sample/demos-jp/pendulum.rb @@ -19,8 +19,10 @@ $pendulum_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($pendulum_demo).pack(:fill=>:both, :expand=>true) + # create label -msg = TkLabel.new($pendulum_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -29,7 +31,7 @@ msg = TkLabel.new($pendulum_demo) { msg.pack('side'=>'top') # create frame -TkFrame.new($pendulum_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -51,7 +53,7 @@ TkFrame.new($pendulum_demo) {|frame| class PendulumAnimationDemo def initialize(frame) # Create some structural widgets - @pane = TkPanedWindow.new(frame).pack(:fill=>:both, :expand=>true) + @pane = TkPanedWindow.new(frame, :orient=>:horizontal).pack(:fill=>:both, :expand=>true) # @pane.add(@lf1 = TkLabelFrame.new(@pane, :text=>'Pendulum Simulation')) # @pane.add(@lf2 = TkLabelFrame.new(@pane, :text=>'Phase Space')) @lf1 = TkLabelFrame.new(@pane, :text=>'Pendulum Simulation') @@ -237,4 +239,4 @@ class PendulumAnimationDemo end # Start the animation processing -PendulumAnimationDemo.new($pendulum_demo) +PendulumAnimationDemo.new(base_frame) diff --git a/ext/tk/sample/demos-jp/plot.rb b/ext/tk/sample/demos-jp/plot.rb index dbca3e971c..9ff71904cd 100644 --- a/ext/tk/sample/demos-jp/plot.rb +++ b/ext/tk/sample/demos-jp/plot.rb @@ -16,14 +16,16 @@ $plot_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($plot_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -TkLabel.new($plot_demo, 'font'=>$font, 'wraplength'=>'4i', 'justify'=>'left', +TkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'4i', 'justify'=>'left', 'text'=>"このウィンドウは簡単な2次元のプロットを含んだキャンバス widgetです。表示された点をマウスボタン1でドラッグしてデータをいじることができます。"){ pack('side'=>'top') } # frame 生成 -$plot_buttons = TkFrame.new($plot_demo) {|frame| +$plot_buttons = TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -49,7 +51,7 @@ $plot_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') end # canvas 設定 -$plot_canvas = TkCanvas.new($plot_demo,'relief'=>'raised','width'=>450,'height'=>300) +$plot_canvas = TkCanvas.new(base_frame,'relief'=>'raised','width'=>450,'height'=>300) $plot_canvas.pack('side'=>'top', 'fill'=>'x') # plot 生成 diff --git a/ext/tk/sample/demos-jp/puzzle.rb b/ext/tk/sample/demos-jp/puzzle.rb index 6a3c8c8ef6..2febc2c55a 100644 --- a/ext/tk/sample/demos-jp/puzzle.rb +++ b/ext/tk/sample/demos-jp/puzzle.rb @@ -16,8 +16,10 @@ $puzzle_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($puzzle_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -msg = TkLabel.new($puzzle_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -26,7 +28,7 @@ msg = TkLabel.new($puzzle_demo) { msg.pack('side'=>'top') # frame 生成 -TkFrame.new($puzzle_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -51,18 +53,27 @@ TkFrame.new($puzzle_demo) {|frame| # begin if Tk.windowingsystem() == 'aqua' - frameSize = 160 + frameWidth = 168 + frameHeight = 168 + elsif Tk.default_widget_set == :Ttk + frameWidth = 148 + frameHeight = 124 else - frameSize = 120 + frameWidth = 120 + frameHeight = 120 end rescue - frameSize = 120 + frameWidth = 120 + frameHeight = 120 end + +# depend_on_button_width = true +depend_on_button_width = false -s = TkScrollbar.new($puzzle_demo) -base = TkFrame.new($puzzle_demo) { - width frameSize - height frameSize +s = TkScrollbar.new(base_frame) +base = TkFrame.new(base_frame) { + width frameWidth + height frameHeight borderwidth 2 relief 'sunken' bg s['troughcolor'] @@ -89,6 +100,9 @@ order = [3,1,6,2,5,7,15,13,4,11,8,9,14,10,12] text num highlightthickness 0 command def_puzzleswitch_proc(w, num) + if depend_on_button_width && (w.winfo_reqwidth * 4 > base.width) + base.width = w.winfo_reqwidth * 4 + end }.place('relx'=>$xpos[num], 'rely'=>$ypos[num], 'relwidth'=>0.25, 'relheight'=>0.25) } diff --git a/ext/tk/sample/demos-jp/radio.rb b/ext/tk/sample/demos-jp/radio.rb index 3a11c394a3..a61ad46d9b 100644 --- a/ext/tk/sample/demos-jp/radio.rb +++ b/ext/tk/sample/demos-jp/radio.rb @@ -16,8 +16,10 @@ $radio_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($radio_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -msg = TkLabel.new($radio_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -30,7 +32,7 @@ size = TkVariable.new color = TkVariable.new # frame 生成 -TkFrame.new($radio_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -50,14 +52,14 @@ TkFrame.new($radio_demo) {|frame| TkButton.new(frame) { text '変数参照' command proc{ - showVars($radio_demo, ['size', size], ['color', color]) + showVars(base_frame, ['size', size], ['color', color]) } }.pack('side'=>'left', 'expand'=>'yes') }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # frame 生成 -f_left = TkFrame.new($radio_demo) -f_right = TkFrame.new($radio_demo) +f_left = TkFrame.new(base_frame) +f_right = TkFrame.new(base_frame) f_left.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'.5c', 'pady'=>'.5c') f_right.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'.5c', 'pady'=>'.5c') diff --git a/ext/tk/sample/demos-jp/radio2.rb b/ext/tk/sample/demos-jp/radio2.rb index b89520cdc5..cf53e3e485 100644 --- a/ext/tk/sample/demos-jp/radio2.rb +++ b/ext/tk/sample/demos-jp/radio2.rb @@ -21,8 +21,10 @@ $radio2_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($radio2_demo).pack(:fill=>:both, :expand=>true) + # label -msg = TkLabel.new($radio2_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '5i' justify 'left' @@ -36,7 +38,7 @@ color = TkVariable.new align = TkVariable.new # frame -TkFrame.new($radio2_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -56,18 +58,18 @@ TkFrame.new($radio2_demo) {|frame| TkButton.new(frame) { text '変数参照' command proc{ - showVars($radio2_demo, + showVars(base_frame, ['size', size], ['color', color], ['compound', align]) } }.pack('side'=>'left', 'expand'=>'yes') }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # frame -f_left = TkLabelFrame.new($radio2_demo, 'text'=>'文字サイズ', +f_left = TkLabelFrame.new(base_frame, 'text'=>'文字サイズ', 'pady'=>2, 'padx'=>2) -f_mid = TkLabelFrame.new($radio2_demo, 'text'=>'色', +f_mid = TkLabelFrame.new(base_frame, 'text'=>'色', 'pady'=>2, 'padx'=>2) -f_right = TkLabelFrame.new($radio2_demo, 'text'=>'ビットマップ配置', +f_right = TkLabelFrame.new(base_frame, 'text'=>'ビットマップ配置', 'pady'=>2, 'padx'=>2) f_left.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'.5c', 'pady'=>'.5c') f_mid.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'.5c', 'pady'=>'.5c') @@ -93,7 +95,8 @@ f_right.pack('side'=>'left', 'expand'=>'yes', 'padx'=>'.5c', 'pady'=>'.5c') }.pack('side'=>'top', 'pady'=>2, 'fill'=>'x') } -label = TkLabel.new(f_right, 'text'=>'ラベル', 'bitmap'=>'questhead', +# label = TkLabel.new(f_right, 'text'=>'ラベル', 'bitmap'=>'questhead', +label = Tk::Label.new(f_right, 'text'=>'ラベル', 'bitmap'=>'questhead', 'compound'=>'left') label.configure('width'=>TkWinfo.reqwidth(label), 'compound'=>'top') label.height(TkWinfo.reqheight(label)) diff --git a/ext/tk/sample/demos-jp/radio3.rb b/ext/tk/sample/demos-jp/radio3.rb index a223a19bc2..4bbc1b31f5 100644 --- a/ext/tk/sample/demos-jp/radio3.rb +++ b/ext/tk/sample/demos-jp/radio3.rb @@ -21,8 +21,10 @@ $radio3_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($radio3_demo).pack(:fill=>:both, :expand=>true) + # label -msg = TkLabel.new($radio3_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '5i' justify 'left' @@ -36,14 +38,14 @@ color = TkVariable.new align = TkVariable.new # frame -TkFrame.new($radio3_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkGrid(TkFrame.new(frame, :height=>2, :relief=>:sunken, :bd=>2), :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) TkGrid('x', TkButton.new(frame, :text=>'変数参照', :image=>$image['view'], :compound=>:left, :command=>proc{ - showVars($radio3_demo, ['size', size], + showVars(base_frame, ['size', size], ['color', color], ['compound', align]) }), TkButton.new(frame, :text=>'コード参照', @@ -63,17 +65,17 @@ TkFrame.new($radio3_demo) {|frame| } # frame -f_left = TkLabelFrame.new($radio3_demo, 'text'=>'文字サイズ', +f_left = TkLabelFrame.new(base_frame, 'text'=>'文字サイズ', 'pady'=>2, 'padx'=>2) -f_mid = TkLabelFrame.new($radio3_demo, 'text'=>'色', +f_mid = TkLabelFrame.new(base_frame, 'text'=>'色', 'pady'=>2, 'padx'=>2) -f_right = TkLabelFrame.new($radio3_demo, 'text'=>'ビットマップ配置', +f_right = TkLabelFrame.new(base_frame, 'text'=>'ビットマップ配置', 'pady'=>2, 'padx'=>2) f_left .grid('column'=>0, 'row'=>1, 'pady'=>'.5c', 'padx'=>'.5c', 'rowspan'=>2) f_mid .grid('column'=>1, 'row'=>1, 'pady'=>'.5c', 'padx'=>'.5c', 'rowspan'=>2) f_right.grid('column'=>2, 'row'=>1, 'pady'=>'.5c', 'padx'=>'.5c') -TkButton.new($radio3_demo, 'text'=>'トライステート', +TkButton.new(base_frame, 'text'=>'トライステート', 'command'=>proc{size.value = 'multi'; color.value = 'multi'}){ grid('column'=>2, 'row'=>2, 'pady'=>'.5c', 'padx'=>'.5c') } @@ -101,7 +103,8 @@ TkButton.new($radio3_demo, 'text'=>' }.pack('side'=>'top', 'pady'=>2, 'fill'=>'x') } -label = TkLabel.new(f_right, 'text'=>'ラベル', 'bitmap'=>'questhead', +# label = TkLabel.new(f_right, 'text'=>'ラベル', 'bitmap'=>'questhead', +label = Tk::Label.new(f_right, 'text'=>'ラベル', 'bitmap'=>'questhead', 'compound'=>'left') label.configure('width'=>TkWinfo.reqwidth(label), 'compound'=>'top') label.height(TkWinfo.reqheight(label)) diff --git a/ext/tk/sample/demos-jp/ruler.rb b/ext/tk/sample/demos-jp/ruler.rb index c913e247d1..d6bc9e76d1 100644 --- a/ext/tk/sample/demos-jp/ruler.rb +++ b/ext/tk/sample/demos-jp/ruler.rb @@ -29,14 +29,16 @@ $ruler_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($ruler_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -TkLabel.new($ruler_demo, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', +TkLabel.new(base_frame, 'font'=>$font, 'wraplength'=>'5i', 'justify'=>'left', 'text'=>"このキャンバスwidgetはルーラーの模型です。ルーラーの右にあるのはタブストップの井戸で、ここから引っ張ってくることによってタブストップを作ることができます。また、すでにあるタブストップを動かすこともできます。タブストップを上方または下方にかすれて表示されるまでドラッグすると、マウスボタンを離した時にそのタブストップは消えます。"){ pack('side'=>'top') } # frame 生成 -$ruler_buttons = TkFrame.new($ruler_demo) {|frame| +$ruler_buttons = TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -55,7 +57,7 @@ $ruler_buttons = TkFrame.new($ruler_demo) {|frame| $ruler_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # canvas 設定 -$ruler_canvas = TkCanvas.new($ruler_demo, 'width'=>'14.8c', 'height'=>'2.5c') +$ruler_canvas = TkCanvas.new(base_frame, 'width'=>'14.8c', 'height'=>'2.5c') $ruler_canvas.pack('side'=>'top', 'fill'=>'x') # 値設定 diff --git a/ext/tk/sample/demos-jp/sayings.rb b/ext/tk/sample/demos-jp/sayings.rb index 24b011f5ab..aa24b3a2ad 100644 --- a/ext/tk/sample/demos-jp/sayings.rb +++ b/ext/tk/sample/demos-jp/sayings.rb @@ -16,8 +16,10 @@ $sayings_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($sayings_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -msg = TkLabel.new($sayings_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -26,7 +28,7 @@ msg = TkLabel.new($sayings_demo) { msg.pack('side'=>'top') # frame 生成 -TkFrame.new($sayings_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -46,7 +48,7 @@ TkFrame.new($sayings_demo) {|frame| # frame 生成 sayings_lbox = nil -TkFrame.new($sayings_demo, 'borderwidth'=>10) {|w| +TkFrame.new(base_frame, 'borderwidth'=>10) {|w| sv = TkScrollbar.new(w) sh = TkScrollbar.new(w, 'orient'=>'horizontal') sayings_lbox = TkListbox.new(w) { diff --git a/ext/tk/sample/demos-jp/search.rb b/ext/tk/sample/demos-jp/search.rb index d3692e2455..9838ff5d19 100644 --- a/ext/tk/sample/demos-jp/search.rb +++ b/ext/tk/sample/demos-jp/search.rb @@ -75,8 +75,10 @@ $search_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($search_demo).pack(:fill=>:both, :expand=>true) + # frame 生成 -$search_buttons = TkFrame.new($search_demo) {|frame| +$search_buttons = TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -95,7 +97,7 @@ $search_buttons = TkFrame.new($search_demo) {|frame| $search_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # frame 生成 -TkFrame.new($search_demo) {|f| +TkFrame.new(base_frame) {|f| TkLabel.new(f, 'text'=>'ファイル名:', 'width'=>13, 'anchor'=>'w').pack('side'=>'left') $search_fileName = TkVariable.new @@ -112,7 +114,7 @@ TkFrame.new($search_demo) {|f| .pack('side'=>'left', 'pady'=>5, 'padx'=>10) }.pack('side'=>'top', 'fill'=>'x') -TkFrame.new($search_demo) {|f| +TkFrame.new(base_frame) {|f| TkLabel.new(f, 'text'=>'検索文字列:', 'width'=>13, 'anchor'=>'w').pack('side'=>'left') $search_searchString = TkVariable.new @@ -130,9 +132,9 @@ TkFrame.new($search_demo) {|f| } }.pack('side'=>'top', 'fill'=>'x') -$search_text = TkText.new($search_demo, 'setgrid'=>true) {|t| +$search_text = TkText.new(base_frame, 'setgrid'=>true) {|t| $search_Tag = TkTextTag.new(t) - TkScrollbar.new($search_demo, 'command'=>proc{|*args| t.yview(*args)}) {|sc| + TkScrollbar.new(base_frame, 'command'=>proc{|*args| t.yview(*args)}) {|sc| t.yscrollcommand(proc{|first,last| sc.set first,last}) pack('side'=>'right', 'fill'=>'y') } diff --git a/ext/tk/sample/demos-jp/spin.rb b/ext/tk/sample/demos-jp/spin.rb index b8eb99c4ed..8d4e33cda0 100644 --- a/ext/tk/sample/demos-jp/spin.rb +++ b/ext/tk/sample/demos-jp/spin.rb @@ -17,10 +17,12 @@ $spin_demo = TkToplevel.new {|w| positionWindow(w) } -TkLabel.new($spin_demo, +base_frame = TkFrame.new($spin_demo).pack(:fill=>:both, :expand=>true) + +TkLabel.new(base_frame, :font=>$font, :wraplength=>'5i', :justify=>:left, :text=><:top) -下には3種類のスピンボックスが表示されています。\ +下には3種類のスピンボックスが表示されています。 それぞれ、マウスで選択して文字を入力することができます。 編集操作としては、Emacs 形式の多くに加えて、一般的な Motif 形式のキー操作がサポートされています。たとえば、 @@ -40,7 +42,7 @@ Backspace を組み合わせて試すようにしてください。 EOL -TkFrame.new($spin_demo){|f| +TkFrame.new(base_frame){|f| pack(:side=>:bottom, :fill=>:x, :pady=>'2m') TkButton.new(f, :text=>'閉じる', :width=>15, :command=>proc{ @@ -59,11 +61,11 @@ australianCities = [ ] [ - TkSpinbox.new($spin_demo, :from=>1, :to=>10, :width=>10, :validate=>:key, + TkSpinbox.new(base_frame, :from=>1, :to=>10, :width=>10, :validate=>:key, :validatecommand=>[ proc{|s| s == '' || /^[+-]?\d+$/ =~ s }, '%P' ]), - TkSpinbox.new($spin_demo, :from=>0, :to=>3, :increment=>0.5, + TkSpinbox.new(base_frame, :from=>0, :to=>3, :increment=>0.5, :format=>'%05.2f', :width=>10), - TkSpinbox.new($spin_demo, :values=>australianCities, :width=>10) + TkSpinbox.new(base_frame, :values=>australianCities, :width=>10) ].each{|sbox| sbox.pack(:side=>:top, :pady=>5, :padx=>10)} diff --git a/ext/tk/sample/demos-jp/states.rb b/ext/tk/sample/demos-jp/states.rb index 3c58711bd1..5e242b7c38 100644 --- a/ext/tk/sample/demos-jp/states.rb +++ b/ext/tk/sample/demos-jp/states.rb @@ -16,8 +16,10 @@ $states_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($states_demo).pack(:fill=>:both, :expand=>true) + # label 生成 -msg = TkLabel.new($states_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -26,7 +28,7 @@ msg = TkLabel.new($states_demo) { msg.pack('side'=>'top') # frame 生成 -TkFrame.new($states_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -46,7 +48,7 @@ TkFrame.new($states_demo) {|frame| # frame 生成 states_lbox = nil -TkFrame.new($states_demo, 'borderwidth'=>'.5c') {|w| +TkFrame.new(base_frame, 'borderwidth'=>'.5c') {|w| s = TkScrollbar.new(w) states_lbox = TkListbox.new(w) { setgrid 1 diff --git a/ext/tk/sample/demos-jp/style.rb b/ext/tk/sample/demos-jp/style.rb index 7a8497f1b2..66b6de0251 100644 --- a/ext/tk/sample/demos-jp/style.rb +++ b/ext/tk/sample/demos-jp/style.rb @@ -17,9 +17,10 @@ $style_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($style_demo).pack(:fill=>:both, :expand=>true) # frame 生成 -TkFrame.new($style_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -38,14 +39,14 @@ TkFrame.new($style_demo) {|frame| # text 生成 -txt = TkText.new($style_demo){|t| +txt = TkText.new(base_frame){|t| # 生成 setgrid 'true' #width 70 #height 32 wrap 'word' font $font - TkScrollbar.new($style_demo) {|s| + TkScrollbar.new(base_frame) {|s| pack('side'=>'right', 'fill'=>'y') command proc{|*args| t.yview(*args)} t.yscrollcommand proc{|first,last| s.set first,last} diff --git a/ext/tk/sample/demos-jp/text.rb b/ext/tk/sample/demos-jp/text.rb index 25e0e64e9a..0ae480eb00 100644 --- a/ext/tk/sample/demos-jp/text.rb +++ b/ext/tk/sample/demos-jp/text.rb @@ -16,6 +16,8 @@ $text_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($text_demo).pack(:fill=>:both, :expand=>true) + # version check if ((Tk::TK_VERSION.split('.').collect{|n| n.to_i} <=> [8,4]) < 0) undo_support = false @@ -24,7 +26,7 @@ else end # frame 生成 -TkFrame.new($text_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -42,13 +44,13 @@ TkFrame.new($text_demo) {|frame| }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # text 生成 -TkText.new($text_demo){|t| +TkText.new(base_frame){|t| # 生成 relief 'sunken' bd 2 setgrid 1 height 30 - TkScrollbar.new($text_demo) {|s| + TkScrollbar.new(base_frame) {|s| pack('side'=>'right', 'fill'=>'y') command proc{|*args| t.yview(*args)} t.yscrollcommand proc{|first,last| s.set first,last} diff --git a/ext/tk/sample/demos-jp/textpeer.rb b/ext/tk/sample/demos-jp/textpeer.rb index 9b2b57a698..4967a99c92 100644 --- a/ext/tk/sample/demos-jp/textpeer.rb +++ b/ext/tk/sample/demos-jp/textpeer.rb @@ -16,10 +16,12 @@ $textpeer_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($textpeer_demo).pack(:fill=>:both, :expand=>true) + count = [0] ## Define a widget that we peer from; it won't ever actually be shown though -first = TkText.new($textpeer_demo, :widgetname=>"text#{count[0] += 1}") +first = TkText.new(base_frame, :widgetname=>"text#{count[0] += 1}") first.insert :end,"このデモは一つの組を成したテキストウィジェットを示します。" first.insert :end,"それらのテキストウィジェットは対等(ピア;peer)の関係に" first.insert :end,"なっています。" @@ -32,6 +34,8 @@ first.insert :end," first.insert :end,"また「ピア(peer)の消去」ボタンを使えば、" first.insert :end,"特定のピアウィジェットを消去することもできます。" +Tk.update_idletasks ## for 'first' widget + ## Procedures to make and kill clones; most of this is just so that the demo ## looks nice... def makeClone(count, win, txt) @@ -58,12 +62,12 @@ def killClone(win, cnt) end ## Now set up the GUI -makeClone(count, $textpeer_demo, first) -makeClone(count, $textpeer_demo, first) +makeClone(count, base_frame, first) +makeClone(count, base_frame, first) first.destroy ## See Code / Dismiss buttons -TkFrame.new($textpeer_demo){|f| +TkFrame.new(base_frame){|f| TkButton.new(f, :text=>'閉じる', :width=>15, :command=>proc{ $textpeer_demo.destroy $textpeer_demo = nil @@ -75,4 +79,4 @@ TkFrame.new($textpeer_demo){|f| TkGrid.configure(f, '-', '-', :sticky=>'ew', :row=>5000) } -TkGrid.columnconfigure($textpeer_demo, 0, :weight=>1) +TkGrid.columnconfigure(base_frame, 0, :weight=>1) diff --git a/ext/tk/sample/demos-jp/toolbar.rb b/ext/tk/sample/demos-jp/toolbar.rb new file mode 100644 index 0000000000..9cb3834c34 --- /dev/null +++ b/ext/tk/sample/demos-jp/toolbar.rb @@ -0,0 +1,136 @@ +# -*- coding: euc-jp -*- +# +# toolbar.rb -- +# +# This demonstration script creates a toolbar that can be torn off. +# +# based on "Id: toolbar.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp" + +if defined?($toolbar_demo) && $toolbar_demo + $toolbar_demo.destroy + $toolbar_demo = nil +end + +$toolbar_demo = TkToplevel.new {|w| + title("Ttk Menu Buttons") + iconname("toolbar") + positionWindow(w) +} + +base_frame = Ttk::Frame.new($toolbar_demo).pack(:fill=>:both, :expand=>true) + +if Tk.windowingsystem != 'aqua' + msg = Ttk::Label.new(base_frame, :wraplength=>'4i', :text=><'4i', :text=><'toolbar') # ウィンドウタイトル文字列とするために,ウィジェット名を明示しています. +sep = Ttk::Separator.new(base_frame) +to_base = Ttk::Frame.new(tbar_base, :cursor=>'fleur') +if Tk.windowingsystem != 'aqua' + to = Ttk::Separator.new(to_base, :orient=>:vertical) + to2 = Ttk::Separator.new(to_base, :orient=>:vertical) + to.pack(:fill=>:y, :expand=>true, :padx=>2, :side=>:left) + to2.pack(:fill=>:y, :expand=>true, :side=>:left) +end + +contents = Ttk::Frame.new(tbar_base) +Tk.grid(to_base, contents, :sticky=>'nsew') +tbar_base.grid_columnconfigure(contents, :weight=>1) +contents.grid_columnconfigure(1000, :weight=>1) + +if Tk.windowingsystem != 'aqua' + ## Bindings so that the toolbar can be torn off and reattached + to_base.bind('B1-Motion', '%X %Y'){|x, y| tbar_base.tearoff(to_base, x, y)} + to. bind('B1-Motion', '%X %Y'){|x, y| tbar_base.tearoff(to_base, x, y)} + to2. bind('B1-Motion', '%X %Y'){|x, y| tbar_base.tearoff(to_base, x, y)} + def tbar_base.tearoff(w, x, y) + on_win = TkWinfo.containing(x, y) + return unless (on_win && on_win.path =~ /^#{@path}(\.|$)/) + self.grid_remove + w.grid_remove + self.wm_manage + # self.wm_title('Toolbar') # もしウィジェット名をウィンドウタイトルにしたくないなら,ここで設定してください + self.wm_protocol('WM_DELETE_WINDOW'){ self.untearoff(self) } + end + def tbar_base.untearoff(w) + self.wm_forget + w.grid + self.grid + end +end + +## Some content for the rest of the toplevel +text = TkText.new(base_frame, :width=>40, :height=>10) + +## Toolbar contents +tb_btn = Ttk::Button.new(tbar_base, :text=>'ボタン', :style=>'Toolbutton', + :command=>proc{ + text.insert(:end, "ボタンが押されました.\n") + }) +tb_chk = Ttk::Checkbutton.new(tbar_base, :text=>'チェックボタン', + :style=>'Toolbutton', + :variable=>(check = TkVariable.new), + :command=>proc{ + text.insert(:end, "チェックボタンの値は#{check.value}です.\n") + }) +tb_mbtn = Ttk::Menubutton.new(tbar_base, :text=>'メニュー') +tb_combo = Ttk::Combobox.new(tbar_base, :value=>TkFont.families, + :state=>:readonly) +tb_mbtn.menu(menu = Tk::Menu.new(tb_mbtn)) +menu.add(:command, :label=>'Just', :command=>proc{text.insert(:end, "Just\n")}) +menu.add(:command, :label=>'An', :command=>proc{text.insert(:end, "An\n")}) +menu.add(:command, :label=>'Example', + :command=>proc{text.insert(:end, "Example\n")}) +tb_combo.bind(''){ text.font.family = tb_combo.get } + +## Arrange contents +Tk.grid(tb_btn, tb_chk, tb_mbtn, tb_combo, + :in=>contents, :padx=>2, :sticky=>'ns') +Tk.grid(tbar_base, :sticky=>'ew') +Tk.grid(sep, :sticky=>'ew') +Tk.grid(msg, :sticky=>'ew') +Tk.grid(text, :sticky=>'nsew') +base_frame.grid_rowconfigure(text, :weight=>1) +base_frame.grid_columnconfigure(text, :weight=>1) + +## See Code / Dismiss buttons +Ttk::Frame.new(base_frame) {|frame| + sep = Ttk::Separator.new(frame) + Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + Ttk::Button.new(frame, :text=>'コード参照', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'toolbar'}), + Ttk::Button.new(frame, :text=>'閉じる', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + $toolbar_demo.destroy + $toolbar_demo = nil + }), + :padx=>4, :pady=>4) + grid_columnconfigure(0, :weight=>1) + Tk.grid(frame, :sticky=>'ew') +} diff --git a/ext/tk/sample/demos-jp/tree.rb b/ext/tk/sample/demos-jp/tree.rb new file mode 100644 index 0000000000..c3b4191144 --- /dev/null +++ b/ext/tk/sample/demos-jp/tree.rb @@ -0,0 +1,120 @@ +# -*- coding: euc-jp -*- +# +# tree.rb -- +# +# This demonstration script creates a toplevel window containing a Ttk +# tree widget. +# +# based on "Id: tree.tcl,v 1.4 2007/12/13 15:27:07 dgp Exp" + +if defined?($tree_demo) && $tree_demo + $tree_demo.destroy + $tree_demo = nil +end + +$tree_demo = TkToplevel.new {|w| + title("Directory Browser") + iconname("tree") + positionWindow(w) +} + +base_frame = TkFrame.new($tree_demo).pack(:fill=>:both, :expand=>true) + +## Explanatory text +Ttk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', + :justify=>:left, :anchor=>'n', :padding=>[10, 2, 10, 6], + :text=><:x) +Ttkとは,テーマ指定可能な新しいウィジェット集合です.\ +このサンプルは,ファイルシステムのような階層的なデータ集合を\ +参照できるようにしたTtk::Treeviewウィジェットを含んでいます.\ +Ttk::Treeviewウィジェットは,木構造自体の表示を可能にするだけでなく,\ +追加情報(このサンプルの場合はファイルサイズ)を表示するために\ +任意の個数の追加カラムも扱うこともできます.\ +また,カラムのタイトル間の区切り部分をドラッグすることで,\ +カラムの幅を変更することも可能です. +EOL + +## See Code / Dismiss +Ttk::Frame.new(base_frame) {|frame| + sep = Ttk::Separator.new(frame) + Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + Ttk::Button.new(frame, :text=>'コード参照', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'tree'}), + Ttk::Button.new(frame, :text=>'閉じる', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + $tree_demo.destroy + $tree_demo = nil + }), + :padx=>4, :pady=>4) + grid_columnconfigure(0, :weight=>1) + pack(:side=>:bottom, :fill=>:x) +} + +## Code to populate the roots of the tree (can be more than one on Windows) +def populate_roots(tree) + TkComm.simplelist(Tk.tk_call('file', 'volumes')).sort.each{|dir| + populate_tree(tree, tree.insert(nil, :end, :text=>dir, + :values=>[dir, 'directory'])) + } +end + +## Code to populate a node of the tree +def populate_tree(tree, node) + return if tree.get(node, :type) != 'directory' + + path = tree.get(node, :fullpath) + tree.delete(tree.children(node)) + Dir.glob("#{path}/*").sort.each{|f| + type = File.ftype(f) + id = tree.insert(node, :end, + :text=>File.basename(f), :values=>[f, type]).id + if type == 'directory' + ## Make it so that this node is openable + tree.insert(id, 0, :text=>'dummy') + tree.itemconfigure(id, :text=>File.basename(f)) + elsif type == 'file' + size = File.size(f) + if size >= 1024*1024*1024 + size = '%.1f GB' % (size.to_f/1024/1024/1024) + elsif size >= 1024*1024 + size = '%.1f MB' % (size.to_f/1024/1024) + elsif size >= 1024 + size = '%.1f KB' % (size.to_f/1024) + else + size = '%.1f bytes' % (size.to_f/1024) + end + tree.set(id, :size, size) + end + } + + # Stop this code from rerunning on the current node + tree.set(node, :type, 'processed_directory') +end + +## Create the tree and set it up +tree = Ttk::Treeview.new(base_frame, :columns=>%w(fullpath type size), + :displaycolumns=>['size']) +if Tk.windowingsystem != 'aqua' + vsb = tree.yscrollbar(Ttk::Scrollbar.new(base_frame)) + hsb = tree.xscrollbar(Ttk::Scrollbar.new(base_frame)) +else + vsb = tree.yscrollbar(Tk::Scrollbar.new(base_frame)) + hsb = tree.xscrollbar(Tk::Scrollbar.new(base_frame)) +end + +tree.heading_configure('#0', :text=>'Directory Structure') +tree.heading_configure('size', :text=>'File Size') +tree.column_configure('size', :stretch=>0, :width=>70) +populate_roots(tree) +tree.bind('', '%W'){|w| populate_tree(w, w.focus_item)} + +## Arrange the tree and its scrollbars in the toplevel +container = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true) +container.lower +Tk.grid(tree, vsb, :in=>container, :sticky=>'nsew') +Tk.grid(hsb, :in=>container, :sticky=>'nsew') +container.grid_columnconfigure(0, :weight=>1) +container.grid_rowconfigure(0, :weight=>1) diff --git a/ext/tk/sample/demos-jp/ttkbut.rb b/ext/tk/sample/demos-jp/ttkbut.rb new file mode 100644 index 0000000000..4d577120bb --- /dev/null +++ b/ext/tk/sample/demos-jp/ttkbut.rb @@ -0,0 +1,145 @@ +# -*- coding: euc-jp -*- +# +# ttkbut.rb +# +# This demonstration script creates a toplevel window containing several +# simple Ttk widgets, such as labels, labelframes, buttons, checkbuttons and +# radiobuttons. +# +# based on "Id: ttkbut.tcl,v 1.4 2007/12/13 15:27:07 dgp Exp" + +if defined?($ttkbut_demo) && $ttkbut_demo + $ttkbut_demo.destroy + $ttkbut_demo = nil +end + +$ttkbut_demo = TkToplevel.new {|w| + title("Simple Ttk Widgets") + iconname("ttkbut") + positionWindow(w) +} + +base_frame = TkFrame.new($ttkbut_demo).pack(:fill=>:both, :expand=>true) + +Ttk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, + :text=><:top, :fill=>:x) +Ttkとは,テーマ指定可能な新しいウィジェット集合です.\ +今,あなたが目にしているのはTtkのテーマ化ラベルで,\ +下にはTtkのラベルフレームの中に三つのグループのTtkウィジェットが\ +表示されています. +最初のグループは全てボタンであり,\ +それぞれクリックすれば現在のアプリケーションのテーマが設定されます. +2番目のグループは三つのチェックボタン集合です.\ +各集合の間には,セパレータウィジェットが置かれています.\ +なお「有効化」ボタンは,このトップレベルウィジェット内の\ +他のすべてのテーマ化ウィジェットの状態(state)が"disabled"かどうかを\ +コントロールすることに注意してください. +3番目のグループは関連付けられたラジオボタン集合となっています. +EOL + +## Add buttons for setting the theme +buttons = Ttk::Labelframe.new(base_frame, :text=>'ボタン') +# Ttk::Style.theme_names.each{|theme| +# Ttk::Button.new(buttons, :text=>theme, +# :command=>proc{Ttk::Style.theme_use theme}).pack(:pady=>2) +# } +Ttk.themes.each{|theme| + Ttk::Button.new(buttons, :text=>theme, + :command=>proc{Ttk.set_theme theme}).pack(:pady=>2) +} + +## Helper procedure for the top checkbutton +def setState(root, value, *excepts) + return if excepts.member?(root) + + ## Non-Ttk widgets (e.g. the toplevel) will fail, so make it silent + begin + root.state = value + rescue + end + + ## Recursively invoke on all children of this root that are in the same + ## toplevel widget + root.winfo_children.each{|w| + setState(w, value, *excepts) if w.winfo_toplevel == root.winfo_toplevel + } +end + +## Set up the checkbutton group +checks = Ttk::Labelframe.new(base_frame, :text=>'チェックボタン') +enabled = TkVariable.new(true) +e = Ttk::Checkbutton.new(checks, :text=>'有効化', :variable=>enabled, + :command=>proc{ + setState($ttkbut_demo, + ((enabled.bool)? "!disabled" : "disabled"), + e) + }) + +## See ttk_widget(n) for other possible state flags +sep1 = Ttk::Separator.new(checks) +sep2 = Ttk::Separator.new(checks) + +cheese = TkVariable.new +tomato = TkVariable.new +basil = TkVariable.new +oregano = TkVariable.new + +c1 = Ttk::Checkbutton.new(checks, :text=>'チーズ', :variable=>cheese) +c2 = Ttk::Checkbutton.new(checks, :text=>'トマト', :variable=>tomato) +c3 = Ttk::Checkbutton.new(checks, :text=>'バジル', :variable=>basil) +c4 = Ttk::Checkbutton.new(checks, :text=>'オレガノ', :variable=>oregano) + +Tk.pack(e, sep1, c1, c2, sep2, c3, c4, :fill=>:x, :pady=>2) + +## Set up the radiobutton group +radios = Ttk::Labelframe.new(base_frame, :text=>'ラジオボタン') + +happyness = TkVariable.new + +r1 = Ttk::Radiobutton.new(radios, :variable=>happyness, + :text=>'Great', :value=>'great') +r2 = Ttk::Radiobutton.new(radios, :variable=>happyness, + :text=>'Good', :value=>'good') +r3 = Ttk::Radiobutton.new(radios, :variable=>happyness, + :text=>'Ok', :value=>'ok') +r4 = Ttk::Radiobutton.new(radios, :variable=>happyness, + :text=>'Poor', :value=>'poor') +r5 = Ttk::Radiobutton.new(radios, :variable=>happyness, + :text=>'Awful', :value=>'awful') + +Tk.pack(r1, r2, r3, r4, r5, :fill=>:x, :padx=>3, :pady=>2) + +## See Code / Dismiss +Ttk::Frame.new(base_frame) {|frame| + sep = Ttk::Separator.new(frame) + Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + Ttk::Button.new(frame, :text=>'変数参照', + :image=>$image['view'], :compound=>:left, + :command=>proc{ + showVars(base_frame, ['有効化', enabled], + ['チーズ', cheese], ['トマト', tomato], + ['バジル', basil], ['オレガノ', oregano], + ['幸福度', happyness]) + }), + Ttk::Button.new(frame, :text=>'コード参照', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'ttkbut'}), + Ttk::Button.new(frame, :text=>'閉じる', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + tmppath = $ttkbut_demo + $ttkbut_demo = nil + $showVarsWin[tmppath.path] = nil + tmppath.destroy + }), + :padx=>4, :pady=>4) + grid_columnconfigure(0, :weight=>1) + pack(:side=>:bottom, :fill=>:x, :expand=>true) +} + +## Arrange things neatly +f = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true) +f.lower +Tk.grid(buttons, checks, radios, :in=>f, :sticky=>'nwe', :pady=>2, :padx=>3) +f.grid_columnconfigure([0, 1, 2], :weight=>1, :uniform=>:yes) diff --git a/ext/tk/sample/demos-jp/ttkmenu.rb b/ext/tk/sample/demos-jp/ttkmenu.rb new file mode 100644 index 0000000000..d349b42d11 --- /dev/null +++ b/ext/tk/sample/demos-jp/ttkmenu.rb @@ -0,0 +1,91 @@ +# -*- coding: euc-jp -*- +# +# ttkmenu.rb -- +# +# This demonstration script creates a toplevel window containing several Ttk +# menubutton widgets. +# +# based on "Id: ttkmenu.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp" + +if defined?($ttkmenu_demo) && $ttkmenu_demo + $ttkmenu_demo.destroy + $ttkmenu_demo = nil +end + +$ttkmenu_demo = TkToplevel.new {|w| + title("Ttk Menu Buttons") + iconname("ttkmenu") + positionWindow(w) +} + +base_frame = Ttk::Frame.new($ttkmenu_demo).pack(:fill=>:both, :expand=>true) + +Ttk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, + :text=><:top, :fill=>:x) +Ttkとは,テーマ指定可能な新しいウィジェット集合です.\ +これによりテーマに対応することができるようになったウィジェットのひとつに\ +メニューボタンがあります.\ +以下では,テーマに対応したメニューボタンがいくつか表示されています.\ +それらを使って,現在使用中のテーマを変更することが可能です.\ +テーマの選択がメニューボタン自身の見掛けを変化させる様子や,\ +中央のメニューボタンだけが異なるスタイル\ +(ツールバーでの一般的な表示に適したもの)で表示されている様子に\ +注目してください.\ +なお,メニューボタンについてはテーマに対応したウィジェットがありますが,\ +メニューについてはテーマに対応したウィジェットは含まれていません.\ +その理由は,標準のTkのメニューウィジェットが\ +すべてのプラットホームで十分に良好な見掛けと操作性を持っている,\ +特に,多くの環境でその環境本来の操作体系となるように実装されていると\ +判断されたことによります. +EOL + +Ttk::Separator.new(base_frame).pack(:side=>:top, :fill=>:x) + +## See Code / Dismiss +Ttk::Frame.new($ttkmenu_demo) {|frame| + sep = Ttk::Separator.new(frame) + Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + Ttk::Button.new(frame, :text=>'コード参照', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'ttkmenu'}), + Ttk::Button.new(frame, :text=>'閉じる', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + $ttkmenu_demo.destroy + $ttkmenu_demo = nil + }), + :padx=>4, :pady=>4) + grid_columnconfigure(0, :weight=>1) + pack(:side=>:bottom, :fill=>:x) +} + +b1 = Ttk::Menubutton.new(base_frame,:text=>'テーマを選択',:direction=>:above) +b2 = Ttk::Menubutton.new(base_frame,:text=>'テーマを選択',:direction=>:left) +b3 = Ttk::Menubutton.new(base_frame,:text=>'テーマを選択',:direction=>:right) +b4 = Ttk::Menubutton.new(base_frame,:text=>'テーマを選択',:direction=>:flush, + :style=>Ttk::Menubutton.style('Toolbutton')) +b5 = Ttk::Menubutton.new(base_frame,:text=>'テーマを選択',:direction=>:below) + +b1.menu(m1 = Tk::Menu.new(b1, :tearoff=>false)) +b2.menu(m2 = Tk::Menu.new(b2, :tearoff=>false)) +b3.menu(m3 = Tk::Menu.new(b3, :tearoff=>false)) +b4.menu(m4 = Tk::Menu.new(b4, :tearoff=>false)) +b5.menu(m5 = Tk::Menu.new(b5, :tearoff=>false)) + +Ttk.themes.each{|theme| + m1.add(:command, :label=>theme, :command=>proc{Ttk.set_theme theme}) + m2.add(:command, :label=>theme, :command=>proc{Ttk.set_theme theme}) + m3.add(:command, :label=>theme, :command=>proc{Ttk.set_theme theme}) + m4.add(:command, :label=>theme, :command=>proc{Ttk.set_theme theme}) + m5.add(:command, :label=>theme, :command=>proc{Ttk.set_theme theme}) +} + +f = Ttk::Frame.new(base_frame).pack(:fill=>:x) +f1 = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true) +f.lower + +f.grid_anchor(:center) +TkGrid('x', b1, 'x', :in=>f, :padx=>3, :pady=>2) +TkGrid(b2, b4, b3, :in=>f, :padx=>3, :pady=>2) +TkGrid('x', b5, 'x', :in=>f, :padx=>3, :pady=>2) diff --git a/ext/tk/sample/demos-jp/ttknote.rb b/ext/tk/sample/demos-jp/ttknote.rb new file mode 100644 index 0000000000..09cc7960a3 --- /dev/null +++ b/ext/tk/sample/demos-jp/ttknote.rb @@ -0,0 +1,97 @@ +# -*- coding: euc-jp -*- +# +# ttknote.rb -- +# +# This demonstration script creates a toplevel window containing a Ttk +# notebook widget. +# +# based on "Id: ttknote.tcl,v 1.5 2007/12/13 15:27:07 dgp Exp" + +if defined?($ttknote_demo) && $ttknote_demo + $ttknote_demo.destroy + $ttknote_demo = nil +end + +$ttknote_demo = TkToplevel.new {|w| + title("Ttk Notebook Widget") + iconname("ttknote") + positionWindow(w) +} + +## See Code / Dismiss +Ttk::Frame.new($ttknote_demo) {|frame| + sep = Ttk::Separator.new(frame) + Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + Ttk::Button.new(frame, :text=>'コード参照', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'ttknote'}), + Ttk::Button.new(frame, :text=>'閉じる', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + $ttknote_demo.destroy + $ttknote_demo = nil + }), + :padx=>4, :pady=>4) + grid_columnconfigure(0, :weight=>1) + pack(:side=>:bottom, :fill=>:x) +} + +base_frame = Ttk::Frame.new($ttknote_demo).pack(:fill=>:both, :expand=>true) + +## Make the notebook and set up Ctrl+Tab traversal +notebook = Ttk::Notebook.new(base_frame).pack(:fill=>:both, :expand=>true, + :padx=>2, :pady=>3) +notebook.enable_traversal + +## Popuplate the first pane +f_msg = Ttk::Frame.new(notebook) +msg_m = Ttk::Label.new(f_msg, :font=>$font, :wraplength=>'5i', + :justify=>:left, :anchor=>'n', :text=><'すてきだ!(Neat!)', :underline=>6, + :command=>proc{ + neat.value = 'あぁ,そのとおりさ...' + Tk.after_cancel(after_id) if after_id + after_id = Tk.after(500){neat.value = ''} + }) +msg_b.winfo_toplevel.bind('Alt-n'){ msg_b.focus; msg_b.invoke } +msg_l = Ttk::Label.new(f_msg, :textvariable=>neat) +notebook.add(f_msg, :text=>'説明(Description)', :underline=>3, :padding=>2) +Tk.grid(msg_m, '-', :sticky=>'new', :pady=>2) +Tk.grid(msg_b, msg_l, :pady=>[2, 4], :padx=>20) +msg_b.grid_configure(:sticky=>'e') +msg_l.grid_configure(:sticky=>'w') +f_msg.grid_rowconfigure(1, :weight=>1) +f_msg.grid_columnconfigure([0, 1], :weight=>1, :uniform=>1) + +## Populate the second pane. Note that the content doesn't really matter +f_disabled = Ttk::Frame.new(notebook) +notebook.add(f_disabled, :text=>'無効化されたタブ', :state=>:disabled) + +## Popuplate the third pane +f_editor = Ttk::Frame.new(notebook) +notebook.add(f_editor, :text=>'テキストエディタ(Text Editor)', :underline=>9) +editor_t = Tk::Text.new(f_editor, :width=>40, :height=>10, :wrap=>:char) +if Tk.windowingsystem != 'aqua' + editor_s = editor_t.yscrollbar(Ttk::Scrollbar.new(f_editor)) +else + editor_s = editor_t.yscrollbar(Tk::Scrollbar.new(f_editor)) +end +editor_s.pack(:side=>:right, :fill=>:y, :padx=>[0,2], :pady=>2) +editor_t.pack(:fill=>:both, :expand=>true, :padx=>[2,0], :pady=>2) diff --git a/ext/tk/sample/demos-jp/ttkpane.rb b/ext/tk/sample/demos-jp/ttkpane.rb new file mode 100644 index 0000000000..96670c0e5c --- /dev/null +++ b/ext/tk/sample/demos-jp/ttkpane.rb @@ -0,0 +1,216 @@ +# -*- coding: euc-jp -*- +# +# ttkpane.rb -- +# +# This demonstration script creates a Ttk pane with some content. +# +# based on "Id: ttkpane.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp" + +if defined?($ttkpane_demo) && $ttkpane_demo + $ttkpane_demo.destroy + $ttkpane_demo = nil +end + +$ttkpane_demo = TkToplevel.new {|w| + title("Themed Nested Panes") + iconname("ttkpane") + positionWindow(w) +} + +base_frame = TkFrame.new($ttkpane_demo).pack(:fill=>:both, :expand=>true) + +Ttk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, + :text=><:top, :fill=>:x) +このデモは,埋め込み関係にあるテーマ付きペインドウィンドウを示しています.\ +それぞれの大きさは,含まれているペインの間にあるエリアをつかんで\ +境界をドラッグすることで変更できます. +EOL + +Ttk::Separator.new(base_frame).pack(:side=>:top, :fill=>:x) + +## See Code / Dismiss +Ttk::Frame.new(base_frame) {|frame| + sep = Ttk::Separator.new(frame) + Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + Ttk::Button.new(frame, :text=>'コード参照', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'ttkpane'}), + Ttk::Button.new(frame, :text=>'閉じる', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + $ttkpane_demo.destroy + $ttkpane_demo = nil + }), + :padx=>4, :pady=>4) + grid_columnconfigure(0, :weight=>1) + pack(:side=>:bottom, :fill=>:x) +} + +frame = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true) + +outer = Ttk::Panedwindow.new(frame, :orient=>:horizontal) +outer.add(in_left = Ttk::Panedwindow.new(outer, :orient=>:vertical)) +outer.add(in_right = Ttk::Panedwindow.new(outer, :orient=>:vertical)) +in_left.add(left_top = Ttk::Labelframe.new(in_left, :text=>'ボタン')) +in_left.add(left_bot = Ttk::Labelframe.new(in_left, :text=>'時計')) +in_right.add(right_top = Ttk::Labelframe.new(in_right, :text=>'プログレス')) +in_right.add(right_bot = Ttk::Labelframe.new(in_right, :text=>'テキスト')) +if Tk.windowingsystem == 'aqua' + [left_top, left_bot, right_top, right_bot].each{|w| w.padding(3) } +end + +# Fill the button pane +Ttk::Button.new(left_top, :text=>'押してね', + :command=>proc{ + Tk.messageBox(:type=>'ok', :icon=>'info', + :message=>'いてて!', + :detail=>'That hurt...', :parent=>base_frame, + :title=>'Button Pressed') + }).pack(:padx=>2, :pady=>5) + + +zones_list = [ + [':Europe/Berlin'], + [':America/Argentina/Buenos_Aires', ':America/Buenos_Aires'], + [':Africa/Johannesburg'], + [':Europe/London'], + [':America/Los_Angeles'], + [':Europe/Moscow'], + [':America/New_York'], + [':Asia/Singapore'], + [':Australia/Sydney'], + [':Asia/Tokyo'], +] + +zones = [] + +# Check tzinfo support +if $tk_major_ver > 8 || ($tk_major_ver == 8 && $tk_minor_ver >= 5) + tzinfo = :tcl + + zones_list.each{|list| + list.each{|zone| + begin + # Force a pre-load of all the timezones needed; otherwise can end up + # poor-looking synch problems! + Tk.tk_call('clock', 'format', '0', '-timezone', zone) + rescue RuntimeError + # ignore + else + zones << [zone, zone[%r<[^/:]+$>].tr('_', ' ')] + break + end + } + } + +else + begin + require 'tzinfo' + tzinfo = :tzinfo + rescue Exception + begin + require 'tzfile' + tzinfo = :tzfile + rescue Exception + tzinfo = nil + end + end + + case tzinfo + when :tzinfo + zones_list.each{|list| + list.each{|zone| + begin + tz = TZInfo::Timezone.get(zone[%r<[^:]+$>]) + rescue Exception + # ignore + else + zones << [tz, zone[%r<[^/:]+$>].tr('_', ' ')] + break + end + } + } + + when :tzfile + zones_list.each{|list| + list.each{|zone| + begin + tz = TZFile.create(zone[%r<[^:]+$>]) + rescue Exception + # ignore + else + zones << [tz, zone[%r<[^/:]+$>].tr('_', ' ')] + break + end + } + } + + else + [ -7, -4, -2, -1, 0, +1, +3, +8, +9, +10 ].each{|zone| + zones << [zone, 'UTC%+03d00' % zone] + } + end +end + +time = TkVariable.new_hash + +case tzinfo +when :tcl + update_proc = proc{|now, tz, label| + time[label] = Tk.tk_call('clock', 'format', now.tv_sec, + '-timezone', tz, '-format', '%T') + } +when :tzinfo + update_proc = proc{|now, tz, label| + time[label] = tz.utc_to_local(now).strftime('%H:%M:%S') + } +when :tzfile + update_proc = proc{|now, tz, label| + time[label] = tz.at(now.tv_sec).strftime('%H:%M:%S') + } +else + update_proc = proc{|now, tz, label| + time[label] = (now + (tz * 3600)).strftime('%H:%M:%S') + } +end + +# Fill the clocks pane +zones.each_with_index{|(zone, label), idx| + Ttk::Separator.new(left_bot).pack(:fill=>:x) if idx > 0 + Ttk::Label.new(left_bot, :text=>label, :anchor=>'w').pack(:fill=>:x) + Ttk::Label.new(left_bot, :textvariable=>time.ref(label), + :anchor=>'w').pack(:fill=>:x) +} + +# Timer start +every = proc{ + now = Time.now.utc + zones.each{|zone, label| update_proc.call(now, zone, label) } +} +TkRTTimer.new(1000, -1, every).start(0, every) + +# Fill the progress pane +Ttk::Progressbar.new(right_top, :mode=>:indeterminate).pack(:fill=>:both, :expand=>true).start + +# Fill the text pane +if Tk.windowingsystem != 'aqua' + # The trick with the ttk::frame makes the text widget look like it fits with + # the current Ttk theme despite not being a themed widget itself. It is done + # by styling the frame like an entry, turning off the border in the text + # widget, and putting the text widget in the frame with enough space to allow + # the surrounding border to show through (2 pixels seems to be enough). + f = Ttk::Frame.new(right_bot, :style=>Ttk::Entry) + txt = TkText.new(frame, :wrap=>:word, :width=>30, :borderwidth=>0) + txt.pack(:fill=>:both, :expand=>true, :in=>f, :pady=>2, :padx=>2) + scr = txt.yscrollbar(Ttk::Scrollbar.new(frame)) + scr.pack(:side=>:right, :fill=>:y, :in=>right_bot) + f.pack(:fill=>:both, :expand=>true) + outer.pack(:fill=>:both, :expand=>true) +else + txt = TkText.new(frame, :wrap=>:word, :width=>30, :borderwidth=>0) + scr = txt.yscrollbar(TkScrollbar.new(frame)) + scr.pack(:side=>:right, :fill=>:y, :in=>right_bot) + txt.pack(:fill=>:both, :expand=>true, :in=>right_bot) + outer.pack(:fill=>:both, :expand=>true, :padx=>10, :pady=>[6, 10]) +end diff --git a/ext/tk/sample/demos-jp/ttkprogress.rb b/ext/tk/sample/demos-jp/ttkprogress.rb new file mode 100644 index 0000000000..43a9cbcd7e --- /dev/null +++ b/ext/tk/sample/demos-jp/ttkprogress.rb @@ -0,0 +1,71 @@ +# -*- coding: euc-jp -*- +# +# ttkprogress.rb -- +# +# This demonstration script creates several progress bar widgets. +# +# based on "Id: ttkprogress.tcl,v 1.3 2007/12/13 15:27:07 dgp Exp" + +if defined?($ttkprogress_demo) && $ttkprogress_demo + $ttkprogress_demo.destroy + $ttkprogress_demo = nil +end + +$ttkprogress_demo = TkToplevel.new {|w| + title("Progress Bar Demonstration") + iconname("ttkprogress") + positionWindow(w) +} + +base_frame = TkFrame.new($ttkprogress_demo).pack(:fill=>:both, :expand=>true) + +Ttk::Label.new(base_frame, :font=>$font, :wraplength=>'4i', :justify=>:left, + :text=><:top, :fill=>:x) +下にあるのは二つのプログレスバーです.\ +上のものは"determinate"タイプのプログレスバーで,\ +例えばプログラムが与えられたタスクを終了するまでにどのくらいかかるかを\ +示すときなどに用いられます.\ +下のものは"indeterminate"タイプのプログレスバーで,\ +例えばプログラムが実行中(busy)であるものの\ +終了までにどれくらいかかるかは分からないという状態を\ +示すときなどに用いられます.\ +いずれのプログレスバーも,すぐ下にあるボタンを使うことで\ +自動アニメーションモードのON/OFFを切替えることができます. +EOL + +## See Code / Dismiss buttons +Ttk::Frame.new(base_frame) {|frame| + sep = Ttk::Separator.new(frame) + Tk.grid(sep, :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) + TkGrid('x', + Ttk::Button.new(frame, :text=>'コード参照', + :image=>$image['view'], :compound=>:left, + :command=>proc{showCode 'ttkprogress'}), + Ttk::Button.new(frame, :text=>'閉じる', + :image=>$image['delete'], :compound=>:left, + :command=>proc{ + $ttkprogress_demo.destroy + $ttkprogress_demo = nil + }), + :padx=>4, :pady=>4) + grid_columnconfigure(0, :weight=>1) + pack(:side=>:bottom, :fill=>:x) +} + +frame = Ttk::Frame.new(base_frame).pack(:fill=>:both, :expand=>true) + +p1 = Ttk::Progressbar.new(frame, :mode=>:determinate) +p2 = Ttk::Progressbar.new(frame, :mode=>:indeterminate) + +start = Ttk::Button.new(frame, :text=>'Start Progress', + :command=>proc{ p1.start; p2.start }) +stop = Ttk::Button.new(frame, :text=>'Stop Progress', + :command=>proc{ p1.stop; p2.stop }) + +Tk.grid(p1, '-', :pady=>5, :padx=>10) +Tk.grid(p2, '-', :pady=>5, :padx=>10) +Tk.grid(start, stop, :padx=>10, :pady=>5) +start.grid_configure(:sticky=>'e') +stop.grid_configure(:sticky=>'w') +frame.grid_columnconfigure(:all, :weight=>1) + diff --git a/ext/tk/sample/demos-jp/twind.rb b/ext/tk/sample/demos-jp/twind.rb index d0fa8ca49e..faefaefd6e 100644 --- a/ext/tk/sample/demos-jp/twind.rb +++ b/ext/tk/sample/demos-jp/twind.rb @@ -16,8 +16,10 @@ $twind_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($twind_demo).pack(:fill=>:both, :expand=>true) + # frame 生成 -$twind_buttons = TkFrame.new($twind_demo) {|frame| +$twind_buttons = TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -37,7 +39,7 @@ $twind_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # frame 生成 $twind_text = nil -TkFrame.new($twind_demo, 'highlightthickness'=>2, 'borderwidth'=>2, +TkFrame.new(base_frame, 'highlightthickness'=>2, 'borderwidth'=>2, 'relief'=>'sunken') {|f| $twind_text = TkText.new(f, 'setgrid'=>'true', 'font'=>$font, 'width'=>'70', 'height'=>35, 'wrap'=>'word', diff --git a/ext/tk/sample/demos-jp/twind2.rb b/ext/tk/sample/demos-jp/twind2.rb index e8009cef19..2a26b28ef6 100644 --- a/ext/tk/sample/demos-jp/twind2.rb +++ b/ext/tk/sample/demos-jp/twind2.rb @@ -16,8 +16,10 @@ $twind2_demo = TkToplevel.new {|w| positionWindow(w) } +base_frame = TkFrame.new($twind2_demo).pack(:fill=>:both, :expand=>true) + # frame 生成 -$twind2_buttons = TkFrame.new($twind2_demo) {|frame| +$twind2_buttons = TkFrame.new(base_frame) {|frame| TkGrid(TkFrame.new(frame, :height=>2, :relief=>:sunken, :bd=>2), :columnspan=>4, :row=>0, :sticky=>'ew', :pady=>2) TkGrid('x', @@ -39,7 +41,7 @@ $twind2_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') # frame 生成 $twind2_text = nil -TkFrame.new($twind2_demo, 'highlightthickness'=>2, 'borderwidth'=>2, +TkFrame.new(base_frame, 'highlightthickness'=>2, 'borderwidth'=>2, 'relief'=>'sunken') {|f| $twind2_text = TkText.new(f, 'setgrid'=>true, 'font'=>$font, # 'width'=>'70', 'height'=>35, 'wrap'=>'word', diff --git a/ext/tk/sample/demos-jp/unicodeout.rb b/ext/tk/sample/demos-jp/unicodeout.rb index 7ab415fe57..178077ec08 100644 --- a/ext/tk/sample/demos-jp/unicodeout.rb +++ b/ext/tk/sample/demos-jp/unicodeout.rb @@ -18,7 +18,9 @@ $unicodeout_demo = TkToplevel.new {|w| positionWindow(w) } -TkLabel.new($unicodeout_demo, +base_frame = TkFrame.new($unicodeout_demo).pack(:fill=>:both, :expand=>true) + +TkLabel.new(base_frame, :font=>$font, :wraplength=>'5.4i', :justify=>:left, :text=><:top) これは,Tkにおける非欧米文字集合を用いる言語に対するサポートについての\ @@ -40,7 +42,7 @@ Tcl EOL #' -TkFrame.new($unicodeout_demo){|f| +TkFrame.new(base_frame){|f| pack(:side=>:bottom, :fill=>:x, :pady=>'2m') TkButton.new(f, :text=>'閉じる', :width=>15, :command=>proc{ @@ -53,7 +55,7 @@ TkFrame.new($unicodeout_demo){|f| }).pack(:side=>:left, :expand=>true) } -wait_msg = TkLabel.new($unicodeout_demo, +wait_msg = TkLabel.new(base_frame, :text=>"フォント読み込みの完了まで" + "しばらくお待ち下さい...", :font=>"Helvetica 12 italic").pack @@ -68,8 +70,8 @@ class Unicodeout_SampleFrame < TkFrame # @@font = 'Newspaper 12' # @@font = '{New century schoolbook} 12' - def initialize() - super($unicodeout_demo) + def initialize(base) + super(base) grid_columnconfig(1, :weight=>1) end @@ -84,7 +86,7 @@ class Unicodeout_SampleFrame < TkFrame l.grid_config(:padx, '1m') end end -f = Unicodeout_SampleFrame.new +f = Unicodeout_SampleFrame.new(base_frame) f.pack(:expand=>true, :fill=>:both, :padx=>'2m', :pady=>'1m') # Processing when some characters are missing might take a while, so make diff --git a/ext/tk/sample/demos-jp/vscale.rb b/ext/tk/sample/demos-jp/vscale.rb index 990ca43215..a1097fd77f 100644 --- a/ext/tk/sample/demos-jp/vscale.rb +++ b/ext/tk/sample/demos-jp/vscale.rb @@ -12,7 +12,9 @@ $vscale_demo = TkToplevel.new {|w| } positionWindow($vscale_demo) -msg = TkLabel.new($vscale_demo) { +base_frame = TkFrame.new($vscale_demo).pack(:fill=>:both, :expand=>true) + +msg = TkLabel.new(base_frame) { font $font wraplength '3.5i' justify 'left' @@ -23,7 +25,7 @@ msg = TkLabel.new($vscale_demo) { } msg.pack('side'=>'top', 'padx'=>'.5c') -TkFrame.new($vscale_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -40,7 +42,17 @@ TkFrame.new($vscale_demo) {|frame| }.pack('side'=>'left', 'expand'=>'yes') }.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m') -TkFrame.new($vscale_demo) {|frame| +def setHeight(w, height) + height = height + 21 + y2 = height - 30 + if y2 < 21 + y2 = 21 + end + w.coords 'poly',15,20,35,20,35,y2,45,y2,25,height,5,y2,15,y2,15,20 + w.coords 'line',15,20,35,20,35,y2,45,y2,25,height,5,y2,15,y2,15,20 +end + +TkFrame.new(base_frame) {|frame| borderwidth 10 canvas = TkCanvas.new(frame) {|c| width 50 @@ -66,14 +78,3 @@ TkFrame.new($vscale_demo) {|frame| }.pack('side'=>'left', 'anchor'=>'ne') scale.set 75 }.pack - -def setHeight(w, height) - height = height + 21 - y2 = height - 30 - if y2 < 21 - y2 = 21 - end - w.coords 'poly',15,20,35,20,35,y2,45,y2,25,height,5,y2,15,y2,15,20 - w.coords 'line',15,20,35,20,35,y2,45,y2,25,height,5,y2,15,y2,15,20 -end - diff --git a/ext/tk/sample/demos-jp/widget b/ext/tk/sample/demos-jp/widget index a7e4bf3ca7..60ec5b5e96 100644 --- a/ext/tk/sample/demos-jp/widget +++ b/ext/tk/sample/demos-jp/widget @@ -12,6 +12,8 @@ end require 'tk' # require 'tkafter' +$RubyTk_WidgetDemo = true + # widget demo directory 位置の獲得 # $demo_dir = File.dirname($0) $demo_dir = File.dirname(__FILE__) @@ -49,7 +51,7 @@ when /^8.*/ $font = TkFont.new('Helvetica -12') $kanji_font = TkFont.new('Helvetica -12', 'Mincho -12') TkOption.add('*kanjiFont', knjfont, 'startupFile') - $msg_kanji_font=TkFont.new('Helvetica 16 bold', 'Gothic 16 bold') + $msg_kanji_font=TkFont.new('Helvetica 14 bold', 'Gothic 14 bold') else $font = TkFont.new('Helvetica 14', nil) @@ -121,14 +123,22 @@ EOD end # メニュー設定 -TkMenubar.new($root, - [[['File', 0], - ['About ... ', proc{aboutBox}, 0, ''], - '---', - ['Quit', proc{exit}, 0, 'Meta-Q'] - ]]).pack('side'=>'top', 'fill'=>'x') +if $tk_major_ver >= 8 + $root.add_menubar([[['File', 0], + ['About ... ', proc{aboutBox}, 0, ''], + '---', + ['Quit', proc{exit}, 0, 'Ctrl-Q'] + ]]) +else + TkMenubar.new($root, + [[['File', 0], + ['About ... ', proc{aboutBox}, 0, ''], + '---', + ['Quit', proc{exit}, 0, 'Ctrl-Q'] + ]]).pack('side'=>'top', 'fill'=>'x') +end $root.bind('F1', proc{aboutBox}) -$root.bind('Meta-q', proc{exit}) +$root.bind('Control-q', proc{exit}) =begin TkFrame.new($root){|frame| @@ -349,6 +359,9 @@ txt.insert('end', " \n ", tag_demospace) txt.insert('end', "14. ラベル付きフレーム (機能に対応したバージョンのTkが必要)\n", tag_demo, "demo-labelframe") txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "15. テーマに対応したウィジェットの簡単な例 (Tile/Ttk拡張への対応が必要)\n", + tag_demo, "demo-ttkbut") +txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") #txt.insert('end', "リストボックス\n", tag_middle) @@ -361,6 +374,12 @@ txt.insert('end', "2. txt.insert('end', " \n ", tag_demospace) txt.insert('end', "3. 格言集\n", tag_demo, "demo-sayings") txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "4. 国についてのマルチカラムリスト (Tile/Ttk拡張への対応が必要)\n", + tag_demo, "demo-mclist") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "5. ディレクトリブラウザ (Tile/Ttk拡張への対応が必要)\n", + tag_demo, "demo-tree") +txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") #txt.insert('end', "エントリとスピンボックス\n", tag_middle) @@ -376,7 +395,10 @@ txt.insert('end', " \n ", tag_demospace) txt.insert('end', "4. スピンボックス (機能に対応したバージョンのTkが必要)\n", tag_demo, "demo-spin") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "5. 簡単なフォーム\n", tag_demo, "demo-form") +txt.insert('end', "5. コンボボックス (Tile/Ttk拡張への対応が必要)\n", + tag_demo, "demo-combo") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "6. 簡単なフォーム\n", tag_demo, "demo-form") txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") @@ -422,18 +444,23 @@ txt.insert('end', " \n ", tag_demospace) txt.insert('end', "8. スクロール可能なキャンバス\n", tag_demo, "demo-cscroll") txt.insert('end', " \n ", tag_demospace) - -txt.insert('end', "\n") -#txt.insert('end', "スケール\n", tag_middle) -txt.insert('end', "スケール\n", tag_kanji_title) -txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "1. 垂直\n", tag_demo.id, "demo-vscale") -txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "2. 水平\n", tag_demo.id, "demo-hscale") +txt.insert('end', "9. チェスボード上の騎士の巡回 (Tile/Ttk拡張への対応が必要)\n", + tag_demo, "demo-knightstour") txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") -txt.insert('end', "ペインドウィンドウ\n", tag_kanji_title) +#txt.insert('end', "スケールとプログレスバー\n", tag_middle) +txt.insert('end', "スケールとプログレスバー\n", tag_kanji_title) +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "1. 垂直スケール\n", tag_demo.id, "demo-vscale") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "2. 水平スケール\n", tag_demo.id, "demo-hscale") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "3. プログレスバー (Tile/Ttk拡張への対応が必要)\n", tag_demo.id, "demo-ttkprogress") +txt.insert('end', " \n ", tag_demospace) + +txt.insert('end', "\n") +txt.insert('end', "ペインドウィンドウとノートブック\n", tag_kanji_title) txt.insert('end', " \n ", tag_demospace) txt.insert('end', "1. 水平方向 (機能に対応したバージョンのTkが必要)\n", tag_demo.id, "demo-paned1") @@ -441,10 +468,16 @@ txt.insert('end', " \n ", tag_demospace) txt.insert('end', "2. 垂直方向 (機能に対応したバージョンのTkが必要)\n", tag_demo.id, "demo-paned2") txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "3. テーマに対応した埋め込みペイン (Tile/Ttk拡張への対応が必要)\n", + tag_demo.id, "demo-ttkpane") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "4. ノートブックウィジェット (Tile/Ttk拡張への対応が必要)\n", + tag_demo.id, "demo-ttknote") +txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") -#txt.insert('end', "メニュー\n", tag_middle) -txt.insert('end', "メニュー\n", tag_kanji_title) +#txt.insert('end', "メニューとツールバー\n", tag_middle) +txt.insert('end', "メニューとツールバー\n", tag_kanji_title) txt.insert('end', " \n ", tag_demospace) txt.insert('end', "1. メニューとカスケードを含んだウィンドウ\n", tag_demo, "demo-menu") @@ -458,6 +491,12 @@ txt.insert('end', " \n ", tag_demospace) txt.insert('end', "4. メニューボタン (Tk8.x 専用)\n", tag_demo, "demo-menubu") txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "5. テーマに対応したメニューボタン (Tile/Ttk拡張への対応が必要)\n", + tag_demo.id, "demo-ttkmenu") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "6. テーマに対応したツールバー (Tile/Ttk拡張への対応が必要)\n", + tag_demo.id, "demo-toolbar") +txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") #txt.insert('end', "ダイアログウィンドウ\n", tag_middle) @@ -465,9 +504,11 @@ txt.insert('end', " txt.insert('end', " \n ", tag_demospace) txt.insert('end', "1. メッセージボックス\n", tag_demo, "demo-msgbox") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "2. ファイル選択ダイアログ\n", tag_demo, "demo-filebox") +txt.insert('end', "2. 詳細テキスト付きのメッセージボックス (機能に対応したバージョンのTkが必要)\n", tag_demo, "demo-msgbox2") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "3. 色選択ダイアログ\n", tag_demo, "demo-clrpick") +txt.insert('end', "3. ファイル選択ダイアログ\n", tag_demo, "demo-filebox") +txt.insert('end', " \n ", tag_demospace) +txt.insert('end', "4. 色選択ダイアログ\n", tag_demo, "demo-clrpick") txt.insert('end', " \n ", tag_demospace) txt.insert('end', "\n") @@ -516,7 +557,8 @@ def showVars1(parent, *args) end top = TkToplevel.new(parent) {|w| title "Variable values" - TkLabel.new(w) { + base = TkFrame.new(w).pack(:fill=>:both, :expand=>true) + TkLabel.new(base) { text "変数値:" width 20 anchor 'center' @@ -531,14 +573,14 @@ def showVars1(parent, *args) len = vnam.to_s.length if vnam.to_s.length > len } args.each{|vnam,vbody| - TkFrame.new(w){|f| + TkFrame.new(base){|f| #TkLabel.new(f, 'text'=>"#{vnam}: ").pack('side'=>'left') TkLabel.new(f, 'text'=>"#{vnam}: ",'width'=>len+2).pack('side'=>'left') TkLabel.new(f, 'textvariable'=>vbody, 'anchor'=>'w')\ .pack('side'=>'left', 'expand'=>'yes', 'fill'=>'x') }.pack('side'=>'top', 'anchor'=>'w', 'fill'=>'x') } - TkButton.new(w) { + TkButton.new(base) { text "了解" command proc{w.destroy} }.pack('side'=>'bottom', 'pady'=>2) @@ -553,10 +595,12 @@ def showVars2(parent, *args) rescue end end - $showVarsWin[parent.path] = TkToplevel.new(parent) {|w| + $showVarsWin[parent.path] = TkToplevel.new(parent) {|top| title "Variable values" - TkLabelFrame.new(w, :text=>"変数値:", + base = TkFrame.new(top).pack(:fill=>:both, :expand=>true) + + TkLabelFrame.new(base, :text=>"変数値:", :font=>{:family=>'Helvetica', :size=>14}){|f| args.each{|vnam,vbody| TkGrid(TkLabel.new(f, :text=>"#{vnam}: ", :anchor=>'w'), @@ -568,15 +612,15 @@ def showVars2(parent, *args) f.grid_columnconfig(1, :weight=>1) f.grid_rowconfig(100, :weight=>1) } - TkButton.new(w, :text=>"了解", :width=>8, :default=>:active, - :command=>proc{w.destroy}){|b| - w.bind('Return', proc{b.invoke}) - w.bind('Escape', proc{b.invoke}) + TkButton.new(base, :text=>"了解", :width=>8, :default=>:active, + :command=>proc{top.destroy}){|b| + top.bind('Return', proc{b.invoke}) + top.bind('Escape', proc{b.invoke}) b.grid(:sticky=>'e', :padx=>4, :pady=>[6, 4]) } - w.grid_columnconfig(0, :weight=>1) - w.grid_rowconfig(0, :weight=>1) + base.grid_columnconfig(0, :weight=>1) + base.grid_rowconfig(0, :weight=>1) } end @@ -670,10 +714,27 @@ def _null_binding end private :_null_binding -def eval_samplecode(code) +def eval_samplecode(code, file=nil) #eval(code) #_null_binding.pseudo_toplevel_eval{ eval(code) } - Thread.new{ _null_binding.pseudo_toplevel_eval{ eval(code) } } + #Thread.new{ _null_binding.pseudo_toplevel_eval{ eval(code) } } + Thread.new{ + _null_binding.pseudo_toplevel_eval{ + begin + if file + eval(code, binding, "(eval:#{file})") + else + eval(code) + end + rescue Exception=>e + #p e + TkBgError.show(e.message + "\n" + + "\n---< backtrace of Ruby side >-----\n" + + e.backtrace.join("\n") + + "\n---< backtrace of Tk side >-------") + end + } + } Tk.update end @@ -687,7 +748,7 @@ def invoke(txt, idx) Tk.update # eval(IO.readlines("#{[$demo_dir, tag[5..-1]].join(File::Separator)}.rb").join, _null_binding) # Tk.update - eval_samplecode(IO.readlines("#{[$demo_dir, tag[5..-1]].join(File::Separator)}.rb").join) + eval_samplecode(IO.readlines("#{[$demo_dir, tag[5..-1]].join(File::Separator)}.rb").join, tag[5..-1] + '.rb') txt.cursor(cursor) $tag_visited.add("#{idx} linestart +1 chars", "#{idx} lineend +1 chars") @@ -733,6 +794,7 @@ def showCode1(demo) if $code_window == nil || TkWinfo.exist?($code_window) == false $code_window = TkToplevel.new(nil) f = TkFrame.new($code_window) + TkButton.new(f) { #text "了解" text "閉じる" @@ -740,14 +802,19 @@ def showCode1(demo) $code_window.destroy $code_window = nil } - }.pack('side'=>'left', 'expand'=>'yes', 'pady'=>2) + }.pack('side'=>'right', 'expand'=>'false', 'pady'=>2) TkButton.new(f) { text "再実行" # command proc{eval($code_text.get('1.0','end'), _null_binding)} - command proc{eval_samplecode($code_text.get('1.0','end'))} - }.pack('side'=>'left', 'expand'=>'yes', 'pady'=>2) -# f.pack('side'=>'bottom', 'expand'=>'yes', 'fill'=>'x') - f.pack('side'=>'bottom', 'fill'=>'x') + command proc{eval_samplecode($code_text.get('1.0','end'), '')} + }.pack('side'=>'right', 'expand'=>'false', 'pady'=>2) + + TkLabel.new(f,'text'=>'line:').pack('side'=>'left') + linenum =TkLabel.new(f,'text'=>'').pack('side'=>'left') + TkLabel.new(f,'text'=>' pos:').pack('side'=>'left') + posnum =TkLabel.new(f,'text'=>'').pack('side'=>'left') + + f.pack('side'=>'bottom', 'expand'=>'true', 'fill'=>'x') if $tk_version =~ /^4\.[01]/ s = TkScrollbar.new($code_window, 'orient'=>'vertical') @@ -805,6 +872,24 @@ def showCode1(demo) #$code_mark = TkTextMark.new($code_text, '1.0') #$code_text.set_insert('1.0') TkTextMarkInsert.new($code_text,'1.0') + + btag = TkBindTag.new + + set_linenum = proc{|w| + line, pos = w.index('insert').split('.') + linenum.text = line + posnum.text = pos + } + + btag.bind('Key', set_linenum, '%W') + btag.bind('Button', set_linenum, '%W') + + btags = $code_text.bindtags + btags.insert(btags.index($code_text.class) + 1, btag) + $code_text.bindtags = btags + + set_linenum.call($code_text) + fid.close end @@ -825,7 +910,13 @@ def showCode2(demo) tf.grid_columnconfigure(0, :weight=>1) bf = TkFrame.new($code_window) - + + lf = TkFrame.new(bf) + TkLabel.new(lf, :text=>'line:').pack(:side=>:left) + linenum =TkLabel.new(lf, :text=>'').pack(:side=>:left) + TkLabel.new(lf, :text=>' pos:').pack(:side=>:left) + posnum =TkLabel.new(lf, :text=>'').pack(:side=>:left) + #b_dis = TkButton.new(bf, :text=>'了解', :default=>:active, b_dis = TkButton.new(bf, :text=>'閉じる', :default=>:active, :command=>proc{ @@ -839,12 +930,12 @@ def showCode2(demo) b_run = TkButton.new(bf, :text=>'再実行', :command=>proc{ # eval($code_text.get('1.0','end'), _null_binding) - eval_samplecode($code_text.get('1.0','end')) + eval_samplecode($code_text.get('1.0','end'), '') }, :image=>$image['refresh'], :compound=>:left) - TkGrid('x', b_run, b_prn, b_dis, :padx=>4, :pady=>[6,4]) - bf.grid_columnconfigure(0, :weight=>1) + TkGrid(lf, 'x', b_run, b_prn, b_dis, :padx=>4, :pady=>[6,4]) + bf.grid_columnconfigure(1, :weight=>1) TkGrid(tf, :sticky=>'news') TkGrid(bf, :sticky=>'ew') @@ -868,6 +959,24 @@ def showCode2(demo) $code_text.delete('1.0', 'end') $code_text.insert('1.0', fid.read) TkTextMarkInsert.new($code_text,'1.0') + + btag = TkBindTag.new + + set_linenum = proc{|w| + line, pos = w.index('insert').split('.') + linenum.text = line + posnum.text = pos + } + + btag.bind('Key', set_linenum, '%W') + btag.bind('Button', set_linenum, '%W') + + btags = $code_text.bindtags + btags.insert(btags.index($code_text.class) + 1, btag) + $code_text.bindtags = btags + + set_linenum.call($code_text) + fid.close end @@ -965,12 +1074,13 @@ end # def aboutBox Tk.messageBox('icon'=>'info', 'type'=>'ok', 'title'=>'About Widget Demo', - 'message'=>"Ruby/Tk ウィジェットデモ Ver.1.6.4-jp\n\n" + + 'message'=>"Ruby/Tk ウィジェットデモ Ver.1.7.0-jp\n\n" + "based on demos of Tk8.1 -- 8.5 " + - "( Copyright:: " + + "( Copyright of Tcl/Tk demos:: " + "(c) 1996-1997 Sun Microsystems, Inc. / " + "(c) 1997-2000 Ajuba Solutions, Inc. / " + - "(c) 2001-2003 Donal K. Fellows )\n\n" + + "(c) 2001-2007 Donal K. Fellows / " + + "(c) 2002-2007 Daniel A. Steffen )\n\n" + "Your Ruby & Tk Version ::\n" + "Ruby#{RUBY_VERSION}(#{RUBY_RELEASE_DATE})[#{RUBY_PLATFORM}] / Tk#{$tk_patchlevel}#{(Tk::JAPANIZED_TK)? '-jp': ''}\n\n" + "Ruby/Tk release date :: tcltklib #{TclTkLib::RELEASE_DATE}; tk #{Tk::RELEASE_DATE}") @@ -992,7 +1102,7 @@ ARGV.each{|cmd| end #eval(IO.readlines("#{[$demo_dir, cmd].join(File::Separator)}.rb").join, # _null_binding) - eval_samplecode(IO.readlines("#{[$demo_dir, cmd].join(File::Separator)}.rb").join) + eval_samplecode(IO.readlines("#{[$demo_dir, cmd].join(File::Separator)}.rb").join, cmd + '.rb') } if no_launcher $root.withdraw # hide root window diff --git a/ext/tk/sample/figmemo_sample.rb b/ext/tk/sample/figmemo_sample.rb new file mode 100644 index 0000000000..1b6979d2dd --- /dev/null +++ b/ext/tk/sample/figmemo_sample.rb @@ -0,0 +1,456 @@ +#!/usr/bin/env ruby +require 'tk' + +begin + # try to use Img extension + require 'tkextlib/tkimg' +rescue Exception + # cannot use Img extention --> ignore +end + + +############################ +# scrolled_canvas +class TkScrolledCanvas < TkCanvas + include TkComposite + + def initialize_composite(keys={}) + @h_scr = TkScrollbar.new(@frame) + @v_scr = TkScrollbar.new(@frame) + + @canvas = TkCanvas.new(@frame) + @path = @canvas.path + + @canvas.xscrollbar(@h_scr) + @canvas.yscrollbar(@v_scr) + + TkGrid.rowconfigure(@frame, 0, :weight=>1, :minsize=>0) + TkGrid.columnconfigure(@frame, 0, :weight=>1, :minsize=>0) + + @canvas.grid(:row=>0, :column=>0, :sticky=>'news') + @h_scr.grid(:row=>1, :column=>0, :sticky=>'ew') + @v_scr.grid(:row=>0, :column=>1, :sticky=>'ns') + + delegate('DEFAULT', @canvas) + delegate('background', @canvas, @h_scr, @v_scr) + delegate('activebackground', @h_scr, @v_scr) + delegate('troughcolor', @h_scr, @v_scr) + delegate('repeatdelay', @h_scr, @v_scr) + delegate('repeatinterval', @h_scr, @v_scr) + delegate('borderwidth', @frame) + delegate('relief', @frame) + + delegate_alias('canvasborderwidth', 'borderwidth', @canvas) + delegate_alias('canvasrelief', 'relief', @canvas) + + delegate_alias('scrollbarborderwidth', 'borderwidth', @h_scr, @v_scr) + delegate_alias('scrollbarrelief', 'relief', @h_scr, @v_scr) + + configure(keys) unless keys.empty? + end +end + +############################ +class PhotoCanvas < TkScrolledCanvas + +USAGE = <@photo) + + width = self.width + height = self.height + @scr_region = [-width, -height, width, height] + self.scrollregion(@scr_region) + self.xview_moveto(0.25) + self.yview_moveto(0.25) + + @col = 'red' + @font = 'Helvetica -12' + + @memo_id_num = -1 + @memo_id_head = 'memo_' + @memo_id_tag = nil + @overlap_d = 2 + + @state = TkVariable.new + @border = 2 + @selectborder = 1 + @delta = @border + @selectborder + @entry = TkEntry.new(self, :relief=>:ridge, :borderwidth=>@border, + :selectborderwidth=>@selectborder, + :highlightthickness=>0) + @entry.bind('Return'){@state.value = 0} + + @mode = old_mode = 0 + + _state0() + + bind('2', :x, :y){|x,y| scan_mark(x,y)} + bind('B2-Motion', :x, :y){|x,y| scan_dragto(x,y)} + + bind('3'){ + next if (old_mode = @mode) == 0 + @items.each{|item| item.delete } + _state0() + } + + bind('Double-3', :widget, :x, :y){|w, x, y| + next if old_mode != 0 + x = w.canvasx(x) + y = w.canvasy(y) + tag = nil + w.find_overlapping(x - @overlap_d, y - @overlap_d, + x + @overlap_d, y + @overlap_d).find{|item| + ! (item.tags.find{|name| + if name =~ /^(#{@memo_id_head}\d+)$/ + tag = $1 + end + }.empty?) + } + w.delete(tag) if tag + } + end + + #----------------------------------- + private + def _state0() # init + @mode = 0 + + @memo_id_num += 1 + @memo_id_tag = @memo_id_head + @memo_id_num.to_s + + @target = nil + @items = [] + @mark = [0, 0] + bind_remove('Motion') + bind('ButtonRelease-1', proc{|x,y| _state1(x,y)}, '%x', '%y') + end + + def _state1(x,y) # set center + @mode = 1 + + @target = TkcOval.new(self, + [canvasx(x), canvasy(y)], [canvasx(x), canvasy(y)], + :outline=>@col, :width=>3, :tags=>[@memo_id_tag]) + @items << @target + @mark = [x,y] + + bind('Motion', proc{|x,y| _state2(x,y)}, '%x', '%y') + bind('ButtonRelease-1', proc{|x,y| _state3(x,y)}, '%x', '%y') + end + + def _state2(x,y) # create circle + @mode = 2 + + r = Integer(Math.sqrt((x-@mark[0])**2 + (y-@mark[1])**2)) + @target.coords([canvasx(@mark[0] - r), canvasy(@mark[1] - r)], + [canvasx(@mark[0] + r), canvasy(@mark[1] + r)]) + end + + def _state3(x,y) # set line start + @mode = 3 + + @target = TkcLine.new(self, + [canvasx(x), canvasy(y)], [canvasx(x), canvasy(y)], + :arrow=>:first, :arrowshape=>[10, 14, 5], + :fill=>@col, :tags=>[@memo_id_tag]) + @items << @target + @mark = [x, y] + + bind('Motion', proc{|x,y| _state4(x,y)}, '%x', '%y') + bind('ButtonRelease-1', proc{|x,y| _state5(x,y)}, '%x', '%y') + end + + def _state4(x,y) # create line + @mode = 4 + + @target.coords([canvasx(@mark[0]), canvasy(@mark[1])], + [canvasx(x), canvasy(y)]) + end + + def _state5(x,y) # set text + @mode = 5 + + if x - @mark[0] >= 0 + justify = 'left' + dx = - @delta + + if y - @mark[1] >= 0 + anchor = 'nw' + dy = - @delta + else + anchor = 'sw' + dy = @delta + end + else + justify = 'right' + dx = @delta + + if y - @mark[1] >= 0 + anchor = 'ne' + dy = - @delta + else + anchor = 'se' + dy = @delta + end + end + + bind_remove('Motion') + + @entry.value = '' + @entry.configure(:justify=>justify, :font=>@font, :foreground=>@col) + + ewin = TkcWindow.new(self, [canvasx(x)+dx, canvasy(y)+dy], + :window=>@entry, :state=>:normal, :anchor=>anchor, + :tags=>[@memo_id_tag]) + + @entry.focus + @entry.grab + @state.wait + @entry.grab_release + + ewin.delete + + @target = TkcText.new(self, [canvasx(x), canvasy(y)], + :anchor=>anchor, :justify=>justify, + :fill=>@col, :font=>@font, :text=>@entry.value, + :tags=>[@memo_id_tag]) + + _state0() + end + + #----------------------------------- + public + def load_photo(filename) + @photo.configure(:file=>filename) + end + + def modified? + ! ((find_withtag('all') - [@img]).empty?) + end + + def fig_erase + (find_withtag('all') - [@img]).each{|item| item.delete} + end + + def reset_region + width = @photo.width + height = @photo.height + + if width > @scr_region[2] + @scr_region[0] = -width + @scr_region[2] = width + end + + if height > @scr_region[3] + @scr_region[1] = -height + @scr_region[3] = height + end + + self.scrollregion(@scr_region) + self.xview_moveto(0.25) + self.yview_moveto(0.25) + end + + def get_texts + ret = [] + find_withtag('all').each{|item| + if item.kind_of?(TkcText) + ret << item[:text] + end + } + ret + end +end +############################ + +# define methods for menu +def open_file(canvas, fname) + if canvas.modified? + ret = Tk.messageBox(:icon=>'warning',:type=>'okcancel',:default=>'cancel', + :message=>'Canvas may be modified. Realy erase? ') + return if ret == 'cancel' + end + + filetypes = [ + ['GIF Files', '.gif'], + ['GIF Files', [], 'GIFF'], + ['PPM Files', '.ppm'], + ['PGM Files', '.pgm'] + ] + + begin + if Tk::Img::package_version != '' + filetypes << ['JPEG Files', ['.jpg', '.jpeg']] + filetypes << ['PNG Files', '.png'] + filetypes << ['PostScript Files', '.ps'] + filetypes << ['PDF Files', '.pdf'] + filetypes << ['Windows Bitmap Files', '.bmp'] + filetypes << ['Windows Icon Files', '.ico'] + filetypes << ['PCX Files', '.pcx'] + filetypes << ['Pixmap Files', '.pixmap'] + filetypes << ['SGI Files', '.sgi'] + filetypes << ['Sun Raster Files', '.sun'] + filetypes << ['TGA Files', '.tga'] + filetypes << ['TIFF Files', '.tiff'] + filetypes << ['XBM Files', '.xbm'] + filetypes << ['XPM Files', '.xpm'] + end + rescue + end + + filetypes << ['ALL Files', '*'] + + fpath = Tk.getOpenFile(:filetypes=>filetypes) + return if fpath.empty? + + begin + canvas.load_photo(fpath) + rescue => e + Tk.messageBox(:icon=>'error', :type=>'ok', + :message=>"Fail to read '#{fpath}'.\n#{e.message}") + end + + canvas.fig_erase + canvas.reset_region + + fname.value = fpath +end + +# -------------------------------- +def save_memo(canvas, fname) + initname = fname.value + if initname != '-' + initname = File.basename(initname, File.extname(initname)) + fpath = Tk.getSaveFile(:filetypes=>[ ['Text Files', '.txt'], + ['ALL Files', '*'] ], + :initialfile=>initname) + else + fpath = Tk.getSaveFile(:filetypes=>[ ['Text Files', '.txt'], + ['ALL Files', '*'] ]) + end + return if fpath.empty? + + begin + fid = open(fpath, 'w') + rescue => e + Tk.messageBox(:icon=>'error', :type=>'ok', + :message=>"Fail to open '#{fname.value}'.\n#{e.message}") + end + + begin + canvas.get_texts.each{|txt| + fid.print(txt, "\n") + } + ensure + fid.close + end +end + +# -------------------------------- +def ps_print(canvas, fname) + initname = fname.value + if initname != '-' + initname = File.basename(initname, File.extname(initname)) + fpath = Tk.getSaveFile(:filetypes=>[ ['Postscript Files', '.ps'], + ['ALL Files', '*'] ], + :initialfile=>initname) + else + fpath = Tk.getSaveFile(:filetypes=>[ ['Postscript Files', '.ps'], + ['ALL Files', '*'] ]) + end + return if fpath.empty? + + bbox = canvas.bbox('all') + canvas.postscript(:file=>fpath, :x=>bbox[0], :y=>bbox[1], + :width=>bbox[2] - bbox[0], :height=>bbox[3] - bbox[1]) +end + +# -------------------------------- +def quit(canvas) + ret = Tk.messageBox(:icon=>'warning', :type=>'okcancel', + :default=>'cancel', + :message=>'Realy quit? ') + exit if ret == 'ok' +end + +# -------------------------------- +# setup root +root = TkRoot.new(:title=>'Fig Memo') + +# create canvas frame +canvas = PhotoCanvas.new(root).pack(:fill=>:both, :expand=>true) +usage_frame = TkFrame.new(root, :relief=>:ridge, :borderwidth=>2) +hide_btn = TkButton.new(usage_frame, :text=>'hide usage', + :font=>{:size=>8}, :pady=>1, + :command=>proc{usage_frame.unpack}) +hide_btn.pack(:anchor=>'e', :padx=>5) +usage = TkLabel.new(usage_frame, :text=>PhotoCanvas::USAGE, + :font=>'Helvetica 8', :justify=>:left).pack + +show_usage = proc{ + usage_frame.pack(:before=>canvas, :fill=>:x, :expand=>true) +} + +fname = TkVariable.new('-') +f = TkFrame.new(root, :relief=>:sunken, :borderwidth=>1).pack(:fill=>:x) +label = TkLabel.new(f, :textvariable=>fname, + :font=>{:size=>-12, :weight=>:bold}, + :anchor=>'w').pack(:side=>:left, :fill=>:x, :padx=>10) + +# create menu +mspec = [ + [ ['File', 0], + ['Show Usage', proc{show_usage.call}, 5], + '---', + ['Open Image File', proc{open_file(canvas, fname)}, 0], + ['Save Memo Texts', proc{save_memo(canvas, fname)}, 0], + '---', + ['Save Postscript', proc{ps_print(canvas, fname)}, 5], + '---', + ['Quit', proc{quit(canvas)}, 0] + ] +] +root.add_menubar(mspec) + +# manage wm_protocol +root.protocol(:WM_DELETE_WINDOW){quit(canvas)} + +# show usage +show_usage.call + +# -------------------------------- +# start eventloop +Tk.mainloop diff --git a/ext/tk/sample/tkextlib/treectrl/demo.rb b/ext/tk/sample/tkextlib/treectrl/demo.rb index 50ecde91f0..eed95d0e1c 100644 --- a/ext/tk/sample/tkextlib/treectrl/demo.rb +++ b/ext/tk/sample/tkextlib/treectrl/demo.rb @@ -9,11 +9,12 @@ $HasColumnCreate = Tk::TreeCtrl::HasColumnCreateCommand $Version_1_1_OrLater = (TkPackage.vcompare(Tk::TreeCtrl.package_version, '1.1') >= 0) -if Hash.instance_methods.include?('key') - # probably ruby 1.9.x --> use Hash#key +#if Hash.instance_methods.include?(:key) +if TkCore::WITH_RUBY_VM ### Ruby 1.9 !!!! + # ruby 1.9.x --> use Hash#key # Because Hash#index show warning "Hash#index is deprecated; use Hash#key". else - # probably ruby 1.8.x --> use Hash#index + # ruby 1.8.x --> use Hash#index class Hash alias key index end diff --git a/ext/tk/tcltklib.c b/ext/tk/tcltklib.c index 680b8da984..8701cfef27 100644 --- a/ext/tk/tcltklib.c +++ b/ext/tk/tcltklib.c @@ -4,7 +4,7 @@ * Oct. 24, 1997 Y. Matsumoto */ -#define TCLTKLIB_RELEASE_DATE "2008-05-16" +#define TCLTKLIB_RELEASE_DATE "2008-05-23" #include "ruby.h" @@ -171,7 +171,7 @@ static ID ID_inspect; static VALUE ip_invoke_real _((int, VALUE*, VALUE)); static VALUE ip_invoke _((int, VALUE*, VALUE)); - +static VALUE ip_invoke_with_position _((int, VALUE*, VALUE, Tcl_QueuePosition)); static VALUE tk_funcall _((VALUE(), int, VALUE*, VALUE)); /* Tcl's object type */ @@ -397,19 +397,24 @@ static VALUE eventloop_thread; Tcl_ThreadId tk_eventloop_thread_id; /* native thread ID of Tcl interpreter */ #endif static VALUE eventloop_stack; -static int window_event_mode = ~(TCL_WINDOW_EVENTS | TCL_IDLE_EVENTS); +static int window_event_mode = ( ~ TCL_IDLE_EVENTS | TCL_WINDOW_EVENTS ); static VALUE watchdog_thread; Tcl_Interp *current_interp; /* thread control strategy */ -#define CONTROL_BY_STATUS_OF_RB_THREAD_WAIT_FOR_VALUE 0 +/* multi-tk works with the following settings only ??? + : CONTROL_BY_STATUS_OF_RB_THREAD_WAITING_FOR_VALUE 1 + : USE_TOGGLE_WINDOW_MODE_FOR_IDLE 0 + : DO_THREAD_SCHEDULE_AT_CALLBACK_DONE 0 +*/ +#define CONTROL_BY_STATUS_OF_RB_THREAD_WAITING_FOR_VALUE 1 #define USE_TOGGLE_WINDOW_MODE_FOR_IDLE 0 -#define DO_THREAD_SCHEDULE_AT_CALLBACK_DONE 1 +#define DO_THREAD_SCHEDULE_AT_CALLBACK_DONE 0 -#if CONTROL_BY_STATUS_OF_RB_THREAD_WAIT_FOR_VALUE -static int have_rb_thread_waited_for_value = 0; +#if CONTROL_BY_STATUS_OF_RB_THREAD_WAITING_FOR_VALUE +static int have_rb_thread_waiting_for_value = 0; #endif /* @@ -426,9 +431,6 @@ static int have_rb_thread_waited_for_value = 0; #define WATCHDOG_INTERVAL 10/*milliseconds ( 1 -- 999 ) */ #define DEFAULT_TIMER_TICK 0/*milliseconds ( 0 -- 999 ) */ #define NO_THREAD_INTERRUPT_TIME 100/*milliseconds ( 1 -- 999 ) */ -#if CONTROL_BY_STATUS_OF_RB_THREAD_WAIT_FOR_VALUE -#define DEFAULT_HAS_WAIT_THREAD_TICK 50/*counts*/ -#endif #else /* ! RUBY_VM */ #define DEFAULT_EVENT_LOOP_MAX 800/*counts*/ #define DEFAULT_NO_EVENT_TICK 10/*counts*/ @@ -436,9 +438,6 @@ static int have_rb_thread_waited_for_value = 0; #define WATCHDOG_INTERVAL 10/*milliseconds ( 1 -- 999 ) */ #define DEFAULT_TIMER_TICK 0/*milliseconds ( 0 -- 999 ) */ #define NO_THREAD_INTERRUPT_TIME 100/*milliseconds ( 1 -- 999 ) */ -#if CONTROL_BY_STATUS_OF_RB_THREAD_WAIT_FOR_VALUE -#define DEFAULT_HAS_WAIT_THREAD_TICK 50/*counts*/ -#endif #endif static int event_loop_max = DEFAULT_EVENT_LOOP_MAX; @@ -447,9 +446,6 @@ static int no_event_wait = DEFAULT_NO_EVENT_WAIT; static int timer_tick = DEFAULT_TIMER_TICK; static int req_timer_tick = DEFAULT_TIMER_TICK; static int run_timer_flag = 0; -#if CONTROL_BY_STATUS_OF_RB_THREAD_WAIT_FOR_VALUE -static int has_wait_thread_tick = DEFAULT_HAS_WAIT_THREAD_TICK; -#endif static int event_loop_wait_event = 0; static int event_loop_abort_on_exc = 1; @@ -967,8 +963,10 @@ call_original_exit(ptr, state) int thr_crit_bup; Tcl_CmdInfo *info; #if TCL_MAJOR_VERSION >= 8 + Tcl_Obj *cmd_obj; Tcl_Obj *state_obj; #endif + DUMP1("original_exit is called"); if (!(ptr->has_orig_exit)) return; @@ -986,35 +984,54 @@ call_original_exit(ptr, state) if (info->isNativeObjectProc) { Tcl_Obj **argv; - /* argv = (Tcl_Obj **)ALLOC_N(Tcl_Obj *, 3); */ /* XXXXXXXXXX */ +#define USE_RUBY_ALLOC 0 +#if USE_RUBY_ALLOC + argv = (Tcl_Obj **)ALLOC_N(Tcl_Obj *, 3); +#else /* not USE_RUBY_ALLOC */ argv = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * 3); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)argv); /* XXXXXXXX */ #endif - argv[0] = Tcl_NewStringObj("exit", 4); +#endif + cmd_obj = Tcl_NewStringObj("exit", 4); + Tcl_IncrRefCount(cmd_obj); + + argv[0] = cmd_obj; argv[1] = state_obj; argv[2] = (Tcl_Obj *)NULL; ptr->return_value = (*(info->objProc))(info->objClientData, ptr->ip, 2, argv); + Tcl_DecrRefCount(cmd_obj); + +#if USE_RUBY_ALLOC + free(argv); +#else /* not USE_RUBY_ALLOC */ #if 0 /* use Tcl_EventuallyFree */ Tcl_EventuallyFree((ClientData)argv, TCL_DYNAMIC); /* XXXXXXXX */ #else #if 0 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)argv); /* XXXXXXXX */ -#endif +#else /* free(argv); */ ckfree((char*)argv); #endif +#endif +#endif +#undef USE_RUBY_ALLOC } else { /* string interface */ char **argv; - /* argv = (char **)ALLOC_N(char *, 3); */ /* XXXXXXXXXX */ +#define USE_RUBY_ALLOC 0 +#if USE_RUBY_ALLOC + argv = (char **)ALLOC_N(char *, 3); /* XXXXXXXXXX */ +#else /* not USE_RUBY_ALLOC */ argv = (char **)ckalloc(sizeof(char *) * 3); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)argv); /* XXXXXXXX */ +#endif #endif argv[0] = "exit"; /* argv[1] = Tcl_GetString(state_obj); */ @@ -1024,15 +1041,21 @@ call_original_exit(ptr, state) ptr->return_value = (*(info->proc))(info->clientData, ptr->ip, 2, (CONST84 char **)argv); +#if USE_RUBY_ALLOC + free(argv); +#else /* not USE_RUBY_ALLOC */ #if 0 /* use Tcl_EventuallyFree */ Tcl_EventuallyFree((ClientData)argv, TCL_DYNAMIC); /* XXXXXXXX */ #else #if 0 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)argv); /* XXXXXXXX */ -#endif +#else /* free(argv); */ ckfree((char*)argv); #endif +#endif +#endif +#undef USE_RUBY_ALLOC } Tcl_DecrRefCount(state_obj); @@ -1041,10 +1064,14 @@ call_original_exit(ptr, state) { /* string interface */ char **argv; - /* argv = (char **)ALLOC_N(char *, 3); */ +#define USE_RUBY_ALLOC 0 +#if USE_RUBY_ALLOC + argv = (char **)ALLOC_N(char *, 3); +#else /* not USE_RUBY_ALLOC */ argv = (char **)ckalloc(sizeof(char *) * 3); #if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)argv); /* XXXXXXXX */ +#endif #endif argv[0] = "exit"; argv[1] = RSTRING_PTR(rb_fix2str(INT2NUM(state), 10)); @@ -1053,17 +1080,24 @@ call_original_exit(ptr, state) ptr->return_value = (*(info->proc))(info->clientData, ptr->ip, 2, argv); +#if USE_RUBY_ALLOC + free(argv); +#else /* not USE_RUBY_ALLOC */ #if 0 /* use Tcl_EventuallyFree */ Tcl_EventuallyFree((ClientData)argv, TCL_DYNAMIC); /* XXXXXXXX */ #else #if 0 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)argv); /* XXXXXXXX */ -#endif +#else /* free(argv); */ ckfree(argv); #endif +#endif +#endif +#undef USE_RUBY_ALLOC } #endif + DUMP1("complete original_exit"); rb_thread_critical = thr_crit_bup; } @@ -1110,10 +1144,14 @@ static int toggle_eventloop_window_mode_for_idle() { if (window_event_mode & TCL_IDLE_EVENTS) { + /* idle -> event */ + window_event_mode |= TCL_WINDOW_EVENTS; window_event_mode &= ~TCL_IDLE_EVENTS; return 1; } else { + /* event -> idle */ window_event_mode |= TCL_IDLE_EVENTS; + window_event_mode &= ~TCL_WINDOW_EVENTS; return 0; } } @@ -1443,7 +1481,11 @@ static VALUE lib_num_of_mainwindows(self) VALUE self; { +#ifdef RUBY_VM /* Ruby 1.9+ !!! */ return tk_funcall(lib_num_of_mainwindows_core, 0, (VALUE*)NULL, self); +#else + return lib_num_of_mainwindows_core(self, 0, (VALUE*)NULL); +#endif } @@ -1789,10 +1831,10 @@ lib_eventloop_core(check_root, update_flag, check_var, interp) if (!st) { if (toggle_eventloop_window_mode_for_idle()) { /* idle-mode -> event-mode*/ - tick_counter = 0; + tick_counter = event_loop_max; } else { /* event-mode -> idle-mode */ - tick_counter = event_loop_max; + tick_counter = 0; } } #endif @@ -1802,6 +1844,14 @@ lib_eventloop_core(check_root, update_flag, check_var, interp) st = RTEST(rb_protect(call_DoOneEvent, INT2FIX(event_flag), &status)); #endif + +#if CONTROL_BY_STATUS_OF_RB_THREAD_WAITING_FOR_VALUE + if (have_rb_thread_waiting_for_value) { + have_rb_thread_waiting_for_value = 0; + rb_thread_schedule(); + } +#endif + if (status) { switch (status) { case TAG_RAISE: @@ -1877,13 +1927,6 @@ lib_eventloop_core(check_root, update_flag, check_var, interp) return 0; } -#if CONTROL_BY_STATUS_OF_RB_THREAD_WAIT_FOR_VALUE - if (have_rb_thread_waited_for_value) { - tick_counter += no_event_tick; - have_rb_thread_waited_for_value = 0; - } -#endif - if (st) { tick_counter++; } else { @@ -1950,7 +1993,8 @@ lib_eventloop_core(check_root, update_flag, check_var, interp) } else { DUMP2("sleep eventloop %lx", current); DUMP2("eventloop thread is %lx", eventloop_thread); - rb_thread_stop(); + /* rb_thread_stop(); */ + rb_thread_sleep_forever(); } if (!NIL_P(watchdog_thread) && eventloop_thread != current) { @@ -2126,7 +2170,8 @@ lib_eventloop_ensure(args) break; } - if (RTEST(rb_funcall(eventloop_thread, ID_alive_p, 0, 0))) { + /* if (RTEST(rb_funcall(eventloop_thread, ID_alive_p, 0, 0))) { */ + if (RTEST(rb_thread_alive_p(eventloop_thread))) { DUMP2("eventloop-enshure: wake up parent %lx", eventloop_thread); rb_thread_wakeup(eventloop_thread); @@ -2444,7 +2489,8 @@ lib_thread_callback(argc, argv, self) foundEvent = RTEST(lib_eventloop_launcher(/* not check root-widget */0, 0, q->done, (Tcl_Interp*)NULL)); - if (RTEST(rb_funcall(th, ID_alive_p, 0))) { + /* if (RTEST(rb_funcall(th, ID_alive_p, 0))) { */ + if (RTEST(rb_thread_alive_p(th))) { rb_funcall(th, ID_kill, 0); ret = Qnil; } else { @@ -2658,12 +2704,15 @@ tcl_protect_core(interp, proc, data) /* should not raise exception */ int status = 0; int thr_crit_bup = rb_thread_critical; + Tcl_ResetResult(interp); + rb_thread_critical = Qfalse; ret = rb_protect(proc, data, &status); rb_thread_critical = Qtrue; if (status) { char *buf; - VALUE old_gc, type, str; + VALUE old_gc; + volatile VALUE type, str; old_gc = rb_gc_disable(); @@ -3125,10 +3174,6 @@ ip_ruby_cmd(clientData, interp, argc, argv) #endif } - /* allocate */ - arg = ALLOC(struct cmd_body_arg); - /* arg = (struct cmd_body_arg *)ckalloc(sizeof(struct cmd_body_arg)); */ - /* get arguments from Tcl objects */ thr_crit_bup = rb_thread_critical; rb_thread_critical = Qtrue; @@ -3194,6 +3239,10 @@ ip_ruby_cmd(clientData, interp, argc, argv) if (old_gc == Qfalse) rb_gc_enable(); rb_thread_critical = thr_crit_bup; + /* allocate */ + arg = ALLOC(struct cmd_body_arg); + /* arg = (struct cmd_body_arg *)ckalloc(sizeof(struct cmd_body_arg)); */ + arg->receiver = receiver; arg->method = method; arg->args = args; @@ -3393,6 +3442,8 @@ ip_rbUpdateCommand(clientData, interp, objc, objv) #endif #endif + Tcl_ResetResult(interp); + if (objc == 1) { flags = TCL_DONT_WAIT; @@ -3561,6 +3612,8 @@ ip_rb_threadUpdateCommand(clientData, interp, objc, objv) DUMP1("start Ruby's 'thread_update' body"); + Tcl_ResetResult(interp); + if (objc == 1) { flags = TCL_DONT_WAIT; @@ -3620,7 +3673,8 @@ ip_rb_threadUpdateCommand(clientData, interp, objc, objv) while(!param->done) { DUMP1("wait for complete idle proc"); - rb_thread_stop(); + /* rb_thread_stop(); */ + rb_thread_sleep_forever(); } #if 0 /* use Tcl_EventuallyFree */ @@ -3628,9 +3682,10 @@ ip_rb_threadUpdateCommand(clientData, interp, objc, objv) #else #if 0 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)param); -#endif +#else /* Tcl_Free((char *)param); */ ckfree((char *)param); +#endif #endif DUMP1("finish Ruby's 'thread_update'"); @@ -3743,6 +3798,8 @@ ip_rbVwaitCommand(clientData, interp, objc, objv) #endif #endif + Tcl_ResetResult(interp); + if (objc != 2) { #ifdef Tcl_WrongNumArgs Tcl_WrongNumArgs(interp, 1, objv, "name"); @@ -3978,6 +4035,7 @@ ip_rbTkWaitCommand(clientData, interp, objc, objv) #endif Tcl_Preserve(interp); + Tcl_ResetResult(interp); if (objc != 3) { #ifdef Tcl_WrongNumArgs @@ -4334,7 +4392,7 @@ rb_threadVwaitProc(clientData, interp, name1, name2, flags) } else { param->done = 1; } - rb_thread_wakeup(param->thread); + if (param->done != 0) rb_thread_wakeup(param->thread); return (char *)NULL; } @@ -4356,7 +4414,7 @@ rb_threadWaitVisibilityProc(clientData, eventPtr) if (eventPtr->type == DestroyNotify) { param->done = TKWAIT_MODE_DESTROY; } - rb_thread_wakeup(param->thread); + if (param->done != 0) rb_thread_wakeup(param->thread); } static void rb_threadWaitWindowProc _((ClientData, XEvent *)); @@ -4370,7 +4428,7 @@ rb_threadWaitWindowProc(clientData, eventPtr) if (eventPtr->type == DestroyNotify) { param->done = TKWAIT_MODE_DESTROY; } - rb_thread_wakeup(param->thread); + if (param->done != 0) rb_thread_wakeup(param->thread); } #if TCL_MAJOR_VERSION >= 8 @@ -4413,6 +4471,7 @@ ip_rb_threadVwaitCommand(clientData, interp, objc, objv) } Tcl_Preserve(interp); + Tcl_ResetResult(interp); if (objc != 2) { #ifdef Tcl_WrongNumArgs @@ -4449,7 +4508,7 @@ ip_rb_threadVwaitCommand(clientData, interp, objc, objv) /* param = (struct th_vwait_param *)Tcl_Alloc(sizeof(struct th_vwait_param)); */ param = (struct th_vwait_param *)ckalloc(sizeof(struct th_vwait_param)); -#if 0 /* use Tcl_Preserve/Release */ +#if 1 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)param); #endif param->thread = current_thread; @@ -4472,12 +4531,13 @@ ip_rb_threadVwaitCommand(clientData, interp, objc, objv) #if 0 /* use Tcl_EventuallyFree */ Tcl_EventuallyFree((ClientData)param, TCL_DYNAMIC); /* XXXXXXXX */ #else -#if 0 /* use Tcl_Preserve/Release */ +#if 1 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)param); -#endif +#else /* Tcl_Free((char *)param); */ ckfree((char *)param); #endif +#endif #if TCL_MAJOR_VERSION >= 8 Tcl_DecrRefCount(objv[1]); @@ -4486,9 +4546,9 @@ ip_rb_threadVwaitCommand(clientData, interp, objc, objv) return TCL_ERROR; } - /* if (!param->done) { */ while(!param->done) { - rb_thread_stop(); + /* rb_thread_stop(); */ + rb_thread_sleep_forever(); } thr_crit_bup = rb_thread_critical; @@ -4503,11 +4563,12 @@ ip_rb_threadVwaitCommand(clientData, interp, objc, objv) #if 0 /* use Tcl_EventuallyFree */ Tcl_EventuallyFree((ClientData)param, TCL_DYNAMIC); /* XXXXXXXX */ #else -#if 0 /* use Tcl_Preserve/Release */ +#if 1 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)param); -#endif +#else /* Tcl_Free((char *)param); */ ckfree((char *)param); +#endif #endif rb_thread_critical = thr_crit_bup; @@ -4567,6 +4628,8 @@ ip_rb_threadTkWaitCommand(clientData, interp, objc, objv) Tcl_Preserve(interp); Tcl_Preserve(tkwin); + Tcl_ResetResult(interp); + if (objc != 3) { #ifdef Tcl_WrongNumArgs Tcl_WrongNumArgs(interp, 1, objv, "variable|visibility|window name"); @@ -4651,7 +4714,7 @@ ip_rb_threadTkWaitCommand(clientData, interp, objc, objv) /* param = (struct th_vwait_param *)Tcl_Alloc(sizeof(struct th_vwait_param)); */ param = (struct th_vwait_param *)ckalloc(sizeof(struct th_vwait_param)); -#if 0 /* use Tcl_Preserve/Release */ +#if 1 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)param); #endif param->thread = current_thread; @@ -4680,12 +4743,13 @@ ip_rb_threadTkWaitCommand(clientData, interp, objc, objv) #if 0 /* use Tcl_EventuallyFree */ Tcl_EventuallyFree((ClientData)param, TCL_DYNAMIC); /* XXXXXXXX */ #else -#if 0 /* use Tcl_Preserve/Release */ +#if 1 /* use Tcl_Preserve/Release */ Tcl_Release(param); -#endif +#else /* Tcl_Free((char *)param); */ ckfree((char *)param); #endif +#endif #if TCL_MAJOR_VERSION >= 8 Tcl_DecrRefCount(objv[2]); @@ -4696,9 +4760,9 @@ ip_rb_threadTkWaitCommand(clientData, interp, objc, objv) return TCL_ERROR; } - /* if (!param->done) { */ while(!param->done) { - rb_thread_stop(); + /* rb_thread_stop(); */ + rb_thread_sleep_forever(); } thr_crit_bup = rb_thread_critical; @@ -4752,12 +4816,13 @@ ip_rb_threadTkWaitCommand(clientData, interp, objc, objv) #if 0 /* use Tcl_EventuallyFree */ Tcl_EventuallyFree((ClientData)param, TCL_DYNAMIC); /* XXXXXXXX */ #else -#if 0 /* use Tcl_Preserve/Release */ +#if 1 /* use Tcl_Preserve/Release */ Tcl_Release(param); -#endif +#else /* Tcl_Free((char *)param); */ ckfree((char *)param); #endif +#endif #if TCL_MAJOR_VERSION >= 8 Tcl_DecrRefCount(objv[2]); @@ -4774,15 +4839,10 @@ ip_rb_threadTkWaitCommand(clientData, interp, objc, objv) rb_thread_critical = thr_crit_bup; - /* if (!param->done) { */ - /* - while(!param->done) { - rb_thread_stop(); - } - */ while(param->done != TKWAIT_MODE_VISIBILITY) { if (param->done == TKWAIT_MODE_DESTROY) break; - rb_thread_stop(); + /* rb_thread_stop(); */ + rb_thread_sleep_forever(); } thr_crit_bup = rb_thread_critical; @@ -4809,12 +4869,13 @@ ip_rb_threadTkWaitCommand(clientData, interp, objc, objv) #if 0 /* use Tcl_EventuallyFree */ Tcl_EventuallyFree((ClientData)param, TCL_DYNAMIC); /* XXXXXXXX */ #else -#if 0 /* use Tcl_Preserve/Release */ +#if 1 /* use Tcl_Preserve/Release */ Tcl_Release(param); -#endif +#else /* Tcl_Free((char *)param); */ ckfree((char *)param); #endif +#endif #if TCL_MAJOR_VERSION >= 8 Tcl_DecrRefCount(objv[2]); @@ -4873,11 +4934,12 @@ ip_rb_threadTkWaitCommand(clientData, interp, objc, objv) #if 0 /* use Tcl_EventuallyFree */ Tcl_EventuallyFree((ClientData)param, TCL_DYNAMIC); /* XXXXXXXX */ #else -#if 0 /* use Tcl_Preserve/Release */ +#if 1 /* use Tcl_Preserve/Release */ Tcl_Release(param); -#endif +#else /* Tcl_Free((char *)param); */ ckfree((char *)param); +#endif #endif Tcl_Release(tkwin); @@ -4892,14 +4954,9 @@ ip_rb_threadTkWaitCommand(clientData, interp, objc, objv) rb_thread_critical = thr_crit_bup; - /* if (!param->done) { */ - /* - while(!param->done) { - rb_thread_stop(); - } - */ while(param->done != TKWAIT_MODE_DESTROY) { - rb_thread_stop(); + /* rb_thread_stop(); */ + rb_thread_sleep_forever(); } Tcl_Release(window); @@ -4920,11 +4977,12 @@ ip_rb_threadTkWaitCommand(clientData, interp, objc, objv) #if 0 /* use Tcl_EventuallyFree */ Tcl_EventuallyFree((ClientData)param, TCL_DYNAMIC); /* XXXXXXXX */ #else -#if 0 /* use Tcl_Preserve/Release */ +#if 1 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)param); -#endif +#else /* Tcl_Free((char *)param); */ ckfree((char *)param); +#endif #endif /* @@ -4950,7 +5008,7 @@ ip_thread_vwait(self, var) argv[0] = cmd_str; argv[1] = var; - return ip_invoke_real(2, argv, self); + return ip_invoke_with_position(2, argv, self, TCL_QUEUE_TAIL); } static VALUE @@ -4966,7 +5024,7 @@ ip_thread_tkwait(self, mode, target) argv[1] = mode; argv[2] = target; - return ip_invoke_real(3, argv, self); + return ip_invoke_with_position(3, argv, self, TCL_QUEUE_TAIL); } @@ -5156,15 +5214,17 @@ ip_finalize(ip) Tcl_CreateCommand(ip, "ruby_cmd", ip_null_proc, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); #endif - rb_thread_critical = thr_crit_bup; - return; + /* + rb_thread_critical = thr_crit_bup; + return; + */ } /* delete root widget */ -#if 0 +#if 1 DUMP1("check `destroy'"); if (Tcl_GetCommandInfo(ip, "destroy", &info)) { - DUMP1("call `destroy'"); + DUMP1("call `destroy .'"); Tcl_GlobalEval(ip, "catch {destroy .}"); } #endif @@ -5183,10 +5243,14 @@ ip_finalize(ip) * Although it is the problem, it is possibly avoidable by * rescuing exceptions and the finalize hook of the interp. */ + Tk_Window win = Tk_MainWindow(ip); + DUMP1("call Tk_DestroyWindow"); ruby_debug = Qfalse; ruby_verbose = Qnil; - Tk_DestroyWindow(Tk_MainWindow(ip)); + if (! (((Tk_FakeWin*)win)->flags & TK_ALREADY_DEAD)) { + Tk_DestroyWindow(win); + } ruby_debug = rb_debug_bup; ruby_verbose = rb_verbose_bup; } @@ -5209,7 +5273,7 @@ ip_finalize(ip) DUMP1("cancel after callbacks"); ruby_debug = Qfalse; ruby_verbose = Qnil; - Tcl_GlobalEval(ip, "foreach id [after info] {after cancel $id}"); + Tcl_GlobalEval(ip, "catch {foreach id [after info] {after cancel $id}}"); ruby_debug = rb_debug_bup; ruby_verbose = rb_verbose_bup; } @@ -5251,8 +5315,8 @@ ip_free(ptr) if (ptr->ip == (Tcl_Interp*)NULL) { DUMP1("ip_free is called for deleted IP"); - /* free(ptr); */ - ckfree((char*)ptr); + free(ptr); + /* ckfree((char*)ptr); */ rb_thread_critical = thr_crit_bup; return; } @@ -5405,9 +5469,10 @@ ip_rbNamespaceObjCmd(clientData, interp, objc, objv) #else #if 0 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)argv); /* XXXXXXXX */ -#endif +#else /* Tcl_Free((char*)argv); */ ckfree((char*)argv); +#endif #endif } @@ -6282,12 +6347,12 @@ call_queue_handler(evPtr, flags) struct call_queue *q = (struct call_queue *)evPtr; volatile VALUE ret; volatile VALUE q_dat; + volatile VALUE thread = q->thread; struct tcltkip *ptr; DUMP2("do_call_queue_handler : evPtr = %p", evPtr); DUMP2("call_queue_handler thread : %lx", rb_thread_current()); - DUMP2("added by thread : %lx", q->thread); - + DUMP2("added by thread : %lx", thread); if (*(q->done)) { DUMP1("processed by another event-loop"); @@ -6296,6 +6361,12 @@ call_queue_handler(evPtr, flags) DUMP1("process it on current event-loop"); } + if (RTEST(rb_thread_alive_p(thread)) + && ! RTEST(rb_funcall(thread, ID_stop_p, 0))) { + DUMP1("caller is not yet ready to receive the result -> pending"); + return 0; + } + /* process it */ *(q->done) = 1; @@ -6316,14 +6387,16 @@ call_queue_handler(evPtr, flags) ret = rb_funcall(rb_proc_new(callq_safelevel_handler, q_dat), ID_call, 0); rb_gc_force_recycle(q_dat); + q_dat = (VALUE)NULL; } else { - DUMP2("call function (for caller thread:%lx)", q->thread); + DUMP2("call function (for caller thread:%lx)", thread); DUMP2("call function (current thread:%lx)", rb_thread_current()); ret = (q->func)(q->interp, q->argc, q->argv); } /* set result */ RARRAY_PTR(q->result)[0] = ret; + ret = (VALUE)NULL; /* decr internal handler mark */ rbtk_internal_eventloop_handler--; @@ -6331,22 +6404,29 @@ call_queue_handler(evPtr, flags) /* complete */ *(q->done) = -1; + /* unlink ruby objects */ + q->argv = (VALUE*)NULL; + q->interp = (VALUE)NULL; + q->result = (VALUE)NULL; + q->thread = (VALUE)NULL; + /* back to caller */ - if (RTEST(rb_funcall(q->thread, ID_alive_p, 0, 0))) { - DUMP2("back to caller (caller thread:%lx)", q->thread); + /* if (RTEST(rb_funcall(thread, ID_alive_p, 0, 0))) { */ + if (RTEST(rb_thread_alive_p(thread))) { + DUMP2("back to caller (caller thread:%lx)", thread); DUMP2(" (current thread:%lx)", rb_thread_current()); -#if CONTROL_BY_STATUS_OF_RB_THREAD_WAIT_FOR_VALUE - have_rb_thread_waited_for_value = 1; - rb_thread_wakeup(q->thread); +#if CONTROL_BY_STATUS_OF_RB_THREAD_WAITING_FOR_VALUE + have_rb_thread_waiting_for_value = 1; + rb_thread_wakeup(thread); #else - rb_thread_run(q->thread); + rb_thread_run(thread); #endif DUMP1("finish back to caller"); #if DO_THREAD_SCHEDULE_AT_CALLBACK_DONE rb_thread_schedule(); #endif } else { - DUMP2("caller is dead (caller thread:%lx)", q->thread); + DUMP2("caller is dead (caller thread:%lx)", thread); DUMP2(" (current thread:%lx)", rb_thread_current()); } @@ -6434,7 +6514,7 @@ tk_funcall(func, argc, argv, obj) /* allocate memory (freed by Tcl_ServiceEvent) */ /* callq = (struct call_queue *)Tcl_Alloc(sizeof(struct call_queue)); */ callq = (struct call_queue *)ckalloc(sizeof(struct call_queue)); -#if 1 /* use Tcl_Preserve/Release */ +#if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve(callq); #endif @@ -6456,17 +6536,24 @@ tk_funcall(func, argc, argv, obj) DUMP1("add handler"); #ifdef RUBY_VM if (ptr && ptr->tk_thread_id) { - Tcl_ThreadQueueEvent(ptr->tk_thread_id, &(callq->ev), TCL_QUEUE_HEAD); + /* Tcl_ThreadQueueEvent(ptr->tk_thread_id, + &(callq->ev), TCL_QUEUE_HEAD); */ + Tcl_ThreadQueueEvent(ptr->tk_thread_id, + (Tcl_Event*)callq, TCL_QUEUE_HEAD); Tcl_ThreadAlert(ptr->tk_thread_id); } else if (tk_eventloop_thread_id) { + /* Tcl_ThreadQueueEvent(tk_eventloop_thread_id, + &(callq->ev), TCL_QUEUE_HEAD); */ Tcl_ThreadQueueEvent(tk_eventloop_thread_id, - &(callq->ev), TCL_QUEUE_HEAD); + (Tcl_Event*)callq, TCL_QUEUE_HEAD); Tcl_ThreadAlert(tk_eventloop_thread_id); } else { - Tcl_QueueEvent(&(callq->ev), TCL_QUEUE_HEAD); + /* Tcl_QueueEvent(&(callq->ev), TCL_QUEUE_HEAD); */ + Tcl_QueueEvent((Tcl_Event*)callq, TCL_QUEUE_HEAD); } #else - Tcl_QueueEvent(&(callq->ev), TCL_QUEUE_HEAD); + /* Tcl_QueueEvent(&(callq->ev), TCL_QUEUE_HEAD); */ + Tcl_QueueEvent((Tcl_Event*)callq, TCL_QUEUE_HEAD); #endif rb_thread_critical = thr_crit_bup; @@ -6475,7 +6562,8 @@ tk_funcall(func, argc, argv, obj) DUMP2("wait for handler (current thread:%lx)", current); while(*alloc_done >= 0) { DUMP2("*** wait for handler (current thread:%lx)", current); - rb_thread_stop(); + /* rb_thread_stop(); */ + rb_thread_sleep_forever(); DUMP2("*** wakeup (current thread:%lx)", current); } DUMP2("back from handler (current thread:%lx)", current); @@ -6487,27 +6575,34 @@ tk_funcall(func, argc, argv, obj) #else #if 0 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)alloc_done); /* XXXXXXXX */ -#endif +#else /* free(alloc_done); */ ckfree((char*)alloc_done); +#endif #endif /* if (argv) free(argv); */ if (argv) { /* if argv != NULL, alloc as 'temp' */ + int i; + for(i = 0; i < argc; i++) { argv[i] = (VALUE)NULL; } + #if 0 /* use Tcl_EventuallyFree */ Tcl_EventuallyFree((ClientData)argv, TCL_DYNAMIC); /* XXXXXXXX */ #else #if 0 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)argv); /* XXXXXXXX */ -#endif +#else ckfree((char*)argv); +#endif #endif } -#if 1 /* use Tcl_Preserve/Release */ +#if 0 /* callq is freed by Tcl_ServiceEvent */ +#if 0 /* use Tcl_Preserve/Release */ Tcl_Release(callq); #else ckfree((char*)callq); +#endif #endif /* exception? */ @@ -6714,11 +6809,12 @@ eval_queue_handler(evPtr, flags) struct eval_queue *q = (struct eval_queue *)evPtr; volatile VALUE ret; volatile VALUE q_dat; + volatile VALUE thread = q->thread; struct tcltkip *ptr; DUMP2("do_eval_queue_handler : evPtr = %p", evPtr); DUMP2("eval_queue_thread : %lx", rb_thread_current()); - DUMP2("added by thread : %lx", q->thread); + DUMP2("added by thread : %lx", thread); if (*(q->done)) { DUMP1("processed by another event-loop"); @@ -6727,6 +6823,12 @@ eval_queue_handler(evPtr, flags) DUMP1("process it on current event-loop"); } + if (RTEST(rb_thread_alive_p(thread)) + && ! RTEST(rb_funcall(thread, ID_stop_p, 0))) { + DUMP1("caller is not yet ready to receive the result -> pending"); + return 0; + } + /* process it */ *(q->done) = 1; @@ -6760,12 +6862,14 @@ eval_queue_handler(evPtr, flags) ret = rb_funcall(rb_proc_new(evq_safelevel_handler, q_dat), ID_call, 0); rb_gc_force_recycle(q_dat); + q_dat = (VALUE)NULL; } else { ret = ip_eval_real(q->interp, q->str, q->len); } /* set result */ RARRAY_PTR(q->result)[0] = ret; + ret = (VALUE)NULL; /* decr internal handler mark */ rbtk_internal_eventloop_handler--; @@ -6773,22 +6877,28 @@ eval_queue_handler(evPtr, flags) /* complete */ *(q->done) = -1; + /* unlink ruby objects */ + q->interp = (VALUE)NULL; + q->result = (VALUE)NULL; + q->thread = (VALUE)NULL; + /* back to caller */ - if (RTEST(rb_funcall(q->thread, ID_alive_p, 0, 0))) { - DUMP2("back to caller (caller thread:%lx)", q->thread); + /* if (RTEST(rb_funcall(thread, ID_alive_p, 0, 0))) { */ + if (RTEST(rb_thread_alive_p(thread))) { + DUMP2("back to caller (caller thread:%lx)", thread); DUMP2(" (current thread:%lx)", rb_thread_current()); -#if CONTROL_BY_STATUS_OF_RB_THREAD_WAIT_FOR_VALUE - have_rb_thread_waited_for_value = 1; - rb_thread_wakeup(q->thread); +#if CONTROL_BY_STATUS_OF_RB_THREAD_WAITING_FOR_VALUE + have_rb_thread_waiting_for_value = 1; + rb_thread_wakeup(thread); #else - rb_thread_run(q->thread); + rb_thread_run(thread); #endif DUMP1("finish back to caller"); #if DO_THREAD_SCHEDULE_AT_CALLBACK_DONE rb_thread_schedule(); #endif } else { - DUMP2("caller is dead (caller thread:%lx)", q->thread); + DUMP2("caller is dead (caller thread:%lx)", thread); DUMP2(" (current thread:%lx)", rb_thread_current()); } @@ -6847,7 +6957,7 @@ ip_eval(self, str) thr_crit_bup = rb_thread_critical; rb_thread_critical = Qtrue; - /* allocate memory (protected from Tcl_ServiceEvent) */ + /* allocate memory (keep result) */ /* alloc_done = (int*)ALLOC(int); */ alloc_done = (int*)ckalloc(sizeof(int)); #if 0 /* use Tcl_Preserve/Release */ @@ -6866,7 +6976,7 @@ ip_eval(self, str) /* allocate memory (freed by Tcl_ServiceEvent) */ /* evq = (struct eval_queue *)Tcl_Alloc(sizeof(struct eval_queue)); */ evq = (struct eval_queue *)ckalloc(sizeof(struct eval_queue)); -#if 1 /* use Tcl_Preserve/Release */ +#if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve(evq); #endif @@ -6889,13 +6999,21 @@ ip_eval(self, str) DUMP1("add handler"); #ifdef RUBY_VM if (ptr->tk_thread_id) { - Tcl_ThreadQueueEvent(ptr->tk_thread_id, &(evq->ev), position); + /* Tcl_ThreadQueueEvent(ptr->tk_thread_id, &(evq->ev), position); */ + Tcl_ThreadQueueEvent(ptr->tk_thread_id, (Tcl_Event*)evq, position); Tcl_ThreadAlert(ptr->tk_thread_id); + } else if (tk_eventloop_thread_id) { + Tcl_ThreadQueueEvent(tk_eventloop_thread_id, (Tcl_Event*)evq, position); + /* Tcl_ThreadQueueEvent(tk_eventloop_thread_id, + &(evq->ev), position); */ + Tcl_ThreadAlert(tk_eventloop_thread_id); } else { - Tcl_QueueEvent(&(evq->ev), position); + /* Tcl_QueueEvent(&(evq->ev), position); */ + Tcl_QueueEvent((Tcl_Event*)evq, position); } #else - Tcl_QueueEvent(&(evq->ev), position); + /* Tcl_QueueEvent(&(evq->ev), position); */ + Tcl_QueueEvent((Tcl_Event*)evq, position); #endif rb_thread_critical = thr_crit_bup; @@ -6904,7 +7022,8 @@ ip_eval(self, str) DUMP2("wait for handler (current thread:%lx)", current); while(*alloc_done >= 0) { DUMP2("*** wait for handler (current thread:%lx)", current); - rb_thread_stop(); + /* rb_thread_stop(); */ + rb_thread_sleep_forever(); DUMP2("*** wakeup (current thread:%lx)", current); } DUMP2("back from handler (current thread:%lx)", current); @@ -6917,23 +7036,27 @@ ip_eval(self, str) #else #if 0 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)alloc_done); /* XXXXXXXX */ -#endif +#else /* free(alloc_done); */ ckfree((char*)alloc_done); #endif +#endif #if 0 /* use Tcl_EventuallyFree */ Tcl_EventuallyFree((ClientData)eval_str, TCL_DYNAMIC); /* XXXXXXXX */ #else #if 0 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)eval_str); /* XXXXXXXX */ -#endif +#else /* free(eval_str); */ ckfree(eval_str); #endif -#if 1 /* use Tcl_Preserve/Release */ +#endif +#if 0 /* evq is freed by Tcl_ServiceEvent */ +#if 0 /* use Tcl_Preserve/Release */ Tcl_Release(evq); #else ckfree((char*)evq); +#endif #endif if (rb_obj_is_kind_of(ret, rb_eException)) { @@ -7112,11 +7235,15 @@ lib_toUTF8_core(ip_obj, src, encodename) /* StringValue(enc); */ enc = rb_funcall(enc, ID_to_s, 0, 0); /* encoding = Tcl_GetEncoding(interp, RSTRING_PTR(enc)); */ - encoding = Tcl_GetEncoding((Tcl_Interp*)NULL, - RSTRING_PTR(enc)); - if (encoding == (Tcl_Encoding)NULL) { + if (!RSTRING_LEN(enc)) { + encoding = (Tcl_Encoding)NULL; + } else { + encoding = Tcl_GetEncoding((Tcl_Interp*)NULL, + RSTRING_PTR(enc)); + if (encoding == (Tcl_Encoding)NULL) { rb_warning("Tk-interp has unknown encoding information (@encoding:'%s')", RSTRING_PTR(enc)); - } + } + } } } } else { @@ -7299,13 +7426,17 @@ lib_fromUTF8_core(ip_obj, src, encodename) /* StringValue(enc); */ enc = rb_funcall(enc, ID_to_s, 0, 0); /* encoding = Tcl_GetEncoding(interp, RSTRING_PTR(enc)); */ - encoding = Tcl_GetEncoding((Tcl_Interp*)NULL, - RSTRING_PTR(enc)); - if (encoding == (Tcl_Encoding)NULL) { + if (!RSTRING_LEN(enc)) { + encoding = (Tcl_Encoding)NULL; + } else { + encoding = Tcl_GetEncoding((Tcl_Interp*)NULL, + RSTRING_PTR(enc)); + if (encoding == (Tcl_Encoding)NULL) { rb_warning("Tk-interp has unknown encoding information (@encoding:'%s')", RSTRING_PTR(enc)); - } else { - encodename = rb_obj_dup(enc); - } + } else { + encodename = rb_obj_dup(enc); + } + } } } @@ -7313,14 +7444,17 @@ lib_fromUTF8_core(ip_obj, src, encodename) StringValue(encodename); if (strcmp(RSTRING_PTR(encodename), "binary") == 0) { + Tcl_Obj *tclstr; char *s; int len; StringValue(str); - s = Tcl_GetByteArrayFromObj(Tcl_NewStringObj(RSTRING_PTR(str), - RSTRING_LEN(str)), - &len); + tclstr = Tcl_NewStringObj(RSTRING_PTR(str), RSTRING_LEN(str)); + Tcl_IncrRefCount(tclstr); + s = Tcl_GetByteArrayFromObj(tclstr, &len); str = rb_tainted_str_new(s, len); + s = (char*)NULL; + Tcl_DecrRefCount(tclstr); #ifdef RUBY_VM rb_enc_associate_index(str, ENCODING_INDEX_BINARY); #endif @@ -7482,18 +7616,20 @@ lib_UTF_backslash_core(self, str, all_bs) #else #if 0 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)src_buf); /* XXXXXXXX */ -#endif +#else /* free(src_buf); */ ckfree(src_buf); #endif +#endif #if 0 /* use Tcl_EventuallyFree */ Tcl_EventuallyFree((ClientData)dst_buf, TCL_DYNAMIC); /* XXXXXXXX */ #else #if 0 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)dst_buf); /* XXXXXXXX */ -#endif +#else /* free(dst_buf); */ ckfree(dst_buf); +#endif #endif rb_thread_critical = thr_crit_bup; @@ -7619,10 +7755,11 @@ invoke_tcl_proc(arg) #else #if 0 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)argv); /* XXXXXXXX */ -#endif +#else /* free(argv); */ ckfree((char*)argv); #endif +#endif #else /* TCL_MAJOR_VERSION < 8 */ inf->ptr->return_value @@ -7852,10 +7989,11 @@ ip_invoke_core(interp, argc, argv) #else #if 0 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)argv); /* XXXXXXXX */ -#endif +#else /* free(argv); */ ckfree((char*)argv); #endif +#endif #else /* TCL_MAJOR_VERSION < 8 */ ptr->return_value = (*info.proc)(info.clientData, ptr->ip, @@ -7873,11 +8011,12 @@ ip_invoke_core(interp, argc, argv) #else #if 0 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)objv); /* XXXXXXXX */ -#endif +#else /* free(objv); */ ckfree((char*)objv); #endif -#else +#endif +#else /* TCL_MAJOR_VERSION < 8 */ free(argv[0]); /* ckfree(argv[0]); */ #if 0 /* use Tcl_EventuallyFree */ @@ -7885,10 +8024,11 @@ ip_invoke_core(interp, argc, argv) #else #if 0 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)argv); /* XXXXXXXX */ -#endif +#else /* free(argv); */ ckfree((char*)argv); #endif +#endif #endif } @@ -7986,8 +8126,10 @@ free_invoke_arguments(argc, av) for (i = 0; i < argc; ++i) { #if TCL_MAJOR_VERSION >= 8 Tcl_DecrRefCount(av[i]); + av[i] = (Tcl_Obj*)NULL; #else /* TCL_MAJOR_VERSION < 8 */ free(av[i]); + av[i] = (char*)NULL; #endif } #if TCL_MAJOR_VERSION >= 8 @@ -7996,20 +8138,22 @@ free_invoke_arguments(argc, av) #else #if 0 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)av); /* XXXXXXXX */ -#endif +#else ckfree((char*)av); #endif +#endif #else /* TCL_MAJOR_VERSION < 8 */ #if 0 /* use Tcl_EventuallyFree */ Tcl_EventuallyFree((ClientData)av, TCL_DYNAMIC); /* XXXXXXXX */ #else #if 0 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)av); /* XXXXXXXX */ -#endif +#else /* free(av); */ ckfree((char*)av); #endif #endif +#endif } static VALUE @@ -8072,11 +8216,12 @@ invoke_queue_handler(evPtr, flags) struct invoke_queue *q = (struct invoke_queue *)evPtr; volatile VALUE ret; volatile VALUE q_dat; + volatile VALUE thread = q->thread; struct tcltkip *ptr; DUMP2("do_invoke_queue_handler : evPtr = %p", evPtr); DUMP2("invoke queue_thread : %lx", rb_thread_current()); - DUMP2("added by thread : %lx", q->thread); + DUMP2("added by thread : %lx", thread); if (*(q->done)) { DUMP1("processed by another event-loop"); @@ -8085,6 +8230,12 @@ invoke_queue_handler(evPtr, flags) DUMP1("process it on current event-loop"); } + if (RTEST(rb_thread_alive_p(thread)) + && ! RTEST(rb_funcall(thread, ID_stop_p, 0))) { + DUMP1("caller is not yet ready to receive the result -> pending"); + return 0; + } + /* process it */ *(q->done) = 1; @@ -8105,14 +8256,16 @@ invoke_queue_handler(evPtr, flags) ret = rb_funcall(rb_proc_new(ivq_safelevel_handler, q_dat), ID_call, 0); rb_gc_force_recycle(q_dat); + q_dat = (VALUE)NULL; } else { - DUMP2("call invoke_real (for caller thread:%lx)", q->thread); + DUMP2("call invoke_real (for caller thread:%lx)", thread); DUMP2("call invoke_real (current thread:%lx)", rb_thread_current()); ret = ip_invoke_core(q->interp, q->argc, q->argv); } /* set result */ RARRAY_PTR(q->result)[0] = ret; + ret = (VALUE)NULL; /* decr internal handler mark */ rbtk_internal_eventloop_handler--; @@ -8120,22 +8273,28 @@ invoke_queue_handler(evPtr, flags) /* complete */ *(q->done) = -1; + /* unlink ruby objects */ + q->interp = (VALUE)NULL; + q->result = (VALUE)NULL; + q->thread = (VALUE)NULL; + /* back to caller */ - if (RTEST(rb_funcall(q->thread, ID_alive_p, 0, 0))) { - DUMP2("back to caller (caller thread:%lx)", q->thread); + /* if (RTEST(rb_funcall(thread, ID_alive_p, 0, 0))) { */ + if (RTEST(rb_thread_alive_p(thread))) { + DUMP2("back to caller (caller thread:%lx)", thread); DUMP2(" (current thread:%lx)", rb_thread_current()); -#if CONTROL_BY_STATUS_OF_RB_THREAD_WAIT_FOR_VALUE - have_rb_thread_waited_for_value = 1; - rb_thread_wakeup(q->thread); +#if CONTROL_BY_STATUS_OF_RB_THREAD_WAITING_FOR_VALUE + have_rb_thread_waiting_for_value = 1; + rb_thread_wakeup(thread); #else - rb_thread_run(q->thread); + rb_thread_run(thread); #endif DUMP1("finish back to caller"); #if DO_THREAD_SCHEDULE_AT_CALLBACK_DONE rb_thread_schedule(); #endif } else { - DUMP2("caller is dead (caller thread:%lx)", q->thread); + DUMP2("caller is dead (caller thread:%lx)", thread); DUMP2(" (current thread:%lx)", rb_thread_current()); } @@ -8216,7 +8375,7 @@ ip_invoke_with_position(argc, argv, obj, position) /* allocate memory (freed by Tcl_ServiceEvent) */ /* ivq = (struct invoke_queue *)Tcl_Alloc(sizeof(struct invoke_queue)); */ ivq = (struct invoke_queue *)ckalloc(sizeof(struct invoke_queue)); -#if 1 /* use Tcl_Preserve/Release */ +#if 0 /* use Tcl_Preserve/Release */ Tcl_Preserve((ClientData)ivq); /* XXXXXXXX */ #endif @@ -8237,13 +8396,22 @@ ip_invoke_with_position(argc, argv, obj, position) DUMP1("add handler"); #ifdef RUBY_VM if (ptr->tk_thread_id) { - Tcl_ThreadQueueEvent(ptr->tk_thread_id, &(ivq->ev), position); + /* Tcl_ThreadQueueEvent(ptr->tk_thread_id, &(ivq->ev), position); */ + Tcl_ThreadQueueEvent(ptr->tk_thread_id, (Tcl_Event*)ivq, position); Tcl_ThreadAlert(ptr->tk_thread_id); + } else if (tk_eventloop_thread_id) { + /* Tcl_ThreadQueueEvent(tk_eventloop_thread_id, + &(ivq->ev), position); */ + Tcl_ThreadQueueEvent(tk_eventloop_thread_id, + (Tcl_Event*)ivq, position); + Tcl_ThreadAlert(tk_eventloop_thread_id); } else { - Tcl_QueueEvent(&(ivq->ev), position); + /* Tcl_QueueEvent(&(ivq->ev), position); */ + Tcl_QueueEvent((Tcl_Event*)ivq, position); } #else - Tcl_QueueEvent(&(ivq->ev), position); + /* Tcl_QueueEvent(&(ivq->ev), position); */ + Tcl_QueueEvent((Tcl_Event*)ivq, position); #endif rb_thread_critical = thr_crit_bup; @@ -8251,7 +8419,8 @@ ip_invoke_with_position(argc, argv, obj, position) /* wait for the handler to be processed */ DUMP2("wait for handler (current thread:%lx)", current); while(*alloc_done >= 0) { - rb_thread_stop(); + /* rb_thread_stop(); */ + rb_thread_sleep_forever(); } DUMP2("back from handler (current thread:%lx)", current); @@ -8262,19 +8431,22 @@ ip_invoke_with_position(argc, argv, obj, position) #else #if 0 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)alloc_done); /* XXXXXXXX */ -#endif +#else /* free(alloc_done); */ ckfree((char*)alloc_done); #endif +#endif +#if 0 /* ivq is freed by Tcl_ServiceEvent */ #if 0 /* use Tcl_EventuallyFree */ Tcl_EventuallyFree((ClientData)ivq, TCL_DYNAMIC); /* XXXXXXXX */ #else -#if 1 /* use Tcl_Preserve/Release */ +#if 0 /* use Tcl_Preserve/Release */ Tcl_Release(ivq); #else ckfree((char*)ivq); #endif +#endif #endif /* free allocated memory */ @@ -8961,9 +9133,10 @@ lib_merge_tklist(argc, argv, obj) #else #if 0 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)flagPtr); -#endif +#else /* free(flagPtr); */ ckfree((char*)flagPtr); +#endif #endif /* create object */ @@ -8974,9 +9147,10 @@ lib_merge_tklist(argc, argv, obj) #else #if 0 /* use Tcl_Preserve/Release */ Tcl_Release((ClientData)result); /* XXXXXXXXXXX */ -#endif +#else /* Tcl_Free(result); */ ckfree(result); +#endif #endif if (old_gc == Qfalse) rb_gc_enable(); @@ -9727,6 +9901,7 @@ ip_make_menu_embeddable_core(interp, argc, argv) char *s = "normal"; /* Tcl_SetStringObj((menuRefPtr->menuPtr)->menuTypePtr, s, strlen(s));*/ (menuRefPtr->menuPtr)->menuTypePtr = Tcl_NewStringObj(s, strlen(s)); + /* Tcl_IncrRefCount((menuRefPtr->menuPtr)->menuTypePtr); */ /* (menuRefPtr->menuPtr)->menuType = TEAROFF_MENU; */ (menuRefPtr->menuPtr)->menuType = MASTER_MENU; } diff --git a/ext/tk/tkutil/tkutil.c b/ext/tk/tkutil/tkutil.c index d6c70db22e..00d719143b 100644 --- a/ext/tk/tkutil/tkutil.c +++ b/ext/tk/tkutil/tkutil.c @@ -7,7 +7,7 @@ ************************************************/ -#define TKUTIL_RELEASE_DATE "2008-05-14" +#define TKUTIL_RELEASE_DATE "2008-05-23" #include "ruby.h" @@ -1100,7 +1100,10 @@ subst_free(ptr) if (ptr) { for(i = 0; i < CBSUBST_TBL_MAX; i++) { - if (ptr->key[i] != (unsigned char *)NULL) free(ptr->key[i]); + if (ptr->key[i] != (unsigned char *)NULL) { + free(ptr->key[i]); + ptr->key[i] = (unsigned char *)NULL; + } } free(ptr); } @@ -1445,6 +1448,7 @@ cbsubst_get_all_subst_keys(self) ret = rb_ary_new3(2, rb_str_new2(keys_buf), rb_str_new2((const char*)buf)); free(buf); + free(keys_buf); return ret; }