diff --git a/ChangeLog b/ChangeLog index 5abd594ea..817c38c61 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +Fri May 23 13:46:09 2008 Nobuyoshi Nakada + + * configure.in (cflags): commit miss. + +Fri May 23 09:52:21 2008 Nobuyoshi Nakada + + * configure.in (MINIRUBY), common.mk (RUBYOPT): add purelib.rb. + [ruby-core:16642] + + * ext/extmk.rb: load purelib.rb only when not cross compiling. + +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. + Fri May 23 01:03:23 2008 Akinori MUSHA * class.c (rb_singleton_class_clone): Pass Qnil, not 0. diff --git a/Makefile.in b/Makefile.in index 18537a53a..a37bcf65f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -35,6 +35,9 @@ RIDATADIR = $(DESTDIR)$(datadir)/ri/$(MAJOR).$(MINOR)/system empty = OUTFLAG = @OUTFLAG@$(empty) CFLAGS = @CFLAGS@ @XCFLAGS@ @ARCH_FLAG@ +cflags = @cflags@ +optflags = @optflags@ +debugflags = @debugflags@ CPPFLAGS = -I. -I$(srcdir) @CPPFLAGS@ LDFLAGS = @STATIC@ $(CFLAGS) @LDFLAGS@ EXTLDFLAGS = diff --git a/class.c b/class.c index 8409f42e3..0b766c0c5 100644 --- a/class.c +++ b/class.c @@ -57,19 +57,18 @@ clone_method(mid, body, nklass) NODE *fbody = body->nd_body; if (fbody) { - NODE *cref = NEW_NODE(NODE_CREF, nklass, 0, 0); VALUE nbody; switch (nd_type(fbody)) { case NODE_SCOPE: - fbody = rb_copy_node_scope(fbody, cref); + fbody = rb_copy_node_scope(fbody, ruby_cref); break; case NODE_BMETHOD: - nbody = rb_block_dup(fbody->nd_cval, nklass, (VALUE)cref); + nbody = rb_block_dup(fbody->nd_cval, nklass, (VALUE)ruby_cref); fbody = NEW_BMETHOD(nbody); break; case NODE_DMETHOD: - nbody = rb_method_dup(fbody->nd_cval, nklass, (VALUE)cref); + nbody = rb_method_dup(fbody->nd_cval, nklass, (VALUE)ruby_cref); fbody = NEW_DMETHOD(nbody); break; } diff --git a/common.mk b/common.mk index a02655403..7b861f845 100644 --- a/common.mk +++ b/common.mk @@ -113,6 +113,9 @@ install-local: pre-install-local do-install-local post-install-local pre-install-local:: pre-install-bin pre-install-lib pre-install-man do-install-local: $(MINIRUBY) $(srcdir)/instruby.rb --make="$(MAKE)" $(INSTRUBY_ARGS) --install=local --mantype="$(MANTYPE)" +loadpath: $(PREP) + $(MINIRUBY) -e 'p $$:' + post-install-local:: post-install-bin post-install-lib post-install-man install-ext: pre-install-ext do-install-ext post-install-ext diff --git a/configure.in b/configure.in index 0dd53a9e9..57be9766a 100644 --- a/configure.in +++ b/configure.in @@ -1635,6 +1635,12 @@ case "$build_os" in esac CPPFLAGS="$CPPFLAGS "'$(DEFS)' +test -z "$CFLAGS" || CFLAGS="$CFLAGS "; CFLAGS="$CFLAGS"'${cflags}' +test -z "$CPPFLAGS" || CPPFLAGS="$CPPFLAGS "; CPPFLAGS="$CPPFLAGS"'${cppflags}' +AC_SUBST(cppflags, [])dnl +AC_SUBST(cflags, ['${optflags} ${debugflags}'])dnl +AC_SUBST(optflags)dnl +AC_SUBST(debugflags)dnl AC_SUBST(XCFLAGS)dnl AC_SUBST(XLDFLAGS)dnl AC_SUBST(LIBRUBY_LDSHARED) diff --git a/ext/extmk.rb b/ext/extmk.rb index 06dd2f7c2..64746552c 100644 --- a/ext/extmk.rb +++ b/ext/extmk.rb @@ -298,7 +298,7 @@ def parse_args() $mflags.unshift(*rest) unless rest.empty? def $mflags.set?(flag) - grep(/\A-(?!-).*#{'%c' % flag}/i) { return true } + grep(/\A-(?!-).*#{flag.chr}/i) { return true } false end def $mflags.defined?(var) @@ -354,12 +354,16 @@ def $mflags.defined?(var) else $ruby = '$(topdir)/miniruby' + EXEEXT end -$ruby << " -I'$(topdir)' -I'$(top_srcdir)/lib'" -$ruby << " -I'$(extout)/$(arch)' -I'$(extout)/common'" if $extout -$ruby << " -I'$(top_srcdir)/ext' -rpurelib.rb" +$ruby << " -I'$(topdir)'" +unless CROSS_COMPILING + $ruby << " -I'$(top_srcdir)/lib'" + $ruby << " -I'$(extout)/$(arch)' -I'$(extout)/common'" if $extout + $ruby << " -I./- -I'$(top_srcdir)/ext' -rpurelib.rb" + ENV["RUBYLIB"] = "-" + ENV["RUBYOPT"] = "-rpurelib.rb" +end $config_h = '$(topdir)/config.h' -ENV["RUBYLIB"] = "-" -ENV["RUBYOPT"] = "-rpurelib.rb" +$mflags << "ruby=#$ruby" MTIMES = [__FILE__, 'rbconfig.rb', srcdir+'/lib/mkmf.rb'].collect {|f| File.mtime(f)} diff --git a/ext/tk/lib/multi-tk.rb b/ext/tk/lib/multi-tk.rb index b3b9e6953..ec718678f 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 e827d71eb..c5d5b804d 100644 --- a/ext/tk/lib/tk.rb +++ b/ext/tk/lib/tk.rb @@ -1298,7 +1298,7 @@ def INTERP.init_ip_internal }) << ' %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 @@ def font_configure(slot) 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 @@ def latinfont_configure(ltn, keys=nil) 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 @@ def kanjifont_configure(knj, keys=nil) 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 @@ def __configinfo_struct end private :__configinfo_struct + def __optkey_aliases + {} + end + private :__optkey_aliases + def __numval_optkeys [] end @@ -3613,6 +3624,11 @@ def __cget_core(slot) 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 @@ def cget(slot) 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 @@ def __configure_core(slot, value=None) 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 @@ def configure(slot, value=None) __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 @@ def __configinfo_core(slot = nil) 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 @@ def __configinfo_core(slot = nil) 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 @@ def initialize(parent=nil, keys=nil) fontkeys[fkey] = keys.delete(fkey) if keys.key?(fkey) } + __optkey_aliases.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 + } + __methodcall_optkeys.each{|key| key = key.to_s methodkeys[key] = keys.delete(key) if keys.key?(key) @@ -4823,18 +4894,24 @@ def create_self(keys) else begin tk_call_without_enc(cmd, @path, *hash_kv(keys, true)) - rescue + rescue => 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 @@ def bindtags_unshift(tag) #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 fceadd5e9..36ea008a1 100644 --- a/ext/tk/lib/tk/canvas.rb +++ b/ext/tk/lib/tk/canvas.rb @@ -168,6 +168,8 @@ def canvasy(screen_y, *args) #tk_tcl2ruby(tk_send_without_enc('canvasy', screen_y, *args)) number(tk_send_without_enc('canvasy', screen_y, *args)) end + alias canvas_x canvasx + alias canvas_y canvasy def coords(tag, *args) if args == [] @@ -642,6 +644,13 @@ def self._parse_create_args(args) 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) diff --git a/ext/tk/lib/tk/canvastag.rb b/ext/tk/lib/tk/canvastag.rb index 7feea1575..49796d80b 100644 --- a/ext/tk/lib/tk/canvastag.rb +++ b/ext/tk/lib/tk/canvastag.rb @@ -63,6 +63,9 @@ def bindinfo(seq=nil) def cget(option) @c.itemcget(@id, option) end + def cget_strict(option) + @c.itemcget_strict(@id, option) + end def configure(key, value=None) @c.itemconfigure(@id, key, value) diff --git a/ext/tk/lib/tk/composite.rb b/ext/tk/lib/tk/composite.rb index 728b02f60..883d43c3e 100644 --- a/ext/tk/lib/tk/composite.rb +++ b/ext/tk/lib/tk/composite.rb @@ -181,6 +181,57 @@ def delegate(option, *wins) delegate_alias(option, option, *wins) end + def __cget_delegates(slot) + slot = slot.to_s + + if @option_methods.include?(slot) + if @option_methods[slot][:cget] + return self.__send__(@option_methods[slot][:cget]) + else + if @option_setting[slot] + return @option_setting[slot] + else + return '' + end + end + end + + tbl = @delegates[slot] + tbl = @delegates['DEFAULT'] unless tbl + + begin + if tbl + opt, wins = tbl[-1] + opt = slot if opt == 'DEFAULT' + if wins && wins[-1] + # return wins[-1].cget(opt) + return wins[-1].cget_strict(opt) + end + end + rescue + end + + return None + end + private :__cget_delegates + + def cget(slot) + if (ret = __cget_delegates(slot)) == None + super(slot) + else + ret + end + end + + def cget_strict(slot) + if (ret = __cget_delegates(slot)) == None + super(slot) + else + ret + end + end + +=begin def cget(slot) slot = slot.to_s @@ -212,6 +263,7 @@ def cget(slot) super(slot) end +=end def configure(slot, value=None) if slot.kind_of? Hash diff --git a/ext/tk/lib/tk/image.rb b/ext/tk/lib/tk/image.rb index 57f82cb81..dffdc1964 100644 --- a/ext/tk/lib/tk/image.rb +++ b/ext/tk/lib/tk/image.rb @@ -156,7 +156,7 @@ def blank self end - def cget(option) + def cget_strict(option) case option.to_s when 'data', 'file' tk_send 'cget', '-' << option.to_s @@ -164,6 +164,23 @@ def cget(option) tk_tcl2ruby(tk_send('cget', '-' << option.to_s)) end end + def cget(option) + unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ + cget_strict(option) + else + begin + cget_strict(option) + rescue => 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 abff676d7..9c6a98d0f 100644 --- a/ext/tk/lib/tk/itemconfig.rb +++ b/ext/tk/lib/tk/itemconfig.rb @@ -8,6 +8,11 @@ module TkItemConfigOptkeys include TkUtil + def __item_optkey_aliases(id) + {} + end + private :__item_optkey_aliases + def __item_numval_optkeys(id) [] end @@ -165,6 +170,11 @@ def __itemcget_core(tagOrId, option) 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 @@ def itemcget(tagOrId, option) __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 @@ def __itemconfigure_core(tagOrId, slot, value=None) 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 @@ def itemconfigure(tagOrId, slot, value=None) __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 @@ def __itemconfiginfo_core(tagOrId, slot = nil) 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 @@ def __itemconfiginfo_core(tagOrId, slot = nil) 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 11d443b59..4c5c917c5 100644 --- a/ext/tk/lib/tk/itemfont.rb +++ b/ext/tk/lib/tk/itemfont.rb @@ -94,11 +94,14 @@ def tagfont_configure(tagOrId, slot) *(__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 @@ def latintagfont_configure(tagOrId, ltn, keys=nil) 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 @@ def kanjitagfont_configure(tagOrId, knj, keys=nil) 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 8ba315629..3ae0548dd 100644 --- a/ext/tk/lib/tk/menu.rb +++ b/ext/tk/lib/tk/menu.rb @@ -34,12 +34,13 @@ def __item_val2ruby_optkeys(id) # { key=>proc, ... } 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 a4c63c70a..4ec82bed1 100644 --- a/ext/tk/lib/tk/text.rb +++ b/ext/tk/lib/tk/text.rb @@ -32,6 +32,9 @@ def __item_pathname(id) 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 @@ def current_tag_configinfo(tagOrId, slot=nil) 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 @@ def current_window_configinfo(tagOrId, slot=nil) 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 d4c973213..fb306a9c1 100644 --- a/ext/tk/lib/tk/textimage.rb +++ b/ext/tk/lib/tk/textimage.rb @@ -52,6 +52,10 @@ def cget(slot) @t.image_cget(@index, slot) end + def cget_strict(slot) + @t.image_cget_strict(@index, slot) + end + def configure(slot, value=None) @t.image_configure(@index, slot, value) self diff --git a/ext/tk/lib/tk/texttag.rb b/ext/tk/lib/tk/texttag.rb index 792d544fe..b08d923ea 100644 --- a/ext/tk/lib/tk/texttag.rb +++ b/ext/tk/lib/tk/texttag.rb @@ -132,6 +132,9 @@ def []=(key,val) def cget(key) @t.tag_cget @id, key end + def cget_strict(key) + @t.tag_cget_strict @id, key + end =begin def cget(key) case key.to_s diff --git a/ext/tk/lib/tk/textwindow.rb b/ext/tk/lib/tk/textwindow.rb index a57732935..004422e4f 100644 --- a/ext/tk/lib/tk/textwindow.rb +++ b/ext/tk/lib/tk/textwindow.rb @@ -72,6 +72,9 @@ def []=(slot, value) def cget(slot) @t.window_cget(@index, slot) end + def cget_strict(slot) + @t.window_cget_strict(@index, slot) + end def configure(slot, value=None) if slot.kind_of?(Hash) diff --git a/ext/tk/lib/tkextlib/blt/component.rb b/ext/tk/lib/tkextlib/blt/component.rb index dd387634e..b2005b2f2 100644 --- a/ext/tk/lib/tkextlib/blt/component.rb +++ b/ext/tk/lib/tkextlib/blt/component.rb @@ -85,6 +85,9 @@ def __item_pathname(id) def axis_cget(id, option) ret = itemcget(['axis', tagid(id)], option) end + def axis_cget_strict(id, option) + ret = itemcget_strict(['axis', tagid(id)], option) + end def axis_configure(*args) slot = args.pop if slot.kind_of?(Hash) @@ -118,6 +121,9 @@ def current_axis_configinfo(id, slot=nil) def crosshairs_cget(option) itemcget('crosshairs', option) end + def crosshairs_cget_strict(option) + itemcget_strict('crosshairs', option) + end def crosshairs_configure(slot, value=None) itemconfigure('crosshairs', slot, value) end @@ -131,6 +137,9 @@ def current_crosshairs_configinfo(slot=nil) def element_cget(id, option) itemcget(['element', tagid(id)], option) end + def element_cget_strict(id, option) + itemcget_strict(['element', tagid(id)], option) + end def element_configure(*args) slot = args.pop if slot.kind_of?(Hash) @@ -152,6 +161,9 @@ def current_element_configinfo(id, slot=nil) def bar_cget(id, option) itemcget(['bar', tagid(id)], option) end + def bar_cget_strict(id, option) + itemcget_strict(['bar', tagid(id)], option) + end def bar_configure(*args) slot = args.pop if slot.kind_of?(Hash) @@ -173,6 +185,9 @@ def current_bar_configinfo(id, slot=nil) def line_cget(id, option) itemcget(['line', tagid(id)], option) end + def line_cget_strict(id, option) + itemcget_strict(['line', tagid(id)], option) + end def line_configure(*args) slot = args.pop if slot.kind_of?(Hash) @@ -194,6 +209,9 @@ def current_line_configinfo(id, slot=nil) def gridline_cget(option) itemcget('grid', option) end + def gridline_cget_strict(option) + itemcget_strict('grid', option) + end def gridline_configure(slot, value=None) itemconfigure('grid', slot, value) end @@ -207,6 +225,9 @@ def current_gridline_configinfo(slot=nil) def legend_cget(option) itemcget('legend', option) end + def legend_cget_strict(option) + itemcget_strict('legend', option) + end def legend_configure(slot, value=None) itemconfigure('legend', slot, value) end @@ -220,6 +241,9 @@ def current_legend_configinfo(slot=nil) def pen_cget(id, option) itemcget(['pen', tagid(id)], option) end + def pen_cget_strict(id, option) + itemcget_strict(['pen', tagid(id)], option) + end def pen_configure(*args) slot = args.pop if slot.kind_of?(Hash) @@ -241,6 +265,9 @@ def current_pen_configinfo(id, slot=nil) def postscript_cget(option) itemcget('postscript', option) end + def postscript_cget_strict(option) + itemcget_strict('postscript', option) + end def postscript_configure(slot, value=None) itemconfigure('postscript', slot, value) end @@ -254,6 +281,9 @@ def current_postscript_configinfo(slot=nil) def marker_cget(id, option) itemcget(['marker', tagid(id)], option) end + def marker_cget_strict(id, option) + itemcget_strict(['marker', tagid(id)], option) + end def marker_configure(*args) slot = args.pop if slot.kind_of?(Hash) @@ -273,11 +303,12 @@ def current_marker_configinfo(id, slot=nil) end alias __itemcget itemcget + alias __itemcget_strict itemcget_strict alias __itemconfiginfo itemconfiginfo alias __current_itemconfiginfo current_itemconfiginfo private :__itemcget, :__itemconfiginfo, :__current_itemconfiginfo - def itemcget(tagOrId, option) + def itemcget_strict(tagOrId, option) ret = __itemcget(tagid(tagOrId), option) if option == 'bindtags' || option == :bindtags ret.collect{|tag| TkBindTag.id2obj(tag)} @@ -285,6 +316,27 @@ def itemcget(tagOrId, option) ret end end + def itemcget(tagOrId, option) + unless TkItemConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__ + itemcget_strict(tagOrId, option) + else + begin + itemcget_strict(tagOrId, option) + rescue => 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 @@ def current_itemconfiginfo(tagOrId, slot = nil) ret end - private :itemcget, :itemconfigure - private :itemconfiginfo, :current_itemconfiginfo + private :itemcget, :itemcget_strict + private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo ################# @@ -428,6 +480,9 @@ def to_eval 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 @@ def to_eval 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 @@ def cget(option) # @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 @@ def to_eval 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 @@ def to_eval 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 @@ def to_eval 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 @@ def to_eval 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 @@ def self._parse_create_args(keys) 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 @@ def to_eval 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 @@ def marker_type(id) 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 @@ def xaxis_use(target=nil) 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 @@ def x2axis_use(target=nil) 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 @@ def yaxis_use(target=nil) 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 a0cf3dc03..0d9cb3018 100644 --- a/ext/tk/lib/tkextlib/blt/htext.rb +++ b/ext/tk/lib/tkextlib/blt/htext.rb @@ -22,6 +22,7 @@ class Htext 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 0ddee21d0..291ca4a96 100644 --- a/ext/tk/lib/tkextlib/bwidget/dialog.rb +++ b/ext/tk/lib/tkextlib/bwidget/dialog.rb @@ -59,6 +59,13 @@ def create_self(keys) 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 224304f2a..846e58062 100644 --- a/ext/tk/lib/tkextlib/bwidget/dynamichelp.rb +++ b/ext/tk/lib/tkextlib/bwidget/dynamichelp.rb @@ -34,6 +34,13 @@ def self.__config_cmd ['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 d8cd72fec..093fcb6fb 100644 --- a/ext/tk/lib/tkextlib/bwidget/listbox.rb +++ b/ext/tk/lib/tkextlib/bwidget/listbox.rb @@ -297,6 +297,9 @@ def []=(key, val) 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 cc8a996f4..b88461baf 100644 --- a/ext/tk/lib/tkextlib/bwidget/messagedlg.rb +++ b/ext/tk/lib/tkextlib/bwidget/messagedlg.rb @@ -65,6 +65,17 @@ def cget(slot) 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 7a46db575..aed4512a7 100644 --- a/ext/tk/lib/tkextlib/bwidget/tree.rb +++ b/ext/tk/lib/tkextlib/bwidget/tree.rb @@ -358,6 +358,9 @@ def []=(key, val) 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 34e51308a..a93364b56 100644 --- a/ext/tk/lib/tkextlib/bwidget/widget.rb +++ b/ext/tk/lib/tkextlib/bwidget/widget.rb @@ -29,6 +29,13 @@ def self.__config_cmd ['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 @@ def self.set_option(win, option, value) 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 a055e07ac..05d58c386 100644 --- a/ext/tk/lib/tkextlib/iwidgets/buttonbox.rb +++ b/ext/tk/lib/tkextlib/iwidgets/buttonbox.rb @@ -47,12 +47,13 @@ def tagid(tagOrId) 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 7d2b41f80..c85d356c5 100644 --- a/ext/tk/lib/tkextlib/iwidgets/checkbox.rb +++ b/ext/tk/lib/tkextlib/iwidgets/checkbox.rb @@ -47,12 +47,13 @@ def tagid(tagOrId) 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 d6c668621..8d43cc07a 100644 --- a/ext/tk/lib/tkextlib/iwidgets/dialogshell.rb +++ b/ext/tk/lib/tkextlib/iwidgets/dialogshell.rb @@ -47,12 +47,13 @@ def tagid(tagOrId) 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 dea3d34c2..5aaefbe50 100644 --- a/ext/tk/lib/tkextlib/iwidgets/menubar.rb +++ b/ext/tk/lib/tkextlib/iwidgets/menubar.rb @@ -62,12 +62,13 @@ def tagid(tagOrId) 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 2bbbec766..98ac32900 100644 --- a/ext/tk/lib/tkextlib/iwidgets/messagebox.rb +++ b/ext/tk/lib/tkextlib/iwidgets/messagebox.rb @@ -47,12 +47,13 @@ def __item_boolval_optkeys(id) 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 268452afe..03b50633d 100644 --- a/ext/tk/lib/tkextlib/iwidgets/notebook.rb +++ b/ext/tk/lib/tkextlib/iwidgets/notebook.rb @@ -42,12 +42,13 @@ def tagid(tagOrId) 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 035df0a5b..3bf73d69f 100644 --- a/ext/tk/lib/tkextlib/iwidgets/panedwindow.rb +++ b/ext/tk/lib/tkextlib/iwidgets/panedwindow.rb @@ -42,12 +42,13 @@ def tagid(tagOrId) 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 cfcbca1aa..e9d952125 100644 --- a/ext/tk/lib/tkextlib/iwidgets/radiobox.rb +++ b/ext/tk/lib/tkextlib/iwidgets/radiobox.rb @@ -47,12 +47,13 @@ def tagid(tagOrId) 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 d85f232b3..d6436d202 100644 --- a/ext/tk/lib/tkextlib/iwidgets/scrolledtext.rb +++ b/ext/tk/lib/tkextlib/iwidgets/scrolledtext.rb @@ -116,7 +116,7 @@ def get_displaychars(*index) 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 @@ def image_cget(index, slot) "-#{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 382604102..dbb90e510 100644 --- a/ext/tk/lib/tkextlib/iwidgets/tabnotebook.rb +++ b/ext/tk/lib/tkextlib/iwidgets/tabnotebook.rb @@ -47,12 +47,13 @@ def tagid(tagOrId) 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 618260e8e..300ba9dee 100644 --- a/ext/tk/lib/tkextlib/iwidgets/tabset.rb +++ b/ext/tk/lib/tkextlib/iwidgets/tabset.rb @@ -42,12 +42,13 @@ def tagid(tagOrId) 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 bf5e54e8c..fc5d8b26d 100644 --- a/ext/tk/lib/tkextlib/tcllib/getstring.rb +++ b/ext/tk/lib/tkextlib/tcllib/getstring.rb @@ -87,7 +87,7 @@ def value @variable.value end - def cget(slot) + def cget_strict(slot) slot = slot.to_s if slot == 'text' @text @@ -95,6 +95,9 @@ def cget(slot) @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 97de0a27c..1c813e36d 100644 --- a/ext/tk/lib/tkextlib/tcllib/swaplist.rb +++ b/ext/tk/lib/tkextlib/tcllib/swaplist.rb @@ -90,7 +90,7 @@ def value 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 @@ def cget(slot) @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 a939a5833..d7a6c9721 100644 --- a/ext/tk/lib/tkextlib/tcllib/tablelist_core.rb +++ b/ext/tk/lib/tkextlib/tcllib/tablelist_core.rb @@ -70,6 +70,9 @@ def __item_config_cmd(mixed_id) 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 @@ def current_cell_configinfo(tagOrId, slot=nil) 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 @@ def current_cell_configinfo(tagOrId, slot=nil) 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 @@ def current_column_configinfo(tagOrId, slot=nil) 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 @@ def current_column_configinfo(tagOrId, slot=nil) 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 @@ def current_row_configinfo(tagOrId, slot=nil) 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 b10378d7d..ef2d1fe57 100644 --- a/ext/tk/lib/tkextlib/tile/dialog.rb +++ b/ext/tk/lib/tkextlib/tile/dialog.rb @@ -54,9 +54,21 @@ def client_frame window(tk_call_without_enc('::ttk::dialog::clientframe', @path)) end + def cget_strict(slot) + @keys[slot.to_s] + end + def cget(slot) + @keys[slot.to_s] + end +=begin def cget(slot) - @keys[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 4b221fcb8..0bea98dcd 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 075059d5c..4d65e363d 100644 --- a/ext/tk/lib/tkextlib/tile/tnotebook.rb +++ b/ext/tk/lib/tkextlib/tile/tnotebook.rb @@ -41,13 +41,35 @@ def __item_methodcall_optkeys(id) # { key=>method, ... } 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 f24b12e92..d96ff4397 100644 --- a/ext/tk/lib/tkextlib/tile/tpaned.rb +++ b/ext/tk/lib/tkextlib/tile/tpaned.rb @@ -66,10 +66,33 @@ def insert(pos, win, keys) 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 7f31b9c23..c978a1a07 100644 --- a/ext/tk/lib/tkextlib/tile/treeview.rb +++ b/ext/tk/lib/tkextlib/tile/treeview.rb @@ -33,6 +33,12 @@ def __itemconfiginfo_core(tagOrId, slot = nil) 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 @@ def __itemconfiginfo_core(tagOrId, slot = nil) 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 @@ def current_itemconfiginfo(tagOrId, slot = nil) 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 @@ def current_itemconfiginfo(tagOrId, slot=nil) 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 @@ def current_columnconfiginfo(tagOrId, slot=nil) __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 @@ def headingcget(tagOrId, option) 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 @@ def current_headingconfiginfo(tagOrId, slot=nil) __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 @@ def current_headingconfiginfo(tagOrId, slot=nil) 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 @@ def current_tagconfiginfo(tagOrId, slot=nil) __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 @@ def id 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 @@ def bindinfo(seq=nil) 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 b5bf4ea6c..f6cf24b40 100644 --- a/ext/tk/lib/tkextlib/tktable/tktable.rb +++ b/ext/tk/lib/tkextlib/tktable/tktable.rb @@ -77,6 +77,9 @@ def __item_val2ruby_optkeys(id) # { key=>method, ... } 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 @@ def current_tag_configinfo(tagOrId, slot=nil) 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 @@ def current_window_configinfo(tagOrId, slot=nil) 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 @@ def lower(target=None) 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 5e86a1940..e10e6e299 100644 --- a/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb +++ b/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb @@ -417,6 +417,9 @@ def __item_keyonly_optkeys(id) # { def_key=>(undef_key|nil), ... } 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 @@ def current_column_configinfo(tagOrId, slot=nil) 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 @@ def current_column_dragconfiginfo(slot=nil) 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 @@ def current_debug_configinfo(slot=nil) 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 @@ def current_dragimage_configinfo(slot=nil) 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 @@ def current_element_configinfo(tagOrId, slot=nil) 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 @@ def current_item_configinfo(tagOrId, slot=nil) 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 @@ def current_item_element_configinfo(item, column, elem, slot=nil) 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 @@ def notify_cget(win, pattern, option) # "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 @@ def current_notify_configinfo(tagOrId, slot=nil) 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 @@ def current_style_configinfo(tagOrId, slot=nil) 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 @@ def to_s 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 @@ def to_s 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 @@ def complex(*args) 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 @@ def element_actual(column, elem, key) 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 @@ def to_s 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 f437dea7f..434ed11a2 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 1975803db..c1fb6857b 100644 --- a/ext/tk/lib/tkextlib/vu/pie.rb +++ b/ext/tk/lib/tkextlib/vu/pie.rb @@ -177,6 +177,10 @@ def cget(slot) @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 f063bc53a..0b9bc7357 100644 --- a/ext/tk/sample/demos-en/anilabel.rb +++ b/ext/tk/sample/demos-en/anilabel.rb @@ -15,8 +15,10 @@ 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.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 @@ }.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 bdb8d217c..63a04a7b9 100644 --- a/ext/tk/sample/demos-en/aniwave.rb +++ b/ext/tk/sample/demos-en/aniwave.rb @@ -16,8 +16,10 @@ 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.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 @@ def stop 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 4a589a089..055cd2af3 100644 --- a/ext/tk/sample/demos-en/arrow.rb +++ b/ext/tk/sample/demos-en/arrow.rb @@ -107,14 +107,16 @@ def arrowSetup(c) 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 @@ def arrowSetup(c) $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 d4e671748..665592a2b 100644 --- a/ext/tk/sample/demos-en/bind.rb +++ b/ext/tk/sample/demos-en/bind.rb @@ -19,8 +19,10 @@ 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 @@ def tag_binding_for_bind_demo(tag, enter_style, leave_style) } 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 7fd551c7a..133adb054 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 @@ def bitmapRow(w,*args) 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 @@ def bitmapRow(w,*args) $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 6614d99c9..5c03bd499 100644 --- a/ext/tk/sample/demos-en/button.rb +++ b/ext/tk/sample/demos-en/button.rb @@ -29,7 +29,7 @@ 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 971a8fea7..2951962a7 100644 --- a/ext/tk/sample/demos-en/check.rb +++ b/ext/tk/sample/demos-en/check.rb @@ -19,8 +19,10 @@ 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 @@ 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 @@ 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 @@ # 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 97d61fba0..faea748a8 100644 --- a/ext/tk/sample/demos-en/check2.rb +++ b/ext/tk/sample/demos-en/check2.rb @@ -15,8 +15,10 @@ 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 @@ 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 @@ # 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 9486fde31..431439d55 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 @@ 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 @@ } }.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 66fb0afa3..4300a660a 100644 --- a/ext/tk/sample/demos-en/colors.rb +++ b/ext/tk/sample/demos-en/colors.rb @@ -20,8 +20,10 @@ 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.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 @@ # 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 @@ 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 000000000..0907d9e8e --- /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 0838dfbe0..259ed3bd8 100644 --- a/ext/tk/sample/demos-en/cscroll.rb +++ b/ext/tk/sample/demos-en/cscroll.rb @@ -19,14 +19,16 @@ 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 @@ # 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 @@ 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 @@ '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 @@ 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 8c10880ed..01374b032 100644 --- a/ext/tk/sample/demos-en/ctext.rb +++ b/ext/tk/sample/demos-en/ctext.rb @@ -19,8 +19,10 @@ 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 @@ } # 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.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 29bc69339..6f5b10fb7 100644 --- a/ext/tk/sample/demos-en/entry1.rb +++ b/ext/tk/sample/demos-en/entry1.rb @@ -15,8 +15,10 @@ 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.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 @@ }.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 d4e58d7dd..d67d04b56 100644 --- a/ext/tk/sample/demos-en/entry2.rb +++ b/ext/tk/sample/demos-en/entry2.rb @@ -19,8 +19,10 @@ 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.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 @@ }.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 68f77a0d4..f7df3a565 100644 --- a/ext/tk/sample/demos-en/entry3.rb +++ b/ext/tk/sample/demos-en/entry3.rb @@ -17,7 +17,9 @@ 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 @@ 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 @@ # 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 @@ def validatePhoneChange(widget, vmode, idx, char) 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 36b19de55..676c34740 100644 --- a/ext/tk/sample/demos-en/filebox.rb +++ b/ext/tk/sample/demos-en/filebox.rb @@ -17,12 +17,14 @@ 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 @@ # 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 @@ 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 @@ $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 53adcf96b..7023f2a72 100644 --- a/ext/tk/sample/demos-en/floor.rb +++ b/ext/tk/sample/demos-en/floor.rb @@ -1590,14 +1590,16 @@ def floor_fg3(w,color) 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 @@ def floor_fg3(w,color) # 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 @@ def floor_fg3(w,color) $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 efaf9e250..88b07aeee 100644 --- a/ext/tk/sample/demos-en/floor2.rb +++ b/ext/tk/sample/demos-en/floor2.rb @@ -1590,14 +1590,16 @@ def floor2_fg3(w,color) 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 @@ def floor2_fg3(w,color) # 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 @@ def floor2_fg3(w,color) $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 dbb14302d..3119752b1 100644 --- a/ext/tk/sample/demos-en/form.rb +++ b/ext/tk/sample/demos-en/form.rb @@ -15,8 +15,10 @@ 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.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 @@ # 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 8d3f6d14f..c6fa37c09 100644 --- a/ext/tk/sample/demos-en/goldberg.rb +++ b/ext/tk/sample/demos-en/goldberg.rb @@ -54,6 +54,8 @@ # positionWindow(w) } +base_frame = TkFrame.new($goldberg_demo).pack(:fill=>:both, :expand=>true) + =begin # label msg = TkLabel.new($goldberg_demo) { @@ -175,7 +177,8 @@ def do_display() 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 @@ def do_display() 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 @@ def do_display() } }.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 @@ def do_display() 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 @@ def anchor(item, where) 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 743c4b485..e66021696 100644 --- a/ext/tk/sample/demos-en/hscale.rb +++ b/ext/tk/sample/demos-en/hscale.rb @@ -11,8 +11,9 @@ } 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.pack('side'=>'top') -TkFrame.new($hscale_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc { @@ -36,7 +37,18 @@ }.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 @@ }.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 58aca2df0..a3921d233 100644 --- a/ext/tk/sample/demos-en/icon.rb +++ b/ext/tk/sample/demos-en/icon.rb @@ -19,8 +19,10 @@ 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.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 @@ 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 @@ }.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 05c9705c9..a9072bb30 100644 --- a/ext/tk/sample/demos-en/image1.rb +++ b/ext/tk/sample/demos-en/image1.rb @@ -18,8 +18,10 @@ 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.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 @@ '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 1aff7173b..1975dd6b0 100644 --- a/ext/tk/sample/demos-en/image2.rb +++ b/ext/tk/sample/demos-en/image2.rb @@ -19,8 +19,10 @@ 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.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 @@ $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 @@ }.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 e46d3796f..43afab7ec 100644 --- a/ext/tk/sample/demos-en/image3.rb +++ b/ext/tk/sample/demos-en/image3.rb @@ -19,27 +19,29 @@ 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 @@ def loadImage(w,x,y) # label -msg = TkLabel.new($image3_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -58,7 +60,7 @@ def loadImage(w,x,y) 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 @@ def loadImage(w,x,y) $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 @@ def loadImage(w,x,y) 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 23191b59b..3fd44fd4f 100644 --- a/ext/tk/sample/demos-en/items.rb +++ b/ext/tk/sample/demos-en/items.rb @@ -19,8 +19,10 @@ 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 @@ }.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 @@ # 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 000000000..618fce5f0 --- /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 55e07a5eb..91e41e4a2 100644 --- a/ext/tk/sample/demos-en/label.rb +++ b/ext/tk/sample/demos-en/label.rb @@ -19,8 +19,10 @@ 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.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 @@ }.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 @@ 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 842a4f6c0..c912ff4c5 100644 --- a/ext/tk/sample/demos-en/labelframe.rb +++ b/ext/tk/sample/demos-en/labelframe.rb @@ -17,8 +17,10 @@ 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 @@ 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 @@ } # 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 000000000..a849eba51 --- /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 8370d2f5f..bf6c22cb9 100644 --- a/ext/tk/sample/demos-en/menu.rb +++ b/ext/tk/sample/demos-en/menu.rb @@ -15,8 +15,10 @@ 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 @@ 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 @@ }.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 @@ '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 @@ 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 cb616d846..4029ce554 100644 --- a/ext/tk/sample/demos-en/menu84.rb +++ b/ext/tk/sample/demos-en/menu84.rb @@ -15,6 +15,8 @@ positionWindow(w) } +base_frame = TkFrame.new($menu84_demo).pack(:fill=>:both, :expand=>true) + begin windowingsystem = Tk.windowingsystem() rescue @@ -22,7 +24,7 @@ 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 @@ 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 @@ # 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 e2ddd07bc..b37367e51 100644 --- a/ext/tk/sample/demos-en/menubu.rb +++ b/ext/tk/sample/demos-en/menubu.rb @@ -37,16 +37,18 @@ def optionMenu(menubutton, varName, firstValue, *rest) 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 @@ def optionMenu(menubutton, varName, firstValue, *rest) 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 @@ def optionMenu(menubutton, varName, firstValue, *rest) 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 aab1b619c..62b1f2b98 100644 --- a/ext/tk/sample/demos-en/msgbox.rb +++ b/ext/tk/sample/demos-en/msgbox.rb @@ -18,12 +18,14 @@ 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 @@ }.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 000000000..6fe6c778b --- /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 48ba86de0..26941b84a 100644 --- a/ext/tk/sample/demos-en/paned1.rb +++ b/ext/tk/sample/demos-en/paned1.rb @@ -16,7 +16,9 @@ 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 @@ 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 @@ }).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 5911cadab..0e6201388 100644 --- a/ext/tk/sample/demos-en/paned2.rb +++ b/ext/tk/sample/demos-en/paned2.rb @@ -16,7 +16,9 @@ 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 @@ 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 @@ ] # 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 a3498d67c..5f7d36117 100644 --- a/ext/tk/sample/demos-en/pendulum.rb +++ b/ext/tk/sample/demos-en/pendulum.rb @@ -18,8 +18,10 @@ 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.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 @@ 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 @@ def repeat 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 6d01deeef..628c9df58 100644 --- a/ext/tk/sample/demos-en/plot.rb +++ b/ext/tk/sample/demos-en/plot.rb @@ -19,14 +19,16 @@ 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 @@ 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 0885cf297..43c61f519 100644 --- a/ext/tk/sample/demos-en/puzzle.rb +++ b/ext/tk/sample/demos-en/puzzle.rb @@ -19,8 +19,10 @@ 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.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 @@ # 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 @@ def def_puzzleswitch_proc(w, num) 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 96cdc4c54..25cfac213 100644 --- a/ext/tk/sample/demos-en/radio.rb +++ b/ext/tk/sample/demos-en/radio.rb @@ -19,8 +19,10 @@ 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 @@ 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 @@ 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 2b56ccc9b..6c02aef0c 100644 --- a/ext/tk/sample/demos-en/radio2.rb +++ b/ext/tk/sample/demos-en/radio2.rb @@ -19,8 +19,10 @@ 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 @@ 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 @@ 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 @@ }.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 70c4abb3b..9c9d75ef4 100644 --- a/ext/tk/sample/demos-en/radio3.rb +++ b/ext/tk/sample/demos-en/radio3.rb @@ -19,8 +19,10 @@ 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 @@ 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 @@ } # 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 @@ }.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 4299d57b4..26cd4f3b1 100644 --- a/ext/tk/sample/demos-en/ruler.rb +++ b/ext/tk/sample/demos-en/ruler.rb @@ -32,14 +32,16 @@ def rulerMkTab(c,x,y) 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 @@ def rulerMkTab(c,x,y) $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 cef0f4ecf..06ec7c1e7 100644 --- a/ext/tk/sample/demos-en/sayings.rb +++ b/ext/tk/sample/demos-en/sayings.rb @@ -20,8 +20,10 @@ 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.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 @@ # 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 3749423bb..e1fc565e9 100644 --- a/ext/tk/sample/demos-en/search.rb +++ b/ext/tk/sample/demos-en/search.rb @@ -79,8 +79,10 @@ def textToggle(cmd1,sleep1,cmd2,sleep2) 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 @@ def textToggle(cmd1,sleep1,cmd2,sleep2) $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 @@ def textToggle(cmd1,sleep1,cmd2,sleep2) .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 @@ def textToggle(cmd1,sleep1,cmd2,sleep2) } }.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 58616b1e0..c2a3a8949 100644 --- a/ext/tk/sample/demos-en/spin.rb +++ b/ext/tk/sample/demos-en/spin.rb @@ -15,7 +15,9 @@ 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 @@ 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 @@ ] [ - 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 d38c1245a..add0e8480 100644 --- a/ext/tk/sample/demos-en/states.rb +++ b/ext/tk/sample/demos-en/states.rb @@ -19,8 +19,10 @@ 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.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 @@ # 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 06952f41b..c2fed2392 100644 --- a/ext/tk/sample/demos-en/style.rb +++ b/ext/tk/sample/demos-en/style.rb @@ -19,8 +19,10 @@ 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 @@ }.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 4bb4b6bc7..3ce8cdfda 100644 --- a/ext/tk/sample/demos-en/text.rb +++ b/ext/tk/sample/demos-en/text.rb @@ -19,6 +19,8 @@ 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 @@ end # frame -TkFrame.new($text_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { text 'Dismiss' command proc{ @@ -44,7 +46,7 @@ }.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 @@ 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 d98ef170b..c25ce15e5 100644 --- a/ext/tk/sample/demos-en/textpeer.rb +++ b/ext/tk/sample/demos-en/textpeer.rb @@ -15,10 +15,12 @@ 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,"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 @@ def killClone(win, cnt) 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 000000000..700db6814 --- /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 000000000..0c7f0e71a --- /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 000000000..b5780f589 --- /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 000000000..75ecdb09c --- /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 000000000..c2a22b447 --- /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 000000000..56df613db --- /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 000000000..d1b882f54 --- /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 f29e49f35..65ee712ff 100644 --- a/ext/tk/sample/demos-en/twind.rb +++ b/ext/tk/sample/demos-en/twind.rb @@ -19,8 +19,10 @@ 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 @@ # 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 c42e0999d..43990c115 100644 --- a/ext/tk/sample/demos-en/twind2.rb +++ b/ext/tk/sample/demos-en/twind2.rb @@ -15,8 +15,10 @@ 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 @@ # 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 07e3bf52b..9c230a253 100644 --- a/ext/tk/sample/demos-en/unicodeout.rb +++ b/ext/tk/sample/demos-en/unicodeout.rb @@ -16,7 +16,9 @@ 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 @@ 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 @@ }).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 @@ def add_sample(lang, *args) 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 c0170467d..b05ed1207 100644 --- a/ext/tk/sample/demos-en/vscale.rb +++ b/ext/tk/sample/demos-en/vscale.rb @@ -15,7 +15,9 @@ } 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.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 @@ }.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 @@ }.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 4456f8ab5..dc40f0a95 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. File selection dialog.\n", tag_demo, "demo-filebox") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "3. Color picker.\n", tag_demo, "demo-clrpick") +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 c6e5c7385..aee57f9f6 100644 --- a/ext/tk/sample/demos-jp/anilabel.rb +++ b/ext/tk/sample/demos-jp/anilabel.rb @@ -17,8 +17,10 @@ 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.pack('side'=>'top') # frame 生成 -TkFrame.new($anilabel_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -46,8 +48,8 @@ }.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 ec307dbc0..8fa14f65f 100644 --- a/ext/tk/sample/demos-jp/aniwave.rb +++ b/ext/tk/sample/demos-jp/aniwave.rb @@ -17,8 +17,10 @@ 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.pack('side'=>'top') # create frame -TkFrame.new($aniwave_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -115,4 +117,4 @@ def stop 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 b2c106702..3c49e67b0 100644 --- a/ext/tk/sample/demos-jp/arrow.rb +++ b/ext/tk/sample/demos-jp/arrow.rb @@ -104,14 +104,16 @@ def arrowSetup(c) 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 @@ def arrowSetup(c) $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 8985463b1..a1bcfdd2e 100644 --- a/ext/tk/sample/demos-jp/bind.rb +++ b/ext/tk/sample/demos-jp/bind.rb @@ -16,8 +16,10 @@ 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 @@ def tag_binding_for_bind_demo(tag, enter_style, leave_style) } 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 4594892c8..b6b0e54bb 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 @@ def bitmapRow(w,*args) 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 @@ def bitmapRow(w,*args) $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 7e9457f5b..18e42008c 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.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 7545df80f..b953e7f62 100644 --- a/ext/tk/sample/demos-jp/check.rb +++ b/ext/tk/sample/demos-jp/check.rb @@ -16,8 +16,10 @@ 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 @@ sober = TkVariable.new(0) # frame 生成 -TkFrame.new($check_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -52,7 +54,7 @@ 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 @@ # 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 90c6dd736..7f7cb9e93 100644 --- a/ext/tk/sample/demos-jp/check2.rb +++ b/ext/tk/sample/demos-jp/check2.rb @@ -16,8 +16,10 @@ 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 @@ 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 @@ # 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 d81ecebc8..ce6b99ab9 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 @@ } # 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 @@ } }.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 68b40e69f..91817a947 100644 --- a/ext/tk/sample/demos-jp/colors.rb +++ b/ext/tk/sample/demos-jp/colors.rb @@ -16,8 +16,10 @@ 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.pack('side'=>'top') # frame 生成 -TkFrame.new($colors_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -46,7 +48,7 @@ # 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 @@ 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 000000000..da00d712b --- /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 0be26133c..845952679 100644 --- a/ext/tk/sample/demos-jp/cscroll.rb +++ b/ext/tk/sample/demos-jp/cscroll.rb @@ -16,14 +16,16 @@ 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 @@ # 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 @@ 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 @@ '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 @@ 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 f5daf7ca0..05ca732cf 100644 --- a/ext/tk/sample/demos-jp/ctext.rb +++ b/ext/tk/sample/demos-jp/ctext.rb @@ -16,8 +16,10 @@ 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 @@ } # 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.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 d79428228..2be29c18d 100644 --- a/ext/tk/sample/demos-jp/entry1.rb +++ b/ext/tk/sample/demos-jp/entry1.rb @@ -16,8 +16,10 @@ 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.pack('side'=>'top') # frame 生成 -TkFrame.new($entry1_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -44,9 +46,9 @@ }.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 528ad6dec..2675b5d32 100644 --- a/ext/tk/sample/demos-jp/entry2.rb +++ b/ext/tk/sample/demos-jp/entry2.rb @@ -16,8 +16,10 @@ 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.pack('side'=>'top') # frame 生成 -TkFrame.new($entry2_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -44,7 +46,7 @@ }.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 46426af6a..6b9cd4cf3 100644 --- a/ext/tk/sample/demos-jp/entry3.rb +++ b/ext/tk/sample/demos-jp/entry3.rb @@ -18,7 +18,9 @@ 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 @@ 入力された文字はアスタリスク記号に置き換えて表示されます. 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 @@ # 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 @@ def validatePhoneChange(widget, vmode, idx, char) 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 04b4810b3..b8846d08a 100644 --- a/ext/tk/sample/demos-jp/filebox.rb +++ b/ext/tk/sample/demos-jp/filebox.rb @@ -16,12 +16,14 @@ 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 @@ # 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 @@ 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 @@ $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 b7d07bdaf..a2ec2e996 100644 --- a/ext/tk/sample/demos-jp/floor.rb +++ b/ext/tk/sample/demos-jp/floor.rb @@ -1587,14 +1587,16 @@ def floor_fg3(w,color) 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 @@ def floor_fg3(w,color) # 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 @@ def floor_fg3(w,color) $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 b7571a592..d4381c554 100644 --- a/ext/tk/sample/demos-jp/floor2.rb +++ b/ext/tk/sample/demos-jp/floor2.rb @@ -1587,14 +1587,16 @@ def floor2_fg3(w,color) 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 @@ def floor2_fg3(w,color) # 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 @@ def floor2_fg3(w,color) $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 637dd9a8e..4de705676 100644 --- a/ext/tk/sample/demos-jp/form.rb +++ b/ext/tk/sample/demos-jp/form.rb @@ -16,8 +16,10 @@ 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.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 @@ # 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 8bf0104c1..a81c7ec70 100644 --- a/ext/tk/sample/demos-jp/goldberg.rb +++ b/ext/tk/sample/demos-jp/goldberg.rb @@ -55,6 +55,8 @@ # positionWindow(w) } +base_frame = TkFrame.new($goldberg_demo).pack(:fill=>:both, :expand=>true) + =begin # label msg = TkLabel.new($goldberg_demo) { @@ -177,7 +179,8 @@ def do_display() 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 @@ def do_display() 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 @@ def do_display() } }.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 @@ def do_display() 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 @@ def anchor(item, where) 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 b636f0579..5615aa50b 100644 --- a/ext/tk/sample/demos-jp/hscale.rb +++ b/ext/tk/sample/demos-jp/hscale.rb @@ -12,8 +12,9 @@ } 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.pack('side'=>'top') -TkFrame.new($hscale_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -40,7 +41,17 @@ }.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 @@ }.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 26382a57a..a2ca6651d 100644 --- a/ext/tk/sample/demos-jp/icon.rb +++ b/ext/tk/sample/demos-jp/icon.rb @@ -16,8 +16,10 @@ 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.pack('side'=>'top') # frame 生成 -TkFrame.new($icon_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -61,16 +63,18 @@ 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 @@ }.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 3b56d240d..d9435cc1a 100644 --- a/ext/tk/sample/demos-jp/image1.rb +++ b/ext/tk/sample/demos-jp/image1.rb @@ -16,8 +16,10 @@ 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.pack('side'=>'top') # frame 生成 -TkFrame.new($image1_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -53,7 +55,10 @@ '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 de627448c..1bb2c9e9c 100644 --- a/ext/tk/sample/demos-jp/image2.rb +++ b/ext/tk/sample/demos-jp/image2.rb @@ -16,8 +16,10 @@ 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.pack('side'=>'top') # frame 生成 -TkFrame.new($image2_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -51,21 +53,21 @@ $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 @@ }.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 36c182374..12b8aafd8 100644 --- a/ext/tk/sample/demos-jp/image3.rb +++ b/ext/tk/sample/demos-jp/image3.rb @@ -20,6 +20,8 @@ positionWindow(w) } +base_frame = TkFrame.new($image3_demo).pack(:fill=>:both, :expand=>true) + # def loadDir3(w) w.delete(0,'end') @@ -50,7 +52,7 @@ def loadImage3(w,x,y) # label -msg = TkLabel.new($image3_demo) { +msg = TkLabel.new(base_frame) { font $font wraplength '4i' justify 'left' @@ -59,7 +61,7 @@ def loadImage3(w,x,y) msg.pack('side'=>'top') # frame -TkFrame.new($image3_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -88,11 +90,11 @@ def loadImage3(w,x,y) $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 @@ def loadImage3(w,x,y) 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 c173d3b57..64ceeff3e 100644 --- a/ext/tk/sample/demos-jp/items.rb +++ b/ext/tk/sample/demos-jp/items.rb @@ -16,8 +16,10 @@ 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 @@ }.pack('side'=>'top') # frame 生成 -TkFrame.new($items_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -44,7 +46,7 @@ # 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 000000000..d4595ea44 --- /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 a1ecc2ec8..2e6b3e7e5 100644 --- a/ext/tk/sample/demos-jp/label.rb +++ b/ext/tk/sample/demos-jp/label.rb @@ -16,8 +16,10 @@ 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.pack('side'=>'top') # frame 生成 -TkFrame.new($label_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -45,8 +47,8 @@ }.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 @@ 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 f16b601ff..11b0d2730 100644 --- a/ext/tk/sample/demos-jp/labelframe.rb +++ b/ext/tk/sample/demos-jp/labelframe.rb @@ -19,8 +19,10 @@ 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 @@ 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 @@ } # 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 000000000..a7834d266 --- /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 6b9e5c9e5..c3d95176b 100644 --- a/ext/tk/sample/demos-jp/menu.rb +++ b/ext/tk/sample/demos-jp/menu.rb @@ -16,8 +16,10 @@ 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 @@ 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 @@ }.pack('side'=>'top') # frame 生成 -TkFrame.new($menu_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -108,7 +110,8 @@ '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 @@ 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 762cfa53b..a631bacd4 100644 --- a/ext/tk/sample/demos-jp/menu84.rb +++ b/ext/tk/sample/demos-jp/menu84.rb @@ -16,6 +16,8 @@ positionWindow(w) } +base_frame = TkFrame.new($menu84_demo).pack(:fill=>:both, :expand=>true) + begin windowingsystem = Tk.windowingsystem() rescue @@ -23,7 +25,7 @@ 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 @@ 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 @@ # 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 23efa7e79..9249f2491 100644 --- a/ext/tk/sample/demos-jp/menu8x.rb +++ b/ext/tk/sample/demos-jp/menu8x.rb @@ -16,16 +16,18 @@ 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 @@ 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 @@ # 状態表示の生成 $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 e73c393aa..90dc36730 100644 --- a/ext/tk/sample/demos-jp/menubu.rb +++ b/ext/tk/sample/demos-jp/menubu.rb @@ -33,16 +33,18 @@ def optionMenu(menubutton, varName, firstValue, *rest) 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 @@ def optionMenu(menubutton, varName, firstValue, *rest) 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 @@ def optionMenu(menubutton, varName, firstValue, *rest) 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 0fe5db7dd..88380e08b 100644 --- a/ext/tk/sample/demos-jp/msgbox.rb +++ b/ext/tk/sample/demos-jp/msgbox.rb @@ -16,12 +16,14 @@ 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 @@ }.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 @@ 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 000000000..d61f25129 --- /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 137e18741..f994e83ff 100644 --- a/ext/tk/sample/demos-jp/paned1.rb +++ b/ext/tk/sample/demos-jp/paned1.rb @@ -18,7 +18,9 @@ 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 @@ 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 @@ }).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 b394432b1..cdc825340 100644 --- a/ext/tk/sample/demos-jp/paned2.rb +++ b/ext/tk/sample/demos-jp/paned2.rb @@ -18,7 +18,9 @@ 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 @@ 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 @@ ] # 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 e19b57a2d..b115f5be2 100644 --- a/ext/tk/sample/demos-jp/pendulum.rb +++ b/ext/tk/sample/demos-jp/pendulum.rb @@ -19,8 +19,10 @@ 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.pack('side'=>'top') # create frame -TkFrame.new($pendulum_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -51,7 +53,7 @@ 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 @@ def repeat 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 dbca3e971..9ff71904c 100644 --- a/ext/tk/sample/demos-jp/plot.rb +++ b/ext/tk/sample/demos-jp/plot.rb @@ -16,14 +16,16 @@ 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 @@ 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 6a3c8c8ef..2febc2c55 100644 --- a/ext/tk/sample/demos-jp/puzzle.rb +++ b/ext/tk/sample/demos-jp/puzzle.rb @@ -16,8 +16,10 @@ 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.pack('side'=>'top') # frame 生成 -TkFrame.new($puzzle_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -51,18 +53,27 @@ # 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 @@ def def_puzzleswitch_proc(w, num) 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 3a11c394a..a61ad46d9 100644 --- a/ext/tk/sample/demos-jp/radio.rb +++ b/ext/tk/sample/demos-jp/radio.rb @@ -16,8 +16,10 @@ 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 @@ color = TkVariable.new # frame 生成 -TkFrame.new($radio_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -50,14 +52,14 @@ 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 b89520cdc..cf53e3e48 100644 --- a/ext/tk/sample/demos-jp/radio2.rb +++ b/ext/tk/sample/demos-jp/radio2.rb @@ -21,8 +21,10 @@ 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 @@ align = TkVariable.new # frame -TkFrame.new($radio2_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -56,18 +58,18 @@ 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 @@ }.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 a223a19bc..4bbc1b31f 100644 --- a/ext/tk/sample/demos-jp/radio3.rb +++ b/ext/tk/sample/demos-jp/radio3.rb @@ -21,8 +21,10 @@ 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 @@ 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 @@ } # 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 @@ }.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 c913e247d..d6bc9e76d 100644 --- a/ext/tk/sample/demos-jp/ruler.rb +++ b/ext/tk/sample/demos-jp/ruler.rb @@ -29,14 +29,16 @@ def rulerMkTab(c,x,y) 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 @@ def rulerMkTab(c,x,y) $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 24b011f5a..aa24b3a2a 100644 --- a/ext/tk/sample/demos-jp/sayings.rb +++ b/ext/tk/sample/demos-jp/sayings.rb @@ -16,8 +16,10 @@ 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.pack('side'=>'top') # frame 生成 -TkFrame.new($sayings_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -46,7 +48,7 @@ # 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 d3692e245..9838ff5d1 100644 --- a/ext/tk/sample/demos-jp/search.rb +++ b/ext/tk/sample/demos-jp/search.rb @@ -75,8 +75,10 @@ def textToggle(cmd1,sleep1,cmd2,sleep2) 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 @@ def textToggle(cmd1,sleep1,cmd2,sleep2) $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 @@ def textToggle(cmd1,sleep1,cmd2,sleep2) .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 @@ def textToggle(cmd1,sleep1,cmd2,sleep2) } }.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 b8eb99c4e..8d4e33cda 100644 --- a/ext/tk/sample/demos-jp/spin.rb +++ b/ext/tk/sample/demos-jp/spin.rb @@ -17,10 +17,12 @@ 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 @@ を組み合わせて試すようにしてください。 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 @@ ] [ - 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 3c58711bd..5e242b7c3 100644 --- a/ext/tk/sample/demos-jp/states.rb +++ b/ext/tk/sample/demos-jp/states.rb @@ -16,8 +16,10 @@ 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.pack('side'=>'top') # frame 生成 -TkFrame.new($states_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -46,7 +48,7 @@ # 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 7a8497f1b..66b6de025 100644 --- a/ext/tk/sample/demos-jp/style.rb +++ b/ext/tk/sample/demos-jp/style.rb @@ -17,9 +17,10 @@ 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 @@ # 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 25e0e64e9..0ae480eb0 100644 --- a/ext/tk/sample/demos-jp/text.rb +++ b/ext/tk/sample/demos-jp/text.rb @@ -16,6 +16,8 @@ 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 @@ end # frame 生成 -TkFrame.new($text_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -42,13 +44,13 @@ }.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 9b2b57a69..4967a99c9 100644 --- a/ext/tk/sample/demos-jp/textpeer.rb +++ b/ext/tk/sample/demos-jp/textpeer.rb @@ -16,10 +16,12 @@ 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,"また「ピア(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 @@ def killClone(win, cnt) 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 000000000..9cb3834c3 --- /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 000000000..c3b419114 --- /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 000000000..4d577120b --- /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 000000000..d349b42d1 --- /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 000000000..09cc7960a --- /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 000000000..96670c0e5 --- /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 000000000..43a9cbcd7 --- /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 d0fa8ca49..faefaefd6 100644 --- a/ext/tk/sample/demos-jp/twind.rb +++ b/ext/tk/sample/demos-jp/twind.rb @@ -16,8 +16,10 @@ 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 @@ # 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 e8009cef1..2a26b28ef 100644 --- a/ext/tk/sample/demos-jp/twind2.rb +++ b/ext/tk/sample/demos-jp/twind2.rb @@ -16,8 +16,10 @@ 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 @@ # 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 7ab415fe5..178077ec0 100644 --- a/ext/tk/sample/demos-jp/unicodeout.rb +++ b/ext/tk/sample/demos-jp/unicodeout.rb @@ -18,7 +18,9 @@ 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 @@ 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 @@ }).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 @@ def add_sample(lang, *args) 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 990ca4321..a1097fd77 100644 --- a/ext/tk/sample/demos-jp/vscale.rb +++ b/ext/tk/sample/demos-jp/vscale.rb @@ -12,7 +12,9 @@ } 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.pack('side'=>'top', 'padx'=>'.5c') -TkFrame.new($vscale_demo) {|frame| +TkFrame.new(base_frame) {|frame| TkButton.new(frame) { #text '了解' text '閉じる' @@ -40,7 +42,17 @@ }.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 @@ }.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 a7e4bf3ca..60ec5b5e9 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', "9. チェスボード上の騎士の巡回 (Tile/Ttk拡張への対応が必要)\n", + tag_demo, "demo-knightstour") +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.id, "demo-vscale") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "1. 垂直\n", tag_demo.id, "demo-vscale") +txt.insert('end', "2. 水平スケール\n", tag_demo.id, "demo-hscale") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "2. 水平\n", tag_demo.id, "demo-hscale") +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_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-filebox") txt.insert('end', " \n ", tag_demospace) -txt.insert('end', "3. 色選択ダイアログ\n", tag_demo, "demo-clrpick") +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 000000000..1b6979d2d --- /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 50ecde91f..eed95d0e1 100644 --- a/ext/tk/sample/tkextlib/treectrl/demo.rb +++ b/ext/tk/sample/tkextlib/treectrl/demo.rb @@ -9,11 +9,12 @@ $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 680b8da98..8701cfef2 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 d6c70db22..00d719143 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; }