diff options
author | nagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-07-01 09:38:48 +0000 |
---|---|---|
committer | nagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-07-01 09:38:48 +0000 |
commit | ffcedd79505ea2e99f859c7cea2fb2221c948d4c (patch) | |
tree | 02232516faf0e1959ecb5d5b7aca25a52f9f87ca /ext/tk/lib/tkextlib | |
parent | 73cf1d02bac2dbdd5d7f673a33d81444a00c865e (diff) |
* ext/tk/lib/tcltklib : bug fix
* ext/tk/lib/tk : bug fix and add Tcl/Tk extension support libraries
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6559 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/tk/lib/tkextlib')
65 files changed, 4817 insertions, 0 deletions
diff --git a/ext/tk/lib/tkextlib/ICONS.rb b/ext/tk/lib/tkextlib/ICONS.rb new file mode 100644 index 0000000000..84f4204c60 --- /dev/null +++ b/ext/tk/lib/tkextlib/ICONS.rb @@ -0,0 +1,16 @@ +# +# ICONS support +# by Hidetoshi NAGAI ([email protected]) +# + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# library directory +dir = File.expand_path(__FILE__).sub(/#{File.extname(__FILE__)}$/, '') + +# call setup script +require File.join(dir, 'setup.rb') + +# load library +require File.join(dir, 'icons') diff --git a/ext/tk/lib/tkextlib/ICONS/icons.rb b/ext/tk/lib/tkextlib/ICONS/icons.rb new file mode 100644 index 0000000000..fe8351fa52 --- /dev/null +++ b/ext/tk/lib/tkextlib/ICONS/icons.rb @@ -0,0 +1,84 @@ +# +# tkextlib/ICONS/icons.rb +# by Hidetoshi NAGAI ([email protected]) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('icons', '1.0') +TkPackage.require('icons') + +module Tk + class ICONS < TkImage + def self.create(*args) # icon, icon, ..., keys + if args[-1].kind_of?(Hash) + keys = args.pop + icons = simplelist(tk_call('::icons::icons', 'create', + *(hash_kv(keys).concat(args.flatten)))) + else + icons = simplelist(tk_call('::icons::icons', 'create', + *(args.flatten))) + end + + icons.collect{|icon| self.new(icon, :without_creating=>true)} + end + + def self.delete(*icons) + return if icons.empty? + tk_call('::icons::icons', 'delete', icons) + end + + def self.query(*args) + if args[-1].kind_of?(Hash) + keys = args.pop + list(tk_call('::icons::icons', 'query', + *(hash_kv(keys).concat(args.flatten)))) + else + list(tk_call('::icons::icons', 'query', *(args.flatten))) + end + end + + ########################################## + + def self.new(name, keys=nil) + Tk_IMGTBL["::icon::#{name}"] || super + end + + def initialize(name, keys=nil) + if name.kind_of?(String) && name =~ /^::icon::(.+)$/ + @name = $1 + @path = name + else + @name = name.to_s + @path = "::icon::#{@name}" + end + keys = _symbolkey2str(keys) + unless keys.delete('without_creating') + tk_call('::icons::icons', 'create', *(hash_kv(keys) << @name)) + end + Tk_IMGTBL[@path] = self + end + + def name + @name + end + + def delete + Tk_IMGTBL.delete(@path) + tk_call('::icons::icons', 'delete', @name) + self + end + + def query(keys) + list(simplelist(tk_call('::icons::icons', 'query', + *(hash_kv(keys) << @name)) + )[0]) + end + end +end diff --git a/ext/tk/lib/tkextlib/ICONS/setup.rb b/ext/tk/lib/tkextlib/ICONS/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ext/tk/lib/tkextlib/ICONS/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ext/tk/lib/tkextlib/SUPPORT_STATUS b/ext/tk/lib/tkextlib/SUPPORT_STATUS new file mode 100644 index 0000000000..6cc5e15617 --- /dev/null +++ b/ext/tk/lib/tkextlib/SUPPORT_STATUS @@ -0,0 +1,161 @@ + + [ current support status of Tcl/Tk extensions ] + +The following list shows *CURRENT* status when this file was modifyed +at last. If you want to add other Tcl/Tk extensions to the planed list +(or change its status position), please request them at the ruby-talk, +ruby-list, or ruby-dev ML. Although we cannot promise to support your +requests, we'll try to do. + +If you want to check that wrapper libraries are ready to use on your +environment, please execute 'pkg_checker.rb' with no arguments. The +script may give you some hints about that. + + + ***** IMPORTANT NOTE ********************************************** + + 'support' means that Ruby/Tk's wrapper libraries are released. + 'not support' does *NOT* mean that the extension doesn't work + on Ruby/Tk. + + Even if the status of the extension is 'not support', you can + control the functions/widgets of the extension without wrapper + libraries by Tk.tk_call(), Tk.ip_eval(), and so on. + + If you cannot use installed Tcl/Tk extension, please check the + followings. + + (1) On your Tcl/Tk, does the extention work? + + (2) Do DLL libraries of the extension exist on DLL load-path? + (See also "<ruby archive>/ext/tcltklib/README.ActiveTcl") + + (3) Is the Tcl library directory of the extension included in + library search-path of the Tcl interpreter linked Ruby/Tk? + + The check results may request you to do some setup operations + before using the extension. If so, then please write the step + of setup oprations into the "setup.rb" file in the directory + of the wrapper libraries for the extention (It is the wrapper + libraries have the standard structure of the libraries in this + directory). The "setup" file is required before requiring the + Tcl library package (TkPackage.require(<libname>)). + + ******************************************************************* + + +===< support with some examples (may be beta quality) >======================= + +Tcllib http://sf.net/projects/tcllib + ==> tcllib (partial support; Tklib part only) + +vu http://tktable.sourceforge.net ==> vu + +TkHTML http://www.hwaci.com/sw/tkhtml/index.html ==> tkHTML + + + +===< support (may be alpha or beta quality) >================================= + +TkImg http://sf.net/projects/tkimg ==> tkimg + +TkTreeCtrl http://tktreectrl.sourceforge.net/ ==> treectrl + +Tile http://tktable.sourceforge.net/tile/ ==> tile + + + +===< possibly support (not tested; alpha quality) >=========================== + +TkTrans http://www2.cmp.uea.ac.uk/~fuzz/tktrans/default.html + ==> tktrans (win32 only) + +TkDND http://sourceforge.net/projects/tkdnd ==> tkDND + +ICONS http://www.satisoft.com/tcltk/icons/ ==> ICONS + + + +===< plan to support (alpha quality libraries may be included) >============== + +TclX http://sf.net/projects/tclx * may support Tk part only + +IncrTcl http://sf.net/projects/incrTcl * may support Tk part only + +IWidgets http://sf.net/projects/incrTcl + +TkTable http://sf.net/projects/tktable + * see http://www.korus.hu/~fery/ruby/tktable.rb + +BWidgets http://sf.net/projects/tcllib + +winico http://tktable.sourceforge.net + + + +===< not determined to supprt or not >======================================== + +GraphViz http://www.graphviz.org/ + +BLT http://sourceforge.net/projects/blt + +Tix http://tixlibrary.sourceforge.net/ + +Tkgeomap http://tkgeomap.sourceforge.net/index.html + +XBit http://www.geocities.com/~chengye/ + +TkZinc http://www.tkzinc.org/ + +Wbc http://home.t-online.de/home/csaba.nemethi/ + +Mentry http://home.t-online.de/home/csaba.nemethi/ + +Tablelist http://home.t-online.de/home/csaba.nemethi/ + +vfwtcl http://sourceforge.net/projects/avicaptcl + +QuickTimeTcl http://hem.fyristorg.com/matben/qt/ + +ANIGIF http://cardtable.sourceforge.net/tcltk/ + +IMG_ROTATE http://cardtable.sourceforge.net/tcltk/ + +TclVfs http://sourceforge.net/projects/tclvfs/ + + + +===< may not support (already exist, out of Ruby/Tk scope, and so on) >======= + +TkCon http://sf.net/projects/tkcon + +Expect http://sf.net/projects/expect + +TclXML http://sf.net/projects/tclxml + +TclXSLT http://sf.net/projects/tclxml + +TclDOM http://sf.net/projects/tclxml + +TclSOAP http://sf.net/projects/tclsoap + +Snack http://www.speech.kth.se/~kare/snack2.2.tar.gz + * use Snack for Ruby (see http://rbsnack.sourceforge.net/) + +Tcom http://www.vex.net/~cthuang/tcom/ + +tDOM http://www.tdom.org + +Mk4tcl http://www.equi4.com/metakit/tcl.html + +Memchan http://memchan.sourceforge.net/ + + + +===< tool (may not supprt) >================================================== + +tbcload/tclcompiler http://www.tcl.tk/software/tclpro/ + + + +(End of List)
\ No newline at end of file diff --git a/ext/tk/lib/tkextlib/pkg_checker.rb b/ext/tk/lib/tkextlib/pkg_checker.rb new file mode 100755 index 0000000000..813273e65b --- /dev/null +++ b/ext/tk/lib/tkextlib/pkg_checker.rb @@ -0,0 +1,129 @@ +#!/usr/bin/env ruby +# +# Ruby/Tk extension library checker +# +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +TkRoot.new.withdraw # hide root window + +name = File.basename(__FILE__) + +if ARGV[0] + dir = File.expand_path(ARGV[0]) +else + dir = File.dirname(File.expand_path(__FILE__)) +end + +print "\nRuby/Tk extension library checker\n" +print "( Note:: This check is very simple one. Shown status may be wrong. )\n" +print "\n check directory :: #{dir}\n" + +def get_pkg_list(file) + pkg_list = [] + + File.foreach(file){|l| + if l =~ /^(?:[^#]+\s|\s*)(?:|;\s*)TkPackage\s*\.\s*require\s*\(?\s*(["'])((\w|:)+)\1/ + pkg = [$2, :package] + pkg_list << pkg unless pkg_list.member?(pkg) + end + if l =~ /^(?:[^#]+\s|\s*)(?:|;\s*)Tk\s*\.\s*load_tcllibrary\s*\(?\s*(["'])((\w|:)+)\1/ + pkg = [$2, :library] + pkg_list << pkg unless pkg_list.member?(pkg) + end + if l =~ /^(?:[^#]+\s|\s*)(?:|;\s*)Tk\s*\.\s*load_tclscript\s*\(?\s*(["'])((\w|:)+)\1/ + pkg = [$2, :script] + pkg_list << pkg unless pkg_list.member?(pkg) + end + } + + pkg_list +end + +def check_pkg(file) + pkg_list = get_pkg_list(file) + + error_list = [] + success_list = {} + + pkg_list.each{|name, type| + next if success_list[name] + + begin + case type + when :package + ver = TkPackage.require(name) + success_list[name] = ver + error_list.delete_if{|n, t| n == name} + + when :library + Tk.load_tcllibrary(name) + success_list[name] = :library + error_list.delete_if{|n, t| n == name} + + when :script + Tk.load_tclscript(name) + success_list[name] = :script + error_list.delete_if{|n, t| n == name} + + end + rescue + error_list << [name, type] + end + } + + success_list.dup.each{|name, ver| + unless ver.kind_of?(String) + begin + ver = TkPackage.require(name) + sccess_list[name] = ver + rescue + end + end + } + + [success_list, error_list] +end + +def subdir_check(dir) + Dir.foreach(dir){|f| + next if f == '.' || f == '..' + if File.directory?(f) + subdir_check(File.join(dir, f)) + elsif File.extname(f) == '.rb' + path = File.join(dir, f) + suc, err = check_pkg(path) + if err.empty? + print 'Ready : ', path, ' : require->', suc.inspect, "\n" + else + print '*LACK : ', path, ' : require->', suc.inspect, + ' FAIL->', err.inspect, "\n" + end + end + } +end + +Dir.chdir(dir) + +(Dir['*.rb'] - ['setup.rb', name]).each{|f| + subdir = File.basename(f, '.*') + begin + # read 'setup.rb' as if the library has standard structure + require File.join(subdir, 'setup.rb') + rescue LoadError + # ignore error + end + + print "\n" + + suc, err = check_pkg(f) + if err.empty? + print 'Ready : ', f, ' : require->', suc.inspect, "\n" + else + print '*LACK : ', f, ' : require->', suc.inspect, + ' FAIL->', err.inspect, "\n" + end + + subdir_check(subdir) if File.directory?(subdir) +} diff --git a/ext/tk/lib/tkextlib/setup.rb b/ext/tk/lib/tkextlib/setup.rb new file mode 100644 index 0000000000..12867e8f9c --- /dev/null +++ b/ext/tk/lib/tkextlib/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before using Tk extension libraries +# +# If you need some setup operations for Tk extensions (for example, +# modify the dynamic library path) required, please write the setup +# operations in this file. This file is required at the last of +# "require 'tk'". +# diff --git a/ext/tk/lib/tkextlib/tcllib.rb b/ext/tk/lib/tkextlib/tcllib.rb new file mode 100644 index 0000000000..56f21556ae --- /dev/null +++ b/ext/tk/lib/tkextlib/tcllib.rb @@ -0,0 +1,57 @@ +# +# tcllib extension support +# by Hidetoshi NAGAI ([email protected]) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# library directory +dir = File.expand_path(__FILE__).sub(/#{File.extname(__FILE__)}$/, '') + +# call setup script +require File.join(dir, 'setup.rb') + +# package:: autoscroll +#require 'tkextlib/tcllib/autoscroll' +require File.join(dir, 'autoscroll') + +# package:: cursor +#require 'tkextlib/tcllib/cursor' +require File.join(dir, 'cursor') + +# package:: style +#require 'tkextlib/tcllib/style' +require File.join(dir, 'style') + + +# autoload +module Tk + module Tcllib + dir = File.expand_path(__FILE__).sub(/#{File.extname(__FILE__)}$/, '') + + # package:: ctext + #autoload :CText, 'tkextlib/tcllib/ctext' + autoload :CText, File.join(dir, 'ctext') + + # package:: datefield + #autoload :Datefield, 'tkextlib/tcllib/datefield' + #autoload :DateField, 'tkextlib/tcllib/datefield' + autoload :Datefield, File.join(dir, 'datefield') + autoload :DateField, File.join(dir, 'datefield') + + # package:: ipentry + #autoload :IP_Entry, 'tkextlib/tcllib/ip_entry' + autoload :IP_Entry, File.join(dir, 'ip_entry') + + # package:: Plotchart + #autoload :Plotchart, 'tkextlib/tcllib/plotchart' + autoload :Plotchart, File.join(dir, 'plotchart') + + # package:: tkpiechart + #autoload :Tkpiechart, 'tkextlib/tcllib/tkpiechart' + autoload :Tkpiechart, File.join(dir, 'tkpiechart') + end +end diff --git a/ext/tk/lib/tkextlib/tcllib/README b/ext/tk/lib/tkextlib/tcllib/README new file mode 100644 index 0000000000..953239befa --- /dev/null +++ b/ext/tk/lib/tkextlib/tcllib/README @@ -0,0 +1,135 @@ + + [ tcllib extension support files ] + +Tcllib includes many utilities. But currently, supports TKLib part +only (see the following 'tcllib contents'). + +If you request to support others, please send your message to one of +ruby-talk/ruby-list/ruby-dev/ruby-ext mailing lists. + +-----<from "What is tcllib?">---------------------------- +Tcllib is a collection of utility modules for Tcl. These modules provide +a wide variety of functionality, from implementations of standard data +structures to implementations of common networking protocols. The intent +is to collect commonly used function into a single library, which users +can rely on to be available and stable. +--------------------------------------------------------- + +-----< tcllib contents (based on tcllib-1.6.1) >--------- +Programming tools + * cmdline - Procedures to process command lines and options. + * comm - A remote communications facility for Tcl (7.6, 8.0, and later) + * control - Procedures for control flow structures. + * fileutil - Procedures implementing some file utilities + * log - Procedures to log messages of libraries and applications. + * logger - System to control logging of events. + * multiplexer - One-to-many communication with sockets. + * snit - Snit's Not Incr Tcl + * snitfaq - Snit Frequently Asked Questions + * stooop - Object oriented extension. + * stoop - Simple Tcl Only Object Oriented Programming + * switched - stooop switched class + * profiler - Tcl source code profiler + +Mathematics + * math::statistics - Basic statistical functions and procedures + * math::calculus - Integration and ordinary differential equations + * math::optimize - Optimisation routines + * math::fuzzy - Fuzzy comparison of floating-point numbers + * counter - Procedures for counters and histograms + * combinatorics - Combinatorial functions in the Tcl Math Library + +Data structures + * struct::list - Procedures for manipulating lists + * struct::set - Procedures for manipulating sets + * struct::stack - Create and manipulate stack objects + * struct::queue - Create and manipulate queue objects + * struct::prioqueue - Create and manipulate prioqueue objects + * struct::skiplist - Create and manipulate skiplists + * struct::tree - Create and manipulate tree objects + * struct::graph - Create and manipulate directed graph objects + * struct::record - Define and create records (similar to 'C' structures) + * struct::matrix - Create and manipulate matrix objects + * struct::pool - Create and manipulate pool objects (of discrete items) + * report - Create and manipulate report objects + +Text processing + * expander - Procedures to process templates and expand text. + * base64 - Procedures to encode and decode base64 + * yencode - encode/decoding a binary file + * uuencode - encode/decoding a binary file + * csv - Procedures to handle CSV data. + * inifile - Parsing of Windows INI files + * htmlparse - Procedures to parse HTML strings + * mime - Manipulation of MIME body parts + * Tcl MIME - generates and parses MIME body parts + * textutil - Procedures to manipulate texts and strings. + * exif - Tcl EXIF extracts and parses EXIF fields from digital images + * EXIF - extract and parse EXIF fields from digital images + +Hashes, checksums, and encryption + * cksum - calculate a cksum(1) compatible checksum + * crc16 - Perform a 16bit Cyclic Redundancy Check + * crc32 - Perform a 32bit Cyclic Redundancy Check + * des - Perform DES encryption of Tcl data + * md4 - MD4 Message-Digest Algorithm + * md5 - MD5 Message-Digest Algorithm + * ripemd160 - RIPEMD-160 Message-Digest Algorithm + * ripemd128 - RIPEMD-128 Message-Digest Algorithm + * md5crypt - MD5-based password encryption + * sha1 - Perform sha1 hashing + * sum - calculate a sum(1) compatible checksum + * soundex - Soundex + +Documentation tools + * mpexpand - Markup processor + * doctools - Create and manipulate doctools converter object + * doctoc_fmt - Specification of simple tcl markup for table of contents + * doctools_api - Interface specification for formatter code + * doctools_fmt - Specification of simple tcl markup for manpages + * docidx - Create and manipulate docidx converter objects + * docidx_api - Interface specification for index formatting code + * docidx_fmt - Specification of simple tcl markup for an index + * doctoc - Create and manipulate doctoc converter objects + * doctoc_api - Interface specification for toc formatting code + * doctools::changelog - Handle text in Emacs ChangeLog format + * doctools::cvs - Handle text in 'cvs log' format + +Networking + * uri - URI utilities + * dns - Tcl Domain Name Service Client + * ntp_time - Tcl Time Service Client + * nntp - Tcl client for the NNTP protocol + * pop3 - Tcl client for POP3 email protocol + * pop3d - Tcl POP3 server implementation + * pop3d::udb - Simple user database for pop3d + * pop3d::dbox - Simple mailbox database for pop3d + * ftp - Client-side tcl implementation of the ftp protocol + * ftp - Client-side tcl implementation of the ftp protocol + * ftpd - Tcl FTP server implementation + * smtp - Client-side tcl implementation of the smtp protocol + * smtpd - Tcl SMTP server implementation + * irc - Create IRC connection and interface. + +CGI programming + * ncgi - Procedures to manipulate CGI values. + * html - Procedures to generate HTML structures + * javascript - Procedures to generate HTML and Java Script structures. + +Grammars and finite automata + * grammar::fa - Create and manipulate finite automatons + * grammar::fa::op - Operations on finite automatons + * grammar::dacceptor - Create and use deterministic acceptors + * grammar::dexec - Execute deterministic finite automatons + +TKLib + * Plotchart - Simple plotting and charting package + * autoscroll - Provides for a scrollbar to automatically mapped and + unmapped as needed + * ctext - An extended text widget with customizable Syntax highlighting + * cursor - Procedures to handle CURSOR data + * datefield - Tk datefield widget + * style - Changes default Tk look&feel + * ipentry - An IP address entry widget + * tkpiechart - Creates and dynamically updates 2D or 3D pie charts +--------------------------------------------------------- diff --git a/ext/tk/lib/tkextlib/tcllib/autoscroll.rb b/ext/tk/lib/tkextlib/tcllib/autoscroll.rb new file mode 100644 index 0000000000..9c161d7ec9 --- /dev/null +++ b/ext/tk/lib/tkextlib/tcllib/autoscroll.rb @@ -0,0 +1,100 @@ +# +# tkextlib/tcllib/autoscroll.rb +# by Hidetoshi NAGAI ([email protected]) +# +# * Part of tcllib extension +# * Provides for a scrollbar to automatically mapped and unmapped as needed +# +# (The following is the original description of the library.) +# +# This package allows scrollbars to be mapped and unmapped as needed +# depending on the size and content of the scrollbars scrolled widget. +# The scrollbar must be managed by either pack or grid, other geometry +# managers are not supported. +# +# When managed by pack, any geometry changes made in the scrollbars parent +# between the time a scrollbar is unmapped, and when it is mapped will be +# lost. It is an error to destroy any of the scrollbars siblings while the +# scrollbar is unmapped. When managed by grid, if anything becomes gridded +# in the same row and column the scrollbar occupied it will be replaced by +# the scrollbar when remapped. +# +# This package may be used on any scrollbar-like widget as long as it +# supports the set subcommand in the same style as scrollbar. If the set +# subcommand is not used then this package will have no effect. +# + +require 'tk' +require 'tk/scrollbar' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('autoscroll', '1.0') +TkPackage.require('autoscroll') + +module Tk + module Scrollable + def autoscroll(mode = nil) + case mode + when :x, 'x' + if @xscrollbar + tk_send_without_enc('::autoscroll::autoscroll', @xscrollbar) + end + when :y, 'y' + if @yscrollbar + tk_send_without_enc('::autoscroll::autoscroll', @yscrollbar) + end + when nil, :both, 'both' + if @xscrollbar + tk_send_without_enc('::autoscroll::autoscroll', @xscrollbar) + end + if @yscrollbar + tk_send_without_enc('::autoscroll::autoscroll', @yscrollbar) + end + else + fail ArgumentError, "'x', 'y' or 'both' (String or Symbol) is expected" + end + self + end + def unautoscroll(mode = nil) + case mode + when :x, 'x' + if @xscrollbar + tk_send_without_enc('::autoscroll::unautoscroll', @xscrollbar) + end + when :y, 'y' + if @yscrollbar + tk_send_without_enc('::autoscroll::unautoscroll', @yscrollbar) + end + when nil, :both, 'both' + if @xscrollbar + tk_send_without_enc('::autoscroll::unautoscroll', @xscrollbar) + end + if @yscrollbar + tk_send_without_enc('::autoscroll::unautoscroll', @yscrollbar) + end + else + fail ArgumentError, "'x', 'y' or 'both' (String or Symbol) is expected" + end + self + end + end +end + +class TkScrollbar + def autoscroll + # Arranges for the already existing scrollbar to be mapped + # and unmapped as needed. + tk_send_without_enc('::autoscroll::autoscroll', @path) + self + end + def unautoscroll + # Returns the scrollbar to its original static state. + tk_send_without_enc('::autoscroll::unautoscroll', @path) + self + end +end diff --git a/ext/tk/lib/tkextlib/tcllib/ctext.rb b/ext/tk/lib/tkextlib/tcllib/ctext.rb new file mode 100644 index 0000000000..6fa3e2edda --- /dev/null +++ b/ext/tk/lib/tkextlib/tcllib/ctext.rb @@ -0,0 +1,141 @@ +# +# tkextlib/tcllib/ctext.rb +# by Hidetoshi NAGAI ([email protected]) +# +# * Part of tcllib extension +# * Overloads the text widget and provides new commands +# + +require 'tk' +require 'tk/text' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('ctext', '3.1') +TkPackage.require('ctext') + +module Tk + module Tcllib + class CText < TkText + end + end +end + +class Tk::Tcllib::CText + TkCommandNames = ['ctext'.freeze].freeze + WidgetClassName = 'Ctext'.freeze + WidgetClassNames[WidgetClassName] = self + + def create_self(keys) + if keys and keys != None + tk_call_without_enc('ctext', @path, *hash_kv(keys, true)) + else + tk_call_without_enc('ctext', @path) + end + end + private :create_self + + def append(*args) + tk_send('append', *args) + end + + def copy + tk_send('copy') + end + + def cut + tk_send('cut') + end + + def fast_delete(*args) + tk_send('fastdelete', *args) + end + + def fast_insert(*args) + tk_send('fastinsert', *args) + end + + def highlight(*args) + tk_send('highlight', *args) + end + + def paste + tk_send('paste') + end + + def edit(*args) + tk_send('edit', *args) + end + + def add_highlight_class(klass, col, *keywords) + tk_call('ctext::addHighlightClass', @path, klass, col, keywords.flatten) + self + end + + def add_highlight_class_for_special_chars(klass, col, *chrs) + tk_call('ctext::addHighlightClassForSpecialChars', + @path, klass, col, chrs.join('')) + self + end + + def add_highlight_class_for_regexp(klass, col, tcl_regexp) + tk_call('ctext::addHighlightClassForRegexp', + @path, klass, col, tcl_regexp) + self + end + + def add_highlight_class_with_only_char_start(klass, col, chr) + tk_call('ctext::addHighlightClassWithOnlyCharStart', + @path, klass, col, chr) + self + end + + def clear_highlight_classes + tk_call('ctext::clearHighlightClasses', @path) + self + end + + def get_highlight_classes + tk_split_simplelist(tk_call('ctext::getHighlightClasses', @path)) + end + + def delete_highlight_class(klass) + tk_call('ctext::deleteHighlightClass', @path, klass) + self + end + + def enable_C_comments + tk_call('ctext::enableComments', @path) + self + end + + def disable_C_comments + tk_call('ctext::disableComments', @path) + self + end + + def find_next_char(idx, chr) + tk_call('ctext::findNextChar', @path, idx, chr) + end + + def find_next_space(idx) + tk_call('ctext::findNextSpace', @path, idx) + end + + def find_previous_space(idx) + tk_call('ctext::findPreviousSpace', @path, idx) + end + + def set_update_proc(cmd=Proc.new) + tk_call('proc', 'ctext::update', '', cmd) + self + end + + def modified(mode) + bool(tk_call('ctext::modified', @path, mode)) + end +end diff --git a/ext/tk/lib/tkextlib/tcllib/cursor.rb b/ext/tk/lib/tkextlib/tcllib/cursor.rb new file mode 100644 index 0000000000..cf4f247209 --- /dev/null +++ b/ext/tk/lib/tkextlib/tcllib/cursor.rb @@ -0,0 +1,41 @@ +# +# tkextlib/tcllib/cursor.rb +# by Hidetoshi NAGAI ([email protected]) +# +# * Part of tcllib extension +# * Procedures to handle CURSOR data +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('cursor', '0.1') +TkPackage.require('cursor') + +module Tk + def self.cursor_display(parent=None) + # Pops up a dialog with a listbox containing all the cursor names. + # Selecting a cursor name will display it in that dialog. + # This is simply for viewing any available cursors on the platform . + tk_call_without_enc('::cursor::display', parent) + end +end + +class TkWindow + def cursor_propagate(cursor) + # Sets the cursor for self and all its descendants to cursor. + tk_send_without_enc('::cursor::propagate', @path, cursor) + end + def cursor_restore(cursor = None) + # Restore the original or previously set cursor for self and all its + # descendants. If cursor is specified, that will be used if on any + # widget that did not have a preset cursor (set by a previous call + # to TkWindow#cursor_propagate). + tk_send_without_enc('::cursor::restore', @path, cursor) + end +end diff --git a/ext/tk/lib/tkextlib/tcllib/datefield.rb b/ext/tk/lib/tkextlib/tcllib/datefield.rb new file mode 100644 index 0000000000..6d3ba4693f --- /dev/null +++ b/ext/tk/lib/tkextlib/tcllib/datefield.rb @@ -0,0 +1,50 @@ +# +# tkextlib/tcllib/datefield.rb +# by Hidetoshi NAGAI ([email protected]) +# +# * Part of tcllib extension +# * Tk datefield widget +# +# (The following is the original description of the library.) +# +# The datefield package provides the datefield widget which is an enhanced +# text entry widget for the purpose of date entry. Only valid dates of the +# form MM/DD/YYYY can be entered. +# +# The datefield widget is, in fact, just an entry widget with specialized +# bindings. This means all the command and options for an entry widget apply +# equally here. + +require 'tk' +require 'tk/entry' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('datefield', '0.1') +TkPackage.require('datefield') + +module Tk + module Tcllib + class Datefield < TkEntry + end + DateField = Datefield + end +end + +class Tk::Tcllib::Datefield + TkCommandNames = ['::datefield::datefield'.freeze].freeze + + def create_self(keys) + if keys and keys != None + tk_call_without_enc('::datefield::datefield', @path, + *hash_kv(keys, true)) + else + tk_call_without_enc('::datefield::datefield', @path) + end + end + private :create_self +end diff --git a/ext/tk/lib/tkextlib/tcllib/ip_entry.rb b/ext/tk/lib/tkextlib/tcllib/ip_entry.rb new file mode 100644 index 0000000000..aed47da63a --- /dev/null +++ b/ext/tk/lib/tkextlib/tcllib/ip_entry.rb @@ -0,0 +1,53 @@ +# +# tkextlib/tcllib/ip_entry.rb +# by Hidetoshi NAGAI ([email protected]) +# +# * Part of tcllib extension +# * An IP address entry widget +# +# (The following is the original description of the library.) +# +# This package provides a widget for the entering of a IP address. +# It guarantees a valid address at all times. + +require 'tk' +require 'tk/entry' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('ipentry', '0.1') +TkPackage.require('ipentry') + +module Tk + module Tcllib + class IP_Entry < TkEntry + end + end +end + +class Tk::Tcllib::IP_Entry + TkCommandNames = ['::ipentry::ipentry'.freeze].freeze + WidgetClassName = 'IPEntry'.freeze + WidgetClassNames[WidgetClassName] = self + + def create_self(keys) + if keys and keys != None + tk_call_without_enc('::ipentry::ipentry', @path, *hash_kv(keys, true)) + else + tk_call_without_enc('::ipentry::ipentry', @path) + end + end + private :create_self + + def complete? + bool(tk_send_without_enc('complete')) + end + + def insert(*ip) + tk_send_without_enc('insert', array2tk_list(ip.flatten)) + end +end diff --git a/ext/tk/lib/tkextlib/tcllib/plotchart.rb b/ext/tk/lib/tkextlib/tcllib/plotchart.rb new file mode 100644 index 0000000000..108507b05b --- /dev/null +++ b/ext/tk/lib/tkextlib/tcllib/plotchart.rb @@ -0,0 +1,666 @@ +# +# tkextlib/tcllib/plotchart.rb +# by Hidetoshi NAGAI ([email protected]) +# +# * Part of tcllib extension +# * Simple plotting and charting package +# +# (The following is the original description of the library.) +# +# Plotchart is a Tcl-only package that focuses on the easy creation of +# xy-plots, barcharts and other common types of graphical presentations. +# The emphasis is on ease of use, rather than flexibility. The procedures +# that create a plot use the entire canvas window, making the layout of the +# plot completely automatic. +# +# This results in the creation of an xy-plot in, say, ten lines of code: +# -------------------------------------------------------------------- +# package require Plotchart +# +# canvas .c -background white -width 400 -height 200 +# pack .c -fill both +# +# # +# # Create the plot with its x- and y-axes +# # +# set s [::Plotchart::createXYPlot .c {0.0 100.0 10.0} {0.0 100.0 20.0}] +# +# foreach {x y} {0.0 32.0 10.0 50.0 25.0 60.0 78.0 11.0 } { +# $s plot series1 $x $y +# } +# +# $s title "Data series" +# -------------------------------------------------------------------- +# +# A drawback of the package might be that it does not do any data management. +# So if the canvas that holds the plot is to be resized, the whole plot must +# be redrawn. The advantage, though, is that it offers a number of plot and +# chart types: +# +# * XY-plots like the one shown above with any number of data series. +# * Stripcharts, a kind of XY-plots where the horizontal axis is adjusted +# automatically. The result is a kind of sliding window on the data +# series. +# * Polar plots, where the coordinates are polar instead of cartesian. +# * Isometric plots, where the scale of the coordinates in the two +# directions is always the same, i.e. a circle in world coordinates +# appears as a circle on the screen. +# You can zoom in and out, as well as pan with these plots (Note: this +# works best if no axes are drawn, the zooming and panning routines do +# not distinguish the axes), using the mouse buttons with the control +# key and the arrow keys with the control key. +# * Piecharts, with automatic scaling to indicate the proportions. +# * Barcharts, with either vertical or horizontal bars, stacked bars or +# bars side by side. +# * Timecharts, where bars indicate a time period and milestones or other +# important moments in time are represented by triangles. +# * 3D plots (both for displaying surfaces and 3D bars) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('Plotchart', '0.9') +TkPackage.require('Plotchart') + +module Tk + module Tcllib + module Plotchart + end + end +end + +module Tk::Tcllib::Plotchart + ############################ + def self.view_port(w, *args) # args := pxmin, pymin, pxmax, pymax + tk_call_without_enc('::Plotchart::viewPort', w.path, *(args.flatten)) + end + + def self.world_coordinates(w, *args) # args := xmin, ymin, xmax, ymax + tk_call_without_enc('::Plotchart::worldCoordinates', + w.path, *(args.flatten)) + end + + def self.world_3D_coordinates(w, *args) + # args := xmin, ymin, zmin, xmax, ymax, zmax + tk_call_without_enc('::Plotchart::world3DCoordinates', + w.path, *(args.flatten)) + end + + def self.coords_to_pixel(w, x, y) + list(tk_call_without_enc('::Plotchart::coordsToPixel', w.path, x, y)) + end + + def self.coords_3D_to_pixel(w, x, y, z) + list(tk_call_without_enc('::Plotchart::coords3DToPixel', w.path, x, y, z)) + end + + def self.polar_coordinates(w, radmax) + tk_call_without_enc('::Plotchart::polarCoordinates', w.path, radmax) + end + + def self.polar_to_pixel(w, rad, phi) + list(tk_call_without_enc('::Plotchart::polarToPixel', w.path, rad, phi)) + end + + def self.pixel_to_coords(w, x, y) + list(tk_call_without_enc('::Plotchart::coordsToPixel', w.path, x, y)) + end + + def self.determine_scale(w, xmax, ymax) + tk_call_without_enc('::Plotchart::determineScale', w.path, xmax, ymax) + end + + def self.set_zoom_pan(w) + tk_call_without_enc('::Plotchart::setZoomPan', w.path) + end + + ############################ + module ChartMethod + include TkUtil + + def title(str) + tk_call_without_enc(@chart, 'title', _get_eval_enc_str(str)) + self + end + + def save_plot(filename) + tk_call_without_enc(@chart, 'saveplot', filename) + self + end + + def xtext(str) + tk_call_without_enc(@chart, 'xtext', _get_eval_enc_str(str)) + self + end + + def ytext(str) + tk_call_without_enc(@chart, 'ytext', _get_eval_enc_str(str)) + self + end + + def xconfig(key, value=None) + if key.kind_of?(Hash) + tk_call_without_enc(@chart, 'xconfig', *hash_kv(key, true)) + else + tk_call_without_enc(@chart, 'xconfig', + "-#{key}", _get_eval_enc_str(value)) + end + self + end + + def yconfig(key, value=None) + if key.kind_of?(Hash) + tk_call_without_enc(@chart, 'yconfig', *hash_kv(key, true)) + else + tk_call_without_enc(@chart, 'yconfig', + "-#{key}", _get_eval_enc_str(value)) + end + self + end + + ############################ + def view_port(*args) # args := pxmin, pymin, pxmax, pymax + tk_call_without_enc('::Plotchart::viewPort', @path, *(args.flatten)) + self + end + + def world_coordinates(*args) # args := xmin, ymin, xmax, ymax + tk_call_without_enc('::Plotchart::worldCoordinates', + @path, *(args.flatten)) + self + end + + def world_3D_coordinates(*args) + # args := xmin, ymin, zmin, xmax, ymax, zmax + tk_call_without_enc('::Plotchart::world3DCoordinates', + @path, *(args.flatten)) + self + end + + def coords_to_pixel(x, y) + list(tk_call_without_enc('::Plotchart::coordsToPixel', @path, x, y)) + end + + def coords_3D_to_pixel(x, y, z) + list(tk_call_without_enc('::Plotchart::coords3DToPixel', @path, x, y, z)) + end + + def polar_coordinates(radmax) + tk_call_without_enc('::Plotchart::polarCoordinates', @path, radmax) + self + end + + def polar_to_pixel(rad, phi) + list(tk_call_without_enc('::Plotchart::polarToPixel', @path, rad, phi)) + end + + def pixel_to_coords(x, y) + list(tk_call_without_enc('::Plotchart::coordsToPixel', @path, x, y)) + end + + def determine_scale(xmax, ymax) + tk_call_without_enc('::Plotchart::determineScale', @path, xmax, ymax) + self + end + + def set_zoom_pan() + tk_call_without_enc('::Plotchart::setZoomPan', @path) + self + end + end + + ############################ + class XYPlot < TkCanvas + include ChartMethod + + TkCommandNames = ['::Plotchart::createXYPlot'.freeze].freeze + + def initialize(*args) # args := ([parent,] xaxis, yaxis [, keys]) + # xaxis := Array of [minimum, maximum, stepsize] + # yaxis := Array of [minimum, maximum, stepsize] + if args[0].kind_of?(Array) + @xaxis = args.shift + @yaxis = args.shift + + super(*args) # create canvas widget + else + parent = args.shift + + @xaxis = args.shift + @yaxis = args.shift + + if parent.kind_of?(TkCanvas) + @path = parent.path + else + super(parent, *args) # create canvas widget + end + end + + @chart = _create_chart + end + + def _create_chart + p self.class::TkCommandNames[0] if $DEBUG + tk_call_without_enc(self.class::TkCommandNames[0], @path, + array2tk_list(@xaxis), array2tk_list(@yaxis)) + end + private :_create_chart + + def plot(series, x, y) + tk_call_without_enc(@chart, 'plot', _get_eval_enc_str(series), x, y) + self + end + + def dataconfig(series, key, value=None) + if key.kind_of?(Hash) + tk_call_without_enc(@chart, 'dataconfig', series, *hash_kv(key, true)) + else + tk_call_without_enc(@chart, 'dataconfig', series, + "-#{key}", _get_eval_enc_str(value)) + end + end + end + + ############################ + class Stripchart < XYPlot + TkCommandNames = ['::Plotchart::createStripchart'.freeze].freeze + end + + ############################ + class PolarPlot < TkCanvas + include ChartMethod + + TkCommandNames = ['::Plotchart::createPolarplot'.freeze].freeze + + def initialize(*args) # args := ([parent,] radius_data [, keys]) + # radius_data := Array of [maximum_radius, stepsize] + if args[0].kind_of?(Array) + @radius_data = args.shift + + super(*args) # create canvas widget + else + parent = args.shift + + @radius_data = args.shift + + if parent.kind_of?(TkCanvas) + @path = parent.path + else + super(parent, *args) # create canvas widget + end + end + + @chart = _create_chart + end + + def _create_chart + p self.class::TkCommandNames[0] if $DEBUG + tk_call_without_enc(self.class::TkCommandNames[0], @path, + array2tk_list(@radius_data)) + end + private :_create_chart + + def plot(series, radius, angle) + tk_call_without_enc(@chart, 'plot', _get_eval_enc_str(series), + radius, angle) + self + end + + def dataconfig(series, key, value=None) + if key.kind_of?(Hash) + tk_call_without_enc(@chart, 'dataconfig', series, *hash_kv(key, true)) + else + tk_call_without_enc(@chart, 'dataconfig', series, + "-#{key}", _get_eval_enc_str(value)) + end + end + end + Polarplot = PolarPlot + + ############################ + class IsometricPlot < TkCanvas + include ChartMethod + + TkCommandNames = ['::Plotchart::createIsometricPlot'.freeze].freeze + + def initialize(*args) # args := ([parent,] xaxis, yaxis, [, step] [, keys]) + # xaxis := Array of [minimum, maximum] + # yaxis := Array of [minimum, maximum] + # step := Float of stepsize | "noaxes" | :noaxes + if args[0].kind_of?(Array) + @xaxis = args.shift + @yaxis = args.shift + + if args[0].kind_of?(Hash) + @stepsize = :noaxes + else + @stepsize = args.shift + end + + super(*args) # create canvas widget + else + parent = args.shift + + @xaxis = args.shift + @yaxis = args.shift + + if args[0].kind_of?(Hash) + @stepsize = :noaxes + else + @stepsize = args.shift + end + + if parent.kind_of?(TkCanvas) + @path = parent.path + else + super(parent, *args) # create canvas widget + end + end + + @chart = _create_chart + end + + def _create_chart + p self.class::TkCommandNames[0] if $DEBUG + tk_call_without_enc(self.class::TkCommandNames[0], @path, + array2tk_list(@xaxis), array2tk_list(@yaxis), + @stepsize) + end + private :_create_chart + + def plot(type, *args) + self.__send__("plot_#{type.to_s.tr('-', '_')}", *args) + end + + def plot_rectangle(*args) # args := x1, y1, x2, y2, color + tk_call_without_enc(@chart, 'plot', 'rectangle', *(args.flatten)) + self + end + + def plot_filled_rectangle(*args) # args := x1, y1, x2, y2, color + tk_call_without_enc(@chart, 'plot', 'filled-rectangle', *(args.flatten)) + self + end + + def plot_circle(*args) # args := xc, yc, radius, color + tk_call_without_enc(@chart, 'plot', 'circle', *(args.flatten)) + self + end + + def plot_filled_circle(*args) # args := xc, yc, radius, color + tk_call_without_enc(@chart, 'plot', 'filled-circle', *(args.flatten)) + self + end + end + Isometricplot = IsometricPlot + + ############################ + class Plot3D < TkCanvas + include ChartMethod + + TkCommandNames = ['::Plotchart::create3DPlot'.freeze].freeze + + def initialize(*args) # args := ([parent,] xaxis, yaxis, zaxis [, keys]) + # xaxis := Array of [minimum, maximum, stepsize] + # yaxis := Array of [minimum, maximum, stepsize] + # zaxis := Array of [minimum, maximum, stepsize] + if args[0].kind_of?(Array) + @xaxis = args.shift + @yaxis = args.shift + @zaxis = args.shift + + super(*args) # create canvas widget + else + parent = args.shift + + @xaxis = args.shift + @yaxis = args.shift + @zaxis = args.shift + + if parent.kind_of?(TkCanvas) + @path = parent.path + else + super(parent, *args) # create canvas widget + end + end + + @chart = _create_chart + end + + def _create_chart + p self.class::TkCommandNames[0] if $DEBUG + tk_call_without_enc(self.class::TkCommandNames[0], @path, + array2tk_list(@xaxis), + array2tk_list(@yaxis), + array2tk_list(@zaxis)) + end + private :_create_chart + + def plot_function(cmd=Proc.new) + Tk.ip_eval("proc #{@path}_#{@chart} {x y} {#{install_cmd(cmd)} $x $y}") + tk_call_without_enc(@chart, 'plotfunc', "#{@path}_#{@chart}") + self + end + + def grid_size(nxcells, nycells) + tk_call_without_enc(@chart, 'gridsize', nxcells, nycells) + self + end + + def plot_data(dat) + # dat has to be provided as a 2 level array. + # 1st level contains rows, drawn in y-direction, + # and each row is an array whose elements are drawn in x-direction, + # for the columns. + tk_call_without_enc(@chart, 'plotdata', dat) + self + end + + def colour(fill, border) + # configure the colours to use for polygon borders and inner area + tk_call_without_enc(@chart, 'colour', fill, border) + self + end + alias colours colour + alias colors colour + alias color colour + end + + ############################ + class Piechart < TkCanvas + include ChartMethod + + TkCommandNames = ['::Plotchart::createPiechart'.freeze].freeze + + def initialize(*args) # args := ([parent] [, keys]) + if args[0].kind_of?(TkCanvas) + parent = args.shift + @path = parent.path + else + super(*args) # create canvas widget + end + @chart = _create_chart + end + + def _create_chart + p self.class::TkCommandNames[0] if $DEBUG + tk_call_without_enc(self.class::TkCommandNames[0], @path) + end + private :_create_chart + + def plot(*dat) # argument is a list of [label, value] + tk_call_without_enc(@chart, 'plot', dat.flatten) + self + end + end + + ############################ + class Barchart < TkCanvas + include ChartMethod + + TkCommandNames = ['::Plotchart::createBarchart'.freeze].freeze + + def initialize(*args) + # args := ([parent,] xlabels, ylabels [, series] [, keys]) + # xlabels, ylabels := labels | axis ( depend on normal or horizontal ) + # labels := Array of [label, label, ...] + # (It determines the number of bars that will be plotted per series.) + # axis := Array of [minimum, maximum, stepsize] + # series := Integer number of data series | 'stacked' | :stacked + if args[0].kind_of?(Array) + @xlabels = args.shift + @ylabels = args.shift + + if args[0].kind_of?(Hash) + @series_size = :stacked + else + @series_size = args.shift + end + + super(*args) # create canvas widget + else + parent = args.shift + + @xlabels = args.shift + @ylabels = args.shift + + if args[0].kind_of?(Hash) + @series_size = :stacked + else + @series_size = args.shift + end + + if parent.kind_of?(TkCanvas) + @path = parent.path + else + super(parent, *args) # create canvas widget + end + end + + @chart = _create_chart + end + + def _create_chart + p self.class::TkCommandNames[0] if $DEBUG + tk_call_without_enc(self.class::TkCommandNames[0], @path, + array2tk_list(@xlabels), array2tk_list(@ylabels), + @series_size) + end + private :_create_chart + + def plot(series, dat, col=None) + tk_call_without_enc(@chart, 'plot', series, dat, col) + self + end + + def colours(*cols) + # set the colours to be used + tk_call_without_enc(@chart, 'colours', *cols) + self + end + alias colour colours + alias colors colours + alias color colours + end + + ############################ + class HorizontalBarchart < Barchart + TkCommandNames = ['::Plotchart::createHorizontalBarchart'.freeze].freeze + end + + ############################ + class Timechart < TkCanvas + include ChartMethod + + TkCommandNames = ['::Plotchart::createTimechart'.freeze].freeze + + def initialize(*args) + # args := ([parent,] time_begin, time_end, items [, keys]) + # time_begin := String of time format (e.g. "1 january 2004") + # time_end := String of time format (e.g. "1 january 2004") + # items := Expected/maximum number of items + # ( This determines the vertical spacing. ) + if args[0].kind_of?(Array) + @time_begin = args.shift + @time_end = args.shift + @items = args.shift + + super(*args) # create canvas widget + else + parent = args.shift + + @time_begin = args.shift + @time_end = args.shift + @items = args.shift + + if parent.kind_of?(TkCanvas) + @path = parent.path + else + super(parent, *args) # create canvas widget + end + end + + @chart = _create_chart + end + + def _create_chart + p self.class::TkCommandNames[0] if $DEBUG + tk_call_without_enc(self.class::TkCommandNames[0], @path, + @time_begin, @time_end, @items) + end + private :_create_chart + + def period(txt, time_begin, time_end, col=None) + tk_call_without_enc(@chart, 'period', txt, time_begin, time_end, col) + self + end + + def milestone(txt, time, col=None) + tk_call_without_enc(@chart, 'milestone', txt, time, col) + self + end + + def vertline(txt, time) + tk_call_without_enc(@chart, 'vertline', txt, time) + self + end + end + + ############################ + class PlotSeries < TkObject + SeriesID_TBL = TkCore::INTERP.create_table + Series_ID = ['series'.freeze, '00000'.taint].freeze + TkCore::INTERP.init_ip_env{ SeriesID_TBL.clear } + + def self.id2obj(chart, id) + path = chart.path + return id unless SeriesID_TBL[path] + SeriesID_TBL[path][id]? SeriesID_TBL[path][id]: id + end + + def initialize(chart, keys=nil) + @parent = @chart_obj = chart + @ppath = @chart_obj.path + @path = @series = @id = Series_ID.join(TkCore::INTERP._ip_id_) + SeriesID_TBL[@id] = self + SeriesID_TBL[@ppath] = {} unless SeriesID_TBL[@ppath] + SeriesID_TBL[@ppath][@id] = self + Series_ID[1].succ! + dataconfig(keys) if keys.kind_of?(Hash) + end + + def plot(*args) + @chart_obj.plot(@series, *args) + end + + def dataconfig(key, value=None) + @chart_obj.dataconfig(@series, key, value) + end + end +end diff --git a/ext/tk/lib/tkextlib/tcllib/setup.rb b/ext/tk/lib/tkextlib/tcllib/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ext/tk/lib/tkextlib/tcllib/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ext/tk/lib/tkextlib/tcllib/style.rb b/ext/tk/lib/tkextlib/tcllib/style.rb new file mode 100644 index 0000000000..e441cd83b0 --- /dev/null +++ b/ext/tk/lib/tkextlib/tcllib/style.rb @@ -0,0 +1,30 @@ +# +# tkextlib/tcllib/style.rb +# by Hidetoshi NAGAI ([email protected]) +# +# * Part of tcllib extension +# * select and use some 'style' of option (resource) DB +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('style', '0.1') +TkPackage.require('style') + +module Tk + module Style + def self.names + tk_split_simplelist(tk_call('style::names')) + end + + def self.use(style) + tk_call('style::use', style) + end + end +end diff --git a/ext/tk/lib/tkextlib/tcllib/tkpiechart.rb b/ext/tk/lib/tkextlib/tcllib/tkpiechart.rb new file mode 100644 index 0000000000..1ef49ef4f4 --- /dev/null +++ b/ext/tk/lib/tkextlib/tcllib/tkpiechart.rb @@ -0,0 +1,284 @@ +# +# tkextlib/tcllib/tkpiechart.rb +# by Hidetoshi NAGAI ([email protected]) +# +# * Part of tcllib extension +# * Create 2D or 3D pies with labels in Tcl canvases +# + +require 'tk' +require 'tk/canvas' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('tkpiechart', '6.6') +TkPackage.require('tkpiechart') + +module Tk + module Tcllib + module Tkpiechart + end + end +end + +module Tk::Tcllib::Tkpiechart + module ConfigMethod + include TkConfigMethod + + def __pathname + self.path + ';' + self.tag + end + private :__pathname + + def __cget_cmd + ['::switched::cget', self.tag] + end + + def __config_cmd + ['::switched::configure', self.tag] + end + private :__config_cmd + + def __configinfo_struct + {:key=>0, :alias=>nil, :db_name=>nil, :db_class=>nil, + :default_value=>1, :current_value=>2} + end + private :__configinfo_struct + end + + #################################### + class PieChartObj < TkcItem + include ConfigMethod + + def __font_optkeys + ['titlefont'] + end + private :__font_optkeys + end + + #################################### + class Pie < TkcItem + include ConfigMethod + + def create_self(x, y, width, height, keys=None) + if keys and keys != None + @tag_key = tk_call_without_enc('::stooop::new', 'pie', + @c, x, y, *hash_kv(keys, true)) + else + @tag_key = tk_call_without_enc('::stooop::new', 'pie', @c, x, y) + end + + @slice_tbl = {} + + id = "pie(#{@tag_key})" + + @tag = @tag_pie = TkcNamedTag(@c, id) + @tag_slices = TkcNamedTag(@c, "pieSlices(#{@tag_key})") + + id + end + private :create_self + + def tag_key + @tag_key + end + def tag + @tag + end + def canvas + @c + end + def _entry_slice(slice) + @slice_tbl[slice.to_eval] = slice + end + def _delete_slice(slice) + @slice_tbl.delete(slice.to_eval) + end + + def delete + tk_call_without_enc('::stooop::delete', @tag_key) + CItemID_TBL[@path].delete(@id) if CItemID_TBL[@path] + self + end + + def new_slice(text=None) + Slice.new(self, text) + end + + def delete_slice(slice) + unless slice.kind_of?(Slice) + unless (slice = @slice_tbl[slice]) + return tk_call_without_enc('pie::deleteSlice', @tag_key, slice) + end + end + unless slice.kind_of?(Slice) && slice.pie == self + fail ArgumentError, "argument is not a slice of self" + end + slice.delete + end + + def selected_slices + tk_split_simplelist(tk_call_without_enc('pie::selectedSlices', + @tag_key)).collect{|slice| + @slice_tbl[slice] || Slice.new(:no_create, self, slice) + } + end + end + + #################################### + class Slice < TkcItem + include ConfigMethod + + def __config_cmd + ['::switched::configure', self.tag] + end + private :__config_cmd + + #------------------------ + + def initialize(pie, *args) + unless pie.kind_of?(Pie) && pie != :no_create + fail ArgumentError, "expects TkPiechart::Pie for 1st argument" + end + + if pie == :no_create + @pie, @tag_key = args + else + text = args[0] || None + @pie = pie + @tag_key = tk_call_without_enc('pie::newSlice', @pie.tag_key, text) + end + @parent = @c = @pie.canvas + @path = @parent.path + + @pie._entry_slice(self) + + @id = "slices(#{@tag_key})" + @tag = TkcNamedTag.new(@pie.canvas, @id) + + CItemID_TBL[@path] = {} unless CItemID_TBL[@path] + CItemID_TBL[@path][@id] = self + end + + def tag_key + @tag_key + end + def tag + @tag + end + def pie + @pie + end + + def delete + tk_call_without_enc('pie::deleteSlice', @pie.tag_key, @tag_key) + CItemID_TBL[@path].delete(@id) if CItemID_TBL[@path] + @pie._delete_slice(self) + self + end + + def size(share, disp=None) + tk_call_without_enc('pie::sizeSlice', + @pie.tag_key, @tag_key, share, disp) + self + end + + def label(text) + tk_call_without_enc('pie::labelSlice', @pie.tag_key, @tag_key, text) + self + end + end + + #################################### + class BoxLabeler < TkcItem + include ConfigMethod + + def __config_cmd + ['::switched::configure', self.tag] + end + private :__config_cmd + + #------------------------ + + def create_self(keys=None) + if keys and keys != None + @tag_key = tk_call_without_enc('::stooop::new', 'pieBoxLabeler', + *hash_kv(keys, true)) + else + @tag_key = tk_call_without_enc('::stooop::new', 'pieBoxLabeler') + end + + id = "pieBoxLabeler(#{@tag_key})" + @tag = TkcNamedTag(@c, id) + + id + end + private :create_self + end + + #################################### + class PeripheralLabeler < TkcItem + include ConfigMethod + + def __font_optkeys + ['font', 'smallfont'] + end + private :__font_optkeys + + def __config_cmd + ['::switched::configure', self.tag] + end + private :__config_cmd + + #------------------------ + + def create_self(keys=None) + if keys and keys != None + @tag_key = tk_call_without_enc('::stooop::new', + 'piePeripheralLabeler', + *hash_kv(keys, true)) + else + @tag_key = tk_call_without_enc('::stooop::new', 'piePeripheralLabeler') + end + + id = "piePeripheralLabeler(#{@tag_key})" + @tag = TkcNamedTag(@c, id) + + id + end + private :create_self + end + + #################################### + class Label < TkcItem + include ConfigMethod + + def __config_cmd + ['::switched::configure', self.tag] + end + private :__config_cmd + + #------------------------ + + def create_self(x, y, keys=None) + if keys and keys != None + @tag_key = tk_call_without_enc('::stooop::new', 'canvasLabel', + @c, x, y, width, height, + *hash_kv(keys, true)) + else + @tag_key = tk_call_without_enc('::stooop::new', 'canvasLabel', + @c, x, y, width, height) + end + + id = "canvasLabel(#{@tag_key})" + @tag = TkcNamedTag(@c, id) + + id + end + private :create_self + end +end diff --git a/ext/tk/lib/tkextlib/tile.rb b/ext/tk/lib/tkextlib/tile.rb new file mode 100644 index 0000000000..866cdf0644 --- /dev/null +++ b/ext/tk/lib/tkextlib/tile.rb @@ -0,0 +1,73 @@ +# +# Tile theme engin (tile widget set) support +# by Hidetoshi NAGAI ([email protected]) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# library directory +dir = File.expand_path(__FILE__).sub(/#{File.extname(__FILE__)}$/, '') + +# call setup script +require File.join(dir, 'setup.rb') + +# load package +# TkPackage.require('tile', '0.4') +TkPackage.require('tile') + +# autoload +module Tk + module Tile + module TileWidget + def instate(state, script=nil, &b) + if script + tk_send('instate', state, script) + elsif b + tk_send('instate', state, Proc.new(&b)) + else + bool(tk_send('instate', state)) + end + end + + def state(state=nil) + if state + tk_send('state', state) + else + list(tk_send('state')) + end + end + end + + + # library directory + dir = File.expand_path(__FILE__).sub(/#{File.extname(__FILE__)}$/, '') + + #autoload :TButton, 'tkextlib/tile/tbutton' + autoload :TButton, File.join(dir, 'tbutton') + + #autoload :TCheckButton, 'tkextlib/tile/tcheckbutton' + #autoload :TCheckbutton, 'tkextlib/tile/tcheckbutton' + autoload :TCheckButton, File.join(dir, 'tcheckbutton') + autoload :TCheckbutton, File.join(dir, 'tcheckbutton') + + #autoload :TLabel, 'tkextlib/tile/tlabel' + autoload :TLabel, File.join(dir, 'tlabel') + + #autoload :TMenubutton, 'tkextlib/tile/tmenubutton' + autoload :TMenubutton, File.join(dir, 'tmenubutton') + + #autoload :TNotebook, 'tkextlib/tile/tnotebook' + autoload :TNotebook, File.join(dir, 'tnotebook') + + #autoload :TRadioButton, 'tkextlib/tile/tradiobutton' + #autoload :TRadiobutton, 'tkextlib/tile/tradiobutton' + autoload :TRadioButton, File.join(dir, 'tradiobutton') + autoload :TRadiobutton, File.join(dir, 'tradiobutton') + + #autoload :Style, 'tkextlib/tile/style' + autoload :Style, File.join(dir, 'style') + end +end diff --git a/ext/tk/lib/tkextlib/tile/setup.rb b/ext/tk/lib/tkextlib/tile/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ext/tk/lib/tkextlib/tile/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ext/tk/lib/tkextlib/tile/style.rb b/ext/tk/lib/tkextlib/tile/style.rb new file mode 100644 index 0000000000..be4b45ab73 --- /dev/null +++ b/ext/tk/lib/tkextlib/tile/style.rb @@ -0,0 +1,67 @@ +# +# style commands +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script -- <libdir>/tkextlib/tile.rb +require(File.dirname(File.expand_path(__FILE__)) + '.rb') + +module Tk::Tile::Style +end + +class << Tk::Tile::Style + def default(style, keys=nil) + if keys && keys != None + tk_call('style', 'default', style, *hash_kv(keys)) + else + tk_call('style', 'default', style) + end + end + + def map(style, keys=nil) + if keys && keys != None + tk_call('style', 'map', style, *hash_kv(keys)) + else + tk_call('style', 'map', style) + end + end + + def layout(style, spec=nil) + if spec + tk_call('style', 'layout', style, spec) + else + tk_call('style', 'layout', style) + end + end + + def element_create(name, type, *args) + tk_call('style', 'element', 'create', name, type, *args) + end + + def element_names() + list(tk_call('style', 'element', 'names')) + end + + def theme_create(name, keys=nil) + if keys && keys != None + tk_call('style', 'theme', 'create', name, type, *hash_kv(keys)) + else + tk_call('style', 'theme', 'create', name, type) + end + end + + def theme_settings(name, cmd=nil, &b) + end + + def theme_names() + list(tk_call('style', 'theme', 'names')) + end + + def theme_use(name) + tk_call('style', 'use', name) + end +end diff --git a/ext/tk/lib/tkextlib/tile/tbutton.rb b/ext/tk/lib/tkextlib/tile/tbutton.rb new file mode 100644 index 0000000000..c73b7904ed --- /dev/null +++ b/ext/tk/lib/tkextlib/tile/tbutton.rb @@ -0,0 +1,28 @@ +# +# tbutton widget +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script -- <libdir>/tkextlib/tile.rb +require(File.dirname(File.expand_path(__FILE__)) + '.rb') + +class Tk::Tile::TButton < TkButton + include Tk::Tile::TileWidget + + TkCommandNames = ['tbutton'.freeze].freeze + WidgetClassName = 'TButton'.freeze + WidgetClassNames[WidgetClassName] = self + + def create_self(keys) + if keys and keys != None + tk_call_without_enc('tbutton', @path, *hash_kv(keys, true)) + else + tk_call_without_enc('tbutton', @path) + end + end + private :create_self +end diff --git a/ext/tk/lib/tkextlib/tile/tcheckbutton.rb b/ext/tk/lib/tkextlib/tile/tcheckbutton.rb new file mode 100644 index 0000000000..f5ab008820 --- /dev/null +++ b/ext/tk/lib/tkextlib/tile/tcheckbutton.rb @@ -0,0 +1,33 @@ +# +# tcheckbutton widget +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script -- <libdir>/tkextlib/tile.rb +require(File.dirname(File.expand_path(__FILE__)) + '.rb') + +class Tk::Tile::TCheckButton < TkCheckButton + include Tk::Tile::TileWidget + + TkCommandNames = ['tcheckbutton'.freeze].freeze + WidgetClassName = 'TCheckbutton'.freeze + WidgetClassNames[WidgetClassName] = self + + def create_self(keys) + if keys and keys != None + tk_call_without_enc('tcheckbutton', @path, *hash_kv(keys, true)) + else + tk_call_without_enc('tcheckbutton', @path) + end + end + private :create_self +end +module Tk + module Tile + TCheckbutton = TCheckButton + end +end diff --git a/ext/tk/lib/tkextlib/tile/tlabel.rb b/ext/tk/lib/tkextlib/tile/tlabel.rb new file mode 100644 index 0000000000..1b7302cab1 --- /dev/null +++ b/ext/tk/lib/tkextlib/tile/tlabel.rb @@ -0,0 +1,28 @@ +# +# tlabel widget +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script -- <libdir>/tkextlib/tile.rb +require(File.dirname(File.expand_path(__FILE__)) + '.rb') + +class Tk::Tile::TLabel < TkLabel + include Tk::Tile::TileWidget + + TkCommandNames = ['tlabel'.freeze].freeze + WidgetClassName = 'TLabel'.freeze + WidgetClassNames[WidgetClassName] = self + + def create_self(keys) + if keys and keys != None + tk_call_without_enc('tlabel', @path, *hash_kv(keys, true)) + else + tk_call_without_enc('tlabel', @path) + end + end + private :create_self +end diff --git a/ext/tk/lib/tkextlib/tile/tmenubutton.rb b/ext/tk/lib/tkextlib/tile/tmenubutton.rb new file mode 100644 index 0000000000..c827629c7d --- /dev/null +++ b/ext/tk/lib/tkextlib/tile/tmenubutton.rb @@ -0,0 +1,28 @@ +# +# tmenubutton widget +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script -- <libdir>/tkextlib/tile.rb +require(File.dirname(File.expand_path(__FILE__)) + '.rb') + +class Tk::Tile::TMenubutton < TkMenubutton + include Tk::Tile::TileWidget + + TkCommandNames = ['tmenubutton'.freeze].freeze + WidgetClassName = 'TMenubutton'.freeze + WidgetClassNames[WidgetClassName] = self + + def create_self(keys) + if keys and keys != None + tk_call_without_enc('tmenubutton', @path, *hash_kv(keys, true)) + else + tk_call_without_enc('tmenubutton', @path) + end + end + private :create_self +end diff --git a/ext/tk/lib/tkextlib/tile/tnotebook.rb b/ext/tk/lib/tkextlib/tile/tnotebook.rb new file mode 100644 index 0000000000..40242b5235 --- /dev/null +++ b/ext/tk/lib/tkextlib/tile/tnotebook.rb @@ -0,0 +1,90 @@ +# +# tnotebook widget +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script -- <libdir>/tkextlib/tile.rb +require(File.dirname(File.expand_path(__FILE__)) + '.rb') + +class Tk::Tile::TNotebook < TkWindow + ################################ + include TkItemConfigMethod + + def __item_cget_cmd(id) + [self.path, 'tabcget', id] + end + private :__item_cget_cmd + + def __item_config_cmd(id) + [self.path, 'tabconfigure', id] + end + private :__item_config_cmd + + + def __item_listval_optkeys + [] + end + private :__item_listval_optkeys + + def __item_methodcall_optkeys # { key=>method, ... } + {} + end + private :__item_listval_optkeys + + alias tabcget itemcget + alias tabconfigure itemconfigure + alias tabconfiginfo itemconfiginfo + alias current_tabconfiginfo current_itemconfiginfo + ################################ + + include Tk::Tile::TileWidget + + TkCommandNames = ['tnotebook'.freeze].freeze + WidgetClassName = 'TNotebook'.freeze + WidgetClassNames[WidgetClassName] = self + + def create_self(keys) + if keys and keys != None + tk_call_without_enc('tnotebook', @path, *hash_kv(keys, true)) + else + tk_call_without_enc('tnotebook', @path) + end + end + private :create_self + + def enable_traversal() + tk_call_without_end('tile::enableNotebookTraversal', @path) + self + end + + def add(child, keys=nil) + if keys && keys != None + tk_send_without_enc('add', _epath(child), *hash_kv(keys)) + else + tk_send_without_enc('add', _epath(child)) + end + self + end + + def forget(idx) + tk_send('forget', idx) + self + end + + def index(idx) + number(tk_send('index', idx)) + end + + def select(idx) + tk_send('select', idx) + self + end + + def tabs + list(tk_send('tabs')) + end +end diff --git a/ext/tk/lib/tkextlib/tile/tradiobutton.rb b/ext/tk/lib/tkextlib/tile/tradiobutton.rb new file mode 100644 index 0000000000..2587a74cf3 --- /dev/null +++ b/ext/tk/lib/tkextlib/tile/tradiobutton.rb @@ -0,0 +1,33 @@ +# +# tradiobutton widget +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script -- <libdir>/tkextlib/tile.rb +require(File.dirname(File.expand_path(__FILE__)) + '.rb') + +class Tk::Tile::TRadioButton < TkRadioButton + include Tk::Tile::TileWidget + + TkCommandNames = ['tradiobutton'.freeze].freeze + WidgetClassName = 'TRadiobutton'.freeze + WidgetClassNames[WidgetClassName] = self + + def create_self(keys) + if keys and keys != None + tk_call_without_enc('tradiobutton', @path, *hash_kv(keys, true)) + else + tk_call_without_enc('tradiobutton', @path) + end + end + private :create_self +end +module Tk + module Tile + TRadiobutton = TRadioButton + end +end diff --git a/ext/tk/lib/tkextlib/tkDND.rb b/ext/tk/lib/tkextlib/tkDND.rb new file mode 100644 index 0000000000..ba5b23b538 --- /dev/null +++ b/ext/tk/lib/tkextlib/tkDND.rb @@ -0,0 +1,25 @@ +# +# TkDND (Tk Drag & Drop Extension) support +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# library directory +dir = File.expand_path(__FILE__).sub(/#{File.extname(__FILE__)}$/, '') + +# call setup script +require File.join(dir, 'setup.rb') + +module Tk + module TkDND + dir = File.expand_path(__FILE__).sub(/#{File.extname(__FILE__)}$/, '') + + #autoload :DND 'tkextlib/tkDND/tkdnd' + #autoload :Shape 'tkextlib/tkDND/shape' + autoload :DND File.join(dir, 'tkdnd') + autoload :Shape File.join(dir, 'shape') + end +end diff --git a/ext/tk/lib/tkextlib/tkDND/setup.rb b/ext/tk/lib/tkextlib/tkDND/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ext/tk/lib/tkextlib/tkDND/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ext/tk/lib/tkextlib/tkDND/shape.rb b/ext/tk/lib/tkextlib/tkDND/shape.rb new file mode 100644 index 0000000000..3e4a94f526 --- /dev/null +++ b/ext/tk/lib/tkextlib/tkDND/shape.rb @@ -0,0 +1,96 @@ +# +# tkextlib/tkDND/shape.rb +# by Hidetoshi NAGAI ([email protected]) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('shape', '0.3') +TkPackage.require('shape') + +module Tk + module TkDND + module Shape + def self.version + tk_call('shape', 'version') + end + + ############################ + + def shape_bounds(kind=nil) + if kind + ret = tk_call('shape', 'bounds', @path, "-#{kind}") + else + ret = tk_call('shape', 'bounds', @path) + end + if ret == "" + nil + else + list(ret) + end + end + + def shape_get(kind=nil) + if kind + list(tk_call('shape', 'get', @path, "-#{kind}")) + else + list(tk_call('shape', 'get', @path)) + end + end + + def shape_offset(x, y, kind=nil) + if kind + tk_call('shape', 'get', @path, "-#{kind}", x, y) + else + tk_call('shape', 'get', @path, x, y) + end + self + end + + def _parse_shapespec_param(args) + cmd = [] + + kind_keys = ['bounding', 'clip', 'both'] + offset_keys = ['offset'] + srckind_keys = ['bitmap', 'rectangles', 'reset', 'test', 'window'] + + cmd << "-#{args.shift}" if kind_keys.member?(args[0].to_s) + + if offset_keys.member?(args[0].to_s) + cmd << "-#{args.shift}" + cmd << args.shift # xOffset + cmd << args.shift # yOffset + end + + if srckind_keys.member?(args[0].to_s) + cmd << "-#{args.shift}" + end + + cmd.concat(args) + + cmd + end + private :_parse_shapespec_param + + def shape_set(*args) # ?kind? ?offset <x> <y>? srckind ?arg ...? + tk_call('shape', 'set', @path, *(_parse_shapespec_param(args))) + self + end + + def shape_update(op, *args) # ?kind? ?offset <x> <y>? srckind ?arg ...? + tk_call('shape', 'update', @path, op, *(_parse_shapespec_param(args))) + self + end + end + end +end + +class TkWindow + include Tk::TkDND::Shape +end diff --git a/ext/tk/lib/tkextlib/tkDND/tkdnd.rb b/ext/tk/lib/tkextlib/tkDND/tkdnd.rb new file mode 100644 index 0000000000..036d1998bd --- /dev/null +++ b/ext/tk/lib/tkextlib/tkDND/tkdnd.rb @@ -0,0 +1,108 @@ +# +# tkextlib/tkDND/tkdnd.rb +# by Hidetoshi NAGAI ([email protected]) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +TkPackage.require('tkdnd') + +module Tk + module TkDND + class DND_Subst < TkUtil::CallbackSubst + KEY_TBL = [ + [ ?a, ?l, :actions ], + [ ?A, ?s, :action ], + [ ?b, ?L, :codes ], + [ ?c, ?s, :code ], + [ ?d, ?l, :descriptions ], + [ ?D, ?l, :data ], + [ ?L, ?l, :source_types ], + [ ?m, ?l, :modifiers ], + [ ?t, ?l, :types ], + [ ?T, ?s, :type ], + [ ?W, ?w, :widget ], + [ ?x, ?n, :x ], + [ ?X, ?n, :x_root ], + [ ?y, ?n, :y ], + [ ?Y, ?n, :y_root ], + nil + ] + + PROC_TBL = [ + [ ?n, TkComm.method(:num_or_str) ], + [ ?s, TkComm.method(:string) ], + [ ?l, TkComm.method(:list) ], + [ ?L, TkComm.method(:simplelist) ], + [ ?w, TkComm.method(:window) ], + nil + ] + + # setup tables + _setup_subst_table(KEY_TBL, PROC_TBL); + end + + module DND + def dnd_bindtarget_info(type=nil, event=nil) + if event + procedure(tk_call('dnd', 'bindtarget', @path, type, event)) + elsif type + procedure(tk_call('dnd', 'bindtarget', @path, type)) + else + simplelist(tk_call('dnd', 'bindtarget', @path)) + end + end + + def dnd_bindtarget(type, event, cmd=Proc.new, prior=50, *args) + event = tk_event_sequence(event) + if prior.kind_of?(Numeric) + tk_call('dnd', 'bindtarget', @path, type, event, + install_bind_for_event_class(DND_Subst, cmd, *args), + prior) + else + tk_call('dnd', 'bindtarget', @path, type, event, + install_bind_for_event_class(DND_Subst, cmd, prior, *args)) + end + self + end + + def dnd_cleartarget + tk_call('dnd', 'cleartarget', @path) + self + end + + def dnd_bindsource_info(type=nil) + if type + procedure(tk_call('dnd', 'bindsource', @path, type)) + else + simplelist(tk_call('dnd', 'bindsource', @path)) + end + end + + def dnd_bindsource(type, cmd=Proc.new, prior=None) + tk_call('dnd', 'bindsource', @path, type, cmd, prior) + self + end + + def dnd_clearsource() + tk_call('dnd', 'clearsource', @path) + self + end + + def dnd_drag(keys=nil) + tk_call('dnd', 'drag', @path, *hash_kv(keys)) + self + end + end + end +end + +class TkWindow + include Tk::TkDND::DND +end diff --git a/ext/tk/lib/tkextlib/tkHTML.rb b/ext/tk/lib/tkextlib/tkHTML.rb new file mode 100644 index 0000000000..f32aed99f1 --- /dev/null +++ b/ext/tk/lib/tkextlib/tkHTML.rb @@ -0,0 +1,16 @@ +# +# TkHtml support +# by Hidetoshi NAGAI ([email protected]) +# + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# library directory +dir = File.expand_path(__FILE__).sub(/#{File.extname(__FILE__)}$/, '') + +# call setup script +require File.join(dir, 'setup.rb') + +# load library +require File.join(dir, 'htmlwidget') diff --git a/ext/tk/lib/tkextlib/tkHTML/htmlwidget.rb b/ext/tk/lib/tkextlib/tkHTML/htmlwidget.rb new file mode 100644 index 0000000000..5c0657025a --- /dev/null +++ b/ext/tk/lib/tkextlib/tkHTML/htmlwidget.rb @@ -0,0 +1,427 @@ +# +# tkextlib/tkHTML/htmlwidget.rb +# by Hidetoshi NAGAI ([email protected]) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('Tkhtml', '2.0') +TkPackage.require('Tkhtml') + +module Tk + class HTML_Widget < TkWindow + class ClippingWindow < TkWindow + end + end +end + +class Tk::HTML_Widget::ClippingWindow + extend TkUtil + + WidgetClassName = 'HtmlClip'.freeze + WidgetClassNames[WidgetClassName] = self + + HtmlClip_TBL = TkCore::INTERP.create_table + TkCore::INTERP.init_ip_env{ HtmlClip_TBL.clear } + + def self.new(parent, keys={}) + if parent.kind_of?(Hash) + keys = _symbolkey2str(parent) + parent = keys.delete('parent') + end + + if parent.kind_of?(String) + ppath = parent.path + elsif parent + ppath = parent + else + ppath = '' + end + return HtmlClip_TBL[ppath] if HtmlClip_TBL[ppath] + + widgetname = keys.delete('widgetname') + if widgetname =~ /^(.*)\.[^.]+$/ + ppath2 = $1 + if ppath2[0] != ?. + ppath2 = ppath + '.' + ppath2 + end + return HtmlClip_TBL[ppath2] if HtmlClip_TBL[ppath2] + + ppath = ppath2 + end + + parent = TkComm._genobj_for_tkwidget(ppath) + unless parent.kind_of?(Tk::HTML_Widget) + fail ArgumentError, "parent must be a Tk::HTML_Widget instance" + end + + super(parent) + end + + def initialize(parent) + @parent = parent + @ppath = parent.path + @path = @id = @ppath + '.x' + HtmlClip_TBL[@ppath] = self + end + + def method_missing(m, *args, &b) + @parent.__send__(m, *args, &b) + end +end + +class Tk::HTML_Widget + include Scrollable + + TkCommandNames = ['html'.freeze].freeze + WidgetClassName = 'Html'.freeze + WidgetClassNames[WidgetClassName] = self + + def create_self(keys) + if keys and keys != None + tk_call_without_enc('html', @path, *hash_kv(keys, true)) + else + tk_call_without_enc('html', @path) + end + end + private :create_self + + ################################### + # class methods + ################################### + def self.reformat(src, dst, txt) + tk_call('html', 'reformat', src, dst, txt) + end + + def self.url_join(*args) # args := sheme authority path query fragment + tk_call('html', 'urljoin', *args) + end + + def self.url_split(uri) + tk_call('html', 'urlsplit', uri) + end + + def self.lockcopy(src, dst) + tk_call('html', 'lockcopy', src, dst) + end + + def self.gzip_file(file, dat) + tk_call('html', 'gzip', 'file', file, dat) + end + + def self.gunzip_file(file, dat) + tk_call('html', 'gunzip', 'file', filet) + end + + def self.gzip_data(dat) + tk_call('html', 'gzip', 'data', file, dat) + end + + def self.gunzip_data(dat) + tk_call('html', 'gunzip', 'data', filet) + end + + def self.base64_encode(dat) + tk_call('html', 'base64', 'encode', dat) + end + + def self.base64_decode(dat) + tk_call('html', 'base64', 'encode', dat) + end + + def self.text_format(dat, len) + tk_call('html', 'text', 'format', dat, len) + end + + def self.xor(cmd, *args) + tk_call('html', 'xor', cmd, *args) + end + + def self.stdchan(cmd, channel) + tk_call('html', 'stdchan', cmd, channel) + end + + def self.crc32(data) + tk_call('html', 'crc32', data) + end + + ################################### + # instance methods + ################################### + def clipping_window + ClippingWindow.new(self) + end + alias clipwin clipping_window + alias htmlclip clipping_window + + def bgimage(image, tid=None) + tk_send('bgimage', image, tid) + self + end + + def clear() + tk_send('clear') + self + end + + def coords(index=None, percent=None) + tk_send('coords', index, percent) + end + + def forminfo(*args) + tk_send('forminfo', *args) + end + alias form_info forminfo + + def href(x, y) + simplelist(tk_send('href', x, y)) + end + + def image_add(id, img) + tk_send('imageadd', id, img) + self + end + + def image_at(x, y) + tk_send('imageat', x, y) + end + + def images() + list(tk_send('images')) + end + + def image_set(id, num) + tk_send('imageset', id, num) + self + end + + def image_update(id, imgs) + tk_send('imageupdate', id, imgs) + self + end + + def index(idx, count=None, unit=None) + tk_send('index', idx, count, unit) + end + + def insert_cursor(idx) + tk_send('insert', idx) + end + + def names() + simple_list(tk_send('names')) + end + + def on_screen(id, x, y) + bool(tk_send('onscreen', id, x, y)) + end + + def over(x, y) + list(tk_send('over', x, y)) + end + + def over_markup(x, y) + list(tk_send('over', x, y, '-muponly')) + end + + def over_attr(x, y, attrs) + list(tk_send('overattr', x, y, attrs)) + end + + def parse(txt) + tk_send('parse', txt) + self + end + + def resolver(*uri_args) + tk_send('resolver', *uri_args) + end + + def selection_clear() + tk_send('selection', 'clear') + self + end + + def selection_set(first, last) + tk_send('selection', 'set', first, last) + self + end + + def refresh(*opts) + tk_send('refresh', *opts) + end + + def layout() + tk_send('layout') + end + + def sizewindow(*args) + tk_send('sizewindow', *args) + end + + def postscript(*args) + tk_send('postscript', *args) + end + + def source() + tk_send('source') + end + + def plain_text(first, last) + tk_send('text', 'ascii', first, last) + end + alias ascii_text plain_text + alias text_ascii plain_text + + def text_delete(first, last) + tk_send('text', 'delete', first, last) + self + end + + def html_text(first, last) + tk_send('text', 'html', first, last) + end + alias text_html html_text + + def text_insert(idx, txt) + tk_send('text', 'insert', idx, txt) + self + end + + def break_text(idx) + tk_send('text', 'break', idx) + end + alias text_break break_text + + def text_find(txt, *args) + tk_send('text', 'find', txt, *args) + end + + def text_table(idx, imgs=None, attrs=None) + tk_send('text', 'table', idx, imgs, attrs) + end + + def token_append(tag, *args) + tk_send('token', 'append', tag, *args) + self + end + + def token_delete(first, last=None) + tk_send('token', 'delete', first, last) + self + end + + def token_define(*args) + tk_send('token', 'defile', *args) + self + end + + def token_find(tag, *args) + list(tk_send('token', 'find', tag, *args)) + end + + def token_get(first, last=None) + list(tk_send('token', 'get', first, last)) + end + + def token_list(first, last=None) + list(tk_send('token', 'list', first, last)) + end + + def token_markup(first, last=None) + list(tk_send('token', 'markup', first, last)) + end + + def token_DOM(first, last=None) + list(tk_send('token', 'domtokens', first, last)) + end + alias token_dom token_DOM + alias token_domtokens token_DOM + alias token_dom_tokens token_DOM + + def token_get_end(idx) + tk_send('token', 'getend', idx) + end + alias token_getend token_get_end + + def token_offset(start, num1, num2) + list(tk_send('token', 'offset', start, num1, num2)) + end + + def token_get_attr(idx, name=None) + list(tk_send('token', 'attr', idx, name)) + end + + def token_set_attr(idx, name=None, val=None) + tk_send('token', 'attr', idx, name, val) + self + end + + def token_handler(tag, cmd=nil, &b) + cmd = Proc.new(&b) if !cmd && b + if cmd + tk_send('token', 'handler', tag, cmd) + return self + else + return tk_send('token', 'handler', tag) + end + end + + def token_insert(idx, tag, *args) + tk_send('token', 'insert', idx, tag, *args) + self + end + + def token_attrs(*args) + list(tk_send('token', 'attrs', *args)) + end + + def token_unique(*args) + list(tk_send('token', 'unique', *args)) + end + + def token_on_events(*args) + list(tk_send('token', 'onEvents', *args)) + end + + def dom_nameidx(tag, name) + number(tk_send('dom', 'nameidx', tag, name)) + end + alias dom_name_index dom_nameidx + + def dom_radioidx(tag, name) + number(tk_send('dom', 'radioidx', tag, name)) + end + alias dom_radio_index dom_radioidx + + def dom_id(*spec) + tk_send('dom', 'id', *spec) + end + + def dom_ids(*spec) + list(tk_send('dom', 'ids', *spec)) + end + + def dom_value(*spec) + list(tk_send('dom', 'value', *spec)) + end + + def dom_attr(idx) + tk_send('dom', 'attr', idx) + end + + def dom_formel(name) + tk_send('dom', 'formel', name) + end + alias dom_form_element dom_formel + + def dom_tree(idx, val) + list(tk_send('dom', 'tree', idx, val)) + end +end diff --git a/ext/tk/lib/tkextlib/tkHTML/setup.rb b/ext/tk/lib/tkextlib/tkHTML/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ext/tk/lib/tkextlib/tkHTML/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ext/tk/lib/tkextlib/tkimg.rb b/ext/tk/lib/tkextlib/tkimg.rb new file mode 100644 index 0000000000..06184589b4 --- /dev/null +++ b/ext/tk/lib/tkextlib/tkimg.rb @@ -0,0 +1,23 @@ +# +# TkImg extension support +# by Hidetoshi NAGAI ([email protected]) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# library directory +dir = File.expand_path(__FILE__).sub(/#{File.extname(__FILE__)}$/, '') + +# call setup script +require File.join(dir, 'setup.rb') + +# load all image format handlers +#TkPackage.require('Img', '1.3') +TkPackage.require('Img') + +# autoload +#autoload :TkPixmapImage, 'tkextlib/tkimg/pixmap' +autoload :TkPixmapImage, File.join(dir, 'pixmap') diff --git a/ext/tk/lib/tkextlib/tkimg/README b/ext/tk/lib/tkextlib/tkimg/README new file mode 100644 index 0000000000..65d36365d0 --- /dev/null +++ b/ext/tk/lib/tkextlib/tkimg/README @@ -0,0 +1,26 @@ + + [ Tcl/Tk Image formats (TkImg) support ] + +TkImg contains a collection of format handlers for the Tk photo +image type, and a new image type, pixmaps. + +Supported formats of TkImg version 1.3 are +------------------------------------------------------- + bmp : Windows Bitmap Format + gif : Graphics Interchange Format + ico : Windows Icon Format + jpeg : Joint Picture Expert Group format + pcx : Paintbrush Format + pixmap : Pixmap Image type + png : Portable Network Graphics format + ppm : Portable Pixmap format + ps : Adobe PostScript Format + sgi : SGI Native Format + sun : Sun Raster Format + tga : Truevision Targa Format + tiff : Tagged Image File Format + window : Tk Windows + xbm : X Window Bitmap Format + xpm : X Window Pixmap Format +------------------------------------------------------- + diff --git a/ext/tk/lib/tkextlib/tkimg/bmp.rb b/ext/tk/lib/tkextlib/tkimg/bmp.rb new file mode 100644 index 0000000000..5bef0c7168 --- /dev/null +++ b/ext/tk/lib/tkextlib/tkimg/bmp.rb @@ -0,0 +1,14 @@ +# +# TkImg - format 'bmp' +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +#TkPackage.require('img::bmp', '1.3') +TkPackage.require('img::bmp') diff --git a/ext/tk/lib/tkextlib/tkimg/gif.rb b/ext/tk/lib/tkextlib/tkimg/gif.rb new file mode 100644 index 0000000000..65c3b88a50 --- /dev/null +++ b/ext/tk/lib/tkextlib/tkimg/gif.rb @@ -0,0 +1,14 @@ +# +# TkImg - format 'gif' +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('img::gif', '1.3') +TkPackage.require('img::gif') diff --git a/ext/tk/lib/tkextlib/tkimg/ico.rb b/ext/tk/lib/tkextlib/tkimg/ico.rb new file mode 100644 index 0000000000..43646ec8da --- /dev/null +++ b/ext/tk/lib/tkextlib/tkimg/ico.rb @@ -0,0 +1,14 @@ +# +# TkImg - format 'ico' +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('img::ico', '1.3') +TkPackage.require('img::ico') diff --git a/ext/tk/lib/tkextlib/tkimg/jpeg.rb b/ext/tk/lib/tkextlib/tkimg/jpeg.rb new file mode 100644 index 0000000000..7b4df8c050 --- /dev/null +++ b/ext/tk/lib/tkextlib/tkimg/jpeg.rb @@ -0,0 +1,14 @@ +# +# TkImg - format 'jpeg' +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('img::jpeg', '1.3') +TkPackage.require('img::jpeg') diff --git a/ext/tk/lib/tkextlib/tkimg/pcx.rb b/ext/tk/lib/tkextlib/tkimg/pcx.rb new file mode 100644 index 0000000000..4486ba2449 --- /dev/null +++ b/ext/tk/lib/tkextlib/tkimg/pcx.rb @@ -0,0 +1,14 @@ +# +# TkImg - format 'pcx' +# by Hidetoshi NAGAI ([email protected])# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('img::pcx', '1.3') +TkPackage.require('img::pcx') diff --git a/ext/tk/lib/tkextlib/tkimg/pixmap.rb b/ext/tk/lib/tkextlib/tkimg/pixmap.rb new file mode 100644 index 0000000000..0c18c71408 --- /dev/null +++ b/ext/tk/lib/tkextlib/tkimg/pixmap.rb @@ -0,0 +1,21 @@ +# +# TkImg - format 'pixmap' +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('img::pixmap', '1.3') +TkPackage.require('img::pixmap') + +class TkPixmapImage<TkImage + def initialize(*args) + @type = 'pixmap' + super + end +end diff --git a/ext/tk/lib/tkextlib/tkimg/png.rb b/ext/tk/lib/tkextlib/tkimg/png.rb new file mode 100644 index 0000000000..275035f47e --- /dev/null +++ b/ext/tk/lib/tkextlib/tkimg/png.rb @@ -0,0 +1,14 @@ +# +# TkImg - format 'png' +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('img::png', '1.3') +TkPackage.require('img::png') diff --git a/ext/tk/lib/tkextlib/tkimg/ppm.rb b/ext/tk/lib/tkextlib/tkimg/ppm.rb new file mode 100644 index 0000000000..730978b281 --- /dev/null +++ b/ext/tk/lib/tkextlib/tkimg/ppm.rb @@ -0,0 +1,14 @@ +# +# TkImg - format 'ppm' +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('img::ppm', '1.3') +TkPackage.require('img::ppm') diff --git a/ext/tk/lib/tkextlib/tkimg/ps.rb b/ext/tk/lib/tkextlib/tkimg/ps.rb new file mode 100644 index 0000000000..edfb8dd783 --- /dev/null +++ b/ext/tk/lib/tkextlib/tkimg/ps.rb @@ -0,0 +1,14 @@ +# +# TkImg - format 'ps' +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('img::ps', '1.3') +TkPackage.require('img::ps') diff --git a/ext/tk/lib/tkextlib/tkimg/setup.rb b/ext/tk/lib/tkextlib/tkimg/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ext/tk/lib/tkextlib/tkimg/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ext/tk/lib/tkextlib/tkimg/sgi.rb b/ext/tk/lib/tkextlib/tkimg/sgi.rb new file mode 100644 index 0000000000..9dcfa614b0 --- /dev/null +++ b/ext/tk/lib/tkextlib/tkimg/sgi.rb @@ -0,0 +1,14 @@ +# +# TkImg - format 'sgi' +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('img::sgi', '1.3') +TkPackage.require('img::sgi') diff --git a/ext/tk/lib/tkextlib/tkimg/sun.rb b/ext/tk/lib/tkextlib/tkimg/sun.rb new file mode 100644 index 0000000000..4ada9c7ff1 --- /dev/null +++ b/ext/tk/lib/tkextlib/tkimg/sun.rb @@ -0,0 +1,14 @@ +# +# TkImg - format 'sun' +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('img::sun', '1.3') +TkPackage.require('img::sun') diff --git a/ext/tk/lib/tkextlib/tkimg/tga.rb b/ext/tk/lib/tkextlib/tkimg/tga.rb new file mode 100644 index 0000000000..221ebe5db1 --- /dev/null +++ b/ext/tk/lib/tkextlib/tkimg/tga.rb @@ -0,0 +1,14 @@ +# +# TkImg - format 'tga' +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('img::tga', '1.3') +TkPackage.require('img::tga') diff --git a/ext/tk/lib/tkextlib/tkimg/tiff.rb b/ext/tk/lib/tkextlib/tkimg/tiff.rb new file mode 100644 index 0000000000..1c7e940843 --- /dev/null +++ b/ext/tk/lib/tkextlib/tkimg/tiff.rb @@ -0,0 +1,14 @@ +# +# TkImg - format 'tiff' +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('img::tiff', '1.3') +TkPackage.require('img::tiff') diff --git a/ext/tk/lib/tkextlib/tkimg/window.rb b/ext/tk/lib/tkextlib/tkimg/window.rb new file mode 100644 index 0000000000..056aa8f3cf --- /dev/null +++ b/ext/tk/lib/tkextlib/tkimg/window.rb @@ -0,0 +1,14 @@ +# +# TkImg - format 'window' +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('img::window', '1.3') +TkPackage.require('img::window') diff --git a/ext/tk/lib/tkextlib/tkimg/xbm.rb b/ext/tk/lib/tkextlib/tkimg/xbm.rb new file mode 100644 index 0000000000..80010c77de --- /dev/null +++ b/ext/tk/lib/tkextlib/tkimg/xbm.rb @@ -0,0 +1,14 @@ +# +# TkImg - format 'xbm' +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('img::xbm', '1.3') +TkPackage.require('img::xbm') diff --git a/ext/tk/lib/tkextlib/tkimg/xpm.rb b/ext/tk/lib/tkextlib/tkimg/xpm.rb new file mode 100644 index 0000000000..04d56287ef --- /dev/null +++ b/ext/tk/lib/tkextlib/tkimg/xpm.rb @@ -0,0 +1,14 @@ +# +# TkImg - format 'xpm' +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('img::xpm', '1.3') +TkPackage.require('img::xpm') diff --git a/ext/tk/lib/tkextlib/tktrans.rb b/ext/tk/lib/tkextlib/tktrans.rb new file mode 100644 index 0000000000..93bb338a9b --- /dev/null +++ b/ext/tk/lib/tkextlib/tktrans.rb @@ -0,0 +1,17 @@ +# +# TkTrans support (win32 only) +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# library directory +dir = File.expand_path(__FILE__).sub(/#{File.extname(__FILE__)}$/, '') + +# call setup script +require File.join(dir, 'setup.rb') + +# load library +require File.join(dir, 'tktrans') diff --git a/ext/tk/lib/tkextlib/tktrans/setup.rb b/ext/tk/lib/tkextlib/tktrans/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ext/tk/lib/tkextlib/tktrans/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ext/tk/lib/tkextlib/tktrans/tktrans.rb b/ext/tk/lib/tkextlib/tktrans/tktrans.rb new file mode 100644 index 0000000000..fa5d7a2eae --- /dev/null +++ b/ext/tk/lib/tkextlib/tktrans/tktrans.rb @@ -0,0 +1,53 @@ +# +# TkTrans support (win32 only) +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +TkPackage.require('tktrans') rescue Tk.load_tcllibrary('tktrans') + +class TkWindow + begin + TkTrans_VERSION = TkPackage.require('tktrans') + rescue + TkTrans_VERSION = nil + end + + def tktrans_set_image(img) + tk_send('tktrans::setwidget', @path, img) + self + end + def tktrans_get_image() + tk_send('tktrans::setwidget', @path) + end +end + +class TkRoot + undef tktrans_set_image, tktrans_get_image + + def tktrans_set_image(img) + tk_send('tktrans::settoplevel', @path, img) + self + end + def tktrans_get_image() + tk_send('tktrans::settoplevel', @path) + end +end + +class TkToplevel + undef tktrans_set_image, tktrans_get_image + + def tktrans_set_image(img) + tk_send('tktrans::settoplevel', @path, img) + self + end + def tktrans_get_image() + tk_send('tktrans::settoplevel', @path) + end +end diff --git a/ext/tk/lib/tkextlib/treectrl.rb b/ext/tk/lib/tkextlib/treectrl.rb new file mode 100644 index 0000000000..fb03283a8d --- /dev/null +++ b/ext/tk/lib/tkextlib/treectrl.rb @@ -0,0 +1,16 @@ +# +# TkTreeCtrl support +# by Hidetoshi NAGAI ([email protected]) +# + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# library directory +dir = File.expand_path(__FILE__).sub(/#{File.extname(__FILE__)}$/, '') + +# call setup script +require File.join(dir, 'setup.rb') + +# load library +require File.join(dir, 'tktreectrl') diff --git a/ext/tk/lib/tkextlib/treectrl/setup.rb b/ext/tk/lib/tkextlib/treectrl/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ext/tk/lib/tkextlib/treectrl/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb b/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb new file mode 100644 index 0000000000..fb74b72c3b --- /dev/null +++ b/ext/tk/lib/tkextlib/treectrl/tktreectrl.rb @@ -0,0 +1,887 @@ +# +# tkextlib/treectrl/tktreectrl.rb +# by Hidetoshi NAGAI ([email protected]) +# + +require 'tk' + +# call setup script +require File.join(File.dirname(File.expand_path(__FILE__)), 'setup.rb') + +# TkPackage.require('treectrl', '1.0') +#TkPackage.require('treectrl') + +module Tk + class TreeCtrl_Widget < TkWindow + #VERSION = TkPackage.require('treectrl', '1.0') + VERSION = TkPackage.require('treectrl') + + class NotifyEvent < TkUtil::CallbackSubst + end + + module ConfigMethod + end + end +end + +############################################## + +class Tk::TreeCtrl_Widget::NotifyEvent + # [ <'%' subst-key char>, <proc type char>, <instance var (accessor) name>] + KEY_TBL = [ + [ ?c, ?n, :item_num ], + [ ?d, ?s, :detail ], + [ ?D, ?l, :items ], + [ ?e, ?e, :event ], + [ ?I, ?n, :id ], + [ ?l, ?b, :lower_bound ], + [ ?p, ?n, :active_id ], + [ ?S, ?l, :sel_items ], + [ ?T, ?w, :widget ], + [ ?U, ?b, :upper_bound ], + [ ?W, ?o, :object ], + nil + ] + + # [ <proc type char>, <proc/method to convert tcl-str to ruby-obj>] + PROC_TBL = [ + [ ?n, TkComm.method(:num_or_str) ], + [ ?s, TkComm.method(:string) ], + [ ?l, TkComm.method(:list) ], + [ ?w, TkComm.method(:window) ], + + [ ?b, proc{|val| list(val)} ], + + [ ?e, proc{|val| + case val + when /^<<[^<>]+>>$/ + TkVirtualEvent.getobj(val[1..-2]) + when /^<[^<>]+>$/ + val[1..-2] + else + val + end + } + ], + + [ ?o, proc{|val| tk_tcl2ruby(val)} ], + + nil + ] + + # setup tables to be used by scan_args, _get_subst_key, _get_all_subst_keys + # + # _get_subst_key() and _get_all_subst_keys() generates key-string + # which describe how to convert callback arguments to ruby objects. + # When binding parameters are given, use _get_subst_key(). + # But when no parameters are given, use _get_all_subst_keys() to + # create a Event class object as a callback parameter. + # + # scan_args() is used when doing callback. It convert arguments + # ( which are Tcl strings ) to ruby objects based on the key string + # that is generated by _get_subst_key() or _get_all_subst_keys(). + # + _setup_subst_table(KEY_TBL, PROC_TBL); +end + +############################################## + +module Tk::TreeCtrl_Widget::ConfigMethod + include TkItemConfigMethod + + def treectrl_tagid(key, obj) + if key.kind_of?(Array) + key = key.join(' ') + else + key = key.to_s + end + + case key + when 'column' + obj + + when 'dragimage' + obj + + when 'element' + obj + + when 'item element' + obj + + when 'marquee' + obj + + when 'notify' + obj + + when 'style' + obj + + else + obj + end + end + + def tagid(mixed_id) + if mixed_id.kind_of?(Array) + [mixed_id[0], treectrl_tagid(*mixed_id)] + else + tagid(mixed_id.split(':')) + end + fail ArgumentError, "unknown id format" + end + + def __item_cget_cmd(mixed_id) + if mixed_id[1].kind_of?(Array) + id = mixed_id[1] + else + id = [mixed_id[1]] + end + + if mixed_id[0].kind_of?(Array) + ([self.path].concat(mixed_id[0]) << 'cget').concat(id) + else + [self.path, mixed_id[0], 'cget'].concat(id) + end + end + private :__item_cget_cmd + + def __item_config_cmd(mixed_id) + if mixed_id[1].kind_of?(Array) + id = mixed_id[1] + else + id = [mixed_id[1]] + end + + if mixed_id[0].kind_of?(Array) + ([self.path].concat(mixed_id[0]) << 'configure').concat(id) + else + [self.path, mixed_id[0], 'configure'].concat(id) + end + end + private :__item_config_cmd + + def __item_pathname(id) + if id.kind_of?(Array) + key = id[0] + if key.kind_of?(Array) + key = key.join(' ') + end + + tag = id[1] + if tag.kind_of?(Array) + tag = tag.join(' ') + end + + id = [key, tag].join(':') + end + [self.path, id].join(';') + end + private :__item_pathname + + def __item_configinfo_struct(id) + if id.kind_of?(Array) && id[0].to_s == 'notify' + {:key=>0, :alias=>nil, :db_name=>nil, :db_class=>nil, + :default_value=>nil, :current_value=>1} + else + {:key=>0, :alias=>1, :db_name=>1, :db_class=>2, + :default_value=>3, :current_value=>4} + end + end + private :__item_configinfo_struct + + def __item_listval_optkeys(id) + [] + end + private :__item_listval_optkeys + + def __item_keyonly_optkeys(id) # { def_key=>(undef_key|nil), ... } + { + 'notreally'=>nil, + 'increasing'=>'decreasing', + 'decreasing'=>'increasing', + 'ascii'=>nil, + 'dictionary'=>nil, + 'integer'=>nil, + 'real'=>nil + } + end + private :__item_keyonly_optkeys + + def column_cget(tagOrId, option) + itemcget(['column', tagOrId], option) + end + def column_configure(tagOrId, slot, value=None) + itemconfigure(['column', tagOrId], slot, value) + end + def column_configinfo(tagOrId, slot=nil) + itemconfigure(['column', tagOrId], slot) + end + def current_column_configinfo(tagOrId, slot=nil) + itemconfigure(['column', tagOrId], slot) + end + + def dragimage_cget(tagOrId, option) + itemcget(['dragimage', tagOrId], option) + end + def dragimage_configure(tagOrId, slot, value=None) + itemconfigure(['dragimage', tagOrId], slot, value) + end + def dragimage_configinfo(tagOrId, slot=nil) + itemconfigure(['dragimage', tagOrId], slot) + end + def current_dragimage_configinfo(tagOrId, slot=nil) + itemconfigure(['dragimage', tagOrId], slot) + end + + def element_cget(tagOrId, option) + itemcget(['element', tagOrId], option) + end + def element_configure(tagOrId, slot, value=None) + itemconfigure(['element', tagOrId], slot, value) + end + def element_configinfo(tagOrId, slot=nil) + itemconfigure(['element', tagOrId], slot) + end + def current_element_configinfo(tagOrId, slot=nil) + itemconfigure(['element', tagOrId], slot) + end + + def item_element_cget(tagOrId, option) + itemcget([['item', 'element'], tagOrId], option) + end + def item_element_configure(tagOrId, slot, value=None) + itemconfigure([['item', 'element'], tagOrId], slot, value) + end + def item_element_configinfo(tagOrId, slot=nil) + itemconfigure([['item', 'element'], tagOrId], slot) + end + def current_item_element_configinfo(tagOrId, slot=nil) + itemconfigure([['item', 'element'], tagOrId], slot) + end + + def marquee_cget(tagOrId, option) + itemcget(['marquee', tagOrId], option) + end + def marquee_configure(tagOrId, slot, value=None) + itemconfigure(['marquee', tagOrId], slot, value) + end + def marquee_configinfo(tagOrId, slot=nil) + itemconfigure(['marquee', tagOrId], slot) + end + def current_marquee_configinfo(tagOrId, slot=nil) + itemconfigure(['marquee', tagOrId], slot) + end + + def notify_cget(win, pattern, option) + itemconfigure(['notify', [win, pattern]], option) + end + def notify_configure(win, pattern, slot, value=None) + itemconfigure(['notify', [win, pattern]], slot, value) + end + def notify_configinfo(win, pattern, slot=nil) + itemconfigure(['notify', [win, pattern]], slot) + end + alias current_notify_configinfo notify_configinfo + + def style_cget(tagOrId, option) + itemcget(['style', tagOrId], option) + end + def style_configure(tagOrId, slot, value=None) + itemconfigure(['style', tagOrId], slot, value) + end + def style_configinfo(tagOrId, slot=nil) + itemconfigure(['style', tagOrId], slot) + end + def current_style_configinfo(tagOrId, slot=nil) + itemconfigure(['style', tagOrId], slot) + end + + private :itemcget, :itemconfigure + private :itemconfiginfo, :current_itemconfiginfo +end + +############################################## + +class Tk::TreeCtrl_Widget + include Tk::TreeCtrl_Widget::ConfigMethod + include Scrollable + + TkCommandNames = ['treectrl'.freeze].freeze + WidgetClassName = ''.freeze + WidgetClassNames[WidgetClassName] = self + + def create_self(keys) + if keys and keys != None + tk_call_without_enc('treectrl', @path, *hash_kv(keys, true)) + else + tk_call_without_enc('treectrl', @path) + end + end + private :create_self + + ######################### + + def activate(desc) + tk_send('activate', desc) + self + end + + def canvasx(x) + number(tk_send('canvasx', x)) + end + + def canvasy(y) + number(tk_send('canvasy', y)) + end + + def collapse(*dsc) + tk_send('collapse', *dsc) + self + end + + def collapse_recurse(*dsc) + tk_send('collapse', '-recurse', *dsc) + self + end + + def column_bbox(idx) + list(tk_send('column', 'bbox', idx)) + end + + def column_delete(idx) + tk_send('column', 'delete', idx) + self + end + + def column_index(idx) + num_or_str(tk_send('column', 'index', idx)) + end + + def column_move(idx, to) + tk_send('column', 'move', idx, to) + self + end + + def column_needed_width(idx) + num_or_str(tk_send('column', 'neededwidth', idx)) + end + alias column_neededwidth column_needed_width + + def column_width(idx) + num_or_str(tk_send('column', 'width', idx)) + end + + def compare(item1, op, item2) + number(tk_send('compare', item1, op, item2)) + end + + def contentbox() + list(tk_send('contentbox')) + end + + def depth(item=None) + num_or_str(tk_send('depth', item)) + end + + def dragimage_add(item, *args) + tk_send('dragimage', 'add', item, *args) + self + end + + def dragimage_clear() + tk_send('dragimage', 'clear') + self + end + + def dragimage_offset(*args) # x, y + if args.empty? + list(tk_send('dragimage', 'offset')) + else + tk_send('dragimage', 'offset', *args) + self + end + end + + def dragimage_visible(*args) # mode + if args..empty? + bool(tk_send('dragimage', 'visible')) + else + tk_send('dragimage', 'visible', *args) + self + end + end + def dragimage_visible? + dragimage_visible() + end + + def element_create(elem, type, keys=nil) + if keys && keys.kind_of?(Hash) + tk_send('element', 'create', elem, type, *hash_kv(keys)) + else + tk_send('element', 'create', elem, type) + end + end + + def element_delete(*elems) + tk_send('element', 'delete', *elems) + self + end + + def element_names() + list(tk_send('element', 'names')) + end + + def element_type(elem) + tk_send('element', 'type', elem) + end + + def expand(*dsc) + tk_send('expand', *dsc) + self + end + + def expand_recurse(*dsc) + tk_send('expand', '-recurse', *dsc) + self + end + + def identify(x, y) + list(tk_send('identify', x, y)) + end + + def index(idx) + num_or_str(tk_send('index', idx)) + end + + def item_ancestors(item) + list(tk_send('item', 'ancestors', item)) + end + + def item_bbox(item, *args) + list(tk_send('item', 'bbox', item, *args)) + end + + def item_children(item) + list(tk_send('item', 'children', item)) + end + + def item_complex(item, *args) + tk_send('item', 'complex', item, *args) + self + end + + def item_create() + num_or_str(tk_send('item', 'create')) + end + + def item_delete(first, last=None) + tk_send('item', 'delete', first, last) + self + end + + def item_dump(item) + list(tk_send('item', 'dump', item)) + end + + def item_element_actual(item, column, elem, key) + tk_send('item', 'element', 'actual', item, column, elem, "-#{key}") + end + + def item_firstchild(parent, child=nil) + if child + tk_send('item', 'firstchild', parent, child) + self + else + num_or_str(tk_send('item', 'firstchild', parent)) + end + end + alias item_first_child item_firstchild + + def item_hashbutton(item, st=None) + if st == None + bool(tk_send('item', 'hashbutton')) + else + tk_send('item', 'hashbutton', st) + self + end + end + def item_hashbutton?(item) + item_hashbutton(item) + end + + def item_index(item) + list(tk_send('item', 'index', item)) + end + + def item_isancestor(item, des) + bool(tk_send('item', 'isancestor', item, des)) + end + alias item_is_ancestor item_isancestor + alias item_isancestor? item_isancestor + alias item_is_ancestor? item_isancestor + + def item_isopen(item) + bool(tk_send('item', 'isopen', item)) + end + alias item_is_open item_isopen + alias item_isopen? item_isopen + alias item_is_open? item_isopen + + def item_lastchild(parent, child=nil) + if child + tk_send('item', 'lastchild', parent, child) + self + else + num_or_str(tk_send('item', 'lastchild', parent)) + end + end + alias item_last_child item_lastchild + + def item_nextsibling(sibling, nxt=nil) + if nxt + tk_send('item', 'nextsibling', sibling, nxt) + self + else + num_or_str(tk_send('item', 'nextsibling', sibling)) + end + end + alias item_next_sibling item_nextsibling + + def item_numchildren() + number(tk_send('item', 'numchildren')) + end + alias item_num_children item_numchildren + alias item_children_size item_numchildren + + def item_parent(item) + num_or_str(tk_send('item', 'parent', item)) + end + + def item_prevsibling(sibling, prev=nil) + if prev + tk_send('item', 'prevsibling', sibling, prev) + self + else + num_or_str(tk_send('item', 'prevsibling', sibling)) + end + end + alias item_prev_sibling item_prevsibling + + def item_remove(item) + list(tk_send('item', 'remove', item)) + end + + def item_rnc(item) + list(tk_send('item', 'rnc', item)) + end + + def item_sort(item, *opts) + flag = false + if opts[-1].kind_of?(Hash) + opts[-1,1] = __conv_item_keyonly_opts(item, opts[-1]).to_a + end + + opts = opts.collect{|opt| + if opt.kind_of?(Array) + key = "-#{opt[0]}" + flag = true if key == '-notreally' + ["-#{opt[0]}", opt[1]] + else + key = "-#{opt}" + flag = true if key == '-notreally' + key + end + }.flatten + + ret = tk_send('item', 'sort', item, *opts) + if flag + list(ret) + else + ret + end + end + + def item_state_get(item, *args) + if args.empty? + list(tk_send('item', 'state', 'get', item *args)) + else + bool(tk_send('item', 'state', 'get', item)) + end + end + + def item_state_set(item, *args) + tk_send('item', 'state', 'set', *args) + self + end + + def item_style_elements(item, colun) + list(tk_send('item', 'style', 'elements', item, column)) + end + + def item_style_map(item, column, style, map) + tk_send('item', 'style', 'map', item, column, style, map) + self + end + + def item_style_set(item, column=nil, *args) + if args.empty? + if column + tk_send('item', 'style', 'set', item, column) + else + list(tk_send('item', 'style', 'set', item)) + end + else + tk_send('item', 'style', 'set', item, *(args.flatten)) + self + end + end + + def item_text(item, column, txt=nil, *args) + if args.empty? + if txt + tk_send('item', 'text', item, column, txt) + self + else + tk_send('item', 'text', item, column) + end + else + tk_send('item', 'text', item, txt, *args) + self + end + end + + def item_visible(item, st=None) + if st == None + bool(tk_send('item', 'visible', item)) + else + tk_send('item', 'visible', item, st) + self + end + end + def item_visible?(item) + item_visible(item) + end + + def marquee_anchor(*args) + if args.empty? + list(tk_send('marquee', 'anchor')) + else + tk_send('marquee', 'anchor', *args) + self + end + end + + def marquee_coords(*args) + if args.empty? + list(tk_send('marquee', 'coords')) + else + tk_send('marquee', 'coords', *args) + self + end + end + + def marquee_corner(*args) + if args.empty? + tk_send('marquee', 'corner') + else + tk_send('marquee', 'corner', *args) + self + end + end + + def marquee_identify() + list(tk_send('marquee', 'identify')) + end + + def marquee_visible(st=None) + if st == None + bool(tk_send('marquee', 'visible')) + else + tk_send('marquee', 'visible', st) + self + end + end + def marquee_visible?() + marquee_visible() + end + + def notify_bind(obj, event, cmd=Proc.new, args=nil) + _bind([@path, 'notify', 'bind', obj], event, cmd, args) + self + end + + def notify_bind_append(obj, event, cmd=Proc.new, args=nil) + _bind([@path, 'notify', 'bind', obj], event, cmd, args) + self + end + + def notify_bindinfo(obj, event=nil) + _bindinfo([@path, 'notify', 'bind', obj], event) + end + + def notify_detailnames(event) + list(tk_send('notify', 'detailnames', event)) + end + + def notify_eventnames() + list(tk_send('notify', 'eventnames')) + end + + def notify_generate(pattern, char_map=None) + tk_send('notify', 'generate', pattern, char_map) + self + end + + def notify_install_detail(event, detail, percents_cmd=nil, &b) + percents_cmd = Proc.new(&b) if !percents_cmd && b + if percents_cmd + tk_send('notify', 'install', 'detail', event, detail, percents_cmd) + else + tk_send('notify', 'install', 'detail', event, detail) + end + end + + def notify_install_event(event, percents_cmd=nil, &b) + percents_cmd = Proc.new(&b) if !percents_cmd && b + if percents_cmd + tk_send('notify', 'install', 'event', event, percents_cmd) + else + tk_send('notify', 'install', 'event', event) + end + end + + def notify_linkage(event, detail=None) + tk_send('notify', 'linkage', event, detail) + end + + def notify_uninstall_detail(event, detail) + tk_send('notify', 'uninstall', 'detail', event, detail) + self + end + + def notify_uninstall_event(event) + tk_send('notify', 'uninstall', 'event', event) + self + end + + def numcolumns() + num_or_str(tk_send('numcolumns')) + end + + def numitems() + num_or_str(tk_send('numitems')) + end + + def orphans() + list(tk_send('orphans')) + end + + def range(first, last) + list(tk_send('range', first, last)) + end + + def state_define(name) + tk_send('state', 'define', name) + self + end + + def state_linkage(name) + tk_send('state', 'linkage', name) + end + + def state_names() + list(tk_send('state', 'names')) + end + + def state_undefine(*names) + tk_send('state', 'undefine', *names) + self + end + + def see(item) + tk_send('see', item) + self + end + + def selection_add(first, last=None) + tk_send('selection', 'add', first, last) + self + end + + def selection_anchor(item=None) + num_or_str(tk_send('selection', 'anchor', item)) + end + + def selection_clear(*args) # first, last + tk_send('selection', 'clear' *args) + self + end + + def selection_count() + number(tk_send('selection', 'count')) + end + + def selection_get() + list(tk_send('selection', 'get')) + end + + def selection_includes(item) + bool(tk_send('selection', 'includes', item)) + end + + def selection_modify(sel, desel) + tk_send('selection', 'modify', sel, desel) + self + end + + def style_create(style, keys=None) + if keys && keys != None + tk_send('style', 'create', style, *hash_kv(keys)) + else + tk_send('style', 'create', style) + end + end + + def style_delete(*args) + tk_send('style', 'delete', *args) + self + end + + def style_elements(style, *elems) + if elems.empty? + list(tk_send('style', 'elements', style)) + else + tk_send('style', 'elements', style, elems.flatten) + self + end + end + + def style_layout(style, elem, keys=None) + if keys && keys != None + if keys.kind_of?(Hash) + tk_send('style', 'layout', style, elem, *hash_kv(keys)) + self + else + tk_send('style', 'layout', style, elem, "-#{keys}") + end + else + list(tk_send('style', 'layout', style, elem)) + end + end + + def style_names() + list(tk_send('style', 'names')) + end + + def toggle(*items) + tk_send('toggle', *items) + self + end + + def toggle_recurse() + tk_send('toggle', '-recurse', *items) + self + end +end diff --git a/ext/tk/lib/tkextlib/vu.rb b/ext/tk/lib/tkextlib/vu.rb new file mode 100644 index 0000000000..923b67ce4e --- /dev/null +++ b/ext/tk/lib/tkextlib/vu.rb @@ -0,0 +1,40 @@ +# +# The vu widget set support +# by Hidetoshi NAGAI ([email protected]) +# + +require 'tk' + +# call setup script for general 'tkextlib' libraries +require 'tkextlib/setup.rb' + +# library directory +dir = File.expand_path(__FILE__).sub(/#{File.extname(__FILE__)}$/, '') + +# call setup script +require File.join(dir, 'setup.rb') + +# load package +# TkPackage.require('vu', '2.1') +#TkPackage.require('vu') + +# autoload +module Tk + module Vu + # load package + # VERSION = TkPackage.require('vu', '2.1') + VERSION = TkPackage.require('vu') + + dir = File.expand_path(__FILE__).sub(/#{File.extname(__FILE__)}$/, '') + + autoload :Dial, File.join(dir, 'dial') + + autoload :Pie, File.join(dir, 'pie') + autoload :PieSlice, File.join(dir, 'pie') + autoload :NamedPieSlice, File.join(dir, 'pie') + + autoload :Spinbox, File.join(dir, 'spinbox') + + autoload :Bargraph, File.join(dir, 'bargraph') + end +end diff --git a/ext/tk/lib/tkextlib/vu/bargraph.rb b/ext/tk/lib/tkextlib/vu/bargraph.rb new file mode 100644 index 0000000000..1dbd49db28 --- /dev/null +++ b/ext/tk/lib/tkextlib/vu/bargraph.rb @@ -0,0 +1,50 @@ +# +# ::vu::bargraph widget +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# create module/class +module Tk + module Vu + class Bargraph < TkWindow + end + end +end + +# call setup script -- <libdir>/tkextlib/vu.rb +require(File.dirname(File.expand_path(__FILE__)) + '.rb') + +class Tk::Vu::Bargraph < TkWindow + TkCommandNames = ['::vu::bargraph'.freeze].freeze + WidgetClassName = 'Bargraph'.freeze + WidgetClassNames[WidgetClassName] = self + + ############################### + + def __boolval_optkeys + ['showminmax', 'showvalue'] + end + private :__boolval_optkeys + + def __listval_optkeys + ['alabels', 'blabels'] + end + private :__listval_optkeys + + def __font_optkeys + ['alabfont', 'blabfont'] + end + private :__font_optkeys + + ############################### + + def set(val = None) + tk_call_without_enc(@path, 'set', val) + self + end + + def get() + num_or_str(tk_call_without_enc(@path, 'get')) + end +end diff --git a/ext/tk/lib/tkextlib/vu/charts.rb b/ext/tk/lib/tkextlib/vu/charts.rb new file mode 100644 index 0000000000..bf2a3075bd --- /dev/null +++ b/ext/tk/lib/tkextlib/vu/charts.rb @@ -0,0 +1,47 @@ +# +# charts -- Create and manipulate canvas Add-On Items +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' +require 'tk/canvas' + +# call setup script -- <libdir>/tkextlib/vu.rb +require(File.dirname(File.expand_path(__FILE__)) + '.rb') + +module Tk + module Vu + module ChartsConfig + include TkItemConfigOptkeys + def __item_boolval_optkeys(id) + super(id) << 'lefttrunc' << 'autocolor' + end + private :__item_boolval_optkeys + + def __item_listval_optkeys(id) + super(id) << 'values' << 'tags' + end + private :__item_listval_optkeys + end + + class TkcSticker < TkcItem + include ChartsConfig + + CItemTypeName = 'sticker'.freeze + CItemTypeToClass[CItemTypeName] = self + end + + class TkcStripchart < TkcItem + include ChartsConfig + + CItemTypeName = 'stripchart'.freeze + CItemTypeToClass[CItemTypeName] = self + end + + class TkcBarchart < TkcItem + include ChartsConfig + + CItemTypeName = 'barchart'.freeze + CItemTypeToClass[CItemTypeName] = self + end + end +end diff --git a/ext/tk/lib/tkextlib/vu/dial.rb b/ext/tk/lib/tkextlib/vu/dial.rb new file mode 100644 index 0000000000..4d5770a320 --- /dev/null +++ b/ext/tk/lib/tkextlib/vu/dial.rb @@ -0,0 +1,102 @@ +# +# ::vu::dial widget +# by Hidetoshi NAGAI ([email protected]) +# +require 'tk' + +# create module/class +module Tk + module Vu + class Dial < TkWindow + end + end +end + +# call setup script -- <libdir>/tkextlib/vu.rb +require(File.dirname(File.expand_path(__FILE__)) + '.rb') + +# define module/class +class Tk::Vu::Dial < TkWindow + TkCommandNames = ['::vu::dial'.freeze].freeze + WidgetClassName = 'Dial'.freeze + WidgetClassNames[WidgetClassName] = self + + ############################### + + def __methodcall_optkeys # { key=>method, ... } + {'coords'=>'coords'} + end + private :__methodcall_optkeys + + ############################### + + def coords(val = nil) + if val + tk_split_list(tk_send_without_enc('coords')) + else + tk_send_without_enc('coords', val) + self + end + end + + def constrain(val = None) + num_or_str(tk_call(@path, 'constrain', val)) + end + + def get(*args) + num_or_str(tk_call(@path, 'get', *args)) + end + + def identify(x, y) + tk_call(@path, 'identify', x, y) + end + + def get_label(val=nil) + if val + tk_call(@path, 'label', val) + else + ret = [] + lst = simplelist(tk_call(@path, 'label')) + while lst.size > 0 + ret << ([num_or_str(lst.shift)] << lst.shift) + end + end + end + + def set_label(val, str, *args) + tk_call(@path, 'label', val, str, *args) + self + end + + def set_label_constrain(val, str, *args) + tk_call(@path, 'label', '-constrain', val, str, *args) + self + end + + def get_tag(val=nil) + if val + tk_call(@path, 'tag', val) + else + ret = [] + lst = simplelist(tk_call(@path, 'tag')) + while lst.size > 0 + ret << ([num_or_str(lst.shift)] << lst.shift) + end + end + end + + def set_tag(val, str, *args) + tk_call(@path, 'tag', val, str, *args) + self + end + + def set_tag_constrain(val, str, *args) + tk_call(@path, 'tag', '-constrain', val, str, *args) + self + end + + def set(val = None) + tk_call_without_enc(@path, 'set', val) + self + end +end diff --git a/ext/tk/lib/tkextlib/vu/pie.rb b/ext/tk/lib/tkextlib/vu/pie.rb new file mode 100644 index 0000000000..833039c9f2 --- /dev/null +++ b/ext/tk/lib/tkextlib/vu/pie.rb @@ -0,0 +1,229 @@ +# +# ::vu::pie widget +# by Hidetoshi NAGAI ([email protected]) +# + +# create module/class +module Tk + module Vu + module PieSliceConfigMethod + end + class Pie < TkWindow + end + class PieSlice < TkObject + end + class NamedPieSlice < PieSlice + end + end +end + +# call setup script -- <libdir>/tkextlib/vu.rb +require(File.dirname(File.expand_path(__FILE__)) + '.rb') + +module Tk::Vu::PieSliceConfigMethod + include TkItemConfigMethod + + def __item_pathname(tagOrId) + if tagOrId.kind_of?(Tk::Vu::PieSlice) + self.path + ';' + tagOrId.id.to_s + else + self.path + ';' + tagOrId.to_s + end + end + private :__item_pathname +end + +class Tk::Vu::Pie < TkWindow + TkCommandNames = ['::vu::pie'.freeze].freeze + WidgetClassName = 'Pie'.freeze + WidgetClassNames[WidgetClassName] = self + + ############################### + + include Tk::Vu::PieSliceConfigMethod + + def tagid(tag) + if tag.kind_of?(Tk::Vu::PieSlice) + tag.id + else + tag + end + end + + ############################### + + def delete(*glob_pats) + tk_call(@path, 'delete', *glob_pats) + self + end + + def explode(slice, *args) + tk_call(@path, 'explode', slice, *args) + self + end + + def explode_value(slice) + num_or_str(tk_call(@path, 'explode', slice)) + end + + def lower(slice, below=None) + tk_call(@path, 'lower', slice, below) + self + end + + def names(*glob_pats) + simplelist(tk_call(@path, 'names', *glob_pats)) + end + alias slices names + + def order(*args) + tk_call(@path, 'order', *args) + self + end + + def raise(slice, above=None) + tk_call(@path, 'raise', slice, above) + self + end + + def swap(slice1, slice2) + tk_call(@path, 'swap', slice1, slice2) + self + end + + def set(slice, *args) + num_or_str(tk_call(@path, 'set', slice, *args)) + end + alias set_value set + alias set_values set + alias create set + + def slice_value(slice) + num_or_str(tk_call(@path, 'set', slice)) + end + + def value(val = None) + num_or_str(tk_call_without_enc(@path, 'value')) + end + alias sum_value value +end + +class Tk::Vu::PieSlice + SliceID_TBL = TkCore::INTERP.create_table + Pie_Slice_ID = ['vu_pie'.freeze, '00000'.taint].freeze + TkCore::INTERP.init_ip_env{ SliceID_TBL.clear } + + def self.id2obj(pie, id) + pie_path = pie.path + return id unless SliceID_TBL[pie_path] + SliceID_TBL[pie_path][id]? SliceID_TBL[pie_path][id]: id + end + + def initialize(parent, *args) + unless parent.kind_of?(Tk::Vu::Pie) + fail ArguemntError, "expect a Tk::Vu::Pie instance for 1st argument" + end + @parent = @pie = parent + @ppath = parent.path + @path = @id = Pie_Slice_ID.join(TkCore::INTERP._ip_id_) + SliceID_TBL[@ppath] = {} unless SliceID_TBL[@ppath] + SliceID_TBL[@ppath][@id] = self + Pie_Slice_ID[1].succ! + + if args[-1].kind_of?(Hash) + keys = args.unshift + end + @pie.set(@id, *args) + configure(keys) + end + + def id + @id + end + + def [](key) + cget key + end + + def []=(key,val) + configure key, val + val + end + + def cget(slot) + @pie.itemcget(@id, slot) + end + + def configure(*args) + @pie.itemconfigure(@id, *args) + self + end + + def configinfo(*args) + @pie.itemconfiginfo(@id, *args) + end + + def current_configinfo(*args) + @pie.current_itemconfiginfo(@id, *args) + end + + def delete + @pie.delete(@id) + end + + def explode(value) + @pie.explode(@id, value) + self + end + + def explode_value + @pie.explode_value(@id) + end + + def lower(other=None) + @pie.lower(@id, other) + self + end + + def raise(other=None) + @pie.raise(@id, other) + self + end + + def set(value) + @pie.set(@id, value) + self + end + alias set_value set + + def value + @pie.set(@id) + end +end + +class Tk::Vu::NamedPieSlice + def self.new(parent, name, *args) + if SliceID_TBL[parent.path] && SliceID_TBL[parent.path][name] + return SliceID_TBL[parent.path][name] + else + super(parent, name, *args) + end + end + + def initialize(parent, name, *args) + unless parent.kind_of?(Tk::Vu::Pie) + fail ArguemntError, "expect a Tk::Vu::Pie instance for 1st argument" + end + @parent = @pie = parent + @ppath = parent.path + @path = @id = name.to_s + SliceID_TBL[@ppath] = {} unless SliceID_TBL[@ppath] + SliceID_TBL[@ppath][@id] = self + + if args[-1].kind_of?(Hash) + keys = args.unshift + end + @pie.set(@id, *args) + configure(keys) + end +end diff --git a/ext/tk/lib/tkextlib/vu/setup.rb b/ext/tk/lib/tkextlib/vu/setup.rb new file mode 100644 index 0000000000..ce0f0bd4d4 --- /dev/null +++ b/ext/tk/lib/tkextlib/vu/setup.rb @@ -0,0 +1,8 @@ +# +# setup.rb -- setup script before calling TkPackage.require() +# +# If you need some setup operations (for example, add a library path +# to the library search path) before using Tcl/Tk library packages +# wrapped by Ruby scripts in this directory, please write the setup +# operations in this file. +# diff --git a/ext/tk/lib/tkextlib/vu/spinbox.rb b/ext/tk/lib/tkextlib/vu/spinbox.rb new file mode 100644 index 0000000000..db2743613c --- /dev/null +++ b/ext/tk/lib/tkextlib/vu/spinbox.rb @@ -0,0 +1,17 @@ +# +# ::vu::spinbox widget +# by Hidetoshi NAGAI ([email protected]) +# +# a standard spinbox (<= 8.3) +# This is the same as the 8.4 core spinbox widget. +# + +if (Tk::TK_MAJOR_VERSION < 8 || + (Tk::TK_MAJOR_VERSION == 8 && Tk::TK_MINOR_VERSION < 4)) + # call setup script -- <libdir>/tkextlib/vu.rb + require(File.dirname(File.expand_path(__FILE__)) + '.rb') + + Tk.tk_call('namespace', 'import', '::vu::spinbox') +end + +Tk::Vu::Spinbox = TkSpinbox |