summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore (renamed from waflib/.gitignore)0
-rw-r--r--AUTHORS4
-rw-r--r--Build.py (renamed from waflib/Build.py)0
-rw-r--r--COPYING699
-rw-r--r--ConfigSet.py (renamed from waflib/ConfigSet.py)0
-rw-r--r--Configure.py (renamed from waflib/Configure.py)0
-rw-r--r--Context.py (renamed from waflib/Context.py)0
-rw-r--r--Errors.py (renamed from waflib/Errors.py)0
-rw-r--r--INSTALL59
-rw-r--r--Logs.py (renamed from waflib/Logs.py)0
-rw-r--r--NEWS58
-rw-r--r--Node.py (renamed from waflib/Node.py)0
-rw-r--r--Options.py (renamed from waflib/Options.py)0
-rw-r--r--README14
-rw-r--r--README.md (renamed from waflib/README.md)0
-rw-r--r--Runner.py (renamed from waflib/Runner.py)0
-rw-r--r--Scripting.py (renamed from waflib/Scripting.py)0
-rw-r--r--Task.py (renamed from waflib/Task.py)0
-rw-r--r--TaskGen.py (renamed from waflib/TaskGen.py)0
-rw-r--r--Tools/__init__.py (renamed from waflib/Tools/__init__.py)0
-rw-r--r--Tools/ar.py (renamed from waflib/Tools/ar.py)0
-rw-r--r--Tools/asm.py (renamed from waflib/Tools/asm.py)0
-rw-r--r--Tools/bison.py (renamed from waflib/Tools/bison.py)0
-rw-r--r--Tools/c.py (renamed from waflib/Tools/c.py)0
-rw-r--r--Tools/c_aliases.py (renamed from waflib/Tools/c_aliases.py)0
-rw-r--r--Tools/c_config.py (renamed from waflib/Tools/c_config.py)0
-rw-r--r--Tools/c_osx.py (renamed from waflib/Tools/c_osx.py)0
-rw-r--r--Tools/c_preproc.py (renamed from waflib/Tools/c_preproc.py)0
-rw-r--r--Tools/c_tests.py (renamed from waflib/Tools/c_tests.py)0
-rw-r--r--Tools/ccroot.py (renamed from waflib/Tools/ccroot.py)0
-rw-r--r--Tools/clang.py (renamed from waflib/Tools/clang.py)0
-rw-r--r--Tools/clangxx.py (renamed from waflib/Tools/clangxx.py)0
-rw-r--r--Tools/compiler_c.py (renamed from waflib/Tools/compiler_c.py)0
-rw-r--r--Tools/compiler_cxx.py (renamed from waflib/Tools/compiler_cxx.py)0
-rw-r--r--Tools/compiler_d.py (renamed from waflib/Tools/compiler_d.py)0
-rw-r--r--Tools/compiler_fc.py (renamed from waflib/Tools/compiler_fc.py)0
-rw-r--r--Tools/cs.py (renamed from waflib/Tools/cs.py)0
-rw-r--r--Tools/cxx.py (renamed from waflib/Tools/cxx.py)0
-rw-r--r--Tools/d.py (renamed from waflib/Tools/d.py)0
-rw-r--r--Tools/d_config.py (renamed from waflib/Tools/d_config.py)0
-rw-r--r--Tools/d_scan.py (renamed from waflib/Tools/d_scan.py)0
-rw-r--r--Tools/dbus.py (renamed from waflib/Tools/dbus.py)0
-rw-r--r--Tools/dmd.py (renamed from waflib/Tools/dmd.py)0
-rw-r--r--Tools/errcheck.py (renamed from waflib/Tools/errcheck.py)0
-rw-r--r--Tools/fc.py (renamed from waflib/Tools/fc.py)0
-rw-r--r--Tools/fc_config.py (renamed from waflib/Tools/fc_config.py)0
-rw-r--r--Tools/fc_scan.py (renamed from waflib/Tools/fc_scan.py)0
-rw-r--r--Tools/flex.py (renamed from waflib/Tools/flex.py)0
-rw-r--r--Tools/g95.py (renamed from waflib/Tools/g95.py)0
-rw-r--r--Tools/gas.py (renamed from waflib/Tools/gas.py)0
-rw-r--r--Tools/gcc.py (renamed from waflib/Tools/gcc.py)0
-rw-r--r--Tools/gdc.py (renamed from waflib/Tools/gdc.py)0
-rw-r--r--Tools/gfortran.py (renamed from waflib/Tools/gfortran.py)0
-rw-r--r--Tools/glib2.py (renamed from waflib/Tools/glib2.py)0
-rw-r--r--Tools/gnu_dirs.py (renamed from waflib/Tools/gnu_dirs.py)0
-rw-r--r--Tools/gxx.py (renamed from waflib/Tools/gxx.py)0
-rw-r--r--Tools/icc.py (renamed from waflib/Tools/icc.py)0
-rw-r--r--Tools/icpc.py (renamed from waflib/Tools/icpc.py)0
-rw-r--r--Tools/ifort.py (renamed from waflib/Tools/ifort.py)0
-rw-r--r--Tools/intltool.py (renamed from waflib/Tools/intltool.py)0
-rw-r--r--Tools/irixcc.py (renamed from waflib/Tools/irixcc.py)0
-rw-r--r--Tools/javaw.py (renamed from waflib/Tools/javaw.py)0
-rw-r--r--Tools/ldc2.py (renamed from waflib/Tools/ldc2.py)0
-rw-r--r--Tools/lua.py (renamed from waflib/Tools/lua.py)0
-rw-r--r--Tools/md5_tstamp.py (renamed from waflib/Tools/md5_tstamp.py)0
-rw-r--r--Tools/msvc.py (renamed from waflib/Tools/msvc.py)0
-rw-r--r--Tools/nasm.py (renamed from waflib/Tools/nasm.py)0
-rw-r--r--Tools/nobuild.py (renamed from waflib/Tools/nobuild.py)0
-rw-r--r--Tools/perl.py (renamed from waflib/Tools/perl.py)0
-rw-r--r--Tools/python.py (renamed from waflib/Tools/python.py)0
-rw-r--r--Tools/qt5.py (renamed from waflib/Tools/qt5.py)0
-rw-r--r--Tools/ruby.py (renamed from waflib/Tools/ruby.py)0
-rw-r--r--Tools/suncc.py (renamed from waflib/Tools/suncc.py)0
-rw-r--r--Tools/suncxx.py (renamed from waflib/Tools/suncxx.py)0
-rw-r--r--Tools/tex.py (renamed from waflib/Tools/tex.py)0
-rw-r--r--Tools/vala.py (renamed from waflib/Tools/vala.py)0
-rw-r--r--Tools/waf_unit_test.py (renamed from waflib/Tools/waf_unit_test.py)0
-rw-r--r--Tools/winres.py (renamed from waflib/Tools/winres.py)0
-rw-r--r--Tools/xlc.py (renamed from waflib/Tools/xlc.py)0
-rw-r--r--Tools/xlcxx.py (renamed from waflib/Tools/xlcxx.py)0
-rw-r--r--Utils.py (renamed from waflib/Utils.py)0
-rw-r--r--__init__.py (renamed from waflib/__init__.py)0
-rw-r--r--ansiterm.py (renamed from waflib/ansiterm.py)0
-rw-r--r--extras/__init__.py (renamed from waflib/extras/__init__.py)0
-rw-r--r--extras/autowaf.py (renamed from waflib/extras/autowaf.py)60
-rw-r--r--extras/batched_cc.py (renamed from waflib/extras/batched_cc.py)0
-rw-r--r--extras/biber.py (renamed from waflib/extras/biber.py)0
-rw-r--r--extras/bjam.py (renamed from waflib/extras/bjam.py)0
-rw-r--r--extras/blender.py (renamed from waflib/extras/blender.py)0
-rw-r--r--extras/boo.py (renamed from waflib/extras/boo.py)0
-rw-r--r--extras/boost.py (renamed from waflib/extras/boost.py)0
-rw-r--r--extras/build_file_tracker.py (renamed from waflib/extras/build_file_tracker.py)0
-rw-r--r--extras/build_logs.py (renamed from waflib/extras/build_logs.py)0
-rw-r--r--extras/buildcopy.py (renamed from waflib/extras/buildcopy.py)0
-rw-r--r--extras/c_bgxlc.py (renamed from waflib/extras/c_bgxlc.py)0
-rw-r--r--extras/c_dumbpreproc.py (renamed from waflib/extras/c_dumbpreproc.py)0
-rw-r--r--extras/c_emscripten.py (renamed from waflib/extras/c_emscripten.py)0
-rw-r--r--extras/c_nec.py (renamed from waflib/extras/c_nec.py)0
-rw-r--r--extras/cabal.py (renamed from waflib/extras/cabal.py)0
-rw-r--r--extras/cfg_altoptions.py (renamed from waflib/extras/cfg_altoptions.py)0
-rw-r--r--extras/clang_compilation_database.py (renamed from waflib/extras/clang_compilation_database.py)0
-rw-r--r--extras/codelite.py (renamed from waflib/extras/codelite.py)0
-rw-r--r--extras/color_gcc.py (renamed from waflib/extras/color_gcc.py)0
-rw-r--r--extras/color_rvct.py (renamed from waflib/extras/color_rvct.py)0
-rw-r--r--extras/compat15.py (renamed from waflib/extras/compat15.py)0
-rw-r--r--extras/cppcheck.py (renamed from waflib/extras/cppcheck.py)0
-rw-r--r--extras/cpplint.py (renamed from waflib/extras/cpplint.py)0
-rw-r--r--extras/cross_gnu.py (renamed from waflib/extras/cross_gnu.py)0
-rw-r--r--extras/cython.py (renamed from waflib/extras/cython.py)0
-rw-r--r--extras/dcc.py (renamed from waflib/extras/dcc.py)0
-rw-r--r--extras/distnet.py (renamed from waflib/extras/distnet.py)0
-rw-r--r--extras/doxygen.py (renamed from waflib/extras/doxygen.py)0
-rw-r--r--extras/dpapi.py (renamed from waflib/extras/dpapi.py)0
-rw-r--r--extras/eclipse.py (renamed from waflib/extras/eclipse.py)0
-rw-r--r--extras/erlang.py (renamed from waflib/extras/erlang.py)0
-rw-r--r--extras/fast_partial.py (renamed from waflib/extras/fast_partial.py)0
-rw-r--r--extras/fc_bgxlf.py (renamed from waflib/extras/fc_bgxlf.py)0
-rw-r--r--extras/fc_cray.py (renamed from waflib/extras/fc_cray.py)0
-rw-r--r--extras/fc_nag.py (renamed from waflib/extras/fc_nag.py)0
-rw-r--r--extras/fc_nec.py (renamed from waflib/extras/fc_nec.py)0
-rw-r--r--extras/fc_open64.py (renamed from waflib/extras/fc_open64.py)0
-rw-r--r--extras/fc_pgfortran.py (renamed from waflib/extras/fc_pgfortran.py)0
-rw-r--r--extras/fc_solstudio.py (renamed from waflib/extras/fc_solstudio.py)0
-rw-r--r--extras/fc_xlf.py (renamed from waflib/extras/fc_xlf.py)0
-rw-r--r--extras/file_to_object.py (renamed from waflib/extras/file_to_object.py)0
-rw-r--r--extras/fluid.py (renamed from waflib/extras/fluid.py)0
-rw-r--r--extras/freeimage.py (renamed from waflib/extras/freeimage.py)0
-rw-r--r--extras/fsb.py (renamed from waflib/extras/fsb.py)0
-rw-r--r--extras/fsc.py (renamed from waflib/extras/fsc.py)0
-rw-r--r--extras/gccdeps.py (renamed from waflib/extras/gccdeps.py)0
-rw-r--r--extras/gdbus.py (renamed from waflib/extras/gdbus.py)0
-rw-r--r--extras/gob2.py (renamed from waflib/extras/gob2.py)0
-rw-r--r--extras/halide.py (renamed from waflib/extras/halide.py)0
-rwxr-xr-xextras/javatest.py (renamed from waflib/extras/javatest.py)0
-rw-r--r--extras/kde4.py (renamed from waflib/extras/kde4.py)0
-rw-r--r--extras/local_rpath.py (renamed from waflib/extras/local_rpath.py)0
-rw-r--r--extras/lv2.py (renamed from waflib/extras/lv2.py)0
-rw-r--r--extras/make.py (renamed from waflib/extras/make.py)0
-rw-r--r--extras/midl.py (renamed from waflib/extras/midl.py)0
-rw-r--r--extras/msvcdeps.py (renamed from waflib/extras/msvcdeps.py)0
-rw-r--r--extras/msvs.py (renamed from waflib/extras/msvs.py)0
-rw-r--r--extras/netcache_client.py (renamed from waflib/extras/netcache_client.py)0
-rw-r--r--extras/objcopy.py (renamed from waflib/extras/objcopy.py)0
-rw-r--r--extras/ocaml.py (renamed from waflib/extras/ocaml.py)0
-rw-r--r--extras/package.py (renamed from waflib/extras/package.py)0
-rw-r--r--extras/parallel_debug.py (renamed from waflib/extras/parallel_debug.py)0
-rw-r--r--extras/pch.py (renamed from waflib/extras/pch.py)0
-rw-r--r--extras/pep8.py (renamed from waflib/extras/pep8.py)0
-rw-r--r--extras/pgicc.py (renamed from waflib/extras/pgicc.py)0
-rw-r--r--extras/pgicxx.py (renamed from waflib/extras/pgicxx.py)0
-rw-r--r--extras/proc.py (renamed from waflib/extras/proc.py)0
-rw-r--r--extras/protoc.py (renamed from waflib/extras/protoc.py)0
-rw-r--r--extras/pyqt5.py (renamed from waflib/extras/pyqt5.py)0
-rw-r--r--extras/pytest.py (renamed from waflib/extras/pytest.py)0
-rw-r--r--extras/qnxnto.py (renamed from waflib/extras/qnxnto.py)0
-rw-r--r--extras/qt4.py (renamed from waflib/extras/qt4.py)0
-rw-r--r--extras/relocation.py (renamed from waflib/extras/relocation.py)0
-rw-r--r--extras/remote.py (renamed from waflib/extras/remote.py)0
-rw-r--r--extras/resx.py (renamed from waflib/extras/resx.py)0
-rw-r--r--extras/review.py (renamed from waflib/extras/review.py)0
-rw-r--r--extras/rst.py (renamed from waflib/extras/rst.py)0
-rw-r--r--extras/run_do_script.py (renamed from waflib/extras/run_do_script.py)0
-rw-r--r--extras/run_m_script.py (renamed from waflib/extras/run_m_script.py)0
-rw-r--r--extras/run_py_script.py (renamed from waflib/extras/run_py_script.py)0
-rw-r--r--extras/run_r_script.py (renamed from waflib/extras/run_r_script.py)0
-rw-r--r--extras/sas.py (renamed from waflib/extras/sas.py)0
-rw-r--r--extras/satellite_assembly.py (renamed from waflib/extras/satellite_assembly.py)0
-rw-r--r--extras/scala.py (renamed from waflib/extras/scala.py)0
-rw-r--r--extras/slow_qt4.py (renamed from waflib/extras/slow_qt4.py)0
-rw-r--r--extras/softlink_libs.py (renamed from waflib/extras/softlink_libs.py)0
-rw-r--r--extras/stale.py (renamed from waflib/extras/stale.py)0
-rw-r--r--extras/stracedeps.py (renamed from waflib/extras/stracedeps.py)0
-rw-r--r--extras/swig.py (renamed from waflib/extras/swig.py)0
-rw-r--r--extras/syms.py (renamed from waflib/extras/syms.py)0
-rw-r--r--extras/ticgt.py (renamed from waflib/extras/ticgt.py)0
-rw-r--r--extras/unity.py (renamed from waflib/extras/unity.py)0
-rw-r--r--extras/use_config.py (renamed from waflib/extras/use_config.py)0
-rw-r--r--extras/valadoc.py (renamed from waflib/extras/valadoc.py)0
-rw-r--r--extras/waf_xattr.py (renamed from waflib/extras/waf_xattr.py)0
-rw-r--r--extras/why.py (renamed from waflib/extras/why.py)0
-rw-r--r--extras/win32_opts.py (renamed from waflib/extras/win32_opts.py)0
-rw-r--r--extras/wix.py (renamed from waflib/extras/wix.py)0
-rw-r--r--extras/xcode6.py (renamed from waflib/extras/xcode6.py)0
-rw-r--r--fixpy2.py (renamed from waflib/fixpy2.py)0
-rw-r--r--ganv.pc.in11
-rw-r--r--ganv/Box.hpp50
-rw-r--r--ganv/Canvas.hpp158
-rw-r--r--ganv/Circle.hpp79
-rw-r--r--ganv/Edge.hpp90
-rw-r--r--ganv/Item.hpp90
-rw-r--r--ganv/Module.hpp130
-rw-r--r--ganv/Node.hpp106
-rw-r--r--ganv/Port.hpp76
-rw-r--r--ganv/box.h78
-rw-r--r--ganv/canvas.h630
-rw-r--r--ganv/circle.h78
-rw-r--r--ganv/edge.h129
-rw-r--r--ganv/ganv.h31
-rw-r--r--ganv/ganv.hpp26
-rw-r--r--ganv/group.h55
-rw-r--r--ganv/item.h184
-rw-r--r--ganv/module.h95
-rw-r--r--ganv/node.h179
-rw-r--r--ganv/port.h103
-rw-r--r--ganv/text.h52
-rw-r--r--ganv/types.h26
-rw-r--r--ganv/types.hpp30
-rw-r--r--ganv/widget.h54
-rw-r--r--ganv/wrap.hpp131
-rwxr-xr-xgtkdoc.sh26
-rwxr-xr-xprocessor.py (renamed from waflib/processor.py)0
-rw-r--r--src/Canvas.cpp4184
-rw-r--r--src/Port.cpp57
-rw-r--r--src/boilerplate.h43
-rw-r--r--src/box.c561
-rw-r--r--src/circle.c467
-rw-r--r--src/color.h63
-rw-r--r--src/edge.c786
-rw-r--r--src/fdgl.hpp166
-rw-r--r--src/ganv-marshal.list4
-rw-r--r--src/ganv-private.h403
-rw-r--r--src/ganv_bench.cpp178
-rw-r--r--src/ganv_test.c119
-rwxr-xr-xsrc/ganv_test.py22
-rw-r--r--src/gettext.h26
-rw-r--r--src/group.c446
-rw-r--r--src/item.c707
-rw-r--r--src/module.c859
-rw-r--r--src/node.c897
-rw-r--r--src/port.c735
-rw-r--r--src/text.c381
-rw-r--r--src/widget.c503
-rw-r--r--waflib/COPYING25
-rwxr-xr-xwaflib/waf16
-rw-r--r--wscript247
235 files changed, 60 insertions, 15426 deletions
diff --git a/waflib/.gitignore b/.gitignore
index 8d35cb3..8d35cb3 100644
--- a/waflib/.gitignore
+++ b/.gitignore
diff --git a/AUTHORS b/AUTHORS
deleted file mode 100644
index f1bb6b3..0000000
--- a/AUTHORS
+++ /dev/null
@@ -1,4 +0,0 @@
-Author:
-
-David Robillard <d@drobilla.net>
-
diff --git a/waflib/Build.py b/Build.py
index 1afcba6..1afcba6 100644
--- a/waflib/Build.py
+++ b/Build.py
diff --git a/COPYING b/COPYING
index 94a9ed0..a4147d2 100644
--- a/COPYING
+++ b/COPYING
@@ -1,674 +1,25 @@
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users. We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors. You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. You must make sure that they, too, receive
-or can get the source code. And you must show them these terms so they
-know their rights.
-
- Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
- For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
- Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so. This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software. The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable. Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products. If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
- Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary. To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
- If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
- <program> Copyright (C) <year> <name of author>
- This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
- The GNU General Public License does not permit incorporating your program
-into proprietary programs. If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License. But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/waflib/ConfigSet.py b/ConfigSet.py
index b300bb5..b300bb5 100644
--- a/waflib/ConfigSet.py
+++ b/ConfigSet.py
diff --git a/waflib/Configure.py b/Configure.py
index d0a4793..d0a4793 100644
--- a/waflib/Configure.py
+++ b/Configure.py
diff --git a/waflib/Context.py b/Context.py
index bb47c92..bb47c92 100644
--- a/waflib/Context.py
+++ b/Context.py
diff --git a/waflib/Errors.py b/Errors.py
index bf75c1b..bf75c1b 100644
--- a/waflib/Errors.py
+++ b/Errors.py
diff --git a/INSTALL b/INSTALL
deleted file mode 100644
index 623cddd..0000000
--- a/INSTALL
+++ /dev/null
@@ -1,59 +0,0 @@
-Installation Instructions
-=========================
-
-Basic Installation
-------------------
-
-Building this software requires only Python. To install with default options:
-
- ./waf configure
- ./waf
- ./waf install
-
-You may need to become root for the install stage, for example:
-
- sudo ./waf install
-
-Configuration Options
----------------------
-
-All supported options can be viewed using the command:
-
- ./waf --help
-
-Most options only need to be passed during the configure stage, for example:
-
- ./waf configure --prefix=/usr
- ./waf
- ./waf install
-
-Compiler Configuration
-----------------------
-
-Several standard environment variables can be used to control how compilers are
-invoked:
-
- * CC: Path to C compiler
- * CFLAGS: C compiler options
- * CXX: Path to C++ compiler
- * CXXFLAGS: C++ compiler options
- * CPPFLAGS: C preprocessor options
- * LINKFLAGS: Linker options
-
-Installation Directories
-------------------------
-
-The --prefix option (or the PREFIX environment variable) can be used to change
-the prefix which all files are installed under. There are also several options
-allowing for more fine-tuned control, see the --help output for details.
-
-Packaging
----------
-
-Everything can be installed to a specific root directory by passing a --destdir
-option to the install stage (or setting the DESTDIR environment variable),
-which adds a prefix to all install paths. For example:
-
- ./waf configure --prefix=/usr
- ./waf
- ./waf install --destdir=/tmp/package
diff --git a/waflib/Logs.py b/Logs.py
index 2a47516..2a47516 100644
--- a/waflib/Logs.py
+++ b/Logs.py
diff --git a/NEWS b/NEWS
deleted file mode 100644
index 4abfd45..0000000
--- a/NEWS
+++ /dev/null
@@ -1,58 +0,0 @@
-ganv (1.4.3) unstable;
-
- * Fix positioning of embedded widgets when changing layout.
- * Fix port position on modules with embedded widgets.
- * Fix unexpected node jumping when dragging new connections.
- * Preserve selection for quickly making several connections.
- * Dampen sprung layout energy over time to prevent oscillation.
- * Add support for edges that do not constrain the layout.
- * Distinguish edge color from port color slighly.
- * Highlight connected edges on port hover.
- * Add support for PDF and PS export.
- * Improve text rendering at high zoom.
- * Improve appearance of graphs with circle nodes.
- * Improve update performance.
- * Add API to specify module port order.
- * Add support for beveled box corners.
- * Fix various minor visual alignment/sizing issues.
- * Fix size of vertical flow modules.
- * Fix compilation with --no-fdgl (patch from Vlad Glagolev).
- * Fix crash when destroying canvas.
- * Upgrade to waf 1.8.14
-
- -- David Robillard <d@drobilla.net> Fri, 14 Oct 2016 18:55:26 -0400
-
-ganv (1.4.2) stable;
-
- * Fix bug where edges would not update when nodes are moved after the canvas
- is cleared (fix stuck connections in Patchage after refresh).
- * Upgrade to waf 1.7.16
-
- -- David Robillard <d@drobilla.net> Fri, 08 Aug 2014 18:24:33 -0400
-
-ganv (1.4.0) stable;
-
- * Begin using library and pkg-config names suitable for parallel
- installation. This version of flowcanvas is flowcanvas-1 and is
- NOT compatible with previous versions
- * Clean up API and improve documentation.
- * Add font size API
- * Use system theme font size by default
- * Size empty ports in font based units so they look right when zoomed
- * Adjust padding and placement to precisely fit text
- * Add ability to select connections directly
- * Add Connection::set_curved()
- * Fix lingering handle when deleting connections
- * Dramatically increase performance by rendering text manually
- rather than using the truly awful Gnome::Canvas::Text.
- * Remove use of boost smart pointers. Adding and removing from containers
- (e.g. Canvas, Module) is now done automatically.
- * Clean up API/ABI by hiding private implementations.
- * Add ability to select connections by their handles, either individually
- or in groups with rect select.
- * Further slight improvements in memory consumption and alignment.
- * Improve scalability to graphs with many connections (eliminate linear
- connection searches and redundant connection collections).
- * Switch to GPLv3+
-
- -- David Robillard <d@drobilla.net> Sun, 27 Apr 2014 23:44:29 -0400
diff --git a/waflib/Node.py b/Node.py
index 4ac1ea8..4ac1ea8 100644
--- a/waflib/Node.py
+++ b/Node.py
diff --git a/waflib/Options.py b/Options.py
index ad802d4..ad802d4 100644
--- a/waflib/Options.py
+++ b/Options.py
diff --git a/README b/README
deleted file mode 100644
index f167deb..0000000
--- a/README
+++ /dev/null
@@ -1,14 +0,0 @@
-Ganv
-====
-
-Ganv is an interactive Gtk canvas widget for graph-based interfaces (patchers,
-modular synthesizers, finite state automata, interactive graphs, etc).
-For more information, see <http://drobilla.net/software/ganv>.
-
-Ganv provides classes for "Modules" (boxes with "Ports"), Circles, and
-Edges (lines that connect either Ports or Circles). The user can rearrange
-items, or Ganv can automatically arrange items using GraphViz. Edges can
-be made by the user one at a time with the mouse, or in groups using the mouse
-and keyboard.
-
- -- David Robillard <d@drobilla.net>
diff --git a/waflib/README.md b/README.md
index c5361b9..c5361b9 100644
--- a/waflib/README.md
+++ b/README.md
diff --git a/waflib/Runner.py b/Runner.py
index 261084d..261084d 100644
--- a/waflib/Runner.py
+++ b/Runner.py
diff --git a/waflib/Scripting.py b/Scripting.py
index 749d4f2..749d4f2 100644
--- a/waflib/Scripting.py
+++ b/Scripting.py
diff --git a/waflib/Task.py b/Task.py
index 0fc449d..0fc449d 100644
--- a/waflib/Task.py
+++ b/Task.py
diff --git a/waflib/TaskGen.py b/TaskGen.py
index a74e643..a74e643 100644
--- a/waflib/TaskGen.py
+++ b/TaskGen.py
diff --git a/waflib/Tools/__init__.py b/Tools/__init__.py
index 079df35..079df35 100644
--- a/waflib/Tools/__init__.py
+++ b/Tools/__init__.py
diff --git a/waflib/Tools/ar.py b/Tools/ar.py
index b39b645..b39b645 100644
--- a/waflib/Tools/ar.py
+++ b/Tools/ar.py
diff --git a/waflib/Tools/asm.py b/Tools/asm.py
index b6f26fb..b6f26fb 100644
--- a/waflib/Tools/asm.py
+++ b/Tools/asm.py
diff --git a/waflib/Tools/bison.py b/Tools/bison.py
index eef56dc..eef56dc 100644
--- a/waflib/Tools/bison.py
+++ b/Tools/bison.py
diff --git a/waflib/Tools/c.py b/Tools/c.py
index effd6b6..effd6b6 100644
--- a/waflib/Tools/c.py
+++ b/Tools/c.py
diff --git a/waflib/Tools/c_aliases.py b/Tools/c_aliases.py
index c9d5369..c9d5369 100644
--- a/waflib/Tools/c_aliases.py
+++ b/Tools/c_aliases.py
diff --git a/waflib/Tools/c_config.py b/Tools/c_config.py
index d2b3c0d..d2b3c0d 100644
--- a/waflib/Tools/c_config.py
+++ b/Tools/c_config.py
diff --git a/waflib/Tools/c_osx.py b/Tools/c_osx.py
index f70b128..f70b128 100644
--- a/waflib/Tools/c_osx.py
+++ b/Tools/c_osx.py
diff --git a/waflib/Tools/c_preproc.py b/Tools/c_preproc.py
index 7e04b4a..7e04b4a 100644
--- a/waflib/Tools/c_preproc.py
+++ b/Tools/c_preproc.py
diff --git a/waflib/Tools/c_tests.py b/Tools/c_tests.py
index f858df5..f858df5 100644
--- a/waflib/Tools/c_tests.py
+++ b/Tools/c_tests.py
diff --git a/waflib/Tools/ccroot.py b/Tools/ccroot.py
index cfef8bf..cfef8bf 100644
--- a/waflib/Tools/ccroot.py
+++ b/Tools/ccroot.py
diff --git a/waflib/Tools/clang.py b/Tools/clang.py
index 3828e39..3828e39 100644
--- a/waflib/Tools/clang.py
+++ b/Tools/clang.py
diff --git a/waflib/Tools/clangxx.py b/Tools/clangxx.py
index 152013c..152013c 100644
--- a/waflib/Tools/clangxx.py
+++ b/Tools/clangxx.py
diff --git a/waflib/Tools/compiler_c.py b/Tools/compiler_c.py
index 2dba3f8..2dba3f8 100644
--- a/waflib/Tools/compiler_c.py
+++ b/Tools/compiler_c.py
diff --git a/waflib/Tools/compiler_cxx.py b/Tools/compiler_cxx.py
index 1af65a2..1af65a2 100644
--- a/waflib/Tools/compiler_cxx.py
+++ b/Tools/compiler_cxx.py
diff --git a/waflib/Tools/compiler_d.py b/Tools/compiler_d.py
index 43bb1f6..43bb1f6 100644
--- a/waflib/Tools/compiler_d.py
+++ b/Tools/compiler_d.py
diff --git a/waflib/Tools/compiler_fc.py b/Tools/compiler_fc.py
index 96b58e7..96b58e7 100644
--- a/waflib/Tools/compiler_fc.py
+++ b/Tools/compiler_fc.py
diff --git a/waflib/Tools/cs.py b/Tools/cs.py
index aecca6d..aecca6d 100644
--- a/waflib/Tools/cs.py
+++ b/Tools/cs.py
diff --git a/waflib/Tools/cxx.py b/Tools/cxx.py
index 194fad7..194fad7 100644
--- a/waflib/Tools/cxx.py
+++ b/Tools/cxx.py
diff --git a/waflib/Tools/d.py b/Tools/d.py
index e4cf73b..e4cf73b 100644
--- a/waflib/Tools/d.py
+++ b/Tools/d.py
diff --git a/waflib/Tools/d_config.py b/Tools/d_config.py
index 6637556..6637556 100644
--- a/waflib/Tools/d_config.py
+++ b/Tools/d_config.py
diff --git a/waflib/Tools/d_scan.py b/Tools/d_scan.py
index 14c6c31..14c6c31 100644
--- a/waflib/Tools/d_scan.py
+++ b/Tools/d_scan.py
diff --git a/waflib/Tools/dbus.py b/Tools/dbus.py
index d520f1c..d520f1c 100644
--- a/waflib/Tools/dbus.py
+++ b/Tools/dbus.py
diff --git a/waflib/Tools/dmd.py b/Tools/dmd.py
index 8917ca1..8917ca1 100644
--- a/waflib/Tools/dmd.py
+++ b/Tools/dmd.py
diff --git a/waflib/Tools/errcheck.py b/Tools/errcheck.py
index de8d75a..de8d75a 100644
--- a/waflib/Tools/errcheck.py
+++ b/Tools/errcheck.py
diff --git a/waflib/Tools/fc.py b/Tools/fc.py
index d9e8d8c..d9e8d8c 100644
--- a/waflib/Tools/fc.py
+++ b/Tools/fc.py
diff --git a/waflib/Tools/fc_config.py b/Tools/fc_config.py
index 222f3a5..222f3a5 100644
--- a/waflib/Tools/fc_config.py
+++ b/Tools/fc_config.py
diff --git a/waflib/Tools/fc_scan.py b/Tools/fc_scan.py
index 12cb0fc..12cb0fc 100644
--- a/waflib/Tools/fc_scan.py
+++ b/Tools/fc_scan.py
diff --git a/waflib/Tools/flex.py b/Tools/flex.py
index 2256657..2256657 100644
--- a/waflib/Tools/flex.py
+++ b/Tools/flex.py
diff --git a/waflib/Tools/g95.py b/Tools/g95.py
index f69ba4f..f69ba4f 100644
--- a/waflib/Tools/g95.py
+++ b/Tools/g95.py
diff --git a/waflib/Tools/gas.py b/Tools/gas.py
index 77afed7..77afed7 100644
--- a/waflib/Tools/gas.py
+++ b/Tools/gas.py
diff --git a/waflib/Tools/gcc.py b/Tools/gcc.py
index acdd473..acdd473 100644
--- a/waflib/Tools/gcc.py
+++ b/Tools/gcc.py
diff --git a/waflib/Tools/gdc.py b/Tools/gdc.py
index d89a66d..d89a66d 100644
--- a/waflib/Tools/gdc.py
+++ b/Tools/gdc.py
diff --git a/waflib/Tools/gfortran.py b/Tools/gfortran.py
index 1050667..1050667 100644
--- a/waflib/Tools/gfortran.py
+++ b/Tools/gfortran.py
diff --git a/waflib/Tools/glib2.py b/Tools/glib2.py
index 949fe37..949fe37 100644
--- a/waflib/Tools/glib2.py
+++ b/Tools/glib2.py
diff --git a/waflib/Tools/gnu_dirs.py b/Tools/gnu_dirs.py
index 2847071..2847071 100644
--- a/waflib/Tools/gnu_dirs.py
+++ b/Tools/gnu_dirs.py
diff --git a/waflib/Tools/gxx.py b/Tools/gxx.py
index 22c5d26..22c5d26 100644
--- a/waflib/Tools/gxx.py
+++ b/Tools/gxx.py
diff --git a/waflib/Tools/icc.py b/Tools/icc.py
index b6492c8..b6492c8 100644
--- a/waflib/Tools/icc.py
+++ b/Tools/icc.py
diff --git a/waflib/Tools/icpc.py b/Tools/icpc.py
index 8a6cc6c..8a6cc6c 100644
--- a/waflib/Tools/icpc.py
+++ b/Tools/icpc.py
diff --git a/waflib/Tools/ifort.py b/Tools/ifort.py
index 74934f3..74934f3 100644
--- a/waflib/Tools/ifort.py
+++ b/Tools/ifort.py
diff --git a/waflib/Tools/intltool.py b/Tools/intltool.py
index af95ba8..af95ba8 100644
--- a/waflib/Tools/intltool.py
+++ b/Tools/intltool.py
diff --git a/waflib/Tools/irixcc.py b/Tools/irixcc.py
index c3ae1ac..c3ae1ac 100644
--- a/waflib/Tools/irixcc.py
+++ b/Tools/irixcc.py
diff --git a/waflib/Tools/javaw.py b/Tools/javaw.py
index f6fd20c..f6fd20c 100644
--- a/waflib/Tools/javaw.py
+++ b/Tools/javaw.py
diff --git a/waflib/Tools/ldc2.py b/Tools/ldc2.py
index a51c344..a51c344 100644
--- a/waflib/Tools/ldc2.py
+++ b/Tools/ldc2.py
diff --git a/waflib/Tools/lua.py b/Tools/lua.py
index 15a333a..15a333a 100644
--- a/waflib/Tools/lua.py
+++ b/Tools/lua.py
diff --git a/waflib/Tools/md5_tstamp.py b/Tools/md5_tstamp.py
index 6428e46..6428e46 100644
--- a/waflib/Tools/md5_tstamp.py
+++ b/Tools/md5_tstamp.py
diff --git a/waflib/Tools/msvc.py b/Tools/msvc.py
index 17b347d..17b347d 100644
--- a/waflib/Tools/msvc.py
+++ b/Tools/msvc.py
diff --git a/waflib/Tools/nasm.py b/Tools/nasm.py
index 411d582..411d582 100644
--- a/waflib/Tools/nasm.py
+++ b/Tools/nasm.py
diff --git a/waflib/Tools/nobuild.py b/Tools/nobuild.py
index 2e4b055..2e4b055 100644
--- a/waflib/Tools/nobuild.py
+++ b/Tools/nobuild.py
diff --git a/waflib/Tools/perl.py b/Tools/perl.py
index 32b03fb..32b03fb 100644
--- a/waflib/Tools/perl.py
+++ b/Tools/perl.py
diff --git a/waflib/Tools/python.py b/Tools/python.py
index 25841d0..25841d0 100644
--- a/waflib/Tools/python.py
+++ b/Tools/python.py
diff --git a/waflib/Tools/qt5.py b/Tools/qt5.py
index 4f9c690..4f9c690 100644
--- a/waflib/Tools/qt5.py
+++ b/Tools/qt5.py
diff --git a/waflib/Tools/ruby.py b/Tools/ruby.py
index 8d92a79..8d92a79 100644
--- a/waflib/Tools/ruby.py
+++ b/Tools/ruby.py
diff --git a/waflib/Tools/suncc.py b/Tools/suncc.py
index 33d34fc..33d34fc 100644
--- a/waflib/Tools/suncc.py
+++ b/Tools/suncc.py
diff --git a/waflib/Tools/suncxx.py b/Tools/suncxx.py
index 3b384f6..3b384f6 100644
--- a/waflib/Tools/suncxx.py
+++ b/Tools/suncxx.py
diff --git a/waflib/Tools/tex.py b/Tools/tex.py
index eaf9fdb..eaf9fdb 100644
--- a/waflib/Tools/tex.py
+++ b/Tools/tex.py
diff --git a/waflib/Tools/vala.py b/Tools/vala.py
index 822ec50..822ec50 100644
--- a/waflib/Tools/vala.py
+++ b/Tools/vala.py
diff --git a/waflib/Tools/waf_unit_test.py b/Tools/waf_unit_test.py
index a71ed1c..a71ed1c 100644
--- a/waflib/Tools/waf_unit_test.py
+++ b/Tools/waf_unit_test.py
diff --git a/waflib/Tools/winres.py b/Tools/winres.py
index 586c596..586c596 100644
--- a/waflib/Tools/winres.py
+++ b/Tools/winres.py
diff --git a/waflib/Tools/xlc.py b/Tools/xlc.py
index 134dd41..134dd41 100644
--- a/waflib/Tools/xlc.py
+++ b/Tools/xlc.py
diff --git a/waflib/Tools/xlcxx.py b/Tools/xlcxx.py
index 76aa59b..76aa59b 100644
--- a/waflib/Tools/xlcxx.py
+++ b/Tools/xlcxx.py
diff --git a/waflib/Utils.py b/Utils.py
index b4665c4..b4665c4 100644
--- a/waflib/Utils.py
+++ b/Utils.py
diff --git a/waflib/__init__.py b/__init__.py
index 079df35..079df35 100644
--- a/waflib/__init__.py
+++ b/__init__.py
diff --git a/waflib/ansiterm.py b/ansiterm.py
index 0d20c63..0d20c63 100644
--- a/waflib/ansiterm.py
+++ b/ansiterm.py
diff --git a/waflib/extras/__init__.py b/extras/__init__.py
index c8a3c34..c8a3c34 100644
--- a/waflib/extras/__init__.py
+++ b/extras/__init__.py
diff --git a/waflib/extras/autowaf.py b/extras/autowaf.py
index 8f9c633..feaae3c 100644
--- a/waflib/extras/autowaf.py
+++ b/extras/autowaf.py
@@ -2,6 +2,7 @@ import glob
import os
import subprocess
import sys
+import time
from waflib import Build, Context, Logs, Options, Utils
from waflib.TaskGen import feature, before, after
@@ -69,7 +70,7 @@ def set_options(opt, debug_by_default=False, test=False):
opts.add_option('-s', '--strict', action='store_true', default=False,
dest='strict',
help="use strict compiler flags and show all warnings")
- opts.add_option('--ultra-strict', action='store_true', default=False,
+ opts.add_option('-S', '--ultra-strict', action='store_true', default=False,
dest='ultra_strict',
help="use extremely strict compiler flags (likely noisy)")
opts.add_option('--docs', action='store_true', default=False, dest='docs',
@@ -731,8 +732,6 @@ def cd_to_build_dir(ctx, appname):
os.chdir(os.path.join('build', appname))
else:
os.chdir('build')
- Logs.pprint('GREEN', ("Waf: Entering directory `%s'" %
- os.path.abspath(os.getcwd())))
def cd_to_orig_dir(ctx, child):
if child:
@@ -741,7 +740,10 @@ def cd_to_orig_dir(ctx, child):
os.chdir('..')
def pre_test(ctx, appname, dirs=['src']):
+ Logs.pprint('GREEN', '\n[==========] Running %s tests' % appname)
+
if not hasattr(ctx, 'autowaf_tests_total'):
+ ctx.autowaf_tests_start_time = time.clock()
ctx.autowaf_tests_total = 0
ctx.autowaf_tests_failed = 0
ctx.autowaf_local_tests_total = 0
@@ -766,6 +768,9 @@ def pre_test(ctx, appname, dirs=['src']):
finally:
clear_log.close()
+class TestFailed(Exception):
+ pass
+
def post_test(ctx, appname, dirs=['src'], remove=['*boost*', 'c++*']):
if not ctx.env.NO_COVERAGE:
diropts = ''
@@ -806,21 +811,22 @@ def post_test(ctx, appname, dirs=['src'], remove=['*boost*', 'c++*']):
coverage_lcov.close()
coverage_log.close()
- if ctx.autowaf_tests[appname]['failed'] > 0:
- Logs.pprint('RED', '\nSummary: %d / %d %s tests failed' % (
- ctx.autowaf_tests[appname]['failed'],
- ctx.autowaf_tests[appname]['total'],
- appname))
- else:
- Logs.pprint('GREEN', '\nSummary: All %d %s tests passed' % (
- ctx.autowaf_tests[appname]['total'], appname))
-
+ duration = (time.clock() - ctx.autowaf_tests_start_time) * 1000.0
+ total_tests = ctx.autowaf_tests[appname]['total']
+ failed_tests = ctx.autowaf_tests[appname]['failed']
+ passed_tests = total_tests - failed_tests
+ Logs.pprint('GREEN', '\n[==========] %d tests from %s ran (%d ms total)' % (
+ total_tests, appname, duration))
if not ctx.env.NO_COVERAGE:
- Logs.pprint('GREEN', 'Coverage: <file://%s>\n'
+ Logs.pprint('GREEN', '[----------] Coverage: <file://%s>'
% os.path.abspath('coverage/index.html'))
- Logs.pprint('GREEN', ("Waf: Leaving directory `%s'" %
- os.path.abspath(os.getcwd())))
+ Logs.pprint('GREEN', '[ PASSED ] %d tests' % passed_tests)
+ if failed_tests > 0:
+ Logs.pprint('RED', '[ FAILED ] %d tests' % failed_tests)
+ raise TestFailed('Tests from %s failed' % appname)
+ Logs.pprint('', '')
+
top_level = (len(ctx.stack_path) > 1)
if top_level:
cd_to_orig_dir(ctx, top_level)
@@ -854,7 +860,7 @@ def run_test(ctx,
if isinstance(test, type([])):
s = ' '.join(test)
if header and not quiet:
- Logs.pprint('Green', '\n** Test %s' % s)
+ Logs.pprint('Green', '\n[ RUN ] %s' % s)
cmd = test
if Options.options.test_wrapper:
cmd = Options.options.test_wrapper + ' ' + test
@@ -869,17 +875,18 @@ def run_test(ctx,
success = desired_status is None or returncode == desired_status
if success:
if not quiet:
- Logs.pprint('GREEN', '** Pass %s' % name)
+ Logs.pprint('GREEN', '[ OK ] %s' % name)
else:
- Logs.pprint('RED', '** FAIL %s' % name)
+ Logs.pprint('RED', '[ FAILED ] %s' % name)
ctx.autowaf_tests_failed += 1
+ ctx.autowaf_local_tests_failed += 1
ctx.autowaf_tests[appname]['failed'] += 1
if type(test) != list and not callable(test):
Logs.pprint('RED', test)
if Options.options.verbose_tests and type(test) != list and not callable(test):
- sys.stdout.write(out[0])
- sys.stderr.write(out[1])
+ sys.stdout.write(out[0].decode('utf-8'))
+ sys.stderr.write(out[1].decode('utf-8'))
return (success, out)
@@ -892,7 +899,8 @@ def tests_name(ctx, appname, name='*'):
def begin_tests(ctx, appname, name='*'):
ctx.autowaf_local_tests_failed = 0
ctx.autowaf_local_tests_total = 0
- Logs.pprint('GREEN', '\n** Begin %s tests' % (
+ ctx.autowaf_local_tests_start_time = time.clock()
+ Logs.pprint('GREEN', '\n[----------] %s' % (
tests_name(ctx, appname, name)))
class Handle:
@@ -905,13 +913,15 @@ def begin_tests(ctx, appname, name='*'):
return Handle()
def end_tests(ctx, appname, name='*'):
+ duration = (time.clock() - ctx.autowaf_local_tests_start_time) * 1000.0
+ total = ctx.autowaf_local_tests_total
failures = ctx.autowaf_local_tests_failed
if failures == 0:
- Logs.pprint('GREEN', '** Passed all %d %s tests' % (
- ctx.autowaf_local_tests_total, tests_name(ctx, appname, name)))
+ Logs.pprint('GREEN', '[----------] %d tests from %s (%d ms total)' % (
+ ctx.autowaf_local_tests_total, tests_name(ctx, appname, name), duration))
else:
- Logs.pprint('RED', '** Failed %d / %d %s tests' % (
- failures, ctx.autowaf_local_tests_total, tests_name(ctx, appname, name)))
+ Logs.pprint('RED', '[----------] %d/%d tests from %s (%d ms total)' % (
+ total - failures, total, tests_name(ctx, appname, name), duration))
def run_tests(ctx,
appname,
diff --git a/waflib/extras/batched_cc.py b/extras/batched_cc.py
index aad2872..aad2872 100644
--- a/waflib/extras/batched_cc.py
+++ b/extras/batched_cc.py
diff --git a/waflib/extras/biber.py b/extras/biber.py
index fd9db4e..fd9db4e 100644
--- a/waflib/extras/biber.py
+++ b/extras/biber.py
diff --git a/waflib/extras/bjam.py b/extras/bjam.py
index 8e04d3a..8e04d3a 100644
--- a/waflib/extras/bjam.py
+++ b/extras/bjam.py
diff --git a/waflib/extras/blender.py b/extras/blender.py
index e5efc28..e5efc28 100644
--- a/waflib/extras/blender.py
+++ b/extras/blender.py
diff --git a/waflib/extras/boo.py b/extras/boo.py
index 06623d4..06623d4 100644
--- a/waflib/extras/boo.py
+++ b/extras/boo.py
diff --git a/waflib/extras/boost.py b/extras/boost.py
index c2aaaa9..c2aaaa9 100644
--- a/waflib/extras/boost.py
+++ b/extras/boost.py
diff --git a/waflib/extras/build_file_tracker.py b/extras/build_file_tracker.py
index c4f26fd..c4f26fd 100644
--- a/waflib/extras/build_file_tracker.py
+++ b/extras/build_file_tracker.py
diff --git a/waflib/extras/build_logs.py b/extras/build_logs.py
index cdf8ed0..cdf8ed0 100644
--- a/waflib/extras/build_logs.py
+++ b/extras/build_logs.py
diff --git a/waflib/extras/buildcopy.py b/extras/buildcopy.py
index a6d9ac8..a6d9ac8 100644
--- a/waflib/extras/buildcopy.py
+++ b/extras/buildcopy.py
diff --git a/waflib/extras/c_bgxlc.py b/extras/c_bgxlc.py
index 6e3eaf7..6e3eaf7 100644
--- a/waflib/extras/c_bgxlc.py
+++ b/extras/c_bgxlc.py
diff --git a/waflib/extras/c_dumbpreproc.py b/extras/c_dumbpreproc.py
index ce9e1a4..ce9e1a4 100644
--- a/waflib/extras/c_dumbpreproc.py
+++ b/extras/c_dumbpreproc.py
diff --git a/waflib/extras/c_emscripten.py b/extras/c_emscripten.py
index e1ac494..e1ac494 100644
--- a/waflib/extras/c_emscripten.py
+++ b/extras/c_emscripten.py
diff --git a/waflib/extras/c_nec.py b/extras/c_nec.py
index 96bfae4..96bfae4 100644
--- a/waflib/extras/c_nec.py
+++ b/extras/c_nec.py
diff --git a/waflib/extras/cabal.py b/extras/cabal.py
index e10a0d1..e10a0d1 100644
--- a/waflib/extras/cabal.py
+++ b/extras/cabal.py
diff --git a/waflib/extras/cfg_altoptions.py b/extras/cfg_altoptions.py
index 47b1189..47b1189 100644
--- a/waflib/extras/cfg_altoptions.py
+++ b/extras/cfg_altoptions.py
diff --git a/waflib/extras/clang_compilation_database.py b/extras/clang_compilation_database.py
index 4d9b5e2..4d9b5e2 100644
--- a/waflib/extras/clang_compilation_database.py
+++ b/extras/clang_compilation_database.py
diff --git a/waflib/extras/codelite.py b/extras/codelite.py
index 523302c..523302c 100644
--- a/waflib/extras/codelite.py
+++ b/extras/codelite.py
diff --git a/waflib/extras/color_gcc.py b/extras/color_gcc.py
index b68c5eb..b68c5eb 100644
--- a/waflib/extras/color_gcc.py
+++ b/extras/color_gcc.py
diff --git a/waflib/extras/color_rvct.py b/extras/color_rvct.py
index f89ccbd..f89ccbd 100644
--- a/waflib/extras/color_rvct.py
+++ b/extras/color_rvct.py
diff --git a/waflib/extras/compat15.py b/extras/compat15.py
index 0e74df8..0e74df8 100644
--- a/waflib/extras/compat15.py
+++ b/extras/compat15.py
diff --git a/waflib/extras/cppcheck.py b/extras/cppcheck.py
index 13ff424..13ff424 100644
--- a/waflib/extras/cppcheck.py
+++ b/extras/cppcheck.py
diff --git a/waflib/extras/cpplint.py b/extras/cpplint.py
index e3302e5..e3302e5 100644
--- a/waflib/extras/cpplint.py
+++ b/extras/cpplint.py
diff --git a/waflib/extras/cross_gnu.py b/extras/cross_gnu.py
index 309f53b..309f53b 100644
--- a/waflib/extras/cross_gnu.py
+++ b/extras/cross_gnu.py
diff --git a/waflib/extras/cython.py b/extras/cython.py
index 481d6f4..481d6f4 100644
--- a/waflib/extras/cython.py
+++ b/extras/cython.py
diff --git a/waflib/extras/dcc.py b/extras/dcc.py
index c1a57c0..c1a57c0 100644
--- a/waflib/extras/dcc.py
+++ b/extras/dcc.py
diff --git a/waflib/extras/distnet.py b/extras/distnet.py
index 09a31a6..09a31a6 100644
--- a/waflib/extras/distnet.py
+++ b/extras/distnet.py
diff --git a/waflib/extras/doxygen.py b/extras/doxygen.py
index 28f56e9..28f56e9 100644
--- a/waflib/extras/doxygen.py
+++ b/extras/doxygen.py
diff --git a/waflib/extras/dpapi.py b/extras/dpapi.py
index b94d482..b94d482 100644
--- a/waflib/extras/dpapi.py
+++ b/extras/dpapi.py
diff --git a/waflib/extras/eclipse.py b/extras/eclipse.py
index bb78741..bb78741 100644
--- a/waflib/extras/eclipse.py
+++ b/extras/eclipse.py
diff --git a/waflib/extras/erlang.py b/extras/erlang.py
index 49f6d5b..49f6d5b 100644
--- a/waflib/extras/erlang.py
+++ b/extras/erlang.py
diff --git a/waflib/extras/fast_partial.py b/extras/fast_partial.py
index b3af513..b3af513 100644
--- a/waflib/extras/fast_partial.py
+++ b/extras/fast_partial.py
diff --git a/waflib/extras/fc_bgxlf.py b/extras/fc_bgxlf.py
index cca1810..cca1810 100644
--- a/waflib/extras/fc_bgxlf.py
+++ b/extras/fc_bgxlf.py
diff --git a/waflib/extras/fc_cray.py b/extras/fc_cray.py
index da733fa..da733fa 100644
--- a/waflib/extras/fc_cray.py
+++ b/extras/fc_cray.py
diff --git a/waflib/extras/fc_nag.py b/extras/fc_nag.py
index edcb218..edcb218 100644
--- a/waflib/extras/fc_nag.py
+++ b/extras/fc_nag.py
diff --git a/waflib/extras/fc_nec.py b/extras/fc_nec.py
index 67c8680..67c8680 100644
--- a/waflib/extras/fc_nec.py
+++ b/extras/fc_nec.py
diff --git a/waflib/extras/fc_open64.py b/extras/fc_open64.py
index 413719f..413719f 100644
--- a/waflib/extras/fc_open64.py
+++ b/extras/fc_open64.py
diff --git a/waflib/extras/fc_pgfortran.py b/extras/fc_pgfortran.py
index afb2817..afb2817 100644
--- a/waflib/extras/fc_pgfortran.py
+++ b/extras/fc_pgfortran.py
diff --git a/waflib/extras/fc_solstudio.py b/extras/fc_solstudio.py
index 53766df..53766df 100644
--- a/waflib/extras/fc_solstudio.py
+++ b/extras/fc_solstudio.py
diff --git a/waflib/extras/fc_xlf.py b/extras/fc_xlf.py
index 5a3da03..5a3da03 100644
--- a/waflib/extras/fc_xlf.py
+++ b/extras/fc_xlf.py
diff --git a/waflib/extras/file_to_object.py b/extras/file_to_object.py
index 1393b51..1393b51 100644
--- a/waflib/extras/file_to_object.py
+++ b/extras/file_to_object.py
diff --git a/waflib/extras/fluid.py b/extras/fluid.py
index 4814a35..4814a35 100644
--- a/waflib/extras/fluid.py
+++ b/extras/fluid.py
diff --git a/waflib/extras/freeimage.py b/extras/freeimage.py
index f27e525..f27e525 100644
--- a/waflib/extras/freeimage.py
+++ b/extras/freeimage.py
diff --git a/waflib/extras/fsb.py b/extras/fsb.py
index 1b8f398..1b8f398 100644
--- a/waflib/extras/fsb.py
+++ b/extras/fsb.py
diff --git a/waflib/extras/fsc.py b/extras/fsc.py
index c67e70b..c67e70b 100644
--- a/waflib/extras/fsc.py
+++ b/extras/fsc.py
diff --git a/waflib/extras/gccdeps.py b/extras/gccdeps.py
index d9758ab..d9758ab 100644
--- a/waflib/extras/gccdeps.py
+++ b/extras/gccdeps.py
diff --git a/waflib/extras/gdbus.py b/extras/gdbus.py
index 0e0476e..0e0476e 100644
--- a/waflib/extras/gdbus.py
+++ b/extras/gdbus.py
diff --git a/waflib/extras/gob2.py b/extras/gob2.py
index b4fa3b9..b4fa3b9 100644
--- a/waflib/extras/gob2.py
+++ b/extras/gob2.py
diff --git a/waflib/extras/halide.py b/extras/halide.py
index 6078e38..6078e38 100644
--- a/waflib/extras/halide.py
+++ b/extras/halide.py
diff --git a/waflib/extras/javatest.py b/extras/javatest.py
index 979b8d8..979b8d8 100755
--- a/waflib/extras/javatest.py
+++ b/extras/javatest.py
diff --git a/waflib/extras/kde4.py b/extras/kde4.py
index e49a9ec..e49a9ec 100644
--- a/waflib/extras/kde4.py
+++ b/extras/kde4.py
diff --git a/waflib/extras/local_rpath.py b/extras/local_rpath.py
index b2507e1..b2507e1 100644
--- a/waflib/extras/local_rpath.py
+++ b/extras/local_rpath.py
diff --git a/waflib/extras/lv2.py b/extras/lv2.py
index 815987f..815987f 100644
--- a/waflib/extras/lv2.py
+++ b/extras/lv2.py
diff --git a/waflib/extras/make.py b/extras/make.py
index 933d9ca..933d9ca 100644
--- a/waflib/extras/make.py
+++ b/extras/make.py
diff --git a/waflib/extras/midl.py b/extras/midl.py
index 43e6cf9..43e6cf9 100644
--- a/waflib/extras/midl.py
+++ b/extras/midl.py
diff --git a/waflib/extras/msvcdeps.py b/extras/msvcdeps.py
index fc1ecd4..fc1ecd4 100644
--- a/waflib/extras/msvcdeps.py
+++ b/extras/msvcdeps.py
diff --git a/waflib/extras/msvs.py b/extras/msvs.py
index 8aa2db0..8aa2db0 100644
--- a/waflib/extras/msvs.py
+++ b/extras/msvs.py
diff --git a/waflib/extras/netcache_client.py b/extras/netcache_client.py
index dc49048..dc49048 100644
--- a/waflib/extras/netcache_client.py
+++ b/extras/netcache_client.py
diff --git a/waflib/extras/objcopy.py b/extras/objcopy.py
index 82d8359..82d8359 100644
--- a/waflib/extras/objcopy.py
+++ b/extras/objcopy.py
diff --git a/waflib/extras/ocaml.py b/extras/ocaml.py
index afe73c0..afe73c0 100644
--- a/waflib/extras/ocaml.py
+++ b/extras/ocaml.py
diff --git a/waflib/extras/package.py b/extras/package.py
index c06498e..c06498e 100644
--- a/waflib/extras/package.py
+++ b/extras/package.py
diff --git a/waflib/extras/parallel_debug.py b/extras/parallel_debug.py
index 35883a3..35883a3 100644
--- a/waflib/extras/parallel_debug.py
+++ b/extras/parallel_debug.py
diff --git a/waflib/extras/pch.py b/extras/pch.py
index 103e752..103e752 100644
--- a/waflib/extras/pch.py
+++ b/extras/pch.py
diff --git a/waflib/extras/pep8.py b/extras/pep8.py
index 676beed..676beed 100644
--- a/waflib/extras/pep8.py
+++ b/extras/pep8.py
diff --git a/waflib/extras/pgicc.py b/extras/pgicc.py
index 9790b9c..9790b9c 100644
--- a/waflib/extras/pgicc.py
+++ b/extras/pgicc.py
diff --git a/waflib/extras/pgicxx.py b/extras/pgicxx.py
index eae121c..eae121c 100644
--- a/waflib/extras/pgicxx.py
+++ b/extras/pgicxx.py
diff --git a/waflib/extras/proc.py b/extras/proc.py
index 764abec..764abec 100644
--- a/waflib/extras/proc.py
+++ b/extras/proc.py
diff --git a/waflib/extras/protoc.py b/extras/protoc.py
index f3cb4d8..f3cb4d8 100644
--- a/waflib/extras/protoc.py
+++ b/extras/protoc.py
diff --git a/waflib/extras/pyqt5.py b/extras/pyqt5.py
index c21dfa7..c21dfa7 100644
--- a/waflib/extras/pyqt5.py
+++ b/extras/pyqt5.py
diff --git a/waflib/extras/pytest.py b/extras/pytest.py
index 7dd5a1a..7dd5a1a 100644
--- a/waflib/extras/pytest.py
+++ b/extras/pytest.py
diff --git a/waflib/extras/qnxnto.py b/extras/qnxnto.py
index 1158124..1158124 100644
--- a/waflib/extras/qnxnto.py
+++ b/extras/qnxnto.py
diff --git a/waflib/extras/qt4.py b/extras/qt4.py
index 90cae7e..90cae7e 100644
--- a/waflib/extras/qt4.py
+++ b/extras/qt4.py
diff --git a/waflib/extras/relocation.py b/extras/relocation.py
index 7e821f4..7e821f4 100644
--- a/waflib/extras/relocation.py
+++ b/extras/relocation.py
diff --git a/waflib/extras/remote.py b/extras/remote.py
index 3b038f7..3b038f7 100644
--- a/waflib/extras/remote.py
+++ b/extras/remote.py
diff --git a/waflib/extras/resx.py b/extras/resx.py
index caf4d31..caf4d31 100644
--- a/waflib/extras/resx.py
+++ b/extras/resx.py
diff --git a/waflib/extras/review.py b/extras/review.py
index 561e062..561e062 100644
--- a/waflib/extras/review.py
+++ b/extras/review.py
diff --git a/waflib/extras/rst.py b/extras/rst.py
index f3c3a5e..f3c3a5e 100644
--- a/waflib/extras/rst.py
+++ b/extras/rst.py
diff --git a/waflib/extras/run_do_script.py b/extras/run_do_script.py
index f3c5812..f3c5812 100644
--- a/waflib/extras/run_do_script.py
+++ b/extras/run_do_script.py
diff --git a/waflib/extras/run_m_script.py b/extras/run_m_script.py
index b5f27eb..b5f27eb 100644
--- a/waflib/extras/run_m_script.py
+++ b/extras/run_m_script.py
diff --git a/waflib/extras/run_py_script.py b/extras/run_py_script.py
index 3670381..3670381 100644
--- a/waflib/extras/run_py_script.py
+++ b/extras/run_py_script.py
diff --git a/waflib/extras/run_r_script.py b/extras/run_r_script.py
index b0d8f2b..b0d8f2b 100644
--- a/waflib/extras/run_r_script.py
+++ b/extras/run_r_script.py
diff --git a/waflib/extras/sas.py b/extras/sas.py
index 754c614..754c614 100644
--- a/waflib/extras/sas.py
+++ b/extras/sas.py
diff --git a/waflib/extras/satellite_assembly.py b/extras/satellite_assembly.py
index 005eb07..005eb07 100644
--- a/waflib/extras/satellite_assembly.py
+++ b/extras/satellite_assembly.py
diff --git a/waflib/extras/scala.py b/extras/scala.py
index a9880f0..a9880f0 100644
--- a/waflib/extras/scala.py
+++ b/extras/scala.py
diff --git a/waflib/extras/slow_qt4.py b/extras/slow_qt4.py
index ec7880b..ec7880b 100644
--- a/waflib/extras/slow_qt4.py
+++ b/extras/slow_qt4.py
diff --git a/waflib/extras/softlink_libs.py b/extras/softlink_libs.py
index 50c777f..50c777f 100644
--- a/waflib/extras/softlink_libs.py
+++ b/extras/softlink_libs.py
diff --git a/waflib/extras/stale.py b/extras/stale.py
index cac3f46..cac3f46 100644
--- a/waflib/extras/stale.py
+++ b/extras/stale.py
diff --git a/waflib/extras/stracedeps.py b/extras/stracedeps.py
index 37d82cb..37d82cb 100644
--- a/waflib/extras/stracedeps.py
+++ b/extras/stracedeps.py
diff --git a/waflib/extras/swig.py b/extras/swig.py
index fd3d6d2..fd3d6d2 100644
--- a/waflib/extras/swig.py
+++ b/extras/swig.py
diff --git a/waflib/extras/syms.py b/extras/syms.py
index dfa0059..dfa0059 100644
--- a/waflib/extras/syms.py
+++ b/extras/syms.py
diff --git a/waflib/extras/ticgt.py b/extras/ticgt.py
index f43a7ea..f43a7ea 100644
--- a/waflib/extras/ticgt.py
+++ b/extras/ticgt.py
diff --git a/waflib/extras/unity.py b/extras/unity.py
index 78128ed..78128ed 100644
--- a/waflib/extras/unity.py
+++ b/extras/unity.py
diff --git a/waflib/extras/use_config.py b/extras/use_config.py
index ef5129f..ef5129f 100644
--- a/waflib/extras/use_config.py
+++ b/extras/use_config.py
diff --git a/waflib/extras/valadoc.py b/extras/valadoc.py
index c50f69e..c50f69e 100644
--- a/waflib/extras/valadoc.py
+++ b/extras/valadoc.py
diff --git a/waflib/extras/waf_xattr.py b/extras/waf_xattr.py
index 351dd63..351dd63 100644
--- a/waflib/extras/waf_xattr.py
+++ b/extras/waf_xattr.py
diff --git a/waflib/extras/why.py b/extras/why.py
index 1bb941f..1bb941f 100644
--- a/waflib/extras/why.py
+++ b/extras/why.py
diff --git a/waflib/extras/win32_opts.py b/extras/win32_opts.py
index 9f7443c..9f7443c 100644
--- a/waflib/extras/win32_opts.py
+++ b/extras/win32_opts.py
diff --git a/waflib/extras/wix.py b/extras/wix.py
index d87bfbb..d87bfbb 100644
--- a/waflib/extras/wix.py
+++ b/extras/wix.py
diff --git a/waflib/extras/xcode6.py b/extras/xcode6.py
index 91bbff1..91bbff1 100644
--- a/waflib/extras/xcode6.py
+++ b/extras/xcode6.py
diff --git a/waflib/fixpy2.py b/fixpy2.py
index 24176e0..24176e0 100644
--- a/waflib/fixpy2.py
+++ b/fixpy2.py
diff --git a/ganv.pc.in b/ganv.pc.in
deleted file mode 100644
index 3edf190..0000000
--- a/ganv.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@PREFIX@
-exec_prefix=@EXEC_PREFIX@
-libdir=@LIBDIR@
-includedir=@INCLUDEDIR@
-
-Name: ganv
-Version: @GANV_VERSION@
-Description: A Gtk canvas widget for graph based interfaces
-Requires: gtk+-2.0
-Libs: -L${libdir} -l@LIB_GANV@
-Cflags: -I${includedir}/ganv-@GANV_MAJOR_VERSION@
diff --git a/ganv/Box.hpp b/ganv/Box.hpp
deleted file mode 100644
index 1b95859..0000000
--- a/ganv/Box.hpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2015 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_BOX_HPP
-#define GANV_BOX_HPP
-
-#include "ganv/Node.hpp"
-#include "ganv/box.h"
-
-namespace Ganv {
-
-class Box : public Node
-{
-public:
- Box(Canvas* canvas, GanvBox* gobj)
- : Node(canvas, GANV_NODE(gobj))
- {}
-
- RW_PROPERTY(const char*, label)
- RW_PROPERTY(gboolean, beveled)
-
- METHODRET0(ganv_box, double, get_x1)
- METHODRET0(ganv_box, double, get_y1)
- METHODRET0(ganv_box, double, get_x2)
- METHODRET0(ganv_box, double, get_y2)
- METHODRET0(ganv_box, double, get_width)
- METHOD1(ganv_box, set_width, double, width)
- METHODRET0(ganv_box, double, get_height)
- METHOD1(ganv_box, set_height, double, height)
- METHODRET0(ganv_box, double, get_border_width)
-
- GanvBox* gobj() { return GANV_BOX(_gobj); }
- const GanvBox* gobj() const { return GANV_BOX(_gobj); }
-};
-
-} // namespace Ganv
-
-#endif // GANV_BOX_HPP
diff --git a/ganv/Canvas.hpp b/ganv/Canvas.hpp
deleted file mode 100644
index 8db1f66..0000000
--- a/ganv/Canvas.hpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2015 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_CANVAS_HPP
-#define GANV_CANVAS_HPP
-
-#include <string>
-
-#include <glib.h>
-#include <glibmm.h>
-#include <gtkmm/layout.h>
-
-#include "ganv/canvas.h"
-#include "ganv/wrap.hpp"
-
-/** Ganv namespace, everything is defined under this.
- *
- * @ingroup Ganv
- */
-namespace Ganv {
-
-class Edge;
-class Item;
-class Node;
-class Port;
-
-/** @defgroup Ganv Ganv
- *
- * A canvas widget for graph-like UIs.
- */
-
-/** The 'master' canvas widget which contains all other objects.
- *
- * Applications must override some virtual methods to make the widget actually
- * do anything (e.g. connect).
- *
- * @ingroup Ganv
- */
-class Canvas
-{
-public:
- Canvas(double width, double height);
- virtual ~Canvas();
-
- GanvItem* root() { return ganv_canvas_root(gobj()); }
-
- METHOD0(ganv_canvas, clear);
- METHODRET0(ganv_canvas, gboolean, empty)
- METHOD2(ganv_canvas, resize, double, width, double, height);
- METHOD4(ganv_canvas, set_scroll_region, double, x1, double, y1, double, x2, double, y2);
- METHOD4(ganv_canvas, get_scroll_region, double*, x1, double*, y1, double*, x2, double*, y2);
- METHOD1(ganv_canvas, set_center_scroll_region, gboolean, c);
- METHODRET0(ganv_canvas, gboolean, get_center_scroll_region);
- METHOD2(ganv_canvas, scroll_to, int, x, int, y);
-
- void get_scroll_offsets(int& cx, int& cy) const {
- ganv_canvas_get_scroll_offsets(gobj(), &cx, &cy);
- }
-
- METHOD1(ganv_canvas, w2c_affine, cairo_matrix_t*, matrix);
- METHOD4(ganv_canvas, w2c, double, wx, double, wy, int*, cx, int*, cy);
- METHOD4(ganv_canvas, w2c_d, double, wx, double, wy, double*, cx, double*, cy);
- METHOD4(ganv_canvas, c2w, int, cx, int, cy, double*, wx, double*, wy);
- METHOD4(ganv_canvas, window_to_world, double, winx, double, winy, double*, worldx, double*, worldy);
- METHOD4(ganv_canvas, world_to_window, double, worldx, double, worldy, double*, winx, double*, winy);
-
- Item* get_item_at(double x, double y) const;
- Edge* get_edge(Node* tail, Node* head) const;
- void remove_edge_between(Node* tail, Node* head);
- void remove_edge(Edge* edge);
-
- METHOD0(ganv_canvas, arrange);
- METHODRET2(ganv_canvas, int, export_image, const char*, filename, bool, draw_background);
- METHOD1(ganv_canvas, export_dot, const char*, filename);
- METHODRET0(ganv_canvas, gboolean, supports_sprung_layout);
- METHODRET1(ganv_canvas, gboolean, set_sprung_layout, gboolean, sprung_layout);
- METHOD2(ganv_canvas, for_each_node, GanvNodeFunc, f, void*, data)
- METHOD2(ganv_canvas, for_each_selected_node, GanvNodeFunc, f, void*, data)
- METHOD2(ganv_canvas, for_each_edge, GanvEdgeFunc, f, void*, data)
- METHOD3(ganv_canvas, for_each_edge_from,
- const GanvNode*, tail,
- GanvEdgeFunc, f,
- void*, data);
- METHOD3(ganv_canvas, for_each_edge_to,
- const GanvNode*, head,
- GanvEdgeFunc, f,
- void*, data);
- METHOD3(ganv_canvas, for_each_edge_on,
- const GanvNode*, node,
- GanvEdgeFunc, f,
- void*, data);
- METHOD2(ganv_canvas, for_each_selected_edge, GanvEdgeFunc, f, void*, data)
-
- METHOD0(ganv_canvas, select_all);
- METHOD0(ganv_canvas, clear_selection);
- METHODRET0(ganv_canvas, double, get_zoom);
- METHOD1(ganv_canvas, set_zoom, double, pix_per_unit);
- METHOD0(ganv_canvas, zoom_full);
- METHODRET0(ganv_canvas, double, get_default_font_size)
- METHODRET0(ganv_canvas, double, get_font_size)
- METHOD1(ganv_canvas, set_font_size, double, points);
- METHOD0(ganv_canvas, get_move_cursor);
- METHOD2(ganv_canvas, move_contents_to, double, x, double, y);
-
- RW_PROPERTY(gboolean, locked)
- RW_PROPERTY(double, width)
- RW_PROPERTY(double, height)
- RW_PROPERTY(GanvDirection, direction)
-
- void set_port_order(GanvPortOrderFunc port_cmp, void* data) {
- ganv_canvas_set_port_order(gobj(), port_cmp, data);
- }
-
- Gtk::Layout& widget() {
- return *Glib::wrap(&_gobj->layout);
- }
-
- GQuark wrapper_key();
-
- GanvCanvas* gobj() { return GANV_CANVAS(_gobj); }
- const GanvCanvas* gobj() const { return GANV_CANVAS(_gobj); }
-
- sigc::signal<bool, GdkEvent*> signal_event;
- sigc::signal<void, Node*, Node*> signal_connect;
- sigc::signal<void, Node*, Node*> signal_disconnect;
-
-private:
- Canvas(const Canvas&); ///< Noncopyable
- const Canvas& operator=(const Canvas&); ///< Noncopyable
-
- GanvCanvas* const _gobj;
-};
-
-} // namespace Ganv
-
-namespace Glib {
-
-static inline Ganv::Canvas*
-wrap(GanvCanvas* canvas)
-{
- return (Ganv::Canvas*)ganv_canvas_get_wrapper(canvas);
-}
-
-} // namespace Glib
-
-#endif // GANV_CANVAS_HPP
diff --git a/ganv/Circle.hpp b/ganv/Circle.hpp
deleted file mode 100644
index ab47669..0000000
--- a/ganv/Circle.hpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2013 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_CIRCLE_HPP
-#define GANV_CIRCLE_HPP
-
-#include <algorithm>
-#include <map>
-#include <string>
-#include <stdint.h>
-
-#include <gdkmm/types.h>
-
-#include "ganv/types.hpp"
-#include "ganv/Node.hpp"
-#include "ganv/circle.h"
-
-GANV_GLIB_WRAP(Circle)
-
-namespace Ganv {
-
-class Canvas;
-
-/** An elliptical Item which is Node.
- *
- * Unlike a Module, this doesn't contain ports, but is directly joinable itself
- * (think your classic circles 'n' lines diagram, ala FSM).
- *
- * @ingroup Ganv
- */
-class Circle : public Node
-{
-public:
- static const uint32_t FILL_COLOUR = 0x1E2224FF;
- static const uint32_t BORDER_COLOUR = 0xD3D7CFFF;
-
- Circle(Canvas& canvas,
- const std::string& name,
- double x,
- double y)
- : Node(&canvas,
- GANV_NODE(
- ganv_item_new(
- GANV_ITEM(canvas.root()),
- ganv_circle_get_type(),
- "x", x,
- "y", y,
- "can-tail", TRUE,
- "can-head", TRUE,
- "fill-color", FILL_COLOUR,
- "border-color", BORDER_COLOUR,
- "label", name.c_str(),
- "draggable", TRUE,
- NULL)))
- {}
-
- RW_PROPERTY(double, radius)
- RW_PROPERTY(double, radius_ems)
- RW_PROPERTY(gboolean, fit_label)
-
- GanvCircle* gobj() { return GANV_CIRCLE(_gobj); }
- const GanvCircle* gobj() const { return GANV_CIRCLE(_gobj); }
-};
-
-} // namespace Ganv
-
-#endif // GANV_CIRCLE_HPP
diff --git a/ganv/Edge.hpp b/ganv/Edge.hpp
deleted file mode 100644
index a01de44..0000000
--- a/ganv/Edge.hpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2015 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_EDGE_HPP
-#define GANV_EDGE_HPP
-
-#include <stdint.h>
-
-#include <gdk/gdkevents.h>
-
-#include "ganv/Canvas.hpp"
-#include "ganv/Item.hpp"
-#include "ganv/Node.hpp"
-#include "ganv/edge.h"
-
-GANV_GLIB_WRAP(Edge)
-
-namespace Ganv {
-
-class Canvas;
-
-/** A edge (line) between two Node objects.
- *
- * @ingroup Ganv
- */
-class Edge : public Item
-{
-public:
- Edge(Canvas& canvas,
- Node* tail,
- Node* head,
- uint32_t color = 0,
- bool show_arrowhead = false,
- bool curved = true)
- : Item(GANV_ITEM(ganv_edge_new(canvas.gobj(),
- tail->gobj(),
- head->gobj(),
- "color", color,
- "curved", (gboolean)curved,
- "arrowhead", (gboolean)show_arrowhead,
- NULL)))
- {}
-
- Edge(GanvEdge* gobj)
- : Item(GANV_ITEM(gobj))
- {}
-
- virtual ~Edge() {
- if (_gobj && ganv_item_get_parent(_gobj)) {
- g_object_unref(_gobj);
- }
- }
-
- gboolean is_within(double x1, double y1, double x2, double y2) const {
- return ganv_edge_is_within(gobj(), x1, y1, x2, y2);
- }
-
- RW_PROPERTY(gboolean, constraining)
- RW_PROPERTY(gboolean, curved)
- RW_PROPERTY(gboolean, selected)
- RW_PROPERTY(gboolean, highlighted)
- RW_PROPERTY(guint, color)
- RW_PROPERTY(gdouble, handle_radius)
-
- METHODRETWRAP0(ganv_edge, Node*, get_tail);
- METHODRETWRAP0(ganv_edge, Node*, get_head);
-
- GanvEdge* gobj() { return (GanvEdge*)_gobj; }
- const GanvEdge* gobj() const { return (GanvEdge*)_gobj; }
-
-private:
- Edge(const Edge& copy);
- Edge& operator=(const Edge& other);
-};
-
-} // namespace Ganv
-
-#endif // GANV_EDGE_HPP
diff --git a/ganv/Item.hpp b/ganv/Item.hpp
deleted file mode 100644
index 680b991..0000000
--- a/ganv/Item.hpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2015 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_ITEM_HPP
-#define GANV_ITEM_HPP
-
-#include <assert.h>
-
-#include <glib.h>
-
-#include <sigc++/signal.h>
-#include <sigc++/trackable.h>
-
-#include "ganv/Canvas.hpp"
-#include "ganv/item.h"
-#include "ganv/wrap.hpp"
-
-GANV_GLIB_WRAP(Item)
-
-namespace Ganv {
-
-class Canvas;
-
-/** An item on the canvas.
- */
-class Item : public sigc::trackable {
-public:
- Item(GanvItem* gobj)
- : _gobj(gobj)
- {
- ganv_item_set_wrapper(gobj, this);
- if (gobj && ganv_item_get_parent(gobj)) {
- g_signal_connect(
- G_OBJECT(_gobj), "event", G_CALLBACK(on_item_event), this);
- }
- }
-
- virtual ~Item() {
- gtk_object_destroy(GTK_OBJECT(_gobj));
- }
-
- RW_PROPERTY(double, x)
- RW_PROPERTY(double, y)
-
- METHOD0(ganv_item, raise);
- METHOD0(ganv_item, lower);
- METHOD2(ganv_item, move, double, dx, double, dy);
- METHOD0(ganv_item, show);
- METHOD0(ganv_item, hide);
- METHOD2(ganv_item, i2w, double*, x, double*, y);
- METHOD2(ganv_item, w2i, double*, x, double*, y);
- METHOD0(ganv_item, grab_focus);
-
- Canvas* canvas() const {
- return Glib::wrap(ganv_item_get_canvas(_gobj));
- }
-
- GanvItem* gobj() const { return _gobj; }
-
- SIGNAL1(event, GdkEvent*)
- SIGNAL1(click, GdkEventButton*)
-
-protected:
- GanvItem* const _gobj;
-
-private:
- static gboolean
- on_item_event(GanvItem* canvasitem,
- GdkEvent* ev,
- void* item)
- {
- return ((Item*)item)->signal_event().emit(ev);
- }
-};
-
-} // namespace Ganv
-
-#endif // GANV_ITEM_HPP
diff --git a/ganv/Module.hpp b/ganv/Module.hpp
deleted file mode 100644
index 8ca4393..0000000
--- a/ganv/Module.hpp
+++ /dev/null
@@ -1,130 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2015 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_MODULE_HPP
-#define GANV_MODULE_HPP
-
-#include <string>
-#include <vector>
-
-#include <gtkmm/container.h>
-
-#include "ganv/Canvas.hpp"
-#include "ganv/Node.hpp"
-#include "ganv/Port.hpp"
-#include "ganv/module.h"
-
-GANV_GLIB_WRAP(Module)
-
-namespace Ganv {
-
-class Canvas;
-
-/** A rectangular Item which can hold a Port.
- *
- * @ingroup Ganv
- */
-class Module : public Box
-{
-public:
- Module(Canvas& canvas,
- const std::string& name,
- double x = 0,
- double y = 0,
- bool show_title = true)
- : Box(&canvas,
- GANV_BOX(ganv_item_new(GANV_ITEM(canvas.root()),
- ganv_module_get_type(),
- "x", x,
- "y", y,
- "can-tail", FALSE,
- "can-head", FALSE,
- "radius-tl", 4.0,
- "radius-tr", 4.0,
- "radius-br", 4.0,
- "radius-bl", 4.0,
- "border-width", 2.0,
- "label", name.c_str(),
- "draggable", TRUE,
- NULL)))
- {}
-
- template<typename P, typename C>
- class iterator_base {
- public:
- iterator_base(GanvModule* m, guint i) : _module(m), _index(i) {}
- template<typename T, typename U>
- iterator_base(const iterator_base<T, U>& i)
- : _module(i._module)
- , _index(i._index)
- {}
- P* operator*() const {
- return Glib::wrap(ganv_module_get_port(_module, _index));
- }
- P* operator->() const {
- return Glib::wrap(ganv_module_get_port(_module, _index));
- }
- iterator_base operator++(int) const {
- return iterator_base<P, C>(_index + 1);
- }
- iterator_base& operator++() {
- ++_index; return *this;
- }
- bool operator==(const iterator_base<P, C>& i) const {
- return _index == i._index;
- }
- bool operator!=(const iterator_base<P, C>& i) const {
- return _index != i._index;
- }
- private:
- template<typename T, typename U> friend class iterator_base;
- GanvModule* _module;
- guint _index;
- };
-
- typedef iterator_base<Port, GanvPort> iterator;
- typedef iterator_base<const Port, const GanvPort> const_iterator;
-
- iterator begin() { return iterator(gobj(), 0); }
- iterator end() { return iterator(gobj(), num_ports()); }
- iterator back() { return iterator(gobj(), num_ports() - 1); }
- const_iterator begin() const { return iterator(const_cast<GanvModule*>(gobj()), 0); }
- const_iterator end() const { return iterator(const_cast<GanvModule*>(gobj()), num_ports()); }
- const_iterator back() const { return iterator(const_cast<GanvModule*>(gobj()), num_ports() - 1); }
-
- void embed(Gtk::Widget* widget) {
- ganv_module_embed(gobj(), widget ? widget->gobj() : NULL);
- }
-
- Port* get_port(guint index) {
- return Glib::wrap(ganv_module_get_port(gobj(), index));
- }
-
- METHOD2(ganv_module, for_each_port, GanvPortFunc, f, void*, data);
-
- METHODRET0(ganv_module, guint, num_ports);
-
- RW_PROPERTY(gboolean, stacked)
-
- METHODRET0(ganv_module, double, get_empty_port_breadth)
- METHODRET0(ganv_module, double, get_empty_port_depth)
-
- GanvModule* gobj() { return GANV_MODULE(_gobj); }
- const GanvModule* gobj() const { return GANV_MODULE(_gobj); }
-};
-
-} // namespace Ganv
-
-#endif // GANV_MODULE_HPP
diff --git a/ganv/Node.hpp b/ganv/Node.hpp
deleted file mode 100644
index 2fef74c..0000000
--- a/ganv/Node.hpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2015 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_NODE_HPP
-#define GANV_NODE_HPP
-
-#include <glib.h>
-#include <assert.h>
-
-#include "ganv/node.h"
-#include "ganv/Item.hpp"
-
-GANV_GLIB_WRAP(Node)
-
-namespace Ganv {
-
-class Canvas;
-class Node;
-
-/** An object a Edge can connect to.
- */
-class Node : public Item {
-public:
- Node(Canvas* canvas, GanvNode* gobj)
- : Item(GANV_ITEM(g_object_ref(gobj)))
- {
- g_signal_connect(gobj, "moved", G_CALLBACK(on_moved), this);
- CONNECT_PROP_SIGNAL(gobj, selected, on_notify_bool, &Node::on_selected)
- }
-
- ~Node() {
- g_object_unref(_gobj);
- }
-
- RW_PROPERTY(gboolean, can_tail)
- RW_PROPERTY(gboolean, can_head)
- RW_PROPERTY(gboolean, is_source)
-
- gboolean is_within(double x1, double y1, double x2, double y2) const {
- return ganv_node_is_within(gobj(), x1, y1, x2, y2);
- }
-
- RW_PROPERTY(const char*, label)
- RW_PROPERTY(double, border_width)
- RW_PROPERTY(double, dash_length)
- RW_PROPERTY(double, dash_offset)
- RW_PROPERTY(guint, fill_color)
- RW_PROPERTY(guint, border_color)
- RW_PROPERTY(gboolean, selected)
- RW_PROPERTY(gboolean, highlighted)
- RW_PROPERTY(gboolean, draggable)
- RW_PROPERTY(gboolean, grabbed)
-
- RW_OBJECT_PROPERTY(Node*, partner);
-
- GanvNode* gobj() { return GANV_NODE(_gobj); }
- const GanvNode* gobj() const { return GANV_NODE(_gobj); }
-
- METHOD2(ganv_node, move, double, dx, double, dy)
- METHOD2(ganv_node, move_to, double, x, double, y)
-
- METHOD0(ganv_node, disconnect);
-
- sigc::signal<void, double, double>& signal_moved() {
- return _signal_moved;
- }
-
-private:
- sigc::signal<void, double, double> _signal_moved;
-
- static void on_moved(GanvNode* node, double x, double y) {
- Glib::wrap(node)->_signal_moved.emit(x, y);
- }
-
- /* GCC 4.6 can't handle this
- template<typename T>
- static void on_notify(GObject* gobj, GParamSpec* pspec, gpointer signal) {
- T value;
- g_object_get(gobj, g_param_spec_get_name(pspec), &value, NULL);
- ((sigc::signal<bool, T>*)signal)->emit(value);
- }
- */
- static void on_notify_bool(GObject* gobj,
- GParamSpec* pspec,
- gpointer signal) {
- gboolean value;
- g_object_get(gobj, g_param_spec_get_name(pspec), &value, NULL);
- ((sigc::signal<bool, gboolean>*)signal)->emit(value);
- }
-};
-
-} // namespace Ganv
-
-#endif // GANV_NODE_HPP
diff --git a/ganv/Port.hpp b/ganv/Port.hpp
deleted file mode 100644
index 94fb760..0000000
--- a/ganv/Port.hpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2014 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_PORT_HPP
-#define GANV_PORT_HPP
-
-#include <stdint.h>
-
-#include <string>
-
-#include <gdkmm/types.h>
-
-#include "ganv/Box.hpp"
-#include "ganv/port.h"
-
-GANV_GLIB_WRAP(Port)
-
-namespace Ganv {
-
-class Module;
-
-/** A port on a Module.
- *
- * This is a group that contains both the label and rectangle for a port.
- *
- * @ingroup Ganv
- */
-class Port : public Box
-{
-public:
- Port(Module& module,
- const std::string& name,
- bool is_input,
- uint32_t color);
-
- RW_PROPERTY(gboolean, is_controllable)
-
- METHODRET0(ganv_port, gboolean, is_input)
- METHODRET0(ganv_port, gboolean, is_output)
-
- METHODRET0(ganv_port, double, get_natural_width);
- METHODRET0(ganv_port, float, get_control_value)
- METHODRET0(ganv_port, float, get_control_min)
- METHODRET0(ganv_port, float, get_control_max)
- METHOD0(ganv_port, show_control)
- METHOD0(ganv_port, hide_control)
- METHOD1(ganv_port, set_control_is_toggle, gboolean, is_toggle)
- METHOD1(ganv_port, set_control_is_integer, gboolean, is_integer)
- METHOD1(ganv_port, set_control_value, float, value)
- METHOD1(ganv_port, set_control_min, float, min)
- METHOD1(ganv_port, set_control_max, float, max)
- METHOD1(ganv_port, set_value_label, const char*, str);
-
- sigc::signal<void, double> signal_value_changed;
-
- Module* get_module() const;
-
- GanvPort* gobj() { return GANV_PORT(_gobj); }
- const GanvPort* gobj() const { return GANV_PORT(_gobj); }
-};
-
-} // namespace Ganv
-
-#endif // GANV_PORT_HPP
diff --git a/ganv/box.h b/ganv/box.h
deleted file mode 100644
index ab166bf..0000000
--- a/ganv/box.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2014 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_BOX_H
-#define GANV_BOX_H
-
-#include "ganv/node.h"
-
-G_BEGIN_DECLS
-
-#define GANV_TYPE_BOX (ganv_box_get_type())
-#define GANV_BOX(obj) (GTK_CHECK_CAST((obj), GANV_TYPE_BOX, GanvBox))
-#define GANV_BOX_CLASS(klass) (GTK_CHECK_CLASS_CAST((klass), GANV_TYPE_BOX, GanvBoxClass))
-#define GANV_IS_BOX(obj) (GTK_CHECK_TYPE((obj), GANV_TYPE_BOX))
-#define GANV_IS_BOX_CLASS(klass) (GTK_CHECK_CLASS_TYPE((klass), GANV_TYPE_BOX))
-#define GANV_BOX_GET_CLASS(obj) (GTK_CHECK_GET_CLASS((obj), GANV_TYPE_BOX, GanvBoxClass))
-
-typedef struct _GanvBoxClass GanvBoxClass;
-typedef struct _GanvBoxPrivate GanvBoxPrivate;
-
-struct _GanvBox {
- GanvNode node;
- GanvBoxPrivate* impl;
-};
-
-/**
- * GanvBoxClass:
- * @parent_class: Node superclass.
- * @set_width: Set the width of the box.
- * @set_height: Set the height of the box.
- */
-struct _GanvBoxClass {
- GanvNodeClass parent_class;
-
- void (*set_width)(GanvBox* box,
- double width);
-
- void (*set_height)(GanvBox* box,
- double height);
-
- /* Reserved for future expansion */
- gpointer spare_vmethods[4];
-};
-
-GType ganv_box_get_type(void) G_GNUC_CONST;
-double ganv_box_get_x1(const GanvBox* box);
-double ganv_box_get_y1(const GanvBox* box);
-double ganv_box_get_x2(const GanvBox* box);
-double ganv_box_get_y2(const GanvBox* box);
-double ganv_box_get_width(const GanvBox* box);
-void ganv_box_set_width(GanvBox* box, double width);
-double ganv_box_get_height(const GanvBox* box);
-void ganv_box_set_height(GanvBox* box, double height);
-double ganv_box_get_border_width(const GanvBox* box);
-
-/**
- * ganv_box_normalize:
- * @box: The box to normalize.
- *
- * Normalize the box coordinates such that x1 < x2 and y1 < y2.
- */
-void ganv_box_normalize(GanvBox* box);
-
-G_END_DECLS
-
-#endif /* GANV_BOX_H */
diff --git a/ganv/canvas.h b/ganv/canvas.h
deleted file mode 100644
index 3ffb55c..0000000
--- a/ganv/canvas.h
+++ /dev/null
@@ -1,630 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2015 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_CANVAS_H
-#define GANV_CANVAS_H
-
-#include <stdarg.h>
-
-#include <cairo.h>
-#include <gtk/gtk.h>
-
-#include "ganv/canvas.h"
-#include "ganv/types.h"
-#include "ganv/edge.h"
-#include "ganv/item.h"
-
-G_BEGIN_DECLS
-
-#define GANV_TYPE_CANVAS (ganv_canvas_get_type())
-#define GANV_CANVAS(obj) (GTK_CHECK_CAST((obj), GANV_TYPE_CANVAS, GanvCanvas))
-#define GANV_CANVAS_CLASS(klass) (GTK_CHECK_CLASS_CAST((klass), GANV_TYPE_CANVAS, GanvCanvasClass))
-#define GANV_IS_CANVAS(obj) (GTK_CHECK_TYPE((obj), GANV_TYPE_CANVAS))
-#define GANV_IS_CANVAS_CLASS(klass) (GTK_CHECK_CLASS_TYPE((klass), GANV_TYPE_CANVAS))
-#define GANV_CANVAS_GET_CLASS(obj) (GTK_CHECK_GET_CLASS((obj), GANV_TYPE_CANVAS, GanvCanvasClass))
-
-typedef struct GanvCanvasImpl GanvCanvasPrivate;
-typedef struct _GanvCanvasClass GanvCanvasClass;
-
-/**
- * GanvDirection:
- * @GANV_DIRECTION_DOWN: Signal flows from top to bottom.
- * @GANV_DIRECTION_RIGHT: Signal flows from left to right.
- *
- * Specifies the direction of signal flow on the canvas, which affects the
- * appearance of modules and how the canvas is auto-arranged.
- */
-typedef enum {
- GANV_DIRECTION_DOWN,
- GANV_DIRECTION_RIGHT
-} GanvDirection;
-
-struct _GanvCanvas {
- GtkLayout layout;
- GanvCanvasPrivate* impl;
-};
-
-struct _GanvCanvasClass {
- GtkLayoutClass parent_class;
-
- /* Reserved for future expansion */
- gpointer spare_vmethods[4];
-};
-
-GType ganv_canvas_get_type(void) G_GNUC_CONST;
-
-/**
- * GanvEdgeFunc:
- * @edge: Canvas edge.
- * @data: User callback data.
- *
- * A node function that takes a user data argument (for callbacks).
- *
- * Note that in the Gtk world it is considered safe to cast a function to a
- * function with more arguments and call the resulting pointer, so functions
- * like ganv_edge_select can safely be used where a GanvEdgeFunc is expected.
- */
-typedef void (*GanvEdgeFunc)(GanvEdge* edge, void* data);
-
-/**
- * GanvNodeFunc:
- * @node: Canvas node.
- * @data: User callback data.
- *
- * A node function that takes a user data argument (for callbacks).
- *
- * Note that in the Gtk world it is considered safe to cast a function to a
- * function with more arguments and call the resulting pointer, so functions
- * like ganv_node_select can safely be used where a GanvNodeFunc is expected.
- */
-typedef void (*GanvNodeFunc)(GanvNode* node, void* data);
-
-typedef int (*GanvPortOrderFunc)(const GanvPort*, const GanvPort*, void* data);
-
-/**
- * ganv_canvas_new:
- *
- * Return value: A newly-created canvas.
- */
-GanvCanvas*
-ganv_canvas_new(double width, double height);
-
-/**
- * ganv_canvas_set_wrapper:
- *
- * Set the opaque wrapper object for the canvas.
- */
-void
-ganv_canvas_set_wrapper(GanvCanvas* canvas, void* wrapper);
-
-/**
- * ganv_canvas_get_wrapper:
- *
- * Return an opaque pointer to the wrapper for the canvas.
- */
-void*
-ganv_canvas_get_wrapper(GanvCanvas* canvas);
-
-/**
- * ganv_canvas_clear:
- *
- * Remove all items from the canvas.
- */
-void
-ganv_canvas_clear(GanvCanvas* canvas);
-
-/**
- * ganv_canvas_empty:
- *
- * Return value: True if there are no items on the canvas.
- */
-gboolean
-ganv_canvas_empty(const GanvCanvas* canvas);
-
-/**
- * ganv_canvas_resize:
- *
- * Resize the canvas to the given dimensions.
- */
-void
-ganv_canvas_resize(GanvCanvas* canvas, double width, double height);
-
-/**
- * ganv_canvas_root:
- * @canvas: A canvas.
- *
- * Return value: (transfer none): The root group of the canvas.
- */
-GanvItem*
-ganv_canvas_root(GanvCanvas* canvas);
-
-/**
- * ganv_canvas_set_scroll_region:
- * @canvas: A canvas.
- * @x1: Leftmost limit of the scrolling region.
- * @y1: Upper limit of the scrolling region.
- * @x2: Rightmost limit of the scrolling region.
- * @y2: Lower limit of the scrolling region.
- *
- * Sets the scrolling region of a canvas to the specified rectangle. The
- * canvas will then be able to scroll only within this region. The view of the
- * canvas is adjusted as appropriate to display as much of the new region as
- * possible.
- */
-void
-ganv_canvas_set_scroll_region(GanvCanvas* canvas,
- double x1, double y1, double x2, double y2);
-
-/**
- * ganv_canvas_get_scroll_region:
- * @canvas: A canvas.
- * @x1: Leftmost limit of the scrolling region (return value).
- * @y1: Upper limit of the scrolling region (return value).
- * @x2: Rightmost limit of the scrolling region (return value).
- * @y2: Lower limit of the scrolling region (return value).
- *
- * Queries the scrolling region of a canvas.
- */
-void
-ganv_canvas_get_scroll_region(GanvCanvas* canvas,
- double* x1, double* y1, double* x2, double* y2);
-
-/**
- * ganv_canvas_set_center_scroll_region:
- * @canvas: A canvas.
- * @center_scroll_region: Whether to center the scrolling region in the canvas
- * window when it is smaller than the canvas' allocation.
- *
- * When the scrolling region of the canvas is smaller than the canvas window,
- * e.g. the allocation of the canvas, it can be either centered on the window
- * or simply made to be on the upper-left corner on the window. This function
- * lets you configure this property.
- */
-void
-ganv_canvas_set_center_scroll_region(GanvCanvas* canvas,
- gboolean center_scroll_region);
-
-/**
- * ganv_canvas_get_center_scroll_region:
- * @canvas: A canvas.
- *
- * Returns whether the canvas is set to center the scrolling region in the
- * window if the former is smaller than the canvas' allocation.
- *
- * Returns: Whether the scroll region is being centered in the canvas window.
- */
-gboolean
-ganv_canvas_get_center_scroll_region(const GanvCanvas* canvas);
-
-/**
- * ganv_canvas_scroll_to:
- * @canvas: A canvas.
- * @cx: Horizontal scrolling offset in canvas pixel units.
- * @cy: Vertical scrolling offset in canvas pixel units.
- *
- * Makes a canvas scroll to the specified offsets, given in canvas pixel units.
- * The canvas will adjust the view so that it is not outside the scrolling
- * region. This function is typically not used, as it is better to hook
- * scrollbars to the canvas layout's scrolling adjusments.
- */
-void
-ganv_canvas_scroll_to(GanvCanvas* canvas, int cx, int cy);
-
-/**
- * ganv_canvas_get_scroll_offsets:
- * @canvas: A canvas.
- * @cx: Horizontal scrolling offset (return value).
- * @cy: Vertical scrolling offset (return value).
- *
- * Queries the scrolling offsets of a canvas. The values are returned in canvas
- * pixel units.
- */
-void
-ganv_canvas_get_scroll_offsets(const GanvCanvas* canvas, int* cx, int* cy);
-
-/**
- * ganv_canvas_w2c_affine:
- * @canvas: A canvas.
- * @matrix: An affine transformation matrix (return value).
- *
- * Gets the affine transform that converts from world coordinates to canvas
- * pixel coordinates.
- */
-void
-ganv_canvas_w2c_affine(GanvCanvas* canvas, cairo_matrix_t* matrix);
-
-/**
- * ganv_canvas_w2c:
- * @canvas: A canvas.
- * @wx: World X coordinate.
- * @wy: World Y coordinate.
- * @cx: X pixel coordinate (return value).
- * @cy: Y pixel coordinate (return value).
- *
- * Converts world coordinates into canvas pixel coordinates.
- */
-void
-ganv_canvas_w2c(GanvCanvas* canvas, double wx, double wy, int* cx, int* cy);
-
-/**
- * ganv_canvas_w2c_d:
- * @canvas: A canvas.
- * @wx: World X coordinate.
- * @wy: World Y coordinate.
- * @cx: X pixel coordinate (return value).
- * @cy: Y pixel coordinate (return value).
- *
- * Converts world coordinates into canvas pixel coordinates. This version
- * uses floating point coordinates for greater precision.
- */
-void
-ganv_canvas_w2c_d(GanvCanvas* canvas,
- double wx,
- double wy,
- double* cx,
- double* cy);
-
-/**
- * ganv_canvas_c2w:
- * @canvas: A canvas.
- * @cx: Canvas pixel X coordinate.
- * @cy: Canvas pixel Y coordinate.
- * @wx: X world coordinate (return value).
- * @wy: Y world coordinate (return value).
- *
- * Converts canvas pixel coordinates to world coordinates.
- */
-void
-ganv_canvas_c2w(GanvCanvas* canvas, int cx, int cy, double* wx, double* wy);
-
-/**
- * ganv_canvas_window_to_world:
- * @canvas: A canvas.
- * @winx: Window-relative X coordinate.
- * @winy: Window-relative Y coordinate.
- * @worldx: X world coordinate (return value).
- * @worldy: Y world coordinate (return value).
- *
- * Converts window-relative coordinates into world coordinates. You can use
- * this when you need to convert mouse coordinates into world coordinates, for
- * example.
- */
-void
-ganv_canvas_window_to_world(GanvCanvas* canvas,
- double winx,
- double winy,
- double* worldx,
- double* worldy);
-
-/**
- * ganv_canvas_world_to_window:
- * @canvas: A canvas.
- * @worldx: World X coordinate.
- * @worldy: World Y coordinate.
- * @winx: X window-relative coordinate.
- * @winy: Y window-relative coordinate.
- *
- * Converts world coordinates into window-relative coordinates.
- */
-void
-ganv_canvas_world_to_window(GanvCanvas* canvas,
- double worldx,
- double worldy,
- double* winx,
- double* winy);
-
-/**
- * ganv_canvas_get_item_at:
- * @canvas: A canvas.
- * @x: X position in world coordinates.
- * @y: Y position in world coordinates.
- *
- * Looks for the item that is under the specified position, which must be
- * specified in world coordinates.
- *
- * Returns: (transfer none): The sought item, or NULL if no item is at the
- * specified coordinates.
- */
-GanvItem*
-ganv_canvas_get_item_at(GanvCanvas* canvas, double x, double y);
-
-/**
- * ganv_canvas_get_edge:
- *
- * Get the edge between two nodes, or NULL if none exists.
- *
- * Return value: (transfer none): The root group of @canvas.
- */
-GanvEdge*
-ganv_canvas_get_edge(GanvCanvas* canvas,
- GanvNode* tail,
- GanvNode* head);
-
-/**
- * ganv_canvas_remove_edge:
- *
- * Remove @edge from the canvas.
- */
-void
-ganv_canvas_remove_edge(GanvCanvas* canvas,
- GanvEdge* edge);
-
-/**
- * ganv_canvas_remove_edge_between:
- *
- * Remove the edge from @tail to @head if one exists.
- */
-void
-ganv_canvas_remove_edge_between(GanvCanvas* canvas,
- GanvNode* tail,
- GanvNode* head);
-
-/**
- * ganv_canvas_get_direction:
- *
- * Return the direction of signal flow.
- */
-GanvDirection
-ganv_canvas_get_direction(GanvCanvas* canvas);
-
-/**
- * ganv_canvas_set_direction:
- *
- * Set the direction of signal flow.
- */
-void
-ganv_canvas_set_direction(GanvCanvas* canvas, GanvDirection dir);
-
-/**
- * ganv_canvas_arrange:
- *
- * Automatically arrange the canvas contents.
- */
-void
-ganv_canvas_arrange(GanvCanvas* canvas);
-
-/**
- * ganv_canvas_export_image:
- *
- * Draw the canvas to an image file. The file type is determined by extension,
- * currently supported: pdf, ps, svg, dot.
- *
- * Returns: 0 on success.
- */
-int
-ganv_canvas_export_image(GanvCanvas* canvas,
- const char* filename,
- gboolean draw_background);
-
-/**
- * ganv_canvas_export_dot:
- *
- * Write a Graphviz DOT description of the canvas to a file.
- */
-void
-ganv_canvas_export_dot(GanvCanvas* canvas, const char* filename);
-
-/**
- * ganv_canvas_supports_sprung_layout:
- *
- * Returns: true iff ganv is compiled with sprung layout support.
- */
-gboolean
-ganv_canvas_supports_sprung_layout(const GanvCanvas* canvas);
-
-/**
- * ganv_canvas_set_sprung_layout:
- *
- * Enable or disable "live" force-directed canvas layout.
- *
- * Returns: true iff sprung layout was enabled.
- */
-gboolean
-ganv_canvas_set_sprung_layout(GanvCanvas* canvas, gboolean sprung_layout);
-
-/**
- * ganv_canvas_get_locked:
- *
- * Return true iff the canvas is locked and nodes may not move.
- */
-gboolean
-ganv_canvas_get_locked(const GanvCanvas* canvas);
-
-/**
- * ganv_canvas_for_each_node:
- * @canvas: The canvas.
- * @f: (scope call): A function to call on every node on @canvas.
- * @data: Data to pass to @f.
- */
-void
-ganv_canvas_for_each_node(GanvCanvas* canvas,
- GanvNodeFunc f,
- void* data);
-
-/**
- * ganv_canvas_for_each_selected_node:
- * @canvas: The canvas.
- * @f: (scope call): A function to call on every selected node on @canvas.
- * @data: Data to pass to @f.
- */
-void
-ganv_canvas_for_each_selected_node(GanvCanvas* canvas,
- GanvNodeFunc f,
- void* data);
-
-/**
- * ganv_canvas_for_each_edge:
- * @canvas: The canvas.
- * @f: (scope call): A function to call on every edge on @canvas.
- * @data: Data to pass to @f.
- */
-void
-ganv_canvas_for_each_edge(GanvCanvas* canvas,
- GanvEdgeFunc f,
- void* data);
-
-/**
- * ganv_canvas_for_each_edge_from:
- * @canvas: The canvas.
- * @tail: The tail to enumerate every edge for.
- * @f: (scope call): A function to call on every edge leaving @tail.
- */
-void
-ganv_canvas_for_each_edge_from(GanvCanvas* canvas,
- const GanvNode* tail,
- GanvEdgeFunc f,
- void* data);
-
-/**
- * ganv_canvas_for_each_edge_to:
- * @canvas: The canvas.
- * @head: The head to enumerate every edge for.
- * @f: (scope call): A function to call on every edge entering @head.
- */
-void
-ganv_canvas_for_each_edge_to(GanvCanvas* canvas,
- const GanvNode* head,
- GanvEdgeFunc f,
- void* data);
-
-/**
- * ganv_canvas_for_each_edge_on:
- * @canvas: The canvas.
- * @node: The node to enumerate every edge for.
- * @f: (scope call): A function to call on every edge attached to @node.
- */
-void
-ganv_canvas_for_each_edge_on(GanvCanvas* canvas,
- const GanvNode* node,
- GanvEdgeFunc f,
- void* data);
-
-/**
- * ganv_canvas_for_each_selected_edge:
- * @canvas: The canvas.
- * @f: (scope call): A function to call on every edge attached to @node.
- * @data: Data to pass to @f.
- */
-void
-ganv_canvas_for_each_selected_edge(GanvCanvas* canvas,
- GanvEdgeFunc f,
- void* data);
-
-/**
- * ganv_canvas_select_all:
- *
- * Select all items on the canvas.
- */
-void
-ganv_canvas_select_all(GanvCanvas* canvas);
-
-/**
- * ganv_canvas_clear_selection:
- *
- * Deselect any selected items on the canvas.
- */
-void
-ganv_canvas_clear_selection(GanvCanvas* canvas);
-
-/**
- * ganv_canvas_get_zoom:
- *
- * Return the current zoom factor (pixels per unit).
- */
-double
-ganv_canvas_get_zoom(const GanvCanvas* canvas);
-
-/**
- * ganv_canvas_set_zoom:
- * @canvas: A canvas.
- * @zoom: The number of pixels that correspond to one canvas unit.
- *
- * The anchor point for zooming, i.e. the point that stays fixed and all others
- * zoom inwards or outwards from it, depends on whether the canvas is set to
- * center the scrolling region or not. You can control this using the
- * ganv_canvas_set_center_scroll_region() function. If the canvas is set to
- * center the scroll region, then the center of the canvas window is used as
- * the anchor point for zooming. Otherwise, the upper-left corner of the
- * canvas window is used as the anchor point.
- */
-void
-ganv_canvas_set_zoom(GanvCanvas* canvas, double zoom);
-
-/**
- * ganv_canvas_zoom_full:
- *
- * Zoom so all canvas contents are visible.
- */
-void
-ganv_canvas_zoom_full(GanvCanvas* canvas);
-
-/**
- * ganv_canvas_get_default_font_size:
- *
- * Get the default font size in points.
- */
-double
-ganv_canvas_get_default_font_size(const GanvCanvas* canvas);
-
-/**
- * ganv_canvas_get_font_size:
- *
- * Get the current font size in points.
- */
-double
-ganv_canvas_get_font_size(const GanvCanvas* canvas);
-
-/**
- * ganv_canvas_set_font_size:
- *
- * Set the current font size in points.
- */
-void
-ganv_canvas_set_font_size(GanvCanvas* canvas, double points);
-
-/**
- * ganv_canvas_get_move_cursor:
- *
- * Return the cursor to use while dragging canvas objects.
- */
-GdkCursor*
-ganv_canvas_get_move_cursor(const GanvCanvas* canvas);
-
-/**
- * ganv_canvas_move_contents_to:
- *
- * Shift all canvas contents so the top-left object is at (x, y).
- */
-void
-ganv_canvas_move_contents_to(GanvCanvas* canvas, double x, double y);
-
-/**
- * ganv_canvas_set_port_order:
- * @canvas The canvas to set the default port order on.
- * @port_cmp Port comparison function.
- * @data Data to be passed to order.
- *
- * Set a comparator function to use as the default order for ports on modules.
- * If left unset, ports are shown in the order they are added.
- */
-void
-ganv_canvas_set_port_order(GanvCanvas* canvas,
- GanvPortOrderFunc port_cmp,
- void* data);
-
-
-G_END_DECLS
-
-#endif /* GANV_CANVAS_H */
diff --git a/ganv/circle.h b/ganv/circle.h
deleted file mode 100644
index f181b54..0000000
--- a/ganv/circle.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2014 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_CIRCLE_H
-#define GANV_CIRCLE_H
-
-#include "ganv/node.h"
-
-G_BEGIN_DECLS
-
-#define GANV_TYPE_CIRCLE (ganv_circle_get_type())
-#define GANV_CIRCLE(obj) (GTK_CHECK_CAST((obj), GANV_TYPE_CIRCLE, GanvCircle))
-#define GANV_CIRCLE_CLASS(klass) (GTK_CHECK_CLASS_CAST((klass), GANV_TYPE_CIRCLE, GanvCircleClass))
-#define GANV_IS_CIRCLE(obj) (GTK_CHECK_TYPE((obj), GANV_TYPE_CIRCLE))
-#define GANV_IS_CIRCLE_CLASS(klass) (GTK_CHECK_CLASS_TYPE((klass), GANV_TYPE_CIRCLE))
-#define GANV_CIRCLE_GET_CLASS(obj) (GTK_CHECK_GET_CLASS((obj), GANV_TYPE_CIRCLE, GanvCircleClass))
-
-typedef struct _GanvCircle GanvCircle;
-typedef struct _GanvCircleClass GanvCircleClass;
-typedef struct _GanvCirclePrivate GanvCirclePrivate;
-
-/**
- * GanvCircle:
- *
- * A circular #GanvNode. A #GanvCircle is a leaf, that is, it does not contain
- * any child nodes (though, like any #GanvNode, it may have a label).
- */
-struct _GanvCircle {
- GanvNode node;
- GanvCirclePrivate* impl;
-};
-
-struct _GanvCircleClass {
- GanvNodeClass parent_class;
-
- /* Reserved for future expansion */
- gpointer spare_vmethods[4];
-};
-
-GType ganv_circle_get_type(void) G_GNUC_CONST;
-
-GanvCircle*
-ganv_circle_new(GanvCanvas* canvas,
- const char* first_prop_name, ...);
-
-double
-ganv_circle_get_radius(const GanvCircle* circle);
-
-void
-ganv_circle_set_radius(GanvCircle* circle, double radius);
-
-double
-ganv_circle_get_radius_ems(const GanvCircle* circle);
-
-void
-ganv_circle_set_radius_ems(GanvCircle* circle, double radius);
-
-gboolean
-ganv_circle_get_fit_label(const GanvCircle* circle);
-
-void
-ganv_circle_set_fit_label(GanvCircle* circle, gboolean fit_label);
-
-G_END_DECLS
-
-#endif /* GANV_CIRCLE_H */
diff --git a/ganv/edge.h b/ganv/edge.h
deleted file mode 100644
index bf0fb14..0000000
--- a/ganv/edge.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2015 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_EDGE_H
-#define GANV_EDGE_H
-
-#include "ganv/item.h"
-#include "ganv/node.h"
-#include "ganv/types.h"
-
-G_BEGIN_DECLS
-
-#define GANV_TYPE_EDGE (ganv_edge_get_type())
-#define GANV_EDGE(obj) (GTK_CHECK_CAST((obj), GANV_TYPE_EDGE, GanvEdge))
-#define GANV_EDGE_CLASS(klass) (GTK_CHECK_CLASS_CAST((klass), GANV_TYPE_EDGE, GanvEdgeClass))
-#define GANV_IS_EDGE(obj) (GTK_CHECK_TYPE((obj), GANV_TYPE_EDGE))
-#define GANV_IS_EDGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE((klass), GANV_TYPE_EDGE))
-#define GANV_EDGE_GET_CLASS(obj) (GTK_CHECK_GET_CLASS((obj), GANV_TYPE_EDGE, GanvEdgeClass))
-
-typedef struct _GanvEdgeClass GanvEdgeClass;
-typedef struct _GanvEdgePrivate GanvEdgePrivate;
-
-struct _GanvEdge {
- GanvItem item;
- GanvEdgePrivate* impl;
-};
-
-struct _GanvEdgeClass {
- GanvItemClass parent_class;
-
- /* Reserved for future expansion */
- gpointer spare_vmethods[4];
-};
-
-GType ganv_edge_get_type(void) G_GNUC_CONST;
-
-GanvEdge*
-ganv_edge_new(GanvCanvas* canvas,
- GanvNode* tail,
- GanvNode* head,
- const char* first_prop_name, ...);
-
-gboolean
-ganv_edge_is_within(const GanvEdge* edge,
- double x1,
- double y1,
- double x2,
- double y2);
-
-gboolean
-ganv_edge_get_curved(const GanvEdge* edge);
-
-void
-ganv_edge_set_curved(GanvEdge* edge, gboolean curved);
-
-gboolean
-ganv_edge_get_constraining(const GanvEdge* edge);
-
-void
-ganv_edge_set_constraining(GanvEdge* edge, gboolean constraining);
-
-void
-ganv_edge_set_selected(GanvEdge* edge, gboolean selected);
-
-void
-ganv_edge_set_highlighted(GanvEdge* edge, gboolean highlighted);
-
-void
-ganv_edge_select(GanvEdge* edge);
-
-void
-ganv_edge_unselect(GanvEdge* edge);
-
-void
-ganv_edge_highlight(GanvEdge* edge);
-
-void
-ganv_edge_unhighlight(GanvEdge* edge);
-
-/**
- * ganv_edge_disconnect:
- *
- * Disconnect the edge. This will disconnect the edge just as if it had been
- * disconnected by the user via the canvas. The canvas disconnect signal will
- * be emitted, allowing the application to control disconnect logic.
- */
-void
-ganv_edge_disconnect(GanvEdge* edge);
-
-/**
- * ganv_edge_remove:
- *
- * Remove the edge from the canvas. This will only remove the edge visually,
- * it will not emit the canvas disconnect signal to notify the application.
- */
-void
-ganv_edge_remove(GanvEdge* edge);
-
-/**
- * ganv_edge_get_tail:
- *
- * Return value: (transfer none): The tail of `edge`.
- */
-GanvNode*
-ganv_edge_get_tail(const GanvEdge* edge);
-
-/**
- * ganv_edge_get_head:
- *
- * Return value: (transfer none): The head of `edge`.
- */
-GanvNode*
-ganv_edge_get_head(const GanvEdge* edge);
-
-G_END_DECLS
-
-#endif /* GANV_EDGE_H */
diff --git a/ganv/ganv.h b/ganv/ganv.h
deleted file mode 100644
index 9a00143..0000000
--- a/ganv/ganv.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2016 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_GANV_H
-#define GANV_GANV_H
-
-#include "ganv/box.h"
-#include "ganv/canvas.h"
-#include "ganv/circle.h"
-#include "ganv/edge.h"
-#include "ganv/ganv.h"
-#include "ganv/group.h"
-#include "ganv/module.h"
-#include "ganv/node.h"
-#include "ganv/port.h"
-#include "ganv/text.h"
-#include "ganv/types.h"
-
-#endif /* GANV_GANV_H */
diff --git a/ganv/ganv.hpp b/ganv/ganv.hpp
deleted file mode 100644
index 9b0334d..0000000
--- a/ganv/ganv.hpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2015 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_GANV_HPP
-#define GANV_GANV_HPP
-
-#include "ganv/Canvas.hpp"
-#include "ganv/Circle.hpp"
-#include "ganv/Edge.hpp"
-#include "ganv/Module.hpp"
-#include "ganv/Node.hpp"
-#include "ganv/Port.hpp"
-
-#endif // GANV_GANV_HPP
diff --git a/ganv/group.h b/ganv/group.h
deleted file mode 100644
index 0f835e4..0000000
--- a/ganv/group.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2014 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_GROUP_H
-#define GANV_GROUP_H
-
-#include "ganv/item.h"
-
-G_BEGIN_DECLS
-
-/* Based on GnomeCanvasGroup, by Federico Mena <federico@nuclecu.unam.mx>
- * and Raph Levien <raph@gimp.org>
- * Copyright 1997-2000 Free Software Foundation
- */
-
-#define GANV_TYPE_GROUP (ganv_group_get_type())
-#define GANV_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GANV_TYPE_GROUP, GanvGroup))
-#define GANV_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GANV_TYPE_GROUP, GanvGroupClass))
-#define GANV_IS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GANV_TYPE_GROUP))
-#define GANV_IS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GANV_TYPE_GROUP))
-#define GANV_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GANV_TYPE_GROUP, GanvGroupClass))
-
-typedef struct _GanvGroup GanvGroup;
-typedef struct _GanvGroupPrivate GanvGroupPrivate;
-typedef struct _GanvGroupClass GanvGroupClass;
-
-struct _GanvGroup {
- GanvItem item;
- GanvGroupPrivate* impl;
-};
-
-struct _GanvGroupClass {
- GanvItemClass parent_class;
-
- /* Reserved for future expansion */
- gpointer spare_vmethods[4];
-};
-
-GType ganv_group_get_type(void) G_GNUC_CONST;
-
-G_END_DECLS
-
-#endif /* GANV_GROUP_H */
diff --git a/ganv/item.h b/ganv/item.h
deleted file mode 100644
index 4605ffb..0000000
--- a/ganv/item.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2016 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Based on GnomeCanvas, by Federico Mena <federico@nuclecu.unam.mx>
- * and Raph Levien <raph@gimp.org>
- * Copyright 1997-2000 Free Software Foundation
- */
-
-#ifndef GANV_ITEM_H
-#define GANV_ITEM_H
-
-#include <stdarg.h>
-
-#include <cairo.h>
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-struct _GanvCanvas;
-
-typedef struct _GanvItem GanvItem;
-typedef struct _GanvItemPrivate GanvItemPrivate;
-typedef struct _GanvItemClass GanvItemClass;
-
-/* Object flags for items */
-enum {
- GANV_ITEM_REALIZED = 1 << 1,
- GANV_ITEM_MAPPED = 1 << 2,
- GANV_ITEM_ALWAYS_REDRAW = 1 << 3,
- GANV_ITEM_VISIBLE = 1 << 4,
- GANV_ITEM_NEED_UPDATE = 1 << 5,
- GANV_ITEM_NEED_VIS = 1 << 6
-};
-
-#define GANV_TYPE_ITEM (ganv_item_get_type())
-#define GANV_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GANV_TYPE_ITEM, GanvItem))
-#define GANV_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GANV_TYPE_ITEM, GanvItemClass))
-#define GANV_IS_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GANV_TYPE_ITEM))
-#define GANV_IS_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GANV_TYPE_ITEM))
-#define GANV_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GANV_TYPE_ITEM, GanvItemClass))
-
-struct _GanvItem {
- GtkObject object;
- GanvItemPrivate* impl;
-};
-
-struct _GanvItemClass {
- GtkObjectClass parent_class;
-
- /* Add a child to this item (optional). */
- void (*add)(GanvItem* item, GanvItem* child);
-
- /* Remove a child from this item (optional). */
- void (*remove)(GanvItem* item, GanvItem* child);
-
- /* Tell the item to update itself.
- *
- * The flags are from the update flags defined above. The item should
- * update its internal state from its queued state, and recompute and
- * request its repaint area. The update method also recomputes the
- * bounding box of the item.
- */
- void (*update)(GanvItem* item, int flags);
-
- /* Realize an item (create GCs, etc.). */
- void (*realize)(GanvItem* item);
-
- /* Unrealize an item. */
- void (*unrealize)(GanvItem* item);
-
- /* Map an item - normally only need by items with their own GdkWindows. */
- void (*map)(GanvItem* item);
-
- /* Unmap an item */
- void (*unmap)(GanvItem* item);
-
- /* Draw an item of this type.
- *
- * (cx, cy) and (width, height) describe the rectangle being drawn in
- * world-relative coordinates.
- */
- void (*draw)(GanvItem* item,
- cairo_t* cr,
- double cx,
- double cy,
- double cw,
- double ch);
-
- /* Calculate the distance from an item to the specified point.
- *
- * It also returns a canvas item which is actual item the point is within,
- * which may not be equal to @item if @item has children.
- * (x, y) are item-relative coordinates.
- */
- double (*point)(GanvItem* item,
- double x,
- double y,
- GanvItem** actual_item);
-
- /* Fetch the item's bounding box (need not be exactly tight).
- *
- * This should be in item-relative coordinates.
- */
- void (*bounds)(GanvItem* item, double* x1, double* y1, double* x2, double* y2);
-
- /* Signal: an event occurred for an item of this type.
- *
- * The (x, y) coordinates are in the canvas world coordinate system.
- */
- gboolean (*event)(GanvItem* item, GdkEvent* event);
-
- /* Reserved for future expansion */
- gpointer spare_vmethods[4];
-};
-
-GType ganv_item_get_type(void) G_GNUC_CONST;
-
-GanvItem* ganv_item_new(GanvItem* parent, GType type,
- const gchar* first_arg_name, ...);
-
-void ganv_item_construct(GanvItem* item, GanvItem* parent,
- const gchar* first_arg_name, va_list args);
-
-void ganv_item_set(GanvItem* item, const gchar* first_arg_name, ...);
-
-void ganv_item_set_valist(GanvItem* item,
- const gchar* first_arg_name, va_list args);
-
-/**
- * ganv_item_get_canvas:
- * @item: The item.
- *
- * Return value: (transfer none): The canvas @item is on.
- */
-struct _GanvCanvas* ganv_item_get_canvas(GanvItem* item);
-
-/**
- * ganv_item_get_parent:
- * @item: The item.
- *
- * Return value: (transfer none): The parent of @item.
- */
-GanvItem* ganv_item_get_parent(GanvItem* item);
-
-void ganv_item_raise(GanvItem* item);
-
-void ganv_item_lower(GanvItem* item);
-
-void ganv_item_move(GanvItem* item, double dx, double dy);
-
-void ganv_item_show(GanvItem* item);
-
-void ganv_item_hide(GanvItem* item);
-
-void ganv_item_i2w(GanvItem* item, double* x, double* y);
-
-void ganv_item_w2i(GanvItem* item, double* x, double* y);
-
-void ganv_item_grab_focus(GanvItem* item);
-
-void ganv_item_get_bounds(GanvItem* item,
- double* x1, double* y1, double* x2, double* y2);
-
-void ganv_item_request_update(GanvItem* item);
-
-void ganv_item_set_wrapper(GanvItem* item, void* wrapper);
-
-void* ganv_item_get_wrapper(GanvItem* item);
-
-G_END_DECLS
-
-#endif /* GANV_ITEM_H */
diff --git a/ganv/module.h b/ganv/module.h
deleted file mode 100644
index 37fcf96..0000000
--- a/ganv/module.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2014 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_MODULE_H
-#define GANV_MODULE_H
-
-#include <glib.h>
-#include <gtk/gtk.h>
-
-#include "ganv/box.h"
-
-G_BEGIN_DECLS
-
-#define GANV_TYPE_MODULE (ganv_module_get_type())
-#define GANV_MODULE(obj) (GTK_CHECK_CAST((obj), GANV_TYPE_MODULE, GanvModule))
-#define GANV_MODULE_CLASS(klass) (GTK_CHECK_CLASS_CAST((klass), GANV_TYPE_MODULE, GanvModuleClass))
-#define GANV_IS_MODULE(obj) (GTK_CHECK_TYPE((obj), GANV_TYPE_MODULE))
-#define GANV_IS_MODULE_CLASS(klass) (GTK_CHECK_CLASS_TYPE((klass), GANV_TYPE_MODULE))
-#define GANV_MODULE_GET_CLASS(obj) (GTK_CHECK_GET_CLASS((obj), GANV_TYPE_MODULE, GanvModuleClass))
-
-typedef struct _GanvModuleClass GanvModuleClass;
-typedef struct _GanvModulePrivate GanvModulePrivate;
-
-typedef void (*GanvPortFunc)(GanvPort* port, void* data);
-
-struct _GanvModule {
- GanvBox box;
- GanvModulePrivate* impl;
-};
-
-struct _GanvModuleClass {
- GanvBoxClass parent_class;
-
- /* Reserved for future expansion */
- gpointer spare_vmethods[4];
-};
-
-GType ganv_module_get_type(void) G_GNUC_CONST;
-
-GanvModule*
-ganv_module_new(GanvCanvas* canvas,
- const char* first_prop_name, ...);
-
-guint
-ganv_module_num_ports(const GanvModule* module);
-
-/**
- * ganv_module_get_port:
- *
- * Get a port by index.
- *
- * Return value: (transfer none): The port on @module at @index.
- */
-GanvPort*
-ganv_module_get_port(GanvModule* module,
- guint index);
-
-double
-ganv_module_get_empty_port_breadth(const GanvModule* module);
-
-double
-ganv_module_get_empty_port_depth(const GanvModule* module);
-
-void
-ganv_module_embed(GanvModule* module, GtkWidget* widget);
-
-void
-ganv_module_set_direction(GanvModule* module, GanvDirection direction);
-
-/**
- * ganv_module_for_each_port:
- * @module: The module.
- * @f: (scope call): A function to call on every port on @module.
- * @data: User data to pass to @f.
- */
-void
-ganv_module_for_each_port(GanvModule* module,
- GanvPortFunc f,
- void* data);
-
-G_END_DECLS
-
-#endif /* GANV_MODULE_H */
diff --git a/ganv/node.h b/ganv/node.h
deleted file mode 100644
index b0dd82f..0000000
--- a/ganv/node.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2014 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_NODE_H
-#define GANV_NODE_H
-
-#include "ganv/item.h"
-#include "ganv/types.h"
-#include "ganv/text.h"
-
-G_BEGIN_DECLS
-
-#define GANV_TYPE_NODE (ganv_node_get_type())
-#define GANV_NODE(obj) (GTK_CHECK_CAST((obj), GANV_TYPE_NODE, GanvNode))
-#define GANV_NODE_CLASS(klass) (GTK_CHECK_CLASS_CAST((klass), GANV_TYPE_NODE, GanvNodeClass))
-#define GANV_IS_NODE(obj) (GTK_CHECK_TYPE((obj), GANV_TYPE_NODE))
-#define GANV_IS_NODE_CLASS(klass) (GTK_CHECK_CLASS_TYPE((klass), GANV_TYPE_NODE))
-#define GANV_NODE_GET_CLASS(obj) (GTK_CHECK_GET_CLASS((obj), GANV_TYPE_NODE, GanvNodeClass))
-
-typedef struct _GanvNodeClass GanvNodeClass;
-typedef struct _GanvNodePrivate GanvNodePrivate;
-
-struct _GanvNode {
- GanvItem item;
- GanvNodePrivate* impl;
-};
-
-struct _GanvNodeClass {
- GanvItemClass parent_class;
-
- void (*tick)(GanvNode* self,
- double seconds);
-
- void (*move)(GanvNode* node,
- double dx,
- double dy);
-
- void (*move_to)(GanvNode* node,
- double x,
- double y);
-
- void (*resize)(GanvNode* node);
-
- void (*redraw_text)(GanvNode* node);
-
- void (*disconnect)(GanvNode* node);
-
- gboolean (*is_within)(const GanvNode* self,
- double x1,
- double y1,
- double x2,
- double y2);
-
- void (*tail_vector)(const GanvNode* self,
- const GanvNode* head,
- double* x,
- double* y,
- double* dx,
- double* dy);
-
- void (*head_vector)(const GanvNode* self,
- const GanvNode* tail,
- double* x,
- double* y,
- double* dx,
- double* dy);
-
- /* Reserved for future expansion */
- gpointer spare_vmethods[4];
-};
-
-GType ganv_node_get_type(void) G_GNUC_CONST;
-
-/**
- * ganv_node_can_tail:
- *
- * Return value: True iff node can act as the tail of an edge.
- */
-gboolean
-ganv_node_can_tail(const GanvNode* node);
-
-/**
- * ganv_node_can_head:
- *
- * Return value: True iff node can act as the head of an edge.
- */
-gboolean
-ganv_node_can_head(const GanvNode* node);
-
-/**
- * ganv_node_set_is_source:
- *
- * Flag a node as a source. This information is used to influence layout.
- */
-void
-ganv_node_set_is_source(const GanvNode* node, gboolean is_source);
-
-/**
- * ganv_node_is_within:
- *
- * Return value: True iff node is entirely within the given rectangle.
- */
-gboolean
-ganv_node_is_within(const GanvNode* node,
- double x1,
- double y1,
- double x2,
- double y2);
-
-const char* ganv_node_get_label(const GanvNode* node);
-
-double ganv_node_get_border_width(const GanvNode* node);
-
-void ganv_node_set_border_width(const GanvNode* node, double border_width);
-
-double ganv_node_get_dash_length(const GanvNode* node);
-
-void ganv_node_set_dash_length(const GanvNode* node, double dash_length);
-
-double ganv_node_get_dash_offset(const GanvNode* node);
-
-void ganv_node_set_dash_offset(const GanvNode* node, double dash_offset);
-
-guint ganv_node_get_fill_color(const GanvNode* node);
-
-void ganv_node_set_fill_color(const GanvNode* node, guint fill_color);
-
-guint ganv_node_get_border_color(const GanvNode* node);
-
-void ganv_node_set_border_color(const GanvNode* node, guint border_color);
-
-/**
- * ganv_node_get_partner:
- *
- * Return value: (transfer none): The partner of @node.
- */
-GanvNode*
-ganv_node_get_partner(const GanvNode* node);
-
-void ganv_node_set_label(GanvNode* node, const char* str);
-void ganv_node_set_show_label(GanvNode* node, gboolean show);
-
-void
-ganv_node_move(GanvNode* node,
- double dx,
- double dy);
-
-void
-ganv_node_move_to(GanvNode* node,
- double x,
- double y);
-
-void
-ganv_node_resize(GanvNode* node);
-
-void
-ganv_node_redraw_text(GanvNode* node);
-
-void
-ganv_node_disconnect(GanvNode* node);
-
-gboolean
-ganv_node_is_selected(GanvNode* node);
-
-G_END_DECLS
-
-#endif /* GANV_NODE_H */
diff --git a/ganv/port.h b/ganv/port.h
deleted file mode 100644
index 03f4bb3..0000000
--- a/ganv/port.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2014 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_PORT_H
-#define GANV_PORT_H
-
-#include "ganv/box.h"
-
-struct _GanvModule;
-
-G_BEGIN_DECLS
-
-#define GANV_TYPE_PORT (ganv_port_get_type())
-#define GANV_PORT(obj) (GTK_CHECK_CAST((obj), GANV_TYPE_PORT, GanvPort))
-#define GANV_PORT_CLASS(klass) (GTK_CHECK_CLASS_CAST((klass), GANV_TYPE_PORT, GanvPortClass))
-#define GANV_IS_PORT(obj) (GTK_CHECK_TYPE((obj), GANV_TYPE_PORT))
-#define GANV_IS_PORT_CLASS(klass) (GTK_CHECK_CLASS_TYPE((klass), GANV_TYPE_PORT))
-#define GANV_PORT_GET_CLASS(obj) (GTK_CHECK_GET_CLASS((obj), GANV_TYPE_PORT, GanvPortClass))
-
-typedef struct _GanvPortClass GanvPortClass;
-typedef struct _GanvPortPrivate GanvPortPrivate;
-
-struct _GanvPort {
- GanvBox box;
- GanvPortPrivate* impl;
-};
-
-struct _GanvPortClass {
- GanvBoxClass parent_class;
-
- /* Reserved for future expansion */
- gpointer spare_vmethods[4];
-};
-
-GType ganv_port_get_type(void) G_GNUC_CONST;
-
-GanvPort*
-ganv_port_new(GanvModule* module,
- gboolean is_input,
- const char* first_prop_name, ...);
-
-void
-ganv_port_set_value_label(GanvPort* port,
- const char* str);
-
-void
-ganv_port_show_control(GanvPort* port);
-
-void
-ganv_port_hide_control(GanvPort* port);
-
-void
-ganv_port_set_control_is_toggle(GanvPort* port,
- gboolean is_toggle);
-
-void
-ganv_port_set_control_is_integer(GanvPort* port,
- gboolean is_integer);
-
-void
-ganv_port_set_control_value(GanvPort* port,
- float value);
-
-void
-ganv_port_set_control_min(GanvPort* port,
- float min);
-
-void
-ganv_port_set_control_max(GanvPort* port,
- float max);
-
-double
-ganv_port_get_natural_width(const GanvPort* port);
-
-/**
- * ganv_port_get_module:
- * @port: The port.
- *
- * Return value: (transfer none): The module @port is on.
- */
-GanvModule* ganv_port_get_module(const GanvPort* port);
-
-float ganv_port_get_control_value(const GanvPort* port);
-float ganv_port_get_control_min(const GanvPort* port);
-float ganv_port_get_control_max(const GanvPort* port);
-gboolean ganv_port_is_input(const GanvPort* port);
-gboolean ganv_port_is_output(const GanvPort* port);
-
-G_END_DECLS
-
-#endif /* GANV_PORT_H */
diff --git a/ganv/text.h b/ganv/text.h
deleted file mode 100644
index 6f03a1b..0000000
--- a/ganv/text.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2014 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_TEXT_H
-#define GANV_TEXT_H
-
-#include "ganv/item.h"
-
-G_BEGIN_DECLS
-
-#define GANV_TYPE_TEXT (ganv_text_get_type())
-#define GANV_TEXT(obj) (GTK_CHECK_CAST((obj), GANV_TYPE_TEXT, GanvText))
-#define GANV_TEXT_CLASS(klass) (GTK_CHECK_CLASS_CAST((klass), GANV_TYPE_TEXT, GanvTextClass))
-#define GANV_IS_TEXT(obj) (GTK_CHECK_TYPE((obj), GANV_TYPE_TEXT))
-#define GANV_IS_TEXT_CLASS(klass) (GTK_CHECK_CLASS_TYPE((klass), GANV_TYPE_TEXT))
-#define GANV_TEXT_GET_CLASS(obj) (GTK_CHECK_GET_CLASS((obj), GANV_TYPE_TEXT, GanvTextClass))
-
-typedef struct _GanvText GanvText;
-typedef struct _GanvTextClass GanvTextClass;
-typedef struct _GanvTextPrivate GanvTextPrivate;
-
-struct _GanvText {
- GanvItem item;
- GanvTextPrivate* impl;
-};
-
-struct _GanvTextClass {
- GanvItemClass parent_class;
-
- /* Reserved for future expansion */
- gpointer spare_vmethodsx[4];
-};
-
-GType ganv_text_get_type(void) G_GNUC_CONST;
-
-void ganv_text_layout(GanvText* text);
-
-G_END_DECLS
-
-#endif /* GANV_TEXT_H */
diff --git a/ganv/types.h b/ganv/types.h
deleted file mode 100644
index 70c21ec..0000000
--- a/ganv/types.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2016 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_TYPES_H
-#define GANV_TYPES_H
-
-typedef struct _GanvCanvas GanvCanvas;
-typedef struct _GanvEdge GanvEdge;
-typedef struct _GanvModule GanvModule;
-typedef struct _GanvNode GanvNode;
-typedef struct _GanvPort GanvPort;
-typedef struct _GanvBox GanvBox;
-
-#endif /* GANV_TYPES_H */
diff --git a/ganv/types.hpp b/ganv/types.hpp
deleted file mode 100644
index 280af16..0000000
--- a/ganv/types.hpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2015 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_TYPES_HPP
-#define GANV_TYPES_HPP
-
-namespace Ganv {
-
-class Canvas;
-class Edge;
-class Item;
-class Module;
-class Node;
-class Port;
-
-}; // namespace Ganv
-
-#endif // GANV_TYPES_HPP
diff --git a/ganv/widget.h b/ganv/widget.h
deleted file mode 100644
index 5b54ba4..0000000
--- a/ganv/widget.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2014 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Based on GnomeCanvasWidget, by Federico Mena <federico@nuclecu.unam.mx>
- * Copyright 1997-2000 Free Software Foundation
- */
-
-#ifndef GANV_WIDGET_H
-#define GANV_WIDGET_H
-
-#include "ganv/item.h"
-
-G_BEGIN_DECLS
-
-#define GANV_TYPE_WIDGET (ganv_widget_get_type ())
-#define GANV_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GANV_TYPE_WIDGET, GanvWidget))
-#define GANV_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GANV_TYPE_WIDGET, GanvWidgetClass))
-#define GANV_IS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GANV_TYPE_WIDGET))
-#define GANV_IS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GANV_TYPE_WIDGET))
-#define GANV_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GANV_TYPE_WIDGET, GanvWidgetClass))
-
-typedef struct _GanvWidget GanvWidget;
-typedef struct _GanvWidgetPrivate GanvWidgetPrivate;
-typedef struct _GanvWidgetClass GanvWidgetClass;
-
-struct _GanvWidget {
- GanvItem item;
- GanvWidgetPrivate* impl;
-};
-
-struct _GanvWidgetClass {
- GanvItemClass parent_class;
-
- /* Reserved for future expansion */
- gpointer spare_vmethods [4];
-};
-
-GType ganv_widget_get_type(void) G_GNUC_CONST;
-
-G_END_DECLS
-
-#endif /* GANV_WIDGET_H */
diff --git a/ganv/wrap.hpp b/ganv/wrap.hpp
deleted file mode 100644
index 26e04d1..0000000
--- a/ganv/wrap.hpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2015 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_WRAP_HPP
-#define GANV_WRAP_HPP
-
-#include <glib.h>
-
-#define CONNECT_PROP_SIGNAL(gobj, name, notify, handler) \
- g_signal_connect(gobj, "notify::" #name, \
- G_CALLBACK(notify), &_signal_##name); \
- _signal_##name.connect(sigc::mem_fun(this, handler));
-
-#define SIGNAL1(name, argtype) \
-public: \
- virtual bool on_##name(argtype arg) { return true; } \
- sigc::signal<bool, argtype>& signal_##name() { return _signal_##name; } \
-private: \
- sigc::signal<bool, argtype> _signal_##name;
-
-#define RW_PROPERTY(type, name) \
- virtual type get_##name() const { \
- type value; \
- g_object_get(G_OBJECT(_gobj), #name, &value, NULL); \
- return value; \
- } \
- virtual void set_##name(type value) { \
- g_object_set(G_OBJECT(_gobj), #name, value, NULL); \
- } \
- SIGNAL1(name, type) \
- public:
-
-#define RW_OBJECT_PROPERTY(type, name) \
- type get_##name() const { \
- if (!_gobj) return NULL; \
- Ganv##type ptr; \
- g_object_get(G_OBJECT(_gobj), #name, &ptr, NULL); \
- return Glib::wrap(ptr); \
- } \
- void set_##name(type value) { \
- if (!_gobj) return; \
- ganv_item_set(GANV_ITEM(_gobj), \
- #name, value->gobj(), \
- NULL); \
- }
-
-#define METHOD0(prefix, name) \
- virtual void name() { \
- prefix##_##name(gobj()); \
- }
-
-#define METHOD1(prefix, name, t1, a1) \
- virtual void name(t1 a1) { \
- prefix##_##name(gobj(), a1); \
- }
-
-#define METHODRET0(prefix, ret, name) \
- virtual ret name() const { \
- return prefix##_##name(gobj()); \
- }
-
-#define METHODRET1(prefix, ret, name, t1, a1) \
- virtual ret name(t1 a1) { \
- return prefix##_##name(gobj(), a1); \
- }
-
-#define METHODRET2(prefix, ret, name, t1, a1, t2, a2) \
- virtual ret name(t1 a1, t2 a2) { \
- return prefix##_##name(gobj(), a1, a2); \
- }
-
-#define METHODRETWRAP0(prefix, ret, name) \
- virtual ret name() const { \
- if (gobj()) { \
- return Glib::wrap(prefix##_##name(gobj())); \
- } else { \
- return NULL; \
- } \
- }
-
-#define METHOD2(prefix, name, t1, a1, t2, a2) \
- virtual void name(t1 a1, t2 a2) { \
- prefix##_##name(gobj(), a1, a2); \
- }
-
-#define METHOD3(prefix, name, t1, a1, t2, a2, t3, a3) \
- virtual void name(t1 a1, t2 a2, t3 a3) { \
- prefix##_##name(gobj(), a1, a2, a3); \
- }
-
-#define METHOD4(prefix, name, t1, a1, t2, a2, t3, a3, t4, a4) \
- virtual void name(t1 a1, t2 a2, t3 a3, t4 a4) { \
- prefix##_##name(gobj(), a1, a2, a3, a4); \
- }
-
-#define GANV_GLIB_WRAP(Name) \
- namespace Ganv { \
- class Name; \
- } \
- namespace Glib { \
- /** Return a Ganv::CPPType wrapper for a CType. */ \
- static inline Ganv::Name* \
- wrap(Ganv##Name* gobj) \
- { \
- if (gobj) { \
- return (Ganv::Name*)ganv_item_get_wrapper(GANV_ITEM(gobj)); \
- } else { \
- return NULL; \
- } \
- } \
- /** Return a Ganv::CPPType wrapper for a CType. */ \
- static inline const Ganv::Name* \
- wrap(const Ganv##Name* gobj) \
- { \
- return wrap((Ganv##Name*)gobj); \
- } \
- }
-
-#endif // GANV_WRAP_HPP
diff --git a/gtkdoc.sh b/gtkdoc.sh
deleted file mode 100755
index 42ff39d..0000000
--- a/gtkdoc.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/sh
-
-DOC_MODULE=ganv
-
-pwd=`pwd`
-echo "gtkdoc.sh: Entering directory \`$pwd/docs'"
-
-mkdir -p docs
-cd docs
-
-export CFLAGS="`pkg-config --cflags ganv-1`"
-export LDFLAGS="`pkg-config --libs ganv-1`"
-
-# Sources have changed
-
-gtkdoc-scan --rebuild-sections --rebuild-types --ignore-headers=types.h --module=$DOC_MODULE --source-dir=../ganv
-gtkdoc-scangobj --module=$DOC_MODULE
-gtkdoc-mkdb --module=$DOC_MODULE --output-format=xml --source-dir=../ganv
-
-# XML files have changed
-mkdir -p html
-cd html && gtkdoc-mkhtml $DOC_MODULE ../ganv-docs.xml && cd -
-gtkdoc-fixxref --module=$DOC_MODULE --module-dir=html
-
-echo "gtkdoc.sh: Leaving directory \`$pwd/docs'"
-cd -
diff --git a/waflib/processor.py b/processor.py
index 2eecf3b..2eecf3b 100755
--- a/waflib/processor.py
+++ b/processor.py
diff --git a/src/Canvas.cpp b/src/Canvas.cpp
deleted file mode 100644
index 6a18cdc..0000000
--- a/src/Canvas.cpp
+++ /dev/null
@@ -1,4184 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2016 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Parts based on GnomeCanvas, by Federico Mena <federico@nuclecu.unam.mx>
- * and Raph Levien <raph@gimp.org>
- * Copyright 1997-2000 Free Software Foundation
- */
-
-#define _POSIX_C_SOURCE 200809L // strdup
-#define _XOPEN_SOURCE 600 // isascii on BSD
-
-#include <math.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <algorithm>
-#include <cassert>
-#include <cmath>
-#include <iostream>
-#include <map>
-#include <set>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include <cairo.h>
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-#include <gtk/gtkstyle.h>
-#include <gtkmm/widget.h>
-
-#include "ganv/Canvas.hpp"
-#include "ganv/Circle.hpp"
-#include "ganv/Edge.hpp"
-#include "ganv/Module.hpp"
-#include "ganv/Port.hpp"
-#include "ganv/box.h"
-#include "ganv/canvas.h"
-#include "ganv/edge.h"
-#include "ganv/group.h"
-#include "ganv/node.h"
-#include "ganv_config.h"
-
-#include "./color.h"
-#include "./ganv-marshal.h"
-#include "./ganv-private.h"
-#include "./gettext.h"
-
-#ifdef HAVE_AGRAPH
-// Deal with graphviz API amateur hour...
-# define _DLL_BLD 0
-# define _dll_import 0
-# define _BLD_cdt 0
-# define _PACKAGE_ast 0
-# include <gvc.h>
-#endif
-#ifdef GANV_FDGL
-# include "./fdgl.hpp"
-#endif
-
-#define CANVAS_IDLE_PRIORITY (GDK_PRIORITY_REDRAW - 5)
-
-static const double GANV_CANVAS_PAD = 8.0;
-
-typedef struct {
- int x;
- int y;
- int width;
- int height;
-} IRect;
-
-extern "C" {
-static void add_idle(GanvCanvas* canvas);
-static void ganv_canvas_destroy(GtkObject* object);
-static void ganv_canvas_map(GtkWidget* widget);
-static void ganv_canvas_unmap(GtkWidget* widget);
-static void ganv_canvas_realize(GtkWidget* widget);
-static void ganv_canvas_unrealize(GtkWidget* widget);
-static void ganv_canvas_size_allocate(GtkWidget* widget,
- GtkAllocation* allocation);
-static gint ganv_canvas_button(GtkWidget* widget,
- GdkEventButton* event);
-static gint ganv_canvas_motion(GtkWidget* widget,
- GdkEventMotion* event);
-static gint ganv_canvas_expose(GtkWidget* widget,
- GdkEventExpose* event);
-static gboolean ganv_canvas_key(GtkWidget* widget,
- GdkEventKey* event);
-static gboolean ganv_canvas_scroll(GtkWidget* widget,
- GdkEventScroll* event);
-static gint ganv_canvas_crossing(GtkWidget* widget,
- GdkEventCrossing* event);
-static gint ganv_canvas_focus_in(GtkWidget* widget,
- GdkEventFocus* event);
-static gint ganv_canvas_focus_out(GtkWidget* widget,
- GdkEventFocus* event);
-
-static GtkLayoutClass* canvas_parent_class;
-}
-
-static guint signal_connect;
-static guint signal_disconnect;
-
-static GEnumValue dir_values[3];
-
-typedef std::set<GanvNode*> Items;
-
-#define FOREACH_ITEM(items, i) \
- for (Items::const_iterator i = items.begin(); i != items.end(); ++i)
-
-#define FOREACH_ITEM_MUT(items, i) \
- for (Items::iterator i = items.begin(); i != items.end(); ++i)
-
-#define FOREACH_EDGE(edges, i) \
- for (GanvCanvasImpl::Edges::const_iterator i = edges.begin(); \
- i != edges.end(); \
- ++i)
-
-#define FOREACH_EDGE_MUT(edges, i) \
- for (GanvCanvasImpl::Edges::iterator i = edges.begin(); \
- i != edges.end(); \
- ++i)
-
-#define FOREACH_SELECTED_EDGE(edges, i) \
- for (GanvCanvasImpl::SelectedEdges::const_iterator i = edges.begin(); \
- i != edges.end(); \
- ++i)
-
-#define FOREACH_SELECTED_PORT(p) \
- for (SelectedPorts::iterator p = _selected_ports.begin(); \
- p != _selected_ports.end(); ++p)
-
-#ifdef HAVE_AGRAPH
-class GVNodes : public std::map<GanvNode*, Agnode_t*> {
-public:
- GVNodes() : gvc(0), G(0) {}
-
- void cleanup() {
- gvFreeLayout(gvc, G);
- agclose (G);
- gvc = 0;
- G = 0;
- }
-
- GVC_t* gvc;
- Agraph_t* G;
-};
-#endif
-
-static const uint32_t SELECT_RECT_FILL_COLOUR = 0x2E444577;
-static const uint32_t SELECT_RECT_BORDER_COLOUR = 0x2E4445FF;
-
-/* Order edges by (tail, head) */
-struct TailHeadOrder {
- inline bool operator()(const GanvEdge* a, const GanvEdge* b) const {
- return ((a->impl->tail < b->impl->tail)
- || (a->impl->tail == b->impl->tail
- && a->impl->head < b->impl->head));
- }
-};
-
-/* Order edges by (head, tail) */
-struct HeadTailOrder {
- inline bool operator()(const GanvEdge* a, const GanvEdge* b) const {
- return ((a->impl->head < b->impl->head)
- || (a->impl->head == b->impl->head
- && a->impl->tail < b->impl->tail));
- }
-};
-
-/* Callback used when the root item of a canvas is destroyed. The user should
- * never ever do this, so we panic if this happens.
- */
-static void
-panic_root_destroyed(GtkObject* object, gpointer data)
-{
- g_error("Eeeek, root item %p of canvas %p was destroyed!", (void*)object, data);
-}
-
-struct GanvCanvasImpl {
- GanvCanvasImpl(GanvCanvas* canvas)
- : _gcanvas(canvas)
- , _wrapper(NULL)
- , _connect_port(NULL)
- , _last_selected_port(NULL)
- , _drag_edge(NULL)
- , _drag_node(NULL)
- , _select_rect(NULL)
- , _select_start_x(0.0)
- , _select_start_y(0.0)
- , _drag_state(NOT_DRAGGING)
- {
- this->root = GANV_ITEM(g_object_new(ganv_group_get_type(), NULL));
- this->root->impl->canvas = canvas;
- g_object_ref_sink(this->root);
-
- this->direction = GANV_DIRECTION_RIGHT;
- this->width = 0;
- this->height = 0;
-
- this->redraw_region = NULL;
- this->current_item = NULL;
- this->new_current_item = NULL;
- this->grabbed_item = NULL;
- this->focused_item = NULL;
- this->pixmap_gc = NULL;
-
- this->pick_event.type = GDK_LEAVE_NOTIFY;
- this->pick_event.crossing.x = 0;
- this->pick_event.crossing.y = 0;
-
- this->scroll_x1 = 0.0;
- this->scroll_y1 = 0.0;
- this->scroll_x2 = canvas->layout.width;
- this->scroll_y2 = canvas->layout.height;
-
- this->pixels_per_unit = 1.0;
- this->font_size = ganv_canvas_get_default_font_size(canvas);
-
- this->idle_id = 0;
- this->root_destroy_id = g_signal_connect(
- this->root, "destroy", G_CALLBACK(panic_root_destroyed), canvas);
-
- this->redraw_x1 = 0;
- this->redraw_y1 = 0;
- this->redraw_x2 = 0;
- this->redraw_y2 = 0;
-
- this->draw_xofs = 0;
- this->draw_yofs = 0;
- this->zoom_xofs = 0;
- this->zoom_yofs = 0;
-
- this->state = 0;
- this->grabbed_event_mask = 0;
-
- this->center_scroll_region = FALSE;
- this->need_update = FALSE;
- this->need_redraw = FALSE;
- this->need_repick = TRUE;
- this->left_grabbed_item = FALSE;
- this->in_repick = FALSE;
- this->locked = FALSE;
- this->exporting = FALSE;
-
-#ifdef GANV_FDGL
- this->layout_idle_id = 0;
- this->layout_energy = 0.4;
- this->sprung_layout = FALSE;
-#endif
-
- _animate_idle_id = 0;
-
- _port_order.port_cmp = NULL;
- _port_order.data = NULL;
-
- gtk_layout_set_hadjustment(GTK_LAYOUT(canvas), NULL);
- gtk_layout_set_vadjustment(GTK_LAYOUT(canvas), NULL);
-
- _move_cursor = gdk_cursor_new(GDK_FLEUR);
- }
-
- ~GanvCanvasImpl()
- {
- if (_animate_idle_id) {
- g_source_remove(_animate_idle_id);
- _animate_idle_id = 0;
- }
-
- while (g_idle_remove_by_data(this)) {}
- ganv_canvas_clear(_gcanvas);
- gdk_cursor_unref(_move_cursor);
- }
-
- static gboolean on_animate_timeout(gpointer impl);
-
-#ifdef GANV_FDGL
- static gboolean on_layout_timeout(gpointer impl) {
- return ((GanvCanvasImpl*)impl)->layout_iteration();
- }
-
- static void on_layout_done(gpointer impl) {
- ((GanvCanvasImpl*)impl)->layout_idle_id = 0;
- }
-
- gboolean layout_iteration();
- gboolean layout_calculate(double dur, bool update);
-#endif
-
- void unselect_ports();
-
-#ifdef HAVE_AGRAPH
- GVNodes layout_dot(const std::string& filename);
-#endif
-
- typedef std::set<GanvEdge*, TailHeadOrder> Edges;
- typedef std::set<GanvEdge*, HeadTailOrder> DstEdges;
- typedef std::set<GanvEdge*> SelectedEdges;
- typedef std::set<GanvPort*> SelectedPorts;
-
- Edges::const_iterator first_edge_from(const GanvNode* src);
- DstEdges::const_iterator first_edge_to(const GanvNode* dst);
-
- void select_port(GanvPort* p, bool unique=false);
- void select_port_toggle(GanvPort* p, int mod_state);
- void unselect_port(GanvPort* p);
- void selection_joined_with(GanvPort* port);
- void join_selection();
-
- GanvNode* get_node_at(double x, double y);
-
- bool on_event(GdkEvent* event);
-
- bool scroll_drag_handler(GdkEvent* event);
- bool select_drag_handler(GdkEvent* event);
- bool connect_drag_handler(GdkEvent* event);
- void end_connect_drag();
-
- /*
- Event handler for ports.
-
- This must be implemented as a Canvas method since port event handling
- depends on shared data (for selection and connecting). This function
- should only be used by Port implementations.
- */
- bool port_event(GdkEvent* event, GanvPort* port);
-
- void ports_joined(GanvPort* port1, GanvPort* port2);
- void port_clicked(GdkEvent* event, GanvPort* port);
- void highlight_port(GanvPort* port, bool highlight);
-
- void move_contents_to_internal(double x, double y, double min_x, double min_y);
-
- GanvCanvas* _gcanvas;
- Ganv::Canvas* _wrapper;
-
- Items _items; ///< Items on this canvas
- Edges _edges; ///< Edges ordered (src, dst)
- DstEdges _dst_edges; ///< Edges ordered (dst, src)
- Items _selected_items; ///< Currently selected items
- SelectedEdges _selected_edges; ///< Currently selected edges
-
- SelectedPorts _selected_ports; ///< Selected ports (hilited red)
- GanvPort* _connect_port; ///< Port for which a edge is being made
- GanvPort* _last_selected_port;
- GanvEdge* _drag_edge;
- GanvNode* _drag_node;
-
- GanvBox* _select_rect; ///< Rectangle for drag selection
- double _select_start_x; ///< Selection drag start x coordinate
- double _select_start_y; ///< Selection drag start y coordinate
-
- enum DragState { NOT_DRAGGING, EDGE, SCROLL, SELECT };
- DragState _drag_state;
-
- GdkCursor* _move_cursor;
- guint _animate_idle_id;
-
- PortOrderCtx _port_order;
-
- /* Root canvas item */
- GanvItem* root;
-
- /* Flow direction */
- GanvDirection direction;
-
- /* Canvas width */
- double width;
-
- /* Canvas height */
- double height;
-
- /* Region that needs redrawing (list of rectangles) */
- GSList* redraw_region;
-
- /* The item containing the mouse pointer, or NULL if none */
- GanvItem* current_item;
-
- /* Item that is about to become current (used to track deletions and such) */
- GanvItem* new_current_item;
-
- /* Item that holds a pointer grab, or NULL if none */
- GanvItem* grabbed_item;
-
- /* If non-NULL, the currently focused item */
- GanvItem* focused_item;
-
- /* GC for temporary draw pixmap */
- GdkGC* pixmap_gc;
-
- /* Event on which selection of current item is based */
- GdkEvent pick_event;
-
- /* Scrolling region */
- double scroll_x1;
- double scroll_y1;
- double scroll_x2;
- double scroll_y2;
-
- /* Scaling factor to be used for display */
- double pixels_per_unit;
-
- /* Font size in points */
- double font_size;
-
- /* Idle handler ID */
- guint idle_id;
-
- /* Signal handler ID for destruction of the root item */
- guint root_destroy_id;
-
- /* Area that is being redrawn. Contains (x1, y1) but not (x2, y2).
- * Specified in canvas pixel coordinates.
- */
- int redraw_x1;
- int redraw_y1;
- int redraw_x2;
- int redraw_y2;
-
- /* Offsets of the temprary drawing pixmap */
- int draw_xofs;
- int draw_yofs;
-
- /* Internal pixel offsets when zoomed out */
- int zoom_xofs;
- int zoom_yofs;
-
- /* Last known modifier state, for deferred repick when a button is down */
- int state;
-
- /* Event mask specified when grabbing an item */
- guint grabbed_event_mask;
-
- /* Whether the canvas should center the scroll region in the middle of
- * the window if the scroll region is smaller than the window.
- */
- gboolean center_scroll_region;
-
- /* Whether items need update at next idle loop iteration */
- gboolean need_update;
-
- /* Whether the canvas needs redrawing at the next idle loop iteration */
- gboolean need_redraw;
-
- /* Whether current item will be repicked at next idle loop iteration */
- gboolean need_repick;
-
- /* For use by internal pick_current_item() function */
- gboolean left_grabbed_item;
-
- /* For use by internal pick_current_item() function */
- gboolean in_repick;
-
- /* Disable changes to canvas */
- gboolean locked;
-
- /* True if the current draw is an export */
- gboolean exporting;
-
-#ifdef GANV_FDGL
- guint layout_idle_id;
- gdouble layout_energy;
- gboolean sprung_layout;
-#endif
-};
-
-typedef struct {
- GanvItem item;
- GanvEdgePrivate* impl;
- GanvEdgePrivate impl_data;
-} GanvEdgeKey;
-
-static void
-make_edge_search_key(GanvEdgeKey* key,
- const GanvNode* tail,
- const GanvNode* head)
-{
- memset(key, '\0', sizeof(GanvEdgeKey));
- key->impl = &key->impl_data;
- key->impl->tail = const_cast<GanvNode*>(tail);
- key->impl->head = const_cast<GanvNode*>(head);
-}
-
-GanvCanvasImpl::Edges::const_iterator
-GanvCanvasImpl::first_edge_from(const GanvNode* tail)
-{
- GanvEdgeKey key;
- make_edge_search_key(&key, tail, NULL);
- return _edges.lower_bound((GanvEdge*)&key);
-}
-
-GanvCanvasImpl::DstEdges::const_iterator
-GanvCanvasImpl::first_edge_to(const GanvNode* head)
-{
- GanvEdgeKey key;
- make_edge_search_key(&key, NULL, head);
- return _dst_edges.lower_bound((GanvEdge*)&key);
-}
-
-static void
-select_if_tail_is_selected(GanvEdge* edge, void* data)
-{
- GanvNode* tail = edge->impl->tail;
- gboolean selected;
- g_object_get(tail, "selected", &selected, NULL);
- if (!selected && GANV_IS_PORT(tail)) {
- g_object_get(ganv_port_get_module(GANV_PORT(tail)),
- "selected", &selected, NULL);
- }
-
- if (selected) {
- ganv_edge_select(edge);
- }
-}
-
-static void
-select_if_head_is_selected(GanvEdge* edge, void* data)
-{
- GanvNode* head = edge->impl->head;
- gboolean selected;
- g_object_get(head, "selected", &selected, NULL);
- if (!selected && GANV_IS_PORT(head)) {
- g_object_get(ganv_port_get_module(GANV_PORT(head)),
- "selected", &selected, NULL);
- }
-
- if (selected) {
- ganv_edge_set_selected(edge, TRUE);
- }
-}
-
-static void
-select_edges(GanvPort* port, void* data)
-{
- GanvCanvasImpl* impl = (GanvCanvasImpl*)data;
- if (port->impl->is_input) {
- ganv_canvas_for_each_edge_to(impl->_gcanvas,
- GANV_NODE(port),
- select_if_tail_is_selected,
- NULL);
- } else {
- ganv_canvas_for_each_edge_from(impl->_gcanvas,
- GANV_NODE(port),
- select_if_head_is_selected,
- NULL);
- }
-}
-
-#ifdef HAVE_AGRAPH
-static void
-gv_set(void* subject, const char* key, double value)
-{
- std::ostringstream ss;
- ss << value;
- agsafeset(subject, (char*)key, (char*)ss.str().c_str(), (char*)"");
-}
-
-GVNodes
-GanvCanvasImpl::layout_dot(const std::string& filename)
-{
- GVNodes nodes;
-
- const double dpi = gdk_screen_get_resolution(gdk_screen_get_default());
-
- GVC_t* gvc = gvContext();
-
- Agraph_t* G = agopen((char*)"g", Agdirected, NULL);
-
- agsafeset(G, (char*)"splines", (char*)"false", (char*)"");
- agsafeset(G, (char*)"compound", (char*)"true", (char*)"");
- agsafeset(G, (char*)"remincross", (char*)"true", (char*)"");
- agsafeset(G, (char*)"overlap", (char*)"scale", (char*)"");
- agsafeset(G, (char*)"nodesep", (char*)"0.05", (char*)"");
- gv_set(G, "fontsize", ganv_canvas_get_font_size(_gcanvas));
- gv_set(G, "dpi", dpi);
-
- nodes.gvc = gvc;
- nodes.G = G;
-
- const bool flow_right = _gcanvas->impl->direction;
- if (flow_right) {
- agattr(G, AGRAPH, (char*)"rankdir", (char*)"LR");
- } else {
- agattr(G, AGRAPH, (char*)"rankdir", (char*)"TD");
- }
-
- unsigned id = 0;
- std::ostringstream ss;
- FOREACH_ITEM(_items, i) {
- ss.str("");
- ss << "n" << id++;
- const std::string node_id = ss.str();
-
- Agnode_t* node = agnode(G, strdup(node_id.c_str()), true);
- nodes.insert(std::make_pair(*i, node));
-
- if (GANV_IS_MODULE(*i)) {
- GanvModule* const m = GANV_MODULE(*i);
-
- agsafeset(node, (char*)"shape", (char*)"plaintext", (char*)"");
- gv_set(node, "width", ganv_box_get_width(GANV_BOX(*i)) / dpi);
- gv_set(node, "height", ganv_box_get_height(GANV_BOX(*i)) / dpi);
-
- std::string inputs; // Down flow
- std::string outputs; // Down flow
- std::string ports; // Right flow
- unsigned n_inputs = 0;
- unsigned n_outputs = 0;
- for (size_t i = 0; i < ganv_module_num_ports(m); ++i) {
- GanvPort* port = ganv_module_get_port(m, i);
- ss.str("");
- ss << port;
-
- if (port->impl->is_input) {
- ++n_inputs;
- } else {
- ++n_outputs;
- }
-
- std::string cell = std::string("<TD PORT=\"") + ss.str() + "\"";
-
- cell += " FIXEDSIZE=\"TRUE\"";
- ss.str("");
- ss << ganv_box_get_width(GANV_BOX(port));// / dpp * 1.3333333;
- cell += " WIDTH=\"" + ss.str() + "\"";
-
- ss.str("");
- ss << ganv_box_get_height(GANV_BOX(port));// / dpp * 1.333333;
- cell += " HEIGHT=\"" + ss.str() + "\"";
-
- cell += ">";
- const char* label = ganv_node_get_label(GANV_NODE(port));
- if (label && flow_right) {
- cell += label;
- }
- cell += "</TD>";
-
- if (flow_right) {
- ports += "<TR>" + cell + "</TR>";
- } else if (port->impl->is_input) {
- inputs += cell;
- } else {
- outputs += cell;
- }
-
- nodes.insert(std::make_pair(GANV_NODE(port), node));
- }
-
- const unsigned n_cols = std::max(n_inputs, n_outputs);
-
- std::string html = "<TABLE CELLPADDING=\"0\" CELLSPACING=\"0\">";
-
- // Input row (down flow only)
- if (!inputs.empty()) {
- for (unsigned i = n_inputs; i < n_cols + 1; ++i) {
- inputs += "<TD BORDER=\"0\"></TD>";
- }
- html += std::string("<TR>") + inputs + "</TR>";
- }
-
- // Label row
- std::stringstream colspan;
- colspan << (flow_right ? 1 : (n_cols + 1));
- html += std::string("<TR><TD BORDER=\"0\" CELLPADDING=\"2\" COLSPAN=\"")
- + colspan.str()
- + "\">";
- const char* label = ganv_node_get_label(GANV_NODE(m));
- if (label) {
- html += label;
- }
- html += "</TD></TR>";
-
- // Ports rows (right flow only)
- if (!ports.empty()) {
- html += ports;
- }
-
- // Output row (down flow only)
- if (!outputs.empty()) {
- for (unsigned i = n_outputs; i < n_cols + 1; ++i) {
- outputs += "<TD BORDER=\"0\"></TD>";
- }
- html += std::string("<TR>") + outputs + "</TR>";
- }
- html += "</TABLE>";
-
- char* html_label_str = agstrdup_html(G, (char*)html.c_str());
-
- agsafeset(node, (char*)"label", (char*)html_label_str, (char*)"");
- } else if (GANV_IS_CIRCLE(*i)) {
- agsafeset(node, (char*)"shape", (char*)"circle", (char*)"");
- agsafeset(node, (char*)"fixedsize", (char*)"true", (char*)"");
- agsafeset(node, (char*)"margin", (char*)"0.0,0.0", (char*)"");
-
- const double radius = ganv_circle_get_radius(GANV_CIRCLE(*i));
- const double penwidth = ganv_node_get_border_width(GANV_NODE(*i));
- const double span = (radius + penwidth) * 2.3 / dpi;
- gv_set(node, (char*)"width", span);
- gv_set(node, (char*)"height", span);
- gv_set(node, (char*)"penwidth", penwidth);
-
- if (ganv_node_get_dash_length(GANV_NODE(*i)) > 0.0) {
- agsafeset(node, (char*)"style", (char*)"dashed", (char*)"");
- }
-
- const char* label = ganv_node_get_label(GANV_NODE(*i));
- if (label) {
- agsafeset(node, (char*)"label", (char*)label, (char*)"");
- } else {
- agsafeset(node, (char*)"label", (char*)"", (char*)"");
- }
- } else {
- std::cerr << "Unable to arrange item of unknown type" << std::endl;
- }
- }
-
- FOREACH_EDGE(_edges, i) {
- const GanvEdge* const edge = *i;
- GVNodes::iterator tail_i = nodes.find(edge->impl->tail);
- GVNodes::iterator head_i = nodes.find(edge->impl->head);
-
- if (tail_i != nodes.end() && head_i != nodes.end()) {
- Agedge_t* e = agedge(G, tail_i->second, head_i->second, NULL, true);
- if (GANV_IS_PORT(edge->impl->tail)) {
- ss.str((char*)"");
- ss << edge->impl->tail << (flow_right ? ":e" : ":s");
- agsafeset(e, (char*)"tailport", (char*)ss.str().c_str(), (char*)"");
- }
- if (GANV_IS_PORT(edge->impl->head)) {
- ss.str((char*)"");
- ss << edge->impl->head << (flow_right ? ":w" : ":n");
- agsafeset(e, (char*)"headport", (char*)ss.str().c_str(), (char*)"");
- }
- if (!ganv_edge_get_constraining(edge)) {
- agsafeset(e, (char*)"constraint", (char*)"false", (char*)"");
- }
- } else {
- std::cerr << "Unable to find graphviz node" << std::endl;
- }
- }
-
- // Add edges between partners to have them lined up as if connected
- for (GVNodes::iterator i = nodes.begin(); i != nodes.end(); ++i) {
- GanvNode* partner = ganv_node_get_partner(i->first);
- if (partner) {
- GVNodes::iterator p = nodes.find(partner);
- if (p != nodes.end()) {
- Agedge_t* e = agedge(G, i->second, p->second, NULL, true);
- agsafeset(e, (char*)"style", (char*)"invis", (char*)"");
- }
- }
- }
-
- gvLayout(gvc, G, (char*)"dot");
- FILE* tmp = fopen("/dev/null", "w");
- gvRender(gvc, G, (char*)"dot", tmp);
- fclose(tmp);
-
- if (filename != "") {
- FILE* fd = fopen(filename.c_str(), "w");
- gvRender(gvc, G, (char*)"dot", fd);
- fclose(fd);
- }
-
- return nodes;
-}
-#endif
-
-inline uint64_t
-get_monotonic_time()
-{
-#if GLIB_CHECK_VERSION(2, 28, 0)
- return g_get_monotonic_time();
-#else
- GTimeVal time;
- g_get_current_time(&time);
- return time.tv_sec + time.tv_usec;
-#endif
-}
-
-#ifdef GANV_FDGL
-
-inline Region
-get_region(GanvNode* node)
-{
- GanvItem* item = &node->item;
-
- double x1, y1, x2, y2;
- ganv_item_get_bounds(item, &x1, &y1, &x2, &y2);
-
- Region reg;
- ganv_item_get_bounds(item, &reg.pos.x, &reg.pos.y, &reg.area.x, &reg.area.y);
- reg.area.x = x2 - x1;
- reg.area.y = y2 - y1;
- reg.pos.x = item->impl->x + (reg.area.x / 2.0);
- reg.pos.y = item->impl->y + (reg.area.y / 2.0);
-
- // No need for i2w here since we only care about top-level items
- return reg;
-}
-
-inline void
-apply_force(GanvNode* a, GanvNode* b, const Vector& f)
-{
- a->impl->force = vec_add(a->impl->force, f);
- b->impl->force = vec_sub(b->impl->force, f);
-}
-
-gboolean
-GanvCanvasImpl::layout_iteration()
-{
- if (_drag_state == EDGE) {
- return FALSE; // Canvas is locked, halt layout process
- } else if (!sprung_layout) {
- return FALSE; // We shouldn't be running at all
- }
-
- static const double T_PER_US = .0001; // Sym time per real microsecond
-
- static uint64_t prev = 0; // Previous iteration time
-
- const uint64_t now = get_monotonic_time();
- const double time_to_run = std::min((now - prev) * T_PER_US, 10.0);
-
- prev = now;
-
- const double QUANTUM = 0.05;
- double sym_time = 0.0;
- while (sym_time + QUANTUM < time_to_run) {
- if (!layout_calculate(QUANTUM, FALSE)) {
- break;
- }
- sym_time += QUANTUM;
- }
-
- return layout_calculate(QUANTUM, TRUE);
-}
-
-gboolean
-GanvCanvasImpl::layout_calculate(double dur, bool update)
-{
- // A light directional force to push sources to the top left
- static const double DIR_MAGNITUDE = -1000.0;
- Vector dir = { 0.0, 0.0 };
- switch (_gcanvas->impl->direction) {
- case GANV_DIRECTION_RIGHT: dir.x = DIR_MAGNITUDE; break;
- case GANV_DIRECTION_DOWN: dir.y = DIR_MAGNITUDE; break;
- }
-
- // Calculate attractive spring forces for edges
- FOREACH_EDGE(_edges, i) {
- const GanvEdge* const edge = *i;
- if (!ganv_edge_get_constraining(edge)) {
- continue;
- }
-
- GanvNode* tail = ganv_edge_get_tail(edge);
- GanvNode* head = ganv_edge_get_head(edge);
- if (GANV_IS_PORT(tail)) {
- tail = GANV_NODE(ganv_port_get_module(GANV_PORT(tail)));
- }
- if (GANV_IS_PORT(head)) {
- head = GANV_NODE(ganv_port_get_module(GANV_PORT(head)));
- }
- if (tail == head) {
- continue;
- }
-
- head->impl->connected = tail->impl->connected = TRUE;
-
- GanvEdgeCoords coords;
- ganv_edge_get_coords(edge, &coords);
-
- const Vector tpos = { coords.x1, coords.y1 };
- const Vector hpos = { coords.x2, coords.y2 };
- apply_force(tail, head, edge_force(dir, hpos, tpos));
- }
-
- // Calculate repelling forces between nodes
- FOREACH_ITEM(_items, i) {
- if (!GANV_IS_MODULE(*i) && !GANV_IS_CIRCLE(*i)) {
- continue;
- }
-
- GanvNode* const node = *i;
- GanvNode* partner = ganv_node_get_partner(node);
- if (!partner && !node->impl->connected) {
- continue;
- }
-
- const Region reg = get_region(node);
- if (partner) {
- // Add fake long spring to partner to line up as if connected
- const Region preg = get_region(partner);
- apply_force(node, partner, edge_force(dir, preg.pos, reg.pos));
- }
-
- /* Add tide force which pulls all objects as if the layout is happening
- on a flowing river surface. This prevents disconnected components
- from being ejected, since at some point the tide force will be
- greater than distant repelling charges. */
- const Vector mouth = { -100000.0, -100000.0 };
- node->impl->force = vec_add(
- node->impl->force,
- tide_force(mouth, reg.pos, 4000000000000.0));
-
- // Add slight noise to force to limit oscillation
- const Vector noise = { rand() / (float)RAND_MAX * 128.0,
- rand() / (float)RAND_MAX * 128.0 };
- node->impl->force = vec_add(noise, node->impl->force);
-
- FOREACH_ITEM(_items, j) {
- if (i == j || (!GANV_IS_MODULE(*i) && !GANV_IS_CIRCLE(*i))) {
- continue;
- }
- apply_force(node, *j, repel_force(reg, get_region(*j)));
- }
- }
-
- // Update positions based on calculated forces
- size_t n_moved = 0;
- FOREACH_ITEM(_items, i) {
- if (!GANV_IS_MODULE(*i) && !GANV_IS_CIRCLE(*i)) {
- continue;
- }
-
- GanvNode* const node = *i;
-
- if (node->impl->grabbed ||
- (!node->impl->connected && !ganv_node_get_partner(node))) {
- node->impl->vel.x = 0.0;
- node->impl->vel.y = 0.0;
- } else {
- node->impl->vel = vec_add(node->impl->vel,
- vec_mult(node->impl->force, dur));
- node->impl->vel = vec_mult(node->impl->vel, layout_energy);
-
- static const double MAX_VEL = 1000.0;
- static const double MIN_COORD = 4.0;
-
- // Clamp velocity
- const double vel_mag = vec_mag(node->impl->vel);
- if (vel_mag > MAX_VEL) {
- node->impl->vel = vec_mult(
- vec_mult(node->impl->vel, 1.0 / vel_mag),
- MAX_VEL);
- }
-
- // Update position
- GanvItem* item = &node->item;
- const double x0 = item->impl->x;
- const double y0 = item->impl->y;
- const Vector dpos = vec_mult(node->impl->vel, dur);
-
- item->impl->x = std::max(MIN_COORD, item->impl->x + dpos.x);
- item->impl->y = std::max(MIN_COORD, item->impl->y + dpos.y);
-
- if (update) {
- ganv_item_request_update(item);
- item->impl->canvas->impl->need_repick = TRUE;
- }
-
- if (lrint(x0) != lrint(item->impl->x) || lrint(y0) != lrint(item->impl->y)) {
- ++n_moved;
- }
- }
-
- // Reset forces for next time
- node->impl->force.x = 0.0;
- node->impl->force.y = 0.0;
- node->impl->connected = FALSE;
- }
-
- if (update) {
- // Now update edge positions to reflect new node positions
- FOREACH_EDGE(_edges, i) {
- GanvEdge* const edge = *i;
- ganv_edge_update_location(edge);
- }
- }
-
- layout_energy *= 0.999;
- return n_moved > 0;
-}
-
-#endif // GANV_FDGL
-
-void
-GanvCanvasImpl::select_port(GanvPort* p, bool unique)
-{
- if (unique) {
- unselect_ports();
- }
- g_object_set(G_OBJECT(p), "selected", TRUE, NULL);
- _selected_ports.insert(p);
- _last_selected_port = p;
-}
-
-void
-GanvCanvasImpl::select_port_toggle(GanvPort* port, int mod_state)
-{
- gboolean selected;
- g_object_get(G_OBJECT(port), "selected", &selected, NULL);
- if ((mod_state & GDK_CONTROL_MASK)) {
- if (selected)
- unselect_port(port);
- else
- select_port(port);
- } else if ((mod_state & GDK_SHIFT_MASK)) {
- GanvModule* const m = ganv_port_get_module(port);
- if (_last_selected_port && m
- && ganv_port_get_module(_last_selected_port) == m) {
- // Pivot around _last_selected_port in a single pass over module ports each click
- GanvPort* old_last_selected = _last_selected_port;
- GanvPort* first = NULL;
- bool done = false;
- for (size_t i = 0; i < ganv_module_num_ports(m); ++i) {
- GanvPort* const p = ganv_module_get_port(m, i);
- if (!first && !done && (p == _last_selected_port || p == port)) {
- first = p;
- }
-
- if (first && !done && p->impl->is_input == first->impl->is_input) {
- select_port(p, false);
- } else {
- unselect_port(p);
- }
-
- if (p != first && (p == old_last_selected || p == port)) {
- done = true;
- }
- }
- _last_selected_port = old_last_selected;
- } else {
- if (selected) {
- unselect_port(port);
- } else {
- select_port(port);
- }
- }
- } else {
- if (selected) {
- unselect_ports();
- } else {
- select_port(port, true);
- }
- }
-}
-
-void
-GanvCanvasImpl::unselect_port(GanvPort* p)
-{
- _selected_ports.erase(p);
- g_object_set(G_OBJECT(p), "selected", FALSE, NULL);
- if (_last_selected_port == p) {
- _last_selected_port = NULL;
- }
-}
-
-void
-GanvCanvasImpl::selection_joined_with(GanvPort* port)
-{
- FOREACH_SELECTED_PORT(i)
- ports_joined(*i, port);
-}
-
-void
-GanvCanvasImpl::join_selection()
-{
- std::vector<GanvPort*> inputs;
- std::vector<GanvPort*> outputs;
- FOREACH_SELECTED_PORT(i) {
- if ((*i)->impl->is_input) {
- inputs.push_back(*i);
- } else {
- outputs.push_back(*i);
- }
- }
-
- if (inputs.size() == 1) { // 1 -> n
- for (size_t i = 0; i < outputs.size(); ++i)
- ports_joined(inputs[0], outputs[i]);
- } else if (outputs.size() == 1) { // n -> 1
- for (size_t i = 0; i < inputs.size(); ++i)
- ports_joined(inputs[i], outputs[0]);
- } else { // n -> m
- size_t num_to_connect = std::min(inputs.size(), outputs.size());
- for (size_t i = 0; i < num_to_connect; ++i) {
- ports_joined(inputs[i], outputs[i]);
- }
- }
-}
-
-GanvNode*
-GanvCanvasImpl::get_node_at(double x, double y)
-{
- GanvItem* item = ganv_canvas_get_item_at(GANV_CANVAS(_gcanvas), x, y);
- while (item) {
- if (GANV_IS_NODE(item)) {
- return GANV_NODE(item);
- } else {
- item = item->impl->parent;
- }
- }
-
- return NULL;
-}
-
-bool
-GanvCanvasImpl::on_event(GdkEvent* event)
-{
- static const int scroll_increment = 10;
- int scroll_x, scroll_y;
-
- bool handled = false;
- switch (event->type) {
- case GDK_KEY_PRESS:
- handled = true;
- ganv_canvas_get_scroll_offsets(GANV_CANVAS(_gcanvas), &scroll_x, &scroll_y);
- switch (event->key.keyval) {
- case GDK_Up:
- scroll_y -= scroll_increment;
- break;
- case GDK_Down:
- scroll_y += scroll_increment;
- break;
- case GDK_Left:
- scroll_x -= scroll_increment;
- break;
- case GDK_Right:
- scroll_x += scroll_increment;
- break;
- case GDK_Return:
- if (_selected_ports.size() > 1) {
- join_selection();
- ganv_canvas_clear_selection(_gcanvas);
- }
- break;
- default:
- handled = false;
- }
- if (handled) {
- ganv_canvas_scroll_to(GANV_CANVAS(_gcanvas), scroll_x, scroll_y);
- return true;
- }
- break;
-
- case GDK_SCROLL:
- if ((event->scroll.state & GDK_CONTROL_MASK)) {
- const double zoom = ganv_canvas_get_zoom(_gcanvas);
- if (event->scroll.direction == GDK_SCROLL_UP) {
- ganv_canvas_set_zoom(_gcanvas, zoom * 1.25);
- return true;
- } else if (event->scroll.direction == GDK_SCROLL_DOWN) {
- ganv_canvas_set_zoom(_gcanvas, zoom * 0.75);
- return true;
- }
- }
- break;
-
- default:
- break;
- }
-
- return scroll_drag_handler(event)
- || select_drag_handler(event)
- || connect_drag_handler(event);
-}
-
-bool
-GanvCanvasImpl::scroll_drag_handler(GdkEvent* event)
-{
- bool handled = true;
-
- static int original_scroll_x = 0;
- static int original_scroll_y = 0;
- static double origin_x = 0;
- static double origin_y = 0;
- static double scroll_offset_x = 0;
- static double scroll_offset_y = 0;
- static double last_x = 0;
- static double last_y = 0;
-
- GanvItem* root = ganv_canvas_root(_gcanvas);
-
- if (event->type == GDK_BUTTON_PRESS && event->button.button == 2) {
- ganv_canvas_grab_item(
- root,
- GDK_POINTER_MOTION_MASK|GDK_BUTTON_RELEASE_MASK,
- NULL, event->button.time);
- ganv_canvas_get_scroll_offsets(GANV_CANVAS(_gcanvas), &original_scroll_x, &original_scroll_y);
- scroll_offset_x = 0;
- scroll_offset_y = 0;
- origin_x = event->button.x_root;
- origin_y = event->button.y_root;
- //cerr << "Origin: (" << origin_x << "," << origin_y << ")\n";
- last_x = origin_x;
- last_y = origin_y;
- _drag_state = SCROLL;
-
- } else if (event->type == GDK_MOTION_NOTIFY && _drag_state == SCROLL) {
- const double x = event->motion.x_root;
- const double y = event->motion.y_root;
- const double x_offset = last_x - x;
- const double y_offset = last_y - y;
-
- //cerr << "Coord: (" << x << "," << y << ")\n";
- //cerr << "Offset: (" << x_offset << "," << y_offset << ")\n";
-
- scroll_offset_x += x_offset;
- scroll_offset_y += y_offset;
- ganv_canvas_scroll_to(GANV_CANVAS(_gcanvas),
- lrint(original_scroll_x + scroll_offset_x),
- lrint(original_scroll_y + scroll_offset_y));
- last_x = x;
- last_y = y;
- } else if (event->type == GDK_BUTTON_RELEASE && _drag_state == SCROLL) {
- ganv_canvas_ungrab_item(root, event->button.time);
- _drag_state = NOT_DRAGGING;
- } else {
- handled = false;
- }
-
- return handled;
-}
-
-static void
-get_motion_coords(GdkEventMotion* motion, double* x, double* y)
-{
- if (motion->is_hint) {
- gint px;
- gint py;
- GdkModifierType state;
- gdk_window_get_pointer(motion->window, &px, &py, &state);
- *x = px;
- *y = py;
- } else {
- *x = motion->x;
- *y = motion->y;
- }
-}
-
-bool
-GanvCanvasImpl::select_drag_handler(GdkEvent* event)
-{
- GanvItem* root = ganv_canvas_root(_gcanvas);
- if (event->type == GDK_BUTTON_PRESS && event->button.button == 1) {
- assert(_select_rect == NULL);
- _drag_state = SELECT;
- if ( !(event->button.state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) )
- ganv_canvas_clear_selection(_gcanvas);
- _select_rect = GANV_BOX(
- ganv_item_new(
- root,
- ganv_box_get_type(),
- "x1", event->button.x,
- "y1", event->button.y,
- "x2", event->button.x,
- "y2", event->button.y,
- "fill-color", SELECT_RECT_FILL_COLOUR,
- "border-color", SELECT_RECT_BORDER_COLOUR,
- NULL));
- _select_start_x = event->button.x;
- _select_start_y = event->button.y;
- ganv_canvas_grab_item(
- root, GDK_POINTER_MOTION_MASK|GDK_BUTTON_RELEASE_MASK,
- NULL, event->button.time);
- return true;
- } else if (event->type == GDK_MOTION_NOTIFY && _drag_state == SELECT) {
- assert(_select_rect);
- double x, y;
- get_motion_coords(&event->motion, &x, &y);
- _select_rect->impl->coords.x1 = MIN(_select_start_x, x);
- _select_rect->impl->coords.y1 = MIN(_select_start_y, y);
- _select_rect->impl->coords.x2 = MAX(_select_start_x, x);
- _select_rect->impl->coords.y2 = MAX(_select_start_y, y);
- ganv_item_request_update(&_select_rect->node.item);
- return true;
- } else if (event->type == GDK_BUTTON_RELEASE && _drag_state == SELECT) {
- // Normalize select rect
- ganv_box_normalize(_select_rect);
-
- // Select all modules within rect
- FOREACH_ITEM(_items, i) {
- GanvNode* node = *i;
- if ((void*)node != (void*)_select_rect &&
- ganv_node_is_within(
- node,
- ganv_box_get_x1(_select_rect),
- ganv_box_get_y1(_select_rect),
- ganv_box_get_x2(_select_rect),
- ganv_box_get_y2(_select_rect))) {
- gboolean selected;
- g_object_get(G_OBJECT(node), "selected", &selected, NULL);
- if (selected) {
- ganv_canvas_unselect_node(_gcanvas, node);
- } else {
- ganv_canvas_select_node(_gcanvas, node);
- }
- }
- }
-
- // Select all edges with handles within rect
- FOREACH_EDGE(_edges, i) {
- if (ganv_edge_is_within(
- (*i),
- ganv_box_get_x1(_select_rect),
- ganv_box_get_y1(_select_rect),
- ganv_box_get_x2(_select_rect),
- ganv_box_get_y2(_select_rect))) {
- ganv_canvas_select_edge(_gcanvas, *i);
- }
- }
-
- ganv_canvas_ungrab_item(root, event->button.time);
-
- gtk_object_destroy(GTK_OBJECT(_select_rect));
- _select_rect = NULL;
- _drag_state = NOT_DRAGGING;
- return true;
- }
- return false;
-}
-
-bool
-GanvCanvasImpl::connect_drag_handler(GdkEvent* event)
-{
- static bool snapped = false;
-
- if (_drag_state != EDGE) {
- return false;
- }
-
- if (event->type == GDK_MOTION_NOTIFY) {
- double x, y;
- get_motion_coords(&event->motion, &x, &y);
-
- if (!_drag_edge) {
- // Create drag edge
- assert(!_drag_node);
- assert(_connect_port);
-
- _drag_node = GANV_NODE(
- ganv_item_new(
- GANV_ITEM(ganv_canvas_root(GANV_CANVAS(_gcanvas))),
- ganv_node_get_type(),
- "x", x,
- "y", y,
- NULL));
-
- _drag_edge = ganv_edge_new(
- _gcanvas,
- GANV_NODE(_connect_port),
- _drag_node,
- "color", GANV_NODE(_connect_port)->impl->fill_color,
- "curved", TRUE,
- "ghost", TRUE,
- NULL);
- }
-
- GanvNode* joinee = get_node_at(x, y);
- if (joinee && ganv_node_can_head(joinee) && joinee != _drag_node) {
- // Snap to item
- snapped = true;
- ganv_item_set(&_drag_edge->item, "head", joinee, NULL);
- } else if (snapped) {
- // Unsnap from item
- snapped = false;
- ganv_item_set(&_drag_edge->item, "head", _drag_node, NULL);
- }
-
- // Update drag edge for pointer position
- ganv_node_move_to(_drag_node, x, y);
- ganv_item_request_update(GANV_ITEM(_drag_node));
- ganv_item_request_update(GANV_ITEM(_drag_edge));
-
- return true;
-
- } else if (event->type == GDK_BUTTON_RELEASE) {
- ganv_canvas_ungrab_item(root, event->button.time);
-
- double x = event->button.x;
- double y = event->button.y;
-
- GanvNode* joinee = get_node_at(x, y);
-
- if (GANV_IS_PORT(joinee)) {
- if (joinee == GANV_NODE(_connect_port)) {
- // Drag ended on the same port it started on, port clicked
- if (_selected_ports.empty()) {
- // No selected ports, port clicked
- select_port(_connect_port);
- } else {
- // Connect to selected ports
- selection_joined_with(_connect_port);
- _connect_port = NULL;
- }
- } else { // drag ended on different port
- ports_joined(_connect_port, GANV_PORT(joinee));
- _connect_port = NULL;
- }
- }
-
- end_connect_drag();
- return true;
- }
-
- return false;
-}
-
-void
-GanvCanvasImpl::end_connect_drag()
-{
- if (_connect_port) {
- highlight_port(_connect_port, false);
- }
- gtk_object_destroy(GTK_OBJECT(_drag_edge));
- gtk_object_destroy(GTK_OBJECT(_drag_node));
- _drag_state = NOT_DRAGGING;
- _connect_port = NULL;
- _drag_edge = NULL;
- _drag_node = NULL;
-}
-
-bool
-GanvCanvasImpl::port_event(GdkEvent* event, GanvPort* port)
-{
- static bool port_pressed = true;
- static bool port_dragging = false;
- static bool control_dragging = false;
- static double control_start_x = 0;
- static double control_start_y = 0;
- static float control_start_value = 0;
-
- switch (event->type) {
- case GDK_BUTTON_PRESS:
- if (event->button.button == 1) {
- GanvModule* const module = ganv_port_get_module(port);
- double port_x = event->button.x;
- double port_y = event->button.y;
- ganv_item_w2i(GANV_ITEM(port), &port_x, &port_y);
-
- if (_selected_ports.empty() && module && port->impl->control &&
- (port->impl->is_input ||
- (port->impl->is_controllable &&
- port_x < ganv_box_get_width(GANV_BOX(port)) / 2.0))) {
- if (port->impl->control->is_toggle) {
- if (port->impl->control->value >= 0.5) {
- ganv_port_set_control_value_internal(port, 0.0);
- } else {
- ganv_port_set_control_value_internal(port, 1.0);
- }
- } else {
- control_dragging = port_pressed = true;
- control_start_x = event->button.x_root;
- control_start_y = event->button.y_root;
- control_start_value = ganv_port_get_control_value(port);
- ganv_canvas_grab_item(
- GANV_ITEM(port),
- GDK_POINTER_MOTION_MASK|GDK_BUTTON_RELEASE_MASK,
- NULL, event->button.time);
- GANV_NODE(port)->impl->grabbed = TRUE;
-
- }
- } else if (!port->impl->is_input) {
- port_dragging = port_pressed = true;
- ganv_canvas_grab_item(
- GANV_ITEM(port),
- GDK_BUTTON_RELEASE_MASK|GDK_POINTER_MOTION_MASK|
- GDK_ENTER_NOTIFY_MASK|GDK_LEAVE_NOTIFY_MASK,
- NULL, event->button.time);
- } else {
- port_pressed = true;
- ganv_canvas_grab_item(GANV_ITEM(port),
- GDK_BUTTON_RELEASE_MASK,
- NULL, event->button.time);
- }
- return true;
- }
- break;
-
- case GDK_MOTION_NOTIFY:
- if (control_dragging) {
- const double mouse_x = event->button.x_root;
- const double mouse_y = event->button.y_root;
- GdkScreen* screen = gdk_screen_get_default();
- const int screen_width = gdk_screen_get_width(screen);
- const int screen_height = gdk_screen_get_height(screen);
- const double drag_dx = mouse_x - control_start_x;
- const double drag_dy = mouse_y - control_start_y;
- const double ythresh = 0.2; // Minimum y fraction for fine
-
- const double range_x = ((drag_dx > 0)
- ? (screen_width - control_start_x)
- : control_start_x) - GANV_CANVAS_PAD;
-
- const double range_y = ((drag_dy > 0)
- ? (screen_height - control_start_y)
- : control_start_y);
-
- const double dx = drag_dx / range_x;
- const double dy = fabs(drag_dy / range_y);
-
- const double value_range = (drag_dx > 0)
- ? port->impl->control->max - control_start_value
- : control_start_value - port->impl->control->min;
-
- const double sens = (dy < ythresh)
- ? 1.0
- : 1.0 - fabs(drag_dy / (range_y + ythresh));
-
- const double dvalue = (dx * value_range) * sens;
- double value = control_start_value + dvalue;
- if (value < port->impl->control->min) {
- value = port->impl->control->min;
- } else if (value > port->impl->control->max) {
- value = port->impl->control->max;
- }
- ganv_port_set_control_value_internal(port, value);
- return true;
- } else if (port_dragging) {
- return true;
- }
- break;
-
- case GDK_BUTTON_RELEASE:
- if (port_pressed) {
- ganv_canvas_ungrab_item(GANV_ITEM(port), event->button.time);
- }
-
- if (port_dragging) {
- if (_connect_port) { // dragging
- ports_joined(port, _connect_port);
- } else {
- port_clicked(event, port);
- }
- port_dragging = false;
- } else if (control_dragging) {
- control_dragging = false;
- GANV_NODE(port)->impl->grabbed = FALSE;
- if (event->button.x_root == control_start_x &&
- event->button.y_root == control_start_y) {
- select_port_toggle(port, event->button.state);
- }
- } else {
- port_clicked(event, port);
- }
- return true;
-
- case GDK_ENTER_NOTIFY:
- gboolean selected;
- g_object_get(G_OBJECT(port), "selected", &selected, NULL);
- if (!control_dragging && !selected) {
- highlight_port(port, true);
- return true;
- }
- break;
-
- case GDK_LEAVE_NOTIFY:
- if (port_dragging) {
- _drag_state = GanvCanvasImpl::EDGE;
- _connect_port = port;
- port_dragging = false;
- ganv_canvas_ungrab_item(GANV_ITEM(port), event->crossing.time);
- ganv_canvas_grab_item(
- root,
- GDK_BUTTON_PRESS_MASK|GDK_POINTER_MOTION_MASK|GDK_BUTTON_RELEASE_MASK,
- NULL, event->crossing.time);
- return true;
- } else if (!control_dragging) {
- highlight_port(port, false);
- return true;
- }
- break;
-
- default:
- break;
- }
-
- return false;
-}
-
-/* Called when two ports are 'joined' (connected or disconnected) */
-void
-GanvCanvasImpl::ports_joined(GanvPort* port1, GanvPort* port2)
-{
- if (port1 == port2 || !port1 || !port2 || !port1->impl || !port2->impl) {
- return;
- }
-
- highlight_port(port1, false);
- highlight_port(port2, false);
-
- GanvNode* src_node;
- GanvNode* dst_node;
-
- if (port2->impl->is_input && !port1->impl->is_input) {
- src_node = GANV_NODE(port1);
- dst_node = GANV_NODE(port2);
- } else if (!port2->impl->is_input && port1->impl->is_input) {
- src_node = GANV_NODE(port2);
- dst_node = GANV_NODE(port1);
- } else {
- return;
- }
-
- if (!ganv_canvas_get_edge(_gcanvas, src_node, dst_node)) {
- g_signal_emit(_gcanvas, signal_connect, 0,
- src_node, dst_node, NULL);
- } else {
- g_signal_emit(_gcanvas, signal_disconnect, 0,
- src_node, dst_node, NULL);
- }
-}
-
-void
-GanvCanvasImpl::port_clicked(GdkEvent* event, GanvPort* port)
-{
- const bool modded = event->button.state & (GDK_SHIFT_MASK|GDK_CONTROL_MASK);
- if (!modded && _last_selected_port &&
- _last_selected_port->impl->is_input != port->impl->is_input) {
- selection_joined_with(port);
- } else {
- select_port_toggle(port, event->button.state);
- }
-}
-
-void
-GanvCanvasImpl::highlight_port(GanvPort* port, bool highlight)
-{
- g_object_set(G_OBJECT(port), "highlighted", highlight, NULL);
- ganv_canvas_for_each_edge_on(_gcanvas,
- GANV_NODE(port),
- (highlight
- ? (GanvEdgeFunc)ganv_edge_highlight
- : (GanvEdgeFunc)ganv_edge_unhighlight),
- NULL);
-}
-
-/* Update animated "rubber band" selection effect. */
-gboolean
-GanvCanvasImpl::on_animate_timeout(gpointer data)
-{
- GanvCanvasImpl* impl = (GanvCanvasImpl*)data;
- if (!impl->pixmap_gc) {
- return FALSE; // Unrealized
- }
-
- const double seconds = get_monotonic_time() / 1000000.0;
-
- FOREACH_ITEM(impl->_selected_items, s) {
- ganv_node_tick(*s, seconds);
- }
-
- for (SelectedPorts::iterator p = impl->_selected_ports.begin();
- p != impl->_selected_ports.end();
- ++p) {
- ganv_node_tick(GANV_NODE(*p), seconds);
- }
-
- FOREACH_EDGE(impl->_selected_edges, c) {
- ganv_edge_tick(*c, seconds);
- }
-
- return TRUE;
-}
-
-void
-GanvCanvasImpl::move_contents_to_internal(double x, double y, double min_x, double min_y)
-{
- FOREACH_ITEM(_items, i) {
- ganv_node_move(*i,
- x - min_x,
- y - min_y);
- }
-}
-
-void
-GanvCanvasImpl::unselect_ports()
-{
- for (GanvCanvasImpl::SelectedPorts::iterator i = _selected_ports.begin();
- i != _selected_ports.end(); ++i)
- g_object_set(G_OBJECT(*i), "selected", FALSE, NULL);
-
- _selected_ports.clear();
- _last_selected_port = NULL;
-}
-
-namespace Ganv {
-
-static gboolean
-on_event_after(GanvItem* canvasitem,
- GdkEvent* ev,
- void* canvas)
-{
- return ((Canvas*)canvas)->signal_event.emit(ev);
-}
-
-static void
-on_connect(GanvCanvas* canvas, GanvNode* tail, GanvNode* head, void* data)
-{
- Canvas* canvasmm = (Canvas*)data;
- canvasmm->signal_connect.emit(Glib::wrap(tail), Glib::wrap(head));
-}
-
-static void
-on_disconnect(GanvCanvas* canvas, GanvNode* tail, GanvNode* head, void* data)
-{
- Canvas* canvasmm = (Canvas*)data;
- canvasmm->signal_disconnect.emit(Glib::wrap(tail), Glib::wrap(head));
-}
-
-Canvas::Canvas(double width, double height)
- : _gobj(GANV_CANVAS(ganv_canvas_new(width, height)))
-{
- ganv_canvas_set_wrapper(_gobj, this);
-
- g_signal_connect_after(ganv_canvas_root(_gobj), "event",
- G_CALLBACK(on_event_after), this);
- g_signal_connect(gobj(), "connect",
- G_CALLBACK(on_connect), this);
- g_signal_connect(gobj(), "disconnect",
- G_CALLBACK(on_disconnect), this);
-}
-
-Canvas::~Canvas()
-{
- delete _gobj->impl;
-}
-
-void
-Canvas::remove_edge_between(Node* item1, Node* item2)
-{
- GanvEdge* edge = ganv_canvas_get_edge(_gobj, item1->gobj(), item2->gobj());
- if (edge) {
- ganv_canvas_remove_edge(_gobj, edge);
- }
-}
-
-void
-Canvas::remove_edge(Edge* edge)
-{
- ganv_canvas_remove_edge(_gobj, edge->gobj());
-}
-
-Item*
-Canvas::get_item_at(double x, double y) const
-{
- GanvItem* item = ganv_canvas_get_item_at(_gobj, x, y);
- if (item) {
- return Glib::wrap(item);
- }
- return NULL;
-}
-
-Edge*
-Canvas::get_edge(Node* tail, Node* head) const
-{
- GanvEdge* e = ganv_canvas_get_edge(_gobj, tail->gobj(), head->gobj());
- if (e) {
- return Glib::wrap(e);
- }
- return NULL;
-}
-
-} // namespace Ganv
-
-extern "C" {
-
-#include "ganv/canvas.h"
-
-#include "./boilerplate.h"
-#include "./color.h"
-#include "./gettext.h"
-
-G_DEFINE_TYPE_WITH_CODE(GanvCanvas, ganv_canvas, GTK_TYPE_LAYOUT,
- G_ADD_PRIVATE(GanvCanvas))
-
-enum {
- PROP_0,
- PROP_WIDTH,
- PROP_HEIGHT,
- PROP_DIRECTION,
- PROP_FONT_SIZE,
- PROP_LOCKED,
- PROP_FOCUSED_ITEM
-};
-
-static gboolean
-on_canvas_event(GanvItem* canvasitem,
- GdkEvent* ev,
- void* impl)
-{
- return ((GanvCanvasImpl*)impl)->on_event(ev);
-}
-
-static void
-ganv_canvas_init(GanvCanvas* canvas)
-{
- GTK_WIDGET_SET_FLAGS(canvas, GTK_CAN_FOCUS);
-
- canvas->impl = new GanvCanvasImpl(canvas);
-
- g_signal_connect(G_OBJECT(ganv_canvas_root(canvas)),
- "event", G_CALLBACK(on_canvas_event), canvas->impl);
-}
-
-static void
-ganv_canvas_set_property(GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_CANVAS(object));
-
- GanvCanvas* canvas = GANV_CANVAS(object);
-
- switch (prop_id) {
- case PROP_WIDTH:
- ganv_canvas_resize(canvas, g_value_get_double(value), canvas->impl->height);
- break;
- case PROP_HEIGHT:
- ganv_canvas_resize(canvas, canvas->impl->width, g_value_get_double(value));
- break;
- case PROP_DIRECTION:
- ganv_canvas_set_direction(canvas, (GanvDirection)g_value_get_enum(value));
- break;
- case PROP_FONT_SIZE:
- ganv_canvas_set_font_size(canvas, g_value_get_double(value));
- break;
- case PROP_LOCKED:
- canvas->impl->locked = g_value_get_boolean(value);
- break;
- case PROP_FOCUSED_ITEM:
- canvas->impl->focused_item = GANV_ITEM(g_value_get_object(value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-ganv_canvas_get_property(GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_CANVAS(object));
-
- GanvCanvas* canvas = GANV_CANVAS(object);
-
- switch (prop_id) {
- GET_CASE(WIDTH, double, canvas->impl->width)
- GET_CASE(HEIGHT, double, canvas->impl->height)
- GET_CASE(LOCKED, boolean, canvas->impl->locked);
- case PROP_FOCUSED_ITEM:
- g_value_set_object(value, GANV_CANVAS(object)->impl->focused_item);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-ganv_canvas_class_init(GanvCanvasClass* klass)
-{
- GObjectClass* gobject_class = (GObjectClass*)klass;
- GtkObjectClass* object_class = (GtkObjectClass*)klass;
- GtkWidgetClass* widget_class = (GtkWidgetClass*)klass;
-
- canvas_parent_class = GTK_LAYOUT_CLASS(g_type_class_peek_parent(klass));
-
- gobject_class->set_property = ganv_canvas_set_property;
- gobject_class->get_property = ganv_canvas_get_property;
-
- object_class->destroy = ganv_canvas_destroy;
-
- widget_class->map = ganv_canvas_map;
- widget_class->unmap = ganv_canvas_unmap;
- widget_class->realize = ganv_canvas_realize;
- widget_class->unrealize = ganv_canvas_unrealize;
- widget_class->size_allocate = ganv_canvas_size_allocate;
- widget_class->button_press_event = ganv_canvas_button;
- widget_class->button_release_event = ganv_canvas_button;
- widget_class->motion_notify_event = ganv_canvas_motion;
- widget_class->expose_event = ganv_canvas_expose;
- widget_class->key_press_event = ganv_canvas_key;
- widget_class->key_release_event = ganv_canvas_key;
- widget_class->enter_notify_event = ganv_canvas_crossing;
- widget_class->leave_notify_event = ganv_canvas_crossing;
- widget_class->focus_in_event = ganv_canvas_focus_in;
- widget_class->focus_out_event = ganv_canvas_focus_out;
- widget_class->scroll_event = ganv_canvas_scroll;
-
- g_object_class_install_property(
- gobject_class, PROP_FOCUSED_ITEM, g_param_spec_object(
- "focused-item",
- _("Focused item"),
- _("The item that currently has keyboard focus."),
- GANV_TYPE_ITEM,
- (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE)));
-
- g_object_class_install_property(
- gobject_class, PROP_WIDTH, g_param_spec_double(
- "width",
- _("Width"),
- _("The width of the canvas."),
- 0.0, G_MAXDOUBLE,
- 800.0,
- (GParamFlags)G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_HEIGHT, g_param_spec_double(
- "height",
- _("Height"),
- _("The height of the canvas"),
- 0.0, G_MAXDOUBLE,
- 600.0,
- (GParamFlags)G_PARAM_READWRITE));
-
- GEnumValue down_dir = { GANV_DIRECTION_DOWN, "down", "down" };
- GEnumValue right_dir = { GANV_DIRECTION_RIGHT, "right", "right" };
- GEnumValue null_dir = { 0, 0, 0 };
- dir_values[0] = down_dir;
- dir_values[1] = right_dir;
- dir_values[2] = null_dir;
- GType dir_type = g_enum_register_static("GanvDirection",
- dir_values);
-
- g_object_class_install_property(
- gobject_class, PROP_DIRECTION, g_param_spec_enum(
- "direction",
- _("Direction"),
- _("The direction of the signal flow on the canvas."),
- dir_type,
- GANV_DIRECTION_RIGHT,
- (GParamFlags)G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_FONT_SIZE, g_param_spec_double(
- "font-size",
- _("Font size"),
- _("The default font size for the canvas"),
- 0.0, G_MAXDOUBLE,
- 12.0,
- (GParamFlags)G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_LOCKED, g_param_spec_boolean(
- "locked",
- _("Locked"),
- _("If true, nodes on the canvas can not be moved by the user."),
- FALSE,
- (GParamFlags)G_PARAM_READWRITE));
-
- signal_connect = g_signal_new("connect",
- ganv_canvas_get_type(),
- G_SIGNAL_RUN_FIRST,
- 0, NULL, NULL,
- ganv_marshal_VOID__OBJECT_OBJECT,
- G_TYPE_NONE,
- 2,
- ganv_node_get_type(),
- ganv_node_get_type(),
- 0);
-
- signal_disconnect = g_signal_new("disconnect",
- ganv_canvas_get_type(),
- G_SIGNAL_RUN_FIRST,
- 0, NULL, NULL,
- ganv_marshal_VOID__OBJECT_OBJECT,
- G_TYPE_NONE,
- 2,
- ganv_node_get_type(),
- ganv_node_get_type(),
- 0);
-}
-
-void
-ganv_canvas_resize(GanvCanvas* canvas, double width, double height)
-{
- if (width != canvas->impl->width || height != canvas->impl->height) {
- canvas->impl->width = width;
- canvas->impl->height = height;
- ganv_canvas_set_scroll_region(canvas, 0.0, 0.0, width, height);
- }
-}
-
-void
-ganv_canvas_contents_changed(GanvCanvas* canvas)
-{
-#ifdef GANV_FDGL
- if (!canvas->impl->layout_idle_id && canvas->impl->sprung_layout) {
- canvas->impl->layout_energy = 0.4;
- canvas->impl->layout_idle_id = g_timeout_add_full(
- G_PRIORITY_DEFAULT_IDLE,
- 33,
- GanvCanvasImpl::on_layout_timeout,
- canvas->impl,
- GanvCanvasImpl::on_layout_done);
- }
-#endif
-}
-
-double
-ganv_canvas_get_default_font_size(const GanvCanvas* canvas)
-{
- GtkStyle* style = gtk_rc_get_style(GTK_WIDGET(canvas));
- const PangoFontDescription* font = style->font_desc;
- return pango_font_description_get_size(font) / (double)PANGO_SCALE;
-}
-
-double
-ganv_canvas_get_font_size(const GanvCanvas* canvas)
-{
- return canvas->impl->font_size;
-}
-
-void
-ganv_canvas_set_zoom(GanvCanvas* canvas, double zoom)
-{
- g_return_if_fail(GANV_IS_CANVAS(canvas));
-
- zoom = std::max(zoom, 0.01);
- if (zoom == canvas->impl->pixels_per_unit) {
- return;
- }
-
- const int anchor_x = (canvas->impl->center_scroll_region)
- ? GTK_WIDGET(canvas)->allocation.width / 2
- : 0;
- const int anchor_y = (canvas->impl->center_scroll_region)
- ? GTK_WIDGET(canvas)->allocation.height / 2
- : 0;
-
- /* Find the coordinates of the anchor point in units. */
- const double ax = (canvas->layout.hadjustment)
- ? ((canvas->layout.hadjustment->value + anchor_x)
- / canvas->impl->pixels_per_unit
- + canvas->impl->scroll_x1 + canvas->impl->zoom_xofs)
- : ((0.0 + anchor_x) / canvas->impl->pixels_per_unit
- + canvas->impl->scroll_x1 + canvas->impl->zoom_xofs);
- const double ay = (canvas->layout.hadjustment)
- ? ((canvas->layout.vadjustment->value + anchor_y)
- / canvas->impl->pixels_per_unit
- + canvas->impl->scroll_y1 + canvas->impl->zoom_yofs)
- : ((0.0 + anchor_y) / canvas->impl->pixels_per_unit
- + canvas->impl->scroll_y1 + canvas->impl->zoom_yofs);
-
- /* Now calculate the new offset of the upper left corner. */
- const int x1 = ((ax - canvas->impl->scroll_x1) * zoom) - anchor_x;
- const int y1 = ((ay - canvas->impl->scroll_y1) * zoom) - anchor_y;
-
- canvas->impl->pixels_per_unit = zoom;
- ganv_canvas_scroll_to(canvas, x1, y1);
-
- ganv_canvas_request_update(canvas);
- gtk_widget_queue_draw(GTK_WIDGET(canvas));
-
- canvas->impl->need_repick = TRUE;
-}
-
-void
-ganv_canvas_set_font_size(GanvCanvas* canvas, double points)
-{
- points = std::max(points, 1.0);
- if (points != canvas->impl->font_size) {
- canvas->impl->font_size = points;
- FOREACH_ITEM(canvas->impl->_items, i) {
- ganv_node_redraw_text(*i);
- }
- }
-}
-
-void
-ganv_canvas_zoom_full(GanvCanvas* canvas)
-{
- if (canvas->impl->_items.empty())
- return;
-
- int win_width, win_height;
- GdkWindow* win = gtk_widget_get_window(
- GTK_WIDGET(canvas->impl->_gcanvas));
- gdk_window_get_size(win, &win_width, &win_height);
-
- // Box containing all canvas items
- double left = DBL_MAX;
- double right = DBL_MIN;
- double top = DBL_MIN;
- double bottom = DBL_MAX;
-
- FOREACH_ITEM(canvas->impl->_items, i) {
- GanvItem* const item = GANV_ITEM(*i);
- const double x = item->impl->x;
- const double y = item->impl->y;
- if (GANV_IS_CIRCLE(*i)) {
- const double r = GANV_CIRCLE(*i)->impl->coords.radius;
- left = MIN(left, x - r);
- right = MAX(right, x + r);
- bottom = MIN(bottom, y - r);
- top = MAX(top, y + r);
- } else {
- left = MIN(left, x);
- right = MAX(right, x + ganv_box_get_width(GANV_BOX(*i)));
- bottom = MIN(bottom, y);
- top = MAX(top, y + ganv_box_get_height(GANV_BOX(*i)));
- }
- }
-
- static const double pad = GANV_CANVAS_PAD;
-
- const double new_zoom = std::min(
- ((double)win_width / (double)(right - left + pad*2.0)),
- ((double)win_height / (double)(top - bottom + pad*2.0)));
-
- ganv_canvas_set_zoom(canvas, new_zoom);
-
- int scroll_x, scroll_y;
- ganv_canvas_w2c(canvas->impl->_gcanvas,
- lrintf(left - pad), lrintf(bottom - pad),
- &scroll_x, &scroll_y);
-
- ganv_canvas_scroll_to(canvas->impl->_gcanvas,
- scroll_x, scroll_y);
-}
-
-static void
-set_node_direction(GanvNode* node, void* data)
-{
- if (GANV_IS_MODULE(node)) {
- ganv_module_set_direction(GANV_MODULE(node), *(GanvDirection*)data);
- }
-}
-
-GanvDirection
-ganv_canvas_get_direction(GanvCanvas* canvas)
-{
- return canvas->impl->direction;
-}
-
-void
-ganv_canvas_set_direction(GanvCanvas* canvas, GanvDirection dir)
-{
- if (canvas->impl->direction != dir) {
- canvas->impl->direction = dir;
- ganv_canvas_for_each_node(canvas, set_node_direction, &dir);
- ganv_canvas_contents_changed(canvas);
- }
-}
-
-void
-ganv_canvas_clear_selection(GanvCanvas* canvas)
-{
- canvas->impl->unselect_ports();
-
- Items items(canvas->impl->_selected_items);
- canvas->impl->_selected_items.clear();
- FOREACH_ITEM(items, i) {
- ganv_item_set(GANV_ITEM(*i), "selected", FALSE, NULL);
- }
-
- GanvCanvasImpl::SelectedEdges edges(canvas->impl->_selected_edges);
- canvas->impl->_selected_edges.clear();
- FOREACH_SELECTED_EDGE(edges, c) {
- ganv_item_set(GANV_ITEM(*c), "selected", FALSE, NULL);
- }
-}
-
-void
-ganv_canvas_move_selected_items(GanvCanvas* canvas,
- double dx,
- double dy)
-{
- FOREACH_ITEM(canvas->impl->_selected_items, i) {
- if ((*i)->item.impl->parent == canvas->impl->root) {
- ganv_node_move(*i, dx, dy);
- }
- }
-}
-
-void
-ganv_canvas_selection_move_finished(GanvCanvas* canvas)
-{
- FOREACH_ITEM(canvas->impl->_selected_items, i) {
- const double x = GANV_ITEM(*i)->impl->x;
- const double y = GANV_ITEM(*i)->impl->y;
- g_signal_emit(*i, signal_moved, 0, x, y, NULL);
- }
-}
-
-static void
-select_if_ends_are_selected(GanvEdge* edge, void* data)
-{
- if (ganv_node_is_selected(ganv_edge_get_tail(edge)) &&
- ganv_node_is_selected(ganv_edge_get_head(edge))) {
- ganv_edge_set_selected(edge, TRUE);
- }
-}
-
-static void
-unselect_edges(GanvPort* port, void* data)
-{
- GanvCanvasImpl* impl = (GanvCanvasImpl*)data;
- if (port->impl->is_input) {
- ganv_canvas_for_each_edge_to(impl->_gcanvas,
- GANV_NODE(port),
- (GanvEdgeFunc)ganv_edge_unselect,
- NULL);
- } else {
- ganv_canvas_for_each_edge_from(impl->_gcanvas,
- GANV_NODE(port),
- (GanvEdgeFunc)ganv_edge_unselect,
- NULL);
- }
-}
-
-void
-ganv_canvas_select_node(GanvCanvas* canvas,
- GanvNode* node)
-{
- canvas->impl->_selected_items.insert(node);
-
- // Select any connections to or from this node
- if (GANV_IS_MODULE(node)) {
- ganv_module_for_each_port(GANV_MODULE(node), select_edges, canvas->impl);
- } else {
- ganv_canvas_for_each_edge_on(
- canvas, node, select_if_ends_are_selected, canvas->impl);
- }
-
- g_object_set(node, "selected", TRUE, NULL);
-}
-
-void
-ganv_canvas_unselect_node(GanvCanvas* canvas,
- GanvNode* node)
-{
- // Unselect any connections to or from canvas->impl node
- if (GANV_IS_MODULE(node)) {
- ganv_module_for_each_port(GANV_MODULE(node), unselect_edges, canvas->impl);
- } else {
- ganv_canvas_for_each_edge_on(
- canvas, node, (GanvEdgeFunc)ganv_edge_unselect, NULL);
- }
-
- // Unselect item
- canvas->impl->_selected_items.erase(node);
- g_object_set(node, "selected", FALSE, NULL);
-}
-
-void
-ganv_canvas_add_node(GanvCanvas* canvas,
- GanvNode* node)
-{
- GanvItem* item = GANV_ITEM(node);
- if (item->impl->parent == ganv_canvas_root(canvas)) {
- canvas->impl->_items.insert(node);
- }
-}
-
-void
-ganv_canvas_remove_node(GanvCanvas* canvas,
- GanvNode* node)
-{
- if (node == (GanvNode*)canvas->impl->_connect_port) {
- if (canvas->impl->_drag_state == GanvCanvasImpl::EDGE) {
- ganv_canvas_ungrab_item(ganv_canvas_root(canvas), 0);
- canvas->impl->end_connect_drag();
- }
- canvas->impl->_connect_port = NULL;
- }
-
- // Remove from selection
- canvas->impl->_selected_items.erase(node);
-
- // Remove children ports from selection if item is a module
- if (GANV_IS_MODULE(node)) {
- GanvModule* const module = GANV_MODULE(node);
- for (unsigned i = 0; i < ganv_module_num_ports(module); ++i) {
- canvas->impl->unselect_port(ganv_module_get_port(module, i));
- }
- }
-
- // Remove from items
- canvas->impl->_items.erase(node);
-}
-
-GanvEdge*
-ganv_canvas_get_edge(GanvCanvas* canvas,
- GanvNode* tail,
- GanvNode* head)
-{
- GanvEdgeKey key;
- make_edge_search_key(&key, tail, head);
- GanvCanvasImpl::Edges::const_iterator i = canvas->impl->_edges.find((GanvEdge*)&key);
- return (i != canvas->impl->_edges.end()) ? *i : NULL;
-}
-
-void
-ganv_canvas_remove_edge_between(GanvCanvas* canvas,
- GanvNode* tail,
- GanvNode* head)
-{
- ganv_canvas_remove_edge(canvas, ganv_canvas_get_edge(canvas, tail, head));
-}
-
-void
-ganv_canvas_disconnect_edge(GanvCanvas* canvas,
- GanvEdge* edge)
-{
- g_signal_emit(canvas, signal_disconnect, 0,
- edge->impl->tail, edge->impl->head, NULL);
-}
-
-void
-ganv_canvas_add_edge(GanvCanvas* canvas,
- GanvEdge* edge)
-{
- canvas->impl->_edges.insert(edge);
- canvas->impl->_dst_edges.insert(edge);
- ganv_canvas_contents_changed(canvas);
-}
-
-void
-ganv_canvas_remove_edge(GanvCanvas* canvas,
- GanvEdge* edge)
-{
- if (edge) {
- canvas->impl->_selected_edges.erase(edge);
- canvas->impl->_edges.erase(edge);
- canvas->impl->_dst_edges.erase(edge);
- ganv_edge_request_redraw(GANV_ITEM(edge), &edge->impl->coords);
- gtk_object_destroy(GTK_OBJECT(edge));
- ganv_canvas_contents_changed(canvas);
- }
-}
-
-void
-ganv_canvas_select_edge(GanvCanvas* canvas,
- GanvEdge* edge)
-{
- ganv_item_set(GANV_ITEM(edge), "selected", TRUE, NULL);
- canvas->impl->_selected_edges.insert(edge);
-}
-
-void
-ganv_canvas_unselect_edge(GanvCanvas* canvas,
- GanvEdge* edge)
-{
- ganv_item_set(GANV_ITEM(edge), "selected", FALSE, NULL);
- canvas->impl->_selected_edges.erase(edge);
-}
-
-void
-ganv_canvas_for_each_node(GanvCanvas* canvas,
- GanvNodeFunc f,
- void* data)
-{
- FOREACH_ITEM(canvas->impl->_items, i) {
- f(*i, data);
- }
-}
-
-void
-ganv_canvas_for_each_selected_node(GanvCanvas* canvas,
- GanvNodeFunc f,
- void* data)
-{
- FOREACH_ITEM(canvas->impl->_selected_items, i) {
- f(*i, data);
- }
-}
-
-gboolean
-ganv_canvas_empty(const GanvCanvas* canvas)
-{
- return canvas->impl->_items.empty();
-}
-
-void
-ganv_canvas_for_each_edge(GanvCanvas* canvas,
- GanvEdgeFunc f,
- void* data)
-{
- GanvCanvasImpl* impl = canvas->impl;
- for (GanvCanvasImpl::Edges::const_iterator i = impl->_edges.begin();
- i != impl->_edges.end();) {
- GanvCanvasImpl::Edges::const_iterator next = i;
- ++next;
- f((*i), data);
- i = next;
- }
-}
-
-void
-ganv_canvas_for_each_edge_from(GanvCanvas* canvas,
- const GanvNode* tail,
- GanvEdgeFunc f,
- void* data)
-{
- GanvCanvasImpl* impl = canvas->impl;
- for (GanvCanvasImpl::Edges::const_iterator i = impl->first_edge_from(tail);
- i != impl->_edges.end() && (*i)->impl->tail == tail;) {
- GanvCanvasImpl::Edges::const_iterator next = i;
- ++next;
- f((*i), data);
- i = next;
- }
-}
-
-void
-ganv_canvas_for_each_edge_to(GanvCanvas* canvas,
- const GanvNode* head,
- GanvEdgeFunc f,
- void* data)
-{
- GanvCanvasImpl* impl = canvas->impl;
- for (GanvCanvasImpl::Edges::const_iterator i = impl->first_edge_to(head);
- i != impl->_dst_edges.end() && (*i)->impl->head == head;) {
- GanvCanvasImpl::Edges::const_iterator next = i;
- ++next;
- f((*i), data);
- i = next;
- }
-}
-
-void
-ganv_canvas_for_each_edge_on(GanvCanvas* canvas,
- const GanvNode* node,
- GanvEdgeFunc f,
- void* data)
-{
- ganv_canvas_for_each_edge_from(canvas, node, f, data);
- ganv_canvas_for_each_edge_to(canvas, node, f, data);
-}
-
-void
-ganv_canvas_for_each_selected_edge(GanvCanvas* canvas,
- GanvEdgeFunc f,
- void* data)
-{
- FOREACH_EDGE(canvas->impl->_selected_edges, i) {
- f((*i), data);
- }
-}
-
-GdkCursor*
-ganv_canvas_get_move_cursor(const GanvCanvas* canvas)
-{
- return canvas->impl->_move_cursor;
-}
-
-gboolean
-ganv_canvas_port_event(GanvCanvas* canvas,
- GanvPort* port,
- GdkEvent* event)
-{
- return canvas->impl->port_event(event, port);
-}
-
-void
-ganv_canvas_clear(GanvCanvas* canvas)
-{
- canvas->impl->_selected_items.clear();
- canvas->impl->_selected_edges.clear();
-
- Items items = canvas->impl->_items; // copy
- FOREACH_ITEM(items, i) {
- gtk_object_destroy(GTK_OBJECT(*i));
- }
- canvas->impl->_items.clear();
-
- GanvCanvasImpl::Edges edges = canvas->impl->_edges; // copy
- FOREACH_EDGE(edges, i) {
- gtk_object_destroy(GTK_OBJECT(*i));
- }
- canvas->impl->_edges.clear();
- canvas->impl->_dst_edges.clear();
-
- canvas->impl->_selected_ports.clear();
- canvas->impl->_connect_port = NULL;
-}
-
-void
-ganv_canvas_select_all(GanvCanvas* canvas)
-{
- ganv_canvas_clear_selection(canvas);
- FOREACH_ITEM(canvas->impl->_items, i) {
- ganv_canvas_select_node(canvas, *i);
- }
-}
-
-double
-ganv_canvas_get_zoom(const GanvCanvas* canvas)
-{
- return canvas->impl->pixels_per_unit;
-}
-
-void
-ganv_canvas_move_contents_to(GanvCanvas* canvas, double x, double y)
-{
- double min_x=HUGE_VAL, min_y=HUGE_VAL;
- FOREACH_ITEM(canvas->impl->_items, i) {
- const double x = GANV_ITEM(*i)->impl->x;
- const double y = GANV_ITEM(*i)->impl->y;
- min_x = std::min(min_x, x);
- min_y = std::min(min_y, y);
- }
- canvas->impl->move_contents_to_internal(x, y, min_x, min_y);
-}
-
-void
-ganv_canvas_arrange(GanvCanvas* canvas)
-{
-#ifdef HAVE_AGRAPH
- GVNodes nodes = canvas->impl->layout_dot((char*)"");
-
- double least_x=HUGE_VAL, least_y=HUGE_VAL, most_x=0, most_y=0;
-
- // Set numeric locale to POSIX for reading graphviz output with strtod
- char* locale = strdup(setlocale(LC_NUMERIC, NULL));
- setlocale(LC_NUMERIC, "POSIX");
-
- const double dpi = gdk_screen_get_resolution(gdk_screen_get_default());
- const double dpp = dpi / 72.0;
-
- // Arrange to graphviz coordinates
- for (GVNodes::iterator i = nodes.begin(); i != nodes.end(); ++i) {
- if (GANV_ITEM(i->first)->impl->parent != GANV_ITEM(ganv_canvas_root(canvas))) {
- continue;
- }
- const std::string pos = agget(i->second, (char*)"pos");
- const std::string x_str = pos.substr(0, pos.find(","));
- const std::string y_str = pos.substr(pos.find(",") + 1);
- const double cx = lrint(strtod(x_str.c_str(), NULL) * dpp);
- const double cy = lrint(strtod(y_str.c_str(), NULL) * dpp);
-
- double w, h;
- if (GANV_IS_BOX(i->first)) {
- w = ganv_box_get_width(GANV_BOX(i->first));
- h = ganv_box_get_height(GANV_BOX(i->first));
- } else {
- w = h = ganv_circle_get_radius(GANV_CIRCLE(i->first)) * 2.3;
- }
-
- /* Dot node positions are supposedly node centers, but things only
- match up if x is interpreted as center and y as top...
- */
- double x = cx - (w / 2.0);
- double y = -cy - (h / 2.0);
-
- ganv_node_move_to(i->first, x, y);
-
- if (GANV_IS_CIRCLE(i->first)) {
- // Offset least x and y to avoid cutting off circles at origin
- const double r = ganv_circle_get_radius(GANV_CIRCLE(i->first));
- x -= r;
- y -= r;
- }
-
- least_x = std::min(least_x, x);
- least_y = std::min(least_y, y);
- most_x = std::max(most_x, x + w);
- most_y = std::max(most_y, y + h);
- }
-
- // Reset numeric locale to original value
- setlocale(LC_NUMERIC, locale);
- free(locale);
-
- const double graph_width = most_x - least_x;
- const double graph_height = most_y - least_y;
-
- //cerr << "CWH: " << _width << ", " << _height << endl;
- //cerr << "GWH: " << graph_width << ", " << graph_height << endl;
-
- double old_width, old_height;
- g_object_get(G_OBJECT(canvas),
- "width", &old_width,
- "height", &old_height,
- NULL);
-
- const double new_width = std::max(graph_width + 10.0, old_width);
- const double new_height = std::max(graph_height + 10.0, old_height);
- if (new_width != old_width || new_height != old_height) {
- ganv_canvas_resize(canvas, new_width, new_height);
- }
- nodes.cleanup();
-
- static const double border_width = GANV_CANVAS_PAD;
- canvas->impl->move_contents_to_internal(border_width, border_width, least_x, least_y);
- ganv_canvas_scroll_to(canvas->impl->_gcanvas, 0, 0);
-
- FOREACH_ITEM(canvas->impl->_items, i) {
- const double x = GANV_ITEM(*i)->impl->x;
- const double y = GANV_ITEM(*i)->impl->y;
- g_signal_emit(*i, signal_moved, 0, x, y, NULL);
- }
-#endif
-}
-
-int
-ganv_canvas_export_image(GanvCanvas* canvas,
- const char* filename,
- gboolean draw_background)
-{
- const char* ext = strrchr(filename, '.');
- if (!ext) {
- return 1;
- } else if (!strcmp(ext, ".dot")) {
- ganv_canvas_export_dot(canvas, filename);
- return 0;
- }
-
- cairo_surface_t* rec_surface = cairo_recording_surface_create(
- CAIRO_CONTENT_COLOR_ALPHA, NULL);
-
- // Draw to recording surface
- cairo_t* cr = cairo_create(rec_surface);
- canvas->impl->exporting = TRUE;
- (*GANV_ITEM_GET_CLASS(canvas->impl->root)->draw)(
- canvas->impl->root, cr,
- 0, 0, canvas->impl->width, canvas->impl->height);
- canvas->impl->exporting = FALSE;
- cairo_destroy(cr);
-
- // Get draw extent
- double x, y, w, h;
- cairo_recording_surface_ink_extents(rec_surface, &x, &y, &w, &h);
-
- // Create image surface with the appropriate size
- const double pad = GANV_CANVAS_PAD;
- const double img_w = w + pad * 2;
- const double img_h = h + pad * 2;
- cairo_surface_t* img = NULL;
- if (!strcmp(ext, ".svg")) {
- img = cairo_svg_surface_create(filename, img_w, img_h);
- } else if (!strcmp(ext, ".pdf")) {
- img = cairo_pdf_surface_create(filename, img_w, img_h);
- } else if (!strcmp(ext, ".ps")) {
- img = cairo_ps_surface_create(filename, img_w, img_h);
- } else {
- cairo_surface_destroy(rec_surface);
- return 1;
- }
-
- // Draw recording to image surface
- cr = cairo_create(img);
- if (draw_background) {
- double r, g, b, a;
- color_to_rgba(DEFAULT_BACKGROUND_COLOR, &r, &g, &b, &a);
- cairo_set_source_rgba(cr, r, g, b, a);
- cairo_rectangle(cr, 0, 0, w + 2 * pad, h + 2 * pad);
- cairo_fill(cr);
- }
- cairo_set_source_surface(cr, rec_surface, -x + pad, -y + pad);
- cairo_paint(cr);
- cairo_destroy(cr);
- cairo_surface_destroy(rec_surface);
- cairo_surface_destroy(img);
- return 0;
-}
-
-void
-ganv_canvas_export_dot(GanvCanvas* canvas, const char* filename)
-{
-#ifdef HAVE_AGRAPH
- GVNodes nodes = canvas->impl->layout_dot(filename);
- nodes.cleanup();
-#endif
-}
-
-gboolean
-ganv_canvas_supports_sprung_layout(const GanvCanvas* canvas)
-{
-#ifdef GANV_FDGL
- return TRUE;
-#else
- return FALSE;
-#endif
-}
-
-gboolean
-ganv_canvas_set_sprung_layout(GanvCanvas* canvas, gboolean sprung_layout)
-{
-#ifndef GANV_FDGL
- return FALSE;
-#else
- canvas->impl->sprung_layout = sprung_layout;
- ganv_canvas_contents_changed(canvas);
- return TRUE;
-#endif
-}
-
-gboolean
-ganv_canvas_get_locked(const GanvCanvas* canvas)
-{
- return canvas->impl->locked;
-}
-
-/* Convenience function to remove the idle handler of a canvas */
-static void
-remove_idle(GanvCanvas* canvas)
-{
- if (canvas->impl->idle_id == 0) {
- return;
- }
-
- g_source_remove(canvas->impl->idle_id);
- canvas->impl->idle_id = 0;
-}
-
-/* Removes the transient state of the canvas (idle handler, grabs). */
-static void
-shutdown_transients(GanvCanvas* canvas)
-{
- /* We turn off the need_redraw flag, since if the canvas is mapped again
- * it will request a redraw anyways. We do not turn off the need_update
- * flag, though, because updates are not queued when the canvas remaps
- * itself.
- */
- if (canvas->impl->need_redraw) {
- canvas->impl->need_redraw = FALSE;
- g_slist_foreach(canvas->impl->redraw_region, (GFunc)g_free, NULL);
- g_slist_free(canvas->impl->redraw_region);
- canvas->impl->redraw_region = NULL;
- canvas->impl->redraw_x1 = 0;
- canvas->impl->redraw_y1 = 0;
- canvas->impl->redraw_x2 = 0;
- canvas->impl->redraw_y2 = 0;
- }
-
- if (canvas->impl->grabbed_item) {
- canvas->impl->grabbed_item = NULL;
- gdk_pointer_ungrab(GDK_CURRENT_TIME);
- }
-
- remove_idle(canvas);
-}
-
-/* Destroy handler for GanvCanvas */
-static void
-ganv_canvas_destroy(GtkObject* object)
-{
- g_return_if_fail(GANV_IS_CANVAS(object));
-
- /* remember, destroy can be run multiple times! */
-
- GanvCanvas* canvas = GANV_CANVAS(object);
-
- if (canvas->impl->root_destroy_id) {
- g_signal_handler_disconnect(canvas->impl->root, canvas->impl->root_destroy_id);
- canvas->impl->root_destroy_id = 0;
- }
- if (canvas->impl->root) {
- gtk_object_destroy(GTK_OBJECT(canvas->impl->root));
- g_object_unref(G_OBJECT(canvas->impl->root));
- canvas->impl->root = NULL;
- }
-
- shutdown_transients(canvas);
-
- if (GTK_OBJECT_CLASS(canvas_parent_class)->destroy) {
- (*GTK_OBJECT_CLASS(canvas_parent_class)->destroy)(object);
- }
-}
-
-GanvCanvas*
-ganv_canvas_new(double width, double height)
-{
- GanvCanvas* canvas = GANV_CANVAS(
- g_object_new(ganv_canvas_get_type(),
- "width", width,
- "height", height,
- NULL));
-
- ganv_canvas_set_scroll_region(canvas, 0.0, 0.0, width, height);
-
- return canvas;
-}
-
-void
-ganv_canvas_set_wrapper(GanvCanvas* canvas, void* wrapper)
-{
- canvas->impl->_wrapper = (Ganv::Canvas*)wrapper;
-}
-
-void*
-ganv_canvas_get_wrapper(GanvCanvas* canvas)
-{
- return canvas->impl->_wrapper;
-}
-
-/* Map handler for the canvas */
-static void
-ganv_canvas_map(GtkWidget* widget)
-{
- g_return_if_fail(GANV_IS_CANVAS(widget));
-
- /* Normal widget mapping stuff */
-
- if (GTK_WIDGET_CLASS(canvas_parent_class)->map) {
- (*GTK_WIDGET_CLASS(canvas_parent_class)->map)(widget);
- }
-
- GanvCanvas* canvas = GANV_CANVAS(widget);
-
- if (canvas->impl->need_update) {
- add_idle(canvas);
- }
-
- /* Map items */
-
- if (GANV_ITEM_GET_CLASS(canvas->impl->root)->map) {
- (*GANV_ITEM_GET_CLASS(canvas->impl->root)->map)(canvas->impl->root);
- }
-}
-
-/* Unmap handler for the canvas */
-static void
-ganv_canvas_unmap(GtkWidget* widget)
-{
- g_return_if_fail(GANV_IS_CANVAS(widget));
-
- GanvCanvas* canvas = GANV_CANVAS(widget);
-
- shutdown_transients(canvas);
-
- /* Unmap items */
-
- if (GANV_ITEM_GET_CLASS(canvas->impl->root)->unmap) {
- (*GANV_ITEM_GET_CLASS(canvas->impl->root)->unmap)(canvas->impl->root);
- }
-
- /* Normal widget unmapping stuff */
-
- if (GTK_WIDGET_CLASS(canvas_parent_class)->unmap) {
- (*GTK_WIDGET_CLASS(canvas_parent_class)->unmap)(widget);
- }
-}
-
-/* Realize handler for the canvas */
-static void
-ganv_canvas_realize(GtkWidget* widget)
-{
- g_return_if_fail(GANV_IS_CANVAS(widget));
-
- /* Normal widget realization stuff */
-
- if (GTK_WIDGET_CLASS(canvas_parent_class)->realize) {
- (*GTK_WIDGET_CLASS(canvas_parent_class)->realize)(widget);
- }
-
- GanvCanvas* canvas = GANV_CANVAS(widget);
-
- gdk_window_set_events(
- canvas->layout.bin_window,
- (GdkEventMask)(gdk_window_get_events(canvas->layout.bin_window)
- | GDK_EXPOSURE_MASK
- | GDK_BUTTON_PRESS_MASK
- | GDK_BUTTON_RELEASE_MASK
- | GDK_POINTER_MOTION_MASK
- | GDK_KEY_PRESS_MASK
- | GDK_KEY_RELEASE_MASK
- | GDK_ENTER_NOTIFY_MASK
- | GDK_LEAVE_NOTIFY_MASK
- | GDK_FOCUS_CHANGE_MASK));
-
- /* Create our own temporary pixmap gc and realize all the items */
-
- canvas->impl->pixmap_gc = gdk_gc_new(canvas->layout.bin_window);
-
- (*GANV_ITEM_GET_CLASS(canvas->impl->root)->realize)(canvas->impl->root);
-
- canvas->impl->_animate_idle_id = g_timeout_add(
- 120, GanvCanvasImpl::on_animate_timeout, canvas->impl);
-}
-
-/* Unrealize handler for the canvas */
-static void
-ganv_canvas_unrealize(GtkWidget* widget)
-{
- g_return_if_fail(GANV_IS_CANVAS(widget));
-
- GanvCanvas* canvas = GANV_CANVAS(widget);
-
- if (canvas->impl->_animate_idle_id) {
- g_source_remove(canvas->impl->_animate_idle_id);
- canvas->impl->_animate_idle_id = 0;
- }
- while (g_idle_remove_by_data(canvas->impl)) {}
-
- shutdown_transients(canvas);
-
- /* Unrealize items and parent widget */
-
- (*GANV_ITEM_GET_CLASS(canvas->impl->root)->unrealize)(canvas->impl->root);
-
- g_object_unref(canvas->impl->pixmap_gc);
- canvas->impl->pixmap_gc = NULL;
-
- if (GTK_WIDGET_CLASS(canvas_parent_class)->unrealize) {
- (*GTK_WIDGET_CLASS(canvas_parent_class)->unrealize)(widget);
- }
-}
-
-/* Handles scrolling of the canvas. Adjusts the scrolling and zooming offset to
- * keep as much as possible of the canvas scrolling region in view.
- */
-static void
-scroll_to(GanvCanvas* canvas, int cx, int cy)
-{
- int scroll_width, scroll_height;
- int right_limit, bottom_limit;
- int old_zoom_xofs, old_zoom_yofs;
- int changed_x = FALSE, changed_y = FALSE;
- int canvas_width, canvas_height;
-
- canvas_width = GTK_WIDGET(canvas)->allocation.width;
- canvas_height = GTK_WIDGET(canvas)->allocation.height;
-
- scroll_width = floor((canvas->impl->scroll_x2 - canvas->impl->scroll_x1) * canvas->impl->pixels_per_unit
- + 0.5);
- scroll_height = floor((canvas->impl->scroll_y2 - canvas->impl->scroll_y1) * canvas->impl->pixels_per_unit
- + 0.5);
-
- right_limit = scroll_width - canvas_width;
- bottom_limit = scroll_height - canvas_height;
-
- old_zoom_xofs = canvas->impl->zoom_xofs;
- old_zoom_yofs = canvas->impl->zoom_yofs;
-
- if (right_limit < 0) {
- cx = 0;
-
- if (canvas->impl->center_scroll_region) {
- canvas->impl->zoom_xofs = (canvas_width - scroll_width) / 2;
- scroll_width = canvas_width;
- } else {
- canvas->impl->zoom_xofs = 0;
- }
- } else if (cx < 0) {
- cx = 0;
- canvas->impl->zoom_xofs = 0;
- } else if (cx > right_limit) {
- cx = right_limit;
- canvas->impl->zoom_xofs = 0;
- } else {
- canvas->impl->zoom_xofs = 0;
- }
-
- if (bottom_limit < 0) {
- cy = 0;
-
- if (canvas->impl->center_scroll_region) {
- canvas->impl->zoom_yofs = (canvas_height - scroll_height) / 2;
- scroll_height = canvas_height;
- } else {
- canvas->impl->zoom_yofs = 0;
- }
- } else if (cy < 0) {
- cy = 0;
- canvas->impl->zoom_yofs = 0;
- } else if (cy > bottom_limit) {
- cy = bottom_limit;
- canvas->impl->zoom_yofs = 0;
- } else {
- canvas->impl->zoom_yofs = 0;
- }
-
- if ((canvas->impl->zoom_xofs != old_zoom_xofs) || (canvas->impl->zoom_yofs != old_zoom_yofs)) {
- ganv_canvas_request_update(canvas);
- gtk_widget_queue_draw(GTK_WIDGET(canvas));
- }
-
- if (canvas->layout.hadjustment && ( ((int)canvas->layout.hadjustment->value) != cx) ) {
- canvas->layout.hadjustment->value = cx;
- changed_x = TRUE;
- }
-
- if (canvas->layout.vadjustment && ( ((int)canvas->layout.vadjustment->value) != cy) ) {
- canvas->layout.vadjustment->value = cy;
- changed_y = TRUE;
- }
-
- if ((scroll_width != (int)canvas->layout.width)
- || (scroll_height != (int)canvas->layout.height)) {
- gtk_layout_set_size(GTK_LAYOUT(canvas), scroll_width, scroll_height);
- }
-
- /* Signal GtkLayout that it should do a redraw. */
-
- if (changed_x) {
- g_signal_emit_by_name(canvas->layout.hadjustment, "value_changed");
- }
-
- if (changed_y) {
- g_signal_emit_by_name(canvas->layout.vadjustment, "value_changed");
- }
-}
-
-/* Size allocation handler for the canvas */
-static void
-ganv_canvas_size_allocate(GtkWidget* widget, GtkAllocation* allocation)
-{
- g_return_if_fail(GANV_IS_CANVAS(widget));
- g_return_if_fail(allocation != NULL);
-
- if (GTK_WIDGET_CLASS(canvas_parent_class)->size_allocate) {
- (*GTK_WIDGET_CLASS(canvas_parent_class)->size_allocate)(widget, allocation);
- }
-
- GanvCanvas* canvas = GANV_CANVAS(widget);
-
- /* Recenter the view, if appropriate */
-
- canvas->layout.hadjustment->page_size = allocation->width;
- canvas->layout.hadjustment->page_increment = allocation->width / 2;
-
- canvas->layout.vadjustment->page_size = allocation->height;
- canvas->layout.vadjustment->page_increment = allocation->height / 2;
-
- scroll_to(canvas,
- canvas->layout.hadjustment->value,
- canvas->layout.vadjustment->value);
-
- g_signal_emit_by_name(canvas->layout.hadjustment, "changed");
- g_signal_emit_by_name(canvas->layout.vadjustment, "changed");
-}
-
-/* Returns whether the item is an inferior of or is equal to the parent. */
-static gboolean
-is_descendant(GanvItem* item, GanvItem* parent)
-{
- for (; item; item = item->impl->parent) {
- if (item == parent) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-
-/* Emits an event for an item in the canvas, be it the current item, grabbed
- * item, or focused item, as appropriate.
- */
-int
-ganv_canvas_emit_event(GanvCanvas* canvas, GdkEvent* event)
-{
- GdkEvent* ev;
- gint finished;
- GanvItem* item;
- GanvItem* parent;
- guint mask;
-
- /* Perform checks for grabbed items */
-
- if (canvas->impl->grabbed_item
- && !is_descendant(canvas->impl->current_item, canvas->impl->grabbed_item)) {
- /* I think this warning is annoying and I don't know what it's for
- * so I'll disable it for now.
- */
- /* g_warning ("emit_event() returning FALSE!\n");*/
- return FALSE;
- }
-
- if (canvas->impl->grabbed_item) {
- switch (event->type) {
- case GDK_ENTER_NOTIFY:
- mask = GDK_ENTER_NOTIFY_MASK;
- break;
-
- case GDK_LEAVE_NOTIFY:
- mask = GDK_LEAVE_NOTIFY_MASK;
- break;
-
- case GDK_MOTION_NOTIFY:
- mask = GDK_POINTER_MOTION_MASK;
- break;
-
- case GDK_BUTTON_PRESS:
- case GDK_2BUTTON_PRESS:
- case GDK_3BUTTON_PRESS:
- mask = GDK_BUTTON_PRESS_MASK;
- break;
-
- case GDK_BUTTON_RELEASE:
- mask = GDK_BUTTON_RELEASE_MASK;
- break;
-
- case GDK_KEY_PRESS:
- mask = GDK_KEY_PRESS_MASK;
- break;
-
- case GDK_KEY_RELEASE:
- mask = GDK_KEY_RELEASE_MASK;
- break;
-
- case GDK_SCROLL:
- mask = GDK_SCROLL_MASK;
- break;
-
- default:
- mask = 0;
- break;
- }
-
- if (!(mask & canvas->impl->grabbed_event_mask)) {
- return FALSE;
- }
- }
-
- /* Convert to world coordinates -- we have two cases because of diferent
- * offsets of the fields in the event structures.
- */
-
- ev = gdk_event_copy(event);
-
- switch (ev->type) {
- case GDK_ENTER_NOTIFY:
- case GDK_LEAVE_NOTIFY:
- ganv_canvas_window_to_world(canvas,
- ev->crossing.x, ev->crossing.y,
- &ev->crossing.x, &ev->crossing.y);
- break;
-
- case GDK_MOTION_NOTIFY:
- case GDK_BUTTON_PRESS:
- case GDK_2BUTTON_PRESS:
- case GDK_3BUTTON_PRESS:
- case GDK_BUTTON_RELEASE:
- ganv_canvas_window_to_world(canvas,
- ev->motion.x, ev->motion.y,
- &ev->motion.x, &ev->motion.y);
- break;
-
- default:
- break;
- }
-
- /* Choose where we send the event */
-
- item = canvas->impl->current_item;
-
- if (canvas->impl->focused_item
- && ((event->type == GDK_KEY_PRESS)
- || (event->type == GDK_KEY_RELEASE)
- || (event->type == GDK_FOCUS_CHANGE))) {
- item = canvas->impl->focused_item;
- }
-
- /* The event is propagated up the hierarchy (for if someone connected to
- * a group instead of a leaf event), and emission is stopped if a
- * handler returns TRUE, just like for GtkWidget events.
- */
-
- finished = FALSE;
-
- while (item && !finished) {
- g_object_ref(G_OBJECT(item));
-
- ganv_item_emit_event(item, ev, &finished);
-
- parent = item->impl->parent;
- g_object_unref(G_OBJECT(item));
-
- item = parent;
- }
-
- gdk_event_free(ev);
-
- return finished;
-}
-
-void
-ganv_canvas_set_need_repick(GanvCanvas* canvas)
-{
- canvas->impl->need_repick = TRUE;
-}
-
-void
-ganv_canvas_forget_item(GanvCanvas* canvas, GanvItem* item)
-{
- if (canvas->impl && item == canvas->impl->current_item) {
- canvas->impl->current_item = NULL;
- canvas->impl->need_repick = TRUE;
- }
-
- if (canvas->impl && item == canvas->impl->new_current_item) {
- canvas->impl->new_current_item = NULL;
- canvas->impl->need_repick = TRUE;
- }
-
- if (canvas->impl && item == canvas->impl->grabbed_item) {
- canvas->impl->grabbed_item = NULL;
- gdk_pointer_ungrab(GDK_CURRENT_TIME);
- }
-
- if (canvas->impl && item == canvas->impl->focused_item) {
- canvas->impl->focused_item = NULL;
- }
-}
-
-void
-ganv_canvas_grab_focus(GanvCanvas* canvas, GanvItem* item)
-{
- g_return_if_fail(GANV_IS_ITEM(item));
- g_return_if_fail(GTK_WIDGET_CAN_FOCUS(GTK_WIDGET(canvas)));
-
- GanvItem* focused_item = canvas->impl->focused_item;
- GdkEvent ev;
-
- if (focused_item) {
- ev.focus_change.type = GDK_FOCUS_CHANGE;
- ev.focus_change.window = canvas->layout.bin_window;
- ev.focus_change.send_event = FALSE;
- ev.focus_change.in = FALSE;
-
- ganv_canvas_emit_event(canvas, &ev);
- }
-
- canvas->impl->focused_item = item;
- gtk_widget_grab_focus(GTK_WIDGET(canvas));
-
- if (focused_item) {
- ev.focus_change.type = GDK_FOCUS_CHANGE;
- ev.focus_change.window = canvas->layout.bin_window;
- ev.focus_change.send_event = FALSE;
- ev.focus_change.in = TRUE;
-
- ganv_canvas_emit_event(canvas, &ev);
- }
-}
-
-/**
- * ganv_canvas_grab_item:
- * @item: A canvas item.
- * @event_mask: Mask of events that will be sent to this item.
- * @cursor: If non-NULL, the cursor that will be used while the grab is active.
- * @etime: The timestamp required for grabbing the mouse, or GDK_CURRENT_TIME.
- *
- * Specifies that all events that match the specified event mask should be sent
- * to the specified item, and also grabs the mouse by calling
- * gdk_pointer_grab(). The event mask is also used when grabbing the pointer.
- * If @cursor is not NULL, then that cursor is used while the grab is active.
- * The @etime parameter is the timestamp required for grabbing the mouse.
- *
- * Return value: If an item was already grabbed, it returns %GDK_GRAB_ALREADY_GRABBED. If
- * the specified item was hidden by calling ganv_item_hide(), then it
- * returns %GDK_GRAB_NOT_VIEWABLE. Else, it returns the result of calling
- * gdk_pointer_grab().
- **/
-int
-ganv_canvas_grab_item(GanvItem* item, guint event_mask, GdkCursor* cursor, guint32 etime)
-{
- g_return_val_if_fail(GANV_IS_ITEM(item), GDK_GRAB_NOT_VIEWABLE);
- g_return_val_if_fail(GTK_WIDGET_MAPPED(item->impl->canvas), GDK_GRAB_NOT_VIEWABLE);
-
- if (item->impl->canvas->impl->grabbed_item) {
- return GDK_GRAB_ALREADY_GRABBED;
- }
-
- if (!(item->object.flags & GANV_ITEM_VISIBLE)) {
- return GDK_GRAB_NOT_VIEWABLE;
- }
-
- int retval = gdk_pointer_grab(item->impl->canvas->layout.bin_window,
- FALSE,
- (GdkEventMask)event_mask,
- NULL,
- cursor,
- etime);
-
- if (retval != GDK_GRAB_SUCCESS) {
- return retval;
- }
-
- item->impl->canvas->impl->grabbed_item = item;
- item->impl->canvas->impl->grabbed_event_mask = event_mask;
- item->impl->canvas->impl->current_item = item; /* So that events go to the grabbed item */
-
- return retval;
-}
-
-/**
- * ganv_canvas_ungrab_item:
- * @item: A canvas item that holds a grab.
- * @etime: The timestamp for ungrabbing the mouse.
- *
- * Ungrabs the item, which must have been grabbed in the canvas, and ungrabs the
- * mouse.
- **/
-void
-ganv_canvas_ungrab_item(GanvItem* item, guint32 etime)
-{
- g_return_if_fail(GANV_IS_ITEM(item));
-
- if (item->impl->canvas->impl->grabbed_item != item) {
- return;
- }
-
- item->impl->canvas->impl->grabbed_item = NULL;
-
- gdk_pointer_ungrab(etime);
-}
-
-void
-ganv_canvas_get_zoom_offsets(GanvCanvas* canvas, int* x, int* y)
-{
- *x = canvas->impl->zoom_xofs;
- *y = canvas->impl->zoom_yofs;
-}
-
-/* Re-picks the current item in the canvas, based on the event's coordinates.
- * Also emits enter/leave events for items as appropriate.
- */
-static int
-pick_current_item(GanvCanvas* canvas, GdkEvent* event)
-{
- int retval = FALSE;
-
- /* If a button is down, we'll perform enter and leave events on the
- * current item, but not enter on any other item. This is more or less
- * like X pointer grabbing for canvas items.
- */
- int button_down = canvas->impl->state & (GDK_BUTTON1_MASK
- | GDK_BUTTON2_MASK
- | GDK_BUTTON3_MASK
- | GDK_BUTTON4_MASK
- | GDK_BUTTON5_MASK);
- if (!button_down) {
- canvas->impl->left_grabbed_item = FALSE;
- }
-
- /* Save the event in the canvas. This is used to synthesize enter and
- * leave events in case the current item changes. It is also used to
- * re-pick the current item if the current one gets deleted. Also,
- * synthesize an enter event.
- */
- if (event != &canvas->impl->pick_event) {
- if ((event->type == GDK_MOTION_NOTIFY) || (event->type == GDK_BUTTON_RELEASE)) {
- /* these fields have the same offsets in both types of events */
-
- canvas->impl->pick_event.crossing.type = GDK_ENTER_NOTIFY;
- canvas->impl->pick_event.crossing.window = event->motion.window;
- canvas->impl->pick_event.crossing.send_event = event->motion.send_event;
- canvas->impl->pick_event.crossing.subwindow = NULL;
- canvas->impl->pick_event.crossing.x = event->motion.x;
- canvas->impl->pick_event.crossing.y = event->motion.y;
- canvas->impl->pick_event.crossing.mode = GDK_CROSSING_NORMAL;
- canvas->impl->pick_event.crossing.detail = GDK_NOTIFY_NONLINEAR;
- canvas->impl->pick_event.crossing.focus = FALSE;
- canvas->impl->pick_event.crossing.state = event->motion.state;
-
- /* these fields don't have the same offsets in both types of events */
-
- if (event->type == GDK_MOTION_NOTIFY) {
- canvas->impl->pick_event.crossing.x_root = event->motion.x_root;
- canvas->impl->pick_event.crossing.y_root = event->motion.y_root;
- } else {
- canvas->impl->pick_event.crossing.x_root = event->button.x_root;
- canvas->impl->pick_event.crossing.y_root = event->button.y_root;
- }
- } else {
- canvas->impl->pick_event = *event;
- }
- }
-
- /* Don't do anything else if this is a recursive call */
-
- if (canvas->impl->in_repick) {
- return retval;
- }
-
- /* LeaveNotify means that there is no current item, so we don't look for one */
-
- if (canvas->impl->pick_event.type != GDK_LEAVE_NOTIFY) {
- /* these fields don't have the same offsets in both types of events */
-
- double x, y;
- if (canvas->impl->pick_event.type == GDK_ENTER_NOTIFY) {
- x = canvas->impl->pick_event.crossing.x - canvas->impl->zoom_xofs;
- y = canvas->impl->pick_event.crossing.y - canvas->impl->zoom_yofs;
- } else {
- x = canvas->impl->pick_event.motion.x - canvas->impl->zoom_xofs;
- y = canvas->impl->pick_event.motion.y - canvas->impl->zoom_yofs;
- }
-
- /* world coords */
-
- x = canvas->impl->scroll_x1 + x / canvas->impl->pixels_per_unit;
- y = canvas->impl->scroll_y1 + y / canvas->impl->pixels_per_unit;
-
- /* find the closest item */
-
- if (canvas->impl->root->object.flags & GANV_ITEM_VISIBLE) {
- GANV_ITEM_GET_CLASS(canvas->impl->root)->point(
- canvas->impl->root,
- x - canvas->impl->root->impl->x, y - canvas->impl->root->impl->y,
- &canvas->impl->new_current_item);
- } else {
- canvas->impl->new_current_item = NULL;
- }
- } else {
- canvas->impl->new_current_item = NULL;
- }
-
- if ((canvas->impl->new_current_item == canvas->impl->current_item) && !canvas->impl->left_grabbed_item) {
- return retval; /* current item did not change */
-
- }
- /* Synthesize events for old and new current items */
-
- if ((canvas->impl->new_current_item != canvas->impl->current_item)
- && (canvas->impl->current_item != NULL)
- && !canvas->impl->left_grabbed_item) {
- GdkEvent new_event;
-
- new_event = canvas->impl->pick_event;
- new_event.type = GDK_LEAVE_NOTIFY;
-
- new_event.crossing.detail = GDK_NOTIFY_ANCESTOR;
- new_event.crossing.subwindow = NULL;
- canvas->impl->in_repick = TRUE;
- retval = ganv_canvas_emit_event(canvas, &new_event);
- canvas->impl->in_repick = FALSE;
- }
-
- /* new_current_item may have been set to NULL during the call to ganv_canvas_emit_event() above */
-
- if ((canvas->impl->new_current_item != canvas->impl->current_item) && button_down) {
- canvas->impl->left_grabbed_item = TRUE;
- return retval;
- }
-
- /* Handle the rest of cases */
-
- canvas->impl->left_grabbed_item = FALSE;
- canvas->impl->current_item = canvas->impl->new_current_item;
-
- if (canvas->impl->current_item != NULL) {
- GdkEvent new_event;
-
- new_event = canvas->impl->pick_event;
- new_event.type = GDK_ENTER_NOTIFY;
- new_event.crossing.detail = GDK_NOTIFY_ANCESTOR;
- new_event.crossing.subwindow = NULL;
- retval = ganv_canvas_emit_event(canvas, &new_event);
- }
-
- return retval;
-}
-
-/* Button event handler for the canvas */
-static gint
-ganv_canvas_button(GtkWidget* widget, GdkEventButton* event)
-{
- int mask;
- int retval;
-
- g_return_val_if_fail(GANV_IS_CANVAS(widget), FALSE);
- g_return_val_if_fail(event != NULL, FALSE);
-
- retval = FALSE;
-
- GanvCanvas* canvas = GANV_CANVAS(widget);
-
- /*
- * dispatch normally regardless of the event's window if an item has
- * has a pointer grab in effect
- */
- if (!canvas->impl->grabbed_item && ( event->window != canvas->layout.bin_window) ) {
- return retval;
- }
-
- switch (event->button) {
- case 1:
- mask = GDK_BUTTON1_MASK;
- break;
- case 2:
- mask = GDK_BUTTON2_MASK;
- break;
- case 3:
- mask = GDK_BUTTON3_MASK;
- break;
- case 4:
- mask = GDK_BUTTON4_MASK;
- break;
- case 5:
- mask = GDK_BUTTON5_MASK;
- break;
- default:
- mask = 0;
- }
-
- switch (event->type) {
- case GDK_BUTTON_PRESS:
- case GDK_2BUTTON_PRESS:
- case GDK_3BUTTON_PRESS:
- /* Pick the current item as if the button were not pressed, and
- * then process the event.
- */
- canvas->impl->state = event->state;
- pick_current_item(canvas, (GdkEvent*)event);
- canvas->impl->state ^= mask;
- retval = ganv_canvas_emit_event(canvas, (GdkEvent*)event);
- break;
-
- case GDK_BUTTON_RELEASE:
- /* Process the event as if the button were pressed, then repick
- * after the button has been released
- */
- canvas->impl->state = event->state;
- retval = ganv_canvas_emit_event(canvas, (GdkEvent*)event);
- event->state ^= mask;
- canvas->impl->state = event->state;
- pick_current_item(canvas, (GdkEvent*)event);
- event->state ^= mask;
- break;
-
- default:
- g_assert_not_reached();
- }
-
- return retval;
-}
-
-/* Motion event handler for the canvas */
-static gint
-ganv_canvas_motion(GtkWidget* widget, GdkEventMotion* event)
-{
- g_return_val_if_fail(GANV_IS_CANVAS(widget), FALSE);
- g_return_val_if_fail(event != NULL, FALSE);
-
- GanvCanvas* canvas = GANV_CANVAS(widget);
-
- if (event->window != canvas->layout.bin_window) {
- return FALSE;
- }
-
- canvas->impl->state = event->state;
- pick_current_item(canvas, (GdkEvent*)event);
- return ganv_canvas_emit_event(canvas, (GdkEvent*)event);
-}
-
-static gboolean
-ganv_canvas_scroll(GtkWidget* widget, GdkEventScroll* event)
-{
- g_return_val_if_fail(GANV_IS_CANVAS(widget), FALSE);
- g_return_val_if_fail(event != NULL, FALSE);
-
- GanvCanvas* canvas = GANV_CANVAS(widget);
-
- if (event->window != canvas->layout.bin_window) {
- return FALSE;
- }
-
- canvas->impl->state = event->state;
- pick_current_item(canvas, (GdkEvent*)event);
- return ganv_canvas_emit_event(canvas, (GdkEvent*)event);
-}
-
-/* Key event handler for the canvas */
-static gboolean
-ganv_canvas_key(GtkWidget* widget, GdkEventKey* event)
-{
- g_return_val_if_fail(GANV_IS_CANVAS(widget), FALSE);
- g_return_val_if_fail(event != NULL, FALSE);
-
- GanvCanvas* canvas = GANV_CANVAS(widget);
-
- if (!ganv_canvas_emit_event(canvas, (GdkEvent*)event)) {
- GtkWidgetClass* widget_class;
-
- widget_class = GTK_WIDGET_CLASS(canvas_parent_class);
-
- if (event->type == GDK_KEY_PRESS) {
- if (widget_class->key_press_event) {
- return (*widget_class->key_press_event)(widget, event);
- }
- } else if (event->type == GDK_KEY_RELEASE) {
- if (widget_class->key_release_event) {
- return (*widget_class->key_release_event)(widget, event);
- }
- } else {
- g_assert_not_reached();
- }
-
- return FALSE;
- } else {
- return TRUE;
- }
-}
-
-/* Crossing event handler for the canvas */
-static gint
-ganv_canvas_crossing(GtkWidget* widget, GdkEventCrossing* event)
-{
- g_return_val_if_fail(GANV_IS_CANVAS(widget), FALSE);
- g_return_val_if_fail(event != NULL, FALSE);
-
- GanvCanvas* canvas = GANV_CANVAS(widget);
-
- if (event->window != canvas->layout.bin_window) {
- return FALSE;
- }
-
- canvas->impl->state = event->state;
- return pick_current_item(canvas, (GdkEvent*)event);
-}
-
-/* Focus in handler for the canvas */
-static gint
-ganv_canvas_focus_in(GtkWidget* widget, GdkEventFocus* event)
-{
- GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS);
-
- GanvCanvas* canvas = GANV_CANVAS(widget);
-
- if (canvas->impl->focused_item) {
- return ganv_canvas_emit_event(canvas, (GdkEvent*)event);
- } else {
- return FALSE;
- }
-}
-
-/* Focus out handler for the canvas */
-static gint
-ganv_canvas_focus_out(GtkWidget* widget, GdkEventFocus* event)
-{
- GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS);
-
- GanvCanvas* canvas = GANV_CANVAS(widget);
-
- if (canvas->impl->focused_item) {
- return ganv_canvas_emit_event(canvas, (GdkEvent*)event);
- } else {
- return FALSE;
- }
-}
-
-#define REDRAW_QUANTUM_SIZE 512
-
-static void
-ganv_canvas_paint_rect(GanvCanvas* canvas, gint x0, gint y0, gint x1, gint y1)
-{
- gint draw_x1, draw_y1;
- gint draw_x2, draw_y2;
- gint draw_width, draw_height;
-
- g_return_if_fail(!canvas->impl->need_update);
-
- draw_x1 = MAX(x0, canvas->layout.hadjustment->value - canvas->impl->zoom_xofs);
- draw_y1 = MAX(y0, canvas->layout.vadjustment->value - canvas->impl->zoom_yofs);
- draw_x2 = MIN(draw_x1 + GTK_WIDGET(canvas)->allocation.width, x1);
- draw_y2 = MIN(draw_y1 + GTK_WIDGET(canvas)->allocation.height, y1);
-
- draw_width = draw_x2 - draw_x1;
- draw_height = draw_y2 - draw_y1;
-
- if ((draw_width < 1) || (draw_height < 1)) {
- return;
- }
-
- canvas->impl->redraw_x1 = draw_x1;
- canvas->impl->redraw_y1 = draw_y1;
- canvas->impl->redraw_x2 = draw_x2;
- canvas->impl->redraw_y2 = draw_y2;
- canvas->impl->draw_xofs = draw_x1;
- canvas->impl->draw_yofs = draw_y1;
-
- cairo_t* cr = gdk_cairo_create(canvas->layout.bin_window);
-
- double win_x, win_y;
- ganv_canvas_window_to_world(canvas, 0, 0, &win_x, &win_y);
- cairo_translate(cr, -win_x, -win_y);
- cairo_scale(cr, canvas->impl->pixels_per_unit, canvas->impl->pixels_per_unit);
-
- if (canvas->impl->root->object.flags & GANV_ITEM_VISIBLE) {
- double wx1, wy1, ww, wh;
- ganv_canvas_c2w(canvas, draw_x1, draw_y1, &wx1, &wy1);
- ganv_canvas_c2w(canvas, draw_width, draw_height, &ww, &wh);
-
- // Draw background
- double r, g, b, a;
- color_to_rgba(DEFAULT_BACKGROUND_COLOR, &r, &g, &b, &a);
- cairo_set_source_rgba(cr, r, g, b, a);
- cairo_rectangle(cr, wx1, wy1, ww, wh);
- cairo_fill(cr);
-
- // Draw root group
- (*GANV_ITEM_GET_CLASS(canvas->impl->root)->draw)(
- canvas->impl->root, cr,
- wx1, wy1, ww, wh);
- }
-
- cairo_destroy(cr);
-}
-
-/* Expose handler for the canvas */
-static gint
-ganv_canvas_expose(GtkWidget* widget, GdkEventExpose* event)
-{
- GanvCanvas* canvas = GANV_CANVAS(widget);
- if (!GTK_WIDGET_DRAWABLE(widget) ||
- (event->window != canvas->layout.bin_window)) {
- return FALSE;
- }
-
- /* Find a single bounding rectangle for all rectangles in the region.
- Since drawing the root group is O(n) and thus very expensive for large
- canvases, it's much faster to do a single paint than many, even though
- more area may be painted that way. With a better group implementation,
- it would likely be better to paint each changed rectangle separately. */
- GdkRectangle clip;
- gdk_region_get_clipbox(event->region, &clip);
-
- const int x2 = clip.x + clip.width;
- const int y2 = clip.y + clip.height;
-
- if (canvas->impl->need_update || canvas->impl->need_redraw) {
- /* Update or drawing is scheduled, so just mark exposed area as dirty */
- ganv_canvas_request_redraw_c(canvas, clip.x, clip.y, x2, y2);
- } else {
- /* No pending updates, draw exposed area immediately */
- ganv_canvas_paint_rect(canvas, clip.x, clip.y, x2, y2);
-
- /* And call expose on parent container class */
- if (GTK_WIDGET_CLASS(canvas_parent_class)->expose_event) {
- (*GTK_WIDGET_CLASS(canvas_parent_class)->expose_event)(
- widget, event);
- }
- }
-
- return FALSE;
-}
-
-/* Repaints the areas in the canvas that need it */
-static void
-paint(GanvCanvas* canvas)
-{
- for (GSList* l = canvas->impl->redraw_region; l; l = l->next) {
- IRect* rect = (IRect*)l->data;
-
- const GdkRectangle gdkrect = {
- rect->x + canvas->impl->zoom_xofs,
- rect->y + canvas->impl->zoom_yofs,
- rect->width,
- rect->height
- };
-
- gdk_window_invalidate_rect(canvas->layout.bin_window, &gdkrect, FALSE);
- g_free(rect);
- }
-
- g_slist_free(canvas->impl->redraw_region);
- canvas->impl->redraw_region = NULL;
- canvas->impl->need_redraw = FALSE;
-
- canvas->impl->redraw_x1 = 0;
- canvas->impl->redraw_y1 = 0;
- canvas->impl->redraw_x2 = 0;
- canvas->impl->redraw_y2 = 0;
-}
-
-static void
-do_update(GanvCanvas* canvas)
-{
- /* Cause the update if necessary */
-
-update_again:
- if (canvas->impl->need_update) {
- ganv_item_invoke_update(canvas->impl->root, 0);
-
- canvas->impl->need_update = FALSE;
- }
-
- /* Pick new current item */
-
- while (canvas->impl->need_repick) {
- canvas->impl->need_repick = FALSE;
- pick_current_item(canvas, &canvas->impl->pick_event);
- }
-
- /* it is possible that during picking we emitted an event in which
- the user then called some function which then requested update
- of something. Without this we'd be left in a state where
- need_update would have been left TRUE and the canvas would have
- been left unpainted. */
- if (canvas->impl->need_update) {
- goto update_again;
- }
-
- /* Paint if able to */
-
- if (GTK_WIDGET_DRAWABLE(canvas) && canvas->impl->need_redraw) {
- paint(canvas);
- }
-}
-
-/* Idle handler for the canvas. It deals with pending updates and redraws. */
-static gboolean
-idle_handler(gpointer data)
-{
- GDK_THREADS_ENTER();
-
- GanvCanvas* canvas = GANV_CANVAS(data);
-
- do_update(canvas);
-
- /* Reset idle id */
- canvas->impl->idle_id = 0;
-
- GDK_THREADS_LEAVE();
-
- return FALSE;
-}
-
-/* Convenience function to add an idle handler to a canvas */
-static void
-add_idle(GanvCanvas* canvas)
-{
- g_assert(canvas->impl->need_update || canvas->impl->need_redraw);
-
- if (!canvas->impl->idle_id) {
- canvas->impl->idle_id = g_idle_add_full(CANVAS_IDLE_PRIORITY,
- idle_handler,
- canvas,
- NULL);
- }
-
- /* canvas->idle_id = gtk_idle_add (idle_handler, canvas); */
-}
-
-GanvItem*
-ganv_canvas_root(GanvCanvas* canvas)
-{
- g_return_val_if_fail(GANV_IS_CANVAS(canvas), NULL);
-
- return canvas->impl->root;
-}
-
-void
-ganv_canvas_set_scroll_region(GanvCanvas* canvas,
- double x1, double y1, double x2, double y2)
-{
- double wxofs, wyofs;
- int xofs, yofs;
-
- g_return_if_fail(GANV_IS_CANVAS(canvas));
-
- /*
- * Set the new scrolling region. If possible, do not move the visible contents of the
- * canvas.
- */
-
- ganv_canvas_c2w(canvas,
- GTK_LAYOUT(canvas)->hadjustment->value + canvas->impl->zoom_xofs,
- GTK_LAYOUT(canvas)->vadjustment->value + canvas->impl->zoom_yofs,
- /*canvas->impl->zoom_xofs,
- canvas->impl->zoom_yofs,*/
- &wxofs, &wyofs);
-
- canvas->impl->scroll_x1 = x1;
- canvas->impl->scroll_y1 = y1;
- canvas->impl->scroll_x2 = x2;
- canvas->impl->scroll_y2 = y2;
-
- ganv_canvas_w2c(canvas, wxofs, wyofs, &xofs, &yofs);
-
- scroll_to(canvas, xofs, yofs);
-
- canvas->impl->need_repick = TRUE;
-#if 0
- /* todo: should be requesting update */
- (*GANV_ITEM_CLASS(canvas->impl->root->object.klass)->update)(
- canvas->impl->root, NULL, NULL, 0);
-#endif
-}
-
-void
-ganv_canvas_get_scroll_region(GanvCanvas* canvas,
- double* x1, double* y1, double* x2, double* y2)
-{
- g_return_if_fail(GANV_IS_CANVAS(canvas));
-
- if (x1) {
- *x1 = canvas->impl->scroll_x1;
- }
-
- if (y1) {
- *y1 = canvas->impl->scroll_y1;
- }
-
- if (x2) {
- *x2 = canvas->impl->scroll_x2;
- }
-
- if (y2) {
- *y2 = canvas->impl->scroll_y2;
- }
-}
-
-void
-ganv_canvas_set_center_scroll_region(GanvCanvas* canvas, gboolean center_scroll_region)
-{
- g_return_if_fail(GANV_IS_CANVAS(canvas));
-
- canvas->impl->center_scroll_region = center_scroll_region != 0;
-
- scroll_to(canvas,
- canvas->layout.hadjustment->value,
- canvas->layout.vadjustment->value);
-}
-
-gboolean
-ganv_canvas_get_center_scroll_region(const GanvCanvas* canvas)
-{
- g_return_val_if_fail(GANV_IS_CANVAS(canvas), FALSE);
-
- return canvas->impl->center_scroll_region ? TRUE : FALSE;
-}
-
-void
-ganv_canvas_scroll_to(GanvCanvas* canvas, int cx, int cy)
-{
- g_return_if_fail(GANV_IS_CANVAS(canvas));
-
- scroll_to(canvas, cx, cy);
-}
-
-void
-ganv_canvas_get_scroll_offsets(const GanvCanvas* canvas, int* cx, int* cy)
-{
- g_return_if_fail(GANV_IS_CANVAS(canvas));
-
- if (cx) {
- *cx = canvas->layout.hadjustment->value;
- }
-
- if (cy) {
- *cy = canvas->layout.vadjustment->value;
- }
-}
-
-GanvItem*
-ganv_canvas_get_item_at(GanvCanvas* canvas, double x, double y)
-{
- g_return_val_if_fail(GANV_IS_CANVAS(canvas), NULL);
-
- GanvItem* item = NULL;
- double dist = GANV_ITEM_GET_CLASS(canvas->impl->root)->point(
- canvas->impl->root,
- x - canvas->impl->root->impl->x,
- y - canvas->impl->root->impl->y,
- &item);
- if ((int)(dist * canvas->impl->pixels_per_unit + 0.5) <= GANV_CLOSE_ENOUGH) {
- return item;
- } else {
- return NULL;
- }
-}
-
-void
-ganv_canvas_request_update(GanvCanvas* canvas)
-{
- if (canvas->impl->need_update) {
- return;
- }
-
- canvas->impl->need_update = TRUE;
- if (GTK_WIDGET_MAPPED((GtkWidget*)canvas)) {
- add_idle(canvas);
- }
-}
-
-static inline gboolean
-rect_overlaps(const IRect* a, const IRect* b)
-{
- if ((a->x > b->x + b->width) ||
- (a->y > b->y + b->height) ||
- (a->x + a->width < b->x) ||
- (a->y + a->height < b->y)) {
- return FALSE;
- }
- return TRUE;
-}
-
-static inline gboolean
-rect_is_visible(GanvCanvas* canvas, const IRect* r)
-{
- const IRect rect = {
- (int)(canvas->layout.hadjustment->value - canvas->impl->zoom_xofs),
- (int)(canvas->layout.vadjustment->value - canvas->impl->zoom_yofs),
- GTK_WIDGET(canvas)->allocation.width,
- GTK_WIDGET(canvas)->allocation.height
- };
-
- return rect_overlaps(&rect, r);
-}
-
-void
-ganv_canvas_request_redraw_c(GanvCanvas* canvas,
- int x1, int y1, int x2, int y2)
-{
- g_return_if_fail(GANV_IS_CANVAS(canvas));
-
- if (!GTK_WIDGET_DRAWABLE(canvas) || (x1 >= x2) || (y1 >= y2)) {
- return;
- }
-
- const IRect rect = { x1, y1, x2 - x1, y2 - y1 };
-
- if (!rect_is_visible(canvas, &rect)) {
- return;
- }
-
- IRect* r = (IRect*)g_malloc(sizeof(IRect));
- *r = rect;
-
- canvas->impl->redraw_region = g_slist_prepend(canvas->impl->redraw_region, r);
- canvas->impl->need_redraw = TRUE;
-
- if (canvas->impl->idle_id == 0) {
- add_idle(canvas);
- }
-}
-
-/* Request a redraw of the specified rectangle in world coordinates */
-void
-ganv_canvas_request_redraw_w(GanvCanvas* canvas,
- double x1, double y1, double x2, double y2)
-{
- int cx1, cx2, cy1, cy2;
- ganv_canvas_w2c(canvas, x1, y1, &cx1, &cy1);
- ganv_canvas_w2c(canvas, x2, y2, &cx2, &cy2);
- ganv_canvas_request_redraw_c(canvas, cx1, cy1, cx2, cy2);
-}
-
-void
-ganv_canvas_w2c_affine(GanvCanvas* canvas, cairo_matrix_t* matrix)
-{
- g_return_if_fail(GANV_IS_CANVAS(canvas));
- g_return_if_fail(matrix != NULL);
-
- cairo_matrix_init_translate(matrix,
- -canvas->impl->scroll_x1,
- -canvas->impl->scroll_y1);
-
- cairo_matrix_scale(matrix,
- canvas->impl->pixels_per_unit,
- canvas->impl->pixels_per_unit);
-}
-
-void
-ganv_canvas_w2c(GanvCanvas* canvas, double wx, double wy, int* cx, int* cy)
-{
- g_return_if_fail(GANV_IS_CANVAS(canvas));
-
- cairo_matrix_t matrix;
- ganv_canvas_w2c_affine(canvas, &matrix);
-
- cairo_matrix_transform_point(&matrix, &wx, &wy);
-
- if (cx) {
- *cx = floor(wx + 0.5);
- }
- if (cy) {
- *cy = floor(wy + 0.5);
- }
-}
-
-void
-ganv_canvas_w2c_d(GanvCanvas* canvas, double wx, double wy, double* cx, double* cy)
-{
- g_return_if_fail(GANV_IS_CANVAS(canvas));
-
- cairo_matrix_t matrix;
- ganv_canvas_w2c_affine(canvas, &matrix);
-
- cairo_matrix_transform_point(&matrix, &wx, &wy);
-
- if (cx) {
- *cx = wx;
- }
- if (cy) {
- *cy = wy;
- }
-}
-
-void
-ganv_canvas_c2w(GanvCanvas* canvas, int cx, int cy, double* wx, double* wy)
-{
- g_return_if_fail(GANV_IS_CANVAS(canvas));
-
- cairo_matrix_t matrix;
- ganv_canvas_w2c_affine(canvas, &matrix);
- cairo_matrix_invert(&matrix);
-
- double x = cx;
- double y = cy;
- cairo_matrix_transform_point(&matrix, &x, &y);
-
- if (wx) {
- *wx = x;
- }
- if (wy) {
- *wy = y;
- }
-}
-
-void
-ganv_canvas_window_to_world(GanvCanvas* canvas, double winx, double winy,
- double* worldx, double* worldy)
-{
- g_return_if_fail(GANV_IS_CANVAS(canvas));
-
- if (worldx) {
- *worldx = canvas->impl->scroll_x1 + ((winx - canvas->impl->zoom_xofs)
- / canvas->impl->pixels_per_unit);
- }
-
- if (worldy) {
- *worldy = canvas->impl->scroll_y1 + ((winy - canvas->impl->zoom_yofs)
- / canvas->impl->pixels_per_unit);
- }
-}
-
-void
-ganv_canvas_world_to_window(GanvCanvas* canvas, double worldx, double worldy,
- double* winx, double* winy)
-{
- g_return_if_fail(GANV_IS_CANVAS(canvas));
-
- if (winx) {
- *winx = (canvas->impl->pixels_per_unit) * (worldx - canvas->impl->scroll_x1) + canvas->impl->zoom_xofs;
- }
-
- if (winy) {
- *winy = (canvas->impl->pixels_per_unit) * (worldy - canvas->impl->scroll_y1) + canvas->impl->zoom_yofs;
- }
-}
-
-void
-ganv_canvas_set_port_order(GanvCanvas* canvas,
- GanvPortOrderFunc port_cmp,
- void* data)
-{
- g_return_if_fail(GANV_IS_CANVAS(canvas));
-
- canvas->impl->_port_order.port_cmp = port_cmp;
- canvas->impl->_port_order.data = data;
-}
-
-PortOrderCtx
-ganv_canvas_get_port_order(GanvCanvas* canvas)
-{
- return canvas->impl->_port_order;
-}
-
-gboolean
-ganv_canvas_exporting(GanvCanvas* canvas)
-{
- return canvas->impl->exporting;
-}
-
-} // extern "C"
diff --git a/src/Port.cpp b/src/Port.cpp
deleted file mode 100644
index 3f0d02b..0000000
--- a/src/Port.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2015 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <string>
-
-#include <glib.h>
-
-#include "ganv/Canvas.hpp"
-#include "ganv/Module.hpp"
-#include "ganv/Port.hpp"
-
-#include "./color.h"
-
-namespace Ganv {
-
-static void
-on_value_changed(GanvPort* port, double value, void* portmm)
-{
- ((Port*)portmm)->signal_value_changed.emit(value);
-}
-
-/* Construct a Port on an existing module. */
-Port::Port(Module& module,
- const std::string& name,
- bool is_input,
- uint32_t color)
- : Box(module.canvas(),
- GANV_BOX(ganv_port_new(module.gobj(), is_input,
- "fill-color", color,
- "border-color", PORT_BORDER_COLOR(color),
- "border-width", 2.0,
- "label", name.c_str(),
- NULL)))
-{
- g_signal_connect(gobj(), "value-changed",
- G_CALLBACK(on_value_changed), this);
-}
-
-Module*
-Port::get_module() const
-{
- return Glib::wrap(ganv_port_get_module(gobj()));
-}
-
-} // namespace Ganv
diff --git a/src/boilerplate.h b/src/boilerplate.h
deleted file mode 100644
index a419711..0000000
--- a/src/boilerplate.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2016 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-typedef gpointer gobject;
-
-/**
- A case in a switch statement in a set_properties implementation.
- @prop: Property enumeration ID.
- @type: Name of the value type, e.g. uint for guint.
- @field: Field to set to the new value.
-*/
-#define SET_CASE(prop, type, field) \
- case PROP_##prop: { \
- const g##type tmp = g_value_get_##type(value); \
- if ((field) != tmp) { \
- (field) = tmp; \
- ganv_item_request_update(GANV_ITEM(object)); \
- } \
- break; \
- }
-
-/**
- A case in a switch statement in a get_properties implementation.
- @prop: Property enumeration ID.
- @type: Name of the value type, e.g. uint for guint.
- @field: Field to set to the new value.
-*/
-#define GET_CASE(prop, type, field) \
- case PROP_##prop: \
- g_value_set_##type(value, field); \
- break;
diff --git a/src/box.c b/src/box.c
deleted file mode 100644
index e7ecac8..0000000
--- a/src/box.c
+++ /dev/null
@@ -1,561 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2015 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <math.h>
-#include <string.h>
-
-#include <cairo.h>
-
-#include "ganv/box.h"
-
-#include "./boilerplate.h"
-#include "./color.h"
-#include "./gettext.h"
-#include "./ganv-private.h"
-
-static const double STACKED_OFFSET = 4.0;
-
-G_DEFINE_TYPE_WITH_CODE(GanvBox, ganv_box, GANV_TYPE_NODE,
- G_ADD_PRIVATE(GanvBox))
-
-static GanvNodeClass* parent_class;
-
-enum {
- PROP_0,
- PROP_X1,
- PROP_Y1,
- PROP_X2,
- PROP_Y2,
- PROP_RADIUS_TL,
- PROP_RADIUS_TR,
- PROP_RADIUS_BR,
- PROP_RADIUS_BL,
- PROP_STACKED,
- PROP_BEVELED
-};
-
-static void
-ganv_box_init(GanvBox* box)
-{
- box->impl = ganv_box_get_instance_private(box);
-
- memset(&box->impl->coords, '\0', sizeof(GanvBoxCoords));
-
- box->impl->coords.border_width = GANV_NODE(box)->impl->border_width;
- box->impl->old_coords = box->impl->coords;
- box->impl->radius_tl = 0.0;
- box->impl->radius_tr = 0.0;
- box->impl->radius_br = 0.0;
- box->impl->radius_bl = 0.0;
- box->impl->beveled = FALSE;
-}
-
-static void
-ganv_box_destroy(GtkObject* object)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_BOX(object));
-
- if (GTK_OBJECT_CLASS(parent_class)->destroy) {
- (*GTK_OBJECT_CLASS(parent_class)->destroy)(object);
- }
-}
-
-static void
-ganv_box_set_property(GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_BOX(object));
-
- GanvBox* box = GANV_BOX(object);
- GanvBoxPrivate* impl = box->impl;
- GanvBoxCoords* coords = &impl->coords;
-
- switch (prop_id) {
- SET_CASE(X1, double, coords->x1);
- SET_CASE(Y1, double, coords->y1);
- SET_CASE(X2, double, coords->x2);
- SET_CASE(Y2, double, coords->y2);
- SET_CASE(RADIUS_TL, double, impl->radius_tl);
- SET_CASE(RADIUS_TR, double, impl->radius_tr);
- SET_CASE(RADIUS_BR, double, impl->radius_br);
- SET_CASE(RADIUS_BL, double, impl->radius_bl);
- SET_CASE(STACKED, boolean, coords->stacked);
- SET_CASE(BEVELED, boolean, impl->beveled);
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-ganv_box_get_property(GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_BOX(object));
-
- GanvBox* box = GANV_BOX(object);
- GanvBoxPrivate* impl = box->impl;
- GanvBoxCoords* coords = &impl->coords;
-
- switch (prop_id) {
- GET_CASE(X1, double, coords->x1);
- GET_CASE(X2, double, coords->x2);
- GET_CASE(Y1, double, coords->y1);
- GET_CASE(Y2, double, coords->y2);
- GET_CASE(RADIUS_TL, double, impl->radius_tl);
- GET_CASE(RADIUS_TR, double, impl->radius_tr);
- GET_CASE(RADIUS_BR, double, impl->radius_br);
- GET_CASE(RADIUS_BL, double, impl->radius_bl);
- GET_CASE(STACKED, boolean, impl->coords.stacked);
- GET_CASE(BEVELED, boolean, impl->beveled);
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-ganv_box_bounds_item(const GanvBoxCoords* coords,
- double* x1, double* y1,
- double* x2, double* y2)
-{
- *x1 = coords->x1 - coords->border_width;
- *y1 = coords->y1 - coords->border_width;
- *x2 = coords->x2 + coords->border_width + (coords->stacked * STACKED_OFFSET);
- *y2 = coords->y2 + coords->border_width + (coords->stacked * STACKED_OFFSET);
-}
-
-void
-ganv_box_request_redraw(GanvItem* item,
- const GanvBoxCoords* coords,
- gboolean world)
-{
- double x1, y1, x2, y2;
- ganv_box_bounds_item(coords, &x1, &y1, &x2, &y2);
-
- if (!world) {
- // Convert from item-relative coordinates to world coordinates
- ganv_item_i2w_pair(item, &x1, &y1, &x2, &y2);
- }
-
- ganv_canvas_request_redraw_w(item->impl->canvas, x1, y1, x2, y2);
-}
-
-static void
-coords_i2w(GanvItem* item, GanvBoxCoords* coords)
-{
- ganv_item_i2w_pair(item, &coords->x1, &coords->y1, &coords->x2, &coords->y2);
-}
-
-static void
-ganv_box_bounds(GanvItem* item,
- double* x1, double* y1,
- double* x2, double* y2)
-{
- // Note this will not be correct if children are outside the box bounds
- GanvBox* box = (GanvBox*)item;
- ganv_box_bounds_item(&box->impl->coords, x1, y1, x2, y2);
-}
-
-static void
-ganv_box_update(GanvItem* item, int flags)
-{
- GanvBox* box = GANV_BOX(item);
- GanvBoxPrivate* impl = box->impl;
- impl->coords.border_width = box->node.impl->border_width;
-
- // Request redraw of old location
- ganv_box_request_redraw(item, &impl->old_coords, TRUE);
-
- // Store old coordinates in world relative coordinates in case the
- // group we are in moves between now and the next update
- impl->old_coords = impl->coords;
- coords_i2w(item, &impl->old_coords);
-
- // Call parent class update method, resizing if necessary
- GANV_ITEM_CLASS(parent_class)->update(item, flags);
- ganv_box_normalize(box);
-
- // Update world-relative bounding box
- ganv_box_bounds(item, &item->impl->x1, &item->impl->y1, &item->impl->x2, &item->impl->y2);
- ganv_item_i2w_pair(item, &item->impl->x1, &item->impl->y1, &item->impl->x2, &item->impl->y2);
-
- // Request redraw of new location
- ganv_box_request_redraw(item, &impl->coords, FALSE);
-}
-
-void
-ganv_box_path(GanvBox* box,
- cairo_t* cr, double x1, double y1, double x2, double y2,
- double dr)
-{
- static const double degrees = G_PI / 180.0;
-
- GanvBoxPrivate* impl = box->impl;
-
- if (impl->radius_tl == 0.0 && impl->radius_tr == 0.0
- && impl->radius_br == 0.0 && impl->radius_bl == 0.0) {
- // Simple rectangle
- cairo_rectangle(cr, x1, y1, x2 - x1, y2 - y1);
- } else if (impl->beveled) {
- // Beveled rectangle
- cairo_new_sub_path(cr);
- cairo_move_to(cr, x1 + impl->radius_tl, y1);
- cairo_line_to(cr, x2 - impl->radius_tr, y1);
- cairo_line_to(cr, x2, y1 + impl->radius_tr);
- cairo_line_to(cr, x2, y2 - impl->radius_br);
- cairo_line_to(cr, x2 - impl->radius_br, y2);
- cairo_line_to(cr, x1 + impl->radius_bl, y2);
- cairo_line_to(cr, x1, y2 - impl->radius_bl);
- cairo_line_to(cr, x1, y2 - impl->radius_bl);
- cairo_line_to(cr, x1, y1 + impl->radius_tl);
- cairo_close_path(cr);
- } else {
- // Rounded rectangle
- cairo_new_sub_path(cr);
- cairo_arc(cr,
- x2 - impl->radius_tr - dr,
- y1 + impl->radius_tr + dr,
- impl->radius_tr + dr, -90 * degrees, 0 * degrees);
- cairo_arc(cr,
- x2 - impl->radius_br - dr, y2 - impl->radius_br - dr,
- impl->radius_br + dr, 0 * degrees, 90 * degrees);
- cairo_arc(cr,
- x1 + impl->radius_bl + dr, y2 - impl->radius_bl - dr,
- impl->radius_bl + dr, 90 * degrees, 180 * degrees);
- cairo_arc(cr,
- x1 + impl->radius_tl + dr, y1 + impl->radius_tl + dr,
- impl->radius_tl + dr, 180 * degrees, 270 * degrees);
- cairo_close_path(cr);
- }
-}
-
-static void
-ganv_box_draw(GanvItem* item,
- cairo_t* cr, double cx, double cy, double cw, double ch)
-{
- GanvBox* box = GANV_BOX(item);
- GanvBoxPrivate* impl = box->impl;
-
- double x1 = impl->coords.x1;
- double y1 = impl->coords.y1;
- double x2 = impl->coords.x2;
- double y2 = impl->coords.y2;
- ganv_item_i2w_pair(item, &x1, &y1, &x2, &y2);
-
- double dash_length, border_color, fill_color;
- ganv_node_get_draw_properties(
- &box->node, &dash_length, &border_color, &fill_color);
-
- double r, g, b, a;
-
- for (int i = (impl->coords.stacked ? 1 : 0); i >= 0; --i) {
- const double x = 0.0 - (STACKED_OFFSET * i);
- const double y = 0.0 - (STACKED_OFFSET * i);
-
- // Trace basic box path
- ganv_box_path(box, cr, x1 - x, y1 - y, x2 - x, y2 - y, 0.0);
-
- // Fill
- color_to_rgba(fill_color, &r, &g, &b, &a);
- cairo_set_source_rgba(cr, r, g, b, a);
-
- // Border
- if (impl->coords.border_width > 0.0) {
- cairo_fill_preserve(cr);
- color_to_rgba(border_color, &r, &g, &b, &a);
- cairo_set_source_rgba(cr, r, g, b, a);
- cairo_set_line_width(cr, impl->coords.border_width);
- if (dash_length > 0) {
- cairo_set_dash(cr, &dash_length, 1, box->node.impl->dash_offset);
- } else {
- cairo_set_dash(cr, &dash_length, 0, 0);
- }
- cairo_stroke(cr);
- } else {
- cairo_fill(cr);
- }
- }
-
- GanvItemClass* item_class = GANV_ITEM_CLASS(parent_class);
- item_class->draw(item, cr, cx, cy, cw, ch);
-}
-
-static double
-ganv_box_point(GanvItem* item, double x, double y, GanvItem** actual_item)
-{
- GanvBox* box = GANV_BOX(item);
- GanvBoxPrivate* impl = box->impl;
-
- *actual_item = NULL;
-
- double x1, y1, x2, y2;
- ganv_box_bounds_item(&impl->coords, &x1, &y1, &x2, &y2);
-
- // Point is inside the box (distance 0)
- if ((x >= x1) && (y >= y1) && (x <= x2) && (y <= y2)) {
- *actual_item = item;
- return 0.0;
- }
-
- // Point is outside the box
- double dx = 0.0;
- double dy = 0.0;
-
- // Find horizontal distance to nearest edge
- if (x < x1) {
- dx = x1 - x;
- } else if (x > x2) {
- dx = x - x2;
- }
-
- // Find vertical distance to nearest edge
- if (y < y1) {
- dy = y1 - y;
- } else if (y > y2) {
- dy = y - y2;
- }
-
- return sqrt((dx * dx) + (dy * dy));
-}
-
-static gboolean
-ganv_box_is_within(const GanvNode* self,
- double x1,
- double y1,
- double x2,
- double y2)
-{
- double bx1, by1, bx2, by2;
- g_object_get(G_OBJECT(self),
- "x1", &bx1,
- "y1", &by1,
- "x2", &bx2,
- "y2", &by2,
- NULL);
-
- ganv_item_i2w_pair(GANV_ITEM(self), &bx1, &by1, &bx2, &by2);
-
- return ( bx1 >= x1
- && by2 >= y1
- && bx2 <= x2
- && by2 <= y2);
-}
-
-static void
-ganv_box_default_set_width(GanvBox* box, double width)
-{
- box->impl->coords.x2 = ganv_box_get_x1(box) + width;
- ganv_item_request_update(GANV_ITEM(box));
-}
-
-static void
-ganv_box_default_set_height(GanvBox* box, double height)
-{
- box->impl->coords.y2 = ganv_box_get_y1(box) + height;
- ganv_item_request_update(GANV_ITEM(box));
-}
-
-static void
-ganv_box_class_init(GanvBoxClass* klass)
-{
- GObjectClass* gobject_class = (GObjectClass*)klass;
- GtkObjectClass* object_class = (GtkObjectClass*)klass;
- GanvItemClass* item_class = (GanvItemClass*)klass;
- GanvNodeClass* node_class = (GanvNodeClass*)klass;
-
- parent_class = GANV_NODE_CLASS(g_type_class_peek_parent(klass));
-
- gobject_class->set_property = ganv_box_set_property;
- gobject_class->get_property = ganv_box_get_property;
-
- g_object_class_install_property(
- gobject_class, PROP_X1, g_param_spec_double(
- "x1",
- _("x1"),
- _("Top left x coordinate."),
- -G_MAXDOUBLE, G_MAXDOUBLE,
- 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_Y1, g_param_spec_double(
- "y1",
- _("y1"),
- _("Top left y coordinate."),
- -G_MAXDOUBLE, G_MAXDOUBLE,
- 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_X2, g_param_spec_double(
- "x2",
- _("x2"),
- _("Bottom right x coordinate."),
- -G_MAXDOUBLE, G_MAXDOUBLE,
- 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_Y2, g_param_spec_double(
- "y2",
- _("y2"),
- _("Bottom right y coordinate."),
- -G_MAXDOUBLE, G_MAXDOUBLE,
- 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_RADIUS_TL, g_param_spec_double(
- "radius-tl",
- _("Top left radius"),
- _("The radius of the top left corner."),
- 0.0, G_MAXDOUBLE,
- 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_RADIUS_TR, g_param_spec_double(
- "radius-tr",
- _("Top right radius"),
- _("The radius of the top right corner."),
- 0.0, G_MAXDOUBLE,
- 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_RADIUS_BR, g_param_spec_double(
- "radius-br",
- _("Bottom right radius"),
- _("The radius of the bottom right corner."),
- 0.0, G_MAXDOUBLE,
- 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_RADIUS_BL, g_param_spec_double(
- "radius-bl",
- _("Bottom left radius"),
- _("The radius of the bottom left corner."),
- 0.0, G_MAXDOUBLE,
- 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_STACKED, g_param_spec_boolean(
- "stacked",
- _("Stacked"),
- _("Show box with a stacked appearance."),
- FALSE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_BEVELED, g_param_spec_boolean(
- "beveled",
- _("Beveled"),
- _("Show radiused corners with a sharp bevel."),
- FALSE,
- G_PARAM_READWRITE));
-
- object_class->destroy = ganv_box_destroy;
-
- item_class->update = ganv_box_update;
- item_class->bounds = ganv_box_bounds;
- item_class->point = ganv_box_point;
- item_class->draw = ganv_box_draw;
-
- node_class->is_within = ganv_box_is_within;
-
- klass->set_width = ganv_box_default_set_width;
- klass->set_height = ganv_box_default_set_height;
-}
-
-void
-ganv_box_normalize(GanvBox* box)
-{
- if (box->impl->coords.x2 < box->impl->coords.x1) {
- const double tmp = box->impl->coords.x1;
- box->impl->coords.x1 = box->impl->coords.x2;
- box->impl->coords.x2 = tmp;
- }
- if (box->impl->coords.y2 < box->impl->coords.y1) {
- const double tmp = box->impl->coords.y1;
- box->impl->coords.y1 = box->impl->coords.y2;
- box->impl->coords.y2 = tmp;
- }
-}
-
-double
-ganv_box_get_x1(const GanvBox* box)
-{
- return box->impl->coords.x1;
-}
-
-double
-ganv_box_get_y1(const GanvBox* box)
-{
- return box->impl->coords.y1;
-}
-
-double
-ganv_box_get_x2(const GanvBox* box)
-{
- return box->impl->coords.x2;
-}
-
-double
-ganv_box_get_y2(const GanvBox* box)
-{
- return box->impl->coords.y2;
-}
-
-double
-ganv_box_get_width(const GanvBox* box)
-{
- return box->impl->coords.x2 - box->impl->coords.x1;
-}
-
-void
-ganv_box_set_width(GanvBox* box,
- double width)
-{
- GANV_BOX_GET_CLASS(box)->set_width(box, width);
-}
-
-double
-ganv_box_get_height(const GanvBox* box)
-{
- return box->impl->coords.y2 - box->impl->coords.y1;
-}
-
-void
-ganv_box_set_height(GanvBox* box,
- double height)
-{
- GANV_BOX_GET_CLASS(box)->set_height(box, height);
-}
-
-double
-ganv_box_get_border_width(const GanvBox* box)
-{
- return box->impl->coords.border_width;
-}
diff --git a/src/circle.c b/src/circle.c
deleted file mode 100644
index a69c207..0000000
--- a/src/circle.c
+++ /dev/null
@@ -1,467 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2015 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <math.h>
-#include <string.h>
-
-#include "ganv/canvas.h"
-#include "ganv/circle.h"
-
-#include "./color.h"
-#include "./boilerplate.h"
-#include "./gettext.h"
-#include "./ganv-private.h"
-
-G_DEFINE_TYPE_WITH_CODE(GanvCircle, ganv_circle, GANV_TYPE_NODE,
- G_ADD_PRIVATE(GanvCircle))
-
-static GanvNodeClass* parent_class;
-
-enum {
- PROP_0,
- PROP_RADIUS,
- PROP_RADIUS_EMS,
- PROP_FIT_LABEL
-};
-
-static void
-ganv_circle_init(GanvCircle* circle)
-{
- circle->impl = ganv_circle_get_instance_private(circle);
-
- memset(&circle->impl->coords, '\0', sizeof(GanvCircleCoords));
- circle->impl->coords.radius = 0.0;
- circle->impl->coords.radius_ems = 1.0;
- circle->impl->coords.width = 2.0;
- circle->impl->old_coords = circle->impl->coords;
- circle->impl->fit_label = TRUE;
-}
-
-static void
-ganv_circle_destroy(GtkObject* object)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_CIRCLE(object));
-
- if (GTK_OBJECT_CLASS(parent_class)->destroy) {
- (*GTK_OBJECT_CLASS(parent_class)->destroy)(object);
- }
-}
-
-static void
-ganv_circle_set_property(GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_CIRCLE(object));
-
- GanvCircle* circle = GANV_CIRCLE(object);
-
- switch (prop_id) {
- SET_CASE(RADIUS, double, circle->impl->coords.radius);
- SET_CASE(RADIUS_EMS, double, circle->impl->coords.radius_ems);
- SET_CASE(FIT_LABEL, boolean, circle->impl->fit_label);
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-
- if (prop_id == PROP_RADIUS_EMS) {
- ganv_circle_set_radius_ems(circle, circle->impl->coords.radius_ems);
- }
-}
-
-static void
-ganv_circle_get_property(GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_CIRCLE(object));
-
- GanvCircle* circle = GANV_CIRCLE(object);
-
- switch (prop_id) {
- GET_CASE(RADIUS, double, circle->impl->coords.radius);
- GET_CASE(RADIUS_EMS, double, circle->impl->coords.radius_ems);
- GET_CASE(FIT_LABEL, boolean, circle->impl->fit_label);
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-ganv_circle_resize(GanvNode* self)
-{
- GanvNode* node = GANV_NODE(self);
- GanvCircle* circle = GANV_CIRCLE(self);
- GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(node)->impl->canvas);
-
- if (node->impl->label) {
- if (node->impl->label->impl->needs_layout) {
- ganv_text_layout(node->impl->label);
- }
-
- const double label_w = node->impl->label->impl->coords.width;
- const double label_h = node->impl->label->impl->coords.height;
- if (circle->impl->fit_label) {
- // Resize to fit text
- const double radius = MAX(label_w, label_h) / 2.0 + 3.0;
- if (radius != circle->impl->coords.radius) {
- ganv_item_set(GANV_ITEM(self),
- "radius", radius,
- NULL);
- }
- }
-
- // Center label
- ganv_item_set(GANV_ITEM(node->impl->label),
- "x", label_w / -2.0,
- "y", label_h / -2.0,
- NULL);
- }
-
- if (parent_class->resize) {
- parent_class->resize(self);
- }
-
- ganv_canvas_for_each_edge_on(
- canvas, node, (GanvEdgeFunc)ganv_edge_update_location, NULL);
-}
-
-static void
-ganv_circle_redraw_text(GanvNode* self)
-{
- GanvCircle* circle = GANV_CIRCLE(self);
- if (circle->impl->coords.radius_ems) {
- ganv_circle_set_radius_ems(circle, circle->impl->coords.radius_ems);
- }
-
- if (parent_class->redraw_text) {
- parent_class->redraw_text(self);
- }
-}
-
-static gboolean
-ganv_circle_is_within(const GanvNode* self,
- double x1,
- double y1,
- double x2,
- double y2)
-{
- const double x = GANV_ITEM(self)->impl->x;
- const double y = GANV_ITEM(self)->impl->y;
-
- return x >= x1
- && x <= x2
- && y >= y1
- && y <= y2;
-}
-
-static void
-ganv_circle_vector(const GanvNode* self,
- const GanvNode* other,
- double* x,
- double* y,
- double* dx,
- double* dy)
-{
- GanvCircle* circle = GANV_CIRCLE(self);
-
- const double cx = GANV_ITEM(self)->impl->x;
- const double cy = GANV_ITEM(self)->impl->y;
- const double other_x = GANV_ITEM(other)->impl->x;
- const double other_y = GANV_ITEM(other)->impl->y;
-
- const double border = circle->node.impl->border_width;
- const double xdist = other_x - cx;
- const double ydist = other_y - cy;
- const double h = sqrt((xdist * xdist) + (ydist * ydist));
- const double theta = asin(xdist / (h + DBL_EPSILON));
- const double y_mod = (cy < other_y) ? 1 : -1;
- const double ret_h = h - circle->impl->coords.radius - border / 2.0;
- const double ret_x = other_x - sin(theta) * ret_h;
- const double ret_y = other_y - cos(theta) * ret_h * y_mod;
-
- *x = ret_x;
- *y = ret_y;
- *dx = 0.0;
- *dy = 0.0;
-
- ganv_item_i2w(GANV_ITEM(circle)->impl->parent, x, y);
-}
-
-static void
-request_redraw(GanvItem* item,
- const GanvCircleCoords* coords,
- gboolean world)
-{
- const double w = coords->width;
-
- double x1 = coords->x - coords->radius - w;
- double y1 = coords->y - coords->radius - w;
- double x2 = coords->x + coords->radius + w;
- double y2 = coords->y + coords->radius + w;
-
- if (!world) {
- // Convert from parent-relative coordinates to world coordinates
- ganv_item_i2w_pair(item, &x1, &y1, &x2, &y2);
- }
-
- ganv_canvas_request_redraw_w(item->impl->canvas, x1, y1, x2, y2);
-}
-
-static void
-coords_i2w(GanvItem* item, GanvCircleCoords* coords)
-{
- ganv_item_i2w(item, &coords->x, &coords->y);
-}
-
-static void
-ganv_circle_bounds_item(GanvItem* item,
- double* x1, double* y1,
- double* x2, double* y2)
-{
- const GanvCircle* circle = GANV_CIRCLE(item);
- const GanvCircleCoords* coords = &circle->impl->coords;
- *x1 = coords->x - coords->radius - coords->width;
- *y1 = coords->y - coords->radius - coords->width;
- *x2 = coords->x + coords->radius + coords->width;
- *y2 = coords->y + coords->radius + coords->width;
-}
-
-static void
-ganv_circle_bounds(GanvItem* item,
- double* x1, double* y1,
- double* x2, double* y2)
-{
- ganv_circle_bounds_item(item, x1, y1, x2, y2);
-}
-
-static void
-ganv_circle_update(GanvItem* item, int flags)
-{
- GanvCircle* circle = GANV_CIRCLE(item);
- GanvCirclePrivate* impl = circle->impl;
- impl->coords.width = circle->node.impl->border_width;
-
- // Request redraw of old location
- request_redraw(item, &impl->old_coords, TRUE);
-
- // Store old coordinates in world relative coordinates in case the
- // group we are in moves between now and the next update
- impl->old_coords = impl->coords;
- coords_i2w(item, &impl->old_coords);
-
- // Update world-relative bounding box
- ganv_circle_bounds(item, &item->impl->x1, &item->impl->y1, &item->impl->x2, &item->impl->y2);
- ganv_item_i2w_pair(item, &item->impl->x1, &item->impl->y1, &item->impl->x2, &item->impl->y2);
-
- // Request redraw of new location
- request_redraw(item, &impl->coords, FALSE);
-
- GANV_ITEM_CLASS(parent_class)->update(item, flags);
-}
-
-static void
-ganv_circle_draw(GanvItem* item,
- cairo_t* cr, double cx, double cy, double cw, double ch)
-{
- GanvNode* node = GANV_NODE(item);
- GanvCircle* circle = GANV_CIRCLE(item);
- GanvCirclePrivate* impl = circle->impl;
-
- double r, g, b, a;
-
- double x = impl->coords.x;
- double y = impl->coords.y;
- ganv_item_i2w(item, &x, &y);
-
- double dash_length, border_color, fill_color;
- ganv_node_get_draw_properties(
- &circle->node, &dash_length, &border_color, &fill_color);
-
- // Fill
- cairo_new_path(cr);
- cairo_arc(cr,
- x,
- y,
- impl->coords.radius + (impl->coords.width / 2.0),
- 0, 2 * G_PI);
- color_to_rgba(fill_color, &r, &g, &b, &a);
- cairo_set_source_rgba(cr, r, g, b, a);
- cairo_fill(cr);
-
- // Border
- cairo_arc(cr,
- x,
- y,
- impl->coords.radius,
- 0, 2 * G_PI);
- color_to_rgba(border_color, &r, &g, &b, &a);
- cairo_set_source_rgba(cr, r, g, b, a);
- cairo_set_line_width(cr, impl->coords.width);
- if (dash_length > 0) {
- cairo_set_dash(cr, &dash_length, 1, circle->node.impl->dash_offset);
- } else {
- cairo_set_dash(cr, &dash_length, 0, 0);
- }
- cairo_stroke(cr);
-
- // Draw label
- if (node->impl->label) {
- GanvItem* label_item = GANV_ITEM(node->impl->label);
-
- if (label_item->object.flags & GANV_ITEM_VISIBLE) {
- GANV_ITEM_GET_CLASS(label_item)->draw(
- label_item, cr, cx, cy, cw, ch);
- }
- }
-}
-
-static double
-ganv_circle_point(GanvItem* item, double x, double y, GanvItem** actual_item)
-{
- const GanvCircle* circle = GANV_CIRCLE(item);
- const GanvCircleCoords* coords = &circle->impl->coords;
-
- *actual_item = item;
-
- const double dx = fabs(x - coords->x);
- const double dy = fabs(y - coords->y);
- const double d = sqrt((dx * dx) + (dy * dy));
-
- if (d <= coords->radius + coords->width) {
- // Point is inside the circle
- return 0.0;
- } else {
- // Distance from the edge of the circle
- return d - (coords->radius + coords->width);
- }
-}
-
-static void
-ganv_circle_class_init(GanvCircleClass* klass)
-{
- GObjectClass* gobject_class = (GObjectClass*)klass;
- GtkObjectClass* object_class = (GtkObjectClass*)klass;
- GanvItemClass* item_class = (GanvItemClass*)klass;
- GanvNodeClass* node_class = (GanvNodeClass*)klass;
-
- parent_class = GANV_NODE_CLASS(g_type_class_peek_parent(klass));
-
- gobject_class->set_property = ganv_circle_set_property;
- gobject_class->get_property = ganv_circle_get_property;
-
- g_object_class_install_property(
- gobject_class, PROP_RADIUS, g_param_spec_double(
- "radius",
- _("Radius"),
- _("The radius of the circle."),
- 0, G_MAXDOUBLE,
- 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_RADIUS_EMS, g_param_spec_double(
- "radius-ems",
- _("Radius in ems"),
- _("The radius of the circle in ems."),
- 0, G_MAXDOUBLE,
- 1.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_FIT_LABEL, g_param_spec_boolean(
- "fit-label",
- _("Fit label"),
- _("If true, expand circle to fit its label"),
- TRUE,
- (GParamFlags)G_PARAM_READWRITE));
-
- object_class->destroy = ganv_circle_destroy;
-
- node_class->resize = ganv_circle_resize;
- node_class->is_within = ganv_circle_is_within;
- node_class->tail_vector = ganv_circle_vector;
- node_class->head_vector = ganv_circle_vector;
- node_class->redraw_text = ganv_circle_redraw_text;
-
- item_class->update = ganv_circle_update;
- item_class->bounds = ganv_circle_bounds;
- item_class->point = ganv_circle_point;
- item_class->draw = ganv_circle_draw;
-}
-
-GanvCircle*
-ganv_circle_new(GanvCanvas* canvas,
- const char* first_property_name, ...)
-{
- GanvCircle* circle = GANV_CIRCLE(
- g_object_new(ganv_circle_get_type(), "canvas", canvas, NULL));
-
- va_list args;
- va_start(args, first_property_name);
- g_object_set_valist(G_OBJECT(circle), first_property_name, args);
- va_end(args);
-
- return circle;
-}
-
-double
-ganv_circle_get_radius(const GanvCircle* circle)
-{
- return circle->impl->coords.radius;
-}
-
-void
-ganv_circle_set_radius(GanvCircle* circle, double radius)
-{
- circle->impl->coords.radius = radius;
- ganv_item_request_update(GANV_ITEM(circle));
-}
-
-double
-ganv_circle_get_radius_ems(const GanvCircle* circle)
-{
- return circle->impl->coords.radius_ems;
-}
-
-void
-ganv_circle_set_radius_ems(GanvCircle* circle, double ems)
-{
- GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(circle)->impl->canvas);
- const double points = ganv_canvas_get_font_size(canvas);
- circle->impl->coords.radius_ems = ems;
- circle->impl->coords.radius = points * ems;
- ganv_item_request_update(GANV_ITEM(circle));
-}
-
-gboolean
-ganv_circle_get_fit_label(const GanvCircle* circle)
-{
- return circle->impl->fit_label;
-}
-
-void
-ganv_circle_set_fit_label(GanvCircle* circle, gboolean fit_label)
-{
- circle->impl->fit_label = fit_label;
- ganv_item_request_update(GANV_ITEM(circle));
-}
diff --git a/src/color.h b/src/color.h
deleted file mode 100644
index ca52d98..0000000
--- a/src/color.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2015 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_UTIL_H
-#define GANV_UTIL_H
-
-#include <glib.h>
-
-#ifdef GANV_USE_LIGHT_THEME
-# define DEFAULT_BACKGROUND_COLOR 0xFFFFFFFF
-# define DEFAULT_TEXT_COLOR 0x000000FF
-# define DIM_TEXT_COLOR 0x333333BB
-# define DEFAULT_FILL_COLOR 0xEEEEEEFF
-# define DEFAULT_BORDER_COLOR 0x000000FF
-# define PORT_BORDER_COLOR(fill) 0x000000FF
-# define EDGE_COLOR(base) highlight_color(tail_color, -48)
-#else
-# define DEFAULT_BACKGROUND_COLOR 0x000000FF
-# define DEFAULT_TEXT_COLOR 0xFFFFFFFF
-# define DIM_TEXT_COLOR 0xCCCCCCBB
-# define DEFAULT_FILL_COLOR 0x1E2224FF
-# define DEFAULT_BORDER_COLOR 0x3E4244FF
-# define PORT_BORDER_COLOR(fill) highlight_color(fill, 0x20)
-# define EDGE_COLOR(base) highlight_color(tail_color, 48)
-#endif
-
-static inline void
-color_to_rgba(guint color, double* r, double* g, double* b, double* a)
-{
- *r = ((color >> 24) & 0xFF) / 255.0;
- *g = ((color >> 16) & 0xFF) / 255.0;
- *b = ((color >> 8) & 0xFF) / 255.0;
- *a = ((color) & 0xFF) / 255.0;
-}
-
-static inline guint
-highlight_color(guint c, guint delta)
-{
- const guint max_char = 255;
- const guint r = MIN((c >> 24) + delta, max_char);
- const guint g = MIN(((c >> 16) & 0xFF) + delta, max_char);
- const guint b = MIN(((c >> 8) & 0xFF) + delta, max_char);
- const guint a = c & 0xFF;
-
- return ((((guint)(r)) << 24) |
- (((guint)(g)) << 16) |
- (((guint)(b)) << 8) |
- (((guint)(a))));
-}
-
-#endif // GANV_UTIL_H
diff --git a/src/edge.c b/src/edge.c
deleted file mode 100644
index a22bc73..0000000
--- a/src/edge.c
+++ /dev/null
@@ -1,786 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2016 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <math.h>
-#include <string.h>
-
-#include <cairo.h>
-
-#include "ganv/canvas.h"
-#include "ganv/edge.h"
-#include "ganv/node.h"
-
-#include "./boilerplate.h"
-#include "./color.h"
-#include "./gettext.h"
-
-#include "color.h"
-#include "ganv-private.h"
-
-#define ARROW_DEPTH 32
-#define ARROW_BREADTH 32
-
-// Uncomment to see control point path as straight lines
-//#define GANV_DEBUG_CURVES 1
-
-// Uncomment along with GANV_DEBUG_CURVES to see bounding box (buggy)
-//#define GANV_DEBUG_BOUNDS 1
-
-enum {
- PROP_0,
- PROP_TAIL,
- PROP_HEAD,
- PROP_WIDTH,
- PROP_HANDLE_RADIUS,
- PROP_DASH_LENGTH,
- PROP_DASH_OFFSET,
- PROP_COLOR,
- PROP_CONSTRAINING,
- PROP_CURVED,
- PROP_ARROWHEAD,
- PROP_SELECTED,
- PROP_HIGHLIGHTED,
- PROP_GHOST
-};
-
-G_DEFINE_TYPE_WITH_CODE(GanvEdge, ganv_edge, GANV_TYPE_ITEM,
- G_ADD_PRIVATE(GanvEdge))
-
-static GanvItemClass* parent_class;
-
-static void
-ganv_edge_init(GanvEdge* edge)
-{
- GanvEdgePrivate* impl = ganv_edge_get_instance_private(edge);
-
- edge->impl = impl;
-
- impl->tail = NULL;
- impl->head = NULL;
-
- memset(&impl->coords, '\0', sizeof(GanvEdgeCoords));
- impl->coords.width = 2.0;
- impl->coords.handle_radius = 4.0;
- impl->coords.constraining = TRUE;
- impl->coords.curved = FALSE;
- impl->coords.arrowhead = FALSE;
-
- impl->old_coords = impl->coords;
- impl->dash_length = 0.0;
- impl->dash_offset = 0.0;
- impl->color = 0;
-}
-
-static void
-ganv_edge_destroy(GtkObject* object)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_EDGE(object));
-
- GanvEdge* edge = GANV_EDGE(object);
- GanvCanvas* canvas = GANV_CANVAS(edge->item.impl->canvas);
- if (canvas && !edge->impl->ghost) {
- edge->item.impl->canvas = NULL;
- }
- edge->item.impl->parent = NULL;
-
- if (GTK_OBJECT_CLASS(parent_class)->destroy) {
- (*GTK_OBJECT_CLASS(parent_class)->destroy)(object);
- }
-}
-
-static void
-ganv_edge_set_property(GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_EDGE(object));
-
- GanvItem* item = GANV_ITEM(object);
- GanvEdge* edge = GANV_EDGE(object);
- GanvEdgePrivate* impl = edge->impl;
- GanvEdgeCoords* coords = &impl->coords;
-
- switch (prop_id) {
- SET_CASE(WIDTH, double, coords->width);
- SET_CASE(HANDLE_RADIUS, double, coords->handle_radius);
- SET_CASE(DASH_LENGTH, double, impl->dash_length);
- SET_CASE(DASH_OFFSET, double, impl->dash_offset);
- SET_CASE(COLOR, uint, impl->color);
- SET_CASE(CONSTRAINING, boolean, impl->coords.constraining);
- SET_CASE(CURVED, boolean, impl->coords.curved);
- SET_CASE(ARROWHEAD, boolean, impl->coords.arrowhead);
- SET_CASE(SELECTED, boolean, impl->selected);
- SET_CASE(HIGHLIGHTED, boolean, impl->highlighted);
- SET_CASE(GHOST, boolean, impl->ghost);
- case PROP_TAIL: {
- const gobject tmp = g_value_get_object(value);
- if (impl->tail != tmp) {
- impl->tail = GANV_NODE(tmp);
- ganv_item_request_update(item);
- }
- break;
- }
- case PROP_HEAD: {
- const gobject tmp = g_value_get_object(value);
- if (impl->head != tmp) {
- impl->head = GANV_NODE(tmp);
- ganv_item_request_update(item);
- }
- break;
- }
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-ganv_edge_get_property(GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_EDGE(object));
-
- GanvEdge* edge = GANV_EDGE(object);
- GanvEdgePrivate* impl = edge->impl;
-
- switch (prop_id) {
- GET_CASE(TAIL, object, impl->tail);
- GET_CASE(HEAD, object, impl->head);
- GET_CASE(WIDTH, double, impl->coords.width);
- SET_CASE(HANDLE_RADIUS, double, impl->coords.handle_radius);
- GET_CASE(DASH_LENGTH, double, impl->dash_length);
- GET_CASE(DASH_OFFSET, double, impl->dash_offset);
- GET_CASE(COLOR, uint, impl->color);
- GET_CASE(CONSTRAINING, boolean, impl->coords.constraining);
- GET_CASE(CURVED, boolean, impl->coords.curved);
- GET_CASE(ARROWHEAD, boolean, impl->coords.arrowhead);
- GET_CASE(SELECTED, boolean, impl->selected);
- GET_CASE(HIGHLIGHTED, boolean, impl->highlighted);
- SET_CASE(GHOST, boolean, impl->ghost);
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-void
-ganv_edge_request_redraw(GanvItem* item,
- const GanvEdgeCoords* coords)
-{
- GanvCanvas* canvas = item->impl->canvas;
- const double w = coords->width;
- if (coords->curved) {
- const double src_x = coords->x1;
- const double src_y = coords->y1;
- const double dst_x = coords->x2;
- const double dst_y = coords->y2;
- const double join_x = (src_x + dst_x) / 2.0;
- const double join_y = (src_y + dst_y) / 2.0;
- const double src_x1 = coords->cx1;
- const double src_y1 = coords->cy1;
- const double dst_x1 = coords->cx2;
- const double dst_y1 = coords->cy2;
-
- const double r1x1 = MIN(MIN(src_x, join_x), src_x1);
- const double r1y1 = MIN(MIN(src_y, join_y), src_y1);
- const double r1x2 = MAX(MAX(src_x, join_x), src_x1);
- const double r1y2 = MAX(MAX(src_y, join_y), src_y1);
- ganv_canvas_request_redraw_w(canvas,
- r1x1 - w, r1y1 - w,
- r1x2 + w, r1y2 + w);
-
- const double r2x1 = MIN(MIN(dst_x, join_x), dst_x1);
- const double r2y1 = MIN(MIN(dst_y, join_y), dst_y1);
- const double r2x2 = MAX(MAX(dst_x, join_x), dst_x1);
- const double r2y2 = MAX(MAX(dst_y, join_y), dst_y1);
- ganv_canvas_request_redraw_w(canvas,
- r2x1 - w, r2y1 - w,
- r2x2 + w, r2y2 + w);
-
- } else {
- const double x1 = MIN(coords->x1, coords->x2);
- const double y1 = MIN(coords->y1, coords->y2);
- const double x2 = MAX(coords->x1, coords->x2);
- const double y2 = MAX(coords->y1, coords->y2);
-
- ganv_canvas_request_redraw_w(canvas,
- x1 - w, y1 - w,
- x2 + w, y2 + w);
- }
-
- if (coords->handle_radius > 0.0) {
- ganv_canvas_request_redraw_w(
- canvas,
- coords->handle_x - coords->handle_radius - w,
- coords->handle_y - coords->handle_radius - w,
- coords->handle_x + coords->handle_radius + w,
- coords->handle_y + coords->handle_radius + w);
- }
-
- if (coords->arrowhead) {
- ganv_canvas_request_redraw_w(
- canvas,
- coords->x2 - ARROW_DEPTH,
- coords->y2 - ARROW_BREADTH,
- coords->x2 + ARROW_DEPTH,
- coords->y2 + ARROW_BREADTH);
- }
-}
-
-static void
-ganv_edge_bounds(GanvItem* item,
- double* x1, double* y1,
- double* x2, double* y2)
-{
- GanvEdge* edge = GANV_EDGE(item);
- GanvEdgePrivate* impl = edge->impl;
- GanvEdgeCoords* coords = &impl->coords;
- const double w = coords->width;
-
- if (coords->curved) {
- *x1 = MIN(coords->x1, MIN(coords->cx1, MIN(coords->x2, coords->cx2))) - w;
- *y1 = MIN(coords->y1, MIN(coords->cy1, MIN(coords->y2, coords->cy2))) - w;
- *x2 = MAX(coords->x1, MAX(coords->cx1, MAX(coords->x2, coords->cx2))) + w;
- *y2 = MAX(coords->y1, MAX(coords->cy1, MAX(coords->y2, coords->cy2))) + w;
- } else {
- *x1 = MIN(impl->coords.x1, impl->coords.x2) - w;
- *y1 = MIN(impl->coords.y1, impl->coords.y2) - w;
- *x2 = MAX(impl->coords.x1, impl->coords.x2) + w;
- *y2 = MAX(impl->coords.y1, impl->coords.y2) + w;
- }
-}
-
-void
-ganv_edge_get_coords(const GanvEdge* edge, GanvEdgeCoords* coords)
-{
- GanvEdgePrivate* impl = edge->impl;
-
- GANV_NODE_GET_CLASS(impl->tail)->tail_vector(
- impl->tail, impl->head,
- &coords->x1, &coords->y1, &coords->cx1, &coords->cy1);
- GANV_NODE_GET_CLASS(impl->head)->head_vector(
- impl->head, impl->tail,
- &coords->x2, &coords->y2, &coords->cx2, &coords->cy2);
-
- const double dx = coords->x2 - coords->x1;
- const double dy = coords->y2 - coords->y1;
-
- coords->handle_x = coords->x1 + (dx / 2.0);
- coords->handle_y = coords->y1 + (dy / 2.0);
-
- const double abs_dx = fabs(dx);
- const double abs_dy = fabs(dy);
-
- coords->cx1 = coords->x1 + (coords->cx1 * (abs_dx / 4.0));
- coords->cy1 = coords->y1 + (coords->cy1 * (abs_dy / 4.0));
- coords->cx2 = coords->x2 + (coords->cx2 * (abs_dx / 4.0));
- coords->cy2 = coords->y2 + (coords->cy2 * (abs_dy / 4.0));
-}
-
-static void
-ganv_edge_update(GanvItem* item, int flags)
-{
- GanvEdge* edge = GANV_EDGE(item);
- GanvEdgePrivate* impl = edge->impl;
-
- // Request redraw of old location
- ganv_edge_request_redraw(item, &impl->old_coords);
-
- // Calculate new coordinates from tail and head
- ganv_edge_get_coords(edge, &impl->coords);
-
- // Update old coordinates
- impl->old_coords = impl->coords;
-
- // Get bounding box
- double x1, x2, y1, y2;
- ganv_edge_bounds(item, &x1, &y1, &x2, &y2);
-
- // Ensure bounding box has non-zero area
- if (x1 == x2) {
- x2 += 1.0;
- }
- if (y1 == y2) {
- y2 += 1.0;
- }
-
- // Update world-relative bounding box
- item->impl->x1 = x1;
- item->impl->y1 = y1;
- item->impl->x2 = x2;
- item->impl->y2 = y2;
- ganv_item_i2w_pair(item, &item->impl->x1, &item->impl->y1, &item->impl->x2, &item->impl->y2);
-
- // Request redraw of new location
- ganv_edge_request_redraw(item, &impl->coords);
-
- parent_class->update(item, flags);
-}
-
-static void
-ganv_edge_draw(GanvItem* item,
- cairo_t* cr, double cx, double cy, double cw, double ch)
-{
- GanvEdge* edge = GANV_EDGE(item);
- GanvEdgePrivate* impl = edge->impl;
-
- double src_x = impl->coords.x1;
- double src_y = impl->coords.y1;
- double dst_x = impl->coords.x2;
- double dst_y = impl->coords.y2;
- double dx = src_x - dst_x;
- double dy = src_y - dst_y;
-
- double r, g, b, a;
- if (impl->highlighted) {
- color_to_rgba(highlight_color(impl->color, 0x40), &r, &g, &b, &a);
- } else {
- color_to_rgba(impl->color, &r, &g, &b, &a);
- }
- cairo_set_source_rgba(cr, r, g, b, a);
-
- cairo_set_line_width(cr, impl->coords.width);
- cairo_move_to(cr, src_x, src_y);
-
- const double dash_length = (impl->selected ? 4.0 : impl->dash_length);
- if (dash_length > 0.0) {
- double dashed[2] = { dash_length, dash_length };
- cairo_set_dash(cr, dashed, 2, impl->dash_offset);
- } else {
- cairo_set_dash(cr, &dash_length, 0, 0);
- }
-
- const double join_x = (src_x + dst_x) / 2.0;
- const double join_y = (src_y + dst_y) / 2.0;
-
- if (impl->coords.curved) {
- // Curved line as 2 paths which join at the middle point
-
- // Path 1 (src_x, src_y) -> (join_x, join_y)
- // Control point 1
- const double src_x1 = impl->coords.cx1;
- const double src_y1 = impl->coords.cy1;
- // Control point 2
- const double src_x2 = (join_x + src_x1) / 2.0;
- const double src_y2 = (join_y + src_y1) / 2.0;
-
- // Path 2, (join_x, join_y) -> (dst_x, dst_y)
- // Control point 1
- const double dst_x1 = impl->coords.cx2;
- const double dst_y1 = impl->coords.cy2;
- // Control point 2
- const double dst_x2 = (join_x + dst_x1) / 2.0;
- const double dst_y2 = (join_y + dst_y1) / 2.0;
-
- cairo_move_to(cr, src_x, src_y);
- cairo_curve_to(cr, src_x1, src_y1, src_x2, src_y2, join_x, join_y);
- cairo_curve_to(cr, dst_x2, dst_y2, dst_x1, dst_y1, dst_x, dst_y);
-
-#ifdef GANV_DEBUG_CURVES
- cairo_stroke(cr);
- cairo_save(cr);
- cairo_set_source_rgba(cr, 1.0, 0, 0, 0.5);
-
- cairo_move_to(cr, src_x, src_y);
- cairo_line_to(cr, src_x1, src_y1);
- cairo_stroke(cr);
-
- cairo_move_to(cr, join_x, join_y);
- cairo_line_to(cr, src_x2, src_y2);
- cairo_stroke(cr);
-
- cairo_move_to(cr, join_x, join_y);
- cairo_line_to(cr, dst_x2, dst_y2);
- cairo_stroke(cr);
-
- cairo_move_to(cr, dst_x, dst_y);
- cairo_line_to(cr, dst_x1, dst_y1);
- cairo_stroke(cr);
-
-#ifdef GANV_DEBUG_BOUNDS
- double bounds_x1, bounds_y1, bounds_x2, bounds_y2;
- ganv_edge_bounds(item, &bounds_x1, &bounds_y1, &bounds_x2, &bounds_y2);
- cairo_rectangle(cr,
- bounds_x1, bounds_y1,
- bounds_x2 - bounds_x1, bounds_y2 - bounds_y1);
-#endif
-
- cairo_restore(cr);
-#endif
-
- cairo_stroke(cr);
- if (impl->coords.arrowhead) {
- cairo_move_to(cr, dst_x - 12, dst_y - 4);
- cairo_line_to(cr, dst_x, dst_y);
- cairo_line_to(cr, dst_x - 12, dst_y + 4);
- cairo_close_path(cr);
- cairo_stroke_preserve(cr);
- cairo_fill(cr);
- }
-
- } else {
- // Straight line from (x1, y1) to (x2, y2)
- cairo_move_to(cr, src_x, src_y);
- cairo_line_to(cr, dst_x, dst_y);
- cairo_stroke(cr);
-
- if (impl->coords.arrowhead) {
- const double ah = sqrt(dx * dx + dy * dy);
- const double adx = dx / ah * 8.0;
- const double ady = dy / ah * 8.0;
-
- cairo_move_to(cr,
- dst_x + adx - ady/1.5,
- dst_y + ady + adx/1.5);
- cairo_set_line_join(cr, CAIRO_LINE_JOIN_BEVEL);
- cairo_line_to(cr, dst_x, dst_y);
- cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER);
- cairo_line_to(cr,
- dst_x + adx + ady/1.5,
- dst_y + ady - adx/1.5);
- cairo_close_path(cr);
- cairo_stroke_preserve(cr);
- cairo_fill(cr);
- }
- }
-
- if (!ganv_canvas_exporting(item->impl->canvas) &&
- impl->coords.handle_radius > 0.0) {
- cairo_move_to(cr, join_x, join_y);
- cairo_arc(cr, join_x, join_y, impl->coords.handle_radius, 0, 2 * G_PI);
- cairo_fill(cr);
- }
-}
-
-static double
-ganv_edge_point(GanvItem* item, double x, double y, GanvItem** actual_item)
-{
- const GanvEdge* edge = GANV_EDGE(item);
- const GanvEdgeCoords* coords = &edge->impl->coords;
-
- const double dx = fabs(x - coords->handle_x);
- const double dy = fabs(y - coords->handle_y);
- const double d = sqrt((dx * dx) + (dy * dy));
-
- *actual_item = item;
-
- if (d <= coords->handle_radius) {
- // Point is inside the handle
- return 0.0;
- } else {
- // Distance from the edge of the handle
- return d - (coords->handle_radius + coords->width);
- }
-}
-
-gboolean
-ganv_edge_is_within(const GanvEdge* edge,
- double x1,
- double y1,
- double x2,
- double y2)
-{
- const double handle_x = edge->impl->coords.handle_x;
- const double handle_y = edge->impl->coords.handle_y;
-
- return handle_x >= x1
- && handle_x <= x2
- && handle_y >= y1
- && handle_y <= y2;
-}
-
-static void
-ganv_edge_class_init(GanvEdgeClass* klass)
-{
- GObjectClass* gobject_class = (GObjectClass*)klass;
- GtkObjectClass* object_class = (GtkObjectClass*)klass;
- GanvItemClass* item_class = (GanvItemClass*)klass;
-
- parent_class = GANV_ITEM_CLASS(g_type_class_peek_parent(klass));
-
- gobject_class->set_property = ganv_edge_set_property;
- gobject_class->get_property = ganv_edge_get_property;
-
- g_object_class_install_property(
- gobject_class, PROP_TAIL, g_param_spec_object(
- "tail",
- _("Tail"),
- _("Node this edge starts from."),
- GANV_TYPE_NODE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_HEAD, g_param_spec_object(
- "head",
- _("Head"),
- _("Node this edge ends at."),
- GANV_TYPE_NODE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_WIDTH, g_param_spec_double(
- "width",
- _("Line width"),
- _("Width of edge line."),
- 0.0, G_MAXDOUBLE,
- 2.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_HANDLE_RADIUS, g_param_spec_double(
- "handle-radius",
- _("Gandle radius"),
- _("Radius of handle in canvas units."),
- 0.0, G_MAXDOUBLE,
- 4.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_DASH_LENGTH, g_param_spec_double(
- "dash-length",
- _("Line dash length"),
- _("Length of line dashes, or zero for no dashing."),
- 0.0, G_MAXDOUBLE,
- 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_DASH_OFFSET, g_param_spec_double(
- "dash-offset",
- _("Line dash offset"),
- _("Start offset for line dashes, used for selected animation."),
- 0.0, G_MAXDOUBLE,
- 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_COLOR, g_param_spec_uint(
- "color",
- _("Color"),
- _("Line color as an RGBA integer."),
- 0, G_MAXUINT,
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_CONSTRAINING, g_param_spec_boolean(
- "constraining",
- _("Constraining"),
- _("Whether edge should constrain the layout."),
- 1,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_CURVED, g_param_spec_boolean(
- "curved",
- _("Curved"),
- _("Whether line should be curved rather than straight."),
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_ARROWHEAD, g_param_spec_boolean(
- "arrowhead",
- _("Arrowhead"),
- _("Whether to show an arrowhead at the head of this edge."),
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_SELECTED, g_param_spec_boolean(
- "selected",
- _("Selected"),
- _("Whether this edge is selected."),
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_HIGHLIGHTED, g_param_spec_boolean(
- "highlighted",
- _("Highlighted"),
- _("Whether to highlight the edge."),
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_GHOST, g_param_spec_boolean(
- "ghost",
- _("Ghost"),
- _("Whether this edge is a `ghost', which is an edge that is not "
- "added to the canvas data structures. Ghost edges are used for "
- "temporary edges that are not considered `real', e.g. the edge "
- "made while dragging to make a connection."),
- 0,
- G_PARAM_READWRITE));
-
- object_class->destroy = ganv_edge_destroy;
-
- item_class->update = ganv_edge_update;
- item_class->bounds = ganv_edge_bounds;
- item_class->point = ganv_edge_point;
- item_class->draw = ganv_edge_draw;
-}
-
-GanvEdge*
-ganv_edge_new(GanvCanvas* canvas,
- GanvNode* tail,
- GanvNode* head,
- const char* first_prop_name, ...)
-{
- GanvEdge* edge = GANV_EDGE(
- g_object_new(ganv_edge_get_type(), NULL));
-
- va_list args;
- va_start(args, first_prop_name);
- ganv_item_construct(&edge->item,
- GANV_ITEM(ganv_canvas_root(canvas)),
- first_prop_name, args);
- va_end(args);
-
- edge->impl->tail = tail;
- edge->impl->head = head;
-
- if (!edge->impl->color) {
- const guint tail_color = GANV_NODE(tail)->impl->fill_color;
- g_object_set(G_OBJECT(edge),
- "color", EDGE_COLOR(tail_color),
- NULL);
- }
-
- if (!edge->impl->ghost) {
- ganv_canvas_add_edge(canvas, edge);
- }
- return edge;
-}
-
-void
-ganv_edge_update_location(GanvEdge* edge)
-{
- ganv_item_request_update(GANV_ITEM(edge));
-}
-
-gboolean
-ganv_edge_get_constraining(const GanvEdge* edge)
-{
- return edge->impl->coords.constraining;
-}
-
-void
-ganv_edge_set_constraining(GanvEdge* edge, gboolean constraining)
-{
- edge->impl->coords.constraining = constraining;
- ganv_edge_request_redraw(GANV_ITEM(edge), &edge->impl->coords);
-}
-
-gboolean
-ganv_edge_get_curved(const GanvEdge* edge)
-{
- return edge->impl->coords.curved;
-}
-
-void
-ganv_edge_set_curved(GanvEdge* edge, gboolean curved)
-{
- edge->impl->coords.curved = curved;
- ganv_edge_request_redraw(GANV_ITEM(edge), &edge->impl->coords);
-}
-
-void
-ganv_edge_set_selected(GanvEdge* edge, gboolean selected)
-{
- GanvCanvas* canvas = GANV_CANVAS(edge->item.impl->canvas);
- if (selected) {
- ganv_canvas_select_edge(canvas, edge);
- } else {
- ganv_canvas_unselect_edge(canvas, edge);
- }
-}
-
-void
-ganv_edge_select(GanvEdge* edge)
-{
- ganv_edge_set_selected(edge, TRUE);
-}
-
-void
-ganv_edge_unselect(GanvEdge* edge)
-{
- ganv_edge_set_selected(edge, FALSE);
-}
-
-void
-ganv_edge_highlight(GanvEdge* edge)
-{
- ganv_edge_set_highlighted(edge, TRUE);
-}
-
-void
-ganv_edge_unhighlight(GanvEdge* edge)
-{
- ganv_edge_set_highlighted(edge, FALSE);
-}
-
-void
-ganv_edge_set_highlighted(GanvEdge* edge, gboolean highlighted)
-{
- edge->impl->highlighted = highlighted;
- ganv_edge_request_redraw(GANV_ITEM(edge), &edge->impl->coords);
-}
-
-void
-ganv_edge_tick(GanvEdge* edge, double seconds)
-{
- ganv_item_set(GANV_ITEM(edge),
- "dash-offset", seconds * 8.0,
- NULL);
-}
-
-void
-ganv_edge_disconnect(GanvEdge* edge)
-{
- if (!edge->impl->ghost) {
- ganv_canvas_disconnect_edge(
- GANV_CANVAS(edge->item.impl->canvas),
- edge);
- }
-}
-
-void
-ganv_edge_remove(GanvEdge* edge)
-{
- if (!edge->impl->ghost) {
- ganv_canvas_remove_edge(
- GANV_CANVAS(edge->item.impl->canvas),
- edge);
- }
-}
-
-GanvNode*
-ganv_edge_get_tail(const GanvEdge* edge)
-{
- return edge->impl->tail;
-}
-
-GanvNode*
-ganv_edge_get_head(const GanvEdge* edge)
-{
- return edge->impl->head;
-}
diff --git a/src/fdgl.hpp b/src/fdgl.hpp
deleted file mode 100644
index 38fded1..0000000
--- a/src/fdgl.hpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2015 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <float.h>
-#include <math.h>
-
-static const double CHARGE_KE = 4000000.0;
-static const double EDGE_K = 16.0;
-static const double EDGE_LEN = 0.1;
-
-struct Region {
- Vector pos;
- Vector area;
-};
-
-inline Vector
-vec_add(const Vector& a, const Vector& b)
-{
- const Vector result = { a.x + b.x, a.y + b.y };
- return result;
-}
-
-inline Vector
-vec_sub(const Vector& a, const Vector& b)
-{
- const Vector result = { a.x - b.x, a.y - b.y };
- return result;
-}
-
-inline Vector
-vec_mult(const Vector& a, double m)
-{
- const Vector result = { a.x * m, a.y * m };
- return result;
-}
-
-inline double
-vec_mult(const Vector& a, const Vector& b)
-{
- return a.x * b.x + a.y * b.y;
-}
-
-/** Magnitude. */
-inline double
-vec_mag(const Vector& vec)
-{
- return sqrt(vec.x * vec.x + vec.y * vec.y);
-}
-
-/** Reciprocal of magnitude. */
-inline double
-vec_rmag(const Vector& vec)
-{
- return 1.0 / sqrt(vec.x * vec.x + vec.y * vec.y);
-}
-
-/** Hooke's law */
-inline Vector
-spring_force(const Vector& a, const Vector& b, double length, double k)
-{
- const Vector vec = vec_sub(b, a);
- const double mag = vec_mag(vec);
- const double displacement = length - mag;
- return vec_mult(vec, k * displacement * 0.5 / mag);
-}
-
-/** Spring force with a directional force to align with flow direction. */
-static const Vector
-edge_force(const Vector& dir, const Vector& hpos, const Vector& tpos)
-{
- return vec_add(dir, spring_force(hpos, tpos, EDGE_LEN, EDGE_K));
-}
-
-/** Constant tide force, does not vary with distance. */
-inline Vector
-tide_force(const Vector& a, const Vector& b, double power)
-{
- static const double G = 0.0000000000667;
- const Vector vec = vec_sub(a, b);
- const double mag = vec_mag(vec);
- return vec_mult(vec, G * power / mag);
-}
-
-inline double
-rect_distance(Vector* vec,
- const double ax1, const double ay1,
- const double ax2, const double ay2,
- const double bx1, const double by1,
- const double bx2, const double by2)
-{
- vec->x = 0.0;
- vec->y = 0.0;
-
- if (ax2 <= bx1) { // A is completely to the left of B
- vec->x = ax2 - bx1;
- if (ay2 <= by1) { // Top Left
- const double dx = bx1 - ax2;
- const double dy = by1 - ay2;
- vec->y = ay2 - by1;
- return sqrt(dx * dx + dy * dy);
- } else if (ay1 >= by2) { // Bottom left
- const double dx = bx1 - ax2;
- const double dy = ay1 - by2;
- vec->y = ay1 - by2;
- return sqrt(dx * dx + dy * dy);
- } else { // Left
- return bx1 - ax2;
- }
- } else if (ax1 >= bx2) { // A is completely to the right of B
- vec->x = ax1 - bx2;
- if (ay2 <= by1) { // Top right
- const double dx = ax1 - bx2;
- const double dy = by1 - ay2;
- vec->y = ay2 - by1;
- return sqrt(dx * dx + dy * dy);
- } else if (ay1 >= by2) { // Bottom right
- const double dx = ax1 - bx2;
- const double dy = ay1 - by2;
- vec->y = ay1 - by2;
- return sqrt(dx * dx + dy * dy);
- } else { // Right
- return ax1 - bx2;
- }
- } else if (ay2 <= by1) { // Top
- vec->y = ay2 - by1;
- return by1 - ay2;
- } else if (ay1 >= by2) { // Bottom
- vec->y = ay1 - by2;
- return ay1 - by2;
- } else { // Overlap
- return 0.0;
- }
-}
-
-/** Repelling charge force, ala Coulomb's law. */
-inline Vector
-repel_force(const Region& a, const Region& b)
-{
- static const double MIN_DIST = 1.0;
-
- Vector vec;
- double dist = rect_distance(
- &vec,
- a.pos.x - (a.area.x / 2.0), a.pos.y - (a.area.y / 2.0),
- a.pos.x + (a.area.x / 2.0), a.pos.y + (a.area.y / 2.0),
- b.pos.x - (b.area.x / 2.0), b.pos.y - (b.area.y / 2.0),
- b.pos.x + (b.area.x / 2.0), b.pos.y + (b.area.y / 2.0));
-
- if (dist <= MIN_DIST) {
- dist = MIN_DIST;
- vec = vec_sub(a.pos, b.pos);
- }
- return vec_mult(vec, (CHARGE_KE * 0.5 / (vec_mag(vec) * dist * dist)));
-}
diff --git a/src/ganv-marshal.list b/src/ganv-marshal.list
deleted file mode 100644
index 64e6c6b..0000000
--- a/src/ganv-marshal.list
+++ /dev/null
@@ -1,4 +0,0 @@
-BOOLEAN:BOXED
-VOID:DOUBLE,DOUBLE
-VOID:OBJECT,INT,INT,INT,INT
-VOID:OBJECT,OBJECT
diff --git a/src/ganv-private.h b/src/ganv-private.h
deleted file mode 100644
index df611a9..0000000
--- a/src/ganv-private.h
+++ /dev/null
@@ -1,403 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2015 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_PRIVATE_H
-#define GANV_PRIVATE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <cairo.h>
-
-#include "ganv/canvas.h"
-#include "ganv/text.h"
-#include "ganv/types.h"
-
-#define GANV_CLOSE_ENOUGH 1
-
-extern guint signal_moved;
-
-/* Box */
-
-typedef struct {
- double x1, y1, x2, y2;
- double border_width;
- gboolean stacked;
-} GanvBoxCoords;
-
-struct _GanvBoxPrivate {
- GanvBoxCoords coords;
- GanvBoxCoords old_coords;
- double radius_tl;
- double radius_tr;
- double radius_br;
- double radius_bl;
- gboolean beveled;
-};
-
-/* Circle */
-
-typedef struct {
- double x, y, radius, radius_ems;
- double width;
-} GanvCircleCoords;
-
-struct _GanvCirclePrivate {
- GanvCircleCoords coords;
- GanvCircleCoords old_coords;
- gboolean fit_label;
-};
-
-/* Edge */
-
-typedef struct {
- double x1, y1, x2, y2;
- double cx1, cy1, cx2, cy2;
- double handle_x, handle_y, handle_radius;
- double width;
- gboolean constraining;
- gboolean curved;
- gboolean arrowhead;
-} GanvEdgeCoords;
-
-struct _GanvEdgePrivate
-{
- GanvNode* tail;
- GanvNode* head;
- GanvEdgeCoords coords;
- GanvEdgeCoords old_coords;
- double dash_length;
- double dash_offset;
- guint color;
- gboolean selected;
- gboolean highlighted;
- gboolean ghost;
-};
-
-/* Module */
-
-struct _GanvModulePrivate
-{
- GPtrArray* ports;
- GanvItem* embed_item;
- int embed_width;
- int embed_height;
- double widest_input;
- double widest_output;
- gboolean must_reorder;
-};
-
-/* Node */
-
-#ifdef GANV_FDGL
-typedef struct {
- double x;
- double y;
-} Vector;
-#endif
-
-struct _GanvNodePrivate {
- struct _GanvNode* partner;
- GanvText* label;
- double dash_length;
- double dash_offset;
- double border_width;
- guint fill_color;
- guint border_color;
- gboolean can_tail;
- gboolean can_head;
- gboolean is_source;
- gboolean selected;
- gboolean highlighted;
- gboolean draggable;
- gboolean show_label;
- gboolean grabbed;
- gboolean must_resize;
-#ifdef GANV_FDGL
- Vector force;
- Vector vel;
- gboolean connected;
-#endif
-};
-
-/* Widget */
-
-struct _GanvWidgetPrivate {
- GtkWidget* widget; /* The child widget */
-
- double x, y; /* Position at anchor */
- double width, height; /* Dimensions of widget */
- GtkAnchorType anchor; /* Anchor side for widget */
-
- int cx, cy; /* Top-left canvas coordinates for widget */
- int cwidth, cheight; /* Size of widget in pixels */
-
- guint destroy_id; /* Signal connection id for destruction of child widget */
-
- guint size_pixels : 1; /* Is size specified in (unchanging) pixels or units (get scaled)? */
- guint in_destroy : 1; /* Is child widget being destroyed? */
-};
-
-/* Group */
-struct _GanvGroupPrivate {
- GList* item_list;
- GList* item_list_end;
-};
-
-/* Item */
-struct _GanvItemPrivate {
- /* Parent canvas for this item */
- struct _GanvCanvas* canvas;
-
- /* Parent for this item */
- GanvItem* parent;
-
- /* Wrapper object for this item, if any */
- void* wrapper;
-
- /* Layer (z order), higher values are on top */
- guint layer;
-
- /* Position in parent-relative coordinates. */
- double x, y;
-
- /* Bounding box for this item (in world coordinates) */
- double x1, y1, x2, y2;
-
- /* True if parent manages this item (don't call add/remove) */
- gboolean managed;
-};
-
-void
-ganv_node_tick(GanvNode* self, double seconds);
-
-void
-ganv_node_tail_vector(const GanvNode* self,
- const GanvNode* head,
- double* x1,
- double* y1,
- double* x2,
- double* y2);
-
-void
-ganv_node_head_vector(const GanvNode* self,
- const GanvNode* tail,
- double* x1,
- double* y1,
- double* x2,
- double* y2);
-
-/**
- * ganv_node_get_draw_properties:
- *
- * Get the colours that should currently be used for drawing this node. Note
- * these may not be identical to the property values because of highlighting
- * and selection.
- */
-void
-ganv_node_get_draw_properties(const GanvNode* node,
- double* dash_length,
- double* border_color,
- double* fill_color);
-
-/* Port */
-
-typedef struct {
- GanvBox* rect;
- float value;
- float min;
- float max;
- gboolean is_toggle;
- gboolean is_integer;
-} GanvPortControl;
-
-struct _GanvPortPrivate {
- GanvPortControl* control;
- GanvText* value_label;
- gboolean is_input;
- gboolean is_controllable;
-};
-
-/* Text */
-
-typedef struct
-{
- double x;
- double y;
- double width;
- double height;
-} GanvTextCoords;
-
-struct _GanvTextPrivate
-{
- PangoLayout* layout;
- char* text;
- GanvTextCoords coords;
- GanvTextCoords old_coords;
- double font_size;
- guint color;
- gboolean needs_layout;
-};
-
-/* Canvas */
-
-typedef struct {
- GanvPortOrderFunc port_cmp;
- void* data;
-} PortOrderCtx;
-
-void
-ganv_canvas_move_selected_items(GanvCanvas* canvas,
- double dx,
- double dy);
-
-void
-ganv_canvas_selection_move_finished(GanvCanvas* canvas);
-
-void
-ganv_canvas_add_node(GanvCanvas* canvas,
- GanvNode* node);
-
-void
-ganv_canvas_remove_node(GanvCanvas* canvas,
- GanvNode* node);
-
-void
-ganv_canvas_select_node(GanvCanvas* canvas,
- GanvNode* node);
-
-void
-ganv_canvas_unselect_node(GanvCanvas* canvas,
- GanvNode* node);
-
-void
-ganv_canvas_add_edge(GanvCanvas* canvas,
- GanvEdge* edge);
-
-void
-ganv_canvas_select_edge(GanvCanvas* canvas,
- GanvEdge* edge);
-
-void
-ganv_canvas_unselect_edge(GanvCanvas* canvas,
- GanvEdge* edge);
-
-void
-ganv_canvas_disconnect_edge(GanvCanvas* canvas,
- GanvEdge* edge);
-
-gboolean
-ganv_canvas_port_event(GanvCanvas* canvas,
- GanvPort* port,
- GdkEvent* event);
-
-void
-ganv_canvas_contents_changed(GanvCanvas* canvas);
-
-void
-ganv_item_i2w_offset(GanvItem* item, double* px, double* py);
-
-void
-ganv_item_i2w_pair(GanvItem* item, double* x1, double* y1, double* x2, double* y2);
-
-void
-ganv_item_invoke_update(GanvItem* item, int flags);
-
-void
-ganv_item_emit_event(GanvItem* item, GdkEvent* event, gint* finished);
-
-void
-ganv_canvas_request_update(GanvCanvas* canvas);
-
-int
-ganv_canvas_emit_event(GanvCanvas* canvas, GdkEvent* event);
-
-void
-ganv_canvas_set_need_repick(GanvCanvas* canvas);
-
-void
-ganv_canvas_forget_item(GanvCanvas* canvas, GanvItem* item);
-
-void
-ganv_canvas_grab_focus(GanvCanvas* canvas, GanvItem* item);
-
-void
-ganv_canvas_get_zoom_offsets(GanvCanvas* canvas, int* x, int* y);
-
-int
-ganv_canvas_grab_item(GanvItem* item, guint event_mask, GdkCursor* cursor, guint32 etime);
-
-void
-ganv_canvas_ungrab_item(GanvItem* item, guint32 etime);
-
-/* Request a redraw of the specified rectangle in canvas coordinates */
-void
-ganv_canvas_request_redraw_c(GanvCanvas* canvas,
- int x1, int y1, int x2, int y2);
-
-/* Request a redraw of the specified rectangle in world coordinates */
-void
-ganv_canvas_request_redraw_w(GanvCanvas* canvas,
- double x1, double y1, double x2, double y2);
-
-PortOrderCtx
-ganv_canvas_get_port_order(GanvCanvas* canvas);
-
-gboolean
-ganv_canvas_exporting(GanvCanvas* canvas);
-
-/* Edge */
-
-void
-ganv_edge_update_location(GanvEdge* edge);
-
-void
-ganv_edge_get_coords(const GanvEdge* edge, GanvEdgeCoords* coords);
-
-void
-ganv_edge_request_redraw(GanvItem* item,
- const GanvEdgeCoords* coords);
-
-void
-ganv_edge_tick(GanvEdge* edge, double seconds);
-
-/* Box */
-
-void
-ganv_box_path(GanvBox* box,
- cairo_t* cr, double x1, double y1, double x2, double y2,
- double dr);
-
-void
-ganv_box_request_redraw(GanvItem* item,
- const GanvBoxCoords* coords,
- gboolean world);
-
-/* Port */
-
-void
-ganv_port_set_control_value_internal(GanvPort* port,
- float value);
-
-void
-ganv_port_set_direction(GanvPort* port,
- GanvDirection direction);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* GANV_PRIVATE_H */
diff --git a/src/ganv_bench.cpp b/src/ganv_bench.cpp
deleted file mode 100644
index b1bdefb..0000000
--- a/src/ganv_bench.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2013 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glibmm.h>
-#include <gtkmm/main.h>
-#include <gtkmm/scrolledwindow.h>
-#include <gtkmm/window.h>
-
-#include "ganv/ganv.hpp"
-
-using namespace std;
-using namespace Ganv;
-
-static const int MAX_NUM_PORTS = 16;
-
-vector<Node*> ins;
-vector<Node*> outs;
-
-static Module*
-make_module(Canvas* canvas)
-{
- char name[8];
-
- snprintf(name, 8, "mod%d", rand() % 10000);
- Module* m(new Module(*canvas, name,
- rand() % (int)canvas->get_width(),
- rand() % (int)canvas->get_height(),
- true));
-
- int n_ins = rand() % MAX_NUM_PORTS;
- for (int i = 0; i < n_ins; ++i) {
- snprintf(name, 8, "in%d", rand() % 10000);
- Port* p(new Port(*m, name, true,
- ((rand() % 0xFFFFFF) << 8) | 0xFF));
- ins.push_back(p);
- }
-
- int n_outs = rand() % MAX_NUM_PORTS;
- for (int i = 0; i < n_outs; ++i) {
- snprintf(name, 8, "out%d", rand() % 10000);
- Port* p(new Port(*m, name, false,
- ((rand() % 0xFFFFFF) << 8) | 0xFF));
- outs.push_back(p);
- }
-
- m->show();
- return m;
-}
-
-static Circle*
-make_circle(Canvas* canvas)
-{
- char name[8];
-
- snprintf(name, 8, "%d", rand() % 10000);
- Circle* e(new Circle(*canvas, name,
- rand() % (int)canvas->get_width(),
- rand() % (int)canvas->get_height()));
-
- ins.push_back(e);
- outs.push_back(e);
-
- return e;
-}
-
-static bool
-quit()
-{
- Gtk::Main::quit();
- return true;
-}
-
-static int
-print_usage(const char* name)
-{
- fprintf(stderr,
- "USAGE: %s [OPTION]... CANVAS_W CANVAS_H N_MODULES N_CIRCLES N_EDGES\n\n"
- "Options:\n"
- " -o Remain open (do not close immediately)\n"
- " -a Arrange canvas\n"
- " -s Straight edges\n",
- name);
- return 1;
-}
-
-int
-main(int argc, char** argv)
-{
- if (argc < 5) {
- return print_usage(argv[0]);
- }
-
- int arg = 1;
-
- bool remain_open = false;
- bool arrange = false;
- bool straight = false;
- for (; arg < argc && argv[arg][0] == '-'; ++arg) {
- if (argv[arg][1] == 'o') {
- remain_open = true;
- } else if (argv[arg][1] == 'a') {
- arrange = true;
- } else if (argv[arg][1] == 's') {
- straight = true;
- } else {
- return print_usage(argv[0]);
- }
- }
-
- const int canvas_w = atoi(argv[arg++]);
- const int canvas_h = atoi(argv[arg++]);
-
- if (argc - arg < 3) {
- return print_usage(argv[0]);
- }
-
- const int n_modules = atoi(argv[arg++]);
- const int n_circles = atoi(argv[arg++]);
- const int n_edges = atoi(argv[arg++]);
-
- srand(time(NULL));
-
- Gtk::Main kit(argc, argv);
-
- Gtk::Window window;
- Gtk::ScrolledWindow* scroller = Gtk::manage(new Gtk::ScrolledWindow());
-
- Canvas* canvas = new Canvas(canvas_w, canvas_h);
- scroller->add(canvas->widget());
- window.add(*scroller);
-
- window.show_all();
-
- for (int i = 0; i < n_modules; ++i) {
- make_module(canvas);
- }
-
- for (int i = 0; i < n_circles; ++i) {
- make_circle(canvas);
- }
-
- for (int i = 0; i < n_edges; ++i) {
- Node* src = outs[rand() % outs.size()];
- Node* dst = ins[rand() % ins.size()];
- Edge* c = new Edge(*canvas, src, dst, 0x808080FF);
- if (straight) {
- c->set_curved(false);
- }
- }
-
- if (arrange) {
- canvas->arrange();
- }
-
- if (!remain_open) {
- Glib::signal_idle().connect(sigc::ptr_fun(quit));
- }
-
- Gtk::Main::run(window);
-
- return 0;
-}
diff --git a/src/ganv_test.c b/src/ganv_test.c
deleted file mode 100644
index ec1b0a8..0000000
--- a/src/ganv_test.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2013 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <gtk/gtk.h>
-
-#include "ganv/ganv.h"
-
-static void
-on_window_destroy(GtkWidget* widget, void* data)
-{
- gtk_main_quit();
-}
-
-static void
-on_connect(GanvCanvas* canvas, GanvNode* tail, GanvNode* head, void* data)
-{
- ganv_edge_new(canvas, tail, head, "color", 0xFFFFFFFF, NULL);
-}
-
-static void
-on_disconnect(GanvCanvas* canvas, GanvNode* tail, GanvNode* head, void* data)
-{
- ganv_canvas_remove_edge_between(canvas, tail, head);
-}
-
-static void
-on_value_changed(GanvPort* port, double value, void* data)
-{
- fprintf(stderr, "Value changed: port %p = %lf\n", (void*)port, value);
-}
-
-int
-main(int argc, char** argv)
-{
- gtk_init(&argc, &argv);
-
- GtkWindow* win = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
- gtk_window_set_title(win, "Ganv Test");
- g_signal_connect(win, "destroy",
- G_CALLBACK(on_window_destroy), NULL);
-
- GanvCanvas* canvas = ganv_canvas_new(1024, 768);
- gtk_container_add(GTK_CONTAINER(win), GTK_WIDGET(canvas));
-
- GanvCircle* circle = ganv_circle_new(canvas,
- "x", 400.0,
- "y", 400.0,
- "draggable", TRUE,
- "label", "state",
- "radius", 32.0,
- NULL);
- ganv_item_show(GANV_ITEM(circle));
-
- GanvModule* module = ganv_module_new(canvas,
- "x", 10.0,
- "y", 10.0,
- "draggable", TRUE,
- "label", "test",
- NULL);
-
- ganv_port_new(module, FALSE,
- "label", "Signal",
- NULL);
-
- GanvPort* cport = ganv_port_new(module, TRUE,
- "label", "Control",
- NULL);
- ganv_port_show_control(cport);
- g_signal_connect(cport, "value-changed",
- G_CALLBACK(on_value_changed), NULL);
-
- //GtkWidget* entry = gtk_entry_new();
- //ganv_module_embed(module, entry);
-
- GanvPort* tport = ganv_port_new(module, TRUE,
- "label", "Toggle",
- NULL);
- ganv_port_show_control(tport);
- ganv_port_set_control_is_toggle(tport, TRUE);
-
- ganv_item_show(GANV_ITEM(module));
-
- GanvModule* module2 = ganv_module_new(canvas,
- "x", 200.0,
- "y", 10.0,
- "draggable", TRUE,
- "label", "test2",
- NULL);
-
- ganv_port_new(module2, TRUE,
- "label", "Signal",
- NULL);
-
- g_signal_connect(canvas, "connect",
- G_CALLBACK(on_connect), canvas);
-
- g_signal_connect(canvas, "disconnect",
- G_CALLBACK(on_disconnect), canvas);
-
- ganv_item_show(GANV_ITEM(module2));
-
- gtk_widget_show_all(GTK_WIDGET(win));
- gtk_window_present(win);
- gtk_main();
-
- return 0;
-}
diff --git a/src/ganv_test.py b/src/ganv_test.py
deleted file mode 100755
index 1ea53c2..0000000
--- a/src/ganv_test.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env python
-
-from gi.repository import Ganv, Gtk
-
-win = Gtk.Window()
-win.set_title("Ganv Python Test")
-win.connect("destroy", lambda obj: Gtk.main_quit())
-
-canvas = Ganv.Canvas.new(1024, 768)
-module = Ganv.Module(canvas=canvas,
- label="Test")
-# iport = Ganv.Port(module=module,
-# is_input=True,
-# label="In")
-# oport = Ganv.Port(module=module,
-# is_input=False,
-# label="In")
-
-win.add(canvas)
-win.show_all()
-win.present()
-Gtk.main()
diff --git a/src/gettext.h b/src/gettext.h
deleted file mode 100644
index d32bb70..0000000
--- a/src/gettext.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2013 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GANV_GETTEXT_H
-#define GANV_GETTEXT_H
-
-#ifdef ENABLE_NLS
-# include <libintl.h>
-# define _(str) dgettext("ganv", str)
-#else
-# define _(str) str
-#endif
-
-#endif /* GANV_GETTEXT_H */
diff --git a/src/group.c b/src/group.c
deleted file mode 100644
index 503e57b..0000000
--- a/src/group.c
+++ /dev/null
@@ -1,446 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2015 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Based on GnomeCanvasGroup, by Federico Mena <federico@nuclecu.unam.mx>
- * and Raph Levien <raph@gimp.org>
- * Copyright 1997-2000 Free Software Foundation
- */
-
-#include <math.h>
-
-#include "ganv/canvas.h"
-#include "ganv/group.h"
-
-#include "./gettext.h"
-#include "./ganv-private.h"
-
-enum {
- GROUP_PROP_0
-};
-
-G_DEFINE_TYPE_WITH_CODE(GanvGroup, ganv_group, GANV_TYPE_ITEM,
- G_ADD_PRIVATE(GanvGroup))
-
-static GanvItemClass* group_parent_class;
-
-static void
-ganv_group_init(GanvGroup* group)
-{
- GanvGroupPrivate* impl = ganv_group_get_instance_private(group);
-
- group->impl = impl;
- group->impl->item_list = NULL;
- group->impl->item_list_end = NULL;
-}
-
-static void
-ganv_group_set_property(GObject* gobject, guint param_id,
- const GValue* value, GParamSpec* pspec)
-{
- g_return_if_fail(GANV_IS_GROUP(gobject));
-
- switch (param_id) {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, param_id, pspec);
- break;
- }
-}
-
-static void
-ganv_group_get_property(GObject* gobject, guint param_id,
- GValue* value, GParamSpec* pspec)
-{
- g_return_if_fail(GANV_IS_GROUP(gobject));
-
- switch (param_id) {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, param_id, pspec);
- break;
- }
-}
-
-static void
-ganv_group_destroy(GtkObject* object)
-{
- GanvGroup* group;
-
- g_return_if_fail(GANV_IS_GROUP(object));
-
- group = GANV_GROUP(object);
-
- while (group->impl->item_list) {
- // child is unref'ed by the child's group_remove().
- gtk_object_destroy(GTK_OBJECT(group->impl->item_list->data));
- }
- if (GTK_OBJECT_CLASS(group_parent_class)->destroy) {
- (*GTK_OBJECT_CLASS(group_parent_class)->destroy)(object);
- }
-}
-
-static void
-ganv_group_update(GanvItem* item, int flags)
-{
- GanvGroup* group = GANV_GROUP(item);
-
- double min_x = 0.0;
- double min_y = 0.0;
- double max_x = 0.0;
- double max_y = 0.0;
-
- for (GList* list = group->impl->item_list; list; list = list->next) {
- GanvItem* i = (GanvItem*)list->data;
-
- ganv_item_invoke_update(i, flags);
-
- min_x = fmin(min_x, fmin(i->impl->x1, i->impl->x2));
- min_y = fmin(min_y, fmin(i->impl->y1, i->impl->y2));
- max_x = fmax(max_x, fmax(i->impl->x1, i->impl->x2));
- max_y = fmax(max_y, fmax(i->impl->y2, i->impl->y2));
- }
- item->impl->x1 = min_x;
- item->impl->y1 = min_y;
- item->impl->x2 = max_x;
- item->impl->y2 = max_y;
-
- (*group_parent_class->update)(item, flags);
-}
-
-static void
-ganv_group_realize(GanvItem* item)
-{
- GanvGroup* group;
- GList* list;
- GanvItem* i;
-
- group = GANV_GROUP(item);
-
- for (list = group->impl->item_list; list; list = list->next) {
- i = (GanvItem*)list->data;
-
- if (!(i->object.flags & GANV_ITEM_REALIZED)) {
- (*GANV_ITEM_GET_CLASS(i)->realize)(i);
- }
- }
-
- (*group_parent_class->realize)(item);
-}
-
-static void
-ganv_group_unrealize(GanvItem* item)
-{
- GanvGroup* group;
- GList* list;
- GanvItem* i;
-
- group = GANV_GROUP(item);
-
- for (list = group->impl->item_list; list; list = list->next) {
- i = (GanvItem*)list->data;
-
- if (i->object.flags & GANV_ITEM_REALIZED) {
- (*GANV_ITEM_GET_CLASS(i)->unrealize)(i);
- }
- }
-
- (*group_parent_class->unrealize)(item);
-}
-
-static void
-ganv_group_map(GanvItem* item)
-{
- GanvGroup* group;
- GList* list;
- GanvItem* i;
-
- group = GANV_GROUP(item);
-
- for (list = group->impl->item_list; list; list = list->next) {
- i = (GanvItem*)list->data;
-
- if (!(i->object.flags & GANV_ITEM_MAPPED)) {
- (*GANV_ITEM_GET_CLASS(i)->map)(i);
- }
- }
-
- (*group_parent_class->map)(item);
-}
-
-static void
-ganv_group_unmap(GanvItem* item)
-{
- GanvGroup* group;
- GList* list;
- GanvItem* i;
-
- group = GANV_GROUP(item);
-
- for (list = group->impl->item_list; list; list = list->next) {
- i = (GanvItem*)list->data;
-
- if (i->object.flags & GANV_ITEM_MAPPED) {
- (*GANV_ITEM_GET_CLASS(i)->unmap)(i);
- }
- }
-
- (*group_parent_class->unmap)(item);
-}
-
-static void
-ganv_group_draw(GanvItem* item,
- cairo_t* cr, double cx, double cy, double cw, double ch)
-{
- GanvGroup* group = GANV_GROUP(item);
-
- // TODO: Layered drawing
-
- for (GList* list = group->impl->item_list; list; list = list->next) {
- GanvItem* child = (GanvItem*)list->data;
-
- if (((child->object.flags & GANV_ITEM_VISIBLE)
- && ((child->impl->x1 < (cx + cw))
- && (child->impl->y1 < (cy + ch))
- && (child->impl->x2 > cx)
- && (child->impl->y2 > cy)))) {
- if (GANV_ITEM_GET_CLASS(child)->draw) {
- (*GANV_ITEM_GET_CLASS(child)->draw)(
- child, cr, cx, cy, cw, ch);
- }
- }
- }
-}
-
-static double
-ganv_group_point(GanvItem* item, double x, double y, GanvItem** actual_item)
-{
- GanvGroup* group = GANV_GROUP(item);
-
- const double x1 = x - GANV_CLOSE_ENOUGH;
- const double y1 = y - GANV_CLOSE_ENOUGH;
- const double x2 = x + GANV_CLOSE_ENOUGH;
- const double y2 = y + GANV_CLOSE_ENOUGH;
-
- double dist = 0.0;
- double best = 0.0;
-
- *actual_item = NULL;
-
- for (GList* list = group->impl->item_list; list; list = list->next) {
- GanvItem* child = (GanvItem*)list->data;
- if ((child->impl->x1 > x2) || (child->impl->y1 > y2) || (child->impl->x2 < x1) || (child->impl->y2 < y1)) {
- continue;
- }
-
- GanvItem* point_item = NULL;
-
- int has_point = FALSE;
- if ((child->object.flags & GANV_ITEM_VISIBLE)
- && GANV_ITEM_GET_CLASS(child)->point) {
- dist = GANV_ITEM_GET_CLASS(child)->point(
- child,
- x - child->impl->x, y - child->impl->y,
- &point_item);
- has_point = TRUE;
- }
-
- if (has_point
- && point_item
- && ((int)(dist + 0.5) <= GANV_CLOSE_ENOUGH)) {
- best = dist;
- *actual_item = point_item;
- }
- }
-
- if (*actual_item) {
- return best;
- } else {
- *actual_item = item;
- return 0.0;
- }
-}
-
-/* Get bounds of child item in group-relative coordinates. */
-static void
-get_child_bounds(GanvItem* child, double* x1, double* y1, double* x2, double* y2)
-{
- ganv_item_get_bounds(child, x1, y1, x2, y2);
-
- // Make bounds relative to the item's parent coordinate system
- *x1 -= child->impl->x;
- *y1 -= child->impl->y;
- *x2 -= child->impl->x;
- *y2 -= child->impl->y;
-}
-
-static void
-ganv_group_bounds(GanvItem* item, double* x1, double* y1, double* x2, double* y2)
-{
- GanvGroup* group;
- GanvItem* child;
- GList* list;
- double tx1, ty1, tx2, ty2;
- double minx, miny, maxx, maxy;
- int set;
-
- group = GANV_GROUP(item);
-
- /* Get the bounds of the first visible item */
-
- child = NULL; /* Unnecessary but eliminates a warning. */
-
- set = FALSE;
-
- for (list = group->impl->item_list; list; list = list->next) {
- child = (GanvItem*)list->data;
-
- if (child->object.flags & GANV_ITEM_VISIBLE) {
- set = TRUE;
- get_child_bounds(child, &minx, &miny, &maxx, &maxy);
- break;
- }
- }
-
- /* If there were no visible items, return an empty bounding box */
-
- if (!set) {
- *x1 = *y1 = *x2 = *y2 = 0.0;
- return;
- }
-
- /* Now we can grow the bounds using the rest of the items */
-
- list = list->next;
-
- for (; list; list = list->next) {
- child = (GanvItem*)list->data;
-
- if (!(child->object.flags & GANV_ITEM_VISIBLE)) {
- continue;
- }
-
- get_child_bounds(child, &tx1, &ty1, &tx2, &ty2);
-
- if (tx1 < minx) {
- minx = tx1;
- }
-
- if (ty1 < miny) {
- miny = ty1;
- }
-
- if (tx2 > maxx) {
- maxx = tx2;
- }
-
- if (ty2 > maxy) {
- maxy = ty2;
- }
- }
-
- *x1 = minx;
- *y1 = miny;
- *x2 = maxx;
- *y2 = maxy;
-}
-
-static void
-ganv_group_add(GanvItem* parent, GanvItem* item)
-{
- GanvGroup* group = GANV_GROUP(parent);
- g_object_ref_sink(G_OBJECT(item));
-
- if (!group->impl->item_list) {
- group->impl->item_list = g_list_append(group->impl->item_list, item);
- group->impl->item_list_end = group->impl->item_list;
- } else {
- group->impl->item_list_end = g_list_append(group->impl->item_list_end, item)->next;
- }
-
- if (group->item.object.flags & GANV_ITEM_REALIZED) {
- (*GANV_ITEM_GET_CLASS(item)->realize)(item);
- }
-
- if (group->item.object.flags & GANV_ITEM_MAPPED) {
- (*GANV_ITEM_GET_CLASS(item)->map)(item);
- }
-
- g_object_notify(G_OBJECT(item), "parent");
-}
-
-static void
-ganv_group_remove(GanvItem* parent, GanvItem* item)
-{
- GanvGroup* group = GANV_GROUP(parent);
- GList* children;
-
- g_return_if_fail(GANV_IS_GROUP(group));
- g_return_if_fail(GANV_IS_ITEM(item));
-
- for (children = group->impl->item_list; children; children = children->next) {
- if (children->data == item) {
- if (item->object.flags & GANV_ITEM_MAPPED) {
- (*GANV_ITEM_GET_CLASS(item)->unmap)(item);
- }
-
- if (item->object.flags & GANV_ITEM_REALIZED) {
- (*GANV_ITEM_GET_CLASS(item)->unrealize)(item);
- }
-
- /* Unparent the child */
-
- item->impl->parent = NULL;
- g_object_unref(G_OBJECT(item));
-
- /* Remove it from the list */
-
- if (children == group->impl->item_list_end) {
- group->impl->item_list_end = children->prev;
- }
-
- group->impl->item_list = g_list_remove_link(group->impl->item_list, children);
- g_list_free(children);
- break;
- }
- }
-}
-
-static void
-ganv_group_class_init(GanvGroupClass* klass)
-{
- GObjectClass* gobject_class;
- GtkObjectClass* object_class;
- GanvItemClass* item_class;
-
- gobject_class = (GObjectClass*)klass;
- object_class = (GtkObjectClass*)klass;
- item_class = (GanvItemClass*)klass;
-
- group_parent_class = (GanvItemClass*)g_type_class_peek_parent(klass);
-
- gobject_class->set_property = ganv_group_set_property;
- gobject_class->get_property = ganv_group_get_property;
-
- object_class->destroy = ganv_group_destroy;
-
- item_class->add = ganv_group_add;
- item_class->remove = ganv_group_remove;
- item_class->update = ganv_group_update;
- item_class->realize = ganv_group_realize;
- item_class->unrealize = ganv_group_unrealize;
- item_class->map = ganv_group_map;
- item_class->unmap = ganv_group_unmap;
- item_class->draw = ganv_group_draw;
- item_class->point = ganv_group_point;
- item_class->bounds = ganv_group_bounds;
-}
diff --git a/src/item.c b/src/item.c
deleted file mode 100644
index a458acd..0000000
--- a/src/item.c
+++ /dev/null
@@ -1,707 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2016 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Based on GnomeCanvas, by Federico Mena <federico@nuclecu.unam.mx>
- * and Raph Levien <raph@gimp.org>
- * Copyright 1997-2000 Free Software Foundation
- */
-
-#include "ganv/canvas.h"
-#include "ganv/node.h"
-
-#include "./boilerplate.h"
-#include "./ganv-marshal.h"
-#include "./ganv-private.h"
-#include "./gettext.h"
-
-/* All canvas items are derived from GanvItem. The only information a GanvItem
- * contains is its parent canvas, its parent canvas item, its bounding box in
- * world coordinates, and its current affine transformation.
- *
- * Items inside a canvas are organized in a tree, where leaves are items
- * without any children. Each canvas has a single root item, which can be
- * obtained with the ganv_canvas_base_get_root() function.
- *
- * The abstract GanvItem class does not have any configurable or queryable
- * attributes.
- */
-
-/* Update flags for items */
-enum {
- GANV_CANVAS_UPDATE_REQUESTED = 1 << 0,
- GANV_CANVAS_UPDATE_AFFINE = 1 << 1,
- GANV_CANVAS_UPDATE_VISIBILITY = 1 << 2
-};
-
-#define GCI_UPDATE_MASK (GANV_CANVAS_UPDATE_REQUESTED \
- | GANV_CANVAS_UPDATE_AFFINE \
- | GANV_CANVAS_UPDATE_VISIBILITY)
-
-enum {
- ITEM_PROP_0,
- ITEM_PROP_PARENT,
- ITEM_PROP_X,
- ITEM_PROP_Y,
- ITEM_PROP_MANAGED
-};
-
-enum {
- ITEM_EVENT,
- ITEM_LAST_SIGNAL
-};
-
-static guint item_signals[ITEM_LAST_SIGNAL];
-
-G_DEFINE_TYPE_WITH_CODE(GanvItem, ganv_item, GTK_TYPE_OBJECT,
- G_ADD_PRIVATE(GanvItem))
-
-static GtkObjectClass* item_parent_class;
-
-/* Object initialization function for GanvItem */
-static void
-ganv_item_init(GanvItem* item)
-{
- GanvItemPrivate* impl = ganv_item_get_instance_private(item);
-
- item->object.flags |= GANV_ITEM_VISIBLE;
- item->impl = impl;
- item->impl->managed = FALSE;
- item->impl->wrapper = NULL;
-}
-
-/**
- * ganv_item_new:
- * @parent: The parent group for the new item.
- * @type: The object type of the item.
- * @first_arg_name: A list of object argument name/value pairs, NULL-terminated,
- * used to configure the item. For example, "fill_color", "black",
- * "width_units", 5.0, NULL.
- * @...: first argument value, second argument name, second argument value, ...
- *
- * Creates a new canvas item with @parent as its parent group. The item is
- * created at the top of its parent's stack, and starts up as visible. The item
- * is of the specified @type, for example, it can be
- * ganv_canvas_rect_get_type(). The list of object arguments/value pairs is
- * used to configure the item. If you need to pass construct time parameters, you
- * should use g_object_new() to pass the parameters and
- * ganv_item_construct() to set up the canvas item.
- *
- * Return value: (transfer full): The newly-created item.
- **/
-GanvItem*
-ganv_item_new(GanvItem* parent, GType type, const gchar* first_arg_name, ...)
-{
- g_return_val_if_fail(g_type_is_a(type, ganv_item_get_type()), NULL);
-
- GanvItem* item = GANV_ITEM(g_object_new(type, NULL));
-
- va_list args;
- va_start(args, first_arg_name);
- ganv_item_construct(item, parent, first_arg_name, args);
- va_end(args);
-
- return item;
-}
-
-/* Performs post-creation operations on a canvas item (adding it to its parent
- * group, etc.)
- */
-static void
-item_post_create_setup(GanvItem* item)
-{
- GanvItemClass* parent_class = GANV_ITEM_GET_CLASS(item->impl->parent);
- if (!item->impl->managed) {
- if (parent_class->add) {
- parent_class->add(item->impl->parent, item);
- } else {
- g_warning("item added to non-parent item\n");
- }
- }
- ganv_canvas_request_redraw_w(item->impl->canvas,
- item->impl->x1, item->impl->y1,
- item->impl->x2 + 1, item->impl->y2 + 1);
- ganv_canvas_set_need_repick(item->impl->canvas);
-}
-
-static void
-ganv_item_set_property(GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_ITEM(object));
-
- GanvItem* item = GANV_ITEM(object);
-
- switch (prop_id) {
- case ITEM_PROP_PARENT:
- if (item->impl->parent != NULL) {
- g_warning("Cannot set `parent' argument after item has "
- "already been constructed.");
- } else if (g_value_get_object(value)) {
- item->impl->parent = GANV_ITEM(g_value_get_object(value));
- item->impl->canvas = item->impl->parent->impl->canvas;
- item_post_create_setup(item);
- }
- break;
- case ITEM_PROP_X:
- item->impl->x = g_value_get_double(value);
- ganv_item_request_update(item);
- break;
- case ITEM_PROP_Y:
- item->impl->y = g_value_get_double(value);
- ganv_item_request_update(item);
- break;
- case ITEM_PROP_MANAGED:
- item->impl->managed = g_value_get_boolean(value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-ganv_item_get_property(GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_ITEM(object));
-
- GanvItem* item = GANV_ITEM(object);
-
- switch (prop_id) {
- case ITEM_PROP_PARENT:
- g_value_set_object(value, item->impl->parent);
- break;
- case ITEM_PROP_X:
- g_value_set_double(value, item->impl->x);
- break;
- case ITEM_PROP_Y:
- g_value_set_double(value, item->impl->y);
- break;
- case ITEM_PROP_MANAGED:
- g_value_set_boolean(value, item->impl->managed);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-/**
- * ganv_item_construct:
- * @item: An unconstructed canvas item.
- * @parent: The parent group for the item.
- * @first_arg_name: The name of the first argument for configuring the item.
- * @args: The list of arguments used to configure the item.
- *
- * Constructs a canvas item; meant for use only by item implementations.
- **/
-void
-ganv_item_construct(GanvItem* item, GanvItem* parent,
- const gchar* first_arg_name, va_list args)
-{
- g_return_if_fail(GANV_IS_ITEM(item));
-
- item->impl->parent = parent;
- item->impl->wrapper = NULL;
- item->impl->canvas = item->impl->parent->impl->canvas;
- item->impl->layer = 0;
-
- g_object_set_valist(G_OBJECT(item), first_arg_name, args);
-
- item_post_create_setup(item);
-}
-
-/* If the item is visible, requests a redraw of it. */
-static void
-redraw_if_visible(GanvItem* item)
-{
- if (item->object.flags & GANV_ITEM_VISIBLE) {
- ganv_canvas_request_redraw_w(item->impl->canvas,
- item->impl->x1, item->impl->y1,
- item->impl->x2 + 1, item->impl->y2 + 1);
- }
-}
-
-/* Standard object dispose function for canvas items */
-static void
-ganv_item_dispose(GObject* object)
-{
- GanvItem* item;
-
- g_return_if_fail(GANV_IS_ITEM(object));
-
- item = GANV_ITEM(object);
-
- if (item->impl->canvas) {
- redraw_if_visible(item);
- ganv_canvas_forget_item(item->impl->canvas, item);
- }
-
- /* Normal destroy stuff */
-
- if (item->object.flags & GANV_ITEM_MAPPED) {
- (*GANV_ITEM_GET_CLASS(item)->unmap)(item);
- }
-
- if (item->object.flags & GANV_ITEM_REALIZED) {
- (*GANV_ITEM_GET_CLASS(item)->unrealize)(item);
- }
-
- if (!item->impl->managed && item->impl->parent) {
- if (GANV_ITEM_GET_CLASS(item->impl->parent)->remove) {
- GANV_ITEM_GET_CLASS(item->impl->parent)->remove(item->impl->parent, item);
- } else {
- fprintf(stderr, "warning: Item parent has no remove method\n");
- }
- }
-
- G_OBJECT_CLASS(item_parent_class)->dispose(object);
- /* items should remove any reference to item->impl->canvas after the
- first ::destroy */
- item->impl->canvas = NULL;
-}
-
-/* Realize handler for canvas items */
-static void
-ganv_item_realize(GanvItem* item)
-{
- GTK_OBJECT_SET_FLAGS(item, GANV_ITEM_REALIZED);
-
- ganv_item_request_update(item);
-}
-
-/* Unrealize handler for canvas items */
-static void
-ganv_item_unrealize(GanvItem* item)
-{
- GTK_OBJECT_UNSET_FLAGS(item, GANV_ITEM_REALIZED);
-}
-
-/* Map handler for canvas items */
-static void
-ganv_item_map(GanvItem* item)
-{
- GTK_OBJECT_SET_FLAGS(item, GANV_ITEM_MAPPED);
-}
-
-/* Unmap handler for canvas items */
-static void
-ganv_item_unmap(GanvItem* item)
-{
- GTK_OBJECT_UNSET_FLAGS(item, GANV_ITEM_MAPPED);
-}
-
-/* Update handler for canvas items */
-static void
-ganv_item_update(GanvItem* item, int flags)
-{
- GTK_OBJECT_UNSET_FLAGS(item, GANV_ITEM_NEED_UPDATE);
- GTK_OBJECT_UNSET_FLAGS(item, GANV_ITEM_NEED_VIS);
-}
-
-/* Point handler for canvas items */
-static double
-ganv_item_point(GanvItem* item, double x, double y, GanvItem** actual_item)
-{
- *actual_item = NULL;
- return G_MAXDOUBLE;
-}
-
-void
-ganv_item_invoke_update(GanvItem* item, int flags)
-{
- int child_flags = flags;
-
- /* apply object flags to child flags */
-
- child_flags &= ~GANV_CANVAS_UPDATE_REQUESTED;
-
- if (item->object.flags & GANV_ITEM_NEED_UPDATE) {
- child_flags |= GANV_CANVAS_UPDATE_REQUESTED;
- }
-
- if (item->object.flags & GANV_ITEM_NEED_VIS) {
- child_flags |= GANV_CANVAS_UPDATE_VISIBILITY;
- }
-
- if (child_flags & GCI_UPDATE_MASK) {
- if (GANV_ITEM_GET_CLASS(item)->update) {
- GANV_ITEM_GET_CLASS(item)->update(item, child_flags);
- g_assert(!(GTK_OBJECT_FLAGS(item) & GANV_ITEM_NEED_UPDATE));
- }
- }
-}
-
-/**
- * ganv_item_set:
- * @item: A canvas item.
- * @first_arg_name: The list of object argument name/value pairs used to configure the item.
- * @...: first argument value, second argument name, second argument value, ...
- *
- * Configures a canvas item. The arguments in the item are set to the specified
- * values, and the item is repainted as appropriate.
- **/
-void
-ganv_item_set(GanvItem* item, const gchar* first_arg_name, ...)
-{
- va_list args;
-
- va_start(args, first_arg_name);
- ganv_item_set_valist(item, first_arg_name, args);
- va_end(args);
-}
-
-/**
- * ganv_item_set_valist:
- * @item: A canvas item.
- * @first_arg_name: The name of the first argument used to configure the item.
- * @args: The list of object argument name/value pairs used to configure the item.
- *
- * Configures a canvas item. The arguments in the item are set to the specified
- * values, and the item is repainted as appropriate.
- **/
-void
-ganv_item_set_valist(GanvItem* item, const gchar* first_arg_name, va_list args)
-{
- g_return_if_fail(GANV_IS_ITEM(item));
-
- g_object_set_valist(G_OBJECT(item), first_arg_name, args);
-
- ganv_canvas_set_need_repick(item->impl->canvas);
-}
-
-GanvCanvas*
-ganv_item_get_canvas(GanvItem* item)
-{
- return item->impl->canvas;
-}
-
-GanvItem*
-ganv_item_get_parent(GanvItem* item)
-{
- return item->impl->parent;
-}
-
-void
-ganv_item_raise(GanvItem* item)
-{
- ++item->impl->layer;
-}
-
-void
-ganv_item_lower(GanvItem* item)
-{
- --item->impl->layer;
-}
-
-/**
- * ganv_item_move:
- * @item: A canvas item.
- * @dx: Horizontal offset.
- * @dy: Vertical offset.
- **/
-void
-ganv_item_move(GanvItem* item, double dx, double dy)
-{
- if (!item || !GANV_IS_ITEM(item)) {
- return;
- }
-
- item->impl->x += dx;
- item->impl->y += dy;
-
- ganv_item_request_update(item);
- ganv_canvas_set_need_repick(item->impl->canvas);
-}
-
-/**
- * ganv_item_show:
- * @item: A canvas item.
- *
- * Shows a canvas item. If the item was already shown, then no action is taken.
- **/
-void
-ganv_item_show(GanvItem* item)
-{
- g_return_if_fail(GANV_IS_ITEM(item));
-
- if (!(item->object.flags & GANV_ITEM_VISIBLE)) {
- item->object.flags |= GANV_ITEM_VISIBLE;
- ganv_canvas_request_redraw_w(item->impl->canvas,
- item->impl->x1, item->impl->y1,
- item->impl->x2 + 1, item->impl->y2 + 1);
- ganv_canvas_set_need_repick(item->impl->canvas);
- }
-}
-
-/**
- * ganv_item_hide:
- * @item: A canvas item.
- *
- * Hides a canvas item. If the item was already hidden, then no action is
- * taken.
- **/
-void
-ganv_item_hide(GanvItem* item)
-{
- g_return_if_fail(GANV_IS_ITEM(item));
-
- if (item->object.flags & GANV_ITEM_VISIBLE) {
- item->object.flags &= ~GANV_ITEM_VISIBLE;
- ganv_canvas_request_redraw_w(item->impl->canvas,
- item->impl->x1, item->impl->y1,
- item->impl->x2 + 1, item->impl->y2 + 1);
- ganv_canvas_set_need_repick(item->impl->canvas);
- }
-}
-
-void
-ganv_item_i2w_offset(GanvItem* item, double* px, double* py)
-{
- double x = 0.0;
- double y = 0.0;
- while (item) {
- x += item->impl->x;
- y += item->impl->y;
- item = item->impl->parent;
- }
- *px = x;
- *py = y;
-}
-
-/**
- * ganv_item_i2w:
- * @item: A canvas item.
- * @x: X coordinate to convert (input/output value).
- * @y: Y coordinate to convert (input/output value).
- *
- * Converts a coordinate pair from item-relative coordinates to world
- * coordinates.
- **/
-void
-ganv_item_i2w(GanvItem* item, double* x, double* y)
-{
- /*g_return_if_fail(GANV_IS_ITEM(item));
- g_return_if_fail(x != NULL);
- g_return_if_fail(y != NULL);*/
-
- double off_x;
- double off_y;
- ganv_item_i2w_offset(item, &off_x, &off_y);
-
- *x += off_x;
- *y += off_y;
-}
-
-void
-ganv_item_i2w_pair(GanvItem* item, double* x1, double* y1, double* x2, double* y2)
-{
- double off_x;
- double off_y;
- ganv_item_i2w_offset(item, &off_x, &off_y);
-
- *x1 += off_x;
- *y1 += off_y;
- *x2 += off_x;
- *y2 += off_y;
-}
-
-/**
- * ganv_item_w2i:
- * @item: A canvas item.
- * @x: X coordinate to convert (input/output value).
- * @y: Y coordinate to convert (input/output value).
- *
- * Converts a coordinate pair from world coordinates to item-relative
- * coordinates.
- **/
-void
-ganv_item_w2i(GanvItem* item, double* x, double* y)
-{
- double off_x;
- double off_y;
- ganv_item_i2w_offset(item, &off_x, &off_y);
-
- *x -= off_x;
- *y -= off_y;
-}
-
-/**
- * ganv_item_grab_focus:
- * @item: A canvas item.
- *
- * Makes the specified item take the keyboard focus, so all keyboard events will
- * be sent to it. If the canvas widget itself did not have the focus, it grabs
- * it as well.
- **/
-void
-ganv_item_grab_focus(GanvItem* item)
-{
- ganv_canvas_grab_focus(item->impl->canvas, item);
-}
-
-void
-ganv_item_emit_event(GanvItem* item, GdkEvent* event, gint* finished)
-{
- g_signal_emit(item, item_signals[ITEM_EVENT], 0, event, finished);
-}
-
-static void
-ganv_item_default_bounds(GanvItem* item, double* x1, double* y1, double* x2, double* y2)
-{
- *x1 = *y1 = *x2 = *y2 = 0.0;
-}
-
-/**
- * ganv_item_get_bounds:
- * @item: A canvas item.
- * @x1: Leftmost edge of the bounding box (return value).
- * @y1: Upper edge of the bounding box (return value).
- * @x2: Rightmost edge of the bounding box (return value).
- * @y2: Lower edge of the bounding box (return value).
- *
- * Queries the bounding box of a canvas item. The bounding box may not be
- * exactly tight, but the canvas items will do the best they can. The bounds
- * are returned in the coordinate system of the item's parent.
- **/
-void
-ganv_item_get_bounds(GanvItem* item, double* x1, double* y1, double* x2, double* y2)
-{
- GANV_ITEM_GET_CLASS(item)->bounds(item, x1, y1, x2, y2);
-}
-
-/**
- * ganv_item_request_update:
- * @item: A canvas item.
- *
- * To be used only by item implementations. Requests that the canvas queue an
- * update for the specified item.
- **/
-void
-ganv_item_request_update(GanvItem* item)
-{
- if (!item->impl->canvas) {
- /* Item is being / has been destroyed, ignore */
- return;
- }
-
- item->object.flags |= GANV_ITEM_NEED_UPDATE;
-
- if (item->impl->parent != NULL &&
- !(item->impl->parent->object.flags & GANV_ITEM_NEED_UPDATE)) {
- /* Recurse up the tree */
- ganv_item_request_update(item->impl->parent);
- } else {
- /* Have reached the top of the tree, make sure the update call gets scheduled. */
- ganv_canvas_request_update(item->impl->canvas);
- }
-}
-
-void
-ganv_item_set_wrapper(GanvItem* item, void* wrapper)
-{
- item->impl->wrapper = wrapper;
-}
-
-void*
-ganv_item_get_wrapper(GanvItem* item)
-{
- return item->impl->wrapper;
-}
-
-static gboolean
-boolean_handled_accumulator(GSignalInvocationHint* ihint,
- GValue* return_accu,
- const GValue* handler_return,
- gpointer dummy)
-{
- gboolean continue_emission;
- gboolean signal_handled;
-
- signal_handled = g_value_get_boolean(handler_return);
- g_value_set_boolean(return_accu, signal_handled);
- continue_emission = !signal_handled;
-
- return continue_emission;
-}
-
-/* Class initialization function for GanvItemClass */
-static void
-ganv_item_class_init(GanvItemClass* klass)
-{
- GObjectClass* gobject_class;
-
- gobject_class = (GObjectClass*)klass;
-
- item_parent_class = (GtkObjectClass*)g_type_class_peek_parent(klass);
-
- gobject_class->set_property = ganv_item_set_property;
- gobject_class->get_property = ganv_item_get_property;
-
- g_object_class_install_property
- (gobject_class, ITEM_PROP_PARENT,
- g_param_spec_object("parent", NULL, NULL,
- GANV_TYPE_ITEM,
- (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE)));
-
- g_object_class_install_property
- (gobject_class, ITEM_PROP_X,
- g_param_spec_double("x",
- _("X"),
- _("X"),
- -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
- (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE)));
- g_object_class_install_property
- (gobject_class, ITEM_PROP_Y,
- g_param_spec_double("y",
- _("Y"),
- _("Y"),
- -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
- (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE)));
-
- g_object_class_install_property
- (gobject_class, ITEM_PROP_MANAGED,
- g_param_spec_boolean("managed",
- _("Managed"),
- _("Whether the item is managed by its parent"),
- 0,
- (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE)));
-
- item_signals[ITEM_EVENT]
- = g_signal_new("event",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(GanvItemClass, event),
- boolean_handled_accumulator, NULL,
- ganv_marshal_BOOLEAN__BOXED,
- G_TYPE_BOOLEAN, 1,
- GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
-
- gobject_class->dispose = ganv_item_dispose;
-
- klass->realize = ganv_item_realize;
- klass->unrealize = ganv_item_unrealize;
- klass->map = ganv_item_map;
- klass->unmap = ganv_item_unmap;
- klass->update = ganv_item_update;
- klass->point = ganv_item_point;
- klass->bounds = ganv_item_default_bounds;
-}
diff --git a/src/module.c b/src/module.c
deleted file mode 100644
index bad930b..0000000
--- a/src/module.c
+++ /dev/null
@@ -1,859 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2016 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "ganv/canvas.h"
-#include "ganv/module.h"
-#include "ganv/port.h"
-#include "ganv/widget.h"
-
-#include "./color.h"
-#include "./boilerplate.h"
-#include "./gettext.h"
-#include "./ganv-private.h"
-
-#define FOREACH_PORT(ports, i) \
- for (GanvPort** i = (GanvPort**)ports->pdata; \
- i != (GanvPort**)ports->pdata + ports->len; ++i)
-
-#define FOREACH_PORT_CONST(ports, i) \
- for (const GanvPort** i = (const GanvPort**)ports->pdata; \
- i != (const GanvPort**)ports->pdata + ports->len; ++i)
-
-static const double PAD = 2.0;
-static const double EDGE_PAD = 5.0;
-static const double MODULE_LABEL_PAD = 2.0;
-
-G_DEFINE_TYPE_WITH_CODE(GanvModule, ganv_module, GANV_TYPE_BOX,
- G_ADD_PRIVATE(GanvModule))
-
-static GanvBoxClass* parent_class;
-
-enum {
- PROP_0
-};
-
-static void
-ganv_module_init(GanvModule* module)
-{
- GanvModulePrivate* impl = ganv_module_get_instance_private(module);
-
- module->impl = impl;
-
- GANV_NODE(module)->impl->can_head = FALSE;
- GANV_NODE(module)->impl->can_tail = FALSE;
-
- impl->ports = g_ptr_array_new();
- impl->embed_item = NULL;
- impl->embed_width = 0;
- impl->embed_height = 0;
- impl->widest_input = 0.0;
- impl->widest_output = 0.0;
- impl->must_reorder = FALSE;
-}
-
-static void
-ganv_module_destroy(GtkObject* object)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_MODULE(object));
-
- GanvModule* module = GANV_MODULE(object);
- GanvModulePrivate* impl = module->impl;
-
- if (impl->ports) {
- FOREACH_PORT(impl->ports, p) {
- g_object_unref(GTK_OBJECT(*p));
- }
- g_ptr_array_free(impl->ports, TRUE);
- impl->ports = NULL;
- }
-
- if (impl->embed_item) {
- g_object_unref(GTK_OBJECT(impl->embed_item));
- impl->embed_item = NULL;
- }
-
- if (GTK_OBJECT_CLASS(parent_class)->destroy) {
- (*GTK_OBJECT_CLASS(parent_class)->destroy)(object);
- }
-}
-
-static void
-ganv_module_set_property(GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_MODULE(object));
-
- switch (prop_id) {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-ganv_module_get_property(GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_MODULE(object));
-
- switch (prop_id) {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-typedef struct {
- double embed_x;
- double width;
- double input_width;
- double output_width;
- gboolean horiz;
- gboolean embed_between;
-} Metrics;
-
-static void
-title_size(GanvModule* module, double* w, double* h)
-{
- if (module->box.node.impl->label) {
- g_object_get(G_OBJECT(module->box.node.impl->label),
- "width", w,
- "height", h,
- NULL);
- } else {
- *w = *h = 0.0;
- }
-}
-
-static void
-measure(GanvModule* module, Metrics* m)
-{
- memset(m, '\0', sizeof(Metrics));
-
- double title_w, title_h;
- title_size(module, &title_w, &title_h);
-
- GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(module));
- GanvText* canvas_title = GANV_NODE(module)->impl->label;
- GanvModulePrivate* impl = module->impl;
-
- if (ganv_canvas_get_direction(canvas) == GANV_DIRECTION_DOWN) {
- double contents_width = 0.0;
- if (canvas_title) {
- contents_width += title_w + (2.0 * PAD);
- }
-
- m->embed_x = 0;
- m->input_width = ganv_module_get_empty_port_breadth(module);
- m->output_width = ganv_module_get_empty_port_breadth(module);
-
- // TODO: cache this or merge with resize_right
- unsigned n_inputs = 0;
- unsigned n_outputs = 0;
- FOREACH_PORT(impl->ports, pi) {
- if ((*pi)->impl->is_input) {
- ++n_inputs;
- } else {
- ++n_outputs;
- }
- }
-
- const unsigned hor_ports = MAX(1, MAX(n_inputs, n_outputs));
- const double ports_width = (2 * EDGE_PAD) +
- ((m->input_width) * hor_ports) +
- ((PAD + 1.0) * (hor_ports - 1));
-
- m->width = MAX(contents_width, ports_width);
- m->width = MAX(m->width, impl->embed_width);
-
- if (impl->embed_item) {
- m->width = MAX(impl->embed_width + 2.0 * PAD, m->width);
- m->embed_x = PAD;
- }
- return;
- }
-
- // The amount of space between a port edge and the module edge (on the
- // side that the port isn't right on the edge).
- const double hor_pad = (canvas_title ? 10.0 : 20.0);
-
- m->width = (canvas_title) ? title_w + 10.0 : 1.0;
-
- // Title is wide or there is an embedded widget,
- // put inputs and outputs beside each other
- m->horiz = (impl->embed_item ||
- (impl->widest_input + impl->widest_output + 10.0
- < MAX(m->width, impl->embed_width)));
-
- // Fit ports to module (or vice-versa)
- m->input_width = impl->widest_input;
- m->output_width = impl->widest_output;
- double expand_w = (m->horiz ? (m->width / 2.0) : m->width) - hor_pad;
- if (!impl->embed_item) {
- m->input_width = MAX(impl->widest_input, expand_w);
- m->output_width = MAX(impl->widest_output, expand_w);
- }
-
- const double widest = MAX(m->input_width, m->output_width);
-
- if (impl->embed_item) {
- double above_w = MAX(m->width, widest + hor_pad);
- double between_w = MAX(m->width,
- (m->input_width
- + m->output_width
- + impl->embed_width));
-
- above_w = MAX(above_w, impl->embed_width);
-
- // Decide where to place embedded widget if necessary)
- if (impl->embed_width < impl->embed_height * 2.0) {
- m->embed_between = TRUE;
- m->width = between_w;
- m->embed_x = m->input_width;
- } else {
- m->width = above_w;
- m->embed_x = 2.0;
- }
- }
-
- if (!canvas_title && (impl->widest_input == 0.0
- || impl->widest_output == 0.0)) {
- m->width += 10.0;
- }
-
- m->width += 4.0;
- m->width = MAX(m->width, widest + hor_pad);
-}
-
-static void
-place_title(GanvModule* module, GanvDirection dir)
-{
- GanvBox* box = GANV_BOX(module);
- GanvText* canvas_title = GANV_NODE(module)->impl->label;
-
- double title_w, title_h;
- title_size(module, &title_w, &title_h);
-
- if (!canvas_title) {
- return;
- }
-
- GanvItem* t = GANV_ITEM(canvas_title);
- if (dir == GANV_DIRECTION_RIGHT) {
- t->impl->x = (ganv_box_get_width(box) - title_w) / 2.0;
- t->impl->y = 1.0;
- } else {
- t->impl->x = (ganv_box_get_width(box) - title_w) / 2.0;
- t->impl->y = ganv_module_get_empty_port_depth(module) + 1.0;
- }
-}
-
-static void
-resize_right(GanvModule* module)
-{
- GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(module));
- GanvModulePrivate* impl = module->impl;
-
- Metrics m;
- measure(module, &m);
-
- double title_w, title_h;
- title_size(module, &title_w, &title_h);
-
- // Basic height contains title
- double header_height = title_h ? (3.0 + title_h) : EDGE_PAD;
-
- if (impl->embed_item) {
- ganv_item_set(impl->embed_item,
- "x", (double)m.embed_x,
- "y", header_height,
- NULL);
- }
-
- // Actually set width and height
- ganv_box_set_width(GANV_BOX(module), m.width);
-
- // Offset ports below embedded widget
- if (!m.embed_between) {
- header_height += impl->embed_height;
- }
-
- // Move ports to appropriate locations
- double in_y = header_height;
- double out_y = header_height;
- FOREACH_PORT(impl->ports, pi) {
- GanvPort* const p = (*pi);
- GanvBox* const pbox = GANV_BOX(p);
- GanvNode* const pnode = GANV_NODE(p);
- const double h = ganv_box_get_height(pbox);
-
- // Offset to shift ports to make borders line up
- const double border_off = (GANV_NODE(module)->impl->border_width -
- pnode->impl->border_width) / 2.0;
-
- if (p->impl->is_input) {
- ganv_node_move_to(pnode, -border_off, in_y + 1.0);
- ganv_box_set_width(pbox, m.input_width);
- in_y += h + pnode->impl->border_width + 1.0;
-
- ganv_canvas_for_each_edge_to(
- canvas, pnode,
- (GanvEdgeFunc)ganv_edge_update_location, NULL);
- } else {
- ganv_node_move_to(pnode, m.width - m.output_width + border_off, out_y + 1.0);
- ganv_box_set_width(pbox, m.output_width);
- out_y += h + pnode->impl->border_width + 1.0;
-
- ganv_canvas_for_each_edge_from(
- canvas, pnode,
- (GanvEdgeFunc)ganv_edge_update_location, NULL);
- }
-
- if (!m.horiz) {
- in_y = MAX(in_y, out_y);
- out_y = MAX(in_y, out_y);
- }
- }
-
- double height = MAX(in_y, out_y) + EDGE_PAD;
- if (impl->embed_item && m.embed_between)
- height = MAX(height, impl->embed_height + header_height + 2.0);
-
- ganv_box_set_height(GANV_BOX(module), height);
-
- place_title(module, GANV_DIRECTION_RIGHT);
-}
-
-static void
-resize_down(GanvModule* module)
-{
- GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(module));
- GanvModulePrivate* impl = module->impl;
-
- Metrics m;
- measure(module, &m);
-
- double title_w, title_h;
- title_size(module, &title_w, &title_h);
-
- const double port_depth = ganv_module_get_empty_port_depth(module);
- const double port_breadth = ganv_module_get_empty_port_breadth(module);
-
- if (impl->embed_item) {
- ganv_item_set(impl->embed_item,
- "x", (double)m.embed_x,
- "y", port_depth + title_h,
- NULL);
- }
-
- const double height = PAD + title_h
- + impl->embed_height + (port_depth * 2.0);
-
- // Move ports to appropriate locations
- guint in_count = 0;
- guint out_count = 0;
- double in_x = 0.0;
- double out_x = 0.0;
- FOREACH_PORT(impl->ports, pi) {
- GanvPort* const p = (*pi);
- GanvBox* const pbox = GANV_BOX(p);
- GanvNode* const pnode = GANV_NODE(p);
- ganv_box_set_width(pbox, port_breadth);
- ganv_box_set_height(pbox, port_depth);
-
- // Offset to shift ports to make borders line up
- const double border_off = (GANV_NODE(module)->impl->border_width -
- pnode->impl->border_width) / 2.0;
-
- if (p->impl->is_input) {
- in_x = EDGE_PAD + (in_count++ * (port_breadth + PAD + 1.0));
- ganv_node_move_to(pnode, in_x, -border_off);
- ganv_canvas_for_each_edge_to(
- canvas, pnode,
- (GanvEdgeFunc)ganv_edge_update_location, NULL);
- } else {
- out_x = EDGE_PAD + (out_count++ * (port_breadth + PAD + 1.0));
- ganv_node_move_to(pnode, out_x, height - port_depth + border_off);
- ganv_canvas_for_each_edge_from(
- canvas, pnode,
- (GanvEdgeFunc)ganv_edge_update_location, NULL);
- }
- }
-
- ganv_box_set_height(GANV_BOX(module), height);
- ganv_box_set_width(GANV_BOX(module), m.width);
- place_title(module, GANV_DIRECTION_DOWN);
-}
-
-static void
-measure_ports(GanvModule* module)
-{
- GanvModulePrivate* impl = module->impl;
-
- impl->widest_input = 0.0;
- impl->widest_output = 0.0;
- FOREACH_PORT_CONST(impl->ports, pi) {
- const GanvPort* const p = (*pi);
- const double w = ganv_port_get_natural_width(p);
- if (p->impl->is_input) {
- if (w > impl->widest_input) {
- impl->widest_input = w;
- }
- } else {
- if (w > impl->widest_output) {
- impl->widest_output = w;
- }
- }
- }
-}
-
-static void
-ganv_module_resize(GanvNode* self)
-{
- GanvModule* module = GANV_MODULE(self);
- GanvNode* node = GANV_NODE(self);
- GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(module));
-
- double label_w = 0.0;
- double label_h = 0.0;
- if (node->impl->label) {
- g_object_get(node->impl->label,
- "width", &label_w,
- "height", &label_h,
- NULL);
- }
-
- measure_ports(module);
-
- ganv_box_set_width(GANV_BOX(module), label_w + (MODULE_LABEL_PAD * 2.0));
- ganv_box_set_height(GANV_BOX(module), label_h);
-
- switch (ganv_canvas_get_direction(canvas)) {
- case GANV_DIRECTION_RIGHT:
- resize_right(module);
- break;
- case GANV_DIRECTION_DOWN:
- resize_down(module);
- break;
- }
-
- if (GANV_NODE_CLASS(parent_class)->resize) {
- GANV_NODE_CLASS(parent_class)->resize(self);
- }
-}
-
-static void
-ganv_module_redraw_text(GanvNode* self)
-{
- FOREACH_PORT(GANV_MODULE(self)->impl->ports, p) {
- ganv_node_redraw_text(GANV_NODE(*p));
- }
-
- if (parent_class->parent_class.redraw_text) {
- parent_class->parent_class.redraw_text(self);
- }
-}
-
-static void
-ganv_module_add_port(GanvModule* module,
- GanvPort* port)
-{
- GanvModulePrivate* impl = module->impl;
-
- // Update widest input/output measurements if necessary
- const double width = ganv_port_get_natural_width(port);
- if (port->impl->is_input && width > impl->widest_input) {
- impl->widest_input = width;
- } else if (!port->impl->is_input && width > impl->widest_output) {
- impl->widest_output = width;
- }
-
- // Add to port array
- g_ptr_array_add(impl->ports, port);
-
- // Request update with resize and reorder
- GANV_NODE(module)->impl->must_resize = TRUE;
- impl->must_reorder = TRUE;
-}
-
-static void
-ganv_module_remove_port(GanvModule* module,
- GanvPort* port)
-{
- gboolean removed = g_ptr_array_remove(module->impl->ports, port);
- if (removed) {
- const double width = ganv_box_get_width(GANV_BOX(port));
- // Find new widest input or output, if necessary
- if (port->impl->is_input && width >= module->impl->widest_input) {
- module->impl->widest_input = 0;
- FOREACH_PORT_CONST(module->impl->ports, i) {
- const GanvPort* const p = (*i);
- const double w = ganv_box_get_width(GANV_BOX(p));
- if (p->impl->is_input && w >= module->impl->widest_input) {
- module->impl->widest_input = w;
- }
- }
- } else if (!port->impl->is_input && width >= module->impl->widest_output) {
- module->impl->widest_output = 0;
- FOREACH_PORT_CONST(module->impl->ports, i) {
- const GanvPort* const p = (*i);
- const double w = ganv_box_get_width(GANV_BOX(p));
- if (!p->impl->is_input && w >= module->impl->widest_output) {
- module->impl->widest_output = w;
- }
- }
- }
-
- GANV_NODE(module)->impl->must_resize = TRUE;
- } else {
- fprintf(stderr, "Failed to find port to remove\n");
- }
-}
-
-static void
-ganv_module_add(GanvItem* item, GanvItem* child)
-{
- if (GANV_IS_PORT(child)) {
- ganv_module_add_port(GANV_MODULE(item), GANV_PORT(child));
- }
- ganv_item_request_update(item);
- if (GANV_ITEM_CLASS(parent_class)->add) {
- GANV_ITEM_CLASS(parent_class)->add(item, child);
- }
-}
-
-static void
-ganv_module_remove(GanvItem* item, GanvItem* child)
-{
- if (GANV_IS_PORT(child)) {
- ganv_module_remove_port(GANV_MODULE(item), GANV_PORT(child));
- }
- ganv_item_request_update(item);
- if (GANV_ITEM_CLASS(parent_class)->remove) {
- GANV_ITEM_CLASS(parent_class)->remove(item, child);
- }
-}
-
-static int
-ptr_sort(const GanvPort** a, const GanvPort** b, const PortOrderCtx* ctx)
-{
- return ctx->port_cmp(*a, *b, ctx->data);
-}
-
-static void
-ganv_module_update(GanvItem* item, int flags)
-{
- GanvModule* module = GANV_MODULE(item);
- GanvCanvas* canvas = ganv_item_get_canvas(item);
-
- if (module->impl->must_reorder) {
- // Sort ports array
- PortOrderCtx ctx = ganv_canvas_get_port_order(canvas);
- if (ctx.port_cmp) {
- g_ptr_array_sort_with_data(module->impl->ports,
- (GCompareDataFunc)ptr_sort,
-
- &ctx);
- }
- module->impl->must_reorder = FALSE;
- }
-
- if (module->impl->embed_item) {
- // Kick the embedded item to update position if we have moved
- ganv_item_move(GANV_ITEM(module->impl->embed_item), 0.0, 0.0);
- }
-
- FOREACH_PORT(module->impl->ports, p) {
- ganv_item_invoke_update(GANV_ITEM(*p), flags);
- }
-
- if (module->impl->embed_item) {
- ganv_item_invoke_update(GANV_ITEM(module->impl->embed_item), flags);
- }
-
- GANV_ITEM_CLASS(parent_class)->update(item, flags);
-}
-
-static void
-ganv_module_draw(GanvItem* item,
- cairo_t* cr, double cx, double cy, double cw, double ch)
-{
- GanvNode* node = GANV_NODE(item);
- GanvModule* module = GANV_MODULE(item);
-
- // Draw box
- if (GANV_ITEM_CLASS(parent_class)->draw) {
- (*GANV_ITEM_CLASS(parent_class)->draw)(item, cr, cx, cy, cw, ch);
- }
-
- // Draw label
- if (node->impl->label) {
- GanvItem* label_item = GANV_ITEM(node->impl->label);
- GANV_ITEM_GET_CLASS(label_item)->draw(label_item, cr, cx, cy, cw, ch);
- }
-
- // Draw ports
- FOREACH_PORT(module->impl->ports, p) {
- GANV_ITEM_GET_CLASS(GANV_ITEM(*p))->draw(
- GANV_ITEM(*p), cr, cx, cy, cw, ch);
- }
-
- // Draw embed item
- if (module->impl->embed_item) {
- GANV_ITEM_GET_CLASS(module->impl->embed_item)->draw(
- module->impl->embed_item, cr, cx, cy, cw, ch);
- }
-}
-
-static void
-ganv_module_move_to(GanvNode* node,
- double x,
- double y)
-{
- GanvModule* module = GANV_MODULE(node);
- GANV_NODE_CLASS(parent_class)->move_to(node, x, y);
- FOREACH_PORT(module->impl->ports, p) {
- ganv_node_move(GANV_NODE(*p), 0.0, 0.0);
- }
- if (module->impl->embed_item) {
- ganv_item_move(GANV_ITEM(module->impl->embed_item), 0.0, 0.0);
- }
-}
-
-static void
-ganv_module_move(GanvNode* node,
- double dx,
- double dy)
-{
- GanvModule* module = GANV_MODULE(node);
- GANV_NODE_CLASS(parent_class)->move(node, dx, dy);
- FOREACH_PORT(module->impl->ports, p) {
- ganv_node_move(GANV_NODE(*p), 0.0, 0.0);
- }
- if (module->impl->embed_item) {
- ganv_item_move(GANV_ITEM(module->impl->embed_item), 0.0, 0.0);
- }
-}
-
-static double
-ganv_module_point(GanvItem* item, double x, double y, GanvItem** actual_item)
-{
- GanvModule* module = GANV_MODULE(item);
-
- double d = GANV_ITEM_CLASS(parent_class)->point(item, x, y, actual_item);
-
- if (!*actual_item) {
- // Point is not inside module at all, no point in checking children
- return d;
- }
-
- FOREACH_PORT(module->impl->ports, p) {
- GanvItem* const port = GANV_ITEM(*p);
-
- *actual_item = NULL;
- d = GANV_ITEM_GET_CLASS(port)->point(
- port, x - port->impl->x, y - port->impl->y, actual_item);
-
- if (*actual_item) {
- // Point is inside a port
- return d;
- }
- }
-
- // Point is inside module, but not a child port
- *actual_item = item;
- return 0.0;
-}
-
-static void
-ganv_module_class_init(GanvModuleClass* klass)
-{
- GObjectClass* gobject_class = (GObjectClass*)klass;
- GtkObjectClass* object_class = (GtkObjectClass*)klass;
- GanvItemClass* item_class = (GanvItemClass*)klass;
- GanvNodeClass* node_class = (GanvNodeClass*)klass;
-
- parent_class = GANV_BOX_CLASS(g_type_class_peek_parent(klass));
-
- gobject_class->set_property = ganv_module_set_property;
- gobject_class->get_property = ganv_module_get_property;
-
- object_class->destroy = ganv_module_destroy;
-
- item_class->add = ganv_module_add;
- item_class->remove = ganv_module_remove;
- item_class->update = ganv_module_update;
- item_class->draw = ganv_module_draw;
- item_class->point = ganv_module_point;
-
- node_class->move = ganv_module_move;
- node_class->move_to = ganv_module_move_to;
- node_class->resize = ganv_module_resize;
- node_class->redraw_text = ganv_module_redraw_text;
-}
-
-GanvModule*
-ganv_module_new(GanvCanvas* canvas,
- const char* first_property_name, ...)
-{
- GanvModule* module = GANV_MODULE(
- g_object_new(ganv_module_get_type(), "canvas", canvas, NULL));
-
- va_list args;
- va_start(args, first_property_name);
- g_object_set_valist(G_OBJECT(module), first_property_name, args);
- va_end(args);
-
- return module;
-}
-
-guint
-ganv_module_num_ports(const GanvModule* module)
-{
- return module->impl->ports ? module->impl->ports->len : 0;
-}
-
-GanvPort*
-ganv_module_get_port(GanvModule* module,
- guint index)
-{
- return (GanvPort*)g_ptr_array_index(module->impl->ports, index);
-}
-
-double
-ganv_module_get_empty_port_breadth(const GanvModule* module)
-{
- return ganv_module_get_empty_port_depth(module) * 2.0;
-}
-
-double
-ganv_module_get_empty_port_depth(const GanvModule* module)
-{
- GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(module));
-
- return ganv_canvas_get_font_size(canvas) * 1.1;
-}
-
-static void
-on_embed_size_request(GtkWidget* widget,
- GtkRequisition* r,
- void* user_data)
-{
- GanvModule* module = GANV_MODULE(user_data);
- GanvModulePrivate* impl = module->impl;
- if (impl->embed_width == r->width && impl->embed_height == r->height) {
- return;
- }
-
- impl->embed_width = r->width;
- impl->embed_height = r->height;
- GANV_NODE(module)->impl->must_resize = TRUE;
-
- GtkAllocation allocation;
- allocation.width = r->width;
- allocation.height = r->width;
-
- gtk_widget_size_allocate(widget, &allocation);
- ganv_item_set(impl->embed_item,
- "width", (double)r->width,
- "height", (double)r->height,
- NULL);
-}
-
-void
-ganv_module_embed(GanvModule* module,
- GtkWidget* widget)
-{
- GanvModulePrivate* impl = module->impl;
- if (!widget && !impl->embed_item) {
- return;
- }
-
- if (impl->embed_item) {
- // Free existing embedded widget
- gtk_object_destroy(GTK_OBJECT(impl->embed_item));
- impl->embed_item = NULL;
- }
-
- if (!widget) {
- // Removing an existing embedded widget
- impl->embed_width = 0;
- impl->embed_height = 0;
- GANV_NODE(module)->impl->must_resize = TRUE;
- ganv_item_request_update(GANV_ITEM(module));
- return;
- }
-
- double title_w, title_h;
- title_size(module, &title_w, &title_h);
-
- impl->embed_item = ganv_item_new(
- GANV_ITEM(module),
- ganv_widget_get_type(),
- "x", 2.0,
- "y", 4.0 + title_h,
- "widget", widget,
- NULL);
-
- GtkRequisition r;
- gtk_widget_show_all(widget);
- gtk_widget_size_request(widget, &r);
- on_embed_size_request(widget, &r, module);
- ganv_item_show(impl->embed_item);
-
- g_signal_connect(widget, "size-request",
- G_CALLBACK(on_embed_size_request), module);
-
- GANV_NODE(module)->impl->must_resize = TRUE;
- ganv_item_request_update(GANV_ITEM(module));
-}
-
-void
-ganv_module_set_direction(GanvModule* module,
- GanvDirection direction)
-{
- FOREACH_PORT(module->impl->ports, p) {
- ganv_port_set_direction(*p, direction);
- }
- GANV_NODE(module)->impl->must_resize = TRUE;
- ganv_item_request_update(GANV_ITEM(module));
-}
-
-void
-ganv_module_for_each_port(GanvModule* module,
- GanvPortFunc f,
- void* data)
-{
- GanvModulePrivate* impl = module->impl;
- const int len = impl->ports->len;
- GanvPort** copy = (GanvPort**)malloc(sizeof(GanvPort*) * len);
- memcpy(copy, impl->ports->pdata, sizeof(GanvPort*) * len);
-
- for (int i = 0; i < len; ++i) {
- f(copy[i], data);
- }
-
- free(copy);
-}
diff --git a/src/node.c b/src/node.c
deleted file mode 100644
index 4955f36..0000000
--- a/src/node.c
+++ /dev/null
@@ -1,897 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2016 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "ganv/canvas.h"
-#include "ganv/node.h"
-
-#include "./boilerplate.h"
-#include "./color.h"
-#include "./ganv-marshal.h"
-#include "./ganv-private.h"
-#include "./gettext.h"
-
-guint signal_moved;
-
-G_DEFINE_TYPE_WITH_CODE(GanvNode, ganv_node, GANV_TYPE_ITEM,
- G_ADD_PRIVATE(GanvNode))
-
-static GanvItemClass* parent_class;
-
-enum {
- PROP_0,
- PROP_CANVAS,
- PROP_PARTNER,
- PROP_LABEL,
- PROP_SHOW_LABEL,
- PROP_DASH_LENGTH,
- PROP_DASH_OFFSET,
- PROP_BORDER_WIDTH,
- PROP_FILL_COLOR,
- PROP_BORDER_COLOR,
- PROP_CAN_TAIL,
- PROP_CAN_HEAD,
- PROP_IS_SOURCE,
- PROP_SELECTED,
- PROP_HIGHLIGHTED,
- PROP_DRAGGABLE,
- PROP_GRABBED
-};
-
-static void
-ganv_node_init(GanvNode* node)
-{
- GanvNodePrivate* impl = ganv_node_get_instance_private(node);
-
- node->impl = impl;
-
- impl->partner = NULL;
- impl->label = NULL;
- impl->dash_length = 0.0;
- impl->dash_offset = 0.0;
- impl->border_width = 2.0;
- impl->fill_color = DEFAULT_FILL_COLOR;
- impl->border_color = DEFAULT_BORDER_COLOR;
- impl->can_tail = FALSE;
- impl->can_head = FALSE;
- impl->is_source = FALSE;
- impl->selected = FALSE;
- impl->highlighted = FALSE;
- impl->draggable = FALSE;
- impl->show_label = TRUE;
- impl->grabbed = FALSE;
- impl->must_resize = FALSE;
-#ifdef GANV_FDGL
- impl->force.x = 0.0;
- impl->force.y = 0.0;
- impl->vel.x = 0.0;
- impl->vel.y = 0.0;
- impl->connected = FALSE;
-#endif
-}
-
-static void
-ganv_node_realize(GanvItem* item)
-{
- GANV_ITEM_CLASS(parent_class)->realize(item);
- ganv_canvas_add_node(ganv_item_get_canvas(item), GANV_NODE(item));
-}
-
-static void
-ganv_node_destroy(GtkObject* object)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_NODE(object));
-
- GanvNode* node = GANV_NODE(object);
- GanvNodePrivate* impl = node->impl;
- if (impl->label) {
- g_object_unref(impl->label);
- impl->label = NULL;
- }
-
- GanvItem* item = GANV_ITEM(object);
- ganv_node_disconnect(node);
- if (item->impl->canvas) {
- ganv_canvas_remove_node(item->impl->canvas, node);
- }
-
- if (GTK_OBJECT_CLASS(parent_class)->destroy) {
- (*GTK_OBJECT_CLASS(parent_class)->destroy)(object);
- }
-
- impl->partner = NULL;
- item->impl->canvas = NULL;
-}
-
-static void
-ganv_node_update(GanvItem* item, int flags)
-{
- GanvNode* node = GANV_NODE(item);
- if (node->impl->must_resize) {
- ganv_node_resize(node);
- node->impl->must_resize = FALSE;
- }
-
- if (node->impl->label) {
- ganv_item_invoke_update(GANV_ITEM(node->impl->label), flags);
- }
-
- GANV_ITEM_CLASS(parent_class)->update(item, flags);
-}
-
-static void
-ganv_node_draw(GanvItem* item,
- cairo_t* cr, double cx, double cy, double cw, double ch)
-{
- /* TODO: Label is not drawn here because ports need to draw control
- rects then the label on top. I can't see a way of solving this since
- there's no single time parent class draw needs to be called, so perhaps
- label shouldn't be part of this class... */
-}
-
-static void
-ganv_node_set_property(GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_NODE(object));
-
- GanvNode* node = GANV_NODE(object);
- GanvNodePrivate* impl = node->impl;
-
- switch (prop_id) {
- SET_CASE(DASH_LENGTH, double, impl->dash_length);
- SET_CASE(DASH_OFFSET, double, impl->dash_offset);
- SET_CASE(BORDER_WIDTH, double, impl->border_width);
- SET_CASE(FILL_COLOR, uint, impl->fill_color);
- SET_CASE(BORDER_COLOR, uint, impl->border_color);
- SET_CASE(CAN_TAIL, boolean, impl->can_tail);
- SET_CASE(CAN_HEAD, boolean, impl->can_head);
- SET_CASE(IS_SOURCE, boolean, impl->is_source);
- SET_CASE(HIGHLIGHTED, boolean, impl->highlighted);
- SET_CASE(DRAGGABLE, boolean, impl->draggable);
- SET_CASE(GRABBED, boolean, impl->grabbed);
- case PROP_PARTNER:
- impl->partner = (GanvNode*)g_value_get_object(value);
- break;
- case PROP_SELECTED:
- if (impl->selected != g_value_get_boolean(value)) {
- GanvItem* item = GANV_ITEM(object);
- impl->selected = g_value_get_boolean(value);
- if (item->impl->canvas) {
- if (impl->selected) {
- ganv_canvas_select_node(ganv_item_get_canvas(item), node);
- } else {
- ganv_canvas_unselect_node(ganv_item_get_canvas(item), node);
- }
- ganv_item_request_update(item);
- }
- }
- break;
- case PROP_CANVAS:
- if (!GANV_ITEM(object)->impl->parent) {
- GanvCanvas* canvas = GANV_CANVAS(g_value_get_object(value));
- g_object_set(object, "parent", ganv_canvas_root(canvas), NULL);
- ganv_canvas_add_node(canvas, node);
- } else {
- g_warning("Cannot change `canvas' property after construction");
- }
- break;
- case PROP_LABEL:
- ganv_node_set_label(node, g_value_get_string(value));
- break;
- case PROP_SHOW_LABEL:
- ganv_node_set_show_label(node, g_value_get_boolean(value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-ganv_node_get_property(GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_NODE(object));
-
- GanvNode* node = GANV_NODE(object);
- GanvNodePrivate* impl = node->impl;
-
- switch (prop_id) {
- GET_CASE(PARTNER, object, impl->partner);
- GET_CASE(LABEL, string, impl->label ? impl->label->impl->text : NULL);
- GET_CASE(DASH_LENGTH, double, impl->dash_length);
- GET_CASE(DASH_OFFSET, double, impl->dash_offset);
- GET_CASE(BORDER_WIDTH, double, impl->border_width);
- GET_CASE(FILL_COLOR, uint, impl->fill_color);
- GET_CASE(BORDER_COLOR, uint, impl->border_color);
- GET_CASE(CAN_TAIL, boolean, impl->can_tail);
- GET_CASE(CAN_HEAD, boolean, impl->can_head);
- GET_CASE(IS_SOURCE, boolean, impl->is_source);
- GET_CASE(SELECTED, boolean, impl->selected);
- GET_CASE(HIGHLIGHTED, boolean, impl->highlighted);
- GET_CASE(DRAGGABLE, boolean, impl->draggable);
- GET_CASE(GRABBED, boolean, impl->grabbed);
- case PROP_CANVAS:
- g_value_set_object(value, ganv_item_get_canvas(GANV_ITEM(object)));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-ganv_node_default_tail_vector(const GanvNode* self,
- const GanvNode* head,
- double* x,
- double* y,
- double* dx,
- double* dy)
-{
- GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(self));
-
- *x = GANV_ITEM(self)->impl->x;
- *y = GANV_ITEM(self)->impl->y;
-
- switch (ganv_canvas_get_direction(canvas)) {
- case GANV_DIRECTION_RIGHT:
- *dx = 1.0;
- *dy = 0.0;
- break;
- case GANV_DIRECTION_DOWN:
- *dx = 0.0;
- *dy = 1.0;
- break;
- }
-
- ganv_item_i2w(GANV_ITEM(self)->impl->parent, x, y);
-}
-
-static void
-ganv_node_default_head_vector(const GanvNode* self,
- const GanvNode* tail,
- double* x,
- double* y,
- double* dx,
- double* dy)
-{
- GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(self));
-
- *x = GANV_ITEM(self)->impl->x;
- *y = GANV_ITEM(self)->impl->y;
-
- switch (ganv_canvas_get_direction(canvas)) {
- case GANV_DIRECTION_RIGHT:
- *dx = -1.0;
- *dy = 0.0;
- break;
- case GANV_DIRECTION_DOWN:
- *dx = 0.0;
- *dy = -1.0;
- break;
- }
-
- ganv_item_i2w(GANV_ITEM(self)->impl->parent, x, y);
-}
-
-void
-ganv_node_get_draw_properties(const GanvNode* node,
- double* dash_length,
- double* border_color,
- double* fill_color)
-{
- GanvNodePrivate* impl = node->impl;
-
- *dash_length = impl->dash_length;
- *border_color = impl->border_color;
- *fill_color = impl->fill_color;
-
- if (impl->selected) {
- *dash_length = 4.0;
- *border_color = highlight_color(impl->border_color, 0x40);
- }
-
- if (impl->highlighted) {
- *border_color = highlight_color(impl->border_color, 0x40);
- *fill_color = impl->fill_color;
- }
-}
-
-void
-ganv_node_set_label(GanvNode* node, const char* str)
-{
- GanvNodePrivate* impl = node->impl;
- if (!str || str[0] == '\0') {
- if (impl->label) {
- gtk_object_destroy(GTK_OBJECT(impl->label));
- impl->label = NULL;
- }
- } else if (impl->label) {
- ganv_item_set(GANV_ITEM(impl->label),
- "text", str,
- NULL);
- } else {
- impl->label = GANV_TEXT(ganv_item_new(GANV_ITEM(node),
- ganv_text_get_type(),
- "text", str,
- "color", DEFAULT_TEXT_COLOR,
- "managed", TRUE,
- NULL));
- }
-
- impl->must_resize = TRUE;
- ganv_item_request_update(GANV_ITEM(node));
-}
-
-void
-ganv_node_set_show_label(GanvNode* node, gboolean show)
-{
- if (node->impl->label) {
- if (show) {
- ganv_item_show(GANV_ITEM(node->impl->label));
- } else {
- ganv_item_hide(GANV_ITEM(node->impl->label));
- }
- }
- node->impl->show_label = show;
- ganv_item_request_update(GANV_ITEM(node));
-}
-
-static void
-ganv_node_default_tick(GanvNode* self,
- double seconds)
-{
- GanvNode* node = GANV_NODE(self);
- node->impl->dash_offset = seconds * 8.0;
- ganv_item_request_update(GANV_ITEM(self));
-}
-
-static void
-ganv_node_default_disconnect(GanvNode* node)
-{
- GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(node));
- if (canvas) {
- ganv_canvas_for_each_edge_on(
- canvas, node, (GanvEdgeFunc)ganv_edge_disconnect, NULL);
- }
-}
-
-static void
-ganv_node_default_move(GanvNode* node,
- double dx,
- double dy)
-{
- GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(node));
- ganv_item_move(GANV_ITEM(node), dx, dy);
- ganv_canvas_for_each_edge_on(
- canvas, node, (GanvEdgeFunc)ganv_edge_update_location, NULL);
- ganv_item_request_update(GANV_ITEM(node));
-}
-
-static void
-ganv_node_default_move_to(GanvNode* node,
- double x,
- double y)
-{
- GanvItem* item = GANV_ITEM(node);
- GanvCanvas* canvas = ganv_item_get_canvas(item);
- item->impl->x = x;
- item->impl->y = y;
- if (node->impl->can_tail) {
- ganv_canvas_for_each_edge_from(
- canvas, node, (GanvEdgeFunc)ganv_edge_update_location, NULL);
- } else if (node->impl->can_head) {
- ganv_canvas_for_each_edge_to(
- canvas, node, (GanvEdgeFunc)ganv_edge_update_location, NULL);
- }
- ganv_item_request_update(GANV_ITEM(node));
-}
-
-static void
-ganv_node_default_resize(GanvNode* node)
-{
- GanvItem* item = GANV_ITEM(node);
- if (GANV_IS_NODE(item->impl->parent)) {
- ganv_node_resize(GANV_NODE(item->impl->parent));
- }
- node->impl->must_resize = FALSE;
-}
-
-static void
-ganv_node_default_redraw_text(GanvNode* node)
-{
- if (node->impl->label) {
- ganv_text_layout(node->impl->label);
- node->impl->must_resize = TRUE;
- ganv_item_request_update(GANV_ITEM(node));
- }
-}
-
-static gboolean
-ganv_node_default_event(GanvItem* item,
- GdkEvent* event)
-{
- GanvNode* node = GANV_NODE(item);
- GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(node));
-
- // FIXME: put these somewhere better
- static double last_x, last_y;
- static double drag_start_x, drag_start_y;
- static gboolean dragging = FALSE;
-
- switch (event->type) {
- case GDK_ENTER_NOTIFY:
- ganv_item_raise(GANV_ITEM(node));
- node->impl->highlighted = TRUE;
- ganv_item_request_update(item);
- return TRUE;
-
- case GDK_LEAVE_NOTIFY:
- ganv_item_lower(GANV_ITEM(node));
- node->impl->highlighted = FALSE;
- ganv_item_request_update(item);
- return TRUE;
-
- case GDK_BUTTON_PRESS:
- drag_start_x = event->button.x;
- drag_start_y = event->button.y;
- last_x = event->button.x;
- last_y = event->button.y;
- if (!ganv_canvas_get_locked(canvas) && node->impl->draggable && event->button.button == 1) {
- ganv_canvas_grab_item(
- GANV_ITEM(node),
- GDK_POINTER_MOTION_MASK|GDK_BUTTON_RELEASE_MASK|GDK_BUTTON_PRESS_MASK,
- ganv_canvas_get_move_cursor(canvas),
- event->button.time);
- node->impl->grabbed = TRUE;
- dragging = TRUE;
- return TRUE;
- }
- break;
-
- case GDK_BUTTON_RELEASE:
- if (dragging) {
- gboolean selected;
- g_object_get(G_OBJECT(node), "selected", &selected, NULL);
- ganv_canvas_ungrab_item(GANV_ITEM(node), event->button.time);
- node->impl->grabbed = FALSE;
- dragging = FALSE;
- if (event->button.x != drag_start_x || event->button.y != drag_start_y) {
- ganv_canvas_contents_changed(canvas);
- if (selected) {
- ganv_canvas_selection_move_finished(canvas);
- } else {
- const double x = GANV_ITEM(node)->impl->x;
- const double y = GANV_ITEM(node)->impl->y;
- g_signal_emit(node, signal_moved, 0, x, y, NULL);
- }
- } else {
- // Clicked
- if (selected) {
- ganv_canvas_unselect_node(canvas, node);
- } else {
- if (!(event->button.state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK))) {
- ganv_canvas_clear_selection(canvas);
- }
- ganv_canvas_select_node(canvas, node);
- }
- }
- return TRUE;
- }
- break;
-
- case GDK_MOTION_NOTIFY:
- if ((dragging && (event->motion.state & GDK_BUTTON1_MASK))) {
- gboolean selected;
- g_object_get(G_OBJECT(node), "selected", &selected, NULL);
-
- double new_x = event->motion.x;
- double new_y = event->motion.y;
-
- if (event->motion.is_hint) {
- int t_x;
- int t_y;
- GdkModifierType state;
- gdk_window_get_pointer(event->motion.window, &t_x, &t_y, &state);
- new_x = t_x;
- new_y = t_y;
- }
-
- const double dx = new_x - last_x;
- const double dy = new_y - last_y;
- if (selected) {
- ganv_canvas_move_selected_items(canvas, dx, dy);
- } else {
- ganv_node_move(node, dx, dy);
- }
-
- last_x = new_x;
- last_y = new_y;
- return TRUE;
- }
-
- default:
- break;
- }
-
- return FALSE;
-}
-
-static void
-ganv_node_class_init(GanvNodeClass* klass)
-{
- GObjectClass* gobject_class = (GObjectClass*)klass;
- GtkObjectClass* object_class = (GtkObjectClass*)klass;
- GanvItemClass* item_class = (GanvItemClass*)klass;
-
- parent_class = GANV_ITEM_CLASS(g_type_class_peek_parent(klass));
-
- gobject_class->set_property = ganv_node_set_property;
- gobject_class->get_property = ganv_node_get_property;
-
- g_object_class_install_property(
- gobject_class, PROP_CANVAS, g_param_spec_object(
- "canvas",
- _("Canvas"),
- _("The canvas this node is on."),
- GANV_TYPE_CANVAS,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_PARTNER, g_param_spec_object(
- "partner",
- _("Partner"),
- _("Partners are nodes that should be visually aligned to correspond"
- " to each other, even if they are not necessarily connected (e.g."
- " for separate modules representing the inputs and outputs of a"
- " single thing). When the canvas is arranged, the partner will"
- " be aligned as if there was an edge from this node to its"
- " partner."),
- GANV_TYPE_NODE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_LABEL, g_param_spec_string(
- "label",
- _("Label"),
- _("The text to display as a label on this node."),
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_SHOW_LABEL, g_param_spec_boolean(
- "show-label",
- _("Show label"),
- _("Whether or not to show the label."),
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_DASH_LENGTH, g_param_spec_double(
- "dash-length",
- _("Border dash length"),
- _("Length of border dashes, or zero for no dashing."),
- 0.0, G_MAXDOUBLE,
- 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_DASH_OFFSET, g_param_spec_double(
- "dash-offset",
- _("Border dash offset"),
- _("Start offset for border dashes, used for selected animation."),
- 0.0, G_MAXDOUBLE,
- 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_BORDER_WIDTH, g_param_spec_double(
- "border-width",
- _("Border width"),
- _("Width of the border line."),
- 0.0, G_MAXDOUBLE,
- 2.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_FILL_COLOR, g_param_spec_uint(
- "fill-color",
- _("Fill color"),
- _("Color of internal area."),
- 0, G_MAXUINT,
- DEFAULT_FILL_COLOR,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_BORDER_COLOR, g_param_spec_uint(
- "border-color",
- _("Border color"),
- _("Color of border line."),
- 0, G_MAXUINT,
- DEFAULT_BORDER_COLOR,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_CAN_TAIL, g_param_spec_boolean(
- "can-tail",
- _("Can tail"),
- _("Whether this node can be the tail of an edge."),
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_CAN_HEAD, g_param_spec_boolean(
- "can-head",
- _("Can head"),
- _("Whether this object can be the head of an edge."),
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_IS_SOURCE, g_param_spec_boolean(
- "is-source",
- _("Is source"),
- _("Whether this object should be positioned at the start of signal flow."),
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_SELECTED, g_param_spec_boolean(
- "selected",
- _("Selected"),
- _("Whether this object is selected."),
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_HIGHLIGHTED, g_param_spec_boolean(
- "highlighted",
- _("Highlighted"),
- _("Whether this object is highlighted."),
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_DRAGGABLE, g_param_spec_boolean(
- "draggable",
- _("Draggable"),
- _("Whether this object is draggable."),
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_GRABBED, g_param_spec_boolean(
- "grabbed",
- _("Grabbed"),
- _("Whether this object is grabbed by the user."),
- 0,
- G_PARAM_READWRITE));
-
- signal_moved = g_signal_new("moved",
- ganv_node_get_type(),
- G_SIGNAL_RUN_FIRST,
- 0, NULL, NULL,
- ganv_marshal_VOID__DOUBLE_DOUBLE,
- G_TYPE_NONE,
- 2,
- G_TYPE_DOUBLE,
- G_TYPE_DOUBLE,
- 0);
-
- object_class->destroy = ganv_node_destroy;
-
- item_class->realize = ganv_node_realize;
- item_class->event = ganv_node_default_event;
- item_class->update = ganv_node_update;
- item_class->draw = ganv_node_draw;
-
- klass->disconnect = ganv_node_default_disconnect;
- klass->move = ganv_node_default_move;
- klass->move_to = ganv_node_default_move_to;
- klass->resize = ganv_node_default_resize;
- klass->redraw_text = ganv_node_default_redraw_text;
- klass->tick = ganv_node_default_tick;
- klass->tail_vector = ganv_node_default_tail_vector;
- klass->head_vector = ganv_node_default_head_vector;
-}
-
-gboolean
-ganv_node_can_tail(const GanvNode* self)
-{
- return self->impl->can_tail;
-}
-
-gboolean
-ganv_node_can_head(const GanvNode* self)
-{
- return self->impl->can_head;
-}
-
-void
-ganv_node_set_is_source(const GanvNode* node, gboolean is_source)
-{
- node->impl->is_source = is_source;
-}
-
-gboolean
-ganv_node_is_within(const GanvNode* node,
- double x1,
- double y1,
- double x2,
- double y2)
-{
- return GANV_NODE_GET_CLASS(node)->is_within(node, x1, y1, x2, y2);
-}
-
-void
-ganv_node_tick(GanvNode* node,
- double seconds)
-{
- GanvNodeClass* klass = GANV_NODE_GET_CLASS(node);
- if (klass->tick) {
- klass->tick(node, seconds);
- }
-}
-
-void
-ganv_node_tail_vector(const GanvNode* self,
- const GanvNode* head,
- double* x1,
- double* y1,
- double* x2,
- double* y2)
-{
- GANV_NODE_GET_CLASS(self)->tail_vector(
- self, head, x1, y1, x2, y2);
-}
-
-void
-ganv_node_head_vector(const GanvNode* self,
- const GanvNode* tail,
- double* x1,
- double* y1,
- double* x2,
- double* y2)
-{
- GANV_NODE_GET_CLASS(self)->head_vector(
- self, tail, x1, y1, x2, y2);
-}
-
-const char*
-ganv_node_get_label(const GanvNode* node)
-{
- return node->impl->label ? node->impl->label->impl->text : NULL;
-}
-
-double
-ganv_node_get_border_width(const GanvNode* node)
-{
- return node->impl->border_width;
-}
-
-void
-ganv_node_set_border_width(const GanvNode* node, double border_width)
-{
- node->impl->border_width = border_width;
- ganv_item_request_update(GANV_ITEM(node));
-}
-
-double
-ganv_node_get_dash_length(const GanvNode* node)
-{
- return node->impl->dash_length;
-}
-
-void
-ganv_node_set_dash_length(const GanvNode* node, double dash_length)
-{
- node->impl->dash_length = dash_length;
- ganv_item_request_update(GANV_ITEM(node));
-}
-
-double
-ganv_node_get_dash_offset(const GanvNode* node)
-{
- return node->impl->dash_offset;
-}
-
-void
-ganv_node_set_dash_offset(const GanvNode* node, double dash_offset)
-{
- node->impl->dash_offset = dash_offset;
- ganv_item_request_update(GANV_ITEM(node));
-}
-
-guint
-ganv_node_get_fill_color(const GanvNode* node)
-{
- return node->impl->fill_color;
-}
-
-void
-ganv_node_set_fill_color(const GanvNode* node, guint fill_color)
-{
- node->impl->fill_color = fill_color;
- ganv_item_request_update(GANV_ITEM(node));
-}
-
-guint
-ganv_node_get_border_color(const GanvNode* node)
-{
- return node->impl->border_color;
-}
-
-void
-ganv_node_set_border_color(const GanvNode* node, guint border_color)
-{
- node->impl->border_color = border_color;
- ganv_item_request_update(GANV_ITEM(node));
-}
-
-GanvNode*
-ganv_node_get_partner(const GanvNode* node)
-{
- return node->impl->partner;
-}
-
-void
-ganv_node_move(GanvNode* node,
- double dx,
- double dy)
-{
- GANV_NODE_GET_CLASS(node)->move(node, dx, dy);
-}
-
-void
-ganv_node_move_to(GanvNode* node,
- double x,
- double y)
-{
- GANV_NODE_GET_CLASS(node)->move_to(node, x, y);
-}
-
-void
-ganv_node_resize(GanvNode* node)
-{
- GANV_NODE_GET_CLASS(node)->resize(node);
- node->impl->must_resize = FALSE;
-}
-
-void
-ganv_node_redraw_text(GanvNode* node)
-{
- GANV_NODE_GET_CLASS(node)->redraw_text(node);
-}
-
-void
-ganv_node_disconnect(GanvNode* node)
-{
- GANV_NODE_GET_CLASS(node)->disconnect(node);
-}
-
-gboolean
-ganv_node_is_selected(GanvNode* node)
-{
- gboolean selected = FALSE;
- g_object_get(node, "selected", &selected, NULL);
- return selected;
-}
diff --git a/src/port.c b/src/port.c
deleted file mode 100644
index fa76f22..0000000
--- a/src/port.c
+++ /dev/null
@@ -1,735 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2015 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <math.h>
-#include <stdlib.h>
-
-#include "ganv/canvas.h"
-#include "ganv/port.h"
-#include "ganv/module.h"
-
-#include "./boilerplate.h"
-#include "./color.h"
-#include "./ganv-private.h"
-#include "./gettext.h"
-
-static const double PORT_LABEL_HPAD = 4.0;
-static const double PORT_LABEL_VPAD = 1.0;
-
-static void
-ganv_port_update_control_slider(GanvPort* port, float value, gboolean force);
-
-G_DEFINE_TYPE_WITH_CODE(GanvPort, ganv_port, GANV_TYPE_BOX,
- G_ADD_PRIVATE(GanvPort))
-
-static GanvBoxClass* parent_class;
-
-enum {
- PROP_0,
- PROP_IS_INPUT,
- PROP_IS_CONTROLLABLE
-};
-
-enum {
- PORT_VALUE_CHANGED,
- PORT_LAST_SIGNAL
-};
-
-static guint port_signals[PORT_LAST_SIGNAL];
-
-static void
-ganv_port_init(GanvPort* port)
-{
- port->impl = ganv_port_get_instance_private(port);
-
- port->impl->control = NULL;
- port->impl->value_label = NULL;
- port->impl->is_input = TRUE;
- port->impl->is_controllable = FALSE;
-}
-
-static void
-ganv_port_destroy(GtkObject* object)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_PORT(object));
-
- GanvItem* item = GANV_ITEM(object);
- GanvPort* port = GANV_PORT(object);
- GanvCanvas* canvas = ganv_item_get_canvas(item);
- if (canvas) {
- if (port->impl->is_input) {
- ganv_canvas_for_each_edge_to(
- canvas, &port->box.node, (GanvEdgeFunc)ganv_edge_remove, NULL);
- } else {
- ganv_canvas_for_each_edge_from(
- canvas, &port->box.node, (GanvEdgeFunc)ganv_edge_remove, NULL);
- }
- }
-
- if (GTK_OBJECT_CLASS(parent_class)->destroy) {
- (*GTK_OBJECT_CLASS(parent_class)->destroy)(object);
- }
-}
-
-static void
-ganv_port_set_property(GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_PORT(object));
-
- GanvPort* port = GANV_PORT(object);
-
- switch (prop_id) {
- SET_CASE(IS_INPUT, boolean, port->impl->is_input);
- SET_CASE(IS_CONTROLLABLE, boolean, port->impl->is_controllable);
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-ganv_port_get_property(GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_PORT(object));
-
- GanvPort* port = GANV_PORT(object);
-
- switch (prop_id) {
- GET_CASE(IS_INPUT, boolean, port->impl->is_input);
- GET_CASE(IS_CONTROLLABLE, boolean, port->impl->is_controllable);
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-ganv_port_update(GanvItem* item, int flags)
-{
- GanvPort* port = GANV_PORT(item);
- GanvPortPrivate* impl = port->impl;
-
- if (impl->control) {
- ganv_item_invoke_update(GANV_ITEM(impl->control->rect), flags);
- }
-
- if (impl->value_label) {
- ganv_item_invoke_update(GANV_ITEM(port->impl->value_label), flags);
- }
-
- GanvItemClass* item_class = GANV_ITEM_CLASS(parent_class);
- item_class->update(item, flags);
-}
-
-static void
-ganv_port_draw(GanvItem* item,
- cairo_t* cr, double cx, double cy, double cw, double ch)
-{
- GanvPort* port = GANV_PORT(item);
- GanvCanvas* canvas = ganv_item_get_canvas(item);
-
- // Draw Box
- GanvItemClass* item_class = GANV_ITEM_CLASS(parent_class);
- item_class->draw(item, cr, cx, cy, cw, ch);
-
- if (port->impl->control) {
- // Clip to port boundaries (to stay within radiused borders)
- cairo_save(cr);
- const double pad = GANV_NODE(port)->impl->border_width / 2.0;
- GanvBoxCoords coords = GANV_BOX(port)->impl->coords;
- ganv_item_i2w_pair(GANV_ITEM(port),
- &coords.x1, &coords.y1, &coords.x2, &coords.y2);
- ganv_box_path(GANV_BOX(port), cr,
- coords.x1 + pad, coords.y1 + pad,
- coords.x2 - pad, coords.y2 - pad,
- -pad);
- cairo_clip(cr);
-
- GanvItem* const rect = GANV_ITEM(port->impl->control->rect);
- GANV_ITEM_GET_CLASS(rect)->draw(rect, cr, cx, cy, cw, ch);
-
- cairo_restore(cr);
- }
-
- if (ganv_canvas_get_direction(canvas) == GANV_DIRECTION_DOWN ||
- !GANV_NODE(port)->impl->show_label) {
- return;
- }
-
- GanvItem* labels[2] = {
- GANV_ITEM(GANV_NODE(item)->impl->label),
- port->impl->value_label ? GANV_ITEM(port->impl->value_label) : NULL
- };
- for (int i = 0; i < 2; ++i) {
- if (labels[i] && (labels[i]->object.flags & GANV_ITEM_VISIBLE)) {
- GANV_ITEM_GET_CLASS(labels[i])->draw(
- labels[i], cr, cx, cy, cw, ch);
- }
- }
-}
-
-static void
-ganv_port_tail_vector(const GanvNode* self,
- const GanvNode* head,
- double* x,
- double* y,
- double* dx,
- double* dy)
-{
- GanvPort* port = GANV_PORT(self);
- GanvItem* item = &port->box.node.item;
- GanvCanvas* canvas = ganv_item_get_canvas(item);
-
- const double px = item->impl->x;
- const double py = item->impl->y;
- const double border_width = GANV_NODE(port)->impl->border_width;
-
- switch (ganv_canvas_get_direction(canvas)) {
- case GANV_DIRECTION_RIGHT:
- *x = px + ganv_box_get_width(&port->box) + (border_width / 2.0);
- *y = py + ganv_box_get_height(&port->box) / 2.0;
- *dx = 1.0;
- *dy = 0.0;
- break;
- case GANV_DIRECTION_DOWN:
- *x = px + ganv_box_get_width(&port->box) / 2.0;
- *y = py + ganv_box_get_height(&port->box) + (border_width / 2.0);
- *dx = 0.0;
- *dy = 1.0;
- break;
- }
-
- ganv_item_i2w(item->impl->parent, x, y);
-}
-
-static void
-ganv_port_head_vector(const GanvNode* self,
- const GanvNode* tail,
- double* x,
- double* y,
- double* dx,
- double* dy)
-{
- GanvPort* port = GANV_PORT(self);
- GanvItem* item = &port->box.node.item;
- GanvCanvas* canvas = ganv_item_get_canvas(item);
-
- const double px = item->impl->x;
- const double py = item->impl->y;
- const double border_width = GANV_NODE(port)->impl->border_width;
-
- switch (ganv_canvas_get_direction(canvas)) {
- case GANV_DIRECTION_RIGHT:
- *x = px - (border_width / 2.0);
- *y = py + ganv_box_get_height(&port->box) / 2.0;
- *dx = -1.0;
- *dy = 0.0;
- break;
- case GANV_DIRECTION_DOWN:
- *x = px + ganv_box_get_width(&port->box) / 2.0;
- *y = py - (border_width / 2.0);
- *dx = 0.0;
- *dy = -1.0;
- break;
- }
-
- ganv_item_i2w(item->impl->parent, x, y);
-}
-
-static void
-ganv_port_place_labels(GanvPort* port)
-{
- GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(port));
- GanvPortPrivate* impl = port->impl;
- GanvText* label = GANV_NODE(port)->impl->label;
- const double port_w = ganv_box_get_width(&port->box);
- const double port_h = ganv_box_get_height(&port->box);
- double vlabel_w = 0.0;
- if (impl->value_label) {
- const double vlabel_h = impl->value_label->impl->coords.height;
- vlabel_w = impl->value_label->impl->coords.width;
- if (ganv_canvas_get_direction(canvas) == GANV_DIRECTION_RIGHT) {
- ganv_item_set(GANV_ITEM(impl->value_label),
- "x", PORT_LABEL_HPAD,
- "y", (port_h - vlabel_h) / 2.0 - PORT_LABEL_VPAD,
- NULL);
- } else {
- ganv_item_set(GANV_ITEM(impl->value_label),
- "x", (port_w - vlabel_w) / 2.0,
- "y", (port_h - vlabel_h) / 2.0 - PORT_LABEL_VPAD,
- NULL);
- }
- vlabel_w += PORT_LABEL_HPAD;
- }
- if (label) {
- const double label_h = label->impl->coords.height;
- if (ganv_canvas_get_direction(canvas) == GANV_DIRECTION_RIGHT) {
- ganv_item_set(GANV_ITEM(label),
- "x", vlabel_w + PORT_LABEL_HPAD,
- "y", (port_h - label_h) / 2.0 - PORT_LABEL_VPAD,
- NULL);
- }
- }
-}
-
-static void
-ganv_port_resize(GanvNode* self)
-{
- GanvPort* port = GANV_PORT(self);
- GanvNode* node = GANV_NODE(self);
- GanvText* label = node->impl->label;
- GanvText* vlabel = port->impl->value_label;
-
- double label_w = 0.0;
- double label_h = 0.0;
- double vlabel_w = 0.0;
- double vlabel_h = 0.0;
- if (label && (GANV_ITEM(label)->object.flags & GANV_ITEM_VISIBLE)) {
- g_object_get(label, "width", &label_w, "height", &label_h, NULL);
- }
- if (vlabel && (GANV_ITEM(vlabel)->object.flags & GANV_ITEM_VISIBLE)) {
- g_object_get(vlabel, "width", &vlabel_w, "height", &vlabel_h, NULL);
- }
-
- if (label || vlabel) {
- double labels_w = label_w + PORT_LABEL_HPAD * 2.0;
- if (vlabel_w != 0.0) {
- labels_w += vlabel_w + PORT_LABEL_HPAD;
- }
- ganv_box_set_width(&port->box, labels_w);
- ganv_box_set_height(&port->box,
- MAX(label_h, vlabel_h) + (PORT_LABEL_VPAD * 2.0));
-
- ganv_port_place_labels(port);
- }
-
- if (GANV_NODE_CLASS(parent_class)->resize) {
- GANV_NODE_CLASS(parent_class)->resize(self);
- }
-}
-
-static void
-ganv_port_redraw_text(GanvNode* node)
-{
- GanvPort* port = GANV_PORT(node);
- if (port->impl->value_label) {
- ganv_text_layout(port->impl->value_label);
- }
- if (GANV_NODE_CLASS(parent_class)->redraw_text) {
- (*GANV_NODE_CLASS(parent_class)->redraw_text)(node);
- }
- ganv_port_place_labels(port);
-}
-
-static void
-ganv_port_set_width(GanvBox* box,
- double width)
-{
- GanvPort* port = GANV_PORT(box);
- parent_class->set_width(box, width);
- if (port->impl->control) {
- ganv_port_update_control_slider(port, port->impl->control->value, TRUE);
- }
- ganv_port_place_labels(port);
-}
-
-static void
-ganv_port_set_height(GanvBox* box,
- double height)
-{
- GanvPort* port = GANV_PORT(box);
- parent_class->set_height(box, height);
- if (port->impl->control) {
- ganv_item_set(GANV_ITEM(port->impl->control->rect),
- "y1", box->impl->coords.border_width / 2.0,
- "y2", height - box->impl->coords.border_width / 2.0,
- NULL);
- }
- ganv_port_place_labels(port);
-}
-
-static gboolean
-ganv_port_event(GanvItem* item, GdkEvent* event)
-{
- GanvCanvas* canvas = ganv_item_get_canvas(item);
-
- return ganv_canvas_port_event(canvas, GANV_PORT(item), event);
-}
-
-static void
-ganv_port_class_init(GanvPortClass* klass)
-{
- GObjectClass* gobject_class = (GObjectClass*)klass;
- GtkObjectClass* object_class = (GtkObjectClass*)klass;
- GanvItemClass* item_class = (GanvItemClass*)klass;
- GanvNodeClass* node_class = (GanvNodeClass*)klass;
- GanvBoxClass* box_class = (GanvBoxClass*)klass;
-
- parent_class = GANV_BOX_CLASS(g_type_class_peek_parent(klass));
-
- gobject_class->set_property = ganv_port_set_property;
- gobject_class->get_property = ganv_port_get_property;
-
- g_object_class_install_property(
- gobject_class, PROP_IS_INPUT, g_param_spec_boolean(
- "is-input",
- _("Is input"),
- _("Whether this port is an input, rather than an output."),
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_IS_CONTROLLABLE, g_param_spec_boolean(
- "is-controllable",
- _("Is controllable"),
- _("Whether this port can be controlled by the user."),
- 0,
- G_PARAM_READWRITE));
-
- port_signals[PORT_VALUE_CHANGED]
- = g_signal_new("value-changed",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- NULL,
- G_TYPE_NONE, 1,
- G_TYPE_DOUBLE);
-
- object_class->destroy = ganv_port_destroy;
-
- item_class->update = ganv_port_update;
- item_class->event = ganv_port_event;
- item_class->draw = ganv_port_draw;
-
- node_class->tail_vector = ganv_port_tail_vector;
- node_class->head_vector = ganv_port_head_vector;
- node_class->resize = ganv_port_resize;
- node_class->redraw_text = ganv_port_redraw_text;
-
- box_class->set_width = ganv_port_set_width;
- box_class->set_height = ganv_port_set_height;
-}
-
-GanvPort*
-ganv_port_new(GanvModule* module,
- gboolean is_input,
- const char* first_prop_name, ...)
-{
- GanvPort* port = GANV_PORT(g_object_new(ganv_port_get_type(), NULL));
-
- port->impl->is_input = is_input;
-
- GanvItem* item = GANV_ITEM(port);
- va_list args;
- va_start(args, first_prop_name);
- ganv_item_construct(item,
- GANV_ITEM(module),
- first_prop_name, args);
- va_end(args);
-
- GanvBox* box = GANV_BOX(port);
- box->impl->coords.border_width = 1.0;
-
- GanvNode* node = GANV_NODE(port);
- node->impl->can_tail = !is_input;
- node->impl->can_head = is_input;
- node->impl->draggable = FALSE;
- node->impl->border_width = 2.0;
-
- GanvCanvas* canvas = ganv_item_get_canvas(GANV_ITEM(port));
- ganv_port_set_direction(port, ganv_canvas_get_direction(canvas));
-
- return port;
-}
-
-void
-ganv_port_set_direction(GanvPort* port,
- GanvDirection direction)
-{
- GanvNode* node = GANV_NODE(port);
- GanvBox* box = GANV_BOX(port);
- gboolean is_input = port->impl->is_input;
- switch (direction) {
- case GANV_DIRECTION_RIGHT:
- box->impl->radius_tl = (is_input ? 0.0 : 5.0);
- box->impl->radius_tr = (is_input ? 5.0 : 0.0);
- box->impl->radius_br = (is_input ? 5.0 : 0.0);
- box->impl->radius_bl = (is_input ? 0.0 : 5.0);
- break;
- case GANV_DIRECTION_DOWN:
- box->impl->radius_tl = (is_input ? 0.0 : 5.0);
- box->impl->radius_tr = (is_input ? 0.0 : 5.0);
- box->impl->radius_br = (is_input ? 5.0 : 0.0);
- box->impl->radius_bl = (is_input ? 5.0 : 0.0);
- break;
- }
-
- node->impl->must_resize = TRUE;
- ganv_item_request_update(GANV_ITEM(node));
-}
-
-void
-ganv_port_show_control(GanvPort* port)
-{
- if (port->impl->control) {
- return;
- }
-
- const guint color = 0xFFFFFF66;
- const double border_width = GANV_NODE(port)->impl->border_width;
-
- GanvPortControl* control = (GanvPortControl*)malloc(sizeof(GanvPortControl));
- port->impl->control = control;
-
- control->value = 0.0f;
- control->min = 0.0f;
- control->max = 1.0f;
- control->is_toggle = FALSE;
- control->is_integer = FALSE;
- control->rect = GANV_BOX(
- ganv_item_new(GANV_ITEM(port),
- ganv_box_get_type(),
- "x1", border_width / 2.0,
- "y1", border_width / 2.0,
- "x2", 0.0,
- "y2", ganv_box_get_height(&port->box) - border_width / 2.0,
- "fill-color", color,
- "border-color", color,
- "border-width", 0.0,
- "managed", TRUE,
- NULL));
- ganv_item_show(GANV_ITEM(control->rect));
-}
-
-void
-ganv_port_hide_control(GanvPort* port)
-{
- gtk_object_destroy(GTK_OBJECT(port->impl->control->rect));
- free(port->impl->control);
- port->impl->control = NULL;
-}
-
-void
-ganv_port_set_value_label(GanvPort* port,
- const char* str)
-{
- GanvPortPrivate* impl = port->impl;
-
- if (!str || str[0] == '\0') {
- if (impl->value_label) {
- gtk_object_destroy(GTK_OBJECT(impl->value_label));
- impl->value_label = NULL;
- }
- } else if (impl->value_label) {
- ganv_item_set(GANV_ITEM(impl->value_label),
- "text", str,
- NULL);
- } else {
- impl->value_label = GANV_TEXT(ganv_item_new(GANV_ITEM(port),
- ganv_text_get_type(),
- "text", str,
- "color", DIM_TEXT_COLOR,
- "managed", TRUE,
- NULL));
- }
-}
-
-static void
-ganv_port_update_control_slider(GanvPort* port, float value, gboolean force)
-{
- GanvPortPrivate* impl = port->impl;
- if (!impl->control) {
- return;
- }
-
- // Clamp to toggle or integer value if applicable
- if (impl->control->is_toggle) {
- if (value != 0.0f) {
- value = impl->control->max;
- } else {
- value = impl->control->min;
- }
- } else if (impl->control->is_integer) {
- value = lrintf(value);
- }
-
- // Clamp to range
- if (value < impl->control->min) {
- value = impl->control->min;
- }
- if (value > impl->control->max) {
- value = impl->control->max;
- }
-
- if (!force && value == impl->control->value) {
- return; // No change, do nothing
- }
-
- const double span = (ganv_box_get_width(&port->box) -
- GANV_NODE(port)->impl->border_width);
-
- const double w = (value - impl->control->min)
- / (impl->control->max - impl->control->min)
- * span;
-
- if (isnan(w)) {
- return; // Shouldn't happen, but ignore crazy values
- }
-
- // Redraw port
- impl->control->value = value;
- ganv_box_set_width(impl->control->rect, MAX(0.0, w));
- ganv_box_request_redraw(
- GANV_ITEM(port), &GANV_BOX(port)->impl->coords, FALSE);
-}
-
-void
-ganv_port_set_control_is_toggle(GanvPort* port,
- gboolean is_toggle)
-{
- if (port->impl->control) {
- port->impl->control->is_toggle = is_toggle;
- ganv_port_update_control_slider(port, port->impl->control->value, TRUE);
- }
-}
-
-void
-ganv_port_set_control_is_integer(GanvPort* port,
- gboolean is_integer)
-{
- if (port->impl->control) {
- port->impl->control->is_integer = is_integer;
- const float rounded = rintf(port->impl->control->value);
- ganv_port_update_control_slider(port, rounded, TRUE);
- }
-}
-
-void
-ganv_port_set_control_value(GanvPort* port,
- float value)
-{
- ganv_port_update_control_slider(port, value, FALSE);
-}
-
-void
-ganv_port_set_control_value_internal(GanvPort* port,
- float value)
-{
- // Update slider
- ganv_port_set_control_value(port, value);
-
- // Fire signal to notify user value has changed
- const double dvalue = port->impl->control->value;
- g_signal_emit(port, port_signals[PORT_VALUE_CHANGED], 0, dvalue, NULL);
-}
-
-void
-ganv_port_set_control_min(GanvPort* port,
- float min)
-{
- if (port->impl->control) {
- const gboolean force = port->impl->control->min != min;
- port->impl->control->min = min;
- if (port->impl->control->max < min) {
- port->impl->control->max = min;
- }
- ganv_port_update_control_slider(port, port->impl->control->value, force);
- }
-}
-
-void
-ganv_port_set_control_max(GanvPort* port,
- float max)
-{
- if (port->impl->control) {
- const gboolean force = port->impl->control->max != max;
- port->impl->control->max = max;
- if (port->impl->control->min > max) {
- port->impl->control->min = max;
- }
- ganv_port_update_control_slider(port, port->impl->control->value, force);
- }
-}
-
-double
-ganv_port_get_natural_width(const GanvPort* port)
-{
- GanvCanvas* const canvas = ganv_item_get_canvas(GANV_ITEM(port));
- GanvText* const label = port->box.node.impl->label;
- double w = 0.0;
- if (ganv_canvas_get_direction(canvas) == GANV_DIRECTION_DOWN) {
- w = ganv_module_get_empty_port_breadth(ganv_port_get_module(port));
- } else if (label && (GANV_ITEM(label)->object.flags & GANV_ITEM_VISIBLE)) {
- double label_w;
- g_object_get(port->box.node.impl->label, "width", &label_w, NULL);
- w = label_w + (PORT_LABEL_HPAD * 2.0);
- } else {
- w = ganv_module_get_empty_port_depth(ganv_port_get_module(port));
- }
- if (port->impl->value_label &&
- (GANV_ITEM(port->impl->value_label)->object.flags
- & GANV_ITEM_VISIBLE)) {
- double label_w;
- g_object_get(port->impl->value_label, "width", &label_w, NULL);
- w += label_w + PORT_LABEL_HPAD;
- }
- return w;
-}
-
-GanvModule*
-ganv_port_get_module(const GanvPort* port)
-{
- return GANV_MODULE(GANV_ITEM(port)->impl->parent);
-}
-
-float
-ganv_port_get_control_value(const GanvPort* port)
-{
- return port->impl->control ? port->impl->control->value : 0.0f;
-}
-
-float
-ganv_port_get_control_min(const GanvPort* port)
-{
- return port->impl->control ? port->impl->control->min : 0.0f;
-}
-
-float
-ganv_port_get_control_max(const GanvPort* port)
-{
- return port->impl->control ? port->impl->control->max : 0.0f;
-}
-
-gboolean
-ganv_port_is_input(const GanvPort* port)
-{
- return port->impl->is_input;
-}
-
-gboolean
-ganv_port_is_output(const GanvPort* port)
-{
- return !port->impl->is_input;
-}
diff --git a/src/text.c b/src/text.c
deleted file mode 100644
index bbac187..0000000
--- a/src/text.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2015 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <math.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <gtk/gtkstyle.h>
-
-#include "ganv/canvas.h"
-#include "ganv/text.h"
-
-#include "./color.h"
-#include "./boilerplate.h"
-#include "./gettext.h"
-#include "./ganv-private.h"
-
-G_DEFINE_TYPE_WITH_CODE(GanvText, ganv_text, GANV_TYPE_ITEM,
- G_ADD_PRIVATE(GanvText))
-
-static GanvItemClass* parent_class;
-
-enum {
- PROP_0,
- PROP_TEXT,
- PROP_X,
- PROP_Y,
- PROP_WIDTH,
- PROP_HEIGHT,
- PROP_COLOR,
- PROP_FONT_SIZE
-};
-
-static void
-ganv_text_init(GanvText* text)
-{
- GanvTextPrivate* impl = ganv_text_get_instance_private(text);
-
- text->impl = impl;
-
- memset(&impl->coords, '\0', sizeof(GanvTextCoords));
- impl->coords.width = 1.0;
- impl->coords.height = 1.0;
- impl->old_coords = impl->coords;
-
- impl->layout = NULL;
- impl->text = NULL;
- impl->font_size = 0.0;
- impl->color = DEFAULT_TEXT_COLOR;
- impl->needs_layout = FALSE;
-}
-
-static void
-ganv_text_destroy(GtkObject* object)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_TEXT(object));
-
- GanvText* text = GANV_TEXT(object);
- GanvTextPrivate* impl = text->impl;
-
- if (impl->text) {
- g_free(impl->text);
- impl->text = NULL;
- }
-
- if (impl->layout) {
- g_object_unref(impl->layout);
- impl->layout = NULL;
- }
-
- if (GTK_OBJECT_CLASS(parent_class)->destroy) {
- (*GTK_OBJECT_CLASS(parent_class)->destroy)(object);
- }
-}
-
-void
-ganv_text_layout(GanvText* text)
-{
- GanvTextPrivate* impl = text->impl;
- GanvItem* item = GANV_ITEM(text);
- GanvCanvas* canvas = ganv_item_get_canvas(item);
- GtkWidget* widget = GTK_WIDGET(canvas);
- double points = impl->font_size;
- GtkStyle* style = gtk_rc_get_style(widget);
-
- if (impl->font_size == 0.0) {
- points = ganv_canvas_get_font_size(canvas);
- }
-
- if (impl->layout) {
- g_object_unref(impl->layout);
- }
- impl->layout = gtk_widget_create_pango_layout(widget, impl->text);
-
- PangoFontDescription* font = pango_font_description_copy(style->font_desc);
- PangoContext* ctx = pango_layout_get_context(impl->layout);
- cairo_font_options_t* opt = cairo_font_options_copy(
- pango_cairo_context_get_font_options(ctx));
-
- pango_font_description_set_size(font, points * (double)PANGO_SCALE);
- pango_layout_set_font_description(impl->layout, font);
- pango_cairo_context_set_font_options(ctx, opt);
- cairo_font_options_destroy(opt);
- pango_font_description_free(font);
-
- int width, height;
- pango_layout_get_pixel_size(impl->layout, &width, &height);
-
- impl->coords.width = width;
- impl->coords.height = height;
- impl->needs_layout = FALSE;
-
- ganv_item_request_update(GANV_ITEM(text));
-}
-
-static void
-ganv_text_set_property(GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_TEXT(object));
-
- GanvText* text = GANV_TEXT(object);
- GanvTextPrivate* impl = text->impl;
-
- switch (prop_id) {
- case PROP_X:
- impl->coords.x = g_value_get_double(value);
- break;
- case PROP_Y:
- impl->coords.y = g_value_get_double(value);
- break;
- case PROP_COLOR:
- impl->color = g_value_get_uint(value);
- break;
- case PROP_FONT_SIZE:
- impl->font_size = g_value_get_double(value);
- impl->needs_layout = TRUE;
- break;
- case PROP_TEXT:
- free(impl->text);
- impl->text = g_value_dup_string(value);
- impl->needs_layout = TRUE;
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- return;
- }
- if (impl->needs_layout) {
- if (GANV_IS_NODE(GANV_ITEM(text)->impl->parent)) {
- GANV_NODE(GANV_ITEM(text)->impl->parent)->impl->must_resize = TRUE;
- }
- }
- ganv_item_request_update(GANV_ITEM(text));
-}
-
-static void
-ganv_text_get_property(GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_TEXT(object));
-
- GanvText* text = GANV_TEXT(object);
- GanvTextPrivate* impl = text->impl;
-
- if (impl->needs_layout && (prop_id == PROP_WIDTH
- || prop_id == PROP_HEIGHT)) {
- ganv_text_layout(text);
- }
-
- switch (prop_id) {
- GET_CASE(TEXT, string, impl->text);
- GET_CASE(X, double, impl->coords.x);
- GET_CASE(Y, double, impl->coords.y);
- GET_CASE(WIDTH, double, impl->coords.width);
- GET_CASE(HEIGHT, double, impl->coords.height);
- GET_CASE(COLOR, uint, impl->color);
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-ganv_text_bounds_item(GanvItem* item,
- double* x1, double* y1,
- double* x2, double* y2)
-{
- GanvText* text = GANV_TEXT(item);
- GanvTextPrivate* impl = text->impl;
-
- if (impl->needs_layout) {
- ganv_text_layout(text);
- }
-
- *x1 = impl->coords.x;
- *y1 = impl->coords.y;
- *x2 = impl->coords.x + impl->coords.width;
- *y2 = impl->coords.y + impl->coords.height;
-}
-
-static void
-ganv_text_bounds(GanvItem* item,
- double* x1, double* y1,
- double* x2, double* y2)
-{
- ganv_text_bounds_item(item, x1, y1, x2, y2);
-}
-
-static void
-ganv_text_update(GanvItem* item, int flags)
-{
- // Update world-relative bounding box
- ganv_text_bounds(item, &item->impl->x1, &item->impl->y1, &item->impl->x2, &item->impl->y2);
- ganv_item_i2w_pair(item, &item->impl->x1, &item->impl->y1, &item->impl->x2, &item->impl->y2);
-
- ganv_canvas_request_redraw_w(
- item->impl->canvas, item->impl->x1, item->impl->y1, item->impl->x2, item->impl->y2);
-
- parent_class->update(item, flags);
-}
-
-static double
-ganv_text_point(GanvItem* item, double x, double y, GanvItem** actual_item)
-{
- *actual_item = NULL;
-
- double x1, y1, x2, y2;
- ganv_text_bounds_item(item, &x1, &y1, &x2, &y2);
- if ((x >= x1) && (y >= y1) && (x <= x2) && (y <= y2)) {
- return 0.0;
- }
-
- // Point is outside the box
- double dx, dy;
-
- // Find horizontal distance to nearest edge
- if (x < x1) {
- dx = x1 - x;
- } else if (x > x2) {
- dx = x - x2;
- } else {
- dx = 0.0;
- }
-
- // Find vertical distance to nearest edge
- if (y < y1) {
- dy = y1 - y;
- } else if (y > y2) {
- dy = y - y2;
- } else {
- dy = 0.0;
- }
-
- return sqrt((dx * dx) + (dy * dy));
-}
-
-static void
-ganv_text_draw(GanvItem* item,
- cairo_t* cr, double cx, double cy, double cw, double ch)
-{
- GanvText* text = GANV_TEXT(item);
- GanvTextPrivate* impl = text->impl;
-
- double wx = impl->coords.x;
- double wy = impl->coords.y;
- ganv_item_i2w(item, &wx, &wy);
-
- if (impl->needs_layout) {
- ganv_text_layout(text);
- }
-
- double r, g, b, a;
- color_to_rgba(impl->color, &r, &g, &b, &a);
-
- cairo_set_source_rgba(cr, r, g, b, a);
- cairo_move_to(cr, wx, wy);
- pango_cairo_show_layout(cr, impl->layout);
-}
-
-static void
-ganv_text_class_init(GanvTextClass* klass)
-{
- GObjectClass* gobject_class = (GObjectClass*)klass;
- GtkObjectClass* object_class = (GtkObjectClass*)klass;
- GanvItemClass* item_class = (GanvItemClass*)klass;
-
- parent_class = GANV_ITEM_CLASS(g_type_class_peek_parent(klass));
-
- gobject_class->set_property = ganv_text_set_property;
- gobject_class->get_property = ganv_text_get_property;
-
- g_object_class_install_property(
- gobject_class, PROP_TEXT, g_param_spec_string(
- "text",
- _("Text"),
- _("The string to display."),
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_X, g_param_spec_double(
- "x",
- _("x"),
- _("Top left x coordinate."),
- -G_MAXDOUBLE, G_MAXDOUBLE,
- 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_Y, g_param_spec_double(
- "y",
- _("y"),
- _("Top left y coordinate."),
- -G_MAXDOUBLE, G_MAXDOUBLE,
- 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_WIDTH, g_param_spec_double(
- "width",
- _("Width"),
- _("The current width of the text."),
- -G_MAXDOUBLE, G_MAXDOUBLE,
- 1.0,
- G_PARAM_READABLE));
-
- g_object_class_install_property(
- gobject_class, PROP_HEIGHT, g_param_spec_double(
- "height",
- _("Height"),
- _("The current height of the text."),
- -G_MAXDOUBLE, G_MAXDOUBLE,
- 1.0,
- G_PARAM_READABLE));
-
- g_object_class_install_property(
- gobject_class, PROP_COLOR, g_param_spec_uint(
- "color",
- _("Color"),
- _("The color of the text."),
- 0, G_MAXUINT,
- DEFAULT_TEXT_COLOR,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_FONT_SIZE, g_param_spec_double(
- "font-size",
- _("Font size"),
- _("The font size in points."),
- -G_MAXDOUBLE, G_MAXDOUBLE,
- 0.0,
- G_PARAM_READWRITE));
-
-
- object_class->destroy = ganv_text_destroy;
-
- item_class->update = ganv_text_update;
- item_class->bounds = ganv_text_bounds;
- item_class->point = ganv_text_point;
- item_class->draw = ganv_text_draw;
-}
diff --git a/src/widget.c b/src/widget.c
deleted file mode 100644
index b08715b..0000000
--- a/src/widget.c
+++ /dev/null
@@ -1,503 +0,0 @@
-/* This file is part of Ganv.
- * Copyright 2007-2016 David Robillard <http://drobilla.net>
- *
- * Ganv is free software: you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or any later version.
- *
- * Ganv is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with Ganv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Based on GnomeCanvasWidget, by Federico Mena <federico@nuclecu.unam.mx>
- * Copyright 1997-2000 Free Software Foundation
- */
-
-#include <math.h>
-
-#include <gtk/gtksignal.h>
-
-#include "ganv/canvas.h"
-#include "ganv/widget.h"
-
-#include "./gettext.h"
-#include "./ganv-private.h"
-
-G_DEFINE_TYPE_WITH_CODE(GanvWidget, ganv_widget, GANV_TYPE_ITEM,
- G_ADD_PRIVATE(GanvWidget))
-
-static GanvItemClass* parent_class;
-
-enum {
- PROP_0,
- PROP_WIDGET,
- PROP_X,
- PROP_Y,
- PROP_WIDTH,
- PROP_HEIGHT,
- PROP_ANCHOR,
- PROP_SIZE_PIXELS
-};
-
-static void
-ganv_widget_init(GanvWidget* witem)
-{
- GanvWidgetPrivate* impl = ganv_widget_get_instance_private(witem);
-
- witem->impl = impl;
- witem->impl->x = 0.0;
- witem->impl->y = 0.0;
- witem->impl->width = 0.0;
- witem->impl->height = 0.0;
- witem->impl->anchor = GTK_ANCHOR_NW;
- witem->impl->size_pixels = FALSE;
-}
-
-static void
-ganv_widget_destroy(GtkObject* object)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_WIDGET(object));
-
- GanvWidget* witem = GANV_WIDGET(object);
-
- if (witem->impl->widget && !witem->impl->in_destroy) {
- g_signal_handler_disconnect(witem->impl->widget, witem->impl->destroy_id);
- gtk_widget_destroy(witem->impl->widget);
- witem->impl->widget = NULL;
- }
-
- if (GTK_OBJECT_CLASS(parent_class)->destroy) {
- (*GTK_OBJECT_CLASS(parent_class)->destroy)(object);
- }
-}
-
-static void
-recalc_bounds(GanvWidget* witem)
-{
- GanvItem* item = GANV_ITEM(witem);
-
- /* Get world coordinates */
-
- double wx = witem->impl->x;
- double wy = witem->impl->y;
- ganv_item_i2w(item, &wx, &wy);
-
- /* Get canvas pixel coordinates */
-
- ganv_canvas_w2c(item->impl->canvas, wx, wy, &witem->impl->cx, &witem->impl->cy);
-
- /* Anchor widget item */
-
- switch (witem->impl->anchor) {
- case GTK_ANCHOR_N:
- case GTK_ANCHOR_CENTER:
- case GTK_ANCHOR_S:
- witem->impl->cx -= witem->impl->cwidth / 2;
- break;
-
- case GTK_ANCHOR_NE:
- case GTK_ANCHOR_E:
- case GTK_ANCHOR_SE:
- witem->impl->cx -= witem->impl->cwidth;
- break;
-
- default:
- break;
- }
-
- switch (witem->impl->anchor) {
- case GTK_ANCHOR_W:
- case GTK_ANCHOR_CENTER:
- case GTK_ANCHOR_E:
- witem->impl->cy -= witem->impl->cheight / 2;
- break;
-
- case GTK_ANCHOR_SW:
- case GTK_ANCHOR_S:
- case GTK_ANCHOR_SE:
- witem->impl->cy -= witem->impl->cheight;
- break;
-
- default:
- break;
- }
-
- /* Bounds */
-
- item->impl->x1 = witem->impl->cx;
- item->impl->y1 = witem->impl->cy;
- item->impl->x2 = witem->impl->cx + witem->impl->cwidth;
- item->impl->y2 = witem->impl->cy + witem->impl->cheight;
-
- int zoom_xofs, zoom_yofs;
- ganv_canvas_get_zoom_offsets(item->impl->canvas, &zoom_xofs, &zoom_yofs);
- if (witem->impl->widget) {
- gtk_layout_move(GTK_LAYOUT(item->impl->canvas), witem->impl->widget,
- witem->impl->cx + zoom_xofs,
- witem->impl->cy + zoom_yofs);
- }
-}
-
-static void
-do_destroy(GtkObject* object, gpointer data)
-{
- GanvWidget* witem = GANV_WIDGET(data);
-
- witem->impl->in_destroy = TRUE;
- gtk_object_destroy(GTK_OBJECT(data));
-}
-
-static void
-ganv_widget_set_property(GObject* object,
- guint param_id,
- const GValue* value,
- GParamSpec* pspec)
-{
- GanvItem* item = GANV_ITEM(object);
- GanvWidget* witem = GANV_WIDGET(object);
- int update = FALSE;
- int calc_bounds = FALSE;
- GObject* obj;
-
- switch (param_id) {
- case PROP_WIDGET:
- if (witem->impl->widget) {
- g_signal_handler_disconnect(witem->impl->widget, witem->impl->destroy_id);
- gtk_container_remove(GTK_CONTAINER(item->impl->canvas), witem->impl->widget);
- }
-
- obj = (GObject*)g_value_get_object(value);
- if (obj) {
- witem->impl->widget = GTK_WIDGET(obj);
- witem->impl->destroy_id = g_signal_connect(obj, "destroy",
- G_CALLBACK(do_destroy),
- witem);
- int zoom_xofs, zoom_yofs;
- ganv_canvas_get_zoom_offsets(item->impl->canvas, &zoom_xofs, &zoom_yofs);
-
- gtk_layout_put(GTK_LAYOUT(item->impl->canvas), witem->impl->widget,
- witem->impl->cx + zoom_xofs,
- witem->impl->cy + zoom_yofs);
- }
-
- update = TRUE;
- break;
-
- case PROP_X:
- if (witem->impl->x != g_value_get_double(value)) {
- witem->impl->x = g_value_get_double(value);
- calc_bounds = TRUE;
- }
- break;
-
- case PROP_Y:
- if (witem->impl->y != g_value_get_double(value)) {
- witem->impl->y = g_value_get_double(value);
- calc_bounds = TRUE;
- }
- break;
-
- case PROP_WIDTH:
- if (witem->impl->width != fabs(g_value_get_double(value))) {
- witem->impl->width = fabs(g_value_get_double(value));
- update = TRUE;
- }
- break;
-
- case PROP_HEIGHT:
- if (witem->impl->height != fabs(g_value_get_double(value))) {
- witem->impl->height = fabs(g_value_get_double(value));
- update = TRUE;
- }
- break;
-
- case PROP_ANCHOR:
- if (witem->impl->anchor != (GtkAnchorType)g_value_get_enum(value)) {
- witem->impl->anchor = (GtkAnchorType)g_value_get_enum(value);
- update = TRUE;
- }
- break;
-
- case PROP_SIZE_PIXELS:
- if (witem->impl->size_pixels != g_value_get_boolean(value)) {
- witem->impl->size_pixels = g_value_get_boolean(value);
- update = TRUE;
- }
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
- break;
- }
-
- if (update) {
- (*GANV_ITEM_GET_CLASS(item)->update)(item, 0);
- }
-
- if (calc_bounds) {
- recalc_bounds(witem);
- }
-}
-
-static void
-ganv_widget_get_property(GObject* object,
- guint param_id,
- GValue* value,
- GParamSpec* pspec)
-{
- g_return_if_fail(object != NULL);
- g_return_if_fail(GANV_IS_WIDGET(object));
-
- GanvWidget* witem = GANV_WIDGET(object);
-
- switch (param_id) {
- case PROP_WIDGET:
- g_value_set_object(value, (GObject*)witem->impl->widget);
- break;
-
- case PROP_X:
- g_value_set_double(value, witem->impl->x);
- break;
-
- case PROP_Y:
- g_value_set_double(value, witem->impl->y);
- break;
-
- case PROP_WIDTH:
- g_value_set_double(value, witem->impl->width);
- break;
-
- case PROP_HEIGHT:
- g_value_set_double(value, witem->impl->height);
- break;
-
- case PROP_ANCHOR:
- g_value_set_enum(value, witem->impl->anchor);
- break;
-
- case PROP_SIZE_PIXELS:
- g_value_set_boolean(value, witem->impl->size_pixels);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
- break;
- }
-}
-
-static void
-ganv_widget_update(GanvItem* item, int flags)
-{
- GanvWidget* witem = GANV_WIDGET(item);
-
- if (parent_class->update) {
- (*parent_class->update)(item, flags);
- }
-
- if (witem->impl->widget) {
- const double pixels_per_unit = ganv_canvas_get_zoom(item->impl->canvas);
- if (witem->impl->size_pixels) {
- witem->impl->cwidth = (int)(witem->impl->width + 0.5);
- witem->impl->cheight = (int)(witem->impl->height + 0.5);
- } else {
- witem->impl->cwidth = (int)(witem->impl->width * pixels_per_unit + 0.5);
- witem->impl->cheight = (int)(witem->impl->height * pixels_per_unit + 0.5);
- }
-
- gtk_widget_set_size_request(witem->impl->widget, witem->impl->cwidth, witem->impl->cheight);
- } else {
- witem->impl->cwidth = 0.0;
- witem->impl->cheight = 0.0;
- }
-
- recalc_bounds(witem);
-}
-
-static void
-ganv_widget_draw(GanvItem* item,
- cairo_t* cr, double cx, double cy, double cw, double ch)
-{
- GanvWidget* witem = GANV_WIDGET(item);
-
- if (witem->impl->widget) {
- gtk_widget_queue_draw(witem->impl->widget);
- }
-}
-
-static double
-ganv_widget_point(GanvItem* item, double x, double y, GanvItem** actual_item)
-{
- GanvWidget* witem = GANV_WIDGET(item);
-
- *actual_item = item;
-
- double x1, y1;
- ganv_canvas_c2w(item->impl->canvas, witem->impl->cx, witem->impl->cy, &x1, &y1);
-
- const double pixels_per_unit = ganv_canvas_get_zoom(item->impl->canvas);
-
- double x2 = x1 + (witem->impl->cwidth - 1) / pixels_per_unit;
- double y2 = y1 + (witem->impl->cheight - 1) / pixels_per_unit;
-
- /* Is point inside widget bounds? */
-
- if ((x >= x1) && (y >= y1) && (x <= x2) && (y <= y2)) {
- return 0.0;
- }
-
- /* Point is outside widget bounds */
-
- double dx;
- if (x < x1) {
- dx = x1 - x;
- } else if (x > x2) {
- dx = x - x2;
- } else {
- dx = 0.0;
- }
-
- double dy;
- if (y < y1) {
- dy = y1 - y;
- } else if (y > y2) {
- dy = y - y2;
- } else {
- dy = 0.0;
- }
-
- return sqrt(dx * dx + dy * dy);
-}
-
-static void
-ganv_widget_bounds(GanvItem* item, double* x1, double* y1, double* x2, double* y2)
-{
- GanvWidget* witem = GANV_WIDGET(item);
-
- *x1 = witem->impl->x;
- *y1 = witem->impl->y;
-
- switch (witem->impl->anchor) {
- case GTK_ANCHOR_NW:
- case GTK_ANCHOR_W:
- case GTK_ANCHOR_SW:
- break;
-
- case GTK_ANCHOR_N:
- case GTK_ANCHOR_CENTER:
- case GTK_ANCHOR_S:
- *x1 -= witem->impl->width / 2.0;
- break;
-
- case GTK_ANCHOR_NE:
- case GTK_ANCHOR_E:
- case GTK_ANCHOR_SE:
- *x1 -= witem->impl->width;
- break;
-
- default:
- break;
- }
-
- switch (witem->impl->anchor) {
- case GTK_ANCHOR_NW:
- case GTK_ANCHOR_N:
- case GTK_ANCHOR_NE:
- break;
-
- case GTK_ANCHOR_W:
- case GTK_ANCHOR_CENTER:
- case GTK_ANCHOR_E:
- *y1 -= witem->impl->height / 2.0;
- break;
-
- case GTK_ANCHOR_SW:
- case GTK_ANCHOR_S:
- case GTK_ANCHOR_SE:
- *y1 -= witem->impl->height;
- break;
-
- default:
- break;
- }
-
- *x2 = *x1 + witem->impl->width;
- *y2 = *y1 + witem->impl->height;
-}
-
-static void
-ganv_widget_class_init(GanvWidgetClass* klass)
-{
- GObjectClass* gobject_class = (GObjectClass*)klass;
- GtkObjectClass* object_class = (GtkObjectClass*)klass;
- GanvItemClass* item_class = (GanvItemClass*)klass;
-
- parent_class = (GanvItemClass*)g_type_class_peek_parent(klass);
-
- gobject_class->set_property = ganv_widget_set_property;
- gobject_class->get_property = ganv_widget_get_property;
-
- g_object_class_install_property(
- gobject_class, PROP_WIDGET, g_param_spec_object(
- "widget", _("Widget"),
- _("The widget to embed in this item."),
- GTK_TYPE_WIDGET,
- (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE)));
-
- g_object_class_install_property(
- gobject_class, PROP_X, g_param_spec_double(
- "x", _("x"),
- _("The x coordinate of the anchor"),
- -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_Y, g_param_spec_double(
- "y", _("y"),
- _("The x coordinate of the anchor"),
- -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_WIDTH, g_param_spec_double(
- "width", _("Width"),
- _("The width of the widget."),
- -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_HEIGHT, g_param_spec_double(
- "height", _("Height"),
- _("The height of the widget."),
- -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_ANCHOR, g_param_spec_enum(
- "anchor", _("Anchor"),
- _("The anchor point of the widget."),
- GTK_TYPE_ANCHOR_TYPE,
- GTK_ANCHOR_NW,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(
- gobject_class, PROP_SIZE_PIXELS, g_param_spec_boolean(
- "size-pixels", ("Size is in pixels"),
- _("Specifies whether the widget size is specified in pixels or"
- " canvas units. If it is in pixels, then the widget will not"
- " be scaled when the canvas zoom factor changes. Otherwise,"
- " it will be scaled."),
- FALSE,
- G_PARAM_READWRITE));
-
- object_class->destroy = ganv_widget_destroy;
-
- item_class->update = ganv_widget_update;
- item_class->point = ganv_widget_point;
- item_class->bounds = ganv_widget_bounds;
- item_class->draw = ganv_widget_draw;
-}
diff --git a/waflib/COPYING b/waflib/COPYING
deleted file mode 100644
index a4147d2..0000000
--- a/waflib/COPYING
+++ /dev/null
@@ -1,25 +0,0 @@
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
diff --git a/waflib/waf b/waflib/waf
deleted file mode 100755
index e22930a..0000000
--- a/waflib/waf
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env python
-
-# Minimal waf script for projects that include waflib directly
-
-from waflib import Context, Scripting
-
-import inspect
-import os
-
-def main():
- script_path = os.path.abspath(inspect.getfile(inspect.getmodule(main)))
- project_path = os.path.dirname(script_path)
- Scripting.waf_entry_point(os.getcwd(), Context.WAFVERSION, project_path)
-
-if __name__ == '__main__':
- main()
diff --git a/wscript b/wscript
deleted file mode 100644
index da4fdbd..0000000
--- a/wscript
+++ /dev/null
@@ -1,247 +0,0 @@
-#!/usr/bin/env python
-
-import os
-
-from waflib import Options, Utils
-from waflib.extras import autowaf
-
-# Library and package version (UNIX style major, minor, micro)
-# major increment <=> incompatible changes
-# minor increment <=> compatible changes (additions)
-# micro increment <=> no interface changes
-GANV_VERSION = '1.5.4'
-GANV_MAJOR_VERSION = '1'
-
-# Mandatory waf variables
-APPNAME = 'ganv' # Package name for waf dist
-VERSION = GANV_VERSION # Package version for waf dist
-top = '.' # Source directory
-out = 'build' # Build directory
-
-def options(ctx):
- ctx.load('compiler_c')
- ctx.load('compiler_cxx')
- autowaf.set_options(ctx, test=True)
- opt = ctx.get_option_group('Configuration options')
- autowaf.add_flags(
- opt,
- {'no-graphviz': 'do not compile with graphviz support',
- 'light-theme': 'use light coloured theme',
- 'no-fdgl': 'use experimental force-directed graph layout',
- 'no-nls': 'disable i18n (native language support)',
- 'gir': 'build GObject introspection data'})
-
-def configure(conf):
- autowaf.display_header('Ganv Configuration')
- conf.load('compiler_c', cache=True)
- conf.load('compiler_cxx', cache=True)
- conf.load('autowaf', cache=True)
- autowaf.set_c_lang(conf, 'c99')
-
- autowaf.check_pkg(conf, 'gtk+-2.0', uselib_store='GTK',
- atleast_version='2.0.0', mandatory=True)
- autowaf.check_pkg(conf, 'gtkmm-2.4', uselib_store='GTKMM',
- atleast_version='2.10.0', mandatory=True)
-
- if Options.options.gir:
- autowaf.check_pkg(conf, 'gobject-introspection-1.0',
- uselib_store='GIR', mandatory=False)
- conf.find_program('g-ir-doc-tool', var='G_IR_DOC_TOOL', mandatory=False)
- conf.find_program('yelp-build', var='YELP_BUILD', mandatory=False)
-
- if not Options.options.no_graphviz:
- autowaf.check_pkg(conf, 'libgvc', uselib_store='AGRAPH',
- atleast_version='2.30', mandatory=False)
-
- if not Options.options.no_fdgl:
- autowaf.define(conf, 'GANV_FDGL', 1)
-
- if Options.options.light_theme:
- autowaf.define(conf, 'GANV_USE_LIGHT_THEME', 1)
-
- if not Options.options.no_nls:
- autowaf.check_function(conf, 'cxx', 'dgettext',
- header_name = 'libintl.h',
- lib = 'intl',
- define_name = 'ENABLE_NLS',
- mandatory = False)
-
- autowaf.set_lib_env(conf, 'ganv', GANV_VERSION)
- conf.write_config_header('ganv_config.h', remove=False)
-
- autowaf.display_summary(
- conf,
- {'Static (Graphviz) arrange': bool(conf.env.HAVE_AGRAPH_2_20),
- 'Interactive force-directed arrange': bool(conf.env.GANV_FDGL),
- 'Native language support': bool(conf.env.ENABLE_NLS),
- 'GObject introspection': bool(conf.env.HAVE_GIR),
- 'Unit tests': bool(conf.env.BUILD_TESTS)})
-
-ganv_source = [
- 'src/Canvas.cpp',
- 'src/Port.cpp',
- 'src/box.c',
- 'src/circle.c',
- 'src/edge.c',
- 'src/ganv-marshal.c',
- 'src/group.c',
- 'src/item.c',
- 'src/module.c',
- 'src/node.c',
- 'src/port.c',
- 'src/text.c',
- 'src/widget.c'
-]
-
-def declare_doc_files(task):
- bld = task.generator.bld
- path = bld.path.get_bld().find_or_declare('doc-html')
- for i in path.ant_glob('*', remove=False):
- i.sig = Utils.h_file(i.abspath())
-
-def build(bld):
- # Headers
- includedir = '${INCLUDEDIR}/ganv-%s/ganv' % GANV_MAJOR_VERSION
- bld.install_files(includedir, bld.path.ant_glob('ganv/*.h*'))
-
- # Pkgconfig file
- autowaf.build_pc(bld, 'GANV', GANV_VERSION, GANV_MAJOR_VERSION,
- 'GTKMM AGRAPH',
- {'GANV_MAJOR_VERSION' : GANV_MAJOR_VERSION})
-
- bld(rule = 'glib-genmarshal --prefix=ganv_marshal --header ${SRC} > ${TGT}',
- source = 'src/ganv-marshal.list',
- target = 'src/ganv-marshal.h')
-
- bld(rule = 'glib-genmarshal --prefix=ganv_marshal --body ${SRC} > ${TGT}',
- source = 'src/ganv-marshal.list',
- target = 'src/ganv-marshal.c.in')
-
- bld(rule = 'cat ${SRC} > ${TGT}',
- source = ['src/ganv-marshal.h', 'src/ganv-marshal.c.in'],
- target = 'src/ganv-marshal.c')
-
- # Library
- lib = bld(features = 'c cshlib cxx cxxshlib',
- export_includes = ['.'],
- source = ganv_source,
- includes = ['.', './src'],
- name = 'libganv',
- target = 'ganv-%s' % GANV_MAJOR_VERSION,
- uselib = 'GTKMM AGRAPH',
- vnum = GANV_VERSION,
- install_path = '${LIBDIR}')
- if bld.is_defined('ENABLE_NLS'):
- lib.lib = ['intl']
-
- # Benchmark program (C++)
- bld(features = 'cxx cxxprogram',
- source = 'src/ganv_bench.cpp',
- includes = ['.', './src'],
- use = 'libganv',
- uselib = 'GTKMM AGRAPH',
- target = 'src/ganv_bench')
-
- if bld.env.BUILD_TESTS:
- test_libs = []
- test_cflags = ['']
- test_linkflags = ['']
- if not bld.env.NO_COVERAGE:
- test_cflags += ['--coverage']
- test_linkflags += ['--coverage']
-
- # Static library for test program
- bld(features = 'c cstlib cxx cxxshlib',
- source = ganv_source,
- includes = ['.', './src'],
- name = 'libganv_profiled',
- target = 'ganv_profiled',
- uselib = 'GTKMM AGRAPH',
- install_path = '',
- cflags = test_cflags,
- linkflags = test_linkflags)
-
- # Test program (C)
- bld(features = 'cxx cxxprogram',
- source = 'src/ganv_test.c',
- includes = ['.', './src'],
- use = 'libganv_profiled',
- lib = test_libs,
- uselib = 'GTKMM AGRAPH',
- target = 'src/ganv_test',
- cflags = test_cflags,
- linkflags = test_linkflags)
-
- # Documentation
- #autowaf.build_dox(bld, 'GANV', GANV_VERSION, top, out)
-
- if bld.env.HAVE_GIR:
- bld.add_group()
-
- bld_dir = os.path.join(out, APPNAME)
- if not (len(bld.stack_path) > 1): # not top-level
- bld_dir = out
-
- pc_path = os.path.abspath(os.path.join(bld_dir, 'ganv-1.pc'))
-
- bld(name = 'ganv-gir',
- source = ganv_source + bld.path.ant_glob('ganv/*.h'),
- target = 'Ganv-1.0.gir',
- install_path = '${LIBDIR}/girepository-1.0',
- rule = 'g-ir-scanner --warn-all -n Ganv --nsversion=1.0'
- ' --no-libtool ' +
- ('--pkg=%s' % pc_path) +
- (' -I%s' % bld.path.bldpath()) +
- ''.join([' -I' + path for path in bld.env.INCLUDES_GTK]) +
- (' -L%s' % bld_dir) +
- ' --library=ganv-1'
- ' --include=GObject-2.0 --include=Gdk-2.0 --include Gtk-2.0'
- ' -o ${TGT} ${SRC}')
-
- bld(name = 'ganv-typelib',
- after = 'ganv-gir',
- source = 'Ganv-1.0.gir',
- target = 'Ganv-1.0.typelib',
- install_path = '${LIBDIR}/girepository-1.0',
- rule = 'g-ir-compiler ${SRC} -o ${TGT}')
-
- if bld.env.DOCS and bld.env['G_IR_DOC_TOOL'] and bld.env['YELP_BUILD']:
- # The source and target files used here aren't exclusive,
- # but are declared so waf can track dependencies
- bld(rule = '${G_IR_DOC_TOOL} --language C -o doc-xml ${SRC}',
- source = 'Ganv-1.0.gir',
- target = 'doc-xml/index.page')
- bld(name = 'yelp-build',
- rule = '${YELP_BUILD} html -o doc-html doc-xml',
- source = 'doc-xml/index.page',
- target = 'doc-html/index.html')
- bld(name = 'find-docs',
- always = True,
- rule = declare_doc_files,
- after = 'yelp-build')
-
- bld.install_files(
- os.path.join('${DOCDIR}', 'ganv-0', 'html'),
- bld.path.get_bld().ant_glob('doc-html/*'))
-
- bld.add_post_fun(autowaf.run_ldconfig)
-
-def test(ctx):
- autowaf.pre_test(ctx, APPNAME)
- autowaf.run_tests(ctx, APPNAME, ['src/ganv_test'], dirs=['./src'])
- autowaf.post_test(ctx, APPNAME)
-
-def i18n(bld):
- autowaf.build_i18n(bld, '..', 'ganv', APPNAME, ganv_source,
- 'David Robillard')
-
-def posts(ctx):
- path = str(ctx.path.abspath())
- autowaf.news_to_posts(
- os.path.join(path, 'NEWS'),
- {'title' : 'Ganv',
- 'description' : autowaf.get_blurb(os.path.join(path, 'README')),
- 'dist_pattern' : 'http://download.drobilla.net/ganv-%s.tar.bz2'},
- { 'Author' : 'drobilla',
- 'Tags' : 'Hacking, LAD, LV2, Ganv' },
- os.path.join(out, 'posts'))