diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..bed31158b81b150c55fb035eb2328ed3ece708d1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +.config +InstalledFiles +FXRuby.spec +scripts/make-installers.rb +*.iss +*.iss.in +doap.rdf +Makefile +*.tmproj +doc/api +doc/*.html +ext/fox16/*_wrap.cpp +ext/fox16/*.o +ext/fox16/conftest.dSYM +ext/fox16/include/inlinestubs.h +ext/fox16/librb.c +ext/fox16/extconf.rb +ext/fox16/fox16.bundle +ext/fox16/mkmf.log +lib/fox16/version.rb +lib/fox16/kwargs.rb +pre-config.rb +swig-interfaces/dependencies diff --git a/Rakefile b/Rakefile index 34bbe01878d08fdfa1a0c9940b77fbc964727f50..9483fc640ff296ff717bccc1cb0deeb3b3ac0bc5 100755 --- a/Rakefile +++ b/Rakefile @@ -1,13 +1,16 @@ -require 'hoe' +require 'date' +require 'rake/gempackagetask' +require 'rake/rdoctask' +require 'rake/testtask' # FXRuby version number -PKG_VERSION = "1.6.6" +PKG_VERSION = "1.6.18" # Minimum version of FOX required for compatibility FOX_VERSION = "1.6.0" # Path to local installation of FOX (Windows only) -FOX_INSTALL_DIR = "c:\\src\\fox-1.6.20" +FOX_INSTALL_DIR = "e:\\src\\fox-1.6.33" # Path to local installation of FXScintilla (Windows only) FXSCINTILLA_INSTALL_DIR = "c:\\src\\fxscintilla" @@ -15,32 +18,6 @@ FXSCINTILLA_INSTALL_DIR = "c:\\src\\fxscintilla" # Path to local installation of InnoSetup command-line compiler ISCC = "C:\\Progra~1\\InnoSe~1\\ISCC.exe" -# Generate Hoe tasks -=begin -Hoe.new('FXRuby', PKG_VERSION) do |p| - p.url = "http://www.fxruby.org/" - p.author = "Lyle Johnson" - p.email = "lyle@rubyforge.org" - p.changes = "See the change history at http://www.fxruby.org/doc/changes.html" - p.description = "FXRuby is the Ruby binding to the FOX GUI toolkit." - p.summary = "FXRuby is the Ruby binding to the FOX GUI toolkit." - p.clean_globs = %w{config.save InstalledFiles ext/**/*.o ext/**/*.bundle} - p.test_globs = ['tests/**/TC_*.rb'] - p.rdoc_pattern = /^(lib|bin)|txt$/ - p.extra_deps = [] - p.spec_extras = {} - p.need_tar = true - p.need_zip = false - p.spec_extras = { - 'require_paths' => ['ext/fox16', 'lib'], - 'rdoc_options' => ['--main', File.join('rdoc-sources', 'README.rdoc'), '--exclude', 'ext/fox16'], - 'extensions' => ["ext/fox16/extconf.rb"], - 'extra_rdoc_files' => ['rdoc-sources', File.join('rdoc-sources', 'README.rdoc')], - 'test_suite_file' => "tests/TS_All.rb" - } -end -=end - DISTFILES = [ "ANNOUNCE", "LICENSE", @@ -49,10 +26,7 @@ DISTFILES = [ "pre-config.rb", "install.rb", "doap.rdf", - "FXRuby-ruby1.6-i586-mswin32.iss", - "FXRuby-ruby1.8.2-i386-msvcrt.iss", - "FXRuby-ruby1.8.4-i386-msvcrt.iss", - "FXRuby-ruby1.8.5-i386-msvcrt.iss", + "FXRuby-ruby1.8.6-i386-msvcrt.iss", "Rakefile", "index.html", "doc/*.css", @@ -77,10 +51,6 @@ DISTFILES = [ "tests/README", "tests/*.rb", "tests/*.ps", - "web/*.html", - "web/*.css", - "web/art/*.png", - "web/art/*.gif", "rdoc-sources/*.rb", "rdoc-sources/README.rdoc", "scripts/make-installers.rb" @@ -90,7 +60,7 @@ def distdir "FXRuby-#{PKG_VERSION}" end -task :distdir => [:swig, :docs, :setversions] do +task :distdir => [:swig, :docs, :setversions, :generate_kwargs_lib] do rm_rf "#{distdir}" mkdir "#{distdir}" chmod(0777, distdir) @@ -111,6 +81,7 @@ task :distdir => [:swig, :docs, :setversions] do rm_f "#{distdir}/examples/rapt-gui.rb" rm_f "#{distdir}/examples/WhatAQuietStiff.rb" rm_f "#{distdir}/examples/gembrowser.rb" + rm_f "#{distdir}/examples/rmagick.rb" rm_f "#{distdir}/examples/tablenew.rb" end @@ -141,9 +112,12 @@ task :website => [:doap] do system %{scp -Cq doc/*.html lyle@rubyforge.org:/var/www/gforge-projects/fxruby/1.6/doc} system %{scp -Cq doc/images/*.png lyle@rubyforge.org:/var/www/gforge-projects/fxruby/1.6/doc/images} system %{scp -Cq examples/*.rb lyle@rubyforge.org:/var/www/gforge-projects/fxruby/1.6/examples} - system %{scp -Cq index.html lyle@rubyforge.org:/var/www/gforge-projects/fxruby} - system %{scp -Cq web/*.html lyle@rubyforge.org:/var/www/gforge-projects/fxruby/web} - system %{scp -Cq web/art/*.gif web/art/*.png lyle@rubyforge.org:/var/www/gforge-projects/fxruby/web/art} + system %{scp -Cq web/index.html lyle@rubyforge.org:/var/www/gforge-projects/fxruby} + system %{scp -Cq web/community.html lyle@rubyforge.org:/var/www/gforge-projects/fxruby} + system %{scp -Cq web/documentation.html lyle@rubyforge.org:/var/www/gforge-projects/fxruby} + system %{scp -Cq web/downloads.html lyle@rubyforge.org:/var/www/gforge-projects/fxruby} + system %{scp -Cq web/images/* lyle@rubyforge.org:/var/www/gforge-projects/fxruby/images} + system %{scp -Cq web/css/*.css lyle@rubyforge.org:/var/www/gforge-projects/fxruby/css} end desc "Upload the DOAP file to the Web site" @@ -153,7 +127,40 @@ end desc "Upload the RDocs" task :upload_rdoc do - system %{scp -Cqr doc/api lyle@rubyforge.org:/var/www/gforge-projects/fxruby/1.6/doc} +# system %{scp -Cqr doc/api lyle@rubyforge.org:/var/www/gforge-projects/fxruby/1.6/doc} + host = "lyle@rubyforge.org" + remote_dir = "/var/www/gforge-projects/fxruby/doc/api" + local_dir = 'doc/api' + sh %{rsync -av --delete #{local_dir}/ #{host}:#{remote_dir}} +end + +desc "Upload release files to RubyForge" +task :rubyforge do + require 'rubyforge' + rubyforge = RubyForge.new + rubyforge.login + if PLATFORM =~ /mswin32/ + rubyforge.userconfig['processor_id'] = 'i386' + rubyforge.add_file "fxruby", "FXRuby 1.6", PKG_VERSION, "fxruby-#{PKG_VERSION}-mswin32.gem" + rubyforge.add_file "fxruby", "FXRuby 1.6", PKG_VERSION, "FXRuby-#{PKG_VERSION}-ruby186.exe" + else + rubyforge.add_release "fxruby", "FXRuby 1.6", PKG_VERSION, "FXRuby-#{PKG_VERSION}.tar.gz" + rubyforge.add_file "fxruby", "FXRuby 1.6", PKG_VERSION, "fxruby-#{PKG_VERSION}.gem" + end +# rubyforge add_release fxruby "FXRuby 1.6" "1.6.9" FXRuby-1.6.9.tar.gz +# rubyforge add_file fxruby "FXRuby 1.6" "1.6.9" fxruby-1.6.9.gem +# rubyforge add_file -o i386 fxruby "FXRuby 1.6" "1.6.9" fxruby-1.6.9-mswin32.gem +# rubyforge add_file -o i386 fxruby "FXRuby 1.6" "1.6.9" FXRuby-1.6.9-ruby186.exe +end + +desc "Tag this release in Subversion" +task :tag do + require 'rexml/document' + doc = REXML::Document.new(`svn info --xml`) + branch = doc.get_elements("/info/entry/url").first.text + root = doc.get_elements("/info/entry/repository/root").first.text + tag = root + "/tags/REL-#{PKG_VERSION}" + sh %{svn copy -m "Created tag for version #{PKG_VERSION}" #{branch} #{tag}} end desc "Generate all of the documentation files." @@ -180,6 +187,7 @@ Rake::RDocTask.new do |rdoc| "lib/fox16/glshapes.rb", "lib/fox16/input.rb", "lib/fox16/iterators.rb", + "lib/fox16/keys.rb", "lib/fox16/responder2.rb", "lib/fox16/scintilla.rb", "lib/fox16/signal.rb", @@ -200,6 +208,11 @@ end desc "Clean" task :clean do + rm_rf "ext/fox16/Makefile" + rm_rf FileList["ext/fox16/*.o"] + rm_rf FileList["ext/fox16/*.bundle"] + rm_rf "ext/fox16/mkmf.log" + rm_rf "ext/fox16/conftest.dSYM" ruby "install.rb clean" end @@ -210,10 +223,11 @@ def make_impl end task :configure => [:scintilla, :setversions, :generate_kwargs_lib] do - unless File.exist?("config.save") + unless File.exist?(".config") # ruby "install.rb config -- --with-fxscintilla-include=/usr/include/fxscintilla --with-fxscintilla-lib=/usr/lib" # ruby "install.rb config -- --without-fxscintilla" - ruby "install.rb config" +# ruby "install.rb config -- --with-fox-include=/opt/local/include/fox-1.6 --with-fox-lib=/opt/local/lib --with-fxscintilla-include=/opt/local/include/fxscintilla --with-fxscintilla-lib=/opt/local/lib" + ruby "install.rb config -- --with-fox-include=/usr/local/include/fox-1.6 --with-fox-lib=/usr/local/lib --with-fxscintilla-include=/usr/local/include/fxscintilla --with-fxscintilla-lib=/usr/local/lib" make_impl end end @@ -253,10 +267,7 @@ task :setversions => [ :create_installer_scripts ] do setversions("Makefile") setversions("pre-config.rb") setversions("ext/fox16/extconf.rb") - setversions("FXRuby-ruby1.6-i586-mswin32.iss") - setversions("FXRuby-ruby1.8.2-i386-msvcrt.iss") - setversions("FXRuby-ruby1.8.4-i386-msvcrt.iss") - setversions("FXRuby-ruby1.8.5-i386-msvcrt.iss") + setversions("FXRuby-ruby1.8.6-i386-msvcrt.iss") setversions("lib/fox16/version.rb") setversions("doap.rdf") setversions("scripts/make-installers.rb") @@ -265,10 +276,7 @@ end desc "Create INNO Setup Installer Scripts from Template" task :create_installer_scripts do output_filenames = { - "FXRuby-ruby1.6-i586-mswin32.iss.in" => ["1.6", "ruby168", "i586-mswin32"], - "FXRuby-ruby1.8.2-i386-msvcrt.iss.in" => ["1.8", "ruby182", "i386-msvcrt"], - "FXRuby-ruby1.8.4-i386-msvcrt.iss.in" => ["1.8", "ruby184", "i386-msvcrt"], - "FXRuby-ruby1.8.5-i386-msvcrt.iss.in" => ["1.8", "ruby185", "i386-msvcrt"] + "FXRuby-ruby1.8.6-i386-msvcrt.iss.in" => ["1.8", "ruby186", "i386-msvcrt"] } output_filenames.each do |output_filename, info| @@ -285,15 +293,15 @@ task :create_installer_scripts do end # These library files aren't ready for distribution yet. -COOKER_LIBS = %w{acceltable.rb bitmapview.rb canvas.rb html.rb sugar.rb tkcompat.rb} +COOKER_LIBS = %w{acceltable.rb bitmapview.rb canvas.rb html.rb tkcompat.rb} # These example programs aren't ready for distribution yet. -COOKER_EXAMPLES = %w{canvasdemo.rb WhatAQuietStiff.rb examples.rb gdchart.rb gembrowser.rb rapt-gui.rb tablenew.rb} +COOKER_EXAMPLES = %w{canvasdemo.rb WhatAQuietStiff.rb examples.rb gdchart.rb gembrowser.rb rapt-gui.rb rmagick.rb tablenew.rb} # Return the Gem specification for the source Gem def create_gemspec pkg_files = [ - "ANNOUNCE", + "ANNOUNCE", "LICENSE", "README", "index.html", @@ -337,7 +345,8 @@ def create_gemspec s.has_rdoc = true s.rdoc_options = [ '--main', File.join('rdoc-sources', 'README.rdoc'), - '--exclude', 'ext/fox16' + '--exclude', 'ext/fox16', + '--exclude', %r{acceltable|aliases|bitmapview|canvas|html|kwargs|missingdep|responder|tkcompat} ] s.extra_rdoc_files = [ 'rdoc-sources', @@ -347,7 +356,7 @@ def create_gemspec s.test_suite_file = "tests/TS_All.rb" s.author = "Lyle Johnson" - s.email = "lyle@knology.net" + s.email = "lyle.johnson@gmail.com" s.homepage = "http://www.fxruby.org" end end @@ -370,7 +379,7 @@ end # Given the distribution tarball, build the installer for Win32 desc "Build Win32 installer" task :build_win32 do - if File.exist? "config.save" + if File.exist? ".config" ruby "install.rb clean" end ruby "install.rb config --make-prog=nmake -- --with-fox-include=#{FOX_INSTALL_DIR}\\include --with-fox-lib=#{FOX_INSTALL_DIR}\\lib --with-fxscintilla-include=#{FXSCINTILLA_INSTALL_DIR}\\include --with-fxscintilla-lib=#{FXSCINTILLA_INSTALL_DIR}\\lib" @@ -382,14 +391,14 @@ desc "Build Win32 installer using INNO Setup" task :build_win32_installer => [:build_win32] do iss_script_name = nil case VERSION - when /1.6/ - iss_script_name = "FXRuby-ruby1.6-i586-mswin32.iss" when /1.8.2/ iss_script_name = "FXRuby-ruby1.8.2-i386-msvcrt.iss" when /1.8.4/ iss_script_name = "FXRuby-ruby1.8.4-i386-msvcrt.iss" when /1.8.5/ iss_script_name = "FXRuby-ruby1.8.5-i386-msvcrt.iss" + when /1.8.6/ + iss_script_name = "FXRuby-ruby1.8.6-i386-msvcrt.iss" end system(ISCC, iss_script_name) end @@ -397,7 +406,7 @@ end desc "Build Win32 binary Gem" task :build_win32_gem => [:build_win32] do spec = create_gemspec - spec.platform = Gem::Platform::WIN32 + spec.platform = Gem::Platform::CURRENT spec.files += ["ext/fox16/fox16.so"] Gem::Builder.new(spec).build end @@ -406,10 +415,25 @@ desc "Build Win32 binary installer and Gem" task :release_win32 => [:build_win32_installer, :build_win32_gem] do end +desc "Build Mac OS X binary Gem" +task :build_macosx_gem do + raise RuntimeError, "remove libFOX*.dylib and recompile before building gem" unless Dir.glob("/usr/local/lib/libFOX*.dylib").empty? + spec = create_gemspec + spec.platform = Gem::Platform::CURRENT + spec.files += ["ext/fox16/fox16.bundle"] + Gem::Builder.new(spec).build +end + task :generate_kwargs_lib do ruby 'scripts/generate_kwargs_lib.rb' end +Rake::TestTask.new do |t| + t.libs << "tests" + t.test_files = FileList["tests/TC_*.rb"] + t.verbose = true +end + # Default task is build task :default => [:build] do end diff --git a/doc/Makefile b/doc/Makefile index 00c4df5dae42f3f0b998d64f31b28b53a68354b6..b4fefeb10f6ff9665f99298250479ab01eaa5135 100755 --- a/doc/Makefile +++ b/doc/Makefile @@ -4,10 +4,12 @@ # ######################################################################## -SAXON = java -jar /Users/lyle/saxon-6.5.3/saxon.jar +#SAXON = java -jar /Users/lyle/saxon-8.9/saxon8.jar +SAXON = java -jar /Users/lyle/saxon-6.5.5/saxon.jar HTML_STYLESHEET = custom-html.xsl -FO_STYLESHEET = custom-fo.xsl -FOP = /Users/lyle/fop-0.20.4/fop.sh +#FO_STYLESHEET = custom-fo.xsl +FO_STYLESHEET = /Users/lyle/docbook/docbook5-xsl-1.72.0/fo/docbook.xsl +FOP = /Users/lyle/fop-0.93/fop all: html diff --git a/doc/book.xml b/doc/book.xml index 53522edc821102bdc12b4c912df885180eca128d..e36a5527fe08ac318fa900348ec39e9c65f0be69 100755 --- a/doc/book.xml +++ b/doc/book.xml @@ -1,7 +1,7 @@ <?xml version='1.0'?> <!DOCTYPE book - PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" - "file:/Users/lyle/docbook/xml/4.4/docbookx.dtd" [ + PUBLIC "-//OASIS//DTD DocBook V5.0//EN" + "file:/Users/lyle/docbook/xml/5.0/dtd/docbook.dtd" [ <!ENTITY bookinfo.xml SYSTEM "bookinfo.xml"> <!ENTITY build.xml SYSTEM "build.xml"> <!ENTITY changes.xml SYSTEM "changes.xml"> @@ -19,11 +19,10 @@ <!ENTITY library.xml SYSTEM "library.xml"> <!ENTITY opengl.xml SYSTEM "opengl.xml"> <!ENTITY scintilla.xml SYSTEM "scintilla.xml"> -<!ENTITY todo.xml SYSTEM "todo.xml"> <!ENTITY tutorial1.xml SYSTEM "tutorial1.xml"> <!ENTITY unicode.xml SYSTEM "unicode.xml"> ]> -<book id="book" lang="en"> +<book id="book" lang="en" xmlns="http://docbook.org/ns/docbook"> &bookinfo.xml; <part label="I"> <title>The Basics</title> @@ -37,7 +36,6 @@ &examples.xml; &events.xml; <!--&layout.xml;--> -&todo.xml; &infosources.xml; &changes.xml; </part> diff --git a/doc/build.xml b/doc/build.xml index 0db1915d11ba5f953ab4c825cadb355bc0ab0e9c..7eec0f577675fe5fb6f4be1c77b52c0f9d462e64 100755 --- a/doc/build.xml +++ b/doc/build.xml @@ -2,9 +2,11 @@ <chapter id="build"> <title>Building from Source Code</title> - <para>A few words of advice, before getting started:</para> + <para>This chapter provides instructions for building and installing FXRuby + directly from source, and not using some more direct means (such as + installing a gem, or via some package manager).</para> - <itemizedlist mark="bullet"> + <itemizedlist> <listitem> <para>If you're planning to use FXRuby on Windows, with the standard <ulink url="http://rubyinstaller.rubyforge.org">Ruby Installer for @@ -14,12 +16,9 @@ </listitem> <listitem> - <para>If you're planning to use FXRuby on Mac OS X, you may want to - consult <ulink - url="http://www.fox-toolkit.net/cgi-bin/wiki.pl?Mac_OS_X">this - page</ulink> from the <ulink url="http://www.fox-toolkit.net">FOX - Community Wiki</ulink>, in addition to the standard build instructions - listed below.</para> + <para>If you're already using the <ulink + url="http://www.macports.org/">MacPorts</ulink> version of ruby, you may + wish to just install the <filename>rb-fxruby</filename> port.</para> </listitem> </itemizedlist> @@ -30,10 +29,10 @@ and installed FOX. Next, you'll need to download the FXRuby source code tarball and unpack it by typing:</para> - <screen>$ <command>tar xzf FXRuby-1.6.0.tar.gz</command></screen> + <screen>$ <command>tar xzf FXRuby-1.6.13.tar.gz</command></screen> <para>This will create a new directory called <filename - class="directory">FXRuby-1.6.0</filename>. Change to the top-level + class="directory">FXRuby-1.6.13</filename>. Change to the top-level directory and configure the build by typing:</para> <screen>$ <command>ruby install.rb config</command></screen> @@ -46,8 +45,8 @@ <filename>install.rb</filename> during this step, e.g.</para> <screen>$ <command>ruby install.rb config -- \ - --with-fox-include=/home/lyle/fox-1.6.3/include \ - --with-fox-lib=/home/lyle/fox-1.6.3/src/.libs</command></screen> + --with-fox-include=/home/lyle/fox-1.6.32/include \ + --with-fox-lib=/home/lyle/fox-1.6.32/src/.libs</command></screen> <para>Once the build has been configured, you can start the build by typing:</para> @@ -68,7 +67,7 @@ probably fire up <filename>irb</filename> and try to import FXRuby:</para> <screen>$ <command>irb</command> -irb(main):001:0> <userinput>require 'fox'</userinput> +irb(main):001:0> <userinput>require 'fox16'</userinput> true irb(main):002:0></screen> @@ -91,16 +90,16 @@ irb(main):002:0></screen> instructions and build files distributed with the standard Ruby source code. To review, you should have started by unpacking the source code tarball, changing into the top-level source code directory (e.g. <filename - class="directory">C:\ruby-1.8.4</filename>) and then typing:</para> + class="directory">C:\ruby-1.8.6</filename>) and then typing:</para> - <screen>C:\ruby-1.8.4><command>win32\configure</command> + <screen>C:\ruby-1.8.6><command>win32\configure</command> type 'nmake' to make ruby for mswin32. -C:\ruby-1.8.4><command>nmake</command></screen> +C:\ruby-1.8.6><command>nmake</command></screen> <para>After the compilation finished, you installed Ruby somewhere by typing, e.g.,</para> - <screen>C:\ruby-1.8.4><command>nmake DESTDIR=C:\ruby install</command></screen> + <screen>C:\ruby-1.8.6><command>nmake DESTDIR=C:\ruby install</command></screen> <para>Similarly, I'm assuming that you built the FOX library using the Developer Studio project files distributed with the standard FOX source @@ -108,14 +107,14 @@ C:\ruby-1.8.4><command>nmake</command></screen> <para>Now you can configure the FXRuby build by typing:</para> - <screen>C:\FXRuby-1.6.0><command>ruby install.rb config --make-prog=nmake -- \ - --with-fox-include=C:\fox-1.6.3\include \ - --with-fox-lib=C:\fox-1.6.3\lib</command></screen> + <screen>C:\FXRuby-1.6.13><command>ruby install.rb config --make-prog=nmake -- \ + --with-fox-include=C:\fox-1.6.32\include \ + --with-fox-lib=C:\fox-1.6.32\lib</command></screen> <para>Once the build has been configured, you can start the build by typing:</para> - <screen>C:\FXRuby-1.6.0> <command>ruby install.rb setup</command></screen> + <screen>C:\FXRuby-1.6.13> <command>ruby install.rb setup</command></screen> <para>It will take quite awhile to build FXRuby, even on a fast machine, so this might be a good time to take a coffee break. Because Visual C++ is @@ -129,12 +128,12 @@ C:\ruby-1.8.4><command>nmake</command></screen> <para>Once it's finished compiling, install FXRuby by typing:</para> - <screen>C:\FXRuby-1.6.0> <command>ruby install.rb install</command></screen> + <screen>C:\FXRuby-1.6.13> <command>ruby install.rb install</command></screen> <para>As a quick sanity check, to make sure that all is well, you should probably fire up <filename>irb</filename> and try to import FXRuby:</para> - <screen>C:\FXRuby-1.6.0> <command>irb</command> + <screen>C:\FXRuby-1.6.13> <command>irb</command> irb(main):001:0> <userinput>require 'fox16'</userinput> true irb(main):002:0></screen> @@ -232,34 +231,34 @@ core_wrap.cpp:108596: virtual memory exhausted</screen> <para>On Linux and other Unix systems that support shared libraries, FOX is typically installed as a shared library named - <filename>libFOX-1.4.so</filename>. After all of the source files for + <filename>libFOX-1.6.so</filename>. After all of the source files for FXRuby are compiled, the last step is to link all of the FXRuby object files together with the FOX library (and possibly other system libraries) - to produce a new shared library, named <filename>fox14.so</filename>, that + to produce a new shared library, named <filename>fox16.so</filename>, that Ruby can import as an extension module.</para> <para>There are a few things that can go wrong when you try to import this extension into Ruby. A common problem is that the operating system cannot - locate the FOX shared library (<filename>libFOX-1.4.so</filename>) when it + locate the FOX shared library (<filename>libFOX-1.6.so</filename>) when it tries to dynamically load the FXRuby extension module; when this happens, the error message will look something like:</para> <screen>$ <command>irb</command> -irb(main):001:0> <userinput>require 'fox'</userinput> -LoadError: libFOX-0.99.so.173: cannot open shared object file: No such file or directory - /usr/local/lib/ruby/1.6/i586-linux/fox.so +irb(main):001:0> <userinput>require 'fox16'</userinput> +LoadError: libFOX-1.6.so: cannot open shared object file: No such file or directory - /usr/local/lib/ruby/1.8/i686-linux/fox16.so from (irb):1:in 'require' from (irb):1 </screen> <para>One workaround for this problem is to modify the <constant>LD_LIBRARY_PATH</constant> environment variable to include the - directory where <filename>libFOX.so</filename> is installed. For example, - if <filename>libFOX-1.4.so</filename> is installed in <filename + directory where <filename>libFOX-1.6.so</filename> is installed. For + example, if <filename>libFOX-1.6.so</filename> is installed in <filename class="directory">/usr/local/lib</filename>, try setting:</para> <screen>$ <command>export LD_LIBRARY_PATH=/usr/local/lib</command> $ <command>irb</command> -irb(main):001:0> <userinput>require 'fox'</userinput> +irb(main):001:0> <userinput>require 'fox16'</userinput> </screen> <para>If this works, you can of course permanently add the @@ -273,7 +272,7 @@ irb(main):001:0> <userinput>require 'fox'</userinput> <orderedlist numeration="arabic" spacing="compact"> <listitem> <para>Edit your <filename>/etc/ld.so.conf</filename> file and add the - directory where <filename>libFOX.so</filename> is installed; + directory where <filename>libFOX-1.6.so</filename> is installed; and,</para> </listitem> @@ -294,4 +293,4 @@ irb(main):001:0> <userinput>require 'fox'</userinput> <filename>Makefile</filename> and add <option>-lgcc</option> to the <constant>LIBS</constant> line.</para> </simplesect> -</chapter> +</chapter> \ No newline at end of file diff --git a/doc/changes.xml b/doc/changes.xml index d62e6dd71477494a8a07b4429b4e4ef29e2feff9..80c3c078d43c26022765b50e0b2ebfb96652c774 100755 --- a/doc/changes.xml +++ b/doc/changes.xml @@ -2,6 +2,440 @@ <chapter id="changes"> <title>Change History</title> + <simplesect> + <title>Changes For Version 1.6.18 (December 29, 2008)</title> + + <itemizedlist mark="bullet"> + <listitem> + <para>Some users were having trouble building FXRuby on 64-bit operating systems + (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=23375&group_id=300&atid=1223">RubyForge + Bug #23375</ulink>). This problem has been corrected.</para> + </listitem> + </itemizedlist> + </simplesect> + + <simplesect> + <title>Changes For Version 1.6.17 (December 24, 2008)</title> + + <itemizedlist mark="bullet"> + <listitem> + <para>The Ruby interpreter was generating a large number of warning messages about redefined methods + in the <filename>kwargs.rb</filename> library + (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=19231&group_id=300&atid=1223">RubyForge + Bug #19231</ulink> and elsewhere). This problem has been corrected.</para> + </listitem> + + <listitem> + Due to recent changes in Ruby's garbage collection algorithm, FXRuby applications could under some circumstances + crash for large numbers of table items + (see RubyForge bugs <ulink url="http://rubyforge.org/tracker/index.php?func=detail&aid=21983&group_id=300&atid=1223">21983</ulink> and <ulink url="http://rubyforge.org/tracker/index.php?func=detail&aid=23188&group_id=300&atid=1223">23188</ulink>). + This bug has been fixed. + </listitem> + + <listitem> + <para>The documentation for the <classname>FXTable</classname> class referred to the non-existent <methodname>setColumnX</methodname> + and <methodname>setRowY</methodname> instance methods + (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=21987&group_id=300&atid=1223">RubyForge + Bug #21987</ulink>). These entries have been removed from the documentation.</para> + </listitem> + + <listitem> + <para>A number of instance methods for the <classname>FXTable</classname> class could crash an application if they + were passed out-of-bounds index arguments + (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=21987&group_id=300&atid=1223">RubyForge + Bug #21987</ulink>). These methods now raise <classname>IndexError</classname> when they're passed out-of-bounds + indexes.</para> + </listitem> + + <listitem> + <para>Due to a change in the URL scheme for the Dilbert web site, the <filename>dilbert.rb</filename> example + program was no longer working properly + (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=21538&group_id=300&atid=1223">RubyForge + Bug #21538</ulink>). This has been fixed.</para> + </listitem> + + <listitem> + <para>The <methodname>lower</methodname> method for the <classname>FXRangef</classname> was returning + <constant>self</constant> instead of an <classname>FXVec3f</classname> instance for the range's low + bound + (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=22488&group_id=300&atid=1223">RubyForge + Bug #22488</ulink>). This has been fixed.</para> + </listitem> + + <listitem> + <para>Made a number of minor fixes for compatibility with Ruby 1.9.1.</para> + </listitem> + </itemizedlist> + </simplesect> + + <simplesect> + <title>Changes For Version 1.6.16 (July 3, 2008)</title> + + <itemizedlist mark="bullet"> + <listitem> + <para>Historically, if you called <methodname>create</methodname> on a + window before its parent window was created, your application would + crash (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=20702&group_id=300&atid=1223">RubyForge + Bug #20702</ulink> and elsewhere). Now, the code should raise a + <constant>RuntimeError</constant> with a message indicating the + problem.</para> + </listitem> + + <listitem> + <para>The message data that the <classname>FXPicker</classname> widget + sends along with its <constant>SEL_CHANGED</constant> and + <constant>SEL_COMMAND</constant> messages wasn't being handled + properly, and as a result, applications using this widget could crash + (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=20780&group_id=300&atid=1223">RubyForge + Bug #20780</ulink>). This problem has been fixed.</para> + </listitem> + </itemizedlist> + </simplesect> + + <simplesect> + <title>Changes For Version 1.6.15 (June 4, 2008)</title> + + <itemizedlist mark="bullet"> + <listitem> + <para>FXRuby applications could crash (with a segmentation fault) if + <constant>nil</constant> was passed in as the first argument to + <methodname>FXDialogBox.new</methodname> or + <methodname>FXMainWindow.new</methodname> (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=14642&group_id=300&atid=1223">RubyForge + Bug #14642</ulink>). These methods now raise an + <constant>ArgumentError</constant> if <constant>nil</constant> is + passed as the first argument.</para> + </listitem> + + <listitem> + <para>You should only ever construct one <classname>FXApp</classname> + object per application, but there was no protection against doing so + in the code (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=16275&group_id=300&atid=1223">RubyForge + Bug #16275</ulink>). Now, <methodname>FXApp.new</methodname> will + raise a <classname>RuntimeException</classname> if an + <classname>FXApp</classname> object already exists.</para> + </listitem> + + <listitem> + <para>The <filename>babelfish.rb</filename> example program, which + previously depended on an external web service to perform translation + between languages, was broken since that web service no longer exists + (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=16962&group_id=300&atid=1223">RubyForge + Bug #16962</ulink>). The example has now been updated to use Dr. Nic's + <ulink url="http://tranexp.rubyforge.org/">Tranexp</ulink> library + instead.</para> + </listitem> + + <listitem> + <para>The value of the <constant>MBOX_SAVE_CANCEL_DONTSAVE</constant> + option (for the <classname>FXMessageBox</classname> class) wasn't + wrapped properly and was unusable (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=17094&group_id=300&atid=1223">RubyForge + Bug #17094</ulink>). There was also no constant corresponding to the + <constant>MBOX_CLICKED_DONTSAVE</constant> return value. Both of these + problems have been fixed.</para> + </listitem> + + <listitem> + <para>The fields for new <classname>FXHiliteStyle</classname> objects + were uninitialized and as a result sometimes gave unpredictable + results (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=19637&group_id=300&atid=1223">RubyForge + Bug #19637</ulink>). This has been fixed.</para> + </listitem> + + <listitem> + <para>The <methodname>columnHeaderFont</methodname> and + <methodname>rowHeaderFont</methodname> attributes for + <classname>FXTable</classname> weren't implemented properly (see + <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=20142&group_id=300&atid=1223">RubyForge + Bug #20142</ulink>). This has been fixed.</para> + </listitem> + + <listitem> + <para>Ruby 1.8.7 adds a new <methodname>first</methodname> method to + the <classname>Enumerable</classname> module, and this conflicts with + the existing <methodname>first</methodname> method defined in the + <classname>FXWindow</classname> base class for a number of FXRuby + classes which mix in <classname>Enumerable</classname> (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=20418&group_id=300&atid=1223">RubyForge + Bug #20418</ulink>). This problem has been resolved.</para> + </listitem> + + <listitem> + <para>Due to a bug in the <filename>extconf.rb</filename> script, the + build was failing for Ruby 1.9.0 (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=20426&group_id=300&atid=1223">RubyForge + Bug #20426</ulink>). This has been fixed.</para> + </listitem> + </itemizedlist> + </simplesect> + + <simplesect> + <title>Changes For Version 1.6.14 (March 29, 2008)</title> + + <itemizedlist mark="bullet"> + <listitem> + <para>Updated the documentation for the <classname>FXImage</classname> + class to indicate which methods call <methodname>render</methodname> + after they're finished, and which ones do not.</para> + </listitem> + + <listitem> + <para>Corrected a little typo in the + <filename>gembrowser.rb</filename> example program.</para> + </listitem> + + <listitem> + <para>Updated the <filename>dilbert.rb</filename> example program to + use the more popular-and-likely-to-be-installed <ulink + url="http://code.whytheluckystiff.net/hpricot/">Hpricot</ulink> HTML + parser library instead of <ulink + url="http://www.crummy.com/software/RubyfulSoup/">Rubyful + Soup</ulink>.</para> + </listitem> + + <listitem> + <para>Re-added the documentation for the + <constant>TOGGLEBUTTON_KEEPSTATE</constant> option, which had + mysteriously disappeared (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=2286&group_id=300&atid=1223">RubyForge + Bug #2286</ulink>).</para> + </listitem> + + <listitem> + <para>Made a number of minor fixes to support building FXRuby against + Ruby 1.9.</para> + </listitem> + + <listitem> + <para>Added a binary gem for OS X. This works with the Ruby that's + included with OS X (Leopard).</para> + </listitem> + + <listitem> + <para>The binary gem for Windows was built with FOX version 1.6.32 and + FXScintilla version 1.71.</para> + </listitem> + </itemizedlist> + </simplesect> + + <simplesect> + <title>Changes For Version 1.6.13 (November 9, 2007)</title> + + <itemizedlist mark="bullet"> + <listitem> + <para>Calls to the <methodname>extractText</methodname> method for the + <classname>FXTable</classname> class were causing various + memory-related errors on certain platforms (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=15444group_id=300&atid=1223">RubyForge + Bug #15444</ulink>). This problem has been fixed.</para> + </listitem> + + <listitem> + <para>The binary gem for Windows was built with FOX version 1.6.28 and + FXScintilla version 1.71.</para> + </listitem> + </itemizedlist> + </simplesect> + + <simplesect> + <title>Changes For Version 1.6.12 (October 19, 2007)</title> + + <itemizedlist mark="bullet"> + <listitem> + <para>The API documentation for <classname>FXMDIClient</classname> + referred to the non-existent instance method + <methodname>activeChild=</methodname> (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=10259&group_id=300&atid=1223">RubyForge + Bug #10259</ulink>). This method has been added.</para> + </listitem> + + <listitem> + <para>The API documentation for <classname>FXMDIClient</classname> + also referred to the non-existent instance methods + <methodname>getMDIChildFirst</methodname> and + <methodname>getMDIChildLast</methodname>. These entries have been + removed.</para> + </listitem> + + <listitem> + <para>The API documentation for <classname>FXMDIChild</classname> + referred to non-existent instance methods + <methodname>getMDINext</methodname> and + <methodname>getMDIPrev</methodname> (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=10436&group_id=300&atid=1223">RubyForge + Bug #10436</ulink>). The documentation has been corrected.</para> + </listitem> + + <listitem> + <para>Added the <parameter>:repeat</parameter> parameter for the + <methodname>addChore</methodname> and + <methodname>addTimeout</methodname> methods. See the documentation for + more details, and <filename>gltest.rb</filename> for an example of its + use.</para> + </listitem> + + <listitem> + <para>Corrected a number of minor typos in the API + documentation.</para> + </listitem> + + <listitem> + <para>Corrected a typo in the <filename>imageviewer.rb</filename> + example.</para> + </listitem> + + <listitem> + <para>Modified the <filename>inputs.rb</filename> example program to + use <methodname>Pipe.read_nonblock()</methodname> instead of + <methodname>Pipe.read()</methodname>.</para> + </listitem> + + <listitem> + <para>Fixed a bug in the implementation of the + <methodname>findText</methodname> method for the + <classname>FXText</classname> class, when used with the + <constant>SEARCH_REGEX</constant> option.</para> + </listitem> + + <listitem> + <para>The binary gem for Windows was built with FOX version 1.6.28 and + FXScintilla version 1.71.</para> + </listitem> + </itemizedlist> + </simplesect> + + <simplesect> + <title>Changes For Version 1.6.11 (April 18, 2007)</title> + + <itemizedlist mark="bullet"> + <listitem> + <para>Added <methodname>editable</methodname> as an alias for + <methodname>FXTextField#editable?</methodname>.</para> + </listitem> + + <listitem> + <para>Added <methodname>each_child_recursive</methodname> instance + method for the <classname>FXWindow</classname> class. This method + performs a depth-first traversal of the widget tree starting at the + receiver window.</para> + </listitem> + + <listitem> + <para>Corrected some errors in the keyword arguments support for the + <classname>FXVec2d</classname>, <classname>FXVec2f</classname>, + <classname>FXVec3d</classname>, <classname>FVec3f</classname>, + <classname>FXVec4d</classname> and <classname>FXVec4f</classname> + classes.</para> + </listitem> + + <listitem> + <para>Corrected an error in the keyword arguments support for the + <classname>FXIconDict</classname> class.</para> + </listitem> + + <listitem> + <para>Modified the gem specification so that the RDoc generated during + a gem install is consistent with that generated by other methods (see + <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=10035&group_id=300&atid=1223">RubyForge + Bug #10035</ulink>).</para> + </listitem> + + <listitem> + <para>Changes to the <filename>iterators</filename> library in version + 1.6.6 introduced a bug in the <methodname>each</methodname> method for + the <classname>FXFoldingList</classname>, + <classname>FXTreeList</classname> and + <classname>FXTreeListBox</classname> classes (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=10175&group_id=300&atid=1223">RubyForge + Bug #10175</ulink>). This problem has been fixed.</para> + </listitem> + + <listitem> + <para>Applied submitted patches for building FXRuby against Ruby 1.9 + (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=10181&group_id=300&atid=1223">RubyForge + Bug #10181</ulink>). Please note that building FXRuby against the Ruby + 1.9 code base is still officially unsupported; however, I'm glad to + accept patches that will help make this possible.</para> + </listitem> + + <listitem> + <para>The binary gem for Windows was built with FOX version 1.6.25 and + FXScintilla version 1.71.</para> + </listitem> + </itemizedlist> + </simplesect> + + <simplesect> + <title>Changes For Version 1.6.9 (April 8, 2007)</title> + + <itemizedlist mark="bullet"> + <listitem> + <para>A bug was discovered in the keyword arguments library support + for the <classname>FXMenuBar</classname> class (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=9927&group_id=300&atid=1223">RubyForge + Bug #9927</ulink>). This problem has been fixed.</para> + </listitem> + + <listitem> + <para>The binary gem for Windows was built with FOX version 1.6.25 and + FXScintilla version 1.71.</para> + </listitem> + </itemizedlist> + </simplesect> + + <simplesect> + <title>Changes For Version 1.6.8 (April 5, 2007)</title> + + <itemizedlist mark="bullet"> + <listitem> + <para>Due to an internal bookkeeping error, applications like the + <filename>glviewer.rb</filename> example program which create multiple + <classname>FXGLViewer</classname> instances could cause an assertion + to fail. When this assertion fails on Windows, the program simply + crashes (see <ulink + url="http://rubyforge.org/tracker/index.php?func=detail&aid=9775&group_id=300&atid=1223">RubyForge + Bug #9775</ulink>). This problem has been fixed.</para> + </listitem> + + <listitem> + <para>The keyword arguments library, introduced in version 1.6.5, is + now included automatically when you load FXRuby; it is no longer + necessary to explicitly require it.</para> + </listitem> + + <listitem> + <para>The binary gem for Windows was built with FOX version 1.6.25 and + FXScintilla version 1.71.</para> + </listitem> + </itemizedlist> + </simplesect> + + <simplesect> + <title>Changes For Version 1.6.7 (March 31, 2007)</title> + + <itemizedlist mark="bullet"> + <listitem> + <para>The binary gem for Windows was built with FOX version 1.6.25 and + FXScintilla version 1.71.</para> + </listitem> + </itemizedlist> + </simplesect> + <simplesect> <title>Changes For Version 1.6.6 (February 10, 2007)</title> diff --git a/doc/clipboardtut.xml b/doc/clipboardtut.xml index eb32f71dfaa88cad1bb52ef2c32349bc2308b346..92836a0f5ff3dcc5e1306e43213e1563f8486c2a 100755 --- a/doc/clipboardtut.xml +++ b/doc/clipboardtut.xml @@ -21,8 +21,7 @@ doesn't yet provide any clipboard support. This application simply presents a list of customers (from some external source).</para> - <programlisting format="linespecific">require 'rubygems' -require_gem 'fxruby' + <programlisting format="linespecific">require 'fox16' require 'customer' include Fox @@ -30,14 +29,14 @@ include Fox class ClipMainWindow < FXMainWindow def initialize(anApp) # Initialize base class first - super(anApp, "Clipboard Example", nil, nil, DECOR_ALL, 0, 0, 400, 300) + super(anApp, "Clipboard Example", :opts => DECOR_ALL, :width => 400, :height => 300) # Place the list in a sunken frame - sunkenFrame = FXVerticalFrame.new(self, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, - 0, 0, 0, 0, 0, 0, 0, 0) + sunkenFrame = FXVerticalFrame.new(self, + LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding => 0) # Customer list - customerList = FXList.new(sunkenFrame, nil, 0, LIST_BROWSESELECT|LAYOUT_FILL_X|LAYOUT_FILL_Y) + customerList = FXList.new(sunkenFrame, :opts => LIST_BROWSESELECT|LAYOUT_FILL_X|LAYOUT_FILL_Y) $customers.each do |customer| customerList.appendItem(customer.name, nil, customer) end @@ -89,8 +88,7 @@ $customers << Customer.new("Johnny Storm", "123 Maple, Anytown, NC", 12345 <para>Let's begin by augmenting the GUI to include a row of buttons along the bottom of the main window for copying and pasting:</para> - <programlisting format="linespecific">require 'rubygems' -require_gem 'fxruby' + <programlisting format="linespecific">require 'fox16' require 'customer' include Fox @@ -98,7 +96,7 @@ include Fox class ClipMainWindow < FXMainWindow def initialize(anApp) # Initialize base class first - super(anApp, "Clipboard Example", nil, nil, DECOR_ALL, 0, 0, 400, 300) + super(anApp, "Clipboard Example", :opts => DECOR_ALL, :width => 400, :height => 300) <emphasis role="bold"> # Horizontal frame contains buttons buttons = FXHorizontalFrame.new(self, LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH) @@ -108,11 +106,11 @@ class ClipMainWindow < FXMainWindow pasteButton = FXButton.new(buttons, "Paste") </emphasis> # Place the list in a sunken frame - sunkenFrame = FXVerticalFrame.new(self, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, - 0, 0, 0, 0, 0, 0, 0, 0) + sunkenFrame = FXVerticalFrame.new(self, + LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding => 0) # Customer list - customerList = FXList.new(sunkenFrame, nil, 0, LIST_BROWSESELECT|LAYOUT_FILL_X|LAYOUT_FILL_Y) + customerList = FXList.new(sunkenFrame, :opts => LIST_BROWSESELECT|LAYOUT_FILL_X|LAYOUT_FILL_Y) $customers.each do |customer| customerList.appendItem(customer.name, nil, customer) end diff --git a/doc/custom-fo.xsl b/doc/custom-fo.xsl index 563fc05f080c27b33ed8c71453b76302f185f1e0..039868c83ae21c67d3303b20cf6ec232044e9d8e 100755 --- a/doc/custom-fo.xsl +++ b/doc/custom-fo.xsl @@ -3,7 +3,7 @@ version='1.0' xmlns="http://www.w3.org/TR/xhtml1/transitional" exclude-result-prefixes="#default"> -<xsl:import href="/usr/local/docbook/docbook-xsl-1.61.2/fo/docbook.xsl"/> +<xsl:import href="/Users/lyle/docbook/docbook5-xsl-1.72.0/fo/docbook.xsl"/> <!--xsl:param name="use.extensions" select="1"/--> <xsl:param name="fop.extensions" select="1"/> <xsl:param name="shade.verbatim" select="1"/> diff --git a/doc/custom-html.xsl b/doc/custom-html.xsl index 3cbb41b2b9a2dff53074d59558570ec7a2479f5b..aa8dd7fe57651d3c7a9320b15d8abb15a4c78dfe 100755 --- a/doc/custom-html.xsl +++ b/doc/custom-html.xsl @@ -4,7 +4,7 @@ xmlns="http://www.w3.org/TR/xhtml1/transitional" exclude-result-prefixes="#default"> -<xsl:import href="/Users/lyle/docbook/docbook-xsl-1.68.1/html/chunk.xsl"/> +<xsl:import href="/Users/lyle/docbook/docbook5-xsl-1.72.0/html/chunk.xsl"/> <xsl:variable name="root.filename">book</xsl:variable> <xsl:param name="html.stylesheet.type">text/css</xsl:param> diff --git a/doc/dragdroptut.xml b/doc/dragdroptut.xml index 31a93b530c43b4376ee6bc398f9f2cc664c3f47d..5db5d2f4076d473115898f5bc76c6cf9953ca545 100755 --- a/doc/dragdroptut.xml +++ b/doc/dragdroptut.xml @@ -15,18 +15,17 @@ of a main window widget (a <classname>DropSite</classname> instance) that parents an <classname>FXCanvas</classname> widget:</para> - <programlisting format="linespecific">require 'rubygems' -require_gem 'fxruby' + <programlisting format="linespecific">require 'fox16' include Fox class DropSite < FXMainWindow def initialize(anApp) # Initialize base class - super(anApp, "Drop Site", nil, nil, DECOR_ALL, 0, 0, 400, 300) + super(anApp, "Drop Site", :opts => DECOR_ALL, :width => 400, :height => 300) # Fill main window with canvas - @canvas = FXCanvas.new(self, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y) + @canvas = FXCanvas.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y) end def create @@ -55,26 +54,25 @@ end that by adding a handler that clears the canvas to its current background color:</para> - <programlisting format="linespecific">require 'rubygems' -require_gem 'fxruby' + <programlisting format="linespecific">require 'fox16' include Fox class DropSite < FXMainWindow def initialize(anApp) # Initialize base class - super(anApp, "Drop Site", nil, nil, DECOR_ALL, 0, 0, 400, 300) + super(anApp, "Drop Site", :opts => DECOR_ALL, :width => 400, :height => 300) # Fill main window with canvas - @canvas = FXCanvas.new(self, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y) + @canvas = FXCanvas.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y) <emphasis role="bold"> # Handle expose events on the canvas - @canvas.connect(SEL_PAINT) { |sender, sel, event| - FXDCWindow.new(@canvas, event) { |dc| + @canvas.connect(SEL_PAINT) do |sender, sel, event| + FXDCWindow.new(@canvas, event) do |dc| dc.foreground = @canvas.backColor dc.fillRectangle(event.rect.x, event.rect.y, event.rect.w, event.rect.h) - } - }</emphasis> + end + end</emphasis> end def create @@ -95,23 +93,23 @@ end from some other window, such as an <classname>FXColorWell</classname> widget, and drop it onto the canvas in order to change the canvas' background color. In order for a FOX widget to be able to accept drops at - all, we need to first call its <methodname>dropEnable()</methodname> + all, we need to first call its <methodname>dropEnable</methodname> method:</para> <programlisting format="linespecific">def initialize(anApp) # Initialize base class - super(anApp, "Drop Site", nil, nil, DECOR_ALL, 0, 0, 400, 300) + super(anApp, "Drop Site", :opts => DECOR_ALL, :width => 400, :height => 300) # Fill main window with canvas - @canvas = FXCanvas.new(self, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y) + @canvas = FXCanvas.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y) # Handle expose events on the canvas - @canvas.connect(SEL_PAINT) { |sender, sel, event| - FXDCWindow.new(@canvas, event) { |dc| + @canvas.connect(SEL_PAINT) do |sender, sel, event| + FXDCWindow.new(@canvas, event) do |dc| dc.foreground = @canvas.backColor dc.fillRectangle(event.rect.x, event.rect.y, event.rect.w, event.rect.h) - } - } + end + end <emphasis role="bold"> # Enable canvas for drag-and-drop messages @canvas.dropEnable @@ -141,39 +139,39 @@ end that the canvas isn't accepting drops of color data yet.</para> <para>To correct this problem, we need to use the canvas' - <methodname>acceptDrop()</methodname> method to indicate whether or not + <methodname>acceptDrop</methodname> method to indicate whether or not we'll accept certain kinds of drops. You can call - <methodname>acceptDrop()</methodname> any time after receiving the initial + <methodname>acceptDrop</methodname> any time after receiving the initial <constant>SEL_DND_ENTER</constant> message, but it's usually done in response to a <constant>SEL_DND_MOTION</constant> message. Let's add a handler for <constant>SEL_DND_MOTION</constant> messages from the canvas - in DropSite's initialize() method. For now, we'll unconditionally accept + in DropSite's <methodname>initialize</methodname> method. For now, we'll unconditionally accept drops from any drag source, regardless of what kind of data they're offering:</para> <programlisting format="linespecific">def initialize(anApp) # Initialize base class - super(anApp, "Drop Site", nil, nil, DECOR_ALL, 0, 0, 400, 300) + super(anApp, "Drop Site", :opts => DECOR_ALL, :width => 400, :height => 300) # Fill main window with canvas - @canvas = FXCanvas.new(self, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y) + @canvas = FXCanvas.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y) # Handle expose events on the canvas - @canvas.connect(SEL_PAINT) { |sender, sel, event| - FXDCWindow.new(@canvas, event) { |dc| + @canvas.connect(SEL_PAINT) do |sender, sel, event| + FXDCWindow.new(@canvas, event) do |dc| dc.foreground = @canvas.backColor dc.fillRectangle(event.rect.x, event.rect.y, event.rect.w, event.rect.h) - } - } + end + end # Enable canvas for drag-and-drop messages @canvas.dropEnable <emphasis role="bold"> # Handle SEL_DND_MOTION messages from the canvas - @canvas.connect(SEL_DND_MOTION) { + @canvas.connect(SEL_DND_MOTION) do # Accept drops unconditionally (for now) @canvas.acceptDrop - } + end </emphasis>end </programlisting> @@ -195,7 +193,7 @@ end <para>Drag types (even the standard ones) must be registered before they can be used, and so we'll start by adding a few lines to - <classname>DropSite</classname>'s <methodname>create()</methodname> method + <classname>DropSite</classname>'s <methodname>create</methodname> method to register the drag type for color data:</para> <programlisting format="linespecific">def create @@ -211,49 +209,49 @@ end </programlisting> <para>Note that the first time that - <methodname>registerDragType()</methodname> is called for a particular + <methodname>registerDragType</methodname> is called for a particular drag type name (such as <methodname>FXWindow.colorTypeName</methodname>) it will generate a unique identifier for that drag type. Subsequent calls - to <methodname>registerDragType()</methodname> for the same drag type name + to <methodname>registerDragType</methodname> for the same drag type name will just return the previously-generated drag type. Now, we want to modify our <constant>SEL_DND_MOTION</constant> handler so that it's a little more picky about which kinds of drops it will accept:</para> <programlisting format="linespecific"># Handle SEL_DND_MOTION messages from the canvas -@canvas.connect(SEL_DND_MOTION) { +@canvas.connect(SEL_DND_MOTION) do <emphasis role="bold"> if @canvas.offeredDNDType?(FROM_DRAGNDROP, FXWindow.colorType) @canvas.acceptDrop end -</emphasis>} +</emphasis>end </programlisting> <para>Here, we call the canvas' <methodname>offeredDNDType?</methodname> method to ask if the drag source can provide its data in the requested format. Only if <methodname>offeredDNDType?</methodname> returns true will - we call <methodname>acceptDrop()</methodname> as before.</para> + we call <methodname>acceptDrop</methodname> as before.</para> <para>The last step is to actually handle the drop, and for that we add a handler for the <constant>SEL_DND_DROP</constant> message:</para> <programlisting format="linespecific"><emphasis role="bold"># Handle SEL_DND_DROP message from the canvas -@canvas.connect(SEL_DND_DROP) { +@canvas.connect(SEL_DND_DROP) do # Try to obtain the data as color values first data = @canvas.getDNDData(FROM_DRAGNDROP, FXWindow.colorType) unless data.nil? # Update canvas background color @canvas.backColor = Fox.fxdecodeColorData(data) end -}</emphasis></programlisting> +end</emphasis></programlisting> <para>Assuming that the drag source is able to provide its data in the - requested format, the <methodname>getDNDData()</methodname> method will - return a String (which for our purposes is just a byte buffer). If you've + requested format, the <methodname>getDNDData</methodname> method will + return a string (which for our purposes is just a byte buffer). If you've defined your own application-specific drag types, this data can of course be anything, and we'll see examples of this in a later tutorial. But the data for standard drag types like <methodname>FXWindow.colorType</methodname> can be decoded using the appropriate built-in library functions. In this case, we use the - <methodname>fxdecodeColorData()</methodname> method to convert the bytes + <methodname>fxdecodeColorData</methodname> method to convert the bytes into a color value that we can use.</para> <para>Now comes the moment of truth. Try running your test program again @@ -265,46 +263,45 @@ end <filename class="directory">examples</filename> directory under the file name <filename>dropsite.rb</filename>.</para> - <programlisting format="linespecific">require 'rubygems' -require_gem 'fxruby' + <programlisting format="linespecific">require 'fox16' include Fox class DropSite < FXMainWindow def initialize(anApp) # Initialize base class - super(anApp, "Drop Site", nil, nil, DECOR_ALL, 0, 0, 400, 300) + super(anApp, "Drop Site", :opts => DECOR_ALL, :width => 400, :height => 300) # Fill main window with canvas - @canvas = FXCanvas.new(self, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y) + @canvas = FXCanvas.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y) # Handle expose events on the canvas - @canvas.connect(SEL_PAINT) { |sender, sel, event| - FXDCWindow.new(@canvas, event) { |dc| + @canvas.connect(SEL_PAINT) do |sender, sel, event| + FXDCWindow.new(@canvas, event) do |dc| dc.foreground = @canvas.backColor dc.fillRectangle(event.rect.x, event.rect.y, event.rect.w, event.rect.h) - } - } + end + end # Enable canvas for drag-and-drop messages @canvas.dropEnable # Handle SEL_DND_MOTION messages from the canvas - @canvas.connect(SEL_DND_MOTION) { + @canvas.connect(SEL_DND_MOTION) do if @canvas.offeredDNDType?(FROM_DRAGNDROP, FXWindow.colorType) @canvas.acceptDrop end - } + end # Handle SEL_DND_DROP message from the canvas - @canvas.connect(SEL_DND_DROP) { + @canvas.connect(SEL_DND_DROP) do # Try to obtain the data as color values first data = @canvas.getDNDData(FROM_DRAGNDROP, FXWindow.colorType) unless data.nil? # Update canvas background color @canvas.backColor = Fox.fxdecodeColorData(data) end - } + end end def create @@ -336,27 +333,26 @@ end consisting of a main window widget (a <classname>DragSource</classname> instance) that parents an <classname>FXCanvas</classname> widget:</para> - <programlisting format="linespecific">require 'rubygems' -require_gem 'fxruby' + <programlisting format="linespecific">require 'fox16' include Fox class DragSource < FXMainWindow def initialize(anApp) # Initialize base class - super(anApp, "Drag Source", nil, nil, DECOR_ALL, 0, 0, 400, 300) + super(anApp, "Drag Source", :opts => DECOR_ALL, :width => 400, :height => 300) # Fill main window with canvas - @canvas = FXCanvas.new(self, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y) + @canvas = FXCanvas.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y) @canvas.backColor = "red" # Handle expose events on the canvas - @canvas.connect(SEL_PAINT) { |sender, sel, event| - FXDCWindow.new(@canvas, event) { |dc| + @canvas.connect(SEL_PAINT) do |sender, sel, event| + FXDCWindow.new(@canvas, event) do |dc| dc.foreground = @canvas.backColor dc.fillRectangle(event.rect.x, event.rect.y, event.rect.w, event.rect.h) - } - } + end + end end def create @@ -397,7 +393,7 @@ end <listitem> <para>The drag type for colors (<constant>FXWindow.colorType</constant>) is registered in the - <classname>DragSource</classname>'s <methodname>create()</methodname> + <classname>DragSource</classname>'s <methodname>create</methodname> method.</para> </listitem> </itemizedlist> @@ -412,7 +408,7 @@ end handler for the <constant>SEL_LEFTBUTTONPRESS</constant> message from the canvas:</para> - <programlisting format="linespecific">@canvas.connect(SEL_LEFTBUTTONPRESS) { + <programlisting format="linespecific">@canvas.connect(SEL_LEFTBUTTONPRESS) do # # Capture (grab) the mouse when the button goes down, so that all future # mouse events will be reported to this widget, even if those events occur @@ -423,13 +419,13 @@ end # Advertise which drag types we can offer dragTypes = [FXWindow.colorType] @canvas.beginDrag(dragTypes) -} +end </programlisting> <para>Note that there are usually two things you're going to want to do in the <constant>SEL_LEFTBUTTONPRESS</constant> handler for a drag source. - The first is to call <methodname>grab()</methodname> on the window that - acts as the drag source. Calling <methodname>grab()</methodname> + The first is to call <methodname>grab</methodname> on the window that + acts as the drag source. Calling <methodname>grab</methodname> "captures" the mouse in the sense that subsequent mouse motion events will be reported as if they occurred inside the grab window. This is important, since in our case we're going to be dragging from this window to some @@ -438,7 +434,7 @@ end <para>The second thing you'll want to do in the <constant>SEL_LEFTBUTTONPRESS</constant> handler for a drag source is to - call <methodname>beginDrag()</methodname>. This not only kicks the + call <methodname>beginDrag</methodname>. This not only kicks the application into drag-and-drop mode, but also provides a way for you to inform the system about the formats of data (i.e. the drag types) that this drag source is able to provide. For this example, the drag source is @@ -448,22 +444,22 @@ end it's important to also add a handler for the <constant>SEL_LEFTBUTTONRELEASE</constant> message:</para> - <programlisting format="linespecific">@canvas.connect(SEL_LEFTBUTTONRELEASE) { + <programlisting format="linespecific">@canvas.connect(SEL_LEFTBUTTONRELEASE) do @canvas.ungrab @canvas.endDrag -} +end </programlisting> <para>This is pretty much the mirror image of our <constant>SEL_LEFTBUTTONPRESS</constant> handler. We call - <methodname>ungrab()</methodname> to release the mouse capture, and - <methodname>endDrag()</methodname> to clean up the drag-and-drop + <methodname>ungrab</methodname> to release the mouse capture, and + <methodname>endDrag</methodname> to clean up the drag-and-drop state.</para> <para>The next change is to add a <constant>SEL_MOTION</constant> handler, to handle mouse motion events during the drag operation:</para> - <programlisting format="linespecific">@canvas.connect(SEL_MOTION) { |sender, sel, event| + <programlisting format="linespecific">@canvas.connect(SEL_MOTION) do |sender, sel, event| if @canvas.dragging? @canvas.handleDrag(event.root_x, event.root_y) unless @canvas.didAccept == DRAG_REJECT @@ -472,23 +468,23 @@ end @canvas.dragCursor = getApp().getDefaultCursor(DEF_DNDSTOP_CURSOR) end end -} +end </programlisting> <para>The <methodname>dragging?</methodname> method returns true if we're in the middle of a drag-and-drop operation for the drag source window, - i.e. after the call to <methodname>beginDrag()</methodname> but before the - call to <methodname>endDrag()</methodname>. If we're not currently + i.e. after the call to <methodname>beginDrag</methodname> but before the + call to <methodname>endDrag</methodname>. If we're not currently processing a drag operation, we're not really interested in mouse motion events for the canvas.</para> <para>If we <emphasis>are</emphasis> processing a drag operation, however, - we need to call <methodname>handleDrag()</methodname> on the drag source + we need to call <methodname>handleDrag</methodname> on the drag source window. FOX uses this information to send drag-and-drop messages (such as <constant>SEL_DND_ENTER</constant>, <constant>SEL_DND_MOTION</constant> and <constant>SEL_DND_LEAVE</constant>) to the window that the mouse is currently over. Note that the coordinates passed to - <methodname>handleDrag()</methodname> are root window coordinates, and not + <methodname>handleDrag</methodname> are root window coordinates, and not window-local coordinates.</para> <para>Another good thing to consider doing here is to change the shape of @@ -530,16 +526,16 @@ end <para>The last (and most important) step is to actually complete the data transfer. At any time during a drag-and-drop operation, a drop site may request a copy of the drag-and-drop data by calling the - <methodname>getDNDData()</methodname> method (as described in the previous + <methodname>getDNDData</methodname> method (as described in the previous section). When this happens, FOX sends a <constant>SEL_DND_REQUEST</constant> message to the current drag source window, and so we now add a handler for that message:</para> - <programlisting format="linespecific">@canvas.connect(SEL_DND_REQUEST) { |sender, sel, event| + <programlisting format="linespecific">@canvas.connect(SEL_DND_REQUEST) do |sender, sel, event| if event.target == FXWindow.colorType @canvas.setDNDData(FROM_DRAGNDROP, FXWindow.colorType, Fox.fxencodeColorData(@canvas.backColor)) end -} +end </programlisting> <para>The first important thing to note here is that the @@ -553,8 +549,8 @@ end <para>Assuming that the drag type is as expected, the last step is send the data to the drop site by calling - <methodname>setDNDData()</methodname>. As with the call to - <methodname>getDNDData()</methodname> for our previous drop site program, + <methodname>setDNDData</methodname>. As with the call to + <methodname>getDNDData</methodname> for our previous drop site program, you want to be sure to specify the origin of the data (<constant>FROM_DRAGNDROP</constant>), the drag type (<constant>FXWindow.colorType</constant>) and the data itself as a binary @@ -569,30 +565,29 @@ end <filename class="directory">examples</filename> directory under the file name <filename>dragsource.rb</filename>.</para> - <programlisting format="linespecific">require 'rubygems' -require_gem 'fxruby' + <programlisting format="linespecific">require 'fox16' include Fox class DragSource < FXMainWindow def initialize(anApp) # Initialize base class - super(anApp, "Drag Source", nil, nil, DECOR_ALL, 0, 0, 400, 300) + super(anApp, "Drag Source", :opts => DECOR_ALL, :width => 400, :height => 300) # Fill main window with canvas - @canvas = FXCanvas.new(self, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y) + @canvas = FXCanvas.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y) @canvas.backColor = "red" # Handle expose events on the canvas - @canvas.connect(SEL_PAINT) { |sender, sel, event| - FXDCWindow.new(@canvas, event) { |dc| + @canvas.connect(SEL_PAINT) do |sender, sel, event| + FXDCWindow.new(@canvas, event) do |dc| dc.foreground = @canvas.backColor dc.fillRectangle(event.rect.x, event.rect.y, event.rect.w, event.rect.h) - } - } + end + end # Handle left button press - @canvas.connect(SEL_LEFTBUTTONPRESS) { + @canvas.connect(SEL_LEFTBUTTONPRESS) do # # Capture (grab) the mouse when the button goes down, so that all future # mouse events will be reported to this widget, even if those events occur @@ -603,10 +598,10 @@ class DragSource < FXMainWindow # Advertise which drag types we can offer dragTypes = [FXWindow.colorType] @canvas.beginDrag(dragTypes) - } + end # Handle mouse motion events - @canvas.connect(SEL_MOTION) { |sender, sel, event| + @canvas.connect(SEL_MOTION) do |sender, sel, event| if @canvas.dragging? @canvas.handleDrag(event.root_x, event.root_y) unless @canvas.didAccept == DRAG_REJECT @@ -615,20 +610,20 @@ class DragSource < FXMainWindow @canvas.dragCursor = getApp().getDefaultCursor(DEF_DNDSTOP_CURSOR) end end - } + end # Handle left button release - @canvas.connect(SEL_LEFTBUTTONRELEASE) { + @canvas.connect(SEL_LEFTBUTTONRELEASE) do @canvas.ungrab @canvas.endDrag - } + end # Handle request for DND data - @canvas.connect(SEL_DND_REQUEST) { |sender, sel, event| + @canvas.connect(SEL_DND_REQUEST) do |sender, sel, event| if event.target == FXWindow.colorType @canvas.setDNDData(FROM_DRAGNDROP, FXWindow.colorType, Fox.fxencodeColorData(@canvas.backColor)) end - } + end end def create @@ -671,7 +666,7 @@ end <itemizedlist> <listitem> - <para>A call to <methodname>dropEnable()</methodname>, to make + <para>A call to <methodname>dropEnable</methodname>, to make <classname>DragSource</classname>'s canvas drop-enabled;</para> </listitem> @@ -702,33 +697,32 @@ end <filename class="directory">examples</filename> directory under the file name <filename>dragdrop.rb</filename>.</para> - <programlisting format="linespecific">require 'rubygems' -require_gem 'fxruby' + <programlisting format="linespecific">require 'fox16' include Fox class DragDropWindow < FXMainWindow def initialize(anApp) # Initialize base class - super(anApp, "Drag and Drop", nil, nil, DECOR_ALL, 0, 0, 400, 300) + super(anApp, "Drag and Drop", :opts => DECOR_ALL, :width => 400, :height => 300) # Fill main window with canvas - @canvas = FXCanvas.new(self, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y) + @canvas = FXCanvas.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y) @canvas.backColor = "red" # Enable canvas for drag-and-drop messages @canvas.dropEnable # Handle expose events on the canvas - @canvas.connect(SEL_PAINT) { |sender, sel, event| - FXDCWindow.new(@canvas, event) { |dc| + @canvas.connect(SEL_PAINT) do |sender, sel, event| + FXDCWindow.new(@canvas, event) do |dc| dc.foreground = @canvas.backColor dc.fillRectangle(event.rect.x, event.rect.y, event.rect.w, event.rect.h) - } - } + end + end # Handle left button press - @canvas.connect(SEL_LEFTBUTTONPRESS) { + @canvas.connect(SEL_LEFTBUTTONPRESS) do # # Capture (grab) the mouse when the button goes down, so that all future # mouse events will be reported to this widget, even if those events occur @@ -739,10 +733,10 @@ class DragDropWindow < FXMainWindow # Advertise which drag types we can offer dragTypes = [FXWindow.colorType] @canvas.beginDrag(dragTypes) - } + end # Handle mouse motion events - @canvas.connect(SEL_MOTION) { |sender, sel, event| + @canvas.connect(SEL_MOTION) do |sender, sel, event| if @canvas.dragging? @canvas.handleDrag(event.root_x, event.root_y) unless @canvas.didAccept == DRAG_REJECT @@ -751,37 +745,37 @@ class DragDropWindow < FXMainWindow @canvas.dragCursor = getApp().getDefaultCursor(DEF_DNDSTOP_CURSOR) end end - } + end # Handle SEL_DND_MOTION messages from the canvas - @canvas.connect(SEL_DND_MOTION) { + @canvas.connect(SEL_DND_MOTION) do if @canvas.offeredDNDType?(FROM_DRAGNDROP, FXWindow.colorType) @canvas.acceptDrop end - } + end # Handle left button release - @canvas.connect(SEL_LEFTBUTTONRELEASE) { + @canvas.connect(SEL_LEFTBUTTONRELEASE) do @canvas.ungrab @canvas.endDrag - } + end # Handle SEL_DND_DROP message from the canvas - @canvas.connect(SEL_DND_DROP) { + @canvas.connect(SEL_DND_DROP) do # Try to obtain the data as color values first data = @canvas.getDNDData(FROM_DRAGNDROP, FXWindow.colorType) unless data.nil? # Update canvas background color @canvas.backColor = Fox.fxdecodeColorData(data) end - } + end # Handle request for DND data - @canvas.connect(SEL_DND_REQUEST) { |sender, sel, event| + @canvas.connect(SEL_DND_REQUEST) do |sender, sel, event| if event.target == FXWindow.colorType @canvas.setDNDData(FROM_DRAGNDROP, FXWindow.colorType, Fox.fxencodeColorData(@canvas.backColor)) end - } + end end def create diff --git a/doc/gems.xml b/doc/gems.xml index 4df9d22096a2deb517631fb2c7f40ea303849c61..b9db6166f66a3f6415b117267d5ab6234ea61d4c 100755 --- a/doc/gems.xml +++ b/doc/gems.xml @@ -5,9 +5,9 @@ <simplesect> <title>Introduction</title> - <para>Starting with FXRuby version 1.2, FXRuby uses <ulink - url="http://rubygems.rubyforge.org">RubyGems</ulink> as its packaging and - distribution method. The code is available both as</para> + <para>FXRuby uses <ulink + url="http://rubygems.rubyforge.org">RubyGems</ulink> as its preferred + packaging and distribution method. The code is available both as</para> <itemizedlist mark="bullet"> <listitem> @@ -28,7 +28,7 @@ <para>If you've already downloaded the source gem, you can install it by typing:</para> - <screen>$ <command>sudo gem install fxruby-1.6.0.gem</command></screen> + <screen>$ <command>sudo gem install fxruby-1.6.13.gem</command></screen> <para>Note the use of the <command>sudo</command> command to invoke superuser privileges, since you'll typically need superuser privileges to @@ -39,12 +39,12 @@ under some other directory (for example, in your home directory) you might need to pass some additional arguments on the command line, e.g.</para> - <screen>$ <command>sudo gem install fxruby-1.6.0.gem --force -- --with-fox-include=/home/lyle/include/fox-1.6 --with-fox-lib=/home/lyle/lib</command></screen> + <screen>$ <command>sudo gem install fxruby-1.6.13.gem --force -- --with-fox-include=/home/lyle/include/fox-1.6 --with-fox-lib=/home/lyle/lib</command></screen> <para>If you're installing a source gem on a Windows box, you'd instead type something like:</para> - <screen>C:\> <command>gem install fxruby-1.6.0.gem --force -- --with-fox-include=C:\include\fox-1.6 --with-fox-lib=C:\lib</command></screen> + <screen>C:\> <command>gem install fxruby-1.6.13.gem --force -- --with-fox-include=C:\include\fox-1.6 --with-fox-lib=C:\lib</command></screen> <para>If you're installing a source gem, it can take quite awhile to build FXRuby, so this might be a good time to take a coffee break. You won't see @@ -75,7 +75,7 @@ true</screen> <para>To install a binary gem for Windows, just type:</para> - <screen>C:\> <command>gem install fxruby-1.6.0-mswin32.gem</command></screen> + <screen>C:\> <command>gem install fxruby-1.6.13-mswin32.gem</command></screen> <para>As a quick sanity check, to make sure that all is well, you should probably fire up <filename>irb</filename> and try to require the FXRuby @@ -115,8 +115,8 @@ true</screen> the error message will look something like:</para> <screen>$ <command>irb</command> -irb(main):001:0> <userinput>require 'fox'</userinput> -LoadError: libFOX-0.99.so.173: cannot open shared object file: No such file or directory - /usr/local/lib/ruby/1.8/i686-linux/fox.so +irb(main):001:0> <userinput>require 'fox16'</userinput> +LoadError: libFOX-1.6.so: cannot open shared object file: No such file or directory - /usr/local/lib/ruby/1.8/i686-linux/fox16.so from (irb):1:in 'require' from (irb):1 </screen> @@ -145,7 +145,7 @@ irb(main):001:0> <userinput>require 'fox16'</userinput> <orderedlist numeration="arabic" spacing="compact"> <listitem> <para>Edit your <filename>/etc/ld.so.conf</filename> file and add the - directory where <filename>libFOX.so</filename> is installed; + directory where <filename>libFOX-1.6.so</filename> is installed; and,</para> </listitem> @@ -155,4 +155,4 @@ irb(main):001:0> <userinput>require 'fox16'</userinput> </listitem> </orderedlist> </simplesect> -</chapter> +</chapter> \ No newline at end of file diff --git a/doc/goals.xml b/doc/goals.xml index 6bdfb9da1fb6db8a9659c44ff78629f554e502ab..8d79c9e9c8fe02450e92c406d23c69b79ed6336e 100755 --- a/doc/goals.xml +++ b/doc/goals.xml @@ -16,7 +16,7 @@ of its maturity and availability on a number of platforms (including the Macintosh). But Tk is also showing its age in many ways and it has failed to keep pace with some of the "younger" cross-platform GUI toolkits like - FOX, wxWindows, FLTK, Qt and GTK+. Of the latter five, only Qt and GTK+ + FOX, wxWidgets, FLTK, Qt and GTK+. Of the latter five, only Qt and GTK+ appeared (at the time) to have usable Ruby interfaces and there are some problems associated with these as well; for Qt, it's the restrictive license for the Windows platform version, and for GTK+ it's a Windows @@ -41,11 +41,18 @@ Ruby Developer's Guide</citetitle> and <citetitle pubwork="book">The Ruby Way</citetitle>) feature FXRuby as a Ruby GUI development option.</para> </listitem> + <listitem><para>FXRuby is used as the GUI for <ulink url="http://freeride.rubyforge.org/wiki/wiki.pl"> + FreeRIDE</ulink> and a number of other Ruby-based projects.</para></listitem> </itemizedlist> <para>Most recently, work has focused on keeping FXRuby up-to-date with the still evolving FOX library while looking for new ways to make Ruby GUI - development fun. For example, FXRuby is under consideration for use as a - GUI front-end to the fledgling <ulink url="http://freeride.rubyforge.org/wiki/wiki.pl"> - FreeRIDE</ulink> project. If you have suggestions about where you'd like to + development fun. If you have suggestions about where you'd like to see things go, feel free to drop me an e-mail.</para> + <simplesect> + <title>About this Document</title> + <para>The contents of this document were written using <ulink url="http://docbook.org/whatis">DocBook</ulink> version 5.0. + The HTML version of this document uses the CSS stylesheet originally developed for the + HTML version of the book <ulink url="http://svnbook.red-bean.com/">Version Control with Subversion</ulink>, + which is licensed under the <ulink url="http://creativecommons.org/licenses/by/2.0/">Creative Commons Attribution License</ulink>.</para> + </simplesect> </preface> diff --git a/doc/infosources.xml b/doc/infosources.xml index 27dcbc1fe307ff911917447abb61a871102083f2..6fb8ec15247e85b86f3a1be0d7961ee3674066ff 100755 --- a/doc/infosources.xml +++ b/doc/infosources.xml @@ -67,7 +67,7 @@ <para>The fxruby-users@rubyforge.org mailing list is a higher-volume list for FXRuby-related discussions. To subscribe to this list, follow the instructions at <ulink - url="http://rubyforge.org/mailman/listinfo/fxruby-announce">http://rubyforge.org/mailman/listinfo/fxruby-announce</ulink></para> + url="http://rubyforge.org/mailman/listinfo/fxruby-users">http://rubyforge.org/mailman/listinfo/fxruby-users</ulink></para> </listitem> <listitem> @@ -85,10 +85,10 @@ </listitem> <listitem> - <para>The ruby-talk@ruby-lang.org mailing list (or its mirror, the + <para>The Ruby-Talk mailing list (or its mirror, the comp.lang.ruby newsgroup) is a high-volume list for Ruby-related discussions. To subscribe to this list, follow the instructions at - <ulink url="http://www.ruby-lang.org/en/ml.html">http://www.ruby-lang.org/en/ml.html</ulink></para> + <ulink url="http://www.ruby-lang.org/en/community/mailing-lists/">http://www.ruby-lang.org/en/community/mailing-lists/</ulink></para> </listitem> </itemizedlist> </simplesect> diff --git a/doc/scintilla.xml b/doc/scintilla.xml index 324dce05ca25f30370f5b20051c0bad2b749157e..2b515056d11bf6164f0dd2e9bdd26aeb00dd7e7e 100755 --- a/doc/scintilla.xml +++ b/doc/scintilla.xml @@ -16,10 +16,10 @@ <para><ulink url="http://savannah.gnu.org/projects/fxscintilla">FXScintilla </ulink> is a FOX widget that wraps around the Scintilla component, or, if you wish, - the FOX "port" of Scintilla. It is being developed by Gilles Filippini, + the FOX "port" of Scintilla. Until recently it was developed by Gilles Filippini, and as of this writing the latest release is available for download from <ulink - url="http://savannah.nongnu.org/download/fxscintilla/fxscintilla-1.63.tar.gz">http://savannah.nongnu.org/download/fxscintilla/fxscintilla-1.63.tar.gz</ulink>.</para> + url="http://download.savannah.gnu.org/releases/fxscintilla/fxscintilla-1.71.tar.gz">http://download.savannah.gnu.org/releases/fxscintilla/fxscintilla-1.71.tar.gz</ulink>.</para> </simplesect> <simplesect> @@ -30,7 +30,7 @@ applications. That is to say, you do not have to separately download the Scintilla source code from the Scintilla home page. When you unpack the FXScintilla tarball, you should get a new <filename class="directory"> - fxscintilla-1.63</filename> directory containing the source code for the + fxscintilla-1.71</filename> directory containing the source code for the FOX port of the Scintilla widget.</para> <para>As of the 1.46 release of FXScintilla, the build process has been @@ -61,13 +61,13 @@ typing:</para> <screen> -$ <command>sudo gem install fxruby-1.2.0.gem --force -- --with-fxscintilla-include=/usr/local/include/fxscintilla --with-fxscintilla-lib=/usr/local/lib</command> +$ <command>sudo gem install fxruby-1.6.7.gem --force -- --with-fxscintilla-include=/usr/local/include/fxscintilla --with-fxscintilla-lib=/usr/local/lib</command> </screen> <para>or, when compiling with Microsoft Visual C++, by typing:</para> <screen> -C:\> <command>gem install fxruby-1.2.0.gem --force -- --with-fox-include=C:\fox-1.2.7\include --with-fox-lib=C:\fox-1.2.7\lib --with-fxscintilla-include=C:\fxscintilla-1.63\include --with-fxscintilla-lib=C:\fxscintilla-1.63\lib</command> +C:\> <command>gem install fxruby-1.6.7.gem --force -- --with-fox-include=C:\fox-1.6.25\include --with-fox-lib=C:\fox-1.6.25\lib --with-fxscintilla-include=C:\fxscintilla-1.71\include --with-fxscintilla-lib=C:\fxscintilla-1.71\lib</command> </screen> <para>Past this point, the build and installation process for either diff --git a/doc/style.css b/doc/style.css index 97f9605441e29726f7d02a8935df6f8d37ccd3f8..a584e5d2ff6593c575ec5a539966a0d28f7f790f 100644 --- a/doc/style.css +++ b/doc/style.css @@ -1,3 +1,247 @@ -pre.programlisting { background-color: #E0E0E0; } -pre.screen { background-color: #E0E0E0; } +/************************************************************************/ +/* Custom style-sheet stuffs for the Subversion book in HTML form. */ +/************************************************************************/ +/* + * Copyright (c) 2003-2007 + * Ben Collins-Sussman, Brian W. Fitzpatrick, C. Michael Pilato. + * + * This work is licensed under the Creative Commons Attribution License. + * To view a copy of this license, visit + * http://creativecommons.org/licenses/by/2.0/ or send a letter to + * Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, + * USA. + */ + +body +{ + background: white; + margin: 0.5in; + font-family: arial,helvetica,sans-serif; +} + +p, li, ul, ol, dd, dt +{ + font-style: normal; + font-weight: normal; + color: black; +} + +tt, pre +{ + font-family: courier new,courier,fixed; +} + +a +{ + color: blue; + text-decoration: underline; +} + +a:hover +{ + background: rgb(75%,75%,100%); + color: blue; + text-decoration: underline; +} + +a:visited +{ + color: purple; + text-decoration: underline; +} + +img +{ + border: none; +} + +h1.title +{ + font-size: 250%; + font-style: normal; + font-weight: bold; + color: black; +} + +h2.subtitle +{ + font-size: 150%; + font-style: italic; + color: black; +} + +h2.title +{ + font-size: 150%; + font-style: normal; + font-weight: bold; + color: black; +} + +h3.title +{ + font-size: 125%; + font-style: normal; + font-weight: bold; + color: black; +} + +h4.title +{ + font-size: 100%; + font-style: normal; + font-weight: bold; + color: black; +} + +.toc b +{ + font-size: 125%; + font-style: normal; + font-weight: bold; + color: black; +} + +.command, .screen, .programlisting, .structname +{ + font-family: courier new,courier,fixed; + font-style: normal; + font-weight: normal; +} + +.filename +{ + font-family: arial,helvetica,sans-serif; + font-style: italic; +} + +.figure, .example, .table +{ + margin: 0.125in 0.25in; +} + +.table table +{ + border-width: 1px; + border-style: solid; + border-color: black; + border-spacing: 0; + background: rgb(240,240,240); +} + +.table td +{ + border: none; + border-right: 1px black solid; + border-bottom: 1px black solid; + padding: 2px; +} + +.table th +{ + background: rgb(180,180,180); + border: none; + border-right: 1px black solid; + border-bottom: 1px black solid; + padding: 2px; +} + +.table p.title, .figure p.title, .example p.title +{ + text-align: left !important; + font-size: 100% !important; +} + +.author, .pubdate +{ + margin: 0; + font-size: 100%; + font-style: italic; + font-weight: normal; + color: black; +} + +.preface div.author, .preface .pubdate +{ + font-size: 80%; +} + +.sidebar +{ + border-top: dotted 1px black; + border-left: dotted 1px black; + border-right: solid 2px black; + border-bottom: solid 2px black; + background: rgb(240,220,170); + padding: 0 0.12in; + margin: 0.25in; +} + +.note .programlisting, .note .screen, +.tip .programlisting, .tip .screen, +.warning .programlisting, .warning .screen, +.sidebar .programlisting, .sidebar .screen +{ + border: none; + background: none; +} + +.sidebar p.title +{ + text-align: center; + font-size: 125%; +} + +.note +{ + border: black solid 1px; + background: url(./images/note.png) no-repeat rgb(252,246,220); + margin: 0.125in 0; + padding: 0 55px; +} + +.tip +{ + border: black solid 1px; + background: url(./images/tip.png) no-repeat rgb(224,244,255); + margin: 0.125in 0; + padding: 0 55px; +} + +.warning +{ + border: black solid 1px; + background: url(./images/warning.png) no-repeat rgb(255,210,210); + margin: 0.125in 0; + padding: 0 55px; +} + +.note .title, .tip .title, .warning .title +{ + display: none; +} + +.programlisting, .screen +{ + font-size: 90%; + color: black; + margin: 1em 0.25in; + padding: 0.5em; + background: rgb(240,240,240); + border-top: black dotted 1px; + border-left: black dotted 1px; + border-right: black solid 2px; + border-bottom: black solid 2px; +} + +.navheader, .navfooter +{ + border: black solid 1px; + background: rgb(180,180,200); +} + +.navheader hr, .navfooter hr +{ + display: none; +} diff --git a/examples/WhatAQuietStiff.rb b/examples/WhatAQuietStiff.rb index 1d5f3802bc35e5bc8cdcac5cd41f18d19ed321ef..35b504cc983e02e55fdd38e2272d3f592dda9f6f 100755 --- a/examples/WhatAQuietStiff.rb +++ b/examples/WhatAQuietStiff.rb @@ -11,7 +11,6 @@ # require 'fox16' -require 'fox16/kwargs' require 'open-uri' begin diff --git a/examples/babelfish.rb b/examples/babelfish.rb index 79527f76c7f8b302f8a3bfbe5d0a042c9062e7cb..81b4d2b4471eb8249b975a13366c495d1b58d74f 100755 --- a/examples/babelfish.rb +++ b/examples/babelfish.rb @@ -1,57 +1,41 @@ #!/usr/bin/env ruby require 'fox16' -require 'fox16/kwargs' -require 'soap/rpc/driver' +require 'tranexp' include Fox TRANSLATIONS = { - "English to French" => "en_fr", - "English to German" => "en_de", - "English to Italian" => "en_it", - "English to Japanese" => "en_jp", - "English to Korean" => "en_kr", - "English to Portugese" => "en_pt", - "English to Spanish" => "en_es", - "French to English" => "fr_en", - "German to English" => "de_en", - "Italian to English" => "it_en", - "Japanese to English" => "jp_en", - "Korean to English" => "kr_en", - "Portugese to English" => "pt_en", - "Spanish to English" => "es_en", - "Russian to English" => "ru_en", - "German to French" => "de_fr", - "French to German" => "fr_de" + "x" => "y" } class Babelfish < FXMainWindow def initialize(app) # Invoke base class initialize first - super(app, "Babelfish", nil, nil, DECOR_ALL, - 0, 0, 600, 400, 0, 0) - - # Initialize the SOAP driver - @drv = SOAP::RPC::Driver.new('http://services.xmethods.net/perl/soaplite.cgi', 'urn:xmethodsBabelFish') - @drv.add_rpc_method_with_soapaction('BabelFish', - 'urn:xmethodsBabelFish#BabelFish', 'translationmode', 'sourcedata') + super(app, "Babelfish", :opts => DECOR_ALL, :width => 600, :height => 400) + @translator = Tranexp::Http.new + # Controls area along the bottom controlsFrame = FXHorizontalFrame.new(self, LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X) FXLabel.new(controlsFrame, "Translate from:") - @transModeCombo = FXComboBox.new(controlsFrame, 15, :opts => COMBOBOX_STATIC|FRAME_SUNKEN|FRAME_THICK) - @transModeCombo.numVisible = 6 - TRANSLATIONS.keys.each do |key| - @transModeCombo.appendItem(key, TRANSLATIONS[key]) + @fromCombo = FXComboBox.new(controlsFrame, 15, :opts => COMBOBOX_STATIC|FRAME_SUNKEN|FRAME_THICK) + @fromCombo.numVisible = 6 + FXLabel.new(controlsFrame, " to:") + @toCombo = FXComboBox.new(controlsFrame, 15, :opts => COMBOBOX_STATIC|FRAME_SUNKEN|FRAME_THICK) + @toCombo.numVisible = 6 + Tranexp::Codes.constants.each do |lang| + @fromCombo.appendItem(lang) + @toCombo.appendItem(lang) end - btn = FXButton.new(controlsFrame, "Translate", :opts => BUTTON_NORMAL|LAYOUT_SIDE_RIGHT) + btn = FXButton.new(controlsFrame, "Translate", :opts => BUTTON_NORMAL|LAYOUT_RIGHT) btn.connect(SEL_COMMAND) do - transMode = @transModeCombo.getItemData(@transModeCombo.currentItem) + from = @fromCombo.getItemText(@fromCombo.currentItem) + to = @toCombo.getItemText(@toCombo.currentItem) getApp().beginWaitCursor() do - @translatedText.text = @drv.BabelFish(transMode, @sourceText.text) + @translatedText.text = @translator.translate(@sourceText.text, from, to) end end @@ -80,15 +64,9 @@ class Babelfish < FXMainWindow end if __FILE__ == $0 - # Make application - application = FXApp.new("Babelfish", "FoxTest") - - # Make window - window = Babelfish.new(application) - - # Create it - application.create - - # Run - application.run + FXApp.new("Babelfish", "FoxTest") do |app| + Babelfish.new(app) + app.create + app.run + end end diff --git a/examples/bounce.rb b/examples/bounce.rb index 44cab454f58d9d187b1246933efeb114b7c69e00..f93cf95757eaa19f188d68077cb11c191f354d0a 100755 --- a/examples/bounce.rb +++ b/examples/bounce.rb @@ -1,5 +1,4 @@ require 'fox16' -require 'fox16/kwargs' include Fox diff --git a/examples/button.rb b/examples/button.rb index 149d6acec01f0b077404e193cf3fda71f2e5e1ed..0da7e8815d4a17e95423c4bfb998a019ed29d49d 100755 --- a/examples/button.rb +++ b/examples/button.rb @@ -1,7 +1,6 @@ #/usr/bin/env ruby require 'fox16' -require 'fox16/kwargs' include Fox diff --git a/examples/charts.rb b/examples/charts.rb new file mode 100644 index 0000000000000000000000000000000000000000..dfb42d40cebe7d59744ce70897a3048346d83b93 --- /dev/null +++ b/examples/charts.rb @@ -0,0 +1,35 @@ +require 'fox16' +require 'google_chart' +require 'open-uri' + +include Fox + +class ChartsWindow < FXMainWindow + def initialize(app) + super(app, "Google Charts Demo", :width => 650, :height => 250) + FXImageFrame.new(self, nil, :opts => LAYOUT_FILL) do |f| + f.image = FXPNGImage.new(app, open(bar_chart.to_escaped_url, "rb").read) + end + end + + def bar_chart + GoogleChart::BarChart.new('600x200', 'My Chart', :vertical) do |bc| + bc.data 'Trend 1', [5,4,3,1,3,5], '0000ff' + bc.data 'Trend 2', [1,2,3,4,5,6], 'ff0000' + bc.data 'Trend 3', [6,5,4,4,5,6], '00ff00' + end + end + + def create + super + show(PLACEMENT_SCREEN) + end +end + +if __FILE__ == $0 + FXApp.new do |app| + ChartsWindow.new(app) + app.create + app.run + end +end \ No newline at end of file diff --git a/examples/custom_table_item.rb b/examples/custom_table_item.rb new file mode 100644 index 0000000000000000000000000000000000000000..acbf7cbec85d9a0df2986d886263227afcc57889 --- /dev/null +++ b/examples/custom_table_item.rb @@ -0,0 +1,170 @@ +require 'fox16' + +include Fox + +class CustomTableItem < FXTableItem + def drawContent(table, dc, x, y, w, h) + puts "in drawContent()" + hg = table.horizontalGridShown? + vg = table.verticalGridShown? + ml = table.marginLeft + (vg ? 1 : 0) + mt = table.marginTop + (hg ? 1 : 0) + mr = table.marginRight + mb = table.marginBottom + font = dc.font + lbl = text + icn = icon + + # Text width and height + beg, tw, th = 0, 0, 0 + begin + _end = beg; + _end += 1 while _end < lbl.length && lbl[_end].chr != '\n' + t = font.getTextWidth(lbl[beg..._end]) + tw = t if t > tw + th += font.fontHeight + beg = _end + 1 + end while _end < lbl.length + + # Icon size + iw, ih = 0, 0 + unless icn.nil? + iw = icn.width + ih = icn.height + end + + # Icon-text spacing + s = 0 + s = 4 if (iw > 0 && tw > 0) + + # Fix x coordinate + if justify & LEFT == 1 + case iconPosition + when BEFORE + ix = x + ml + tx = ix + iw + s + when AFTER + tx = x + ml + ix = tx + tw + s + else + ix = x + ml + tx = x + ml + end + elsif justify & RIGHT == 1 + case iconPosition + when BEFORE + tx = x + w - mr - tw + ix = tx - iw - s + when AFTER + ix = x + w - mr - iw + tx = ix - tw - s + else + ix = x + w - mr - iw + tx = x + w - mr - tw + end + else + case iconPosition + when BEFORE + ix = x + (ml + w - mr)/2 - (tw + iw + s)/2 + tx = ix + iw + s + when AFTER + tx = x + (ml + w - mr)/2 - (tw + iw + s)/2 + ix = tx + tw + s + else + ix = x + (ml + w - mr)/2 - iw/2 + tx = x + (ml + w - mr)/2 -tw/2 + end + end + + # Fix y coordinate + if justify & TOP == 1 + case iconPosition + when ABOVE + iy = y + mt + ty = iy + ih + when BELOW + ty = y + mt + iy = ty + th + else + iy = y + mt + ty = y + mt + end + elsif justify & BOTTOM == 1 + case iconPosition + when ABOVE + ty = y + h - mb - th + iy = ty - ih + when BELOW + iy = y + h - mb - ih + ty = iy - th + else + iy = y + h - mb - ih + ty = y + h - mb - th + end + else + case iconPosition + when ABOVE + iy = y + (mt + h - mb)/2 - (th + ih)/2 + ty = iy + ih + when BELOW + ty = y + (mt + h - mb)/2 - (th + ih)/2 + iy = ty + th + else + iy = y + (mt + h - mb)/2 - ih/2 + ty = y + (mt + h - mb)/2 - th/2 + end + end + + # Paint icon + dc.drawIcon(icn, ix, iy) unless icn.nil? + + # Text color + if selected? + dc.foreground = table.selTextColor + else + dc.foreground = table.textColor + end + puts "dc.foreground = (#{FXREDVAL(dc.foreground)}, #{FXGREENVAL(dc.foreground)}, #{FXBLUEVAL(dc.foreground)})" + + # Draw text + yy = ty + font.fontAscent + beg = 0 + begin + _end = beg + _end += 1 while _end < lbl.length && lbl[_end].chr != '\n' + if justify & LEFT == 1 + xx = tx + elsif justify & RIGHT == 1 + xx = tx + tw - font.getTextWidth(lbl[beg..._end]) + else + xx = tx + (tw - font.getTextWidth(lbl[beg..._end]))/2 + end + dc.drawText(xx, yy, lbl[beg..._end]) + yy += font.fontHeight + beg = _end + 1 + end while _end < lbl.length + end +end + +class CustomTable < FXTable + def createItem *parameters + CustomTableItem.new *parameters + end +end + +app = FXApp.new +main = FXMainWindow.new app, 'Test' + +table = CustomTable.new main +table.setTableSize 2, 2 +table.visibleRows = 2 +table.visibleColumns = 2 + +table.setItemText 0, 0, 'one' +table.setItemText 0, 1, 'two' +table.setItemText 1, 0, 'three' +table.setItemText 1, 1, 'four' + +app.create +main.show PLACEMENT_SCREEN +app.run diff --git a/examples/datatarget.rb b/examples/datatarget.rb index b49f5094d4ff39db3be5eab278b7d07c5291dc3b..816ce42a53fe8386567d45db6a6d69fa9201e18e 100755 --- a/examples/datatarget.rb +++ b/examples/datatarget.rb @@ -2,7 +2,6 @@ require 'fox16' require 'fox16/colors' -require 'fox16/kwargs' include Fox diff --git a/examples/dialog.rb b/examples/dialog.rb index 33e841e70fe0825e0acf20a4cafc66e8db40ec64..c352c0d345b54aa4675247b6bf88bb1e184653f8 100755 --- a/examples/dialog.rb +++ b/examples/dialog.rb @@ -1,7 +1,6 @@ #!/usr/bin/env ruby require 'fox16' -require 'fox16/kwargs' include Fox diff --git a/examples/dilbert.rb b/examples/dilbert.rb index aafd5ac3ba4f4e13b9b1041b2377bedd14fbb717..955c6be81723ddec36eb1ea762537f100a7f6f94 100755 --- a/examples/dilbert.rb +++ b/examples/dilbert.rb @@ -1,16 +1,15 @@ #!/usr/bin/env ruby require 'fox16' -require 'fox16/kwargs' require 'open-uri' begin - require 'rubyful_soup' + require 'hpricot' rescue LoadError require 'fox16/missingdep' MSG = <<EOM - Sorry, this example depends on the RubyfulSoup extension. Please - check the Ruby Application Archives for an appropriate - download site. + Sorry, this example depends on the Hpricot extension. Please + see http://code.whytheluckystiff.net/hpricot/ for instructions + on how to install Hpricot. EOM missingDependency(MSG) end @@ -41,9 +40,8 @@ class DailyDilbert < FXMainWindow end def image_data - src = open("http://www.dilbert.com/").read - soup = BeautifulSoup.new(src) - url = soup.find('img', { :attrs => { 'alt' => /Today's Comic/ } }) + doc = Hpricot(open("http://www.dilbert.com/")) + url = doc.search("img").find { |e| e['src'] =~ /\/dyn\/str_strip\/.*\.gif/ } open("http://www.dilbert.com" + url['src'], "rb").read end diff --git a/examples/dirlist.rb b/examples/dirlist.rb index d8871df87365048ef633b733052c86f95bfb56be..3c7f38f5bb35cfe70c253f13ae8f39cdafb4bc31 100755 --- a/examples/dirlist.rb +++ b/examples/dirlist.rb @@ -1,7 +1,6 @@ #!/usr/bin/env ruby require 'fox16' -require 'fox16/kwargs' include Fox diff --git a/examples/dragdrop.rb b/examples/dragdrop.rb index fb664b74501e91dc2b2d35ba2ef7530da19ef561..08f0d60bbd1c7286600eb34b4bc68d7d4c79b2d7 100755 --- a/examples/dragdrop.rb +++ b/examples/dragdrop.rb @@ -1,5 +1,4 @@ require 'fox16' -require 'fox16/kwargs' include Fox diff --git a/examples/dragsource.rb b/examples/dragsource.rb index a1c54aa197548129bc7c2696de6e36f1df771eb4..f7406b0139748a88ea1b07a89af4d7e67a2ca58e 100755 --- a/examples/dragsource.rb +++ b/examples/dragsource.rb @@ -1,5 +1,4 @@ require 'fox16' -require 'fox16/kwargs' include Fox diff --git a/examples/dropsite.rb b/examples/dropsite.rb index 070ca0dbefd0a5be871c3a3abd5d824e64853724..fd2ba48898c640b3cd5c197a56fb92164fd38bfd 100755 --- a/examples/dropsite.rb +++ b/examples/dropsite.rb @@ -1,5 +1,4 @@ require 'fox16' -require 'fox16/kwargs' include Fox @@ -7,7 +6,7 @@ class DropSite < FXMainWindow def initialize(anApp) # Initialize base class - super(anApp, "Drop Site",:opts => DECOR_ALL, :width => 400, :height => 300) + super(anApp, "Drop Site", :opts => DECOR_ALL, :width => 400, :height => 300) # Fill main window with canvas @canvas = FXCanvas.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y) diff --git a/examples/foursplit.rb b/examples/foursplit.rb index 80fbd73f7ad70299817948b2639901d5bcb91b65..3761c055c386442ce7be3814a48fe0ed7effce17 100755 --- a/examples/foursplit.rb +++ b/examples/foursplit.rb @@ -1,7 +1,6 @@ #!/usr/bin/env ruby require 'fox16' -require 'fox16/kwargs' include Fox diff --git a/examples/gdchart.rb b/examples/gdchart.rb index 1be7a1b2c936de314093044140cca414ad8481fd..5375826ebab629c2c456bb9ac5c0df8026bc2da1 100755 --- a/examples/gdchart.rb +++ b/examples/gdchart.rb @@ -1,5 +1,4 @@ require 'fox16' -require 'fox16/kwargs' require 'tempfile' begin require 'GDChart' diff --git a/examples/gembrowser.rb b/examples/gembrowser.rb index 14a61f40826c445c1da230751e998fc921f89033..04d9fefaf90729cdd11a12cce243450ea7af3350 100755 --- a/examples/gembrowser.rb +++ b/examples/gembrowser.rb @@ -180,7 +180,7 @@ class GemBrowserWindow < FXMainWindow super(anApp, "Gem Browser", nil, nil, DECOR_ALL) # Menu bar - menubar = FXMenubar.new(self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X) + menubar = FXMenuBar.new(self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X) # File menu filemenu = FXMenuPane.new(self) diff --git a/examples/gltest.rb b/examples/gltest.rb index d36ff5d6e6746563a40666e1101f6886ccb6a7cf..7333c900b6d039436bdabfdcdaf518c077bb063d 100755 --- a/examples/gltest.rb +++ b/examples/gltest.rb @@ -1,7 +1,6 @@ #!/usr/bin/env ruby require 'fox16' -require 'fox16/kwargs' begin require 'opengl' rescue LoadError @@ -22,26 +21,6 @@ class GLTestWindow < FXMainWindow # How often our timer will fire (in milliseconds) TIMER_INTERVAL = 100 - # Rotate the boxes when a timer message is received - def onTimeout(sender, sel, ptr) - @angle += 2.0 - if @angle > 360.0 - @angle -= 360.0 - end - drawScene() - @timer = getApp().addTimeout(TIMER_INTERVAL, method(:onTimeout)) - end - - # Rotate the boxes when a chore message is received - def onChore(sender, sel, ptr) - @angle += 2.0 - if @angle > 360.0 - @angle -= 360.0 - end - drawScene() - @chore = getApp().addChore(method(:onChore)) - end - # Draws a simple box using the given corners def drawBox(xmin, ymin, zmin, xmax, ymax, zmax) GL.Begin(GL::TRIANGLE_STRIP) @@ -251,7 +230,13 @@ class GLTestWindow < FXMainWindow spinTimerBtn.padTop, spinTimerBtn.padBottom = 5, 5 spinTimerBtn.connect(SEL_COMMAND) do @spinning = true - @timer = getApp().addTimeout(TIMER_INTERVAL, method(:onTimeout)) + @timer = getApp().addTimeout(TIMER_INTERVAL, :repeat => true) do + @angle += 2.0 + if @angle > 360.0 + @angle -= 360.0 + end + drawScene() + end end spinTimerBtn.connect(SEL_UPDATE) do |sender, sel, ptr| @spinning ? sender.disable : sender.enable @@ -266,7 +251,13 @@ class GLTestWindow < FXMainWindow spinChoreBtn.padTop, spinChoreBtn.padBottom = 5, 5 spinChoreBtn.connect(SEL_COMMAND) do @spinning = true - @chore = getApp().addChore(method(:onChore)) + @chore = getApp().addChore(:repeat => true) do + @angle += 2.0 + if @angle > 360.0 + @angle -= 360.0 + end + drawScene() + end end spinChoreBtn.connect(SEL_UPDATE) do |sender, sel, ptr| @spinning ? sender.disable : sender.enable diff --git a/examples/glviewer.rb b/examples/glviewer.rb index c2f0ebf08e075823ca4545db0cae2770d141e7c3..6a4c28acf68063905009b3624a1512e2ebba54bb 100755 --- a/examples/glviewer.rb +++ b/examples/glviewer.rb @@ -2,7 +2,6 @@ require 'fox16' require 'fox16/responder' -require 'fox16/kwargs' begin require 'fox16/glshapes' rescue LoadError diff --git a/examples/groupbox.rb b/examples/groupbox.rb index b25beb35193f315457a6c7af4fd6e6e42bb8e944..f988521e6c11cefd0cdcb87b5665f8613c87c362 100755 --- a/examples/groupbox.rb +++ b/examples/groupbox.rb @@ -22,7 +22,7 @@ class GroupWindow < FXMainWindow def initialize(app) # Call the base class version of initialize - super(app, "Group Box Test", nil, nil, DECOR_ALL, 0, 0, 0, 0) + super(app, "Group Box Test", :opts => DECOR_ALL) # Some icons we'll use here and there doc = getIcon("minidoc.png") @@ -102,8 +102,7 @@ class GroupWindow < FXMainWindow FXMenuTitle.new(menubar, "&Help", nil, helpmenu, LAYOUT_RIGHT) @popupmenu = FXMenuPane.new(self) - poptext = FXTextField.new(@popupmenu, 10, nil, 0, - FRAME_SUNKEN|FRAME_THICK|LAYOUT_SIDE_TOP, 0, 0, 0, 0) + poptext = FXTextField.new(@popupmenu, 10, :opts => FRAME_SUNKEN|FRAME_THICK|LAYOUT_SIDE_TOP) poptext.setText("Popup with text") # Status bar @@ -129,8 +128,7 @@ class GroupWindow < FXMainWindow testlabel.setFont(FXFont.new(getApp(), "helvetica", 24, FONTWEIGHT_BOLD, FONTSLANT_ITALIC, FONTENCODING_DEFAULT)) FXButton.new(group1, "Small &Button", nil, nil, 0, FRAME_RAISED|FRAME_THICK) - FXButton.new(group1, "Big Fat Wide Button\nComprising\nthree lines", nil, - nil, 0, FRAME_RAISED|FRAME_THICK) + FXButton.new(group1, "Big Fat Wide Button\nComprising\nthree lines", :opts => FRAME_RAISED|FRAME_THICK) FXToggleButton.new(group1, "C&losed\tTooltip for closed\tHelp for closed", "O&pen\nState\tTooltip for open\tHelp for open", @@ -138,94 +136,66 @@ class GroupWindow < FXMainWindow ICON_BEFORE_TEXT|JUSTIFY_LEFT|FRAME_RAISED|FRAME_THICK) pop = FXPopup.new(self) - - FXOption.new(pop, "First\tTip #1\tHelp first", nil, nil, 0, - JUSTIFY_HZ_APART|ICON_AFTER_TEXT).connect(SEL_COMMAND) { - FXMessageBox.information(self, MBOX_OK, "Option Menu", "Chose option 1") - } - FXOption.new(pop, "Second\tTip #2\tHelp second", nil, nil, 0, - JUSTIFY_HZ_APART|ICON_AFTER_TEXT).connect(SEL_COMMAND) { - FXMessageBox.information(self, MBOX_OK, "Option Menu", "Chose option 2") - } - FXOption.new(pop, "Third\tTip #3\tHelp third", nil, nil, 0, - JUSTIFY_HZ_APART|ICON_AFTER_TEXT).connect(SEL_COMMAND) { - FXMessageBox.information(self, MBOX_OK, "Option Menu", "Chose option 3") - } - FXOption.new(pop, "Fourth\tTip #4\tHelp fourth", nil, nil, 0, - JUSTIFY_HZ_APART|ICON_AFTER_TEXT).connect(SEL_COMMAND) { - FXMessageBox.information(self, MBOX_OK, "Option Menu", "Chose option 4") - } + numbers =%w{first second third fourth} + 0.upto(3) do |idx| + FXOption.new(pop, "#{numbers[idx].capitalize}\tTip #{idx+1}\tHelp #{numbers[idx]}", :opts => JUSTIFY_HZ_APART|ICON_AFTER_TEXT).connect(SEL_COMMAND) { + FXMessageBox.information(self, MBOX_OK, "Option Menu", "Chose option #{idx+1}") + } + end FXOptionMenu.new(group1, pop, LAYOUT_TOP|FRAME_RAISED|FRAME_THICK|JUSTIFY_HZ_APART|ICON_AFTER_TEXT) FXLabel.new(group1, "Te&kstje", nil, LAYOUT_TOP|JUSTIFY_LEFT) FXButton.new(group1, - "Add an `&&' by doubling\tTooltip\tHelp text for status", nil, - nil, 0,LAYOUT_TOP|FRAME_RAISED|FRAME_THICK) - FXButton.new(group1, "Te&kstje", nil, nil, 0, - LAYOUT_TOP|FRAME_RAISED|FRAME_THICK).connect(SEL_COMMAND) { + "Add an `&&' by doubling\tTooltip\tHelp text for status", :opts => LAYOUT_TOP|FRAME_RAISED|FRAME_THICK) + FXButton.new(group1, "Te&kstje", :opts => LAYOUT_TOP|FRAME_RAISED|FRAME_THICK).connect(SEL_COMMAND) { x, y, buttons = getRoot().getCursorPosition() @popupmenu.popup(nil, x, y) } - FXMenuButton.new(group1, "&Menu", nil, filemenu, - (MENUBUTTON_ATTACH_BOTH|MENUBUTTON_DOWN|JUSTIFY_HZ_APART|LAYOUT_TOP| - FRAME_RAISED|FRAME_THICK|ICON_AFTER_TEXT)) - FXMenuButton.new(group1, "&Menu", nil, filemenu, - MENUBUTTON_UP|LAYOUT_TOP|FRAME_RAISED|FRAME_THICK|ICON_AFTER_TEXT) + FXMenuButton.new(group1, "&Menu", :opts => MENUBUTTON_ATTACH_BOTH|MENUBUTTON_DOWN|JUSTIFY_HZ_APART|LAYOUT_TOP|FRAME_RAISED|FRAME_THICK|ICON_AFTER_TEXT) + FXMenuButton.new(group1, "&Menu", nil, filemenu, MENUBUTTON_UP|LAYOUT_TOP|FRAME_RAISED|FRAME_THICK|ICON_AFTER_TEXT) coolpop = FXPopup.new(self, POPUP_HORIZONTAL) - FXButton.new(coolpop, "A\tTipA", nil, nil, 0, - FRAME_THICK|FRAME_RAISED|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, 0, 0, 30, 30) - FXButton.new(coolpop, "B\tTipB", nil, nil, 0, - FRAME_THICK|FRAME_RAISED|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, 0, 0, 30, 30) - FXButton.new(coolpop, "C\tTipC", nil, nil, 0, - FRAME_THICK|FRAME_RAISED|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, 0, 0, 30, 30) - FXButton.new(coolpop, "D\tTipD", nil, nil, 0, - FRAME_THICK|FRAME_RAISED|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, 0, 0, 30, 30) + FXButton.new(coolpop, "A\tTipA", + :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, :width => 30, :height => 30) + FXButton.new(coolpop, "B\tTipB", + :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, :width => 30, :height => 30) + FXButton.new(coolpop, "C\tTipC", + :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, :width => 30, :height => 30) + FXButton.new(coolpop, "D\tTipD", + :opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, :width => 30, :height => 30) FXMenuButton.new(group1, "&S\tSideways", nil, coolpop, (MENUBUTTON_ATTACH_BOTH|MENUBUTTON_LEFT|MENUBUTTON_NOARROWS|LAYOUT_TOP| - FRAME_RAISED|FRAME_THICK|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT), 0, 0, 30, 30) + FRAME_RAISED|FRAME_THICK|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT), :width => 30, :height => 30) matrix = FXMatrix.new(group1, 3, FRAME_RAISED|LAYOUT_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y) - FXButton.new(matrix, "A", nil, nil, 0, - FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FILL_ROW) - FXButton.new(matrix, "&Wide button", nil, nil, 0, - FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X) - FXButton.new(matrix, "A", nil, nil, 0, - FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X) + FXButton.new(matrix, "A", :opts => FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FILL_ROW) + FXButton.new(matrix, "&Wide button", :opts => FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X) + FXButton.new(matrix, "A", :opts => FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X) - FXButton.new(matrix, "BBBB", nil, nil, 0, (FRAME_RAISED|FRAME_THICK| - LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FILL_ROW|LAYOUT_FILL_COLUMN)) - FXButton.new(matrix, "B", nil, nil, 0, - FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN) - FXButton.new(matrix, "BB", nil, nil, 0, - FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN) + FXButton.new(matrix, "BBBB", :opts => FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FILL_ROW|LAYOUT_FILL_COLUMN) + FXButton.new(matrix, "B", :opts => FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN) + FXButton.new(matrix, "BB", :opts => FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN) - FXButton.new(matrix, "C", nil, nil, 0, - FRAME_RAISED|FRAME_THICK|LAYOUT_CENTER_Y|LAYOUT_CENTER_X|LAYOUT_FILL_ROW) - FXButton.new(matrix, "&wide", nil, nil, 0, FRAME_RAISED|FRAME_THICK) - FXButton.new(matrix, "CC", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT) + FXButton.new(matrix, "C", :opts => FRAME_RAISED|FRAME_THICK|LAYOUT_CENTER_Y|LAYOUT_CENTER_X|LAYOUT_FILL_ROW) + FXButton.new(matrix, "&wide", :opts => FRAME_RAISED|FRAME_THICK) + FXButton.new(matrix, "CC", :opts => FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT) FXLabel.new(group2, "No Arrow") - FXSlider.new(group2, nil, 0, - LAYOUT_TOP|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|SLIDER_HORIZONTAL, - 0, 0, 200, 30) + FXSlider.new(group2, :opts => LAYOUT_TOP|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|SLIDER_HORIZONTAL, :width => 200, :height => 30) FXLabel.new(group2, "Up Arrow") - FXSlider.new(group2, nil, 0, (LAYOUT_TOP|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT| - SLIDER_HORIZONTAL|SLIDER_ARROW_UP), 0, 0, 200, 30) + FXSlider.new(group2, :opts => LAYOUT_TOP|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|SLIDER_HORIZONTAL|SLIDER_ARROW_UP, :width => 200, :height => 30) FXLabel.new(group2, "Down Arrow") - FXSlider.new(group2, nil, 0, (LAYOUT_TOP|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT| - SLIDER_HORIZONTAL|SLIDER_ARROW_DOWN), 0, 0, 200, 30) + FXSlider.new(group2, :opts => LAYOUT_TOP|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|SLIDER_HORIZONTAL|SLIDER_ARROW_DOWN, :width => 200, :height => 30) FXLabel.new(group2, "Inside Bar") - slider = FXSlider.new(group2, nil, 0, (LAYOUT_TOP|LAYOUT_FILL_X| - LAYOUT_FIX_HEIGHT|SLIDER_HORIZONTAL|SLIDER_INSIDE_BAR), 0, 0, 200, 20) + slider = FXSlider.new(group2, :opts => LAYOUT_TOP|LAYOUT_FILL_X|LAYOUT_FIX_HEIGHT|SLIDER_HORIZONTAL|SLIDER_INSIDE_BAR, :width => 200, :height => 20) slider.range = 0..3 frame = FXHorizontalFrame.new(group2, LAYOUT_FILL_X|LAYOUT_FILL_Y) @@ -252,8 +222,7 @@ class GroupWindow < FXMainWindow LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_RAISED|FRAME_THICK|ARROW_RIGHT) vframe2 = FXVerticalFrame.new(frame, LAYOUT_FILL_X|LAYOUT_FILL_Y) - FXArrowButton.new(vframe2, nil, 0, (LAYOUT_FILL_X|LAYOUT_FILL_Y| - FRAME_RAISED|FRAME_THICK|ARROW_UP|ARROW_TOOLBAR)) + FXArrowButton.new(vframe2, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_RAISED|FRAME_THICK|ARROW_UP|ARROW_TOOLBAR) FXArrowButton.new(vframe2, nil, 0, (LAYOUT_FILL_X|LAYOUT_FILL_Y| FRAME_RAISED|FRAME_THICK|ARROW_DOWN|ARROW_TOOLBAR)) FXArrowButton.new(vframe2, nil, 0, (LAYOUT_FILL_X|LAYOUT_FILL_Y| diff --git a/examples/header.rb b/examples/header.rb index aaf64f227b85aca622ecc21a86552cad42c1f783..7f448072d95151bcec245fb2b9f8645891e0973e 100755 --- a/examples/header.rb +++ b/examples/header.rb @@ -1,7 +1,6 @@ #!/usr/bin/env ruby require 'fox16' -require 'fox16/kwargs' include Fox diff --git a/examples/iconlist.rb b/examples/iconlist.rb index 6dc8622ceb11cf88424d0255049afe5457305c1f..399ba95b6f8b485a25489080c22c475705daf5a0 100755 --- a/examples/iconlist.rb +++ b/examples/iconlist.rb @@ -1,5 +1,4 @@ require 'fox16' -require 'fox16/kwargs' include Fox diff --git a/examples/image.rb b/examples/image.rb index a6a38e8024b2e85c281aa0aab0f26e180d1114d6..44010364fcd85d6024d549f3cad554248467aa77 100755 --- a/examples/image.rb +++ b/examples/image.rb @@ -2,7 +2,6 @@ require 'fox16' require 'fox16/colors' -require 'fox16/kwargs' include Fox diff --git a/examples/imageviewer.rb b/examples/imageviewer.rb index 3a062d365f1fc12286460d858bbedaa1664c315b..27d23196680b4e14f47547ccb7f248164a9589ea 100755 --- a/examples/imageviewer.rb +++ b/examples/imageviewer.rb @@ -1,7 +1,6 @@ #!/usr/bin/env ruby require 'fox16' -require 'fox16/kwargs' include Fox @@ -87,7 +86,7 @@ class ImageWindow < FXMainWindow # Make file list fileframe = FXHorizontalFrame.new(@filebox, FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y, - :padLeft => 0, :padRight => 0, :padTop => 0, :padBottom => 0. :hSpacing => 0, :vSpacing => 0) + :padLeft => 0, :padRight => 0, :padTop => 0, :padBottom => 0, :hSpacing => 0, :vSpacing => 0) @filelist = FXFileList.new(fileframe, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|ICONLIST_MINI_ICONS|ICONLIST_AUTOSIZE) @filelist.connect(SEL_DOUBLECLICKED, method(:onCmdFileList)) diff --git a/examples/inputs.rb b/examples/inputs.rb index e00dde617496ede06186510985ea3f0d35fb64f3..76576256f21be3ab7e313e27cdc41f87ce03f9a9 100755 --- a/examples/inputs.rb +++ b/examples/inputs.rb @@ -1,7 +1,6 @@ #!/usr/bin/env ruby require 'fox16' -require 'fox16/kwargs' include Fox @@ -55,7 +54,7 @@ class InputHandlerWindow < FXMainWindow getApp().addInput(@pipe, INPUT_READ|INPUT_EXCEPT) do |sender, sel, ptr| case FXSELTYPE(sel) when SEL_IO_READ - text = @pipe.read + text = @pipe.read_nonblock(256) if text && text.length > 0 @cmdOutput.appendText(text) else diff --git a/examples/mditest.rb b/examples/mditest.rb index e311104662f30125e3a02724fd7b743fec8db680..0899a78f4b84653a28f766ff0eff54fee0d3730f 100755 --- a/examples/mditest.rb +++ b/examples/mditest.rb @@ -2,7 +2,6 @@ require 'fox16' require 'fox16/colors' -require 'fox16/kwargs' include Fox diff --git a/examples/pig.rb b/examples/pig.rb index 784238db109df8feb5b7ad29b3eebeaddee36d0b..2eadc9bafec7d1e007342c755f229401cf1095e1 100755 --- a/examples/pig.rb +++ b/examples/pig.rb @@ -5,7 +5,6 @@ # require 'fox16' -require 'fox16/kwargs' include Fox diff --git a/examples/raabrowser.rb b/examples/raabrowser.rb index 7997a6c65179d09007c3887bbddd7eb9f4e84898..ec3ba2a1670f44dc9367fc222d8e8fd99882e928 100755 --- a/examples/raabrowser.rb +++ b/examples/raabrowser.rb @@ -1,5 +1,4 @@ require 'fox16' -require 'fox16/kwargs' require 'cgi' require 'soap/wsdlDriver' diff --git a/examples/ratio.rb b/examples/ratio.rb index be0eb464860bbe5fa6935debb887f88869d21f63..6bca0b39a960a891afd333180a6b942fea2f30c2 100644 --- a/examples/ratio.rb +++ b/examples/ratio.rb @@ -6,7 +6,6 @@ require 'fox16' require 'fox16/colors' -require 'fox16/kwargs' include Fox diff --git a/examples/rmagick.rb b/examples/rmagick.rb new file mode 100755 index 0000000000000000000000000000000000000000..7632d2a9d8a08dbbd6aef06c50ed3ddb1b87f4fa --- /dev/null +++ b/examples/rmagick.rb @@ -0,0 +1,44 @@ +require 'fox16' +require 'RMagick' + +include Fox + +class RMagickExample < FXMainWindow + + def initialize(app) + super(app, "RMagick Example", :width => 800, :height => 600) + + # Construct an ImageList + dippy = Magick::ImageList.new(File.join("icons", "dippy.png")) + + # Manipulate the image + text = Magick::Draw.new + text.annotate(dippy, 0, 0, 0, 60, "Dippy Duck") do + self.gravity = Magick::SouthGravity + self.pointsize = 24 + self.stroke = 'transparent' + self.fill = '#0000A9' + self.font_weight = Magick::BoldWeight + end + + # Extract image data and use it to construct FXPNGImage + dippy_image = FXPNGImage.new(app, dippy.to_blob) + + # Display it inside an FXImageFrame + FXImageFrame.new(self, dippy_image, :opts => LAYOUT_FILL) + end + + def create + super + show(PLACEMENT_SCREEN) + end + +end + +if __FILE__ == $0 + FXApp.new("RMagick Example", "FXRuby") do |app| + RMagickExample.new(app) + app.create + app.run + end +end \ No newline at end of file diff --git a/examples/rulerview.rb b/examples/rulerview.rb index b636d27cb45abbf02e515e0a98024d20fe69325d..187d6743b2fc17697a459ab468145ad838ce7a74 100644 --- a/examples/rulerview.rb +++ b/examples/rulerview.rb @@ -1,5 +1,4 @@ require 'fox16' -require 'fox16/kwargs' include Fox diff --git a/examples/scribble.rb b/examples/scribble.rb index 52e431fa983038ea2d2fdf4bb994f93479161336..343e605d753cbc296f099bbc18ac08e1a50b2e50 100755 --- a/examples/scribble.rb +++ b/examples/scribble.rb @@ -1,7 +1,6 @@ #!/usr/bin/env ruby require 'fox16' -require 'fox16/kwargs' include Fox diff --git a/examples/shutter.rb b/examples/shutter.rb index ff9af72341ed971a85399958779ad9e022556466..aefbac40aab420d6a8e7ff92662c8fbfd2c73ed1 100755 --- a/examples/shutter.rb +++ b/examples/shutter.rb @@ -1,7 +1,6 @@ #!/usr/bin/env ruby require 'fox16' -require 'fox16/kwargs' include Fox diff --git a/examples/splitter.rb b/examples/splitter.rb index 10015d6d6073533bb51074a511d1f725822dc79f..f067e521a20dd883319a332043b6d488867314e0 100755 --- a/examples/splitter.rb +++ b/examples/splitter.rb @@ -1,7 +1,6 @@ #!/usr/bin/env ruby require 'fox16' -require 'fox16/kwargs' include Fox diff --git a/examples/styledtext.rb b/examples/styledtext.rb index 9c7ee539e739f4dc5293614517de35eea6a020c8..a0808b839c351045e0686b291048cf1a74fad8a7 100755 --- a/examples/styledtext.rb +++ b/examples/styledtext.rb @@ -40,24 +40,14 @@ class StyledTextWindow < FXMainWindow TEXT_READONLY|TEXT_WORDWRAP|LAYOUT_FILL_X|LAYOUT_FILL_Y) # Construct some hilite styles - hs1 = FXHiliteStyle.new + hs1 = FXHiliteStyle.from_text(text) hs1.normalForeColor = FXColor::Red hs1.normalBackColor = FXColor::Blue - hs1.selectForeColor = text.selTextColor - hs1.selectBackColor = text.selBackColor - hs1.hiliteForeColor = text.hiliteTextColor - hs1.hiliteBackColor = text.hiliteBackColor - hs1.activeBackColor = text.activeBackColor - hs1.style = 0 + hs1.style = FXText::STYLE_BOLD - hs2 = FXHiliteStyle.new + hs2 = FXHiliteStyle.from_text(text) hs2.normalForeColor = FXColor::Blue hs2.normalBackColor = FXColor::Yellow - hs2.selectForeColor = text.selTextColor - hs2.selectBackColor = text.selBackColor - hs2.hiliteForeColor = text.hiliteTextColor - hs2.hiliteBackColor = text.hiliteBackColor - hs2.activeBackColor = text.activeBackColor hs2.style = FXText::STYLE_UNDERLINE # Enable the style buffer for this text widget diff --git a/examples/tabbook.rb b/examples/tabbook.rb index 20517fcef10037dbe77a4a3e414d14bb948e66c8..ea6bbe324053b79f6d601ce0d21c09a9048eff6c 100755 --- a/examples/tabbook.rb +++ b/examples/tabbook.rb @@ -1,7 +1,6 @@ #!/usr/bin/env ruby require 'fox16' -require 'fox16/kwargs' include Fox diff --git a/examples/table.rb b/examples/table.rb index 78cc30c503361f2946f28281583c0eecb7df8c10..c98f1da472290fadc58611a29a5039b24007fa1d 100755 --- a/examples/table.rb +++ b/examples/table.rb @@ -1,7 +1,6 @@ #!/usr/bin/env ruby require 'fox16' -require 'fox16/kwargs' require 'date' include Fox diff --git a/ext/fox16/FXRbApp.cpp b/ext/fox16/FXRbApp.cpp index e819ba6f1812a1c9ae55df1f6b7eed4ee19175e4..ba78205879915cf6deb7576a760276ac52c08020 100755 --- a/ext/fox16/FXRbApp.cpp +++ b/ext/fox16/FXRbApp.cpp @@ -21,14 +21,16 @@ ***********************************************************************/ /*********************************************************************** - * $Id: FXRbApp.cpp 2190 2005-08-24 07:58:47Z lyle $ + * $Id: FXRbApp.cpp 2902 2008-12-11 14:09:20Z lyle $ ***********************************************************************/ #include "FXRbCommon.h" +#ifndef RUBY_1_9 extern "C" { #include "rubysig.h" /* For CHECK_INTS */ } +#endif #ifdef HAVE_SYS_TIME_H #include <sys/time.h> /* For struct timeval */ @@ -95,9 +97,14 @@ long FXRbApp::onChoreThreads(FXObject*,FXSelector,void*){ wait.tv_usec=100*sleepTime; // Confirm that this thread can be interrupted, then go to sleep +#ifndef RUBY_1_9 CHECK_INTS; if(!rb_thread_critical) rb_thread_wait_for(wait); +#else + // if(!rb_thread_critical) rb_thread_wait_for(wait); + rb_thread_wait_for(wait); +#endif /* RUBY_1_9 */ // Re-register this chore for next time addChore(this,ID_CHORE_THREADS); diff --git a/ext/fox16/FXRbDataTarget.cpp b/ext/fox16/FXRbDataTarget.cpp index 0880313e066b531ca76a14e5cb14e5e004cd85a2..d388c9b595a4e97287b444a107cb0aed5fc1d3eb 100755 --- a/ext/fox16/FXRbDataTarget.cpp +++ b/ext/fox16/FXRbDataTarget.cpp @@ -21,7 +21,7 @@ ***********************************************************************/ /*********************************************************************** - * $Id: FXRbDataTarget.cpp 2190 2005-08-24 07:58:47Z lyle $ + * $Id: FXRbDataTarget.cpp 2713 2007-11-14 15:27:36Z lyle $ ***********************************************************************/ #include "FXRbCommon.h" @@ -57,7 +57,7 @@ void FXRbDataTarget::setValue(VALUE value){ connect(doubleValue); break; case T_STRING: - stringValue=STR2CSTR(value); + stringValue=StringValuePtr(value); connect(stringValue); break; case T_TRUE: diff --git a/ext/fox16/FXRuby.cpp b/ext/fox16/FXRuby.cpp index 81f4d720cb080c457f5172f681e33e32af0e5465..650418c142193ddef858e9db07058f2dac53d8e7 100755 --- a/ext/fox16/FXRuby.cpp +++ b/ext/fox16/FXRuby.cpp @@ -21,7 +21,7 @@ ***********************************************************************/ /*********************************************************************** - * $Id: FXRuby.cpp 2608 2007-02-09 20:34:16Z lyle $ + * $Id: FXRuby.cpp 2933 2008-12-29 20:19:33Z lyle $ ***********************************************************************/ #ifdef _MSC_VER @@ -30,16 +30,18 @@ #include "FXRbCommon.h" +#ifndef RUBY_1_9 #include "version.h" #if RUBY_VERSION_CODE < 167 #define RB_RESCUE2_BROKEN_PROTOTYPE 1 #endif -/* The prototype for st_foreach() changed at Ruby version 1.8.2 */ +// The prototype for st_foreach() changed at Ruby version 1.8.2 #if RUBY_VERSION_CODE < 182 #define ST_BROKEN_PROTOTYPES 1 #endif +#endif /* RUBY_1_9 */ #include "impl.h" @@ -51,15 +53,19 @@ #include <signal.h> // for definitions of SIGINT, etc. #endif +#ifndef RUBY_1_9 extern "C" { #include "rubyio.h" // for GetOpenFile(), etc. } +#else +#include "ruby/io.h" +#endif // Symbol table functions from Ruby. If we included "st.h" directly // we'd be dealing with broken prototypes anyways, so just duplicate // the needed declarations here with the correct prototypes. -#ifdef ST_BROKEN_PROTOTYPES +#if defined(ST_BROKEN_PROTOTYPES) extern "C" { @@ -78,11 +84,19 @@ void st_foreach(st_table *table, int (*func)(st_data_t, st_data_t, st_data_t), s #else +#ifdef RUBY_1_9 + +#include "ruby/st.h" + +#else + extern "C" { #include "st.h" } -#endif +#endif /* RUBY_1_9 */ + +#endif /* ST_BROKEN_PROTOTYPES */ // Opaque type declaration from SWIG runtime struct swig_type_info; @@ -136,13 +150,11 @@ VALUE FXRbNewPointerObj(void *ptr,swig_type_info* ty){ FXASSERT(ty!=0); VALUE obj; FXRubyObjDesc *desc; - int result; if(FXMALLOC(&desc,FXRubyObjDesc,1)){ obj=SWIG_Ruby_NewPointerObj(ptr,ty,1); desc->obj=obj; desc->borrowed=true; - result=st_insert(FXRuby_Objects,reinterpret_cast<st_data_t>(ptr),reinterpret_cast<st_data_t>(desc)); - FXASSERT(result==0); + st_insert(FXRuby_Objects,reinterpret_cast<st_data_t>(ptr),reinterpret_cast<st_data_t>(desc)); return obj; } else{ @@ -189,9 +201,15 @@ FXbool FXRbCatchExceptions=FALSE; // Returns an FXInputHandle for this Ruby file object FXInputHandle FXRbGetReadFileHandle(VALUE obj) { +#ifdef RUBY_1_9 + rb_io_t *fptr; + GetOpenFile(obj, fptr); + FILE *fpr=fptr->stdio_file; +#else OpenFile *fptr; GetOpenFile(obj, fptr); FILE *fpr=GetReadFile(fptr); +#endif /* RUBY_1_9 */ #ifdef WIN32 #ifdef __CYGWIN__ return (FXInputHandle) get_osfhandle(fileno(fpr)); @@ -206,9 +224,15 @@ FXInputHandle FXRbGetReadFileHandle(VALUE obj) { // Returns an FXInputHandle for this Ruby file object FXInputHandle FXRbGetWriteFileHandle(VALUE obj) { +#ifdef RUBY_1_9 + rb_io_t *fptr; + GetOpenFile(obj, fptr); + FILE *fpw=fptr->stdio_file; +#else OpenFile *fptr; GetOpenFile(obj, fptr); FILE *fpw=GetWriteFile(fptr); +#endif /* RUBY_1_9 */ #ifdef WIN32 #ifdef __CYGWIN__ return (FXInputHandle) get_osfhandle(fileno(fpw)); @@ -226,7 +250,7 @@ void FXRbRegisterRubyObj(VALUE rubyObj,const void* foxObj) { FXASSERT(!NIL_P(rubyObj)); FXASSERT(foxObj!=0); FXRubyObjDesc* desc; - FXTRACE((1,"FXRbRegisterRubyObj(rubyObj=%d,foxObj=0x%08x)\n",rubyObj,foxObj)); + FXTRACE((1,"FXRbRegisterRubyObj(rubyObj=%d,foxObj=%p)\n",static_cast<int>(rubyObj),foxObj)); if(FXMALLOC(&desc,FXRubyObjDesc,1)){ desc->obj=rubyObj; desc->borrowed=false; @@ -527,6 +551,9 @@ static VALUE FXRbConvertMessageData(FXObject* sender,FXObject* recv,FXSelector s else if(sender->isMemberOf(FXMETACLASS(FXArrowButton))){ if(type==SEL_COMMAND) return to_ruby(static_cast<FXuint>(reinterpret_cast<FXuval>(ptr))); } + else if(sender->isMemberOf(FXMETACLASS(FXPicker))){ + if(type==SEL_COMMAND || type==SEL_CHANGED) return to_ruby(reinterpret_cast<FXPoint*>(ptr)); + } else if(sender->isMemberOf(FXMETACLASS(FXButton))){ if(type==SEL_CLICKED || type==SEL_DOUBLECLICKED || @@ -560,9 +587,7 @@ static VALUE FXRbConvertMessageData(FXObject* sender,FXObject* recv,FXSelector s type==SEL_CLICKED || type==SEL_DOUBLECLICKED || type==SEL_TRIPLECLICKED) { - fprintf(stderr,"ptr=0x%08x\n",ptr); VALUE v=to_ruby(static_cast<FXColor>(reinterpret_cast<unsigned long>(ptr))); - fprintf(stderr,"v=%d\n",v); return v; } } @@ -654,7 +679,7 @@ static VALUE FXRbConvertMessageData(FXObject* sender,FXObject* recv,FXSelector s type==SEL_SELECTED || type==SEL_DESELECTED){ VALUE ary=rb_ary_new(); - FXGLObject** objlist=reinterpret_cast<FXGLObject**>(ptr); + // FXGLObject** objlist=reinterpret_cast<FXGLObject**>(ptr); // FIXME: objlist is a NULL-terminated array of pointers to FXGLObject return ary; } @@ -736,9 +761,6 @@ static VALUE FXRbConvertMessageData(FXObject* sender,FXObject* recv,FXSelector s else if(sender->isMemberOf(FXMETACLASS(FXOptionMenu))){ if(type==SEL_COMMAND) return to_ruby(static_cast<FXint>(reinterpret_cast<FXival>(ptr))); } - else if(sender->isMemberOf(FXMETACLASS(FXPicker))){ - if(type==SEL_COMMAND || type==SEL_CHANGED) return to_ruby(reinterpret_cast<FXPoint*>(ptr)); - } else if(sender->isMemberOf(FXMETACLASS(FXRadioButton))){ if(type==SEL_COMMAND) return to_ruby(static_cast<FXuchar>(reinterpret_cast<FXuval>(ptr))); } @@ -901,7 +923,6 @@ static VALUE FXRbConvertMessageData(FXObject* sender,FXObject* recv,FXSelector s * the appropriate C++ objects. That's what this function is for. */ void* FXRbGetExpectedData(VALUE recv,FXSelector key,VALUE value){ - FXEvent* ev; void *ptr; static FXint intValue; static FXint intRange[2]; @@ -985,7 +1006,7 @@ void* FXRbGetExpectedData(VALUE recv,FXSelector key,VALUE value){ case SEL_QUERY_HELP: return NULL; case SEL_VERIFY: - return reinterpret_cast<void*>(STR2CSTR(value)); + return reinterpret_cast<void*>(StringValuePtr(value)); case SEL_CLICKED: case SEL_DOUBLECLICKED: case SEL_TRIPLECLICKED: @@ -1004,10 +1025,7 @@ void* FXRbGetExpectedData(VALUE recv,FXSelector key,VALUE value){ /* Ignore */ break; } - if(type==SEL_DRAGGED){ - SWIG_Ruby_ConvertPtr(value,&ptr,FXRbTypeQuery("FXEvent *"),1); - return ptr; - } + if(type==SEL_COMMAND){ // Handle FXText-specific messages if(obj->isMemberOf(FXMETACLASS(FXText))){ @@ -1025,7 +1043,7 @@ void* FXRbGetExpectedData(VALUE recv,FXSelector key,VALUE value){ if(obj->isMemberOf(FXMETACLASS(FXTextField))){ switch(id){ case FXTextField::ID_INSERT_STRING: - return reinterpret_cast<void*>(STR2CSTR(value));; + return reinterpret_cast<void*>(StringValuePtr(value));; default: break; } @@ -1094,14 +1112,14 @@ void* FXRbGetExpectedData(VALUE recv,FXSelector key,VALUE value){ obj->isMemberOf(FXMETACLASS(FXDirList)) || obj->isMemberOf(FXMETACLASS(FXDriveBox)) || obj->isMemberOf(FXMETACLASS(FXFileList))){ - return reinterpret_cast<void*>(STR2CSTR(value)); + return reinterpret_cast<void*>(StringValuePtr(value)); } else if(obj->isMemberOf(FXMETACLASS(FXMenuCheck))){ return reinterpret_cast<void*>(static_cast<FXuval>(RTEST(value) ? 1 : 0)); } else if(obj->isMemberOf(FXMETACLASS(FXMenuRadio))){ return reinterpret_cast<void*>(static_cast<FXuval>(RTEST(value) ? 1 : 0)); - } + } else if(obj->isMemberOf(FXMETACLASS(FXMenuCommand))){ return reinterpret_cast<void*>(static_cast<FXuval>(RTEST(value) ? 1 : 0)); } @@ -1122,7 +1140,7 @@ void* FXRbGetExpectedData(VALUE recv,FXSelector key,VALUE value){ realValue=NUM2DBL(value); return reinterpret_cast<void*>(&realValue); case FXWindow::ID_SETSTRINGVALUE: - stringValue=FXString(STR2CSTR(value)); + stringValue=FXString(StringValuePtr(value)); return reinterpret_cast<void*>(&stringValue); case FXWindow::ID_SETINTRANGE: intRange[0]=NUM2INT(rb_ary_entry(value,0)); @@ -1144,6 +1162,20 @@ void* FXRbGetExpectedData(VALUE recv,FXSelector key,VALUE value){ } } } + + if(type==SEL_CHANGED){ + if(obj->isMemberOf(FXMETACLASS(FXPicker))){ + SWIG_Ruby_ConvertPtr(value,&ptr,FXRbTypeQuery("FXPoint *"),1); + return ptr; + } + return 0; + } + + if(type==SEL_DRAGGED){ + SWIG_Ruby_ConvertPtr(value,&ptr,FXRbTypeQuery("FXEvent *"),1); + return ptr; + } + // Pass through as-is return reinterpret_cast<void*>(value); } @@ -1159,7 +1191,7 @@ static ID id_assocs; * message. */ ID FXRbLookupHandler(FXObject* recv,FXSelector key){ - FXTRACE((100,"FXRbLookupHandler(recv=0x%08x(%s),FXSEL(%d,%d))\n",recv,recv->getClassName(),FXSELTYPE(key),FXSELID(key))); + FXTRACE((100,"FXRbLookupHandler(recv=%p(%s),FXSEL(%d,%d))\n",recv,recv->getClassName(),FXSELTYPE(key),FXSELID(key))); ID id=0; VALUE rubyObj=to_ruby(recv); FXASSERT((recv==0 && rubyObj==Qnil) || (recv!=0 && rubyObj!=Qnil)); @@ -1167,7 +1199,7 @@ ID FXRbLookupHandler(FXObject* recv,FXSelector key){ VALUE assocs=rb_ivar_get(rubyObj,id_assocs); VALUE entry; FXSelector keylo,keyhi; - for(long i=0;i<RARRAY(assocs)->len;i++){ + for(long i=0;i<RARRAY_LEN(assocs);i++){ entry=rb_ary_entry(assocs,i); keylo=NUM2UINT(rb_ary_entry(entry,0)); keyhi=NUM2UINT(rb_ary_entry(entry,1)); @@ -1205,14 +1237,14 @@ static ID id_backtrace; static VALUE handle_rescue(VALUE args,VALUE error){ VALUE info=rb_gv_get("$!"); VALUE errat=rb_funcall(info,id_backtrace,0); - VALUE mesg=RARRAY(errat)->ptr[0]; + VALUE mesg=RARRAY_PTR(errat)[0]; fprintf(stderr,"%s: %s (%s)\n", - STR2CSTR(mesg), - STR2CSTR(rb_obj_as_string(info)), + StringValuePtr(mesg), + RSTRING_PTR(rb_obj_as_string(info)), rb_class2name(CLASS_OF(info))); - for(int i=1;i<RARRAY(errat)->len;i++){ - if(TYPE(RARRAY(errat)->ptr[i])==T_STRING){ - fprintf(stderr,"\tfrom %s\n",STR2CSTR(RARRAY(errat)->ptr[i])); + for(int i=1;i<RARRAY_LEN(errat);i++){ + if(TYPE(RARRAY_PTR(errat)[i])==T_STRING){ + fprintf(stderr,"\tfrom %s\n",StringValuePtr(RARRAY_PTR(errat)[i])); } } return Qnil; @@ -1230,7 +1262,7 @@ long FXRbHandleMessage(FXObject* recv,ID func,FXObject* sender,FXSelector key,vo hArgs.nargs=3; VALUE retval; - FXTRACE((100,"FXRbHandleMessage(recv=0x%08x(%s),FXSEL(%s,%d)\n",recv,recv->getClassName(),FXDebugTarget::messageTypeName[FXSELTYPE(key)],FXSELID(key))); + FXTRACE((100,"FXRbHandleMessage(recv=%p(%s),FXSEL(%s,%d)\n",recv,recv->getClassName(),FXDebugTarget::messageTypeName[FXSELTYPE(key)],FXSELID(key))); if(FXRbCatchExceptions){ #ifdef RB_RESCUE2_BROKEN_PROTOTYPE @@ -1380,11 +1412,11 @@ FXGLObject** FXRbCallGLObjectArrayMethod(FXGLViewer* recv,ID func,FXint x,FXint VALUE result=rb_funcall(obj,func,4,INT2NUM(x),INT2NUM(y),INT2NUM(w),INT2NUM(h)); if(!NIL_P(result)){ Check_Type(result,T_ARRAY); - if(FXMALLOC(&objects,FXGLObject*,RARRAY(result)->len+1)){ - for(long i=0; i<RARRAY(result)->len; i++){ + if(FXMALLOC(&objects,FXGLObject*,RARRAY_LEN(result)+1)){ + for(long i=0; i<RARRAY_LEN(result); i++){ objects[i]=reinterpret_cast<FXGLObject*>(DATA_PTR(rb_ary_entry(result,i))); } - objects[RARRAY(result)->len]=0; + objects[RARRAY_LEN(result)]=0; } } return objects; // caller must free this @@ -1439,8 +1471,13 @@ FXFileAssoc* FXRbCallFileAssocMethod(const FXFileDict* recv,ID func,const char* FXIcon* FXRbCallIconMethod(const FXTableItem* recv,ID func){ VALUE obj=FXRbGetRubyObj(recv,false); FXASSERT(!NIL_P(obj)); - VALUE result=rb_funcall(obj,func,0,NULL); - return NIL_P(result) ? 0 : reinterpret_cast<FXIcon*>(DATA_PTR(result)); + if(!NIL_P(obj)){ + VALUE result=rb_funcall(obj,func,0,NULL); + return NIL_P(result) ? 0 : reinterpret_cast<FXIcon*>(DATA_PTR(result)); + } + else{ + return 0; + } } //---------------------------------------------------------------------- @@ -1469,7 +1506,7 @@ FXString FXRbCallStringMethod(const FXObject* recv, ID func){ VALUE obj=FXRbGetRubyObj(recv,false); FXASSERT(!NIL_P(obj)); VALUE result=rb_funcall(obj,func,0,NULL); - return FXString(STR2CSTR(result)); + return FXString(StringValuePtr(result)); } //---------------------------------------------------------------------- @@ -1479,7 +1516,7 @@ const FXchar* FXRbCallCStringMethod(const FXObject* recv, ID func, const FXchar* VALUE obj=FXRbGetRubyObj(recv,false); FXASSERT(!NIL_P(obj)); VALUE result=rb_funcall(obj,func,2,to_ruby(message),to_ruby(hint)); - return NIL_P(result) ? 0 : STR2CSTR(result); + return NIL_P(result) ? 0 : StringValuePtr(result); } // Call functions with const FXchar* return value @@ -1487,7 +1524,7 @@ const FXchar* FXRbCallCStringMethod(const FXObject* recv, ID func, const FXchar* VALUE obj=FXRbGetRubyObj(recv,false); FXASSERT(!NIL_P(obj)); VALUE result=rb_funcall(obj,func,3,to_ruby(context),to_ruby(message),to_ruby(hint)); - return NIL_P(result) ? 0 : STR2CSTR(result); + return NIL_P(result) ? 0 : StringValuePtr(result); } //---------------------------------------------------------------------- @@ -1674,145 +1711,144 @@ FXbool FXRbGLViewer::sortProc(FXfloat*& buffer,FXint& used,FXint& size){ //---------------------------------------------------------------------- -// Copied from the Ruby 1.6.6 sources (signal.c) +// Copied from the Ruby 1.8.6 sources (signal.c) static struct signals { - const char* signm; - FXint signo; - } siglist[]={ + const char *signm; + int signo; +} siglist [] = { + {"EXIT", 0}, #ifdef SIGHUP - { "HUP", SIGHUP }, -#endif -#ifdef SIGINT - { "INT", SIGINT }, + {"HUP", SIGHUP}, #endif + {"INT", SIGINT}, #ifdef SIGQUIT - { "QUIT", SIGQUIT }, + {"QUIT", SIGQUIT}, #endif #ifdef SIGILL - { "ILL", SIGILL }, + {"ILL", SIGILL}, #endif #ifdef SIGTRAP - { "TRAP", SIGTRAP }, + {"TRAP", SIGTRAP}, #endif #ifdef SIGIOT - { "IOT", SIGIOT }, + {"IOT", SIGIOT}, #endif #ifdef SIGABRT - { "ABRT", SIGABRT }, + {"ABRT", SIGABRT}, #endif #ifdef SIGEMT - { "EMT", SIGEMT }, + {"EMT", SIGEMT}, #endif #ifdef SIGFPE - { "FPE", SIGFPE }, + {"FPE", SIGFPE}, #endif #ifdef SIGKILL - { "KILL", SIGKILL }, + {"KILL", SIGKILL}, #endif #ifdef SIGBUS - { "BUS", SIGBUS }, + {"BUS", SIGBUS}, #endif #ifdef SIGSEGV - { "SEGV", SIGSEGV }, + {"SEGV", SIGSEGV}, #endif #ifdef SIGSYS - { "SYS", SIGSYS }, + {"SYS", SIGSYS}, #endif #ifdef SIGPIPE - { "PIPE", SIGPIPE }, + {"PIPE", SIGPIPE}, #endif #ifdef SIGALRM - { "ALRM", SIGALRM }, + {"ALRM", SIGALRM}, #endif #ifdef SIGTERM - { "TERM", SIGTERM }, + {"TERM", SIGTERM}, #endif #ifdef SIGURG - { "URG", SIGURG }, + {"URG", SIGURG}, #endif #ifdef SIGSTOP - { "STOP", SIGSTOP }, + {"STOP", SIGSTOP}, #endif #ifdef SIGTSTP - { "TSTP", SIGTSTP }, + {"TSTP", SIGTSTP}, #endif #ifdef SIGCONT - { "CONT", SIGCONT }, + {"CONT", SIGCONT}, #endif #ifdef SIGCHLD - { "CHLD", SIGCHLD }, + {"CHLD", SIGCHLD}, #endif #ifdef SIGCLD - { "CLD", SIGCLD }, + {"CLD", SIGCLD}, #else # ifdef SIGCHLD - { "CLD", SIGCHLD, }, + {"CLD", SIGCHLD}, # endif #endif #ifdef SIGTTIN - { "TTIN", SIGTTIN }, + {"TTIN", SIGTTIN}, #endif #ifdef SIGTTOU - { "TTOU", SIGTTOU }, + {"TTOU", SIGTTOU}, #endif #ifdef SIGIO - { "IO", SIGIO }, + {"IO", SIGIO}, #endif #ifdef SIGXCPU - { "XCPU", SIGXCPU }, + {"XCPU", SIGXCPU}, #endif #ifdef SIGXFSZ - { "XFSZ", SIGXFSZ }, + {"XFSZ", SIGXFSZ}, #endif #ifdef SIGVTALRM - { "VTALRM", SIGVTALRM }, + {"VTALRM", SIGVTALRM}, #endif #ifdef SIGPROF - { "PROF", SIGPROF }, + {"PROF", SIGPROF}, #endif #ifdef SIGWINCH - { "WINCH", SIGWINCH }, + {"WINCH", SIGWINCH}, #endif #ifdef SIGUSR1 - { "USR1", SIGUSR1 }, + {"USR1", SIGUSR1}, #endif #ifdef SIGUSR2 - { "USR2", SIGUSR2 }, + {"USR2", SIGUSR2}, #endif #ifdef SIGLOST - { "LOST", SIGLOST }, + {"LOST", SIGLOST}, #endif #ifdef SIGMSG - { "MSG", SIGMSG }, + {"MSG", SIGMSG}, #endif #ifdef SIGPWR - { "PWR", SIGPWR }, + {"PWR", SIGPWR}, #endif #ifdef SIGPOLL - { "POLL", SIGPOLL }, + {"POLL", SIGPOLL}, #endif #ifdef SIGDANGER - { "DANGER", SIGDANGER }, + {"DANGER", SIGDANGER}, #endif #ifdef SIGMIGRATE - { "MIGRATE", SIGMIGRATE }, + {"MIGRATE", SIGMIGRATE}, #endif #ifdef SIGPRE - { "PRE", SIGPRE }, + {"PRE", SIGPRE}, #endif #ifdef SIGGRANT - { "GRANT", SIGGRANT }, + {"GRANT", SIGGRANT}, #endif #ifdef SIGRETRACT - { "RETRACT", SIGRETRACT }, + {"RETRACT", SIGRETRACT}, #endif #ifdef SIGSOUND - { "SOUND", SIGSOUND }, + {"SOUND", SIGSOUND}, #endif #ifdef SIGINFO - { "INFO", SIGINFO }, + {"INFO", SIGINFO}, #endif - { NULL, 0 }, + {NULL, 0} }; FXint FXRbSignalNameToNumber(const char* s){ @@ -1849,28 +1885,28 @@ static st_table * appSensitiveDCs; void FXRbRegisterAppSensitiveObject(FXObject* obj){ FXASSERT(obj!=0); - FXTRACE((100,"%s:%d: FXRbRegisterAppSensitiveObject(obj=0x%08x(%s))\n",__FILE__,__LINE__,obj,obj->getClassName())); + FXTRACE((100,"%s:%d: FXRbRegisterAppSensitiveObject(obj=%p(%s))\n",__FILE__,__LINE__,obj,obj->getClassName())); st_insert(appSensitiveObjs,reinterpret_cast<st_data_t>(obj),(st_data_t)0); FXASSERT(st_lookup(appSensitiveObjs,reinterpret_cast<st_data_t>(obj),reinterpret_cast<st_data_t *>(0))!=0); } void FXRbRegisterAppSensitiveObject(FXDC* dc){ FXASSERT(dc!=0); - FXTRACE((100,"%s:%d: FXRbRegisterAppSensitiveObject(dc=0x%08x)\n",__FILE__,__LINE__,dc)); + FXTRACE((100,"%s:%d: FXRbRegisterAppSensitiveObject(dc=%p)\n",__FILE__,__LINE__,dc)); st_insert(appSensitiveDCs,reinterpret_cast<st_data_t>(dc),(st_data_t)0); FXASSERT(st_lookup(appSensitiveDCs,reinterpret_cast<st_data_t>(dc),reinterpret_cast<st_data_t *>(0))!=0); } void FXRbUnregisterAppSensitiveObject(FXObject* obj){ FXASSERT(obj!=0); - FXTRACE((100,"%s:%d: FXRbUnregisterAppSensitiveObject(obj=0x%08x(%s))\n",__FILE__,__LINE__,obj,obj->getClassName())); + FXTRACE((100,"%s:%d: FXRbUnregisterAppSensitiveObject(obj=%p(%s))\n",__FILE__,__LINE__,obj,obj->getClassName())); st_delete(appSensitiveObjs,reinterpret_cast<st_data_t *>(&obj),reinterpret_cast<st_data_t *>(0)); FXASSERT(st_lookup(appSensitiveObjs,reinterpret_cast<st_data_t>(obj),reinterpret_cast<st_data_t *>(0))==0); } void FXRbUnregisterAppSensitiveObject(FXDC* dc){ FXASSERT(dc!=0); - FXTRACE((100,"%s:%d: FXRbUnregisterAppSensitiveObject(dc=0x%08x)\n",__FILE__,__LINE__,dc)); + FXTRACE((100,"%s:%d: FXRbUnregisterAppSensitiveObject(dc=%p)\n",__FILE__,__LINE__,dc)); st_delete(appSensitiveDCs,reinterpret_cast<st_data_t *>(&dc),reinterpret_cast<st_data_t *>(0)); FXASSERT(st_lookup(appSensitiveDCs,reinterpret_cast<st_data_t>(dc),reinterpret_cast<st_data_t *>(0))==0); } @@ -2011,6 +2047,8 @@ extern "C" void Init_fox16(void) { REQUIRE("fox16/glgroup"); REQUIRE("fox16/execute_nonmodal"); REQUIRE("fox16/version"); + REQUIRE("fox16/kwargs"); + REQUIRE("fox16/exceptions_for_fxerror"); id_assocs=rb_intern("@assocs"); id_backtrace=rb_intern("backtrace"); diff --git a/ext/fox16/extconf.rb.in b/ext/fox16/extconf.rb.in index f0b9462ad3bbe5dc81fec655a3960865360a164c..631704557d022fe62a6a3e85d677b8f36a640f2f 100755 --- a/ext/fox16/extconf.rb.in +++ b/ext/fox16/extconf.rb.in @@ -1,12 +1,13 @@ #!/bin/env ruby -require 'ftools' +require 'fileutils' require 'mkmf' def find_installed_fox_version stddirs = ["/usr/include/fox-1.6", "/usr/local/include/fox-1.6", - "/sw/include/fox-1.6"] + "/sw/include/fox-1.6", + "/opt/local/include/fox-1.6"] usrdirs = [] ARGV.each do |arg| if arg =~ /--with-fox-include/ @@ -19,7 +20,7 @@ def find_installed_fox_version incdirs.each do |incdir| filename = File.join(incdir, "fxver.h") - if FileTest.exists?(filename) + if FileTest.exist?(filename) idircflag = "-I" + incdir $CPPFLAGS += " " + idircflag unless $CPPFLAGS.split.include?(idircflag) return @@ -35,7 +36,8 @@ $autodetected_fxscintilla = false def find_installed_fxscintilla_version stddirs = ["/usr/include/fxscintilla", "/usr/local/include/fxscintilla", - "/sw/include/fxscintilla"] + "/sw/include/fxscintilla", + "/opt/local/include/fxscintilla"] usrdirs = [] ARGV.each do |arg| if arg =~ /--with-fxscintilla-include/ @@ -48,7 +50,7 @@ def find_installed_fxscintilla_version incdirs.each do |incdir| filename = File.join(incdir, "FXScintilla.h") - if FileTest.exists?(filename) + if FileTest.exist?(filename) $autodetected_fxscintilla = true idircflag = "-I" + incdir $CPPFLAGS += " " + idircflag unless $CPPFLAGS.split.include?(idircflag) @@ -85,11 +87,11 @@ def do_cygwin_setup $libs = append_library($libs, "FOX-1.6") $CFLAGS = $CFLAGS + " -fpermissive -DWIN32 -Iinclude" if is_fxscintilla_build? - File.move('scintilla_wrap.cpp.bak', 'scintilla_wrap.cpp') if FileTest.exists?('scintilla_wrap.cpp.bak') + FileUtils.move('scintilla_wrap.cpp.bak', 'scintilla_wrap.cpp') if FileTest.exist?('scintilla_wrap.cpp.bak') $CFLAGS = $CFLAGS + " -DWITH_FXSCINTILLA -DHAVE_FOX_1_6" $libs = append_library($libs, "fxscintilla") else - File.move('scintilla_wrap.cpp', 'scintilla_wrap.cpp.bak') if FileTest.exists?('scintilla_wrap.cpp') + FileUtils.move('scintilla_wrap.cpp', 'scintilla_wrap.cpp.bak') if FileTest.exist?('scintilla_wrap.cpp') end end @@ -109,11 +111,11 @@ def do_mswin32_setup $CFLAGS = $CFLAGS + " /DWIN32 /DUNICODE /GR /GX /Iinclude" $LOCAL_LIBS = $LOCAL_LIBS + "FOX-1.6.lib" if is_fxscintilla_build? - File.move('scintilla_wrap.cpp.bak', 'scintilla_wrap.cpp') if FileTest.exists?('scintilla_wrap.cpp.bak') + FileUtils.move('scintilla_wrap.cpp.bak', 'scintilla_wrap.cpp') if FileTest.exist?('scintilla_wrap.cpp.bak') $CFLAGS = $CFLAGS + " /DWITH_FXSCINTILLA /DHAVE_FOX_1_6" $libs = append_library($libs, "fxscintilla") else - File.move('scintilla_wrap.cpp', 'scintilla_wrap.cpp.bak') if FileTest.exists?('scintilla_wrap.cpp') + FileUtils.move('scintilla_wrap.cpp', 'scintilla_wrap.cpp.bak') if FileTest.exist?('scintilla_wrap.cpp') end end @@ -131,13 +133,40 @@ def do_unix_setup find_library("GL", "glXCreateContext", "/usr/X11R6/lib") find_library("GLU", "gluNewQuadric", "/usr/X11R6/lib") $libs = append_library($libs, "FOX-1.6") + $libs = append_library($libs, "Xrandr") $CFLAGS = $CFLAGS + " -O0 -Iinclude" if is_fxscintilla_build? - File.move('scintilla_wrap.cpp.bak', 'scintilla_wrap.cpp') if FileTest.exists?('scintilla_wrap.cpp.bak') + FileUtils.move('scintilla_wrap.cpp.bak', 'scintilla_wrap.cpp') if FileTest.exist?('scintilla_wrap.cpp.bak') $CFLAGS = $CFLAGS + " -DWITH_FXSCINTILLA -DHAVE_FOX_1_6" $libs = append_library($libs, "fxscintilla") else - File.move('scintilla_wrap.cpp', 'scintilla_wrap.cpp.bak') if FileTest.exists?('scintilla_wrap.cpp') + FileUtils.move('scintilla_wrap.cpp', 'scintilla_wrap.cpp.bak') if FileTest.exist?('scintilla_wrap.cpp') + end +end + +def do_darwin_setup + $libs = append_library($libs, "stdc++") + have_header("sys/time.h") + have_header("signal.h") + have_library("png", "png_create_read_struct") + have_library("z", "deflate") + have_library("jpeg", "jpeg_mem_init") + have_library("tiff", "TIFFSetErrorHandler") + find_library("Xext", "XShmQueryVersion", "/usr/X11R6/lib") + find_library("X11", "XFindContext", "/usr/X11R6/lib") + find_library("GL", "glXCreateContext", "/usr/X11R6/lib") + find_library("GLU", "gluNewQuadric", "/usr/X11R6/lib") + $libs = append_library($libs, "FOX-1.6") + $libs = append_library($libs, "Xrandr") + $libs = append_library($libs, "Xcursor") + $libs = append_library($libs, "png") + $CFLAGS = $CFLAGS + " -O0 -Iinclude" + if is_fxscintilla_build? + FileUtils.move('scintilla_wrap.cpp.bak', 'scintilla_wrap.cpp') if FileTest.exist?('scintilla_wrap.cpp.bak') + $CFLAGS = $CFLAGS + " -DWITH_FXSCINTILLA -DHAVE_FOX_1_6" + $libs = append_library($libs, "fxscintilla") + else + FileUtils.move('scintilla_wrap.cpp', 'scintilla_wrap.cpp.bak') if FileTest.exist?('scintilla_wrap.cpp') end end @@ -168,9 +197,14 @@ if RUBY_PLATFORM =~ /cygwin/ || RUBY_PLATFORM =~ /mingw/ do_cygwin_setup elsif RUBY_PLATFORM =~ /mswin32/ do_mswin32_setup +elsif RUBY_PLATFORM =~ /darwin/ + do_darwin_setup else do_unix_setup end +# Check for Ruby 1.9 +$CFLAGS += " -DRUBY_1_9" if RUBY_VERSION =~ /1\.9\./ + # Last step: build the makefile create_makefile("fox16") diff --git a/ext/fox16/include/FXRbApp.h b/ext/fox16/include/FXRbApp.h index 559d81ba8c6f901a0c9a4d2cb8dd910fe32083d9..6ae00c652182af913113d975553780b3075b75d6 100755 --- a/ext/fox16/include/FXRbApp.h +++ b/ext/fox16/include/FXRbApp.h @@ -21,7 +21,7 @@ ***********************************************************************/ /*********************************************************************** - * $Id: FXRbApp.h 2335 2006-01-28 02:33:03Z lyle $ + * $Id: FXRbApp.h 2927 2008-12-29 19:16:57Z lyle $ ***********************************************************************/ #ifndef FXRBAPP_H @@ -41,15 +41,16 @@ inline void cls ## _create(cls *self){ \ static void cls ## _init(cls* self,VALUE ary,bool connect){ \ int i; \ char **argv; \ - int argc=1+RARRAY(ary)->len; \ + int argc=1+RARRAY_LEN(ary); \ if(FXMALLOC(&argv,char*,argc+1)){ \ - argv[0]="foo"; \ + argv[0]=const_cast<char *>("foo"); \ for(i=1;i<argc;i++){ \ - argv[i]=STR2CSTR(RSTRING(rb_ary_entry(ary,i-1))); \ + VALUE e=rb_ary_entry(ary,i-1); \ + argv[i]=StringValuePtr(e); \ } \ argv[argc]=0; \ self->cls::init(argc,argv,connect); \ - while(RARRAY(ary)->len!=0){ \ + while(RARRAY_LEN(ary)!=0){ \ rb_ary_pop(ary); \ } \ for(i=1;i<argc;i++){ \ @@ -97,9 +98,10 @@ inline void cls ## _exit(cls *self,FXint code){ \ rb_ary_push(ary,rb_str_new2(argv[i])); \ } \ FXRbCallVoidMethod(this,rb_intern("init"),ary,connect); \ - argc=RARRAY(ary)->len+1; \ + argc=RARRAY_LEN(ary)+1; \ for(i=1; i<argc; i++){ \ - argv[i]=STR2CSTR(rb_ary_entry(ary,i-1)); \ + VALUE e=rb_ary_entry(ary,i-1); \ + argv[i]=StringValuePtr(e); \ } \ } \ void cls::exit(FXint code){ \ diff --git a/ext/fox16/include/FXRbDC.h b/ext/fox16/include/FXRbDC.h index 8a2ac1aa1b7c763647ad65229d4fd90ff7ca7cea..33cf85aed6e4dd8d88e90dcb611782a7007fb5f0 100755 --- a/ext/fox16/include/FXRbDC.h +++ b/ext/fox16/include/FXRbDC.h @@ -21,7 +21,7 @@ ***********************************************************************/ /*********************************************************************** - * $Id: FXRbDC.h 2372 2006-04-20 00:38:08Z lyle $ + * $Id: FXRbDC.h 2823 2008-03-28 02:04:22Z lyle $ ***********************************************************************/ #ifndef FXRBDC_H diff --git a/ext/fox16/markfuncs.cpp b/ext/fox16/markfuncs.cpp index 1b62c89280dfc396181078a6641fde9f1639067c..bea3a48784b38086fd867abc76282fcb22a9790e 100755 --- a/ext/fox16/markfuncs.cpp +++ b/ext/fox16/markfuncs.cpp @@ -1,5 +1,5 @@ /*********************************************************************** - * $Id: markfuncs.cpp 2479 2006-09-08 23:20:52Z lyle $ + * $Id: markfuncs.cpp 2928 2008-12-29 19:16:57Z lyle $ ***********************************************************************/ #include "FXRbCommon.h" @@ -49,7 +49,7 @@ void FXRbAccelTable::markfunc(FXAccelTable* accelTable){ // Mark dependencies for the GC void FXRbObject::markfunc(FXObject* obj){ - FXTRACE((100,"%s::markfunc(0x%08x)\n",obj?obj->getClassName():"FXRbObject",obj)); + FXTRACE((100,"%s::markfunc(%p)\n",obj?obj->getClassName():"FXRbObject",obj)); } @@ -1568,29 +1568,29 @@ void FXRbTGAImage::markfunc(FXTGAImage* self){ void FXRbBitmapFrame::markfunc(FXBitmapFrame* self){ - FXTRACE((100,"start FXRbBitmapFrame::markfunc(0x%08x)\n",self)); + FXTRACE((100,"start FXRbBitmapFrame::markfunc(%p)\n",self)); FXRbFrame::markfunc(self); if(self!=0){ FXRbGcMark(self->getBitmap()); } - FXTRACE((100,"end FXRbBitmapFrame::markfunc(0x%08x)\n",self)); + FXTRACE((100,"end FXRbBitmapFrame::markfunc(%p)\n",self)); } void FXRbImageFrame::markfunc(FXImageFrame* self){ - FXTRACE((100,"start FXRbImageFrame::markfunc(0x%08x)\n",self)); + FXTRACE((100,"start FXRbImageFrame::markfunc(%p)\n",self)); FXRbFrame::markfunc(self); if(self!=0){ FXRbGcMark(self->getImage()); } - FXTRACE((100,"end FXRbImageFrame::markfunc(0x%08x)\n",self)); + FXTRACE((100,"end FXRbImageFrame::markfunc(%p)\n",self)); } void FXRbGradientBar::markfunc(FXGradientBar* self){ - FXTRACE((100,"start FXRbGradientBar::markfunc(0x%08x)\n",self)); + FXTRACE((100,"start FXRbGradientBar::markfunc(%p)\n",self)); FXRbFrame::markfunc(self); - FXTRACE((100,"end FXRbGradientBar::markfunc(0x%08x)\n",self)); + FXTRACE((100,"end FXRbGradientBar::markfunc(%p)\n",self)); } #ifdef WITH_FXSCINTILLA diff --git a/ext/fox16/unregisterOwnedObjects.cpp b/ext/fox16/unregisterOwnedObjects.cpp index 8c1457985fb082bd235101ca1ab0e629890a3a3f..ca50c0ae1de31ffa4b08edadc99369eb0d1f1129 100644 --- a/ext/fox16/unregisterOwnedObjects.cpp +++ b/ext/fox16/unregisterOwnedObjects.cpp @@ -1,5 +1,5 @@ /*********************************************************************** - * $Id: unregisterOwnedObjects.cpp 2305 2005-12-09 14:38:22Z lyle $ + * $Id: unregisterOwnedObjects.cpp 2911 2008-12-11 14:09:45Z lyle $ ***********************************************************************/ /** @@ -88,7 +88,7 @@ void FXRbScrollWindow::unregisterOwnedObjects(FXScrollWindow *self) void FXRbTable::unregisterOwnedObjects(FXTable *self) { - FXint i,r,c; + FXint r,c; FXRbScrollArea::unregisterOwnedObjects(self); FXRbHeader::unregisterOwnedObjects(self->getRowHeader()); FXRbHeader::unregisterOwnedObjects(self->getColumnHeader()); diff --git a/install.rb b/install.rb index 274ab6e555adaca8d2050bdbd51b2eba2c6bceb2..424a5f37c6fe3a7cac54b0f85688c1cce7da9cdf 100755 --- a/install.rb +++ b/install.rb @@ -1,1095 +1,1582 @@ # -# This file is automatically generated. DO NOT MODIFY! +# setup.rb # -# install.rb +# Copyright (c) 2000-2005 Minero Aoki # -# Copyright (c) 2000-2003 Minero Aoki <aamine@loveruby.net> +# This program is free software. +# You can distribute/modify this program under the terms of +# the GNU LGPL, Lesser General Public License version 2.1. # -# This program is free software. -# You can distribute/modify this program under the terms of -# the GNU Lesser General Public License version 2. -# - -### begin compat.rb -module Enumerable - methods = instance_methods() - - unless methods.include?('map') +unless Enumerable.method_defined?(:map) # Ruby 1.4.6 + module Enumerable alias map collect end +end - unless methods.include?('select') - alias select find_all - end - - unless methods.include?('reject') - def reject - result = [] - each do |i| - result.push i unless yield(i) - end - result - end - end - - unless methods.include?('inject') - def inject( result ) - each do |i| - result = yield(result, i) - end - result - end +unless File.respond_to?(:read) # Ruby 1.6 + def File.read(fname) + open(fname) {|f| + return f.read + } end +end - unless methods.include?('any?') - def any? - each do |i| - return true if yield(i) - end - false +unless Errno.const_defined?(:ENOTEMPTY) # Windows? + module Errno + class ENOTEMPTY + # We do not raise this exception, implementation is not needed. end end end -def File.read_all( fname ) - File.open(fname, 'rb') {|f| return f.read } -end - -def File.write( fname, str ) - File.open(fname, 'wb') {|f| f.write str } +def File.binread(fname) + open(fname, 'rb') {|f| + return f.read + } end -### end compat.rb -### begin config.rb - -if i = ARGV.index(/\A--rbconfig=/) - file = $' - ARGV.delete_at(i) - require file -else - require 'rbconfig' +# for corrupted Windows' stat(2) +def File.dir?(path) + File.directory?((path[-1,1] == '/') ? path : path + '/') end class ConfigTable - c = ::Config::CONFIG + include Enumerable - rubypath = c['bindir'] + '/' + c['ruby_install_name'] + def initialize(rbconfig) + @rbconfig = rbconfig + @items = [] + @table = {} + # options + @install_prefix = nil + @config_opt = nil + @verbose = true + @no_harm = false + end - major = c['MAJOR'].to_i - minor = c['MINOR'].to_i - teeny = c['TEENY'].to_i - version = "#{major}.#{minor}" + attr_accessor :install_prefix + attr_accessor :config_opt - # ruby ver. >= 1.4.4? - newpath_p = ((major >= 2) or - ((major == 1) and - ((minor >= 5) or - ((minor == 4) and (teeny >= 4))))) - - re = Regexp.new('\A' + Regexp.quote(c['prefix'])) - subprefix = lambda {|path| - re === path and path.sub(re, '$prefix') - } + attr_writer :verbose - if c['rubylibdir'] - # V < 1.6.3 - stdruby = subprefix.call(c['rubylibdir']) - siteruby = subprefix.call(c['sitedir']) - versite = subprefix.call(c['sitelibdir']) - sodir = subprefix.call(c['sitearchdir']) - elsif newpath_p - # 1.4.4 <= V <= 1.6.3 - stdruby = "$prefix/lib/ruby/#{version}" - siteruby = subprefix.call(c['sitedir']) - versite = siteruby + '/' + version - sodir = "$site-ruby/#{c['arch']}" - else - # V < 1.4.4 - stdruby = "$prefix/lib/ruby/#{version}" - siteruby = "$prefix/lib/ruby/#{version}/site_ruby" - versite = siteruby - sodir = "$site-ruby/#{c['arch']}" - end - - DESCRIPTER = [ - [ 'prefix', [ c['prefix'], - 'path', - 'path prefix of target environment' ] ], - [ 'std-ruby', [ stdruby, - 'path', - 'the directory for standard ruby libraries' ] ], - [ 'site-ruby-common', [ siteruby, - 'path', - 'the directory for version-independent non-standard ruby libraries' ] ], - [ 'site-ruby', [ versite, - 'path', - 'the directory for non-standard ruby libraries' ] ], - [ 'bin-dir', [ '$prefix/bin', - 'path', - 'the directory for commands' ] ], - [ 'rb-dir', [ '$site-ruby', - 'path', - 'the directory for ruby scripts' ] ], - [ 'so-dir', [ sodir, - 'path', - 'the directory for ruby extentions' ] ], - [ 'data-dir', [ '$prefix/share', - 'path', - 'the directory for shared data' ] ], - [ 'ruby-path', [ rubypath, - 'path', - 'path to set to #! line' ] ], - [ 'ruby-prog', [ rubypath, - 'name', - 'the ruby program using for installation' ] ], - [ 'make-prog', [ 'make', - 'name', - 'the make program to compile ruby extentions' ] ], - [ 'without-ext', [ 'no', - 'yes/no', - 'does not compile/install ruby extentions' ] ] - ] + def verbose? + @verbose + end - SAVE_FILE = 'config.save' + attr_writer :no_harm - def ConfigTable.each_name( &block ) - keys().each(&block) + def no_harm? + @no_harm end - def ConfigTable.keys - DESCRIPTER.map {|k,*dummy| k } + def [](key) + lookup(key).resolve(self) end - def ConfigTable.each_definition( &block ) - DESCRIPTER.each(&block) + def []=(key, val) + lookup(key).set val end - def ConfigTable.get_entry( name ) - name, ent = DESCRIPTER.assoc(name) - ent + def names + @items.map {|i| i.name } end - def ConfigTable.get_entry!( name ) - get_entry(name) or raise ArgumentError, "no such config: #{name}" + def each(&block) + @items.each(&block) end - def ConfigTable.add_entry( name, vals ) - ConfigTable::DESCRIPTER.push [name,vals] + def key?(name) + @table.key?(name) end - def ConfigTable.remove_entry( name ) - get_entry name or raise ArgumentError, "no such config: #{name}" - DESCRIPTER.delete_if {|n,arr| n == name } + def lookup(name) + @table[name] or setup_rb_error "no such config item: #{name}" end - def ConfigTable.config_key?( name ) - get_entry(name) ? true : false + def add(item) + @items.push item + @table[item.name] = item end - def ConfigTable.bool_config?( name ) - ent = get_entry(name) or return false - ent[1] == 'yes/no' + def remove(name) + item = lookup(name) + @items.delete_if {|i| i.name == name } + @table.delete_if {|name, i| i.name == name } + item end - def ConfigTable.value_config?( name ) - ent = get_entry(name) or return false - ent[1] != 'yes/no' + def load_script(path, inst = nil) + if File.file?(path) + MetaConfigEnvironment.new(self, inst).instance_eval File.read(path), path + end end - def ConfigTable.path_config?( name ) - ent = get_entry(name) or return false - ent[1] == 'path' + def savefile + '.config' end - - class << self - alias newobj new - - def new - c = newobj() - c.__send__ :init - c - end - - def load - c = newobj() - raise InstallError, "#{File.basename $0} config first"\ - unless FileTest.file?(SAVE_FILE) - File.foreach(SAVE_FILE) do |line| - k, v = line.split(/=/, 2) - c.instance_eval { - @table[k] = v.strip - } + def load_savefile + begin + File.foreach(savefile()) do |line| + k, v = *line.split(/=/, 2) + self[k] = v.strip end - c + rescue Errno::ENOENT + setup_rb_error $!.message + "\n#{File.basename($0)} config first" end end - def initialize - @table = {} + def save + @items.each {|i| i.value } + File.open(savefile(), 'w') {|f| + @items.each do |i| + f.printf "%s=%s\n", i.name, i.value if i.value? and i.value + end + } end - def init - DESCRIPTER.each do |k, (default, vname, desc, default2)| - @table[k] = default + def load_standard_entries + standard_entries(@rbconfig).each do |ent| + add ent end end - private :init - def save - File.open(SAVE_FILE, 'w') {|f| - @table.each do |k, v| - f.printf "%s=%s\n", k, v if v - end + def standard_entries(rbconfig) + c = rbconfig + + rubypath = File.join(c['bindir'], c['ruby_install_name'] + c['EXEEXT']) + + major = c['MAJOR'].to_i + minor = c['MINOR'].to_i + teeny = c['TEENY'].to_i + version = "#{major}.#{minor}" + + # ruby ver. >= 1.4.4? + newpath_p = ((major >= 2) or + ((major == 1) and + ((minor >= 5) or + ((minor == 4) and (teeny >= 4))))) + + if c['rubylibdir'] + # V > 1.6.3 + libruby = "#{c['prefix']}/lib/ruby" + librubyver = c['rubylibdir'] + librubyverarch = c['archdir'] + siteruby = c['sitedir'] + siterubyver = c['sitelibdir'] + siterubyverarch = c['sitearchdir'] + elsif newpath_p + # 1.4.4 <= V <= 1.6.3 + libruby = "#{c['prefix']}/lib/ruby" + librubyver = "#{c['prefix']}/lib/ruby/#{version}" + librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}" + siteruby = c['sitedir'] + siterubyver = "$siteruby/#{version}" + siterubyverarch = "$siterubyver/#{c['arch']}" + else + # V < 1.4.4 + libruby = "#{c['prefix']}/lib/ruby" + librubyver = "#{c['prefix']}/lib/ruby/#{version}" + librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}" + siteruby = "#{c['prefix']}/lib/ruby/#{version}/site_ruby" + siterubyver = siteruby + siterubyverarch = "$siterubyver/#{c['arch']}" + end + parameterize = lambda {|path| + path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix') } - end - def []=( k, v ) - ConfigTable.config_key? k or raise InstallError, "unknown config option #{k}" - if ConfigTable.path_config? k - @table[k] = (v[0,1] != '$') ? File.expand_path(v) : v + if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg } + makeprog = arg.sub(/'/, '').split(/=/, 2)[1] else - @table[k] = v + makeprog = 'make' + end + + [ + ExecItem.new('installdirs', 'std/site/home', + 'std: install under libruby; site: install under site_ruby; home: install under $HOME')\ + {|val, table| + case val + when 'std' + table['rbdir'] = '$librubyver' + table['sodir'] = '$librubyverarch' + when 'site' + table['rbdir'] = '$siterubyver' + table['sodir'] = '$siterubyverarch' + when 'home' + setup_rb_error '$HOME was not set' unless ENV['HOME'] + table['prefix'] = ENV['HOME'] + table['rbdir'] = '$libdir/ruby' + table['sodir'] = '$libdir/ruby' + end + }, + PathItem.new('prefix', 'path', c['prefix'], + 'path prefix of target environment'), + PathItem.new('bindir', 'path', parameterize.call(c['bindir']), + 'the directory for commands'), + PathItem.new('libdir', 'path', parameterize.call(c['libdir']), + 'the directory for libraries'), + PathItem.new('datadir', 'path', parameterize.call(c['datadir']), + 'the directory for shared data'), + PathItem.new('mandir', 'path', parameterize.call(c['mandir']), + 'the directory for man pages'), + PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']), + 'the directory for system configuration files'), + PathItem.new('localstatedir', 'path', parameterize.call(c['localstatedir']), + 'the directory for local state data'), + PathItem.new('libruby', 'path', libruby, + 'the directory for ruby libraries'), + PathItem.new('librubyver', 'path', librubyver, + 'the directory for standard ruby libraries'), + PathItem.new('librubyverarch', 'path', librubyverarch, + 'the directory for standard ruby extensions'), + PathItem.new('siteruby', 'path', siteruby, + 'the directory for version-independent aux ruby libraries'), + PathItem.new('siterubyver', 'path', siterubyver, + 'the directory for aux ruby libraries'), + PathItem.new('siterubyverarch', 'path', siterubyverarch, + 'the directory for aux ruby binaries'), + PathItem.new('rbdir', 'path', '$siterubyver', + 'the directory for ruby scripts'), + PathItem.new('sodir', 'path', '$siterubyverarch', + 'the directory for ruby extentions'), + PathItem.new('rubypath', 'path', rubypath, + 'the path to set to #! line'), + ProgramItem.new('rubyprog', 'name', rubypath, + 'the ruby program using for installation'), + ProgramItem.new('makeprog', 'name', makeprog, + 'the make program to compile ruby extentions'), + SelectItem.new('shebang', 'all/ruby/never', 'ruby', + 'shebang line (#!) editing mode'), + BoolItem.new('without-ext', 'yes/no', 'no', + 'does not compile/install ruby extentions') + ] + end + private :standard_entries + + def load_multipackage_entries + multipackage_entries().each do |ent| + add ent + end + end + + def multipackage_entries + [ + PackageSelectionItem.new('with', 'name,name...', '', 'ALL', + 'package names that you want to install'), + PackageSelectionItem.new('without', 'name,name...', '', 'NONE', + 'package names that you do not want to install') + ] + end + private :multipackage_entries + + ALIASES = { + 'std-ruby' => 'librubyver', + 'stdruby' => 'librubyver', + 'rubylibdir' => 'librubyver', + 'archdir' => 'librubyverarch', + 'site-ruby-common' => 'siteruby', # For backward compatibility + 'site-ruby' => 'siterubyver', # For backward compatibility + 'bin-dir' => 'bindir', + 'bin-dir' => 'bindir', + 'rb-dir' => 'rbdir', + 'so-dir' => 'sodir', + 'data-dir' => 'datadir', + 'ruby-path' => 'rubypath', + 'ruby-prog' => 'rubyprog', + 'ruby' => 'rubyprog', + 'make-prog' => 'makeprog', + 'make' => 'makeprog' + } + + def fixup + ALIASES.each do |ali, name| + @table[ali] = @table[name] end + @items.freeze + @table.freeze + @options_re = /\A--(#{@table.keys.join('|')})(?:=(.*))?\z/ end - - def []( key ) - @table[key] or return nil - @table[key].gsub(%r<\$([^/]+)>) { self[$1] } + + def parse_opt(opt) + m = @options_re.match(opt) or setup_rb_error "config: unknown option #{opt}" + m.to_a[1,2] end - def set_raw( key, val ) - @table[key] = val + def dllext + @rbconfig['DLEXT'] end - def get_raw( key ) - @table[key] + def value_config?(name) + lookup(name).value? end -end + class Item + def initialize(name, template, default, desc) + @name = name.freeze + @template = template + @value = default + @default = default + @description = desc + end + attr_reader :name + attr_reader :description -module MetaConfigAPI + attr_accessor :default + alias help_default default - def eval_file_ifexist( fname ) - instance_eval File.read_all(fname), fname, 1 if FileTest.file?(fname) - end + def help_opt + "--#{@name}=#{@template}" + end - def config_names - ConfigTable.keys - end + def value? + true + end - def config?( name ) - ConfigTable.config_key? name - end + def value + @value + end + + def resolve(table) + @value.gsub(%r<\$([^/]+)>) { table[$1] } + end + + def set(val) + @value = check(val) + end + + private - def bool_config?( name ) - ConfigTable.bool_config? name + def check(val) + setup_rb_error "config: --#{name} requires argument" unless val + val + end end - def value_config?( name ) - ConfigTable.value_config? name + class BoolItem < Item + def config_type + 'bool' + end + + def help_opt + "--#{@name}" + end + + private + + def check(val) + return 'yes' unless val + case val + when /\Ay(es)?\z/i, /\At(rue)?\z/i then 'yes' + when /\An(o)?\z/i, /\Af(alse)\z/i then 'no' + else + setup_rb_error "config: --#{@name} accepts only yes/no for argument" + end + end end - def path_config?( name ) - ConfigTable.path_config? name + class PathItem < Item + def config_type + 'path' + end + + private + + def check(path) + setup_rb_error "config: --#{@name} requires argument" unless path + path[0,1] == '$' ? path : File.expand_path(path) + end end - def add_config( name, argname, default, desc ) - ConfigTable.add_entry name,[default,argname,desc] + class ProgramItem < Item + def config_type + 'program' + end end - def add_path_config( name, default, desc ) - add_config name, 'path', default, desc + class SelectItem < Item + def initialize(name, selection, default, desc) + super + @ok = selection.split('/') + end + + def config_type + 'select' + end + + private + + def check(val) + unless @ok.include?(val.strip) + setup_rb_error "config: use --#{@name}=#{@template} (#{val})" + end + val.strip + end end - def add_bool_config( name, default, desc ) - add_config name, 'yes/no', default ? 'yes' : 'no', desc + class ExecItem < Item + def initialize(name, selection, desc, &block) + super name, selection, nil, desc + @ok = selection.split('/') + @action = block + end + + def config_type + 'exec' + end + + def value? + false + end + + def resolve(table) + setup_rb_error "$#{name()} wrongly used as option value" + end + + undef set + + def evaluate(val, table) + v = val.strip.downcase + unless @ok.include?(v) + setup_rb_error "invalid option --#{@name}=#{val} (use #{@template})" + end + @action.call v, table + end end - def set_config_default( name, default ) - if bool_config? name - ConfigTable.get_entry!(name)[0] = default ? 'yes' : 'no' - else - ConfigTable.get_entry!(name)[0] = default + class PackageSelectionItem < Item + def initialize(name, template, default, help_default, desc) + super name, template, default, desc + @help_default = help_default + end + + attr_reader :help_default + + def config_type + 'package' + end + + private + + def check(val) + unless File.dir?("packages/#{val}") + setup_rb_error "config: no such package: #{val}" + end + val end end - def remove_config( name ) - ent = ConfigTable.get_entry(name) - ConfigTable.remove_entry name - ent + class MetaConfigEnvironment + def initialize(config, installer) + @config = config + @installer = installer + end + + def config_names + @config.names + end + + def config?(name) + @config.key?(name) + end + + def bool_config?(name) + @config.lookup(name).config_type == 'bool' + end + + def path_config?(name) + @config.lookup(name).config_type == 'path' + end + + def value_config?(name) + @config.lookup(name).config_type != 'exec' + end + + def add_config(item) + @config.add item + end + + def add_bool_config(name, default, desc) + @config.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc) + end + + def add_path_config(name, default, desc) + @config.add PathItem.new(name, 'path', default, desc) + end + + def set_config_default(name, default) + @config.lookup(name).default = default + end + + def remove_config(name) + @config.remove(name) + end + + # For only multipackage + def packages + raise '[setup.rb fatal] multi-package metaconfig API packages() called for single-package; contact application package vendor' unless @installer + @installer.packages + end + + # For only multipackage + def declare_packages(list) + raise '[setup.rb fatal] multi-package metaconfig API declare_packages() called for single-package; contact application package vendor' unless @installer + @installer.packages = list + end end -end +end # class ConfigTable -### end config.rb -### begin fileop.rb +# This module requires: #verbose?, #no_harm? module FileOperations - def mkdir_p( dname, prefix = nil ) - dname = prefix + dname if prefix - $stderr.puts "mkdir -p #{dname}" if verbose? + def mkdir_p(dirname, prefix = nil) + dirname = prefix + File.expand_path(dirname) if prefix + $stderr.puts "mkdir -p #{dirname}" if verbose? return if no_harm? - # does not check '/'... it's too abnormal case - dirs = dname.split(%r<(?=/)>) - if /\A[a-z]:\z/i === dirs[0] + # Does not check '/', it's too abnormal. + dirs = File.expand_path(dirname).split(%r<(?=/)>) + if /\A[a-z]:\z/i =~ dirs[0] disk = dirs.shift dirs[0] = disk + dirs[0] end dirs.each_index do |idx| path = dirs[0..idx].join('') - Dir.mkdir path unless dir? path + Dir.mkdir path unless File.dir?(path) end end - def rm_f( fname ) - $stderr.puts "rm -f #{fname}" if verbose? + def rm_f(path) + $stderr.puts "rm -f #{path}" if verbose? return if no_harm? - - if File.exist? fname or File.symlink? fname - File.chmod 0777, fname - File.unlink fname - end + force_remove_file path end - def rm_rf( dn ) - $stderr.puts "rm -rf #{dn}" if verbose? + def rm_rf(path) + $stderr.puts "rm -rf #{path}" if verbose? return if no_harm? + remove_tree path + end + + def remove_tree(path) + if File.symlink?(path) + remove_file path + elsif File.dir?(path) + remove_tree0 path + else + force_remove_file path + end + end - Dir.chdir dn - Dir.foreach('.') do |fn| - next if fn == '.' - next if fn == '..' - if dir? fn - verbose_off { - rm_rf fn - } + def remove_tree0(path) + Dir.foreach(path) do |ent| + next if ent == '.' + next if ent == '..' + entpath = "#{path}/#{ent}" + if File.symlink?(entpath) + remove_file entpath + elsif File.dir?(entpath) + remove_tree0 entpath else - verbose_off { - rm_f fn - } + force_remove_file entpath end end - Dir.chdir '..' - Dir.rmdir dn + begin + Dir.rmdir path + rescue Errno::ENOTEMPTY + # directory may not be empty + end end - def mv( src, dest ) - rm_f dest + def move_file(src, dest) + force_remove_file dest begin - File.link src, dest + File.rename src, dest rescue - File.write dest, File.read_all(src) + File.open(dest, 'wb') {|f| + f.write File.binread(src) + } File.chmod File.stat(src).mode, dest + File.unlink src + end + end + + def force_remove_file(path) + begin + remove_file path + rescue end - rm_f src end - def install( from, dest, mode, prefix = nil ) + def remove_file(path) + File.chmod 0777, path + File.unlink path + end + + def install(from, dest, mode, prefix = nil) $stderr.puts "install #{from} #{dest}" if verbose? return if no_harm? - realdest = prefix + dest if prefix - if dir? realdest - realdest += '/' + File.basename(from) - end - str = File.read_all(from) - if diff? str, realdest + realdest = prefix ? prefix + File.expand_path(dest) : dest + realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest) + str = File.binread(from) + if diff?(str, realdest) verbose_off { - rm_f realdest if File.exist? realdest + rm_f realdest if File.exist?(realdest) + } + File.open(realdest, 'wb') {|f| + f.write str } - File.write realdest, str File.chmod mode, realdest -# File.open(objdir + '/InstalledFiles', 'a') {|f| f.puts realdest } + File.open("#{objdir_root()}/InstalledFiles", 'a') {|f| + if prefix + f.puts realdest.sub(prefix, '') + else + f.puts realdest + end + } end end - def diff?( orig, targ ) - return true unless File.exist? targ - orig != File.read_all(targ) + def diff?(new_content, path) + return true unless File.exist?(path) + new_content != File.binread(path) end - def command( str ) - $stderr.puts str if verbose? - system str or raise RuntimeError, "'system #{str}' failed" + def command(*args) + $stderr.puts args.join(' ') if verbose? + system(*args) or raise RuntimeError, + "system(#{args.map{|a| a.inspect }.join(' ')}) failed" end - def ruby( str ) - command config('ruby-prog') + ' ' + str + def ruby(*args) + command config('rubyprog'), *args + end + + def make(task = nil) + command(*[config('makeprog'), task].compact) end - def dir?( dname ) - # for corrupted windows stat() - File.directory?((dname[-1,1] == '/') ? dname : dname + '/') + def extdir?(dir) + File.exist?("#{dir}/MANIFEST") or File.exist?("#{dir}/extconf.rb") end - def all_files_in( dname ) - Dir.open(dname) {|d| - return d.select {|n| FileTest.file? "#{dname}/#{n}" } + def files_of(dir) + Dir.open(dir) {|d| + return d.select {|ent| File.file?("#{dir}/#{ent}") } } end - REJECT_DIRS = %w( - CVS SCCS RCS CVS.adm .svn - ) + DIR_REJECT = %w( . .. CVS SCCS RCS CVS.adm .svn ) - def all_dirs_in( dname ) - Dir.open(dname) {|d| - return d.select {|n| dir? "#{dname}/#{n}" } - %w(. ..) - REJECT_DIRS + def directories_of(dir) + Dir.open(dir) {|d| + return d.select {|ent| File.dir?("#{dir}/#{ent}") } - DIR_REJECT } end end -### end fileop.rb -### begin base.rb - -class InstallError < StandardError; end - -class Installer - - Version = '3.1.4' - Copyright = 'Copyright (c) 2000-2003 Minero Aoki' - - - @toplevel = nil - - def self.declare_toplevel_installer( inst ) - raise ArgumentError, 'two toplevel installers declared' if @toplevel - @toplevel = inst - end - - def self.toplevel_installer - @toplevel - end - - - FILETYPES = %w( bin lib ext data ) - - include FileOperations - - def initialize( config, opt, srcroot, objroot ) - @config = config - @options = opt - @srcdir = File.expand_path(srcroot) - @objdir = File.expand_path(objroot) - @currdir = '.' - end - - def inspect - "#<#{self.class} #{__id__}>" - end - - # - # configs/options - # +# This module requires: #srcdir_root, #objdir_root, #relpath +module HookScriptAPI - def get_config( key ) + def get_config(key) @config[key] end alias config get_config - def set_config( key, val ) + # obsolete: use metaconfig to change configuration + def set_config(key, val) @config[key] = val end - def no_harm? - @options['no-harm'] - end - - def verbose? - @options['verbose'] - end - - def verbose_off - save, @options['verbose'] = @options['verbose'], false - yield - @options['verbose'] = save - end - # - # srcdir/objdir + # srcdir/objdir (works only in the package directory) # - attr_reader :srcdir - alias srcdir_root srcdir - alias package_root srcdir - def curr_srcdir - "#{@srcdir}/#{@currdir}" + "#{srcdir_root()}/#{relpath()}" end - attr_reader :objdir - alias objdir_root objdir - def curr_objdir - "#{@objdir}/#{@currdir}" + "#{objdir_root()}/#{relpath()}" end - def srcfile( path ) - curr_srcdir + '/' + path + def srcfile(path) + "#{curr_srcdir()}/#{path}" end - def srcexist?( path ) - File.exist? srcfile(path) + def srcexist?(path) + File.exist?(srcfile(path)) end - def srcdirectory?( path ) - dir? srcfile(path) + def srcdirectory?(path) + File.dir?(srcfile(path)) end - def srcfile?( path ) - FileTest.file? srcfile(path) + def srcfile?(path) + File.file?(srcfile(path)) end - def srcentries( path = '.' ) - Dir.open(curr_srcdir + '/' + path) {|d| - return d.to_a - %w(. ..) - hookfilenames + def srcentries(path = '.') + Dir.open("#{curr_srcdir()}/#{path}") {|d| + return d.to_a - %w(. ..) } end - def srcfiles( path = '.' ) + def srcfiles(path = '.') srcentries(path).select {|fname| - FileTest.file? File.join(curr_srcdir, path, fname) + File.file?(File.join(curr_srcdir(), path, fname)) } end - def srcdirectories( path = '.' ) + def srcdirectories(path = '.') srcentries(path).select {|fname| - dir? File.join(curr_srcdir, path, fname) + File.dir?(File.join(curr_srcdir(), path, fname)) } end - def dive_into( rel ) - return unless dir?("#{@srcdir}/#{rel}") +end - dir = File.basename(rel) - Dir.mkdir dir unless dir?(dir) - prevdir = Dir.pwd - Dir.chdir dir - $stderr.puts '---> ' + rel if verbose? - @currdir = rel - yield - Dir.chdir prevdir - $stderr.puts '<--- ' + rel if verbose? - @currdir = File.dirname(rel) - end - # - # TASK config - # +class ToplevelInstaller - def exec_config - exec_task_traverse 'config' - end + Version = '3.4.1' + Copyright = 'Copyright (c) 2000-2005 Minero Aoki' - def config_dir_bin( rel ) - end + TASKS = [ + [ 'all', 'do config, setup, then install' ], + [ 'config', 'saves your configurations' ], + [ 'show', 'shows current configuration' ], + [ 'setup', 'compiles ruby extentions and others' ], + [ 'install', 'installs files' ], + [ 'test', 'run all tests in test/' ], + [ 'clean', "does `make clean' for each extention" ], + [ 'distclean',"does `make distclean' for each extention" ] + ] - def config_dir_lib( rel ) + def ToplevelInstaller.invoke + config = ConfigTable.new(load_rbconfig()) + config.load_standard_entries + config.load_multipackage_entries if multipackage? + config.fixup + klass = (multipackage?() ? ToplevelInstallerMulti : ToplevelInstaller) + klass.new(File.dirname($0), config).invoke end - def config_dir_ext( rel ) - extconf if extdir? curr_srcdir + def ToplevelInstaller.multipackage? + File.dir?(File.dirname($0) + '/packages') end - def extconf - opt = @options['config-opt'].join(' ') - command "#{config('ruby-prog')} #{curr_srcdir}/extconf.rb #{opt}" + def ToplevelInstaller.load_rbconfig + if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg } + ARGV.delete(arg) + load File.expand_path(arg.split(/=/, 2)[1]) + $".push 'rbconfig.rb' + else + require 'rbconfig' + end + ::Config::CONFIG end - def config_dir_data( rel ) + def initialize(ardir_root, config) + @ardir = File.expand_path(ardir_root) + @config = config + # cache + @valid_task_re = nil end - # - # TASK setup - # - - def exec_setup - exec_task_traverse 'setup' + def config(key) + @config[key] end - def setup_dir_bin( relpath ) - all_files_in(curr_srcdir()).each do |fname| - add_rubypath "#{curr_srcdir}/#{fname}" - end + def inspect + "#<#{self.class} #{__id__()}>" end - SHEBANG_RE = /\A\#!\s*\S*ruby\S*/ - - def add_rubypath( path ) - $stderr.puts %Q<set #! line to "\#!#{config('ruby-path')}" for #{path} ...> if verbose? - return if no_harm? - - tmpfile = File.basename(path) + '.tmp' - begin - File.open(path) {|r| - File.open(tmpfile, 'w') {|w| - first = r.gets - return unless SHEBANG_RE === first # reject '/usr/bin/env ruby' - - w.print first.sub(SHEBANG_RE, '#!' + config('ruby-path')) - w.write r.read - } } - mv tmpfile, File.basename(path) - ensure - rm_f tmpfile if File.exist? tmpfile + def invoke + run_metaconfigs + case task = parsearg_global() + when nil, 'all' + parsearg_config + init_installers + exec_config + exec_setup + exec_install + else + case task + when 'config', 'test' + ; + when 'clean', 'distclean' + @config.load_savefile if File.exist?(@config.savefile) + else + @config.load_savefile + end + __send__ "parsearg_#{task}" + init_installers + __send__ "exec_#{task}" end end - - def setup_dir_lib( relpath ) - end - - def setup_dir_ext( relpath ) - make if extdir?(curr_srcdir) + + def run_metaconfigs + @config.load_script "#{@ardir}/metaconfig" end - def setup_dir_data( relpath ) + def init_installers + @installer = Installer.new(@config, @ardir, File.expand_path('.')) end # - # TASK install + # Hook Script API bases # - def exec_install - exec_task_traverse 'install' - end - - def install_dir_bin( rel ) - install_files target_filenames(), config('bin-dir') + '/' + rel, 0755 + def srcdir_root + @ardir end - def install_dir_lib( rel ) - install_files target_filenames(), config('rb-dir') + '/' + rel, 0644 + def objdir_root + '.' end - def install_dir_ext( rel ) - install_dir_ext_main File.dirname(rel) if extdir?(curr_srcdir) + def relpath + '.' end - def install_dir_ext_main( rel ) - install_files allext('.'), config('so-dir') + '/' + rel, 0555 + # + # Option Parsing + # + + def parsearg_global + while arg = ARGV.shift + case arg + when /\A\w+\z/ + setup_rb_error "invalid task: #{arg}" unless valid_task?(arg) + return arg + when '-q', '--quiet' + @config.verbose = false + when '--verbose' + @config.verbose = true + when '--help' + print_usage $stdout + exit 0 + when '--version' + puts "#{File.basename($0)} version #{Version}" + exit 0 + when '--copyright' + puts Copyright + exit 0 + else + setup_rb_error "unknown global option '#{arg}'" + end + end + nil end - def install_dir_data( rel ) - install_files target_filenames(), config('data-dir') + '/' + rel, 0644 + def valid_task?(t) + valid_task_re() =~ t end - def install_files( list, dest, mode ) - mkdir_p dest, @options['install-prefix'] - list.each do |fname| - install fname, dest, mode, @options['install-prefix'] + def valid_task_re + @valid_task_re ||= /\A(?:#{TASKS.map {|task,desc| task }.join('|')})\z/ + end + + def parsearg_no_options + unless ARGV.empty? + task = caller(0).first.slice(%r<`parsearg_(\w+)'>, 1) + setup_rb_error "#{task}: unknown options: #{ARGV.join(' ')}" end end - def target_filenames - if FileTest.file? "#{curr_srcdir()}/MANIFEST" - mapdir(target_filenames_MANIFEST()) - else - mapdir(target_filenames_AUTO()) + alias parsearg_show parsearg_no_options + alias parsearg_setup parsearg_no_options + alias parsearg_test parsearg_no_options + alias parsearg_clean parsearg_no_options + alias parsearg_distclean parsearg_no_options + + def parsearg_config + evalopt = [] + set = [] + @config.config_opt = [] + while i = ARGV.shift + if /\A--?\z/ =~ i + @config.config_opt = ARGV.dup + break + end + name, value = *@config.parse_opt(i) + if @config.value_config?(name) + @config[name] = value + else + evalopt.push [name, value] + end + set.push name + end + evalopt.each do |name, value| + @config.lookup(name).evaluate value, @config + end + # Check if configuration is valid + set.each do |n| + @config[n] if @config.value_config?(n) end end - def mapdir( filelist ) - filelist.map {|fname| - if File.exist? fname # current objdir == '.' - fname - else - File.join(curr_srcdir(), fname) - end - } + def parsearg_install + @config.no_harm = false + @config.install_prefix = '' + while a = ARGV.shift + case a + when '--no-harm' + @config.no_harm = true + when /\A--prefix=/ + path = a.split(/=/, 2)[1] + path = File.expand_path(path) unless path[0,1] == '/' + @config.install_prefix = path + else + setup_rb_error "install: unknown option #{a}" + end + end end - def target_filenames_MANIFEST - File.read_all("#{curr_srcdir()}/MANIFEST").split + def print_usage(out) + out.puts 'Typical Installation Procedure:' + out.puts " $ ruby #{File.basename $0} config" + out.puts " $ ruby #{File.basename $0} setup" + out.puts " # ruby #{File.basename $0} install (may require root privilege)" + out.puts + out.puts 'Detailed Usage:' + out.puts " ruby #{File.basename $0} <global option>" + out.puts " ruby #{File.basename $0} [<global options>] <task> [<task options>]" + + fmt = " %-24s %s\n" + out.puts + out.puts 'Global options:' + out.printf fmt, '-q,--quiet', 'suppress message outputs' + out.printf fmt, ' --verbose', 'output messages verbosely' + out.printf fmt, ' --help', 'print this message' + out.printf fmt, ' --version', 'print version and quit' + out.printf fmt, ' --copyright', 'print copyright and quit' + out.puts + out.puts 'Tasks:' + TASKS.each do |name, desc| + out.printf fmt, name, desc + end + + fmt = " %-24s %s [%s]\n" + out.puts + out.puts 'Options for CONFIG or ALL:' + @config.each do |item| + out.printf fmt, item.help_opt, item.description, item.help_default + end + out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's" + out.puts + out.puts 'Options for INSTALL:' + out.printf fmt, '--no-harm', 'only display what to do if given', 'off' + out.printf fmt, '--prefix=path', 'install path prefix', '' + out.puts end - - # picked up many entries from cvs-1.11.1/src/ignore.c - REJECT_PATTERNS = %w( - core RCSLOG tags TAGS .make.state - .nse_depinfo #* .#* cvslog.* ,* .del-* *.a *.olb *.o *.obj - *.so *.Z *~ *.old *.elc *.ln *.bak *.BAK *.orig *.rej *.exe _$* *$ - - *.org *.in .* - ).map {|pattern| - Regexp.compile('\A' + pattern.gsub(/[\.\$]/) {|s| '\\' + s }.gsub(/\*/, '.*') + '\z') - } - def target_filenames_AUTO - (existfiles() - hookfiles()).reject {|fname| - REJECT_PATTERNS.any? {|re| re === fname } - } + # + # Task Handlers + # + + def exec_config + @installer.exec_config + @config.save # must be final end - def existfiles - all_files_in(curr_srcdir()) | all_files_in(curr_objdir()) + def exec_setup + @installer.exec_setup end - def hookfiles - %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt| - %w( config setup install clean ).map {|t| sprintf(fmt, t) } - }.flatten + def exec_install + @installer.exec_install end - def allext( dir ) - _allext(dir) or raise InstallError, - "no extention exists: Have you done 'ruby #{$0} setup' ?" + def exec_test + @installer.exec_test end - DLEXT = /\.#{ ::Config::CONFIG['DLEXT'] }\z/ + def exec_show + @config.each do |i| + printf "%-20s %s\n", i.name, i.value if i.value? + end + end - def _allext( dir ) - Dir.open(dir) {|d| - return d.select {|fname| DLEXT === fname } - } + def exec_clean + @installer.exec_clean end - # - # TASK clean - # + def exec_distclean + @installer.exec_distclean + end - def exec_clean - exec_task_traverse 'clean' - rm_f 'config.save' - rm_f 'InstalledFiles' +end # class ToplevelInstaller + + +class ToplevelInstallerMulti < ToplevelInstaller + + include FileOperations + + def initialize(ardir_root, config) + super + @packages = directories_of("#{@ardir}/packages") + raise 'no package exists' if @packages.empty? + @root_installer = Installer.new(@config, @ardir, File.expand_path('.')) end - def clean_dir_bin( rel ) + def run_metaconfigs + @config.load_script "#{@ardir}/metaconfig", self + @packages.each do |name| + @config.load_script "#{@ardir}/packages/#{name}/metaconfig" + end end - def clean_dir_lib( rel ) + attr_reader :packages + + def packages=(list) + raise 'package list is empty' if list.empty? + list.each do |name| + raise "directory packages/#{name} does not exist"\ + unless File.dir?("#{@ardir}/packages/#{name}") + end + @packages = list end - def clean_dir_ext( rel ) - make 'clean' if FileTest.file?('Makefile') + def init_installers + @installers = {} + @packages.each do |pack| + @installers[pack] = Installer.new(@config, + "#{@ardir}/packages/#{pack}", + "packages/#{pack}") + end + with = extract_selection(config('with')) + without = extract_selection(config('without')) + @selected = @installers.keys.select {|name| + (with.empty? or with.include?(name)) \ + and not without.include?(name) + } + end + + def extract_selection(list) + a = list.split(/,/) + a.each do |name| + setup_rb_error "no such package: #{name}" unless @installers.key?(name) + end + a end - def clean_dir_data( rel ) + def print_usage(f) + super + f.puts 'Inluded packages:' + f.puts ' ' + @packages.sort.join(' ') + f.puts end # - # TASK distclean + # Task Handlers # - def exec_distclean - exec_task_traverse 'distclean' - rm_f 'config.save' - rm_f 'InstalledFiles' + def exec_config + run_hook 'pre-config' + each_selected_installers {|inst| inst.exec_config } + run_hook 'post-config' + @config.save # must be final + end + + def exec_setup + run_hook 'pre-setup' + each_selected_installers {|inst| inst.exec_setup } + run_hook 'post-setup' end - def distclean_dir_bin( rel ) + def exec_install + run_hook 'pre-install' + each_selected_installers {|inst| inst.exec_install } + run_hook 'post-install' end - def distclean_dir_lib( rel ) + def exec_test + run_hook 'pre-test' + each_selected_installers {|inst| inst.exec_test } + run_hook 'post-test' end - def distclean_dir_ext( rel ) - make 'distclean' if FileTest.file?('Makefile') + def exec_clean + rm_f @config.savefile + run_hook 'pre-clean' + each_selected_installers {|inst| inst.exec_clean } + run_hook 'post-clean' + end + + def exec_distclean + rm_f @config.savefile + run_hook 'pre-distclean' + each_selected_installers {|inst| inst.exec_distclean } + run_hook 'post-distclean' end # # lib # - - def make( task = '' ) - command config('make-prog') + ' ' + task - end - def exec_task_traverse( task ) - run_hook 'pre-' + task - FILETYPES.each do |type| - if config('without-ext') == 'yes' and type == 'ext' - $stderr.puts 'skipping ext/* by user option' if verbose? - next - end - traverse task, type, task + '_dir_' + type + def each_selected_installers + Dir.mkdir 'packages' unless File.dir?('packages') + @selected.each do |pack| + $stderr.puts "Processing the package `#{pack}' ..." if verbose? + Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}") + Dir.chdir "packages/#{pack}" + yield @installers[pack] + Dir.chdir '../..' end - run_hook 'post-' + task end - def traverse( task, rel, mid ) - dive_into(rel) { - run_hook 'pre-' + task - __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '') - all_dirs_in(curr_srcdir()).each do |d| - traverse task, rel + '/' + d, mid - end - run_hook 'post-' + task - } + def run_hook(id) + @root_installer.run_hook id end - def run_hook( name ) - try_run_hook curr_srcdir + '/' + name or - try_run_hook curr_srcdir + '/' + name + '.rb' + # module FileOperations requires this + def verbose? + @config.verbose? end - def try_run_hook( fname ) - return false unless FileTest.file?(fname) + # module FileOperations requires this + def no_harm? + @config.no_harm? + end - env = self.dup - begin - env.instance_eval File.read_all(fname), fname, 1 - rescue - raise InstallError, "hook #{fname} failed:\n" + $!.message - end - true +end # class ToplevelInstallerMulti + + +class Installer + + FILETYPES = %w( bin lib ext data conf man ) + + include FileOperations + include HookScriptAPI + + def initialize(config, srcroot, objroot) + @config = config + @srcdir = File.expand_path(srcroot) + @objdir = File.expand_path(objroot) + @currdir = '.' end - def extdir?( dir ) - File.exist? dir + '/MANIFEST' + def inspect + "#<#{self.class} #{File.basename(@srcdir)}>" end -end + def noop(rel) + end -### end base.rb -### begin toplevel.rb + # + # Hook Script API base methods + # -class ToplevelInstaller < Installer + def srcdir_root + @srcdir + end - def self.invoke - new(File.dirname($0)).invoke + def objdir_root + @objdir end + def relpath + @currdir + end - TASKS = [ - [ 'config', 'saves your configurations' ], - [ 'show', 'shows current configuration' ], - [ 'setup', 'compiles extention or else' ], - [ 'install', 'installs files' ], - [ 'clean', "does `make clean' for each extention" ], - [ 'distclean',"does `make distclean' for each extention" ] - ] + # + # Config Access + # + # module FileOperations requires this + def verbose? + @config.verbose? + end - def initialize( root ) - super nil, {'verbose' => true}, root, '.' - Installer.declare_toplevel_installer self + # module FileOperations requires this + def no_harm? + @config.no_harm? end + def verbose_off + begin + save, @config.verbose = @config.verbose?, false + yield + ensure + @config.verbose = save + end + end - def invoke - run_metaconfigs + # + # TASK config + # - case task = parsearg_global() - when 'config' - @config = ConfigTable.new - else - @config = ConfigTable.load - end - parsearg_TASK task + def exec_config + exec_task_traverse 'config' + end + + alias config_dir_bin noop + alias config_dir_lib noop - exectask task + def config_dir_ext(rel) + extconf if extdir?(curr_srcdir()) end - include MetaConfigAPI + alias config_dir_data noop + alias config_dir_conf noop + alias config_dir_man noop - def run_metaconfigs - eval_file_ifexist "#{srcdir_root()}/metaconfig" + def extconf + ruby "#{curr_srcdir()}/extconf.rb", *@config.config_opt + end + + # + # TASK setup + # + + def exec_setup + exec_task_traverse 'setup' + end + + def setup_dir_bin(rel) + files_of(curr_srcdir()).each do |fname| + update_shebang_line "#{curr_srcdir()}/#{fname}" + end end + alias setup_dir_lib noop + + def setup_dir_ext(rel) + make if extdir?(curr_srcdir()) + end + + alias setup_dir_data noop + alias setup_dir_conf noop + alias setup_dir_man noop + + def update_shebang_line(path) + return if no_harm? + return if config('shebang') == 'never' + old = Shebang.load(path) + if old + $stderr.puts "warning: #{path}: Shebang line includes too many args. It is not portable and your program may not work." if old.args.size > 1 + new = new_shebang(old) + return if new.to_s == old.to_s + else + return unless config('shebang') == 'all' + new = Shebang.new(config('rubypath')) + end + $stderr.puts "updating shebang: #{File.basename(path)}" if verbose? + open_atomic_writer(path) {|output| + File.open(path, 'rb') {|f| + f.gets if old # discard + output.puts new.to_s + output.print f.read + } + } + end - def exectask( task ) - if task == 'show' - exec_show + def new_shebang(old) + if /\Aruby/ =~ File.basename(old.cmd) + Shebang.new(config('rubypath'), old.args) + elsif File.basename(old.cmd) == 'env' and old.args.first == 'ruby' + Shebang.new(config('rubypath'), old.args[1..-1]) else - try task + return old unless config('shebang') == 'all' + Shebang.new(config('rubypath')) end end - def try( task ) - $stderr.printf "#{File.basename $0}: entering %s phase...\n", task if verbose? + def open_atomic_writer(path, &block) + tmpfile = File.basename(path) + '.tmp' begin - __send__ 'exec_' + task - rescue - $stderr.printf "%s failed\n", task - raise + File.open(tmpfile, 'wb', &block) + File.rename tmpfile, File.basename(path) + ensure + File.unlink tmpfile if File.exist?(tmpfile) + end + end + + class Shebang + def Shebang.load(path) + line = nil + File.open(path) {|f| + line = f.gets + } + return nil unless /\A#!/ =~ line + parse(line) + end + + def Shebang.parse(line) + cmd, *args = *line.strip.sub(/\A\#!/, '').split(' ') + new(cmd, args) + end + + def initialize(cmd, args = []) + @cmd = cmd + @args = args + end + + attr_reader :cmd + attr_reader :args + + def to_s + "#! #{@cmd}" + (@args.empty? ? '' : " #{@args.join(' ')}") end - $stderr.printf "#{File.basename $0}: %s done.\n", task if verbose? end # - # processing arguments + # TASK install # - def parsearg_global - task_re = /\A(?:#{TASKS.map {|i| i[0] }.join '|'})\z/ + def exec_install + rm_f 'InstalledFiles' + exec_task_traverse 'install' + end - while arg = ARGV.shift - case arg - when /\A\w+\z/ - task_re === arg or raise InstallError, "wrong task: #{arg}" - return arg + def install_dir_bin(rel) + install_files targetfiles(), "#{config('bindir')}/#{rel}", 0755 + end - when '-q', '--quiet' - @options['verbose'] = false + def install_dir_lib(rel) + install_files libfiles(), "#{config('rbdir')}/#{rel}", 0644 + end - when '--verbose' - @options['verbose'] = true + def install_dir_ext(rel) + return unless extdir?(curr_srcdir()) + install_files rubyextentions('.'), + "#{config('sodir')}/#{File.dirname(rel)}", + 0555 + end - when '-h', '--help' - print_usage $stdout - exit 0 + def install_dir_data(rel) + install_files targetfiles(), "#{config('datadir')}/#{rel}", 0644 + end - when '-v', '--version' - puts "#{File.basename $0} version #{Version}" - exit 0 - - when '--copyright' - puts Copyright - exit 0 + def install_dir_conf(rel) + # FIXME: should not remove current config files + # (rename previous file to .old/.org) + install_files targetfiles(), "#{config('sysconfdir')}/#{rel}", 0644 + end - else - raise InstallError, "unknown global option '#{arg}'" - end - end + def install_dir_man(rel) + install_files targetfiles(), "#{config('mandir')}/#{rel}", 0644 + end - raise InstallError, "No task or global option given. -Typical installation procedure is: - $ ruby #{File.basename $0} config - $ ruby #{File.basename $0} setup - # ruby #{File.basename $0} install (may require root privilege) -" + def install_files(list, dest, mode) + mkdir_p dest, @config.install_prefix + list.each do |fname| + install fname, dest, mode, @config.install_prefix + end end + def libfiles + glob_reject(%w(*.y *.output), targetfiles()) + end - def parsearg_TASK( task ) - mid = "parsearg_#{task}" - if respond_to? mid, true - __send__ mid - else - ARGV.empty? or - raise InstallError, "#{task}: unknown options: #{ARGV.join ' '}" + def rubyextentions(dir) + ents = glob_select("*.#{@config.dllext}", targetfiles()) + if ents.empty? + setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first" end + ents end - def parsearg_config - re = /\A--(#{ConfigTable.keys.join '|'})(?:=(.*))?\z/ - @options['config-opt'] = [] + def targetfiles + mapdir(existfiles() - hookfiles()) + end - while i = ARGV.shift - if /\A--?\z/ === i - @options['config-opt'] = ARGV.dup - break - end - m = re.match(i) or raise InstallError, "config: unknown option #{i}" - name, value = m.to_a[1,2] - if value - if ConfigTable.bool_config?(name) - /\A(y(es)?|n(o)?|t(rue)?|f(alse))\z/i === value or raise InstallError, "config: --#{name} allows only yes/no for argument" - value = (/\Ay(es)?|\At(rue)/i === value) ? 'yes' : 'no' - end - else - ConfigTable.bool_config?(name) or raise InstallError, "config: --#{name} requires argument" - value = 'yes' + def mapdir(ents) + ents.map {|ent| + if File.exist?(ent) + then ent # objdir + else "#{curr_srcdir()}/#{ent}" # srcdir end - @config[name] = value - end + } end - def parsearg_install - @options['no-harm'] = false - @options['install-prefix'] = '' - while a = ARGV.shift - case a - when /\A--no-harm\z/ - @options['no-harm'] = true - when /\A--prefix=(.*)\z/ - path = $1 - path = File.expand_path(path) unless path[0,1] == '/' - @options['install-prefix'] = path - else - raise InstallError, "install: unknown option #{a}" - end - end + # picked up many entries from cvs-1.11.1/src/ignore.c + JUNK_FILES = %w( + core RCSLOG tags TAGS .make.state + .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb + *~ *.old *.bak *.BAK *.orig *.rej _$* *$ + + *.org *.in .* + ) + + def existfiles + glob_reject(JUNK_FILES, (files_of(curr_srcdir()) | files_of('.'))) end + def hookfiles + %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt| + %w( config setup install clean ).map {|t| sprintf(fmt, t) } + }.flatten + end - def print_usage( out ) - out.puts 'Typical Installation Procedure:' - out.puts " $ ruby #{File.basename $0} config" - out.puts " $ ruby #{File.basename $0} setup" - out.puts " # ruby #{File.basename $0} install (may require root privilege)" - out.puts - out.puts 'Detailed Usage:' - out.puts " ruby #{File.basename $0} <global option>" - out.puts " ruby #{File.basename $0} [<global options>] <task> [<task options>]" + def glob_select(pat, ents) + re = globs2re([pat]) + ents.select {|ent| re =~ ent } + end - fmt = " %-20s %s\n" - out.puts - out.puts 'Global options:' - out.printf fmt, '-q,--quiet', 'suppress message outputs' - out.printf fmt, ' --verbose', 'output messages verbosely' - out.printf fmt, '-h,--help', 'print this message' - out.printf fmt, '-v,--version', 'print version and quit' - out.printf fmt, ' --copyright', 'print copyright and quit' + def glob_reject(pats, ents) + re = globs2re(pats) + ents.reject {|ent| re =~ ent } + end - out.puts - out.puts 'Tasks:' - TASKS.each do |name, desc| - out.printf " %-10s %s\n", name, desc - end + GLOB2REGEX = { + '.' => '\.', + '$' => '\$', + '#' => '\#', + '*' => '.*' + } - out.puts - out.puts 'Options for config:' - ConfigTable.each_definition do |name, (default, arg, desc, default2)| - out.printf " %-20s %s [%s]\n", - '--'+ name + (ConfigTable.bool_config?(name) ? '' : '='+arg), - desc, - default2 || default + def globs2re(pats) + /\A(?:#{ + pats.map {|pat| pat.gsub(/[\.\$\#\*]/) {|ch| GLOB2REGEX[ch] } }.join('|') + })\z/ + end + + # + # TASK test + # + + TESTDIR = 'test' + + def exec_test + unless File.directory?('test') + $stderr.puts 'no test in this package' if verbose? + return + end + $stderr.puts 'Running tests...' if verbose? + begin + require 'test/unit' + rescue LoadError + setup_rb_error 'test/unit cannot loaded. You need Ruby 1.8 or later to invoke this task.' end - out.printf " %-20s %s [%s]\n", - '--rbconfig=path', 'your rbconfig.rb to load', "running ruby's" + runner = Test::Unit::AutoRunner.new(true) + runner.to_run << TESTDIR + runner.run + end - out.puts - out.puts 'Options for install:' - out.printf " %-20s %s [%s]\n", - '--no-harm', 'only display what to do if given', 'off' - out.printf " %-20s %s [%s]\n", - '--prefix', 'install path prefix', '$prefix' + # + # TASK clean + # - out.puts + def exec_clean + exec_task_traverse 'clean' + rm_f @config.savefile + rm_f 'InstalledFiles' + end + + alias clean_dir_bin noop + alias clean_dir_lib noop + alias clean_dir_data noop + alias clean_dir_conf noop + alias clean_dir_man noop + + def clean_dir_ext(rel) + return unless extdir?(curr_srcdir()) + make 'clean' if File.file?('Makefile') end # - # config + # TASK distclean # - def exec_config - super - @config.save + def exec_distclean + exec_task_traverse 'distclean' + rm_f @config.savefile + rm_f 'InstalledFiles' + end + + alias distclean_dir_bin noop + alias distclean_dir_lib noop + + def distclean_dir_ext(rel) + return unless extdir?(curr_srcdir()) + make 'distclean' if File.file?('Makefile') end + alias distclean_dir_data noop + alias distclean_dir_conf noop + alias distclean_dir_man noop + # - # show + # Traversing # - def exec_show - ConfigTable.each_name do |k| - v = @config.get_raw(k) - if not v or v.empty? - v = '(not specified)' + def exec_task_traverse(task) + run_hook "pre-#{task}" + FILETYPES.each do |type| + if type == 'ext' and config('without-ext') == 'yes' + $stderr.puts 'skipping ext/* by user option' if verbose? + next end - printf "%-10s %s\n", k, v + traverse task, type, "#{task}_dir_#{type}" end + run_hook "post-#{task}" end -end + def traverse(task, rel, mid) + dive_into(rel) { + run_hook "pre-#{task}" + __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '') + directories_of(curr_srcdir()).each do |d| + traverse task, "#{rel}/#{d}", mid + end + run_hook "post-#{task}" + } + end + + def dive_into(rel) + return unless File.dir?("#{@srcdir}/#{rel}") + + dir = File.basename(rel) + Dir.mkdir dir unless File.dir?(dir) + prevdir = Dir.pwd + Dir.chdir dir + $stderr.puts '---> ' + rel if verbose? + @currdir = rel + yield + Dir.chdir prevdir + $stderr.puts '<--- ' + rel if verbose? + @currdir = File.dirname(rel) + end -### end toplevel.rb + def run_hook(id) + path = [ "#{curr_srcdir()}/#{id}", + "#{curr_srcdir()}/#{id}.rb" ].detect {|cand| File.file?(cand) } + return unless path + begin + instance_eval File.read(path), path, 1 + rescue + raise if $DEBUG + setup_rb_error "hook #{path} failed:\n" + $!.message + end + end + +end # class Installer + + +class SetupError < StandardError; end + +def setup_rb_error(msg) + raise SetupError, msg +end if $0 == __FILE__ begin ToplevelInstaller.invoke - rescue + rescue SetupError raise if $DEBUG $stderr.puts $!.message $stderr.puts "Try 'ruby #{$0} --help' for detailed usage." diff --git a/lib/fox16/aliases.rb b/lib/fox16/aliases.rb index 4b2d42743eacf6977dbdccc4198354925f9ee98c..a4d08c30a190b03f91c7e4a069470e2625f0493e 100755 --- a/lib/fox16/aliases.rb +++ b/lib/fox16/aliases.rb @@ -2849,6 +2849,9 @@ module Fox def activeChild(*args) # :nodoc: getActiveChild(*args) end + def activeChild=(*args) # :nodoc: + setActiveChild(*args) + end def cascadeX=(*args) # :nodoc: setCascadeX(*args) end @@ -3571,6 +3574,7 @@ module Fox def position=(*args) # :nodoc: setPosition(*args) end + undef_method(:position) if defined?(:position) def position # :nodoc: getPosition end @@ -4382,6 +4386,18 @@ module Fox def rowHeaderMode=(hint) # :nodoc: setRowHeaderMode(hint) end + def columnHeaderFont # :nodoc: + getColumnHeaderFont + end + def columnHeaderFont=(f) # :nodoc: + setColumnHeaderFont(f) + end + def rowHeaderFont # :nodoc: + getRowHeaderFont + end + def rowHeaderFont=(f) # :nodoc: + setRowHeaderFont(f) + end def columnHeaderHeight # :nodoc: getColumnHeaderHeight() end @@ -4764,6 +4780,7 @@ module Fox def editable?(*args) # :nodoc: isEditable(*args) end + alias :editable :editable? def editable=(*args) # :nodoc: setEditable(*args) end diff --git a/lib/fox16/chore.rb b/lib/fox16/chore.rb index 117d02fdce6400ed6e81bdef77751a7dda651f61..36c744b401bb70f2cf4af2fb354c3a940a926070 100755 --- a/lib/fox16/chore.rb +++ b/lib/fox16/chore.rb @@ -1,4 +1,5 @@ module Fox + class FXApp alias addChoreOrig addChore # :nodoc: @@ -26,29 +27,41 @@ module Fox # # The last form takes a block: # - # app.addChore() { |sender, sel, data| + # app.addChore() do |sender, sel, data| # ... handle the chore ... - # } + # end # # All of these return a reference to an opaque FXChore instance that # can be passed to #removeChore if it is necessary to remove the chore # before it fires. # + # For the last two forms, you can pass in the optional +:repeat+ parameter to + # cause the chore to be re-registered after it fires, e.g. + # + # chore = app.addChore(:repeat => true) do |sender, sel, data| + # ... handle the chore ... + # ... re-add the chore ... + # end + # def addChore(*args, &block) + params = {} + params = args.pop if args.last.is_a? Hash tgt, sel = nil, 0 if args.length > 0 if args[0].respond_to? :call - tgt = FXPseudoTarget.new - tgt.pconnect(SEL_CHORE, args[0], block) + tgt = params[:target] || FXPseudoTarget.new + tgt.pconnect(SEL_CHORE, args[0], params) else - tgt, sel = args[0], args[1] + tgt, sel = args[0], args[1] end else - tgt = FXPseudoTarget.new - tgt.pconnect(SEL_CHORE, nil, block) + tgt = params[:target] || FXPseudoTarget.new + tgt.pconnect(SEL_CHORE, block, params) end addChoreOrig(tgt, sel) - return { :target => tgt, :selector => sel } + params[:target] = tgt + params[:selector] = sel + params end # @@ -60,8 +73,8 @@ module Fox if args.length == 2 removeChoreOrig(args[0], args[1]) else - hsh = args[0] - removeChoreOrig(hsh[:target], hsh[:selector]) + params = args[0] + removeChoreOrig(params[:target], params[:selector]) end end @@ -87,5 +100,6 @@ module Fox end end - end -end + end # class FXApp + +end # module Fox diff --git a/lib/fox16/core.rb b/lib/fox16/core.rb index 1437b41153bbdcd891b456fb908091eb4b8c0b9a..041a586672858fd3cba4ffd19e498b73ddf969b4 100755 --- a/lib/fox16/core.rb +++ b/lib/fox16/core.rb @@ -182,6 +182,25 @@ module Fox end end end + + class FXHiliteStyle + # + # Construct a new FXHiliteStyle instance, with fields initialized from + # an FXText instance. + # + def FXHiliteStyle.from_text(textw) + hs = new + hs.activeBackColor = textw.activeBackColor + hs.hiliteBackColor = textw.hiliteBackColor + hs.hiliteForeColor = textw.hiliteTextColor + hs.normalBackColor = textw.backColor + hs.normalForeColor = textw.textColor + hs.selectBackColor = textw.selBackColor + hs.selectForeColor = textw.selTextColor + hs.style = 0 + hs + end + end class FXScrollArea # Returns a reference to the scroll corner (an FXScrollCorner instance) for this window. @@ -218,6 +237,8 @@ module Fox def to_s to_a.to_s end + + def inspect; to_a.inspect; end end class FXVec2f @@ -226,6 +247,8 @@ module Fox # Convert to string def to_s; to_a.to_s; end + + def inspect; to_a.inspect; end end class FXVec3d @@ -234,6 +257,8 @@ module Fox # Convert to string def to_s; to_a.to_s; end + + def inspect; to_a.inspect; end end class FXVec3f @@ -242,6 +267,8 @@ module Fox # Convert to string def to_s; to_a.to_s; end + + def inspect; to_a.inspect; end end class FXVec4d @@ -250,6 +277,8 @@ module Fox # Convert to string def to_s; to_a.to_s; end + + def inspect; to_a.inspect; end end class FXVec4f @@ -258,20 +287,39 @@ module Fox # Convert to string def to_s; to_a.to_s; end + + def inspect; to_a.inspect; end end class FXWindow # # Iterate over the child windows for this window. + # Note that this only reaches the direct child windows for this window + # and no deeper descendants. To traverse the entire widget tree, + # use #each_child_recursive. # - def each_child + def each_child # :yields: child child = self.first while child next_child = child.next yield child - child = next_child + child = next_child + end + end + + # + # Traverse the widget tree starting from this window + # using depth-first traversal. + # + def each_child_recursive # :yields: child + each_child do |child| + yield child + child.each_child_recursive do |subchild| + yield subchild + end end end + # Returns an array containing all child windows of this window def children @@ -447,9 +495,7 @@ module Fox # Create input control for editing this item def getControlFor(table) - combo = FXComboBox.new(table, 1, nil, 0, COMBOBOX_STATIC, 0, 0, 0, 0, - table.marginLeft, table.marginRight, - table.marginTop, table.marginBottom) + combo = FXComboBox.new(table, 1, :opts => COMBOBOX_STATIC, :padLeft => table.marginLeft, :padRight => table.marginRight, :padTop => table.marginTop, :padBottom => table.marginBottom) combo.create justify = 0 justify |= JUSTIFY_LEFT if (self.justify & FXTableItem::LEFT) != 0 @@ -539,6 +585,13 @@ module Fox self.checkState == MAYBE end end + + class FXObject + require 'enumerator' + def self.subclasses + ObjectSpace.enum_for(:each_object, class << self; self; end).to_a + end + end class FXDC # @@ -607,6 +660,41 @@ module Fox def selectItem(row, col, notify=false) selectRange(row, row, col, col, notify) end + +=begin + + # Deselect cell at (_row_, _col_). + # If _notify_ is +true+, a +SEL_DESELECTED+ message is sent to the table's message target + # after the item is deselected. + # Raises IndexError if either _row_ or _col_ is out of bounds. + # + def deselectItem(row, col, notify=false) + raise IndexError, "row index out of bounds" if row < 0 || row >= numRows + raise IndexError, "column index out of bounds" if col < 0 || col >= numColumns + deselectRange(row, row, col, col, notify) + end + + # Deselect range. + # If _notify_ is +true+, a +SEL_DESELECTED+ message is sent to the table's message + # target for each previously selected cell that becomes deselected as a result of + # this operation. + # Raises IndexError if _startRow_, _endRow_, _startColumn_ or _endColumn_ is out of bounds. + def deselectRange(startRow, endRow, startColumn, endColumn, notify=false) + raise IndexError, "starting row index out of bounds" if startRow < 0 || startRow >= numRows + raise IndexError, "ending row index out of bounds" if endRow < 0 || endRow >= numRows + raise IndexError, "starting column index out of bounds" if startColumn < 0 || startColumn >= numColumns + raise IndexError, "ending column index out of bounds" if endColumn < 0 || endColumn >= numColumns + changes = false + for row in startRow..endRow + for col in startColumn..endColumn + changes |= deselectItem(row, col, notify) + end + end + changes + end + +=end + end end diff --git a/lib/fox16/exceptions_for_fxerror.rb b/lib/fox16/exceptions_for_fxerror.rb new file mode 100644 index 0000000000000000000000000000000000000000..5cc5561bbba58cc9086c01cfbb93b180565397c6 --- /dev/null +++ b/lib/fox16/exceptions_for_fxerror.rb @@ -0,0 +1,17 @@ +module Fox + FXWindow.subclasses.each do |klass| + klass.send(:alias_method, :create_without_parent_created_check, :create) + klass.send(:define_method, :create) do + unless parent.created? + raise RuntimeError, "trying to create window before creating parent window" + end + if owner && !owner.created? + raise RuntimeError, "trying to create window before creating owner window" + end + if visual.nil? + raise RuntimeError, "trying to create window without a visual" + end + create_without_parent_created_check + end + end +end diff --git a/lib/fox16/input.rb b/lib/fox16/input.rb index 55fa0596fcd989a1a09f231016c71da4bad52be8..4fbd87bb28980b2cb973039493811cd9a661800a 100755 --- a/lib/fox16/input.rb +++ b/lib/fox16/input.rb @@ -1,4 +1,5 @@ module Fox + class FXApp alias addInputOrig addInput # :nodoc: @@ -31,24 +32,28 @@ module Fox # def addInput(fd, mode, *args, &block) + params = {} + params = args.pop if args.last.is_a? Hash tgt, sel = nil, 0 if args.length > 0 if args[0].respond_to? :call tgt = FXPseudoTarget.new - tgt.pconnect(SEL_IO_READ, args[0], block) - tgt.pconnect(SEL_IO_WRITE, args[0], block) - tgt.pconnect(SEL_IO_EXCEPT, args[0], block) + tgt.pconnect(SEL_IO_READ, args[0], params) + tgt.pconnect(SEL_IO_WRITE, args[0], params) + tgt.pconnect(SEL_IO_EXCEPT, args[0], params) else # it's some other kind of object tgt = args[0] sel = args[1] end else tgt = FXPseudoTarget.new - tgt.pconnect(SEL_IO_READ, nil, block) - tgt.pconnect(SEL_IO_WRITE, nil, block) - tgt.pconnect(SEL_IO_EXCEPT, nil, block) + tgt.pconnect(SEL_IO_READ, block, params) + tgt.pconnect(SEL_IO_WRITE, block, params) + tgt.pconnect(SEL_IO_EXCEPT, block, params) end addInputOrig(fd, mode, tgt, sel) end - end -end + + end # class FXApp + +end # module Fox diff --git a/lib/fox16/iterators.rb b/lib/fox16/iterators.rb index e521c431b3b515604e8d579bde3fdab33e472cb3..0135075c5ffd5cf907aebe13d9b167b6db8963e5 100755 --- a/lib/fox16/iterators.rb +++ b/lib/fox16/iterators.rb @@ -4,6 +4,13 @@ module Fox include Enumerable + # + # Override Enumerable#first with FXWindow#first for backwards compatibility. + # + def first + getFirst + end + # # Calls block once for each item in the list, passing the item's text and # user data as parameters. @@ -25,7 +32,7 @@ module Fox # reference to that item as a parameter. # def each # :yields: aFoldingItem - current = first + current = firstItem while current != nil next_current = current.next yield current @@ -58,6 +65,13 @@ module Fox include Enumerable + # + # Override Enumerable#first with FXWindow#first for backwards compatibility. + # + def first + getFirst + end + # # Calls block once for each item in the list, passing a reference to that # item as a parameter. @@ -90,6 +104,13 @@ module Fox include Enumerable + # + # Override Enumerable#first with FXWindow#first for backwards compatibility. + # + def first + getFirst + end + # # Calls block once for each item in the list, passing a reference to that # item as a parameter. @@ -106,6 +127,13 @@ module Fox include Enumerable + # + # Override Enumerable#first with FXWindow#first for backwards compatibility. + # + def first + getFirst + end + # # Calls block once for each item in the list, passing the item's text, # icon and user data as parameters. @@ -122,6 +150,13 @@ module Fox include Enumerable + # + # Override Enumerable#first with FXWindow#first for backwards compatibility. + # + def first + getFirst + end + # # Calls block once for each row in the table, passing an array of # references (one element per column) as a parameter. @@ -178,12 +213,19 @@ module Fox include Enumerable + # + # Override Enumerable#first with FXWindow#first for backwards compatibility. + # + def first + getFirst + end + # # Calls block once for each root-level tree item, passing a # reference to that item as a parameter. # def each # :yields: aTreeItem - current = first + current = firstItem while current != nil next_current = current.next yield current @@ -197,12 +239,19 @@ module Fox include Enumerable + # + # Override Enumerable#first with FXWindow#first for backwards compatibility. + # + def first + getFirst + end + # # Calls block once for each root-level tree item, passing a # reference to that item as a parameter. # def each # :yields: aTreeItem - current = first + current = firstItem while current != nil next_current = current.next yield current @@ -234,18 +283,18 @@ module Fox def FXFileStream.open(filename, save_or_load, size=8192, container=nil) # :yields: theFileStream fstream = FXFileStream.new(container) if fstream.open(filename, save_or_load, size) - if block_given? - begin - yield fstream - ensure - fstream.close - end - else - fstream - end + if block_given? + begin + yield fstream + ensure + fstream.close + end + else + fstream + end else # FXFileStream#open returned false, so report error - raise FXStreamError.makeStreamError(fstream.status) + raise FXStreamError.makeStreamError(fstream.status) end end end @@ -272,18 +321,18 @@ module Fox def FXMemoryStream.open(save_or_load, data, cont=nil) # :yields: theMemoryStream stream = FXMemoryStream.new(cont) if stream.open(save_or_load, data) - if block_given? - begin - yield stream - ensure - stream.close - end - else - stream - end + if block_given? + begin + yield stream + ensure + stream.close + end + else + stream + end else # FXFileStream#open returned false, so report error - raise FXStreamError.makeStreamError(stream.status) + raise FXStreamError.makeStreamError(stream.status) end end end @@ -318,10 +367,10 @@ module Fox beginWaitCursor0 if block_given? begin - yield - ensure - endWaitCursor - end + yield + ensure + endWaitCursor + end end end end @@ -339,10 +388,10 @@ module Fox result = beginPrint0(job) if block_given? begin - yield self - ensure - endPrint - end + yield self + ensure + endPrint + end else result end @@ -359,10 +408,10 @@ module Fox result = beginPage0(page) if block_given? begin - yield self - ensure - endPage - end + yield self + ensure + endPage + end else result end diff --git a/lib/fox16/pseudokeyboard.rb b/lib/fox16/pseudokeyboard.rb index 4a52e3266d183d65152eecc2a8b9ec5d3647f2f4..40792e8ab58f427018ac358cfb15c1d891c45b76 100755 --- a/lib/fox16/pseudokeyboard.rb +++ b/lib/fox16/pseudokeyboard.rb @@ -1,11 +1,17 @@ module Fox # - # Based on a suggestion from Hugh Sasse on the fxruby-users mailing list, - # an FXPseudoKeyboard object provides a simple means to operate widgets + # An FXPseudoKeyboard object provides a simple means to operate widgets # programmatically, to aid test driven design. An FXPseudoKeyboard instance # can be pointed at an FXObject and will manage the sending of events to # it. # + # For example: + # + # textfield = FXTextField.new(...) + # pk = FXPseudoKeyboard.new(textfield) + # pk.doKeyPress # sends a SEL_KEYPRESS message to the textfield + # pk.doKeyRelease # sends a SEL_KEYRELEASE message to the textfield + # class FXPseudoKeyboard attr_accessor :target @@ -17,16 +23,16 @@ module Fox def doKeyPress unless @target.nil? evt = FXEvent.new - evt.type = Fox::SEL_KEYPRESS - @target.handle(self, Fox.MKUINT(0, Fox::SEL_KEYPRESS), evt) + evt.type = Fox::SEL_KEYPRESS + @target.handle(self, Fox.FXSEL(Fox::SEL_KEYPRESS, 0), evt) end end def doKeyRelease unless @target.nil? evt = FXEvent.new - evt.type = Fox::SEL_KEYRELEASE - @target.handle(self, Fox.MKUINT(0, Fox::SEL_KEYRELEASE), evt) + evt.type = Fox::SEL_KEYRELEASE + @target.handle(self, Fox.FXSEL(Fox::SEL_KEYRELEASE, 0), evt) end end end diff --git a/lib/fox16/pseudomouse.rb b/lib/fox16/pseudomouse.rb index 545dcc07910095107b8a05898a4ae99593d48b0e..471524c333dc74b5b48cc4836aa49afed1e3d042 100755 --- a/lib/fox16/pseudomouse.rb +++ b/lib/fox16/pseudomouse.rb @@ -1,11 +1,16 @@ module Fox # - # Based on a suggestion from Hugh Sasse on the fxruby-users mailing list, - # an FXPseudoMouse object provides a simple means to operate widgets + # An FXPseudoMouse object provides a simple means to operate widgets # programmatically, to aid test driven design. An FXPseudoMouse instance # can be pointed at an FXObject and will manage the sending of events to # it. # + # For example: + # + # canvas = FXCanvas.new(...) + # pm = FXPseudoMouse.new(canvas) + # pm.doLeftButtonPress # sends a SEL_LEFTBUTTONPRESS message to the canvas + # class FXPseudoMouse < FXObject attr_accessor :target @@ -18,7 +23,7 @@ module Fox unless @target.nil? evt = FXEvent.new evt.type = Fox::SEL_MOTION - @target.handle(self, Fox.MKUINT(0, Fox::SEL_MOTION), evt) + @target.handle(self, Fox.FXSEL(Fox::SEL_MOTION, 0), evt) end end @@ -26,7 +31,7 @@ module Fox unless @target.nil? evt = FXEvent.new evt.type = Fox::SEL_MOUSEWHEEL - @target.handle(self, Fox.MKUINT(0, Fox::SEL_MOUSEWHEEL), evt) + @target.handle(self, Fox.FXSEL(Fox::SEL_MOUSEWHEEL, 0), evt) end end @@ -34,7 +39,7 @@ module Fox unless @target.nil? evt = FXEvent.new evt.type = Fox::SEL_LEFTBUTTONPRESS - @target.handle(self, Fox.MKUINT(0, Fox::SEL_LEFTBUTTONPRESS), evt) + @target.handle(self, Fox.FXSEL(Fox::SEL_LEFTBUTTONPRESS, 0), evt) end end @@ -42,7 +47,7 @@ module Fox unless @target.nil? evt = FXEvent.new evt.type = Fox::SEL_LEFTBUTTONRELEASE - @target.handle(self, Fox.MKUINT(0, Fox::SEL_LEFTBUTTONRELEASE), evt) + @target.handle(self, Fox.FXSEL(Fox::SEL_LEFTBUTTONRELEASE, 0), evt) end end @@ -50,7 +55,7 @@ module Fox unless @target.nil? evt = FXEvent.new evt.type = Fox::SEL_MIDDLEBUTTONPRESS - @target.handle(self, Fox.MKUINT(0, Fox::SEL_MIDDLEBUTTONPRESS), evt) + @target.handle(self, Fox.FXSEL(Fox::SEL_MIDDLEBUTTONPRESS, 0), evt) end end @@ -58,7 +63,7 @@ module Fox unless @target.nil? evt = FXEvent.new evt.type = Fox::SEL_MIDDLEBUTTONRELEASE - @target.handle(self, Fox.MKUINT(0, Fox::SEL_MIDDLEBUTTONRELEASE), evt) + @target.handle(self, Fox.FXSEL(Fox::SEL_MIDDLEBUTTONRELEASE, 0), evt) end end @@ -66,7 +71,7 @@ module Fox unless @target.nil? evt = FXEvent.new evt.type = Fox::SEL_RIGHTBUTTONPRESS - @target.handle(self, Fox.MKUINT(0, Fox::SEL_RIGHTBUTTONPRESS), evt) + @target.handle(self, Fox.FXSEL(Fox::SEL_RIGHTBUTTONPRESS, 0), evt) end end @@ -74,7 +79,7 @@ module Fox unless @target.nil? evt = FXEvent.new evt.type = Fox::SEL_RIGHTBUTTONRELEASE - @target.handle(self, Fox.MKUINT(0, Fox::SEL_RIGHTBUTTONRELEASE), evt) + @target.handle(self, Fox.FXSEL(Fox::SEL_RIGHTBUTTONRELEASE, 0), evt) end end end diff --git a/lib/fox16/responder2.rb b/lib/fox16/responder2.rb index b10c454f9a492b26925e750565d5446b07ffd14a..a73a2f750683fe50d443a32ed96304a152348c4d 100755 --- a/lib/fox16/responder2.rb +++ b/lib/fox16/responder2.rb @@ -21,30 +21,25 @@ module Fox # def initialize super - @blocks = {} + @context = {} end # # Store an association between a message of type - # _messageType_ with a callable object or a block. + # _message_type_ with a callable object. # - def pconnect(messageType, callableObject, block) - if callableObject.nil? - @blocks[messageType] = block - else - @blocks[messageType] = callableObject - end - FXMAPTYPE(messageType, :onHandleMsg) - - case messageType - when SEL_TIMEOUT - @@targets_of_pending_timers[self] = self - when SEL_CHORE - @@targets_of_pending_chores[self] = self - when SEL_SIGNAL - @@targets_of_pending_signals[self] = self - when SEL_IO_READ, SEL_IO_WRITE, SEL_IO_EXCEPT - @@targets_of_pending_inputs[self] = self + def pconnect(message_type, callable_object, params={}) + @context[message_type] = { :callable => callable_object, :params => params } + FXMAPTYPE(message_type, :onHandleMsg) + case message_type + when SEL_TIMEOUT + @@targets_of_pending_timers[self] = self + when SEL_CHORE + @@targets_of_pending_chores[self] = self + when SEL_SIGNAL + @@targets_of_pending_signals[self] = self + when SEL_IO_READ, SEL_IO_WRITE, SEL_IO_EXCEPT + @@targets_of_pending_inputs[self] = self end end @@ -53,18 +48,31 @@ module Fox # message data _ptr_. # def onHandleMsg(sender, sel, ptr) - messageType = Fox.FXSELTYPE(sel) - result = @blocks[messageType].call(sender, sel, ptr) - case messageType - when SEL_TIMEOUT - @@targets_of_pending_timers.delete(self) - when SEL_CHORE - @@targets_of_pending_chores.delete(self) + message_type = Fox.FXSELTYPE(sel) + ctx = @context[message_type] + callable_object = ctx[:callable] + params = ctx[:params] + result = callable_object.call(sender, sel, ptr) + case message_type + when SEL_TIMEOUT + if params[:repeat] + FXApp.instance.addTimeout(params[:delay], callable_object, params) + else + @@targets_of_pending_timers.delete(self) + end + when SEL_CHORE + if params[:repeat] + FXApp.instance.addChore(callable_object, params) + else + @@targets_of_pending_chores.delete(self) + end end result end - end -end + + end # class FXPseudoTarget + +end # module Fox # # The Responder2 module provides the #connect method, @@ -95,13 +103,14 @@ module Responder2 # will be "called" with three arguments (the sender, selector and # message data). # - def connect(messageType, callableObject=nil, &block) + def connect(message_type, callable_object=nil, &block) unless instance_variables.include?('@pseudoTarget') @pseudoTarget = Fox::FXPseudoTarget.new self.target = @pseudoTarget end - @pseudoTarget.pconnect(messageType, callableObject, block) + @pseudoTarget.pconnect(message_type, callable_object ? callable_object : block) end + end module Fox diff --git a/lib/fox16/signal.rb b/lib/fox16/signal.rb index 8c9a24377d861958e88901bdecc90cf964616920..513f7062bdfa4fcc1c006712ba189f413e616034 100755 --- a/lib/fox16/signal.rb +++ b/lib/fox16/signal.rb @@ -1,4 +1,5 @@ module Fox + class FXApp alias addSignalOrig addSignal # :nodoc: @@ -18,7 +19,7 @@ module Fox # the message to be sent when this signal is raised. # If _sendImmediately_ is +true+, the message will be sent to the target right away; # this should be used with extreme care as the application is interrupted - # at an unknown point it its execution. + # at an unknown point in its execution. # The _flags_ are to be set as per POSIX definitions. # # A second form of #addSignal takes a Method instance as its second argument: @@ -38,16 +39,18 @@ module Fox # def addSignal(sig, *args, &block) + params = {} + params = args.pop if args.last.is_a? Hash tgt, sel, immediate, flags = nil, 0, false, 0 if args.length > 0 if args[0].respond_to? :call tgt = FXPseudoTarget.new - tgt.pconnect(SEL_SIGNAL, args[0], block) + tgt.pconnect(SEL_SIGNAL, args[0], params) immediate = (args.length > 1) ? args[1] : false flags = (args.length > 2) ? args[2] : 0 elsif (args[0].kind_of? TrueClass) || (args[0].kind_of? FalseClass) tgt = FXPseudoTarget.new - tgt.pconnect(SEL_SIGNAL, nil, block) + tgt.pconnect(SEL_SIGNAL, block, params) immediate = args[0] flags = (args.length > 1) ? args[1] : 0 else # it's some other kind of object @@ -58,9 +61,11 @@ module Fox end else tgt = FXPseudoTarget.new - tgt.pconnect(SEL_SIGNAL, nil, block) + tgt.pconnect(SEL_SIGNAL, block, params) end addSignalOrig(sig, tgt, sel, immediate, flags) end - end -end + + end # class FXApp + +end # module Fox diff --git a/lib/fox16/timeout.rb b/lib/fox16/timeout.rb index ddead0978ed861131ba07fc5a4de0bd24ff0e007..6aae9b66a6b7dd93851677e5265724b08d39f9cc 100755 --- a/lib/fox16/timeout.rb +++ b/lib/fox16/timeout.rb @@ -1,4 +1,5 @@ module Fox + class FXApp alias addTimeoutOrig addTimeout # :nodoc: @@ -7,8 +8,8 @@ module Fox alias remainingTimeoutOrig remainingTimeout # :nodoc: # - # Add a timeout message to be sent to target object in _ms_ milliseconds; - # the timer fires only once after the interval expires. The last argument + # Add a timeout message to be sent to target object in _ms_ milliseconds. + # By default, the timer fires only once after the interval expires. The last argument # is optional user data which will be passed along as the _ptr_ argument of # the message handler. If a timer with the same target and message already exists, # it will be rescheduled. @@ -34,30 +35,43 @@ module Fox # # The last form of #addTimeout takes a block: # - # timeout = app.addTimeout(delay) { |sender, sel, data| + # timeout = app.addTimeout(delay) do |sender, sel, data| # ... handle the timeout ... - # } + # end # # All of these return a reference to an opaque object (actually, a hash) that # can be passed to #removeTimeout if it is necessary to remove the timeout # before it fires. # + # For the last two forms, you can pass in the optional +:repeat+ parameter to + # cause the timeout to be re-registered after it fires, e.g. + # + # timeout = app.addTimeout(delay, :repeat => true) do |sender, sel, data| + # ... handle the timeout ... + # ... re-add the timeout with the same delay ... + # end + # def addTimeout(ms, *args, &block) + params = {} + params = args.pop if args.last.is_a? Hash + params[:delay] = ms tgt, sel = nil, 0 if args.length > 0 if args[0].respond_to? :call - tgt = FXPseudoTarget.new - tgt.pconnect(SEL_TIMEOUT, args[0], nil) + tgt = params[:target] || FXPseudoTarget.new + tgt.pconnect(SEL_TIMEOUT, args[0], params) else # it's some other kind of object tgt = args[0] sel = args[1] end else - tgt = FXPseudoTarget.new - tgt.pconnect(SEL_TIMEOUT, nil, block) + tgt = params[:target] || FXPseudoTarget.new + tgt.pconnect(SEL_TIMEOUT, block, params) end addTimeoutOrig(tgt, sel, ms) - return { :target => tgt, :selector => sel } + params[:target] = tgt + params[:selector] = sel + params end # @@ -69,8 +83,8 @@ module Fox if args.length == 2 removeTimeoutOrig(args[0], args[1]) else - hsh = args[0] - removeTimeoutOrig(hsh[:target], hsh[:selector]) + params = args[0] + removeTimeoutOrig(params[:target], params[:selector]) end end @@ -116,5 +130,7 @@ module Fox remainingTimeoutOrig(hsh[:target], hsh[:selector]) end end - end -end + + end # class FXApp + +end # module Fox diff --git a/pre-config.rb.in b/pre-config.rb.in index 0040fbefc1ec9e3dfc3a5f333af4caedb5cf48d9..dd9c276405355a53e7d2d49faaf7b317b0d75734 100755 --- a/pre-config.rb.in +++ b/pre-config.rb.in @@ -3,7 +3,8 @@ def search_directories dirs = [ "/usr/include/fox-1.6", "/usr/local/include/fox-1.6", - "/sw/include/fox-1.6" + "/sw/include/fox-1.6", + "/opt/local/include/fox-1.6" ] ARGV.each do |arg| if arg =~ /--with-fox-include/ @@ -19,7 +20,7 @@ end def fox_include_files_found? search_directories.each do |path| filename = File.join(path, "fxver.h") - return true if FileTest.exists?(filename) + return true if FileTest.exist?(filename) end false end @@ -43,7 +44,7 @@ end def installed_fox_version search_directories.each do |path| filename = File.join(path, "fxver.h") - if FileTest.exists?(filename) + if FileTest.exist?(filename) foxMajor, foxMinor, foxLevel = read_fox_version(filename) return [foxMajor, foxMinor, foxLevel].join('.') end diff --git a/rdoc-sources/FXButton.rb b/rdoc-sources/FXButton.rb index 85b333bd92395814f8cdfdacd66dab8d91733bcb..71da51f101234e34996f321f51c7d2bd8ccb1098 100755 --- a/rdoc-sources/FXButton.rb +++ b/rdoc-sources/FXButton.rb @@ -14,7 +14,7 @@ module Fox # The option <tt>BUTTON_AUTOGRAY</tt> (<tt>BUTTON_AUTOHIDE</tt>) causes the button to be grayed # out (hidden) if its handler does not respond to the <tt>SEL_UPDATE</tt> message. # This is useful when messages are delegated, for example when using a - # multiple document interface, where the ultimaye destination of a message + # multiple document interface, where the ultimate destination of a message # can be changed. # # === Events diff --git a/rdoc-sources/FXComboBox.rb b/rdoc-sources/FXComboBox.rb index 1b5d3e3f3b976c13f9bfd8939fc068540ae562c0..42daa6af0745c5ef4889e23fdaf0ced64d79cd8b 100755 --- a/rdoc-sources/FXComboBox.rb +++ b/rdoc-sources/FXComboBox.rb @@ -106,6 +106,9 @@ module Fox def initialize(p, cols, target=nil, selector=0, opts=COMBOBOX_NORMAL, x=0, y=0, width=0, height=0, padLeft=DEFAULT_PAD, padRight=DEFAULT_PAD, padTop=DEFAULT_PAD, padBottom=DEFAULT_PAD) # :yields: theComboBox end + # Return the combo box text + def to_s; end + # Return +true+ if combobox is editable def editable?() ; end diff --git a/rdoc-sources/FXCursor.rb b/rdoc-sources/FXCursor.rb index 2afb7b8d4a65be45ff5dbdfbe62d4837e26e10fd..591d405c2e5dfbb00a6ef7ff17f0b472c7955409 100755 --- a/rdoc-sources/FXCursor.rb +++ b/rdoc-sources/FXCursor.rb @@ -48,7 +48,7 @@ module Fox # # Make cursor from FXColor pixels; cursor size should be 32x32 for portability! # - def initialize(a, src, msk, width=32, height=32, hotX=-1, hotY=-1) # :yields: theCursor + def initialize(a, pixels, width=32, height=32, hotX=-1, hotY=-1) # :yields: theCursor end # diff --git a/rdoc-sources/FXGroupBox.rb b/rdoc-sources/FXGroupBox.rb index 76b89dcf770962b85bad27d0d8c6e5bc3c7f113c..7941789dc82cff2cf134c71b2a7a51631500bea6 100755 --- a/rdoc-sources/FXGroupBox.rb +++ b/rdoc-sources/FXGroupBox.rb @@ -28,6 +28,9 @@ module Fox # Construct group box layout manager def initialize(parent, text, opts=GROUPBOX_NORMAL, x=0, y=0, width=0, height=0, padLeft=DEFAULT_SPACING, padRight=DEFAULT_SPACING, padTop=DEFAULT_SPACING, padBottom=DEFAULT_SPACING, hSpacing=DEFAULT_SPACING, vSpacing=DEFAULT_SPACING) # :yields: theGroupBox end + + # Return the group box's title text + def to_s; text; end end end diff --git a/rdoc-sources/FXHeader.rb b/rdoc-sources/FXHeader.rb index 04ccfaec7022220042ec2461dc10127bbd8c6f7f..052a6b04d23dc3fd55fc7588a76c317125ec22b4 100755 --- a/rdoc-sources/FXHeader.rb +++ b/rdoc-sources/FXHeader.rb @@ -57,6 +57,9 @@ module Fox def initialize(text, ic=nil, s=0, ptr=nil) # :yields: theHeaderItem end + # Return the header item's text label + def to_s; text; end + # Return the item's content width in the header. def getWidth(header); end diff --git a/rdoc-sources/FXIconDict.rb b/rdoc-sources/FXIconDict.rb index c758a51efa11462c3d746d42c111f36689e55a88..3d6f3e5bd7b3bb9e164b3a1586537e2642296286 100644 --- a/rdoc-sources/FXIconDict.rb +++ b/rdoc-sources/FXIconDict.rb @@ -21,7 +21,7 @@ module Fox # Construct icon dictionary, and set initial search path; also # creates a default icon source object. # - def initialize(app, path=defaultIconPath); + def initialize(app, path=FXIconDict.defaultIconPath); # Change icon source to _src_ (an FXIconSource instance). def iconSource=(src); end diff --git a/rdoc-sources/FXIconList.rb b/rdoc-sources/FXIconList.rb index 1f9051c8fe977c62df6da83c5c5c3f32b5068150..50f6d5f1020549b914c6507b7114771cd28927e9 100755 --- a/rdoc-sources/FXIconList.rb +++ b/rdoc-sources/FXIconList.rb @@ -28,6 +28,9 @@ module Fox # Constructor def initialize(text, bigIcon=nil, miniIcon=nil, data=nil) # :yields: theIconItem end + + # Return the icon item's text + def to_s; text; end # Set the focused state for this item (where _focus_ is either +true+ or +false+) def setFocus(focus); end diff --git a/rdoc-sources/FXImage.rb b/rdoc-sources/FXImage.rb index 0c4d6f069df4333b6f75af4092577c511c3eacd2..771fc3f1c69bf7e7091aa4f77dbc6548fb572f6c 100755 --- a/rdoc-sources/FXImage.rb +++ b/rdoc-sources/FXImage.rb @@ -113,7 +113,8 @@ module Fox def release(); end # - # Rescale pixels image to the specified width and height. Note that this + # Rescale pixels image to the specified width and height and then + # re-render the server-side image from the client-side pixel buffer. Note that this # serves a slightly different purpose than the base class resize() method, # which simply resizes the client-side pixel data buffer but doesn't # transform the image. @@ -132,7 +133,8 @@ module Fox def scale(w, h, quality=0) ; end # - # Mirror image horizontally and/or vertically. + # Mirror image horizontally and/or vertically and then re-render the + # server-side image from the client-side pixel buffer. # # ==== Parameters: # @@ -142,7 +144,8 @@ module Fox def mirror(horizontal, vertical) ; end # - # Rotate image counter-clockwise by some number of degrees. + # Rotate image counter-clockwise by some number of degrees and then + # re-render the server-side image from the client-side pixel buffer. # # ==== Parameters: # @@ -151,7 +154,8 @@ module Fox def rotate(degrees) ; end # - # Crop image to given rectangle; this calls resize() to adjust the client + # Crop image to given rectangle and then re-render the server-side image + # from the client-side pixel buffer. This method calls resize() to adjust the client # and server side representations. The new image may be smaller or larger # than the old one; blank areas are filled with color. There must be at # least one pixel of overlap between the old and the new image. @@ -165,6 +169,88 @@ module Fox # +color+:: fill color for blank areas after crop [FXColor] # def crop(x, y, w, h, color=0) ; end + + # Fill image with uniform color. + def fill(color); end + + # + # Fade an image to a certain color by a certain factor. The _factor_ is + # some integer value between 0 and 255 inclusive, where a factor of 255 indicates no fading and a factor + # of zero indicates that the image is completely faded to the fade _color_. + # + # ==== Parameters: + # + # +color+:: the fade color [FXColor] + # +factor+:: fading factor [Integer] + # + def fade(color, factor=255); end + + # + # Shear image horizontally and then re-render the server-side image + # from the client-side pixel buffer. The number of pixels is equal to the + # _shear_ parameter times 256. The area outside the image is filled + # with transparent black, unless another _color_ is specified. + # + # ==== Parameters: + # + # +shear+:: how far to shear [Integer] + # +color+:: fill color for areas outside the sheared image [FXColor] + # + def xshear(shear, color=0); end + + # + # Shear image verticallyand then re-render the server-side image + # from the client-side pixel buffer. The number of pixels is equal to the + # _shear_ parameter times 256. The area outside the image is filled + # with transparent black, unless another _color_ is specified. + # + # ==== Parameters: + # + # +shear+:: how far to shear [Integer] + # +color+:: fill color for areas outside the sheared image [FXColor] + # + def yshear(shear, color=0); end + + # + # Fill image using a horizontal gradient. + # + # ==== Parameters: + # + # +left+:: starting color, for leftmost pixels [FXColor] + # +right+:: ending color, for rightmost pixels [FXColor] + # + def hgradient(left, right); end + + # + # Fill image using a vertical gradient. + # + # ==== Parameters: + # + # +top+:: starting color, for topmost pixels [FXColor] + # +bottom+:: ending color, for bottommost pixels [FXColor] + # + def vgradient(top, bottom); end + + # + # Fill image using a bilinear gradient. + # + # ==== Parameters: + # + # +topleft+:: pixel color for top-left corner [FXColor] + # +topright+:: pixel color for top-right corner [FXColor] + # +bottomleft+:: pixel color for bottom-left corner [FXColor] + # +bottomright+:: pixel color for bottom-right corner [FXColor] + # + def gradient(topleft, topright, bottomleft, bottomright); end + + # + # Blend image over uniform color. + # + # ==== Parameters: + # + # +color+:: the blended color [FXColor] + # + def blend(color); end # # Save pixel data to a stream. diff --git a/rdoc-sources/FXImageFrame.rb b/rdoc-sources/FXImageFrame.rb index 7dd0a05515867004de8b96cd17950da95fe1e4fa..ec8436060ee345a08418c9f574f1c031561180ea 100755 --- a/rdoc-sources/FXImageFrame.rb +++ b/rdoc-sources/FXImageFrame.rb @@ -16,6 +16,20 @@ module Fox # # Return an initialized FXImageFrame instance. # + # ==== Parameters: + # + # +p+:: the parent window for this image frame [FXComposite] + # +img+:: the image to display [FXImage] + # +opts+:: frame options [Integer] + # +x+:: initial x-position [Integer] + # +y+:: initial y-position [Integer] + # +width+:: initial width [Integer] + # +height+:: initial height [Integer] + # +padLeft+:: internal padding on the left side, in pixels [Integer] + # +padRight+:: internal padding on the right side, in pixels [Integer] + # +padTop+:: internal padding on the top side, in pixels [Integer] + # +padBottom+:: internal padding on the bottom side, in pixels [Integer] + # def initialize(p, img, opts=FRAME_SUNKEN|FRAME_THICK, x=0, y=0, width=0, height=0, padLeft=0, padRight=0, padTop=0, padBottom=0) # :yields: theImageFrame end end diff --git a/rdoc-sources/FXInputDialog.rb b/rdoc-sources/FXInputDialog.rb index b7bbe25626f97c10b148365b010192b36524d424..42dc8007e93540a303ccf4e45541de37babb4da6 100755 --- a/rdoc-sources/FXInputDialog.rb +++ b/rdoc-sources/FXInputDialog.rb @@ -26,6 +26,9 @@ module Fox # def initialize(owner, caption, label, icon=nil, opts=INPUTDIALOG_STRING, x=0, y=0, width=0, height=0) # :yields: theInputDialog end + + # Return the input dialog's input string text + def to_s; text; end # # Change limits (where _lo_ and _hi_ are numbers). diff --git a/rdoc-sources/FXLabel.rb b/rdoc-sources/FXLabel.rb index abbe0bd9249daf13bc14bf5cf496b59cabd1c428..ebf456f22dd6307c46c30e819e60ccb1fad4f2fb 100755 --- a/rdoc-sources/FXLabel.rb +++ b/rdoc-sources/FXLabel.rb @@ -65,5 +65,8 @@ module Fox # Construct label with given text and icon def initialize(parent, text, icon=nil, opts=LABEL_NORMAL, x=0, y=0, width=0, height=0, padLeft=DEFAULT_PAD, padRight=DEFAULT_PAD, padTop=DEFAULT_PAD, padBottom=DEFAULT_PAD) # :yields: theLabel end + + # Return the label's text + def to_s; text; end end end diff --git a/rdoc-sources/FXList.rb b/rdoc-sources/FXList.rb index a91929d8097415a0c76c7c9dfa21eedd31efed6d..949ae6c631365952155be50a0038f0e6fecdbedd 100755 --- a/rdoc-sources/FXList.rb +++ b/rdoc-sources/FXList.rb @@ -29,6 +29,9 @@ module Fox def initialize(text, icon=nil, data=nil) # :yields: theListItem end + # Return the list item's text + def to_s; text; end + # Returns +true+ if this item has the focus def hasFocus?() ; end @@ -288,8 +291,9 @@ module Fox def findItem(text, start=-1, flags=SEARCH_FORWARD|SEARCH_WRAP) ; end # - # Search items by associated user _data_, beginning from item _start_. If the - # start item is -1 the search will start at the first item in the list. + # Search items by associated user _data_, beginning from item _start_. + # Returns the integer index of the matching item, or -1 if no match is + # found. If the start item is -1 the search will start at the first item in the list. # Flags may be +SEARCH_FORWARD+ or +SEARCH_BACKWARD+ to control the # search direction; this can be combined with +SEARCH_NOWRAP+ or +SEARCH_WRAP+ # to control whether the search wraps at the start or end of the list. diff --git a/rdoc-sources/FXMDIChild.rb b/rdoc-sources/FXMDIChild.rb index f9d18d7c770a4596e481d2bdb023446cd81dfd76..30a741f56e43dfad7f18d5a06e907e124fe59953 100755 --- a/rdoc-sources/FXMDIChild.rb +++ b/rdoc-sources/FXMDIChild.rb @@ -116,12 +116,6 @@ module Fox def initialize(p, name, ic=nil, pup=nil, opts=0, x=0, y=0, width=0, height=0) # :yields: theMDIChild end - # Get next MDI Child - def getMDINext(); end - - # Get previous MDI Child - def getMDIPrev(); end - # # Minimize this window. # If _notify_ is +true+, ... diff --git a/rdoc-sources/FXMDIClient.rb b/rdoc-sources/FXMDIClient.rb index 2553cd9483431568460a2bffd768bdaf96242d2d..5303b66f66dd08cbbeca4f279f2dc9669224e6b5 100755 --- a/rdoc-sources/FXMDIClient.rb +++ b/rdoc-sources/FXMDIClient.rb @@ -38,12 +38,6 @@ module Fox def initialize(p, opts=0, x=0, y=0, width=0, height=0) # :yields: theMDIClient end - # Get first MDI Child - def getMDIChildFirst(); end - - # Get last MDI Child - def getMDIChildLast(); end - # # Pass message to all MDI windows, stopping when one of # the MDI windows fails to handle the message. diff --git a/rdoc-sources/FXMenuCaption.rb b/rdoc-sources/FXMenuCaption.rb index 5482670bf962b19985fb728f455d27a699773e11..128ba6d1735c17160b13479984038be55013cfed 100755 --- a/rdoc-sources/FXMenuCaption.rb +++ b/rdoc-sources/FXMenuCaption.rb @@ -45,6 +45,9 @@ module Fox # def initialize(parent, text, icon=nil, opts=0) # :yields: theMenuCaption end + + # Return the menu caption's text + def to_s; text; end end end diff --git a/rdoc-sources/FXMessageBox.rb b/rdoc-sources/FXMessageBox.rb index ccd4043c8596c41bbc226ae4c483460622f95d49..c77b132e720bb3c2bee9c178752799c0df80fe3a 100755 --- a/rdoc-sources/FXMessageBox.rb +++ b/rdoc-sources/FXMessageBox.rb @@ -29,6 +29,7 @@ module Fox # +MBOX_CLICKED_SAVE+:: The *Save* button was clicked # +MBOX_CLICKED_SKIP+:: The *Skip* button was clicked # +MBOX_CLICKED_SKIPALL+:: The *Skip All* button was clicked + # +MBOX_CLICKED_DONTSAVE+:: The *Don't Save* button was clicked (same as +MBOX_CLICKED_NO+) # class FXMessageBox < FXDialogBox # diff --git a/rdoc-sources/FXPacker.rb b/rdoc-sources/FXPacker.rb index bae1fc30cbca0304868f8df925afc8c8b9888356..7472dff7e4bfd7a299dd90d69357f9767d219089 100755 --- a/rdoc-sources/FXPacker.rb +++ b/rdoc-sources/FXPacker.rb @@ -58,5 +58,6 @@ module Fox # def initialize(parent, opts=0, x=0, y=0, width=0, height=0, padLeft=DEFAULT_SPACING, padRight=DEFAULT_SPACING, padTop=DEFAULT_SPACING, padBottom=DEFAULT_SPACING, hSpacing=DEFAULT_SPACING, vSpacing=DEFAULT_SPACING) # :yields: thePacker end + end end diff --git a/rdoc-sources/FXTable.rb b/rdoc-sources/FXTable.rb index 1ea43329ccd84d9e29e3a189e01ebb03a9bd7c51..7ce4065672bd20966ad4ee112e6836245293168b 100755 --- a/rdoc-sources/FXTable.rb +++ b/rdoc-sources/FXTable.rb @@ -155,7 +155,42 @@ module Fox def destroy; end end - # Table Widget + # + # The FXTable widget displays a table of items, each with some text and optional + # icon. A column Header control provide captions for each column, and a row + # Header control provides captions for each row. Columns are resizable by + # means of the column Header control if the TABLE_COL_SIZABLE option is passed. + # Likewise, rows in the table are resizable if the TABLE_ROW_SIZABLE option is + # specified. An entire row (column) can be selected by clicking on the a button + # in the row (column) Header control. Passing TABLE_NO_COLSELECT disables column + # selection, and passing TABLE_NO_ROWSELECT disables column selection. + # When TABLE_COL_RENUMBER is specified, columns are automatically renumbered when + # columns are added or removed. Similarly, TABLE_ROW_RENUMBER will cause row numbers + # to be recalculated automatically when rows are added or removed. + # To disable editing of cells in the table, the TABLE_READONLY can be specified. + # Cells in the table may or may not have items in them. When populating a cell + # for the first time, an item will be automatically created if necessary. Thus, + # a cell in the table takes no space unless it has actual contents. + # Moreover, a contiguous, rectangular region of cells in the table may refer to + # one single item; in that case, the item will be stretched to cover all the + # cells in the region, and no grid lines will be drawn interior to the spanning + # item. + # + # The Table widget issues SEL_SELECTED or SEL_DESELECTED when cells are selected + # or deselected, respectively. The table position affected is passed along as the + # 3rd parameter of these messages. + # Whenever the current (focus) item is changed, a SEL_CHANGED message is sent with + # the new table position as a parameter. + # When items are added to the table, a SEL_INSERTED message is sent, with the table + # range of the newly added cells as the parameter in the message. + # When items are removed from the table, a SEL_DELETED message is sent prior to the + # removal of the items, and the table range of the removed cells is passed as a parameter. + # A SEL_REPLACED message is sent when the contents of a cell are changed, either through + # editing or by other means; the parameter is the range of affected cells. This message + # is sent prior to the change. + # SEL_CLICKED, SEL_DOUBLECLICKED, and SEL_TRIPLECLICKED messages are sent when a cell + # is clicked, double-clicked, or triple-clicked, respectively. + # A SEL_COMMAND is sent when an enabled item is clicked inside the table. # # === Events # @@ -573,18 +608,10 @@ module Fox # Raises IndexError if _row_ is out of bounds. def getRowHeight(row) ; end - # Set x-coordinate for column. - # Raises IndexError if _column_ is out of bounds. - def setColumnX(column, x) ; end - # Get x-coordinate of column. # Raises IndexError if _column_ is out of bounds. def getColumnX(column) ; end - # Set y-coordinate of row. - # Raises IndexError if _row_ is out of bounds. - def setRowY(row, y) ; end - # Get y-coordinate of row. # Raises IndexError if _row_ is out of bounds. def getRowY(row) ; end @@ -610,51 +637,67 @@ module Fox def fitColumnsToContents(col, nc=1); end # Set column header at _index_ to _text_. + # Raises IndexError if _index_ is out of bounds. def setColumnText(index, text); end # Return text of column header at _index_. + # Raises IndexError if _index_ is out of bounds. def getColumnText(index); end # Set row header at _index_ to _text_. + # Raises IndexError if _index_ is out of bounds. def setRowText(index, text); end # Return text of row header at _index_. + # Raises IndexError if _index_ is out of bounds. def getRowText(index); end - # Change column header icon + # Change column header icon. + # Raises IndexError if _index_ is out of bounds. def setColumnIcon(FXint index,FXIcon* icon); - # Return icon of column header at index + # Return icon of column header at _index_. + # Raises IndexError if _index_ is out of bounds. def getColumnIcon(index); end - # Change row header icon + # Change row header icon. + # Raises IndexError if _index_ is out of bounds. def setRowIcon(index, icon); end - # Return icon of row header at index + # Return icon of row header at _index_. + # Raises IndexError if _index_ is out of bounds. def getRowIcon(index); end # Change column header icon position, e.g. FXHeaderItem::BEFORE, etc. + # Raises IndexError if _index_ is out of bounds. def setColumnIconPosition(index, mode); end - # Return icon position of column header at index + # Return icon position of column header at _index_. + # Raises IndexError if _index_ is out of bounds. def getColumnIconPosition(index); end # Change row header icon position, e.g. FXHeaderItem::BEFORE, etc. + # Raises IndexError if _index_ is out of bounds. def setRowIconPosition(index, mode); end - # Return icon position of row header at index + # Return icon position of row header at _index_. + # Raises IndexError if _index_ is out of bounds. def getRowIconPosition(index); end # Change column header justify, e.g. FXHeaderItem::RIGHT, etc. + # Raises IndexError if _index_ is out of bounds. def setColumnJustify(index, justify); end - # Return justify of column header at index + # Return justify of column header at _index_. + # Raises IndexError if _index_ is out of bounds. def getColumnJustify(index); end # Change row header justify, e.g. FXHeaderItem::RIGHT, etc. + # Raises IndexError if _index_ is out of bounds. def setRowJustify(index, justify); end - # Return justify of row header at index + # Return justify of row header at _index_. + # Raises IndexError if _index_ is out of bounds. def getRowJustify(index); end # diff --git a/rdoc-sources/FXText.rb b/rdoc-sources/FXText.rb index 99d48bd0fff1baa2fb353cc8674ae15ecd7c913c..1ffdd7b9efc307df62e3435dc90f87f3247a4e86 100755 --- a/rdoc-sources/FXText.rb +++ b/rdoc-sources/FXText.rb @@ -2,7 +2,7 @@ module Fox # # Highlight style entry # - class FXHiliteStyle + class FXHiliteStyle # Normal text foreground color [FXColor] attr_accessor :normalForeColor @@ -315,7 +315,7 @@ module Fox # +p+:: the parent window for this text widget [FXComposite] # +target+:: the message target, if any, for this text widget [FXObject] # +selector+:: the message identifier for this text widget [Integer] - # +opts+:: tree list options [Integer] + # +opts+:: text options [Integer] # +x+:: initial x-position [Integer] # +y+:: initial y-position [Integer] # +width+:: initial width [Integer] @@ -324,6 +324,9 @@ module Fox def initialize(p, target=nil, selector=0, opts=0, x=0, y=0, width=0, height=0, padLeft=3, padRight=3, padTop=2, padBottom=2) # :yields: theText end + # Return the text buffer's value + def to_s; text; end + # Return +true+ if text was modified def modified? ; end @@ -430,18 +433,19 @@ module Fox # text is inserted. def shiftText(startPos, endPos, amount, notify=false); end - # Search for _string_ in text buffer, returning the extent of - # the string in _beg_ and _end_. The search starts from the given + # + # Search for _string_ in text buffer, and return the extent of + # the string as a two-element array of arrays. + # The first array contains the beginning index (or indices) + # and the second array contains the ending index (or indices). + # The search starts from the given # _start_ position, scans forward (+SEARCH_FORWARD+) or backward # (+SEARCH_BACKWARD+), and wraps around if +SEARCH_WRAP+ has been # specified. The search type is either a plain search (+SEARCH_EXACT+), # case insensitive search (+SEARCH_IGNORECASE+), or regular expression # search (+SEARCH_REGEX+). - # For regular expression searches, capturing parentheses are used if - # _npar_ is greater than 1; in this case, the number of entries in the - # _beg_ and _end_ arrays must be _npar_ also. If either _beg_ or _end_ or - # both are nil, internal arrays are used. - def findText(string, beg=nil, end=nil, start=0, flags=SEARCH_FORWARD|SEARCH_WRAP|SEARCH_EXACT, npar=1); end + # + def findText(string, start=0, flags=SEARCH_FORWARD|SEARCH_WRAP|SEARCH_EXACT); end # Return +true+ if position _pos_ is selected def positionSelected?(pos); end diff --git a/rdoc-sources/FXToggleButton.rb b/rdoc-sources/FXToggleButton.rb index 6207c43a643f1ec756d802051e5c8a3b9f4e6164..95bd9dac32d96e9ef0447e71d01650cf411c1142 100755 --- a/rdoc-sources/FXToggleButton.rb +++ b/rdoc-sources/FXToggleButton.rb @@ -19,6 +19,7 @@ module Fox # +TOGGLEBUTTON_AUTOGRAY+:: Automatically gray out when not updated # +TOGGLEBUTTON_AUTOHIDE+:: Automatically hide toggle button when not updated # +TOGGLEBUTTON_TOOLBAR+:: Toolbar style toggle button [flat look] + # +TOGGLEBUTTON_KEEPSTATE+:: Draw button according to state # +TOGGLEBUTTON_NORMAL+:: <tt>FRAME_RAISED|FRAME_THICK|JUSTIFY_NORMAL|ICON_BEFORE_TEXT</tt> # class FXToggleButton < FXLabel diff --git a/rdoc-sources/FXToolTip.rb b/rdoc-sources/FXToolTip.rb index 89dd950d31e877b668da14ee36f215a420e209e7..a01eaf28aa84b9e1ffb3b323e9352fc560369a22 100755 --- a/rdoc-sources/FXToolTip.rb +++ b/rdoc-sources/FXToolTip.rb @@ -32,5 +32,8 @@ module Fox # Set the current tip text color def textColor=(color); end + + # Return the tool tip's text + def to_s; text; end end end diff --git a/rdoc-sources/FXVec2d.rb b/rdoc-sources/FXVec2d.rb index a3f91842cc7f0a09cf9077efbc882405ce1379c5..0b1f419c484126e09188a576482eaf61ba90f320 100755 --- a/rdoc-sources/FXVec2d.rb +++ b/rdoc-sources/FXVec2d.rb @@ -7,7 +7,7 @@ module Fox # # Return an initialized FXVec2d instance. # - def initialize(xx, yy); end + def initialize(xx=0.0, yy=0.0); end # # Returns the element at _index_, where _index_ is 0 or 1. diff --git a/rdoc-sources/FXVec2f.rb b/rdoc-sources/FXVec2f.rb index 7706e99bd78b21ea271b78d4694a24d174abb7ba..887a4bd241604da3f322f079e6739209920df52b 100755 --- a/rdoc-sources/FXVec2f.rb +++ b/rdoc-sources/FXVec2f.rb @@ -7,7 +7,7 @@ module Fox # # Return an initialized FXVec2f instance. # - def initialize(xx, yy); end + def initialize(xx=0.0, yy=0.0); end # # Returns the element at _index_, where _index_ is 0 or 1. diff --git a/rdoc-sources/FXVec3d.rb b/rdoc-sources/FXVec3d.rb index ecfc2cb17c09a7e812fa49f794ab6dacffd57ae6..637ab0a925c34b19fbcef242efd4221f9175d120 100755 --- a/rdoc-sources/FXVec3d.rb +++ b/rdoc-sources/FXVec3d.rb @@ -6,9 +6,14 @@ module Fox attr_accessor :z # - # Return an initialized FXVec3d instance. + # Return an FXVec3d instance with _x_, _y_ and _z_ initialized to zeroes. # - def initialize(xx, yy, zz); end + def initialize; end + + # + # Return an FXVec3d instance initialized from specified component values. + # + def initialize(xx, yy, zz=1.0); end # # Returns the element at _index_, where _index_ is 0, 1 or 2. diff --git a/rdoc-sources/FXVec3f.rb b/rdoc-sources/FXVec3f.rb index 97e9bb827e07dbeec533dc95efcee2045969eb37..e3745a884878d14081eadccb1d0bdbecd287ef05 100755 --- a/rdoc-sources/FXVec3f.rb +++ b/rdoc-sources/FXVec3f.rb @@ -6,9 +6,14 @@ module Fox attr_accessor :z # - # Return an initialized FXVec3f instance. + # Return an FXVec3f instance with _x_, _y_ and _z_ initialized to zeroes. # - def initialize(xx, yy, zz); end + def initialize; end + + # + # Return an FXVec3f instance initialized with specified component values. + # + def initialize(xx, yy, zz=1.0); end # # Returns the element at _index_, where _index_ is 0, 1 or 2. diff --git a/rdoc-sources/FXVec4d.rb b/rdoc-sources/FXVec4d.rb index 527a8f65431ace30be65f1969083424797d538ee..f12a40c86c5893946185b66fdae94ba9cddf3554 100755 --- a/rdoc-sources/FXVec4d.rb +++ b/rdoc-sources/FXVec4d.rb @@ -7,12 +7,22 @@ module Fox attr_accessor :w # - # Return an initialized FXVec4d instance. + # Return an FXVec4d instance with _x_, _y_, _z_ and _w_ initialized to zeroes. + # + def initialize; end + + # + # Return an FXVec4d instance initialized from specified component values. # def initialize(xx, yy, zz, ww=1.0); end + + # + # Return an FXVec4d instance initialized from an FXVec3d instance and optional scalar. + # + def initialize(vec3d, ww=1.0); end # - # Returns the element at _index_, where _index_ is 0, 1 or 2. + # Returns the element at _index_, where _index_ is 0, 1, 2 or 3. # Raises IndexError if _index_ is out of range. # def [](index); end diff --git a/rdoc-sources/FXVec4f.rb b/rdoc-sources/FXVec4f.rb index 0f79b3c01c761c9a1db1514518e16ee22264cda6..72fddce934fd521df7f9347c09a748288e7f341c 100755 --- a/rdoc-sources/FXVec4f.rb +++ b/rdoc-sources/FXVec4f.rb @@ -7,12 +7,22 @@ module Fox attr_accessor :w # - # Return an initialized FXVec4f instance. + # Return an FXVec4f instance with _x_, _y_, _z_ and _w_ initialized to zeroes. + # + def initialize; end + + # + # Return an FXVec4f instance initialized from specified component values. # def initialize(xx, yy, zz, ww=1.0); end + + # + # Return an FXVec4f instance initialized from an FXVec3f instance and optional scalar. + # + def initialize(vec3f, ww=1.0); end # - # Returns the element at _index_, where _index_ is 0, 1 or 2. + # Returns the element at _index_, where _index_ is 0, 1, 2 or 3. # Raises IndexError if _index_ is out of range. # def [](index); end diff --git a/rdoc-sources/FXWindow.rb b/rdoc-sources/FXWindow.rb index 317375ec430ecaeaca9672832acbe2e925da54f2..71ce72c8251631feb72d7155f921fcb7256e7e99 100755 --- a/rdoc-sources/FXWindow.rb +++ b/rdoc-sources/FXWindow.rb @@ -78,6 +78,7 @@ module Fox # +LAYOUT_MIN_HEIGHT+:: Minimum height is the default # +LAYOUT_FILL_X+:: Stretch or shrink horizontally # +LAYOUT_FILL_Y+:: Stretch or shrink vertically + # +LAYOUT_FILL:: Stretch or shrink in both directions # +LAYOUT_EXPLICIT+:: Explicit placement # +LAYOUT_DOCK_SAME+:: Dock on same galley, if it fits # +LAYOUT_DOCK_NEXT+:: Dock on next galley diff --git a/scripts/FXRuby.iss.in b/scripts/FXRuby.iss.in index 4733829ea9b34541f7b6b856b7e115266cf7b974..9bbedf4055eabd5df2344ba03b83abd2f02cf3f4 100755 --- a/scripts/FXRuby.iss.in +++ b/scripts/FXRuby.iss.in @@ -20,14 +20,9 @@ OutputBaseFilename=FXRuby-@@FXRUBY_VERSION@@-@@RUBYVER@@ Source: "LICENSE"; DestDir: "{app}\doc\FXRuby"; Flags: ignoreversion Source: "README.win32.txt"; DestDir: "{app}\doc\FXRuby"; Flags: ignoreversion Source: "README"; DestDir: "{app}\doc\FXRuby"; Flags: ignoreversion -Source: "index.html"; DestDir: "{app}\doc\FXRuby"; Flags: ignoreversion ; HTML documentation files Source: "doc\*.html"; DestDir: "{app}\doc\FXRuby\doc"; Flags: ignoreversion Source: "doc\images\*.png"; DestDir: "{app}\doc\FXRuby\doc\images"; Flags: ignoreversion -Source: "web\*.html"; DestDir: "{app}\doc\FXRuby\doc\web"; Flags: ignoreversion -Source: "web\*.css"; DestDir: "{app}\doc\FXRuby\doc\web"; Flags: ignoreversion -Source: "web\art\*.gif"; DestDir: "{app}\doc\FXRuby\doc\web\art"; Flags: ignoreversion -Source: "web\art\*.png"; DestDir: "{app}\doc\FXRuby\doc\web\art"; Flags: ignoreversion ; unit tests Source: "tests\README"; DestDir: "{app}\doc\FXRuby\tests"; Flags: ignoreversion Source: "tests\*.rb"; DestDir: "{app}\doc\FXRuby\tests"; Flags: ignoreversion diff --git a/scripts/generate_kwargs_lib.rb b/scripts/generate_kwargs_lib.rb index 712a056f8dce2d6bd2d27671713320da2d2556f6..0c9cc8a7ac7b86bfb5525d4c8bbe6ebd335c09ae 100644 --- a/scripts/generate_kwargs_lib.rb +++ b/scripts/generate_kwargs_lib.rb @@ -13,27 +13,91 @@ Known problems (due to overloaded constructors): =end +CLASSES_TO_SKIP = %w{FX4Splitter FXCursor FXDCWindow FXExtentd FXExtentf FXFont FXGLCanvas FXGLShape FXGLViewer FXDockBar FXMenuBar FXToolBar FXQuatd FXQuatf FXRanged FXRangef FXRecentFiles FXRectangle FXRegion FXSize FXSphered FXSpheref FXSplitter FXVec2d FXVec2f FXVec3d FXVec3f FXVec4d FXVec4f FXWindow} + class Arg attr_reader :name attr_reader :value + def initialize(name, value) @name = name @value = value end end -class Desc - - attr_accessor :class_name +class MethodDescription + attr_accessor :method_name attr_accessor :required_args attr_accessor :optional_args - + def initialize - @class_name = nil + @method_name = nil @required_args = [] @optional_args = [] end + + def generate_alias + " alias old_#{method_name} #{method_name}\n" + end + + def generate_body + argument_names = optional_args.map { |arg| arg.name } + defaults_hash = optional_args.map { |arg| ":#{arg.name} => #{arg.value}"} + defaults_hash = "{ #{defaults_hash.join(', ')} }" + required = required_args.join(", ") + optional = optional_args.map { |arg| "params[:#{arg.name}]"} + optional = optional.join(", ") + buffer = "" + buffer << " def #{method_name}(#{required}#{required_args.length > 0 ? ', ' : ''}*args#{expects_block? ? ', &blk' : ''})\n" + buffer << " argument_names = %w{#{argument_names.join(' ')}}\n" + buffer << " default_params = #{defaults_hash}\n" + buffer << " params = {}\n" + buffer << " params = args.pop if args.last.is_a? Hash\n" + buffer << " args.each_with_index { |e, i| params[argument_names[i].intern] = e }\n" + if optional_args.any? { |arg| arg.name == "padLeft" } + buffer << " if params.key? :padding\n" + buffer << " value = params.delete(:padding)\n" + buffer << " [:padLeft, :padRight, :padTop, :padBottom].each { |s| params[s] ||= value }\n" + buffer << " end\n" + end + buffer << " params.keys.each { |key| raise ArgumentError, \"Unrecognized parameter \#{key}\" unless default_params.keys.include?(key) }\n" + buffer << " params = default_params.merge(params)\n" + buffer << " old_#{method_name}(#{required}#{(required_args.length > 0) && (optional_args.length > 0) ? ', ' : ''}#{optional}#{expects_block? ? ', &blk' : ''})\n" + buffer << " end\n" + buffer + end + + def expects_block? + method_name == "initialize" + end +end +class ClassDescription + attr_accessor :class_name + attr_accessor :method_descriptions + + def initialize + @class_name = nil + @method_descriptions = [] + end + + def generate_class_initializer + buffer = "" + buffer << " class #{class_name}\n" + method_descriptions.each do |method_description| + buffer << method_description.generate_alias + buffer << method_description.generate_body + end + buffer << " end\n\n" + buffer + end + + def has_methods_with_optional_arguments? + method_descriptions.each do |m| + return true if m.optional_args.length > 0 + end + false + end end class Generator @@ -46,88 +110,65 @@ class Generator out.puts <<-END require 'fox16' +$VERBOSE = nil + module Fox END out.puts(DATA.read) end - def generate_class_initializer(desc) - argument_names = desc.optional_args.map { |arg| arg.name } - defaults_hash = desc.optional_args.map { |arg| ":#{arg.name} => #{arg.value}"} - defaults_hash = "{ #{defaults_hash.join(', ')} }" - required_args = desc.required_args.join(", ") - optional_args = desc.optional_args.map { |arg| "params[:#{arg.name}]"} - optional_args = optional_args.join(", ") - buffer = "" - buffer << " class #{desc.class_name}\n" - buffer << " alias old_initialize initialize\n" - buffer << " def initialize(#{required_args}#{desc.required_args.length > 0 ? ', ' : ''}*args, &blk)\n" - buffer << " argument_names = %w{#{argument_names.join(' ')}}\n" - buffer << " default_params = #{defaults_hash}\n" - buffer << " params = {}\n" - buffer << " params = args.pop if args.last.is_a? Hash\n" - buffer << " args.each_with_index { |e, i| params[argument_names[i].intern] = e }\n" - if desc.optional_args.any? { |arg| arg.name == "padLeft" } - buffer << " if params.key? :padding\n" - buffer << " value = params.delete(:padding)\n" - buffer << " [:padLeft, :padRight, :padTop, :padBottom].each { |s| params[s] ||= value }\n" - buffer << " end\n" - end - buffer << " params.keys.each { |key| raise ArgumentError, \"Unrecognized parameter \#{key}\" unless default_params.keys.include?(key) }\n" - buffer << " params = default_params.merge(params)\n" - buffer << " old_initialize(#{required_args}#{(desc.required_args.length > 0) && (desc.optional_args.length > 0) ? ', ' : ''}#{optional_args}, &blk)\n" - buffer << " end\n" - buffer << " end\n\n" - buffer - end - def go(filenames, output_filename) out = File.new(output_filename, "w") - descriptions = [] - filenames.each { |filename| descriptions += scan_for_descriptions(filename) } + class_descriptions = [] + filenames.each { |filename| class_descriptions += scan_for_descriptions(filename) } generate_preamble(out) - descriptions.each do |desc| - out.puts generate_class_initializer(desc) if desc.optional_args.length > 0 + class_descriptions.each do |class_description| + out.puts class_description.generate_class_initializer if class_description.has_methods_with_optional_arguments? end generate_closing(out) end def generate_closing(out) out.puts "end" + out.puts "" + out.puts "$VERBOSE = true" end def scan_for_descriptions(filename) - desc = nil - descriptions = [] + class_description = nil + class_descriptions = [] IO.foreach(filename) do |str| if str =~ /^ class\s*(\w+).*$/ - desc = Desc.new - desc.class_name = $1 - elsif str =~ /def initialize\((.*)\)/ -# args = $1.split(',').map { |x| x.strip } - args = $1.split(', ').map { |x| x.strip } + class_description = ClassDescription.new + class_description.class_name = $1 + elsif str =~ /def (initialize|findText)\((.*)\)/ + method_description = MethodDescription.new + method_description.method_name = $1 +# args = $2.split(',').map { |x| x.strip } + args = $2.split(', ').map { |x| x.strip } args.each do |arg| if arg =~ /(.*)=(.*)/ - desc.optional_args << Arg.new($1, $2) + method_description.optional_args << Arg.new($1, $2) elsif - desc.required_args << arg + method_description.required_args << arg end end - if @known_classes.has_key? desc.class_name - warn "Overloaded initialize method for class: #{desc.class_name}" + if @known_classes.has_key? class_description.class_name + warn "Overloaded initialize method for class: #{class_description.class_name}" end - @known_classes[desc.class_name] = 1 + @known_classes[class_description.class_name] = 1 + class_description.method_descriptions << method_description elsif str =~ /^ end/ - descriptions << desc unless skip?(desc.class_name) - desc = nil + class_descriptions << class_description unless skip?(class_description.class_name) + class_description = nil end end - descriptions + class_descriptions end def skip?(name) - %w{FX4Splitter FXCursor FXDCWindow FXExtentd FXExtentf FXFont FXGLCanvas FXGLShape FXGLViewer FXDockBar FXMenuBar FXToolBar FXQuatd FXQuatf FXRanged FXRangef FXRecentFiles FXRectangle FXRegion FXSize FXSphered FXSpheref FXSplitter FXWindow}.include? name + CLASSES_TO_SKIP.include? name end end @@ -191,7 +232,9 @@ __END__ end class FXFont + alias old_initialize initialize + def initialize(a, arg1, *args, &blk) if args.length > 0 face, size = arg1, args[0] @@ -207,6 +250,22 @@ __END__ old_initialize(a, arg1, &blk) end end + + class << self + alias old_listFonts listFonts + end + + def FXFont.listFonts(face, *args) + argument_names = %w{weight slant setWidth encoding hints} + default_params = { :weight => 0, :slant => 0, :setWidth => 0, :encoding => 0, :hints => 0 } + params = {} + params = args.pop if args.last.is_a? Hash + args.each_with_index { |e, i| params[argument_names[i].intern] = e } + params.keys.each { |key| raise ArgumentError, "Unrecognized parameter #{key}" unless default_params.keys.include?(key) } + params = default_params.merge(params) + old_listFonts(face, params[:weight], params[:slant], params[:setWidth], params[:encoding], params[:hints]) + end + end class FXGLCanvas @@ -261,6 +320,7 @@ __END__ params = {} params = args.pop if args.last.is_a? Hash if args.length > 0 && (args[0].nil? || args[0].is_a?(FXComposite)) + q = args[0] args.each_with_index { |e, i| params[argument_names[i-1].intern] = e if i >= 1 } if params.key? :padding value = params.delete(:padding) diff --git a/swig-interfaces/FXApp.i b/swig-interfaces/FXApp.i index 56d6546b535f87cfc5855a071259b82b22a60638..b05387f0e7f64bd379be1a3355ea93a606331c10 100755 --- a/swig-interfaces/FXApp.i +++ b/swig-interfaces/FXApp.i @@ -173,7 +173,13 @@ public: * as keys into the registry database for this application's settings */ FXApp(const FXchar* name="Application",const FXchar* vendor="FoxDefault"){ - return FXRbApp::constructAndInit(name,vendor); + if(FXApp::instance()){ + rb_raise(rb_eRuntimeError,"attempted to create more than one FXApp instance"); + return 0; + } + else{ + return FXRbApp::constructAndInit(name,vendor); + } } } @@ -315,7 +321,7 @@ public: FXint sig; switch(TYPE(sigObj)){ case T_STRING: - s=STR2CSTR(sigObj); + s=StringValuePtr(sigObj); sig=FXRbSignalNameToNumber(s); if(sig==0) rb_raise(rb_eArgError,"unrecognized signal name `%s'",s); break; @@ -335,7 +341,7 @@ public: FXint sig; switch(TYPE(sigObj)){ case T_STRING: - s=STR2CSTR(sigObj); + s=StringValuePtr(sigObj); sig=FXRbSignalNameToNumber(s); if(sig==0) rb_raise(rb_eArgError,"unrecognized signal name `%s'",s); break; diff --git a/swig-interfaces/FXDialogBox.i b/swig-interfaces/FXDialogBox.i index 831f78c1ef0c99d5521e3b4d2e32c24f0921d082..31dcb24a4c1cef5d5c4ebfb2d1e3b20a27e9bce7 100755 --- a/swig-interfaces/FXDialogBox.i +++ b/swig-interfaces/FXDialogBox.i @@ -20,7 +20,6 @@ * at "lyle@users.sourceforge.net". ***********************************************************************/ - /** * DialogBox window. * When receiving ID_CANCEL or ID_ACCEPT, the DialogBox breaks out of the @@ -44,13 +43,13 @@ public: public: %extend { /// Construct free-floating dialog - FXDialogBox(FXApp* a,const FXString& name,FXuint opts=DECOR_TITLE|DECOR_BORDER,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=10,FXint pr=10,FXint pt=10,FXint pb=10,FXint hs=4,FXint vs=4){ - return new FXRbDialogBox(a,name,opts,x,y,w,h,pl,pr,pt,pb,hs,vs); + FXDialogBox(FXApp* APP,const FXString& name,FXuint opts=DECOR_TITLE|DECOR_BORDER,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=10,FXint pr=10,FXint pt=10,FXint pb=10,FXint hs=4,FXint vs=4){ + return new FXRbDialogBox(APP,name,opts,x,y,w,h,pl,pr,pt,pb,hs,vs); } /// Construct dialog which will always float over the owner window - FXDialogBox(FXWindow* owner,const FXString& name,FXuint opts=DECOR_TITLE|DECOR_BORDER,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=10,FXint pr=10,FXint pt=10,FXint pb=10,FXint hs=4,FXint vs=4){ - return new FXRbDialogBox(owner,name,opts,x,y,w,h,pl,pr,pt,pb,hs,vs); + FXDialogBox(FXWindow* OWNER,const FXString& name,FXuint opts=DECOR_TITLE|DECOR_BORDER,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=10,FXint pr=10,FXint pt=10,FXint pb=10,FXint hs=4,FXint vs=4){ + return new FXRbDialogBox(OWNER,name,opts,x,y,w,h,pl,pr,pt,pb,hs,vs); } } diff --git a/swig-interfaces/FXFileDialog.i b/swig-interfaces/FXFileDialog.i index cf256b87c7e48404da4e97ec8807a62facb4fefc..421f731cf9bb8eaaf20ecd1def82b9e8a7c05573 100755 --- a/swig-interfaces/FXFileDialog.i +++ b/swig-interfaces/FXFileDialog.i @@ -104,13 +104,13 @@ public: void setPatternList(VALUE ary) { FXString patterns; if(TYPE(ary)==T_STRING){ - patterns=FXString(STR2CSTR(ary)); + patterns=FXString(StringValuePtr(ary)); } else if(TYPE(ary)==T_ARRAY){ - for(long i=0; i<RARRAY(ary)->len; i++){ + for(long i=0; i<RARRAY_LEN(ary); i++){ VALUE obj=rb_ary_entry(ary,i); Check_Type(obj,T_STRING); - patterns+=FXString(STR2CSTR(obj))+FXString("\n"); + patterns+=FXString(StringValuePtr(obj))+FXString("\n"); } } else{ diff --git a/swig-interfaces/FXFileSelector.i b/swig-interfaces/FXFileSelector.i index 90b9efd60dca2aa221c413355a1ff6de523132de..1070ba535c51c81a915e2b546abb6065198d3cef 100755 --- a/swig-interfaces/FXFileSelector.i +++ b/swig-interfaces/FXFileSelector.i @@ -201,13 +201,13 @@ public: void setPatternList(VALUE ary) { FXString patterns; if(TYPE(ary)==T_STRING){ - patterns=FXString(STR2CSTR(ary)); + patterns=FXString(StringValuePtr(ary)); } else if(TYPE(ary)==T_ARRAY){ - for(long i=0; i<RARRAY(ary)->len; i++){ + for(long i=0; i<RARRAY_LEN(ary); i++){ VALUE obj=rb_ary_entry(ary,i); Check_Type(obj,T_STRING); - patterns+=FXString(STR2CSTR(obj))+FXString("\n"); + patterns+=FXString(StringValuePtr(obj))+FXString("\n"); } } else{ diff --git a/swig-interfaces/FXFoldingList.i b/swig-interfaces/FXFoldingList.i index e35df45a584391b945ad1b8e5f0db6d283757416..cd33629a6d89ceb6276eb9738d37d4d7a5837b6f 100755 --- a/swig-interfaces/FXFoldingList.i +++ b/swig-interfaces/FXFoldingList.i @@ -228,11 +228,12 @@ public: /// Set headers from array of strings void setHeaders(VALUE stringArray,FXint size=1){ Check_Type(stringArray,T_ARRAY); - long len=RARRAY(stringArray)->len; + long len=RARRAY_LEN(stringArray); const FXchar **strings; if(FXMALLOC(&strings,FXchar*,len+1)){ for(long i=0;i<len;i++){ - strings[i]=STR2CSTR(rb_ary_entry(stringArray,i)); + VALUE s=rb_ary_entry(stringArray,i); + strings[i]=StringValuePtr(s); } strings[len]=0; self->setHeaders(strings,size); diff --git a/swig-interfaces/FXImage.i b/swig-interfaces/FXImage.i index fd6fbfaa61a1baef8ea356e2a3702a3e8097a3b1..3ecef04abe6164cc33f5f8fd5097726c6caaff1b 100755 --- a/swig-interfaces/FXImage.i +++ b/swig-interfaces/FXImage.i @@ -59,8 +59,8 @@ public: FXColor* pix=0; if(!NIL_P(ary)){ Check_Type(ary,T_ARRAY); - if(FXMALLOC(&pix,FXColor,RARRAY(ary)->len)){ - for(long i=0; i<RARRAY(ary)->len; i++){ + if(FXMALLOC(&pix,FXColor,RARRAY_LEN(ary))){ + for(long i=0; i<RARRAY_LEN(ary); i++){ pix[i]=static_cast<FXColor>(NUM2UINT(rb_ary_entry(ary,i))); } } diff --git a/swig-interfaces/FXMainWindow.i b/swig-interfaces/FXMainWindow.i index dd59958e3685d1eb93f34ae5d0f29cc1d74128a3..08f461aedb1bcc9c03a3b629f6838f16b94f9bc6 100755 --- a/swig-interfaces/FXMainWindow.i +++ b/swig-interfaces/FXMainWindow.i @@ -20,7 +20,6 @@ * at "lyle@users.sourceforge.net". ***********************************************************************/ - /** * Main application window. There may be any number of * MainWindows in an application. @@ -36,8 +35,8 @@ protected: public: %extend { /// Construct a main window - FXMainWindow(FXApp* a,const FXString& name,FXIcon *ic=NULL,FXIcon *mi=NULL,FXuint opts=DECOR_ALL,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=0,FXint pr=0,FXint pt=0,FXint pb=0,FXint hs=0,FXint vs=0){ - return new FXRbMainWindow(a,name,ic,mi,opts,x,y,w,h,pl,pr,pt,pb,hs,vs); + FXMainWindow(FXApp* APP,const FXString& name,FXIcon *ic=NULL,FXIcon *mi=NULL,FXuint opts=DECOR_ALL,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=0,FXint pr=0,FXint pt=0,FXint pb=0,FXint hs=0,FXint vs=0){ + return new FXRbMainWindow(APP,name,ic,mi,opts,x,y,w,h,pl,pr,pt,pb,hs,vs); } } diff --git a/swig-interfaces/FXMemoryStream.i b/swig-interfaces/FXMemoryStream.i index cf503ddf32522fe74354fa7ba5cc6d73d2186adb..8f7558e6ae98206fcd1632b8a106964cb8006a7a 100755 --- a/swig-interfaces/FXMemoryStream.i +++ b/swig-interfaces/FXMemoryStream.i @@ -36,8 +36,8 @@ public: FXuval size=0; FXuchar *data=0; if(!NIL_P(str)){ - size=RSTRING(str)->len; - data=reinterpret_cast<FXuchar*>(STR2CSTR(str)); + size=RSTRING_LEN(str); + data=reinterpret_cast<FXuchar*>(StringValuePtr(str)); return self->open(save_or_load,size,data); } else{ @@ -59,7 +59,7 @@ public: void giveBuffer(VALUE str){ Check_Type(str,T_STRING); FXuchar* buffer=reinterpret_cast<FXuchar*>(StringValuePtr(str)); - FXuval sp=RSTRING(str)->len; + FXuval sp=RSTRING_LEN(str); self->giveBuffer(buffer,sp); } } diff --git a/swig-interfaces/FXMessageBox.i b/swig-interfaces/FXMessageBox.i index 47c5f31dcb9eca103dbae9b3817d8b62c4235aba..45250b06989bed1bd72724133b9dc532105ef921 100755 --- a/swig-interfaces/FXMessageBox.i +++ b/swig-interfaces/FXMessageBox.i @@ -28,10 +28,12 @@ enum { MBOX_YES_NO_CANCEL = 0x40000000, /// Message box has YES, NO, and CANCEL buttons MBOX_QUIT_CANCEL = 0x50000000, /// Message box has QUIT and CANCEL buttons MBOX_QUIT_SAVE_CANCEL = 0x60000000, /// Message box has QUIT, SAVE, and CANCEL buttons - MBOX_SKIP_SKIPALL_CANCEL = 0x70000000, /// Message box has SKIP, SKIP ALL, and CANCEL buttons - MBOX_SAVE_CANCEL_DONTSAVE = 0x80000000 /// Message box has DON'T SAVE,CANCEL and SAVE buttons + MBOX_SKIP_SKIPALL_CANCEL = 0x70000000 /// Message box has SKIP, SKIP ALL, and CANCEL buttons }; +/* SWIG doesn't wrap this value correctly without a hint */ +%constant FXuint MBOX_SAVE_CANCEL_DONTSAVE = 0x80000000; // Message box has DON'T SAVE,CANCEL and SAVE buttons + // Return values enum { @@ -45,6 +47,8 @@ enum { MBOX_CLICKED_SKIPALL = 8 /// The SKIP ALL button was clicked }; +/* FOX doesn't define this constant, but we do for consistency */ +%constant MBOX_CLICKED_DONTSAVE = MBOX_CLICKED_NO; /** * A Message Box is a convenience class which provides a dialog for diff --git a/swig-interfaces/FXPoint.i b/swig-interfaces/FXPoint.i index a28bcf82117d25e074c5d52acf01bcdf68f67dc3..ad333477d462eb524ee519cdee49d89fbb651acf 100755 --- a/swig-interfaces/FXPoint.i +++ b/swig-interfaces/FXPoint.i @@ -28,10 +28,9 @@ public: public: /// Constructors - FXPoint(); FXPoint(const FXSize& s); FXPoint(const FXPoint& p); - FXPoint(FXshort xx,FXshort yy); + FXPoint(FXshort xx=0,FXshort yy=0); %extend { /// Equality diff --git a/swig-interfaces/FXRanged.i b/swig-interfaces/FXRanged.i index 9aafeeffb83280bf9a3c81f83c499df7fe78b8ee..5679eb61a7688c69e3eff08d3f6c90b821dbc097 100755 --- a/swig-interfaces/FXRanged.i +++ b/swig-interfaces/FXRanged.i @@ -146,6 +146,10 @@ public: } /// Union of two boxes + // This is not a typo. + // We're calling this method "onion" to work around a bug in SWIG + // that mistakes the method name "union" for the C++ keyword of the same + // name. FXRanged onion(const FXRanged& other) const { return FX::unite(*self,other); } diff --git a/swig-interfaces/FXRangef.i b/swig-interfaces/FXRangef.i index 88059ae5550d596a70b63446972cd1cedf6d54f4..c3fde7692d58f9b5255fdab5992a59d8b9283b34 100755 --- a/swig-interfaces/FXRangef.i +++ b/swig-interfaces/FXRangef.i @@ -40,9 +40,6 @@ /// Range class FXRangef { -public: - FXVec3f lower; - FXVec3f upper; public: // Default constructor @@ -68,12 +65,21 @@ public: } return (*self)[i]; } + void __setitem__(FXint i,FXVec3f& slice){ if(i<0||1<i){ rb_raise(rb_eIndexError,"index %d out of bounds",i); } (*self)[i]=slice; } + + FXVec3f upper() const { + return self->upper; + } + + FXVec3f lower() const { + return self->lower; + } } // Width of box @@ -151,6 +157,8 @@ public: } /// Union of two boxes + // This is not a typo. We're calling it "onion" here to work around + // a bug in SWIG that thinks "union" is the C++ keyword union. FXRangef onion(const FXRangef& other) const { return FX::unite(*self,other); } diff --git a/swig-interfaces/FXScintilla.i b/swig-interfaces/FXScintilla.i index b8963672dd5b993a3de10e6e1e1760dad1147460..cacb74919abc81f811a571c7d799223f43d8c228 100755 --- a/swig-interfaces/FXScintilla.i +++ b/swig-interfaces/FXScintilla.i @@ -143,7 +143,7 @@ public: wp=static_cast<uptr_t>(NUM2UINT(wParam)); break; case T_STRING: - wp=static_cast<uptr_t>(reinterpret_cast<long>(RSTRING(wParam)->ptr)); + wp=static_cast<uptr_t>(reinterpret_cast<long>(RSTRING_PTR(wParam))); break; case T_TRUE: case T_FALSE: @@ -161,7 +161,7 @@ public: lp=static_cast<sptr_t>(NUM2UINT(lParam)); break; case T_STRING: - lp=static_cast<sptr_t>(reinterpret_cast<long>(RSTRING(lParam)->ptr)); + lp=static_cast<sptr_t>(reinterpret_cast<long>(RSTRING_PTR(lParam))); break; case T_TRUE: case T_FALSE: diff --git a/swig-interfaces/FXSettings.i b/swig-interfaces/FXSettings.i index 77e0b7d930bddc980337af16c65ca24a652d3539..a8df6c57e91d4ebfee9740555ec5426a6bf43dd0 100755 --- a/swig-interfaces/FXSettings.i +++ b/swig-interfaces/FXSettings.i @@ -26,6 +26,8 @@ class FXStringDict; %ignore FXSettings::operator=(const FXSettings& orig); %ignore FXSettings::readFormatEntry(const FXchar *section,const FXchar *key,const FXchar *fmt,...); %ignore FXSettings::writeFormatEntry(const FXchar *section,const FXchar *key,const FXchar *fmt,...); +%ignore FXSettings::readBoolEntry(const FXchar *,const FXchar *,FXbool); +%ignore FXSettings::writeBoolEntry(const FXchar *,const FXchar *,FXbool); /** * The Settings class manages a key-value database. This is normally used as diff --git a/swig-interfaces/FXTable.i b/swig-interfaces/FXTable.i index 97464a33c90ef4c56defbf2e4852acbc02428f87..7cf539b2cc57a9588195c63b9e9f726abab3e1af 100755 --- a/swig-interfaces/FXTable.i +++ b/swig-interfaces/FXTable.i @@ -554,52 +554,52 @@ public: void fitColumnsToContents(FXint col,FXint nc=1); /// Change column header - void setColumnText(FXint index,const FXString& text); + void setColumnText(FXint TABLE_COLUMN_INDEX,const FXString& text); /// Return text of column header at index - FXString getColumnText(FXint index) const; + FXString getColumnText(FXint TABLE_COLUMN_INDEX) const; /// Change row header - void setRowText(FXint index,const FXString& text); + void setRowText(FXint TABLE_ROW_INDEX,const FXString& text); /// Return text of row header at index - FXString getRowText(FXint index) const; + FXString getRowText(FXint TABLE_ROW_INDEX) const; /// Change column header icon - void setColumnIcon(FXint index,FXIcon* icon); + void setColumnIcon(FXint TABLE_COLUMN_INDEX,FXIcon* icon); /// Return icon of column header at index - FXIcon* getColumnIcon(FXint index) const; + FXIcon* getColumnIcon(FXint TABLE_COLUMN_INDEX) const; /// Change row header icon - void setRowIcon(FXint index,FXIcon* icon); + void setRowIcon(FXint TABLE_ROW_INDEX,FXIcon* icon); /// Return icon of row header at index - FXIcon* getRowIcon(FXint index) const; + FXIcon* getRowIcon(FXint TABLE_ROW_INDEX) const; /// Change column header icon position, e.g. FXHeaderItem::BEFORE, etc. - void setColumnIconPosition(FXint index,FXuint mode); + void setColumnIconPosition(FXint TABLE_COLUMN_INDEX,FXuint mode); /// Return icon position of column header at index - FXuint getColumnIconPosition(FXint index) const; + FXuint getColumnIconPosition(FXint TABLE_COLUMN_INDEX) const; /// Change row header icon position, e.g. FXHeaderItem::BEFORE, etc. - void setRowIconPosition(FXint index,FXuint mode); + void setRowIconPosition(FXint TABLE_ROW_INDEX,FXuint mode); /// Return icon position of row header at index - FXuint getRowIconPosition(FXint index) const; + FXuint getRowIconPosition(FXint TABLE_ROW_INDEX) const; /// Change column header justify, e.g. FXHeaderItem::RIGHT, etc. - void setColumnJustify(FXint index,FXuint justify); + void setColumnJustify(FXint TABLE_COLUMN_INDEX,FXuint justify); /// Return justify of column header at index - FXuint getColumnJustify(FXint index) const; + FXuint getColumnJustify(FXint TABLE_COLUMN_INDEX) const; /// Change row header justify, e.g. FXHeaderItem::RIGHT, etc. - void setRowJustify(FXint index,FXuint justify); + void setRowJustify(FXint TABLE_ROW_INDEX,FXuint justify); /// Return justify of row header at index - FXuint getRowJustify(FXint index) const; + FXuint getRowJustify(FXint TABLE_ROW_INDEX) const; %extend { /// Modify cell text @@ -652,21 +652,19 @@ public: %extend { /// Extract cells from given range as text. VALUE extractText(FXint startrow,FXint endrow,FXint startcol,FXint endcol,const FXchar* cs="\t",const FXchar* rs="\n") const { - FXchar* text; - FXint size; + FXString str; VALUE result; if(startrow<0 || startcol<0 || self->getNumRows()<=endrow || self->getNumColumns()<=endcol) rb_raise(rb_eIndexError,"index out of bounds"); - self->extractText(text,size,startrow,endrow,startcol,endcol,cs,rs); - result=rb_str_new2(text); - FXFREE(&text); + self->extractText(str,startrow,endrow,startcol,endcol,cs,rs); + result=rb_str_new2(str.text()); return result; } /// Overlay text over given cell range void overlayText(FXint startrow,FXint endrow,FXint startcol,FXint endcol,VALUE str,const FXchar* cs="\t",const FXchar* rs="\n",FXbool notify=FALSE){ if(startrow<0 || startcol<0 || self->getNumRows()<=endrow || self->getNumColumns()<=endcol) rb_raise(rb_eIndexError,"index out of bounds"); - const FXchar* text=reinterpret_cast<FXchar*>(STR2CSTR(str)); - FXint size=RSTRING(str)->len; + const FXchar* text=reinterpret_cast<FXchar*>(StringValuePtr(str)); + FXint size=RSTRING_LEN(str); self->overlayText(startrow,endrow,startcol,endcol,text,size,cs,rs,notify); } } diff --git a/swig-interfaces/FXText.i b/swig-interfaces/FXText.i index 0a0d45ee846cf0c598be21b26c8a9c5110fb8bb1..0c3e9963be6b0c77b5a79909b793fb7fbf88f766 100755 --- a/swig-interfaces/FXText.i +++ b/swig-interfaces/FXText.i @@ -43,7 +43,20 @@ enum FXTextSelectionMode { /// Highlight style entry struct FXHiliteStyle { - FXHiliteStyle(); + %extend { + FXHiliteStyle(){ + FXHiliteStyle *self = new FXHiliteStyle(); + self->normalForeColor = 0; + self->normalBackColor = 0; + self->selectForeColor = 0; + self->selectBackColor = 0; + self->hiliteForeColor = 0; + self->hiliteBackColor = 0; + self->activeBackColor = 0; + self->style = 0; + return self; + } + } FXColor normalForeColor; /// Normal text foreground color FXColor normalBackColor; /// Normal text background color FXColor selectForeColor; /// Selected text foreground color @@ -519,29 +532,25 @@ public: * both are NULL, internal arrays are used. * [This API is still subject to change!!] */ - VALUE findText(const FXString& string,FXint start=0,FXuint flags=SEARCH_FORWARD|SEARCH_WRAP|SEARCH_EXACT,FXint npar=1){ + VALUE findText(const FXString& string,FXint start=0,FXuint flags=SEARCH_FORWARD|SEARCH_WRAP|SEARCH_EXACT){ FXint* beg; FXint* end; VALUE ary=Qnil; - - if(!FXMALLOC(&beg,FXint,npar)){ + FXint ngroups=string.contains('(')+1; // FIXME: is this right? + if(!FXMALLOC(&beg,FXint,ngroups)){ return Qnil; - } - - if(!FXMALLOC(&end,FXint,npar)){ + } + if(!FXMALLOC(&end,FXint,ngroups)){ FXFREE(&beg); - return Qnil; - } - - if(self->findText(string,beg,end,start,flags,npar)){ + return Qnil; + } + if(self->findText(string,beg,end,start,flags,ngroups)){ ary=rb_ary_new(); - rb_ary_push(ary,FXRbMakeArray(beg,npar)); - rb_ary_push(ary,FXRbMakeArray(end,npar)); + rb_ary_push(ary,FXRbMakeArray(beg,ngroups)); + rb_ary_push(ary,FXRbMakeArray(end,ngroups)); } - FXFREE(&beg); FXFREE(&end); - return ary; } } @@ -706,7 +715,7 @@ public: delete [] text->styles; text->numStyles=0; } - text->numStyles=RARRAY(styles)->len; + text->numStyles=RARRAY_LEN(styles); if(text->numStyles>0){ text->styles=new FXHiliteStyle[text->numStyles]; for (long i=0; i<text->numStyles; i++){ diff --git a/swig-interfaces/FXVec2d.i b/swig-interfaces/FXVec2d.i index 3b296727be9a9c1fb451c3d3eb5988d9899d3b9e..25447940b1e151b192af22752656acf8a9ea7568 100755 --- a/swig-interfaces/FXVec2d.i +++ b/swig-interfaces/FXVec2d.i @@ -27,15 +27,12 @@ public: FXdouble y; public: - /// Default constructor - FXVec2d(); + /// Initialize with components + FXVec2d(FXdouble xx=0.0,FXdouble yy=0.0); /// Copy constructor FXVec2d(const FXVec2d& v); - /// Initialize with components - FXVec2d(FXdouble xx,FXdouble yy); - /// Length and square of length FXdouble length2() const; FXdouble length() const; diff --git a/swig-interfaces/FXVec2f.i b/swig-interfaces/FXVec2f.i index b590a5e5dafddf40045046c0024ffcb918522a52..173bbcca34ab268790cae23111d2dc4377214ff6 100755 --- a/swig-interfaces/FXVec2f.i +++ b/swig-interfaces/FXVec2f.i @@ -27,8 +27,8 @@ public: FXfloat y; public: - /// Default constructor - FXVec2f(); + /// Initialize with components + FXVec2f(FXfloat xx=0.0f,FXfloat yy=0.0f); /// Copy constructor FXVec2f(const FXVec2f& v); @@ -36,9 +36,6 @@ public: // Initialize from array of floats FXVec2f(const FXfloat v[]); - /// Initialize with components - FXVec2f(FXfloat xx,FXfloat yy); - /// Length and square of length FXfloat length2() const; FXfloat length() const; diff --git a/swig-interfaces/FXVec3d.i b/swig-interfaces/FXVec3d.i index 0ac564bbe938be10e3b829bf9d3abea929672409..61d78e6a3839bf33f9bb57720622856509a6706d 100755 --- a/swig-interfaces/FXVec3d.i +++ b/swig-interfaces/FXVec3d.i @@ -29,7 +29,11 @@ public: public: /// Default constructor - FXVec3d(); + %extend { + FXVec3d() { + return new FXVec3d(0.0, 0.0, 0.0); + } + } /// Copy constructor FXVec3d(const FXVec3d& v); diff --git a/swig-interfaces/FXVec3f.i b/swig-interfaces/FXVec3f.i index 86ce4922f30a897ee03b16fa55557da1c8a6aa1d..f32b33d570c7d6f5e51895bb10db189c7a60b6e6 100755 --- a/swig-interfaces/FXVec3f.i +++ b/swig-interfaces/FXVec3f.i @@ -29,7 +29,11 @@ public: public: /// Default constructor - FXVec3f(); + %extend { + FXVec3f() { + return new FXVec3f(0.0f, 0.0f, 0.0f); + } + } /// Copy constructor FXVec3f(const FXVec3f& v); diff --git a/swig-interfaces/FXVec4d.i b/swig-interfaces/FXVec4d.i index 7882ffee860a640a1a22347c5e28fd6d2e36c960..ff3560fe128df4a629a0aed10e9b48e6d787c8f3 100755 --- a/swig-interfaces/FXVec4d.i +++ b/swig-interfaces/FXVec4d.i @@ -32,7 +32,11 @@ public: public: /// Default constructor - FXVec4d(); + %extend { + FXVec4d() { + return new FXVec4d(0.0, 0.0, 0.0, 0.0); + } + } /// Copy constructor FXVec4d(const FXVec4d& v); diff --git a/swig-interfaces/FXVec4f.i b/swig-interfaces/FXVec4f.i index 0eeaa66af5cbbe8224a6077041ff9cb45c4ee8d0..2ba700a3610bff04deb8c38edde2caf006a6c14d 100755 --- a/swig-interfaces/FXVec4f.i +++ b/swig-interfaces/FXVec4f.i @@ -32,7 +32,11 @@ public: public: /// Default constructor - FXVec4f(); + %extend { + FXVec4f() { + return new FXVec4f(0.0f, 0.0f, 0.0f, 0.0f); + } + } /// Copy constructor FXVec4f(const FXVec4f& w); diff --git a/swig-interfaces/FXWindow.i b/swig-interfaces/FXWindow.i index 28aad47a41b5ab5db9f3fd32b72a8308d96ff50d..5f2462100804631bb00da1d8e2b9b6a91e27c800 100755 --- a/swig-interfaces/FXWindow.i +++ b/swig-interfaces/FXWindow.i @@ -595,7 +595,7 @@ public: bool acquireSelection(VALUE typesArray){ Check_Type(typesArray,T_ARRAY); FXDragType *types=0; - FXuint numtypes=RARRAY(typesArray)->len; + FXuint numtypes=RARRAY_LEN(typesArray); if(numtypes>0){ types=new FXDragType[numtypes]; for(FXuint i=0;i<numtypes;i++){ @@ -619,7 +619,7 @@ public: bool acquireClipboard(VALUE typesArray){ Check_Type(typesArray,T_ARRAY); FXDragType *types=0; - FXuint numtypes=RARRAY(typesArray)->len; + FXuint numtypes=RARRAY_LEN(typesArray); if(numtypes>0){ types=new FXDragType[numtypes]; for(FXuint i=0;i<numtypes;i++){ @@ -646,7 +646,7 @@ public: bool beginDrag(VALUE typesArray){ Check_Type(typesArray,T_ARRAY); FXDragType *types=0; - FXuint numtypes=RARRAY(typesArray)->len; + FXuint numtypes=RARRAY_LEN(typesArray); if(numtypes>0){ types=new FXDragType[numtypes]; for(FXuint i=0;i<numtypes;i++){ @@ -728,9 +728,9 @@ public: void setDNDData(FXDNDOrigin origin, FXDragType type, VALUE str) const { Check_Type(str, T_STRING); FXuchar* data; - FXuint size = RSTRING(str)->len; + FXuint size = RSTRING_LEN(str); if (FXMALLOC(&data, FXuchar, size)) { - memcpy((void *) data, (void *) RSTRING(str)->ptr, size); + memcpy((void *) data, (void *) RSTRING_PTR(str), size); self->setDNDData(origin, type, data, size); } else { rb_raise(rb_eNoMemError, "couldn't copy drag-and-drop data"); diff --git a/swig-interfaces/FXXPMIcon.i b/swig-interfaces/FXXPMIcon.i index cc29a0439705cd692a50d7a1aec2a631452da296..e648f466cf91a6ab56d29b4c004cc82bc32630fa 100755 --- a/swig-interfaces/FXXPMIcon.i +++ b/swig-interfaces/FXXPMIcon.i @@ -86,7 +86,7 @@ DECLARE_FXIMAGE_VIRTUALS(FXXPMIcon) // Confirm that the input is an array of strings Check_Type(strArray,T_ARRAY); - len=RARRAY(strArray)->len; + len=RARRAY_LEN(strArray); for(i=0; i<len; i++){ str=rb_ary_entry(strArray,i); Check_Type(str,T_STRING); diff --git a/swig-interfaces/Makefile b/swig-interfaces/Makefile index ee28aaec27d2122a4135073bc92fa3a72e840a5d..a989672c619b91b05bfe437436af2a63bf5937a9 100755 --- a/swig-interfaces/Makefile +++ b/swig-interfaces/Makefile @@ -2,17 +2,17 @@ # This makefile is used to generate the wrapper code from the # SWIG interface files. # -# $Id: Makefile 2300 2005-12-07 14:05:03Z lyle $ +# $Id: Makefile 2827 2008-03-28 16:04:44Z lyle $ # .PHONY: clean -SWIG = swig +SWIG = /usr/local/bin/swig SWIGFLAGS = -fcompact -noruntime -c++ -ruby -no_default -I../fox-includes SRCDIR = ../ext/fox16 SED = sed -f swig.sed RUBY = ruby -SWIGLIB := $(shell swig -swiglib) +SWIGLIB := $(shell /usr/local/bin/swig -swiglib) MODULES = \ $(SRCDIR)/core_wrap.cpp \ diff --git a/swig-interfaces/macros.i b/swig-interfaces/macros.i index 4d251bd558a47f043b373f5998f2c009223b7398..aacc3ff465adafe4593c1ad3eaa3c8bc504f141e 100755 --- a/swig-interfaces/macros.i +++ b/swig-interfaces/macros.i @@ -433,8 +433,8 @@ /// See if font has glyph for ch virtual FXbool hasChar(VALUE ch) const { if(TYPE(ch)==T_STRING){ - if(RSTRING(ch)->len==1){ - return self->hasChar(*(STR2CSTR(ch))); // FIXME: hasChar() expects an FXwchar + if(RSTRING_LEN(ch)==1){ + return self->hasChar(*(StringValuePtr(ch))); // FIXME: hasChar() expects an FXwchar } else{ rb_raise(rb_eArgError,"expected a string of length one"); @@ -708,7 +708,7 @@ %extend klass { /** * Retrieves pixels from the server-side image. For example, to make - * screen snapshots, or to retrieve an image after it has been drawin + * screen snapshots, or to retrieve an image after it has been drawn * into by various means. */ virtual void restore(); diff --git a/swig-interfaces/ruby-typemaps.i b/swig-interfaces/ruby-typemaps.i index 61ae7237b295ead8830a83a2f3025f87031e0658..a059b04df179396a4927131ca53a32a4dcef2dfa 100755 --- a/swig-interfaces/ruby-typemaps.i +++ b/swig-interfaces/ruby-typemaps.i @@ -20,9 +20,13 @@ * at "lyle@users.sourceforge.net". ***********************************************************************/ -/*********************************************************************** - * $Id: ruby-typemaps.i 2460 2006-07-09 23:38:59Z lyle $ - ***********************************************************************/ +%include constraints.i + +%apply Pointer NONNULL { + FXApp* APP, + FXComposite* PARENT, + FXWindow* OWNER +} /* Type-checking rules */ %typecheck(SWIG_TYPECHECK_STRING) const FXString&, FXuchar *data { @@ -61,7 +65,7 @@ inline FXColor to_FXColor(VALUE obj){ inline FXString to_FXString(VALUE obj){ if(!NIL_P(obj)){ Check_Type(obj,T_STRING); - return FXString(STR2CSTR(obj)); + return FXString(StringValuePtr(obj)); } else{ return FXString::null; @@ -112,7 +116,7 @@ inline FXbool to_FXbool(VALUE obj){ %typemap(in) const void* pix { if ($input != Qnil) { Check_Type($input, T_STRING); - $1 = reinterpret_cast<$1_ltype>(RSTRING($input)->ptr); + $1 = reinterpret_cast<$1_ltype>(RSTRING_PTR($input)); } else { $1 = NULL; } @@ -127,8 +131,8 @@ inline FXbool to_FXbool(VALUE obj){ $1=NULL; if($input!=Qnil){ Check_Type($input,T_ARRAY); - if(FXMALLOC(&$1,FXColor,RARRAY($input)->len)){ - for(long i=0; i<RARRAY($input)->len; i++){ + if(FXMALLOC(&$1,FXColor,RARRAY_LEN($input))){ + for(long i=0; i<RARRAY_LEN($input); i++){ $1[i]=static_cast<FXColor>(NUM2UINT(rb_ary_entry($input,i))); } } @@ -149,9 +153,10 @@ inline FXbool to_FXbool(VALUE obj){ $1 = NULL; if ($input != Qnil) { Check_Type($input, T_ARRAY); - if (FXMALLOC(&$1, FXchar *, RARRAY($input)->len)) { - for (long i = 0; i < RARRAY($input)->len; i++) { - $1[i] = (FXchar *) STR2CSTR(rb_ary_entry($input, i)); + if (FXMALLOC(&$1, FXchar *, RARRAY_LEN($input))) { + for (long i = 0; i < RARRAY_LEN($input); i++) { + VALUE e = rb_ary_entry($input, i); + $1[i] = (FXchar *) StringValuePtr(e); } } } @@ -166,7 +171,7 @@ inline FXbool to_FXbool(VALUE obj){ %typecheck(SWIG_TYPECHECK_STRING_ARRAY) const FXchar** strings { $1 = (TYPE($input) == T_ARRAY) ? 1 : 0; if ($1 != 0) { - for (long i = 0; i < RARRAY($input)->len; i++) { + for (long i = 0; i < RARRAY_LEN($input); i++) { if (TYPE(rb_ary_entry($input, i)) != T_STRING) { $1 = 0; break; @@ -179,11 +184,12 @@ inline FXbool to_FXbool(VALUE obj){ $1 = NULL; if(!NIL_P($input)){ Check_Type($input, T_ARRAY); - if (FXMALLOC(&$1, FXchar *, RARRAY($input)->len)+1) { - for (long i = 0; i < RARRAY($input)->len; i++) { - $1[i] = (FXchar *) STR2CSTR(rb_ary_entry($input, i)); + if (FXMALLOC(&$1, FXchar *, RARRAY_LEN($input))+1) { + for (long i = 0; i < RARRAY_LEN($input); i++) { + VALUE e = rb_ary_entry($input, i); + $1[i] = (FXchar *) StringValuePtr(e); } - $1[RARRAY($input)->len] = 0; + $1[RARRAY_LEN($input)] = 0; } } } @@ -195,11 +201,11 @@ inline FXbool to_FXbool(VALUE obj){ $1 = NULL; if(!NIL_P($input)){ Check_Type($input, T_ARRAY); - if (FXMALLOC(&$1, FXColor, RARRAY($input)->len)+1) { - for (long i = 0; i < RARRAY($input)->len; i++) { + if (FXMALLOC(&$1, FXColor, RARRAY_LEN($input))+1) { + for (long i = 0; i < RARRAY_LEN($input); i++) { $1[i] = static_cast<FXColor>(NUM2ULONG(rb_ary_entry($input, i))); } - $1[RARRAY($input)->len] = 0; + $1[RARRAY_LEN($input)] = 0; } } } @@ -231,7 +237,7 @@ inline void* to_FXEvent(VALUE obj){ %typemap(in) void* PTR_COLOR "$1 = reinterpret_cast<void*>(NUM2UINT($input));"; /* Convert a Ruby string to a C string */ -%typemap(in) void* PTR_CSTRING "$1 = static_cast<void*>(STR2CSTR($input));"; +%typemap(in) void* PTR_CSTRING "$1 = static_cast<void*>(StringValuePtr($input));"; /* Convert a Ruby array (of size 2) into an FXdouble array */ %typemap(in) void* PTR_DBLRANGE_IN(FXdouble values[2]) { @@ -320,7 +326,7 @@ inline void* to_FXEvent(VALUE obj){ /* Convert a Ruby string to a pointer to an FXString */ %typemap(in) void* PTR_STRING(FXString value) { - value = FXString(STR2CSTR($input)); + value = FXString(StringValuePtr($input)); $1 = (void *) &value; } @@ -456,6 +462,14 @@ inline void* to_FXEvent(VALUE obj){ } %typemap(out) FXMat4f& "$result = FXRbGetRubyObj($1, \"$1_ltype\");"; +/* Output typemap for FXVec2d instances */ +%typemap(out) FXVec2d* "$result = FXRbGetRubyObj($1, \"$1_ltype\");"; +%typemap(out) FXVec2d& "$result = FXRbGetRubyObj($1, \"$1_ltype\");"; + +/* Output typemap for FXVec2f instances */ +%typemap(out) FXVec2f* "$result = FXRbGetRubyObj($1, \"$1_ltype\");"; +%typemap(out) FXVec2f& "$result = FXRbGetRubyObj($1, \"$1_ltype\");"; + /* Output typemap for FXVec4f instances */ %typemap(out) FXVec4f { FXVec4f* resultptr = new FXVec4f($1); @@ -604,8 +618,8 @@ inline void* to_FXEvent(VALUE obj){ } %typemap(in) (const FXPoint* points, FXuint npoints) { Check_Type($input, T_ARRAY); - $1 = new FXPoint[RARRAY($input)->len]; - $2 = static_cast<FXuint>( RARRAY($input)->len ); + $1 = new FXPoint[RARRAY_LEN($input)]; + $2 = static_cast<FXuint>( RARRAY_LEN($input) ); for (FXuint i = 0; i < $2; i++) { FXPoint *pPoint; Data_Get_Struct(rb_ary_entry($input, i), FXPoint, pPoint); @@ -619,8 +633,8 @@ inline void* to_FXEvent(VALUE obj){ // Extract a C array (segments) and its length (nsegments) from a Ruby array of FXSegment instances %typemap(in) (const FXSegment* segments, FXuint nsegments) { Check_Type($input, T_ARRAY); - $1 = new FXSegment[RARRAY($input)->len]; - $2 = static_cast<FXuint>( RARRAY($input)->len ); + $1 = new FXSegment[RARRAY_LEN($input)]; + $2 = static_cast<FXuint>( RARRAY_LEN($input) ); for (FXuint i = 0; i < $2; i++) { FXSegment *pSeg; Data_Get_Struct(rb_ary_entry($input, i), FXSegment, pSeg); @@ -635,8 +649,8 @@ inline void* to_FXEvent(VALUE obj){ // Extract a C array (rectangles) and its length (nrectangles) from a Ruby array of FXRectangle instances %typemap(in) (const FXRectangle* rectangles, FXuint nrectangles) { Check_Type($input, T_ARRAY); - $1 = new FXRectangle[RARRAY($input)->len]; - $2 = static_cast<FXuint>( RARRAY($input)->len ); + $1 = new FXRectangle[RARRAY_LEN($input)]; + $2 = static_cast<FXuint>( RARRAY_LEN($input) ); for (FXuint i = 0; i < $2; i++) { FXRectangle *pRect; Data_Get_Struct(rb_ary_entry($input, i), FXRectangle, pRect); @@ -651,8 +665,8 @@ inline void* to_FXEvent(VALUE obj){ // Extract a C array (arcs) and its length (narcs) from a Ruby array of FXArc instances %typemap(in) (const FXArc* arcs, FXuint narcs) { Check_Type($input, T_ARRAY); - $1 = new FXArc[RARRAY($input)->len]; - $2 = static_cast<FXuint>( RARRAY($input)->len ); + $1 = new FXArc[RARRAY_LEN($input)]; + $2 = static_cast<FXuint>( RARRAY_LEN($input) ); for (FXuint i = 0; i < $2; i++) { FXArc *pArc; Data_Get_Struct(rb_ary_entry($input, i), FXArc, pArc); @@ -667,15 +681,15 @@ inline void* to_FXEvent(VALUE obj){ // Extract the C string pointer and string length from a Ruby string %typemap(in) (const FXchar* string, FXuint length) { Check_Type($input, T_STRING); - $1 = STR2CSTR($input); - $2 = RSTRING($input)->len; + $1 = StringValuePtr($input); + $2 = RSTRING_LEN($input); } // Extract a C array (dashpattern) and its length (dashlength) from a Ruby array of Fixnums %typemap(in) (const FXchar* dashpattern, FXuint dashlength) { Check_Type($input, T_ARRAY); - $1 = new FXchar[RARRAY($input)->len]; - $2 = static_cast<FXuint>( RARRAY($input)->len ); + $1 = new FXchar[RARRAY_LEN($input)]; + $2 = static_cast<FXuint>( RARRAY_LEN($input) ); for (FXuint i = 0; i < $2; i++) { $1[i] = NUM2INT(rb_ary_entry($input, i)); } @@ -687,8 +701,8 @@ inline void* to_FXEvent(VALUE obj){ %typemap(in) (FXuint* path, FXint n) { Check_Type($input, T_ARRAY); - FXMALLOC(&$1,FXuint,RARRAY($input)->len); - $2=static_cast<FXint>(RARRAY($input)->len); + FXMALLOC(&$1,FXuint,RARRAY_LEN($input)); + $2=static_cast<FXint>(RARRAY_LEN($input)); for(FXint i=0; i<$2; i++){ $1[i]=NUM2UINT(rb_ary_entry($input,i)); } @@ -701,8 +715,8 @@ inline void* to_FXEvent(VALUE obj){ /* Convert an array of FXColor values (see constructor for FXMemoryBuffer) */ %typemap(in) (FXColor *data,FXuint size) { Check_Type($input, T_ARRAY); - FXMALLOC(&$1,FXColor,RARRAY($input)->len); - $2=static_cast<FXuint>(RARRAY($input)->len); + FXMALLOC(&$1,FXColor,RARRAY_LEN($input)); + $2=static_cast<FXuint>(RARRAY_LEN($input)); for(FXint i=0; i<$2; i++){ $1[i]=static_cast<FXColor>(NUM2UINT(rb_ary_entry($input,i))); } @@ -746,7 +760,7 @@ inline void* to_FXEvent(VALUE obj){ /* Convert an FXID to a Ruby Integer (fxid_to_int() is defined in FXRuby.h) */ %typemap(out) FXID "$result = fxid_to_int($1);"; -%typemap(in) FXuchar *data "$1 = NIL_P($input) ? 0 : reinterpret_cast<FXuchar*>(STR2CSTR($input));"; +%typemap(in) FXuchar *data "$1 = NIL_P($input) ? 0 : reinterpret_cast<FXuchar*>(StringValuePtr($input));"; // FXlong values %typemap(in) FXlong "$1 = static_cast<FXlong>(NUM2LONG($input));"; diff --git a/tests/TC_FXApp.rb b/tests/TC_FXApp.rb index a21747c00743080b449f57d6864383b98d4ffaa1..3c706ece54732c8e4944e2b5392c7ecd811eece7 100755 --- a/tests/TC_FXApp.rb +++ b/tests/TC_FXApp.rb @@ -1,15 +1,16 @@ require 'test/unit' require 'fox16' -require 'testcase' include Fox -class TC_FXApp < TestCase - def setup - super(self.class.name) - end - def test_initialized - assert(app.initialized?) +class TC_FXApp < Test::Unit::TestCase + def test_exception_for_second_app + app = FXApp.new + mainWindow = FXMainWindow.new(app, "") + app.create + assert_raise RuntimeError do + app2 = FXApp.new + end end end diff --git a/tests/TC_FXButton.rb b/tests/TC_FXButton.rb index cc80bd8a4a7792d446fd29a3a559d41e117f3203..ac4484fd724d87531caa6730dcb294a0402a965d 100755 --- a/tests/TC_FXButton.rb +++ b/tests/TC_FXButton.rb @@ -69,4 +69,10 @@ class TC_FXButton < TestCase @button.state = STATE_UNCHECKED assert_equal(STATE_UNCHECKED, @button.state) end + + def test_create_for_non_created_parent_window_raises_runtime_error + assert_raise RuntimeError do + @button.create + end + end end diff --git a/tests/TC_FXComboBox.rb b/tests/TC_FXComboBox.rb index 6c2ac898ad9394166ad3540aba48c4d98cf915e2..faaf6aebbd5ce6972a6357cb0fa75768d2a6bf33 100755 --- a/tests/TC_FXComboBox.rb +++ b/tests/TC_FXComboBox.rb @@ -48,5 +48,16 @@ class TC_FXComboBox < TestCase end end + def test_fill_items_returns_num_items_added + assert_equal(3, @comboBox.fillItems(%w{one two three})) + end + + def test_fill_items + @comboBox.fillItems(%w{one two three}) + items = @comboBox.map { |text, data| text } + assert_equal("one", items[0]) + assert_equal("two", items[1]) + assert_equal("three", items[2]) + end end diff --git a/tests/TC_FXDC.rb b/tests/TC_FXDC.rb index bb7a3d748f2e1ee6a2d6c1125947746e8f344f1f..e4d25c3d7292307ce71f12995f96c002ef064d2b 100755 --- a/tests/TC_FXDC.rb +++ b/tests/TC_FXDC.rb @@ -79,7 +79,7 @@ class TC_FXDC < Test::Unit::TestCase @dc.fillRectangle(x, y, w, h) end - def testFillRectangles(rectangles) + def testFillRectangles rectangles = [ FXRectangle.new, FXRectangle.new ] @dc.fillRectangles(rectangles) end diff --git a/tests/TC_FXDCPrint.rb b/tests/TC_FXDCPrint.rb index 96907f8f89253ee8c420efa72d2d1fb591682329..c06fa52cdf0c86f3dba80ef9f072c9488a2cf83e 100755 --- a/tests/TC_FXDCPrint.rb +++ b/tests/TC_FXDCPrint.rb @@ -1,7 +1,6 @@ require 'test/unit' require 'fox16' -require 'ftools' include Fox @@ -64,14 +63,14 @@ public def test_beginPrint @dc.beginPrint(printJob) @dc.endPrint - assert_same_file_contents("blankpage.ps", printJob.name) + assert_same_file_contents(File.join(File.dirname(__FILE__), "blankpage.ps"), printJob.name) end def test_beginPrint_with_block @dc.beginPrint(printJob) do |theDC| assert_same(@dc, theDC) end - assert_same_file_contents("blankpage.ps", printJob.name) + assert_same_file_contents(File.join(File.dirname(__FILE__), "blankpage.ps"), printJob.name) end def test_beginPage @@ -96,7 +95,7 @@ public def teardown if File.exists?("output.ps") - File.rm_f("output.ps") + FileUtils.rm_f("output.ps") end end end diff --git a/tests/TC_FXDialogBox.rb b/tests/TC_FXDialogBox.rb new file mode 100644 index 0000000000000000000000000000000000000000..e65bee693860732fc935d62adeb3a100524975f2 --- /dev/null +++ b/tests/TC_FXDialogBox.rb @@ -0,0 +1,12 @@ +require 'test/unit' +require 'fox16' + +include Fox + +class TC_FXDialogBox < Test::Unit::TestCase + def test_nil_app_raises_argument_error + assert_raise ArgumentError do + FXDialogBox.new(nil, "title") + end + end +end \ No newline at end of file diff --git a/tests/TC_FXExtentd.rb b/tests/TC_FXExtentd.rb new file mode 100755 index 0000000000000000000000000000000000000000..64d37b0fd87111f0c230695df0533154cf380aba --- /dev/null +++ b/tests/TC_FXExtentd.rb @@ -0,0 +1,21 @@ +require 'test/unit' +require 'fox16' + +include Fox + +class TC_FXExtentd < Test::Unit::TestCase + def test_lower_always_returns_same_instance + e = FXExtentd.new(0, 1, 0, 1) + assert_same e.lower, e.lower + end + + def test_upper_always_returns_same_instance + e = FXExtentd.new(0, 1, 0, 1) + assert_same e.upper, e.upper + end + + def test_index_always_returns_same_instance + e = FXExtentd.new(0, 1, 0, 1) + assert_same e[0], e[0] + end +end diff --git a/tests/TC_FXExtentf.rb b/tests/TC_FXExtentf.rb new file mode 100755 index 0000000000000000000000000000000000000000..87a0db656f112a7ffb10d6e727693e6fb3fe9400 --- /dev/null +++ b/tests/TC_FXExtentf.rb @@ -0,0 +1,21 @@ +require 'test/unit' +require 'fox16' + +include Fox + +class TC_FXExtentf < Test::Unit::TestCase + def test_lower_always_returns_same_instance + e = FXExtentf.new(0, 1, 0, 1) + assert_same e.lower, e.lower + end + + def test_upper_always_returns_same_instance + e = FXExtentf.new(0, 1, 0, 1) + assert_same e.upper, e.upper + end + + def test_index_always_returns_same_instance + e = FXExtentf.new(0, 1, 0, 1) + assert_same e[0], e[0] + end +end diff --git a/tests/TC_FXFileStream.rb b/tests/TC_FXFileStream.rb index d331a88d5cc6ae18d4d300e172da8191da5a62d2..22c94883a107acd4ea45a5cd17245f7c55b333b2 100755 --- a/tests/TC_FXFileStream.rb +++ b/tests/TC_FXFileStream.rb @@ -1,6 +1,5 @@ require 'test/unit' require 'fox16' -require 'ftools' require 'tempfile' include Fox @@ -84,7 +83,7 @@ class TC_FXFileStream < Test::Unit::TestCase def teardown if File.exists?("goobers") - File.rm_f("goobers") + FileUtils.rm_f("goobers") end end end diff --git a/tests/TC_FXFoldingList.rb b/tests/TC_FXFoldingList.rb new file mode 100755 index 0000000000000000000000000000000000000000..056c2b019b928167ae9724f81a38a3b1f8d01b1a --- /dev/null +++ b/tests/TC_FXFoldingList.rb @@ -0,0 +1,32 @@ +require 'test/unit' +require 'testcase' +require 'fox16' + +include Fox + +class TC_FXFoldingList < TestCase + + def setup + super(self.class.name) + @foldingList = FXFoldingList.new(mainWindow) + end + + def test_each_for_empty_list + count = 0 + @foldingList.each { |item| count += 1 } + assert_equal(0, count, "count for empty list should be zero") + end + + def test_each + @foldingList.appendItem(nil, "1") + @foldingList.appendItem(nil, "2") + @foldingList.appendItem(nil, "3") + @foldingList.appendItem(nil, "4") + @foldingList.appendItem(nil, "5") + count = 0 + @foldingList.each { |item| count += 1 } + assert_equal(5, count, "count didn't match expected number of items") + end + +end + diff --git a/tests/TC_FXHiliteStyle.rb b/tests/TC_FXHiliteStyle.rb new file mode 100755 index 0000000000000000000000000000000000000000..35fe085c5e28c732af66d6588d3ddc0aff000382 --- /dev/null +++ b/tests/TC_FXHiliteStyle.rb @@ -0,0 +1,23 @@ +require 'fox16' +require 'test/unit' + +include Fox + +class TC_FXHiliteStyle < Test::Unit::TestCase + + def setup + @style = FXHiliteStyle.new + end + + def test_new_object_is_initialized + assert_equal(0, @style.normalForeColor) + assert_equal(0, @style.normalBackColor) + assert_equal(0, @style.selectForeColor) + assert_equal(0, @style.selectBackColor) + assert_equal(0, @style.hiliteForeColor) + assert_equal(0, @style.hiliteBackColor) + assert_equal(0, @style.activeBackColor) + assert_equal(0, @style.style) + end +end + diff --git a/tests/TC_FXId.rb b/tests/TC_FXId.rb index a6f4d4dacd9682ff1f2fbd17eed74ed860aca580..fae3391d39683ae1d7c408a368c6e01e553c95f3 100755 --- a/tests/TC_FXId.rb +++ b/tests/TC_FXId.rb @@ -10,10 +10,10 @@ class TC_FXId < TestCase end def test_created? - assert(!mainWindow.created?) + assert !mainWindow.created? app.create - assert(mainWindow.created?) + assert mainWindow.created?, "main window should be created after call to FXApp#create" mainWindow.destroy - assert(!mainWindow.created?) + assert !mainWindow.created? end end diff --git a/tests/TC_FXMainWindow.rb b/tests/TC_FXMainWindow.rb new file mode 100644 index 0000000000000000000000000000000000000000..aa88b1d7a98f1ba957e4717d667e2195c537f242 --- /dev/null +++ b/tests/TC_FXMainWindow.rb @@ -0,0 +1,19 @@ +require 'test/unit' +require 'fox16' + +include Fox + +class TC_FXMainWindow < Test::Unit::TestCase + def test_nil_app_raises_argument_error + assert_raise ArgumentError do + FXMainWindow.new(nil, "title") + end + end + + def test_non_created_app_raises_runtime_error + app = FXApp.new + assert_raise RuntimeError do + FXMainWindow.new(app, "title").create + end + end +end \ No newline at end of file diff --git a/tests/TC_FXMessageBox.rb b/tests/TC_FXMessageBox.rb new file mode 100755 index 0000000000000000000000000000000000000000..f926d29a66f7ee0253dff79f6bf773b067f4586e --- /dev/null +++ b/tests/TC_FXMessageBox.rb @@ -0,0 +1,25 @@ +require 'test/unit' +require 'testcase' +require 'fox16' + +include Fox + +class TC_FXMessageBox < TestCase + def setup + super(self.class.name) + end + + def test_construct_with_save_cancel_dontsave + assert_nothing_raised(RangeError) do + FXMessageBox.new(mainWindow, "Save?", "Save?", :opts => MBOX_SAVE_CANCEL_DONTSAVE) + end + end + + def test_mbox_clicked_dontsave_defined + assert(Fox.const_defined?(:MBOX_CLICKED_DONTSAVE)) + end + + def test_mbox_clicked_dontsave_equal_to_mbox_clicked_no + assert_equal(MBOX_CLICKED_NO, MBOX_CLICKED_DONTSAVE) + end +end diff --git a/tests/TC_FXQuatf.rb b/tests/TC_FXQuatf.rb index c9b99e0800e9960bc017af1d766e7044c57412d7..d2a5b62c4790bf40eac6c7bd176c70b4810c7693 100755 --- a/tests/TC_FXQuatf.rb +++ b/tests/TC_FXQuatf.rb @@ -7,67 +7,83 @@ class TC_FXQuatf < Test::Unit::TestCase def setup @quat = FXQuatf.new end + def test_default_constructor q = FXQuatf.new end + def test_construct_from_axis_and_angle axis = FXVec3f.new(1.0, 1.0, 1.0) q = FXQuatf.new(axis) q = FXQuatf.new(axis, 0.0) end + def test_construct_from_components x, y, z, w = 1.0, 1.0, 1.0, 1.0 q = FXQuatf.new(x, y, z, w) end + def test_construct_from_roll_pitch_yaw roll, pitch, yaw = 45.0, 45.0, 45.0 q = FXQuatf.new(roll, pitch, yaw) end + def test_adjust! adjusted = @quat.adjust! assert_same(@quat, adjusted) end - def test_setAxisAngle - end - def test_getAxisAngle - end + def test_setRollPitchYaw roll, pitch, yaw = 0.0, 0.0, 0.0 @quat.setRollPitchYaw(roll, pitch, yaw) end + def test_getRollPitchYaw rpy = @quat.getRollPitchYaw() assert_instance_of(Array, rpy) assert_equal(3, rpy.length) end + def test_exp expQuat = @quat.exp assert_instance_of(FXQuatf, expQuat) end + def test_log logQuat = @quat.log assert_instance_of(FXQuatf, logQuat) end + def test_invert invertQuat = @quat.invert assert_instance_of(FXQuatf, invertQuat) end + def test_conj conjQuat = @quat.conj assert_instance_of(FXQuatf, conjQuat) end - def test_mul - anotherQuat = FXQuatf.new - product = @quat*anotherQuat + + def test_multiplication_result_is_another_quat + q1 = FXQuatf.new(1, 2, 3, 4) + q2 = FXQuatf.new(1, 2, 3, 4) + product = q1*q2 assert_instance_of(FXQuatf, product) - assert_equal(product, anotherQuat*@quat) end + + def test_multiplication_is_commutative + q1 = FXQuatf.new(1, 2, 3, 4) + q2 = FXQuatf.new(1, 2, 3, 4) + assert_equal(q1*q2, q2*q1) + end + def test_arc a = FXVec3f.new(0.0, 0.0, 0.0) b = FXVec3f.new(0.0, 0.0, 0.0) q = FXQuatf.arc(a, b) assert_instance_of(FXQuatf, q) end + def test_lerp u = FXQuatf.new v = FXQuatf.new diff --git a/tests/TC_FXRanged.rb b/tests/TC_FXRanged.rb new file mode 100755 index 0000000000000000000000000000000000000000..1cf193cca9c72b37c8e0884543188a59c4450bcc --- /dev/null +++ b/tests/TC_FXRanged.rb @@ -0,0 +1,42 @@ +require 'test/unit' + +require 'fox16' + +include Fox + +class TC_FXRanged < Test::Unit::TestCase + + WIDTH, HEIGHT, DEPTH = 2, 4, 6 + + def setup + @range = FXRanged.new(0, WIDTH, 0, HEIGHT, 0, DEPTH) + end + + def test_lower_is_a_vector + assert_instance_of(FXVec3d, @range.lower) + end + + def test_upper_is_a_vector + assert_instance_of(FXVec3d, @range.upper) + end + + def test_width + assert_equal(@range.width, WIDTH) + end + + def test_height + assert_equal(@range.height, HEIGHT) + end + + def test_depth + assert_equal(@range.depth, DEPTH) + end + + def test_longest + assert_equal([@range.width, @range.height, @range.depth].max, @range.longest) + end + + def test_shortest + assert_equal([@range.width, @range.height, @range.depth].min, @range.shortest) + end +end diff --git a/tests/TC_FXRangef.rb b/tests/TC_FXRangef.rb index 307f9dfabd800e3c71515ae908687f4d4048d5e5..f302d95408d091545422de35fd29e25a1a1881c2 100755 --- a/tests/TC_FXRangef.rb +++ b/tests/TC_FXRangef.rb @@ -12,37 +12,31 @@ class TC_FXRangef < Test::Unit::TestCase @range = FXRangef.new(0, WIDTH, 0, HEIGHT, 0, DEPTH) end + def test_lower_is_a_vector + assert_instance_of(FXVec3f, @range.lower) + end + + def test_upper_is_a_vector + assert_instance_of(FXVec3f, @range.upper) + end + def test_width assert_equal(@range.width, WIDTH) end + def test_height assert_equal(@range.height, HEIGHT) end + def test_depth assert_equal(@range.depth, DEPTH) end + def test_longest assert_equal([@range.width, @range.height, @range.depth].max, @range.longest) end + def test_shortest assert_equal([@range.width, @range.height, @range.depth].min, @range.shortest) end - def test_empty? - end - def test_overlaps? - end - def test_contains? - end - def test_include - end - def test_clipTo - end - def test_corners - end - def test_intersects? - end - def test_center - end - def test_diagonal - end end diff --git a/tests/TC_FXTable.rb b/tests/TC_FXTable.rb index 067d7225a9db75693c14b71da2d174c926f60632..8cfb16938a3ae6dfb8b62fc91e130f25931e10e0 100755 --- a/tests/TC_FXTable.rb +++ b/tests/TC_FXTable.rb @@ -365,4 +365,197 @@ public assert_equal("(1, 0)", @table.getItemText(1, 0)) assert_equal("(1, 1)", @table.getItemText(1, 1)) end + + def test_set_column_icon_negative_index_raises_index_error + assert_raises(IndexError) { + @table.setColumnIcon(-1, nil) + } + end + + def test_set_column_icon_large_index_raises_index_error + assert_raises(IndexError) { + @table.setColumnIcon(@table.numColumns, nil) + } + end + + def test_get_column_icon_negative_index_raises_index_error + assert_raises(IndexError) { + @table.getColumnIcon(-1) + } + end + + def test_get_column_icon_large_index_raises_index_error + assert_raises(IndexError) { + @table.getColumnIcon(@table.numColumns) + } + end + + def test_set_column_icon_position_negative_index_raises_index_error + assert_raises(IndexError) { + @table.setColumnIconPosition(-1, 0) + } + end + + def test_set_column_icon_position_large_index_raises_index_error + assert_raises(IndexError) { + @table.setColumnIconPosition(@table.numColumns, 0) + } + end + + def test_get_column_icon_position_negative_index_raises_index_error + assert_raises(IndexError) { + @table.getColumnIconPosition(-1) + } + end + + def test_get_column_icon_position_large_index_raises_index_error + assert_raises(IndexError) { + @table.getColumnIconPosition(@table.numColumns) + } + end + + def test_set_column_justify_negative_index_raises_index_error + assert_raises(IndexError) { + @table.setColumnJustify(-1, 0) + } + end + + def test_set_column_justify_large_index_raises_index_error + assert_raises(IndexError) { + @table.setColumnJustify(@table.numColumns, 0) + } + end + + def test_get_column_justify_negative_index_raises_index_error + assert_raises(IndexError) { + @table.getColumnJustify(-1) + } + end + + def test_get_column_justify_large_index_raises_index_error + assert_raises(IndexError) { + @table.getColumnJustify(@table.numColumns) + } + end + + def test_set_column_text_negative_index_raises_index_error + assert_raises(IndexError) { + @table.setColumnText(-1, "") + } + end + + def test_set_column_text_large_index_raises_index_error + assert_raises(IndexError) { + @table.setColumnText(@table.numColumns, "") + } + end + + def test_get_column_text_negative_index_raises_index_error + assert_raises(IndexError) { + @table.getColumnText(-1) + } + end + + def test_get_column_text_large_index_raises_index_error + assert_raises(IndexError) { + @table.getColumnText(@table.numColumns) + } + end + + def test_set_row_icon_negative_index_raises_index_error + assert_raises(IndexError) { + @table.setRowIcon(-1, nil) + } + end + + def test_set_row_icon_large_index_raises_index_error + assert_raises(IndexError) { + @table.setRowIcon(@table.numRows, nil) + } + end + + def test_get_row_icon_negative_index_raises_index_error + assert_raises(IndexError) { + @table.getRowIcon(-1) + } + end + + def test_get_row_icon_large_index_raises_index_error + assert_raises(IndexError) { + @table.getRowIcon(@table.numRows) + } + end + + def test_set_row_icon_position_negative_index_raises_index_error + assert_raises(IndexError) { + @table.setRowIconPosition(-1, 0) + } + end + + def test_set_row_icon_position_large_index_raises_index_error + assert_raises(IndexError) { + @table.setRowIconPosition(@table.numRows, 0) + } + end + + def test_get_row_icon_position_negative_index_raises_index_error + assert_raises(IndexError) { + @table.getRowIconPosition(-1) + } + end + + def test_get_row_icon_position_large_index_raises_index_error + assert_raises(IndexError) { + @table.getRowIconPosition(@table.numRows) + } + end + + def test_set_row_justify_negative_index_raises_index_error + assert_raises(IndexError) { + @table.setRowJustify(-1, 0) + } + end + + def test_set_row_justify_large_index_raises_index_error + assert_raises(IndexError) { + @table.setRowJustify(@table.numRows, 0) + } + end + + def test_get_row_justify_negative_index_raises_index_error + assert_raises(IndexError) { + @table.getRowJustify(-1) + } + end + + def test_get_row_justify_large_index_raises_index_error + assert_raises(IndexError) { + @table.getRowJustify(@table.numRows) + } + end + + def test_set_row_text_negative_index_raises_index_error + assert_raises(IndexError) { + @table.setRowText(-1, "") + } + end + + def test_set_row_text_large_index_raises_index_error + assert_raises(IndexError) { + @table.setRowText(@table.numRows, "") + } + end + + def test_get_row_text_negative_index_raises_index_error + assert_raises(IndexError) { + @table.getRowText(-1) + } + end + + def test_get_row_text_large_index_raises_index_error + assert_raises(IndexError) { + @table.getRowText(@table.numRows) + } + end + end diff --git a/tests/TC_FXText.rb b/tests/TC_FXText.rb index 4edb6df398cac2ffe4d1445cef6d0382cbe56196..bd38766f20adb847891521bb2dcc8810ebee7121 100755 --- a/tests/TC_FXText.rb +++ b/tests/TC_FXText.rb @@ -72,10 +72,25 @@ public assert_equal(SAMPLE, @text.text) end - def test_findText + def test_find_text @text.text = "99 bottles of beer" startIndex, endIndex = @text.findText("bottles") assert_equal([3], startIndex) assert_equal([10], endIndex) end + + def test_find_text_with_startpos + @text.text = "I came, I saw, I conquered" + startIndex, endIndex = @text.findText("I ", 5) + assert_equal([8], startIndex) + assert_equal([10], endIndex) + end + + def test_find_text_with_groups + @text.text = "I came, I saw, I conquered" + startIndex, endIndex = @text.findText("I ([a-z]+)(, )?", 0, SEARCH_REGEX) + assert_equal([0, 2, 6], startIndex) + assert_equal([8, 6, 8], endIndex) + end + end diff --git a/tests/TC_FXTreeList.rb b/tests/TC_FXTreeList.rb index 6a959f413bf1b250ab10f43b77d66f6669e3b067..ef5543cd8e1c081a4e994897ac9b4311e94ddbca 100755 --- a/tests/TC_FXTreeList.rb +++ b/tests/TC_FXTreeList.rb @@ -14,27 +14,27 @@ class TC_FXTreeList < TestCase def test_firstItem assert_nil(@treeList.firstItem) - item = @treeList.addItemFirst(nil, "first") + item = @treeList.prependItem(nil, "first") assert_same(item, @treeList.firstItem) end def test_lastItem assert_nil(@treeList.lastItem) - item = @treeList.addItemFirst(nil, "first") + item = @treeList.prependItem(nil, "first") assert_same(item, @treeList.lastItem) end def test_reparentItem - rootItem = @treeList.addItemFirst(nil, "Root Item") - childItem = @treeList.addItemFirst(@treeList.firstItem, "Child Item") + rootItem = @treeList.prependItem(nil, "Root Item") + childItem = @treeList.prependItem(@treeList.firstItem, "Child Item") @treeList.reparentItem(childItem, nil) assert_same(rootItem, @treeList.firstItem) assert_same(childItem, @treeList.lastItem) end def test_moveItemBefore - first = @treeList.addItemLast(nil, "first") - second = @treeList.addItemLast(nil, "second") + first = @treeList.appendItem(nil, "first") + second = @treeList.appendItem(nil, "second") assert_same(second, first.next) assert_same(first, second.prev) assert_same(second, @treeList.moveItemBefore(first, second)) @@ -43,8 +43,8 @@ class TC_FXTreeList < TestCase end def test_moveItemAfter - first = @treeList.addItemLast(nil, "first") - second = @treeList.addItemLast(nil, "second") + first = @treeList.appendItem(nil, "first") + second = @treeList.appendItem(nil, "second") assert_same(second, first.next) assert_same(first, second.prev) assert_same(first, @treeList.moveItemAfter(second, first)) @@ -53,9 +53,9 @@ class TC_FXTreeList < TestCase end def test_sortRootItems - @treeList.addItemLast(nil, "B") - @treeList.addItemLast(nil, "A") - @treeList.addItemLast(nil, "C") + @treeList.appendItem(nil, "B") + @treeList.appendItem(nil, "A") + @treeList.appendItem(nil, "C") @treeList.sortRootItems assert_equal("A", @treeList.firstItem.text) assert_equal("B", @treeList.firstItem.next.text) @@ -67,12 +67,12 @@ class TC_FXTreeList < TestCase @treeList.connect(SEL_INSERTED) { |sender, sel, ptr| anItem = ptr } - theItem = @treeList.addItemLast(nil, "", nil, nil, nil, true) + theItem = @treeList.appendItem(nil, "", nil, nil, nil, true) assert_same(theItem, anItem) end def test_SEL_DELETED - theItem = @treeList.addItemLast(nil, "") + theItem = @treeList.appendItem(nil, "") anItem = nil @treeList.connect(SEL_DELETED) { |sender, sel, ptr| anItem = ptr @@ -80,4 +80,21 @@ class TC_FXTreeList < TestCase @treeList.removeItem(theItem, true) assert_same(theItem, anItem) end + + def test_each_for_empty_list + count = 0 + @treeList.each { |item| count += 1 } + assert_equal(0, count, "count for empty list should be zero") + end + + def test_each + @treeList.appendItem(nil, "1") + @treeList.appendItem(nil, "2") + @treeList.appendItem(nil, "3") + @treeList.appendItem(nil, "4") + count = 0 + @treeList.each { |item| count += 1 } + assert_equal(4, count, "count didn't match expected number of items") + end + end diff --git a/tests/TC_FXTreeListBox.rb b/tests/TC_FXTreeListBox.rb index 9c921802cdfa3d94a9219635b3053d5c5a368344..b54dbaf31562d46a7b0f52a07fcf151da67b8215 100755 --- a/tests/TC_FXTreeListBox.rb +++ b/tests/TC_FXTreeListBox.rb @@ -5,19 +5,37 @@ require 'fox16' include Fox class TC_FXTreeListBox < TestCase + def setup super(self.class.name) @treeListBox = FXTreeListBox.new(mainWindow) end def test_sortRootItems - @treeListBox.addItemLast(nil, "B") - @treeListBox.addItemLast(nil, "A") - @treeListBox.addItemLast(nil, "C") + @treeListBox.appendItem(nil, "B") + @treeListBox.appendItem(nil, "A") + @treeListBox.appendItem(nil, "C") @treeListBox.sortRootItems assert_equal("A", @treeListBox.firstItem.text) assert_equal("B", @treeListBox.firstItem.next.text) assert_equal("C", @treeListBox.lastItem.text) end + + def test_each_for_empty_list + count = 0 + @treeListBox.each { |item| count += 1 } + assert_equal(0, count, "count for empty list should be zero") + end + + def test_each + @treeListBox.appendItem(nil, "1") + @treeListBox.appendItem(nil, "2") + @treeListBox.appendItem(nil, "3") + @treeListBox.appendItem(nil, "4") + count = 0 + @treeListBox.each { |item| count += 1 } + assert_equal(4, count, "count didn't match expected number of items") + end + end diff --git a/tests/stress1.rb b/tests/stress1.rb index 4c1a71d76043c8db2d71d8ab6034e902d5901d91..405ac2e726e03189ce20dcbf9ecb109f317f6a69 100755 --- a/tests/stress1.rb +++ b/tests/stress1.rb @@ -14,13 +14,13 @@ RESTART_FREQUENCY = 20 # Tree # ======================================================================= class DirTree < FXTreeList - def initialize(parent, nvis, tgt = nil, sel = 0, opts = 0, x = 0, y = 0, w = 0, h = 0) - super + def initialize(p) + super(p, :opts => TREELIST_SHOWS_LINES|TREELIST_SHOWS_BOXES|TREELIST_ROOT_BOXES|LAYOUT_FILL_X|LAYOUT_FILL_Y) end def create super - item = addItemLast(nil, "root") + item = appendItem(nil, "root") @currentItem = item expand end @@ -34,7 +34,7 @@ class DirTree < FXTreeList def listSubDir(parentItem) entries = (1..NUMBER_OF_ITEMS).collect { |i| i.to_s } entries.each do |entry| - item = addItemLast(parentItem, entry) + item = appendItem(parentItem, entry) @currentItem = item if entry == "1" end end @@ -57,9 +57,7 @@ class Application < FXApp init(ARGV) @mainWindow = FXMainWindow.new(self, appName, nil, nil, DECOR_ALL, 0, 0, 400, 600) - @dirTree = DirTree.new(@mainWindow, 0, nil, 0, - (TREELIST_SHOWS_LINES|TREELIST_SHOWS_BOXES|TREELIST_ROOT_BOXES| - LAYOUT_FILL_X|LAYOUT_FILL_Y)) + @dirTree = DirTree.new(@mainWindow) @count = 0 end diff --git a/tests/testcase.rb b/tests/testcase.rb index 8d95f8cf0b4a674132640660f3d08b1009f5d0bb..3220e251cc058999ec0b14452a9c4798e1505a75 100755 --- a/tests/testcase.rb +++ b/tests/testcase.rb @@ -10,13 +10,13 @@ module Fox def setup(*args) unless args.empty? appName = args[0] - if FXApp.instance.nil? - @theApp = FXApp.new(appName, 'FXRuby') - @theApp.init([]) - else - @theApp = FXApp.instance - end - @theMainWindow = FXMainWindow.new(@theApp, appName) + if FXApp.instance.nil? + @theApp = FXApp.new(appName, 'FXRuby') + @theApp.init([]) + else + @theApp = FXApp.instance + end + @theMainWindow = FXMainWindow.new(@theApp, appName) end end diff --git a/web/community.html b/web/community.html new file mode 100644 index 0000000000000000000000000000000000000000..04e6abba28b5944f940846e43b372fb39a5d2399 --- /dev/null +++ b/web/community.html @@ -0,0 +1,94 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> + <link rel="stylesheet" href="css/style.css" type="text/css" /> + <link rel="meta" title="DOAP" type="application/rdf+xml" href="http://www.fxruby.org/doap.rdf" /> + <title>Community</title> +</head> + +<body> +<!-- wrap starts here --> +<div id="wrap"> + + <!--header --> + <div id="header"> + + <h1 id="logo-text"><a href="index.html">FXRuby</a></h1> + <p id="slogan">Graphical User Interface Development for Ruby</p> + + </div> + + <!-- menu --> + <div id="menu"> + <ul> + <li ><a href=/ >Home</a></li> + <li id='current'><a href=# >Community</a></li> + <li ><a href=/downloads.html >Downloads</a></li> + <li ><a href=/documentation.html >Documentation</a></li> + </ul> + </div> + + <!-- content-wrap starts here --> + <div id="content-wrap"> + + <div id="sidebar"> + + <h3>Get the Book!</h3> + <a href="http://www.pragprog.com/titles/fxruby"><img src="images/fxruby-book.jpg" alt="FXRuby: Create Lean and Mean GUIs with Ruby" width="175" height="210" /></a> + + <h3>Links</h3> + <ul class="sidemenu"> + <li><a href="http://rubyforge.org/news/?group_id=300">News</a></li> + <li><a href="http://www.fxruby.org/doc/book.html">User's Guide</a></li> + <li><a href="http://www.fxruby.org/doc/api">API Docs</a></li> + <li><a href="http://www.fxruby.org/doc/examples.html">Screenshots</a></li> + <li><a href="http://rubyforge.org/tracker/?atid=1223&group_id=300&func=browse">Report Bugs</a></li> + <li><a href="http://www.gnu.org/copyleft/lesser.html">License</a></li> + </ul> + + </div> + + <div id="main"> + + <h1>Mailing Lists</h1> + + + <h2>Announcements</h2> + + + <p>The announcements list is a low-traffic list on which new releases of FXRuby, as well as software based on FXRuby, will be +announced. Discussions on various topics however should preferably take place in the users list, to prevent swamping people’s +mailboxes. To subscribe, fill out the <a href="http://rubyforge.org/mailman/listinfo/fxruby-announce" title="Announcements List Subscription +Form">web-based subscription form</a>.</p> + + + <h2>General Discussion</h2> + + + <p>The users list is intended for discussion on various FOX and FXRuby topics between developers and/or users of FXRuby and +applications based on it. If you have questions, feel free to post your questions here, as many people are only too happy to +answer them. To subscribe, fill out the <a href="http://rubyforge.org/mailman/listinfo/fxruby-users" title="General Discussion List Subscription +Form">web-based subscription form</a>.</p> + + </div> + + <!-- content-wrap ends here --> + </div> + + <!--footer starts here--> + <div id="footer"> + + <p> + © 2008 Lyle Johnson<br /> + Web Site Generated Using <a href="http://webby.rubyforge.org/" title="Webby">Webby</a> + </p> + + </div> + +<!-- wrap ends here --> +</div> + +</body> +</html> diff --git a/web/css/style.css b/web/css/style.css new file mode 100644 index 0000000000000000000000000000000000000000..36c1a1b1a58c8d053524037a3a530abac5ffa603 --- /dev/null +++ b/web/css/style.css @@ -0,0 +1,407 @@ +/******************************************** + AUTHOR: Erwin Aligam + WEBSITE: http://www.styleshout.com/ + TEMPLATE NAME: Envision + TEMPLATE CODE: S-0013 + VERSION: 1.1 + LAST MODIFIED Nov-14-2007 + *******************************************/ + +/******************************************** + HTML ELEMENTS +********************************************/ + +/* Top Elements */ +* { margin: 0; padding: 0; outline: 0 } + +body { + background: #CCC; + font: 80%/1.5em Verdana, Tahoma, arial, sans-serif; + color: #555; + text-align: center; +} + +/* links */ +a, a:visited { + text-decoration: none; + color: #2180BC; + background: inherit; +} +a:hover { + color: #88ac0b; + background: inherit; + text-decoration: underline; +} + +/* headers */ +h1, h2, h3 { + font-family: 'Trebuchet MS', Tahoma, Sans-serif; +} +h1 { + font-size: 150%; + font-weight: normal; + color: #006699; +} +h2 { + font-size: 140%; + text-transform: uppercase; + color: #88ac0b; +} +h3 { + font-size: 120%; + color: #666666; +} + +/* images */ +img { + background: #FAFAFA; + border: 1px solid #E5E5E5; + padding: 5px; +} +img.float-right { + margin: 5px 0px 10px 10px; +} +img.float-left { + margin: 5px 10px 10px 0px; +} + +h1, h2, h3, p { + padding: 10px; + margin: 0; +} +ul, ol { + margin: 5px 20px; + padding: 0 20px; +} + +code { + margin: 5px 0; + padding: 10px; + text-align: left; + display: block; + overflow: auto; + font: 500 1em/1.5em 'Lucida Console', 'courier new', monospace ; + /* white-space: pre; */ + background: #FAFAFA; + border: 1px solid #f2f2f2; +} +acronym { + cursor: help; + border-bottom: 1px dotted #777; +} +blockquote { + margin: 10px; + padding: 0 0 0 28px; + border: 1px solid #f2f2f2; + background: #FAFAFA url(../images/quote.gif) no-repeat 5px 5px; +} + +/* start - table */ +table { + border-collapse: collapse; + margin: 10px; +} +th strong { + color: #fff; +} +th { + background: #93BC0C; + height: 29px; + padding-left: 12px; + padding-right: 12px; + color: #FFF; + text-align: left; + border-left: 1px solid #B6D59A; + border-bottom: solid 2px #FFF; +} +tr { + height: 30px; +} +td { + padding-left: 11px; + padding-right: 11px; + border-left: 1px solid #FFF; + border-bottom: solid 1px #ffffff; +} +td.first,th.first { + border-left: 0px; +} +tr.row-a { + background: #F8F8F8; +} +tr.row-b { + background: #EFEFEF; +} +/* end - table */ + +/* form elements */ +form { + margin:10px; padding: 0 5px; + border: 1px solid #f2f2f2; + background-color: #FAFAFA; +} +label { + display:block; + font-weight:bold; + margin:5px 0; +} +input { + padding:2px; + border:1px solid #eee; + font: normal 1em Verdana, sans-serif; + color:#777; +} +textarea { + width:400px; + padding:2px; + font: normal 1em Verdana, sans-serif; + border:1px solid #eee; + height:100px; + display:block; + color:#777; +} +input.button { + font: bold 12px Arial, Sans-serif; + height: 24px; + margin: 0; + padding: 2px 3px; + color: #FFF; + background: #8EB50C url(../images/button-bg.jpg) repeat-x 0 0; + border: none; +} + +/* search form */ +.searchform { + background-color: transparent; + border: none; + margin: 0; padding: 5px 0 15px 0; + width: 190px; +} +.searchform p { margin: 0; padding: 0; } +.searchform input.textbox { + width: 120px; + color: #777; + height: 18px; + padding: 2px; + border: 1px solid #E5E5E5; + vertical-align: top; +} +.searchform input.button { + width: 60px; + height: 24px; + padding: 2px 5px; + vertical-align: top; +} + +/******************************************** + LAYOUT +********************************************/ +#wrap { + width: 820px; + background: #CCC url(../images/content.jpg) repeat-y center top; + margin: 0 auto; + text-align: left; +} +#content-wrap { + clear: both; + width: 760px; + padding: 0; + margin: 10px auto; +} +#header { + width: 820px; + position: relative; + height: 103px; + background: #CCC url(../images/header.png) no-repeat center top; + padding: 0; + color: #FFF; +} +#header h1#logo-text a { + position: absolute; + margin: 0; padding: 0; + font: bolder 44px 'Trebuchet MS', Arial, Sans-serif; + letter-spacing: -2px; + color: #FFF; + text-transform: none; + text-decoration: none; + background: transparent; + + /* change the values of top and left to adjust the position of the logo*/ + top: 20px; left: 110px; +} +#header p#slogan { + position: absolute; + margin: 0; padding: 0; + font: normal 12px 'Trebuchet MS', Arial, Sans-serif; + text-transform: none; + color: #FFF; + + /* change the values of top and left to adjust the position of the slogan*/ + top: 70px; left: 110px; +} + +/* header links */ +#header #header-links { + position: absolute; + top: 20px; right: 30px; + color: #C6DDEE; + font-size: 10px; +} +#header #header-links a { + color: #FFF; + text-decoration: none; +} +#header #header-links a:hover { + color: #D4E59F; +} + +/* Menu */ +#menu { + clear: both; + margin: 0 auto; padding: 0; + background: url(../images/menu.jpg) repeat-x 0 0; + font: bold 12px/37px Verdana, Arial, Tahoma, Sans-serif; + height: 37px; + width: 780px; +} +#menu ul { + float: right; + list-style: none; + margin:0; padding: 0; +} +#menu ul li { + display: inline; +} +#menu ul li a { + display: block; + float: left; + padding: 0 12px; + color: #FFF; + text-decoration: none; +} +#menu ul li.last a { + padding-right: 20px; +} +#menu ul li a:hover { + color: #D4E59F; +} +#menu ul li#current a { + color: #D4E59F; +} + +/* Main Column */ +#main { + float: left; + width: 70%; + padding: 0; margin: 5px 0 0 5px; + display: inline; +} +#main h2 { + margin-top: 10px; + font: Bold 140% 'Trebuchet MS', Tahoma, Sans-serif; + color: #88ac0b; + padding: 5px 0 5px 25px; + border-bottom: 1px solid #EFF0F1; + background: #FFF url(../images/square-green.png) no-repeat 3px 50%; + text-transform: none; +} +#main h2 a { + background: none; + color: #88ac0b; + text-decoration: none; +} + +#main ul li { + list-style-image: url(../images/bullet.gif); +} + +.post-footer { + background-color: #FAFAFA; + padding: 5px; margin: 20px 10px 10px 10px; + border: 1px solid #f2f2f2; + font-size: 95%; +} +.post-footer .date { + background: url(../images/clock.gif) no-repeat left center; + padding-left: 20px; margin: 0 10px 0 5px; +} +.post-footer .comments { + background: url(../images/comment.gif) no-repeat left center; + padding-left: 20px; margin: 0 10px 0 5px; +} +.post-footer .readmore { + background: url(../images/page.gif) no-repeat left center; + padding-left: 20px; margin: 0 10px 0 5px; +} + +/* Sidebar */ +#sidebar { + float: right; + width: 26.5%; + padding: 0; margin: 0; + color: #68774A; +} +#sidebar img { + text-align: center; +} +#sidebar h3 { + margin-top: 10px; + /* padding: 5px 5px; */ + text-align: center; + font: bold 1.4em 'Trebuchet MS', Tahoma, Sans-serif; + color: #728D26; +} +#sidebar ul.sidemenu { + list-style: none; + text-align: left; + margin: 7px 4px 8px 0; padding: 0; + text-decoration: none; + background: url(../images/dots.jpg) repeat-x left top; +} +#sidebar ul.sidemenu li { + list-style: none; + background: url(../images/dots.jpg) repeat-x left bottom; + padding: 4px 0 4px 5px; + margin: 0 2px; + color: #68774A; +} +* html body #sidebar ul.sidemenu li { + height: 1%; +} +#sidebar ul.sidemenu li a { + text-decoration: none; + background-image: none; + color: #666666; +} +#sidebar ul.sidemenu li a:hover { + color: #1773BC; +} +#sidebar ul.sidemenu ul { margin: 0 0 0 5px; padding: 0; } +#sidebar ul.sidemenu ul li { background: none; } + + +/* Footer */ +#footer { + color: #C6DDEE; + background: #CCC url(../images/footer.jpg) no-repeat center top; + clear: both; + width: 820px; + height: 65px; + text-align: center; + font-size: 92%; +} +#footer a { + color: #FFF; + text-decoration: none; +} + +/* alignment classes */ +.float-left { float: left; } +.float-right { float: right; } +.align-left { text-align: left; } +.align-right { text-align: right; } + +/* display and additional classes */ +.clear { clear: both; } + + diff --git a/web/documentation.html b/web/documentation.html new file mode 100644 index 0000000000000000000000000000000000000000..9f570fdc33f8c93fe75aee1b5feea9d9547f6686 --- /dev/null +++ b/web/documentation.html @@ -0,0 +1,100 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> + <link rel="stylesheet" href="css/style.css" type="text/css" /> + <link rel="meta" title="DOAP" type="application/rdf+xml" href="http://www.fxruby.org/doap.rdf" /> + <title>Documentation</title> +</head> + +<body> +<!-- wrap starts here --> +<div id="wrap"> + + <!--header --> + <div id="header"> + + <h1 id="logo-text"><a href="index.html">FXRuby</a></h1> + <p id="slogan">Graphical User Interface Development for Ruby</p> + + </div> + + <!-- menu --> + <div id="menu"> + <ul> + <li ><a href=/ >Home</a></li> + <li ><a href=/community.html >Community</a></li> + <li ><a href=/downloads.html >Downloads</a></li> + <li id='current'><a href=# >Documentation</a></li> + </ul> + </div> + + <!-- content-wrap starts here --> + <div id="content-wrap"> + + <div id="sidebar"> + + <h3>Get the Book!</h3> + <a href="http://www.pragprog.com/titles/fxruby"><img src="images/fxruby-book.jpg" alt="FXRuby: Create Lean and Mean GUIs with Ruby" width="175" height="210" /></a> + + <h3>Links</h3> + <ul class="sidemenu"> + <li><a href="http://rubyforge.org/news/?group_id=300">News</a></li> + <li><a href="http://www.fxruby.org/doc/book.html">User's Guide</a></li> + <li><a href="http://www.fxruby.org/doc/api">API Docs</a></li> + <li><a href="http://www.fxruby.org/doc/examples.html">Screenshots</a></li> + <li><a href="http://rubyforge.org/tracker/?atid=1223&group_id=300&func=browse">Report Bugs</a></li> + <li><a href="http://www.gnu.org/copyleft/lesser.html">License</a></li> + </ul> + + </div> + + <div id="main"> + + <h1>Books</h1> + + + <p>The book <cite>FXRuby: Create Lean and Mean GUIs with Ruby</cite> (available from the <a href="http://www.pragmaticprogrammer.com/titles/fxruby/">Pragmatic +Programmers</a> and other booksellers) is the best print source of documentation +for FXRuby. It’s also available as a PDF.</p> + + + <p>Several other books, including <cite>Ruby Developer’s Guide</cite> and <cite>The Ruby Way</cite>, include chapters or sections +on GUI development with FXRuby.</p> + + + <h1>Online</h1> + + + <p>The <a href="http://www.fxruby.org/doc/book.html">FXRuby User’s Guide</a> provides detailed installation instructions as well +as a handful of tutorial exercises to get you started with FXRuby development.</p> + + + <p>If you’re looking for API reference documentation, all of the classes and methods for FXRuby are documented +<a href="http://www.fxruby.org/doc/api/">here</a>.</p> + + + <p>Other good sources of documentation include the <a href="http://www.fox-toolkit.org/">FOX home page</a> and the <a href="http://www.fox-toolkit.net/">FOX Community +Wiki</a> site.</p> + + </div> + + <!-- content-wrap ends here --> + </div> + + <!--footer starts here--> + <div id="footer"> + + <p> + © 2008 Lyle Johnson<br /> + Web Site Generated Using <a href="http://webby.rubyforge.org/" title="Webby">Webby</a> + </p> + + </div> + +<!-- wrap ends here --> +</div> + +</body> +</html> diff --git a/web/downloads.html b/web/downloads.html old mode 100755 new mode 100644 index 688eac69dd8bbc24511da8e218244406ba1ab54d..80610f52f04d5bf410127598870843084e085b97 --- a/web/downloads.html +++ b/web/downloads.html @@ -1,93 +1,114 @@ -<html> -<head> -<link rel="stylesheet" href="page.css" type="text/css"> -<title>Downloads</title> -</head> -<body bgcolor=#ffffff link=#990033 vlink=#990033 alink=#990033 text=#000000> - - -<!--- TOPIC TITLE --> -<p> -<table width=100% cellpadding=0 cellspacing=2><tr><td width=100% valign=bottom id="HEADLINE"><b> -Downloads -<br><img src='art/line.gif' width='100%' height=1></b></td></tr></table> -</p> -<!--- TOPIC TITLE --> -<blockquote> -The latest version of FXRuby is always available -from the <a href="http://rubyforge.org/projects/fxruby" target=_top>RubyForge -project page</a>. The RubyForge releases should always have accompanying -release notes describing the changes for that release. A cumulative -<tt>ChangeLog</tt> file is also included in the FXRuby source code distribution. - -As of the FOX 1.0 release, any FXRuby version 1.0.x release should be compatible with any FOX 1.0.x release. -Similarly, any FXRuby 1.2.x release should be compatible with any FOX 1.2.x release, and -any FXRuby 1.4.x release should be compatible with any FOX 1.4.x release.<p> -</blockquote> - -<!--- TOPIC TITLE --> -<p> -<table width=100% cellpadding=0 cellspacing=2><tr><td width=100% valign=bottom id="HEADLINE"><b> -Source Code -<br><img src='art/line.gif' width='100%' height=1></b></td></tr></table> -</p> -<!--- TOPIC TITLE --> -<blockquote> -The FXRuby source code is distributed as a gzipped tar archive, and is available for -download from the <a href="http://rubyforge.org/projects/fxruby" target=_top>RubyForge -project page</a>. -</blockquote> - -<!--- TOPIC TITLE --> -<p> -<table width=100% cellpadding=0 cellspacing=2><tr><td width=100% valign=bottom id="HEADLINE"><b> -Binaries for Unix/Linux -<br><img src='art/line.gif' width='100%' height=1></b></td></tr></table> -</p> -<!--- TOPIC TITLE --> -<blockquote> -Precompiled binaries for FOX, FXScintilla and FXRuby are available for various Unix/Linux platforms, -but not in any centralized way.<p> -Both the <a href="http://www.fox-toolkit.net">FOX -Community Wiki site</a> and the <a href="http://www.fox-toolkit.com">main FOX web site</a> -list a number of independent sources for package downloads for various Linux distributions, but -many of these are for older FOX releases. You may have better luck using a RPM search engine like -<a href="http://rpmfind.net">rpmfind.net</a> to find the most recent packages for your distribution. -</blockquote> - -<!--- TOPIC TITLE --> -<p> -<table width=100% cellpadding=0 cellspacing=2><tr><td width=100% valign=bottom id="HEADLINE"><b> -Binaries for Microsoft Windows -<br><img src='art/line.gif' width='100%' height=1></b></td></tr></table> -</p> -<!--- TOPIC TITLE --> -<blockquote> -Windows installers for FXRuby are available for download from -the <a href="http://rubyforge.org/projects/fxruby" target=_top>RubyForge -project page</a>. -<b>The FOX and FXScintilla libraries are built into the Windows installers for FXRuby, and -you should not need to download and install those packages separately.</b> -These binaries are also compatible with the standard Ruby -installers for Windows that are available for download from -<a href="http://rubyforge.org/projects/rubyinstaller" target=_top>RubyForge</a>.<p> -Note that the precompiled binaries for Windows are built with OpenGL support, and -thus depend on the OpenGL runtime libraries (<tt>opengl32.dll</tt> and -<tt>glu32.dll</tt>). These libraries were <i>not</i> included with Windows 95 -(earlier than OSR2), so if you're using Ruby and FXRuby on a Windows 95 machine, -you may need to download the <a href="http://download.microsoft.com/download/win95upg/info/1/W95/EN-US/Opengl95.exe">OpenGL runtime libraries</a>. -You must have these libraries installed even if you don't plan to do anything -OpenGL-related with FXRuby. -</blockquote> - -<!--- COPYRIGHT --> -<p> -<table width=100% cellpadding=0 cellspacing=0><tr><td width=100% valign=top id=HEADLINE align=right> -<img src='art/line.gif' width=100% height=1><font size=-1> -Copyright © 2001-2004 Lyle Johnson</font> -</td></tr></table> -</p> -<!--- COPYRIGHT --> - -</body> -</html> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> + <link rel="stylesheet" href="css/style.css" type="text/css" /> + <link rel="meta" title="DOAP" type="application/rdf+xml" href="http://www.fxruby.org/doap.rdf" /> + <title>Downloads</title> +</head> + +<body> +<!-- wrap starts here --> +<div id="wrap"> + + <!--header --> + <div id="header"> + + <h1 id="logo-text"><a href="index.html">FXRuby</a></h1> + <p id="slogan">Graphical User Interface Development for Ruby</p> + + </div> + + <!-- menu --> + <div id="menu"> + <ul> + <li ><a href=/ >Home</a></li> + <li ><a href=/community.html >Community</a></li> + <li id='current'><a href=# >Downloads</a></li> + <li ><a href=/documentation.html >Documentation</a></li> + </ul> + </div> + + <!-- content-wrap starts here --> + <div id="content-wrap"> + + <div id="sidebar"> + + <h3>Get the Book!</h3> + <a href="http://www.pragprog.com/titles/fxruby"><img src="images/fxruby-book.jpg" alt="FXRuby: Create Lean and Mean GUIs with Ruby" width="175" height="210" /></a> + + <h3>Links</h3> + <ul class="sidemenu"> + <li><a href="http://rubyforge.org/news/?group_id=300">News</a></li> + <li><a href="http://www.fxruby.org/doc/book.html">User's Guide</a></li> + <li><a href="http://www.fxruby.org/doc/api">API Docs</a></li> + <li><a href="http://www.fxruby.org/doc/examples.html">Screenshots</a></li> + <li><a href="http://rubyforge.org/tracker/?atid=1223&group_id=300&func=browse">Report Bugs</a></li> + <li><a href="http://www.gnu.org/copyleft/lesser.html">License</a></li> + </ul> + + </div> + + <div id="main"> + + <p>The latest version of FXRuby is always available from the <a href="http://rubyforge.org/projects/fxruby/">RubyForge project page</a>. The +RubyForge releases should always have accompanying release notes describing the changes for that release. A cumulative ChangeLog +file is also included in the FXRuby source code distribution. Note that any FXRuby 1.6.x release should be compatible with any +FOX 1.6.x release, but won’t be compatible with earlier (or later) versions of FOX.</p> + + + <h1>Source Code</h1> + + + <p>The FXRuby source code is distributed as a gzipped tar archive, and is available for download from the <a href="http://rubyforge.org/projects/fxruby/">RubyForge project +page</a>.</p> + + + <h1>Binaries for Unix/Linux</h1> + + + <p>Precompiled binaries for FOX, FXScintilla and FXRuby are available for various Unix/Linux platforms, but not in any +centralized way.</p> + + + <p>Both the <a href="http://www.fox-toolkit.net/">FOX Community Wiki</a> site and the main <a href="http://www.fox-toolkit.org/">FOX web site</a> list a +number of independent sources for package downloads for various Linux distributions, but many of these are for older FOX +releases. You may have better luck using a RPM search engine like <a href="http://rpmfind.net/">rpmfind.net</a> to find the most recent +packages for your distribution.</p> + + + <h1>Binaries for Microsoft Windows</h1> + + + <p>Windows installers for FXRuby are available for download from the <a href="http://rubyforge.org/projects/fxruby/">RubyForge project +page</a>. The FOX and FXScintilla libraries are built into the Windows installers for FXRuby, +and you should not need to download and install those packages separately. These binaries are also compatible with the standard +Ruby installer for Windows that are available for download from RubyForge.</p> + + + <p>Note that the precompiled binaries for Windows are built with OpenGL support, and thus depend on the OpenGL runtime libraries +(opengl32.dll and glu32.dll). These libraries were not included with Windows 95 (earlier than OSR2), so if you’re using Ruby and +FXRuby on a Windows 95 machine, you may need to download the OpenGL runtime libraries. You must have these libraries installed +even if you don’t plan to do anything OpenGL-related with FXRuby.</p> + + </div> + + <!-- content-wrap ends here --> + </div> + + <!--footer starts here--> + <div id="footer"> + + <p> + © 2008 Lyle Johnson<br /> + Web Site Generated Using <a href="http://webby.rubyforge.org/" title="Webby">Webby</a> + </p> + + </div> + +<!-- wrap ends here --> +</div> + +</body> +</html> diff --git a/web/images/bullet.gif b/web/images/bullet.gif new file mode 100644 index 0000000000000000000000000000000000000000..0ba2421a9240d1b20d8a383d3f63dff3864dbf3d Binary files /dev/null and b/web/images/bullet.gif differ diff --git a/web/images/button-bg.jpg b/web/images/button-bg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1c59ae2faa7c6ccf31cb83555c44599138161ad6 Binary files /dev/null and b/web/images/button-bg.jpg differ diff --git a/web/images/comment.gif b/web/images/comment.gif new file mode 100644 index 0000000000000000000000000000000000000000..951082f93a4bb0b7401e9cabdaaea9606cadb3f2 Binary files /dev/null and b/web/images/comment.gif differ diff --git a/web/images/content.jpg b/web/images/content.jpg new file mode 100644 index 0000000000000000000000000000000000000000..23b605f8a1017c479a6f095c0d84c2753ece9e2c Binary files /dev/null and b/web/images/content.jpg differ diff --git a/web/images/dots.jpg b/web/images/dots.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e7f082d2ae29cf5f9b68abf3b6974a04ad001eec Binary files /dev/null and b/web/images/dots.jpg differ diff --git a/web/images/footer.jpg b/web/images/footer.jpg new file mode 100644 index 0000000000000000000000000000000000000000..097d99a9803609f67e65288e8d35af0248db3f19 Binary files /dev/null and b/web/images/footer.jpg differ diff --git a/web/images/fxruby-book.jpg b/web/images/fxruby-book.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f53e20707ff02cd5350c062219a78e8332838a1b Binary files /dev/null and b/web/images/fxruby-book.jpg differ diff --git a/web/images/header.png b/web/images/header.png new file mode 100644 index 0000000000000000000000000000000000000000..6f79ed3735b6ac9a50b9eff96bd880a79bdfc128 Binary files /dev/null and b/web/images/header.png differ diff --git a/web/images/menu.jpg b/web/images/menu.jpg new file mode 100644 index 0000000000000000000000000000000000000000..daaa8bb3a6129ed037d33f9e34b001bdbf232843 Binary files /dev/null and b/web/images/menu.jpg differ diff --git a/web/images/page.gif b/web/images/page.gif new file mode 100644 index 0000000000000000000000000000000000000000..0c49ba877f0cdd497b308ee97f14aea8a7ea2448 Binary files /dev/null and b/web/images/page.gif differ diff --git a/web/images/quote.gif b/web/images/quote.gif new file mode 100644 index 0000000000000000000000000000000000000000..43cbdb3fa50f973d5a45a1686545758168ebaf0b Binary files /dev/null and b/web/images/quote.gif differ diff --git a/web/images/square-green.png b/web/images/square-green.png new file mode 100644 index 0000000000000000000000000000000000000000..82f2dd357b8c5b180aa157fcf4ed611018ff8baa Binary files /dev/null and b/web/images/square-green.png differ diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000000000000000000000000000000000000..ca245b8dfa04f01b6ffd83a0daae891d1bba7043 --- /dev/null +++ b/web/index.html @@ -0,0 +1,97 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> + <meta name="verify-v1" content="oJj9+cXtpch0MSVjYgtyvC+Y57yYC6Cz9zFOd1+FXSw=" /> + <link rel="stylesheet" href="css/style.css" type="text/css" /> + <link rel="meta" title="DOAP" type="application/rdf+xml" href="http://www.fxruby.org/doap.rdf" /> + <title>FXRuby</title> +</head> + +<body> +<!-- wrap starts here --> +<div id="wrap"> + + <!--header --> + <div id="header"> + + <h1 id="logo-text"><a href="index.html">FXRuby</a></h1> + <p id="slogan">Graphical User Interface Development for Ruby</p> + + </div> + + <!-- menu --> + <div id="menu"> + <ul> + <li id='current' ><a href=# >Home</a></li> + <li ><a href=/community.html >Community</a></li> + <li ><a href=/downloads.html >Downloads</a></li> + <li ><a href=/documentation.html >Documentation</a></li> + </ul> + </div> + + <!-- content-wrap starts here --> + <div id="content-wrap"> + + <div id="sidebar"> + + <h3>Get the Book!</h3> + <a href="http://www.pragprog.com/titles/fxruby"><img src="images/fxruby-book.jpg" alt="FXRuby: Create Lean and Mean GUIs with Ruby" width="175" height="210" /></a> + + <h3>Links</h3> + <ul class="sidemenu"> + <li><a href="http://rubyforge.org/news/?group_id=300">News</a></li> + <li><a href="http://www.fxruby.org/doc/book.html">User's Guide</a></li> + <li><a href="http://www.fxruby.org/doc/api">API Docs</a></li> + <li><a href="http://www.fxruby.org/doc/examples.html">Screenshots</a></li> + <li><a href="http://rubyforge.org/tracker/?atid=1223&group_id=300&func=browse">Report Bugs</a></li> + <li><a href="http://www.gnu.org/copyleft/lesser.html">License</a></li> + </ul> + + </div> + + <div id="main"> + + <p>FXRuby is a library for developing powerful and sophisticated cross-platform graphical user interfaces (GUIs) for your Ruby +applications. It’s based on the <a href="http://www.fox-toolkit.org/" title="FOX Home Page">FOX Toolkit</a>, a popular open source +C++ library developed by Jeroen van der Zijp. What that means for you as an application developer is that you’re able to +write code in the <a href="http://www.ruby-lang.org/" title="Ruby Home Page">Ruby</a> programming language that you already know and love, +while at the same time taking advantage of the performance and functionality of a featureful, highly optimized C++ toolkit.</p> + + + <h1>Projects Using FXRuby</h1> + + + <p>Projects using FXRuby include:</p> + + + <ul> + <li><a href="http://www.insula.cz/dbtalk">DbTalk</a> is an interactive GUI-based tool for database querying, programming, administration, etc. It is developed by Dalibor Sramek.</li> + <li><a href="http://freeride.rubyforge.org/wiki/wiki.pl">FreeRIDE</a> is an IDE for the Ruby programming language.</li> + <li><a href="http://www.fisica.uniud.it/~glast/FRED">FRED</a> is a high energy physics event display built out of Ruby and FOX by Riccardo Giannitrapani and Marco Frailis.</li> + <li><a href="http://www.mondrian-ide.com/">Mondrian</a> is a cross-platform project-manager and editor for the Ruby language. Written in 100% native Ruby using the FOX GUI toolkit, Mondrian has the familiar look and feel of a modern IDE while remaining dedicated to the uniqueness of the Ruby language and its community.</li> + <li><a href="http://fox-tool.rubyforge.org/">foxGUIb</a> is an interactive gui builder and codegenerator for FXRuby. This tool makes it easy to quickly build complex and good looking graphical user interfaces for Ruby. +If your project uses FXRuby for its user interface, and you’d like to see it listed here, please send me an e-mail with the information.</li> + </ul> + + </div> + + <!-- content-wrap ends here --> + </div> + + <!--footer starts here--> + <div id="footer"> + + <p> + © 2008 Lyle Johnson<br /> + Web Site Generated Using <a href="http://webby.rubyforge.org/" title="Webby">Webby</a> + </p> + + </div> + +<!-- wrap ends here --> +</div> + +</body> +</html>